Compare commits
15 commits
main
...
pagetop-wo
| Author | SHA1 | Date | |
|---|---|---|---|
| 64db114eb0 | |||
| 9435678e01 | |||
| 26f1cda831 | |||
| d495c05b96 | |||
| dbf0894894 | |||
| 2202a2350c | |||
| 62219584b0 | |||
| 8d0103c257 | |||
| 1bd97d5705 | |||
| f27790c3a2 | |||
| 6376e3e88c | |||
| 38fd24453e | |||
| 511149caa7 | |||
| 41c4379bc3 | |||
| f9e87058d8 |
3
.gitignore
vendored
|
|
@ -1,6 +1,9 @@
|
|||
# Ignora directorios de compilación
|
||||
**/target
|
||||
|
||||
# Ignora directorios de archivos estáticos
|
||||
**/static
|
||||
|
||||
# Archivos de log
|
||||
**/log/*.log*
|
||||
|
||||
|
|
|
|||
58
Cargo.lock
generated
|
|
@ -20,6 +20,15 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
|
|
@ -933,7 +942,7 @@ version = "0.4.18"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"aho-corasick 1.1.4",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata",
|
||||
|
|
@ -965,6 +974,16 @@ dependencies = [
|
|||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bumpalo",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
|
|
@ -1495,6 +1514,17 @@ dependencies = [
|
|||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minify-js"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1fa5546ee8bd66024113e506cabe4230e76635a094c06ea2051b66021dda92e"
|
||||
dependencies = [
|
||||
"aho-corasick 0.7.20",
|
||||
"lazy_static",
|
||||
"parse-js",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
|
|
@ -1721,7 +1751,6 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"pagetop",
|
||||
"pagetop-build",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1731,7 +1760,6 @@ dependencies = [
|
|||
"pagetop",
|
||||
"pagetop-build",
|
||||
"serde",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1739,9 +1767,18 @@ name = "pagetop-build"
|
|||
version = "0.3.2"
|
||||
dependencies = [
|
||||
"grass",
|
||||
"minify-js",
|
||||
"pagetop-statics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pagetop-htmx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"pagetop",
|
||||
"pagetop-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pagetop-macros"
|
||||
version = "0.3.0"
|
||||
|
|
@ -1812,6 +1849,19 @@ dependencies = [
|
|||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parse-js"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2742b5e32dcb5930447ed9f9e401a7dfd883867fc079c4fac44ae8ba3593710e"
|
||||
dependencies = [
|
||||
"aho-corasick 0.7.20",
|
||||
"bumpalo",
|
||||
"hashbrown 0.13.2",
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pastey"
|
||||
version = "0.2.2"
|
||||
|
|
@ -2094,7 +2144,7 @@ version = "0.4.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"aho-corasick 1.1.4",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ members = [
|
|||
# Extensions
|
||||
"extensions/pagetop-aliner",
|
||||
"extensions/pagetop-bootsier",
|
||||
"extensions/pagetop-htmx",
|
||||
"extensions/pagetop-seaorm",
|
||||
]
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ indexmap = "2.14"
|
|||
indoc = "2.0"
|
||||
itoa = "1.0"
|
||||
mime_guess = "2.0"
|
||||
minify-js = "0.6"
|
||||
parking_lot = "0.12"
|
||||
pastey = "0.2"
|
||||
path-slash = "0.2"
|
||||
|
|
@ -62,6 +64,7 @@ pagetop-statics = { version = "0.1", path = "helpers/pagetop-statics" }
|
|||
# Extensions
|
||||
pagetop-aliner = { version = "0.1", path = "extensions/pagetop-aliner" }
|
||||
pagetop-bootsier = { version = "0.1", path = "extensions/pagetop-bootsier" }
|
||||
pagetop-htmx = { version = "0.1", path = "extensions/pagetop-htmx" }
|
||||
pagetop-seaorm = { version = "0.0", path = "extensions/pagetop-seaorm" }
|
||||
# PageTop
|
||||
pagetop = { version = "0.5", path = "." }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<div align="center">
|
||||
|
||||
<img src="https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/static/banner.png" />
|
||||
<img src="https://git.cillero.es/manuelcillero/pagetop/raw/branch/main/assets/banner.png" />
|
||||
|
||||
<h1>PageTop</h1>
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
147
assets/css/basic.css
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
:root {
|
||||
/* Font families */
|
||||
--val-font-sans: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif;
|
||||
--val-font-serif: Georgia,"Times New Roman",serif;
|
||||
--val-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
|
||||
--val-font-family: var(--val-font-sans);
|
||||
/* Font size */
|
||||
--val-fs--base: 1rem;
|
||||
/* Font weight */
|
||||
--val-fw--base: 400;
|
||||
/* Line height */
|
||||
--val-lh--base: 1.5;
|
||||
/* Colors */
|
||||
--val-color--bg: #fafafa;
|
||||
--val-color--text: #212529;
|
||||
--val-color--text--muted: color-mix(in srgb, var(--val-color--text) 50%, var(--val-color--bg));
|
||||
--val-color--border: #212529;
|
||||
--val-color--primary: #0d6efd;
|
||||
--val-color--danger: #dc3545;
|
||||
--val-color--switch-off: #adb5bd;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--val-font-family);
|
||||
font-size: var(--val-fs--base);
|
||||
font-weight: var(--val-fw--base);
|
||||
line-height: var(--val-lh--base);
|
||||
color: var(--val-color--text);
|
||||
background-color: var(--val-color--bg);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Form components
|
||||
*/
|
||||
|
||||
.form-required {
|
||||
color: var(--val-color--danger);
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
font-size: 0.9375rem;
|
||||
color: var(--val-color--text--muted);
|
||||
}
|
||||
|
||||
.form-field > select.form-select,
|
||||
.form-field > input.form-control,
|
||||
.form-field > input.form-range,
|
||||
.form-field > textarea.form-control {
|
||||
display: block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 2rem 0 1rem;
|
||||
background: var(--val-color--bg);
|
||||
}
|
||||
fieldset > legend {
|
||||
background-color: var(--val-color--bg);
|
||||
border: 2px groove threedface;
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
min-height: 1.5rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.form-check-inline {
|
||||
display: inline-flex;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
.form-check-reverse {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
text-align: right;
|
||||
}
|
||||
.form-check-input {
|
||||
flex-shrink: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.form-check-label {
|
||||
cursor: pointer;
|
||||
}
|
||||
.form-switch .form-check-input {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
width: 2em;
|
||||
height: 1em;
|
||||
background-color: var(--val-color--switch-off);
|
||||
border-radius: 1em;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: background-color .15s ease-in-out;
|
||||
}
|
||||
.form-switch .form-check-input::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: transform .15s ease-in-out;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.form-switch .form-check-input:checked {
|
||||
background-color: var(--val-color--primary);
|
||||
}
|
||||
.form-switch .form-check-input:checked::after {
|
||||
transform: translateX(1em);
|
||||
}
|
||||
|
||||
input:disabled,
|
||||
input:disabled + label {
|
||||
cursor: default !important;
|
||||
}
|
||||
input:disabled + label {
|
||||
color: var(--val-color--text--muted);
|
||||
}
|
||||
|
||||
/*
|
||||
* Region Footer
|
||||
*/
|
||||
|
||||
.region-footer {
|
||||
padding: .75rem 0 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -389,10 +389,10 @@ body {
|
|||
.intro-text-body .block {
|
||||
position: relative;
|
||||
}
|
||||
.intro-text-body .block__title {
|
||||
.intro-text-body .block-title {
|
||||
margin: 1em 0 .8em;
|
||||
}
|
||||
.intro-text-body .block__title span {
|
||||
.intro-text-body .block-title span {
|
||||
display: inline-block;
|
||||
padding: 10px 30px 14px;
|
||||
margin: 30px 20px 0;
|
||||
|
|
@ -403,7 +403,7 @@ body {
|
|||
border-color: orangered;
|
||||
transform: rotate(-3deg) translateY(-25%);
|
||||
}
|
||||
.intro-text-body .block__title:before {
|
||||
.intro-text-body .block-title:before {
|
||||
content: "";
|
||||
height: 5px;
|
||||
position: absolute;
|
||||
|
|
@ -416,7 +416,7 @@ body {
|
|||
transform: rotate(2deg) translateY(-50%);
|
||||
transform-origin: top left;
|
||||
}
|
||||
.intro-text-body .block__title:after {
|
||||
.intro-text-body .block-title:after {
|
||||
content: "";
|
||||
height: 120%;
|
||||
position: absolute;
|
||||
|
|
@ -427,22 +427,22 @@ body {
|
|||
background: var(--intro-bg-block-1);
|
||||
transform: rotate(2deg);
|
||||
}
|
||||
.intro-text-body .block:nth-of-type(6n+1) .block__title:after {
|
||||
.intro-text-body .block:nth-of-type(6n+1) .block-title:after {
|
||||
background: var(--intro-bg-block-1);
|
||||
}
|
||||
.intro-text-body .block:nth-of-type(6n+2) .block__title:after {
|
||||
.intro-text-body .block:nth-of-type(6n+2) .block-title:after {
|
||||
background: var(--intro-bg-block-2);
|
||||
}
|
||||
.intro-text-body .block:nth-of-type(6n+3) .block__title:after {
|
||||
.intro-text-body .block:nth-of-type(6n+3) .block-title:after {
|
||||
background: var(--intro-bg-block-3);
|
||||
}
|
||||
.intro-text-body .block:nth-of-type(6n+4) .block__title:after {
|
||||
.intro-text-body .block:nth-of-type(6n+4) .block-title:after {
|
||||
background: var(--intro-bg-block-4);
|
||||
}
|
||||
.intro-text-body .block:nth-of-type(6n+5) .block__title:after {
|
||||
.intro-text-body .block:nth-of-type(6n+5) .block-title:after {
|
||||
background: var(--intro-bg-block-5);
|
||||
}
|
||||
.intro-text-body .block:nth-of-type(6n+6) .block__title:after {
|
||||
.intro-text-body .block:nth-of-type(6n+6) .block-title:after {
|
||||
background: var(--intro-bg-block-6);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
8
build.rs
|
|
@ -1,6 +1,12 @@
|
|||
use pagetop_build::StaticFilesBundle;
|
||||
use pagetop_build::{StaticFilesBundle, copy_dir};
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
// Regenera `static/` desde cero sólo si hay cambios en `assets/`.
|
||||
println!("cargo:rerun-if-changed=assets");
|
||||
let _ = std::fs::remove_dir_all("static");
|
||||
|
||||
copy_dir("assets", "static")?;
|
||||
|
||||
StaticFilesBundle::from_dir("./static", None)
|
||||
.with_name("assets")
|
||||
.build()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use pagetop_bootsier::theme::form;
|
||||
use pagetop_bootsier::theme::*;
|
||||
|
||||
include_locales!(LOC from "examples/locale");
|
||||
|
|
@ -143,17 +144,20 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|||
.with_value("form-selections"),
|
||||
)
|
||||
// Botones de acción.
|
||||
.with_child(Button::submit(L10n::t("btn_submit", &LOC)).with_prop(
|
||||
PropsOp::add_classes(classes::ButtonColor::solid(
|
||||
Color::Primary,
|
||||
)),
|
||||
))
|
||||
.with_child(Button::reset(L10n::t("btn_reset", &LOC)).with_prop(
|
||||
PropsOp::add_classes(classes::ButtonColor::outline(
|
||||
Color::Secondary,
|
||||
)),
|
||||
))
|
||||
.with_child(
|
||||
Button::submit(L10n::t("btn_submit", &LOC))
|
||||
.with_color(ButtonColor::Background(Color::Primary)),
|
||||
)
|
||||
.with_child(
|
||||
Button::reset(L10n::t("btn_reset", &LOC))
|
||||
.with_color(ButtonColor::Outline(Color::Secondary)),
|
||||
)
|
||||
.with_child(
|
||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
||||
.with_color(ButtonColor::Link),
|
||||
Button::plain(L10n::t("btn_cancel", &LOC)).with_prop(
|
||||
PropsOp::add_classes(classes::ButtonColor::link()),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -175,6 +179,7 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|||
.with_name("name")
|
||||
.with_label(L10n::t("label_name", &LOC))
|
||||
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
||||
.with_help_text(L10n::t("help_name", &LOC))
|
||||
.with_required(true),
|
||||
)
|
||||
.with_child(
|
||||
|
|
@ -185,6 +190,7 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|||
"placeholder_email",
|
||||
&LOC,
|
||||
))
|
||||
.with_help_text(L10n::t("help_email", &LOC))
|
||||
.with_autocomplete(
|
||||
Some(form::Autocomplete::email()),
|
||||
)
|
||||
|
|
@ -262,194 +268,175 @@ async fn form_controls(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|||
.with_value("form-text"),
|
||||
)
|
||||
// Botones de acción.
|
||||
.with_child(Button::submit(L10n::t("btn_submit", &LOC)).with_prop(
|
||||
PropsOp::add_classes(classes::ButtonColor::solid(
|
||||
Color::Primary,
|
||||
)),
|
||||
))
|
||||
.with_child(Button::reset(L10n::t("btn_reset", &LOC)).with_prop(
|
||||
PropsOp::add_classes(classes::ButtonColor::outline(
|
||||
Color::Secondary,
|
||||
)),
|
||||
))
|
||||
.with_child(
|
||||
Button::submit(L10n::t("btn_submit", &LOC))
|
||||
.with_color(ButtonColor::Background(Color::Primary)),
|
||||
)
|
||||
.with_child(
|
||||
Button::reset(L10n::t("btn_reset", &LOC))
|
||||
.with_color(ButtonColor::Outline(Color::Secondary)),
|
||||
)
|
||||
.with_child(
|
||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
||||
.with_color(ButtonColor::Link),
|
||||
Button::plain(L10n::t("btn_cancel", &LOC)).with_prop(
|
||||
PropsOp::add_classes(classes::ButtonColor::link()),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
// Bloque 3: listas de selección y etiquetas flotantes.
|
||||
.with_child(
|
||||
Block::new()
|
||||
.with_title(L10n::t("block_lists", &LOC))
|
||||
.with_child(
|
||||
Form::new()
|
||||
.with_id("form-lists")
|
||||
.with_action("/")
|
||||
.with_method(form::Method::Post)
|
||||
// Listas de selección (form::select::Field).
|
||||
.with_child(
|
||||
form::Fieldset::new()
|
||||
.with_legend(L10n::t("fieldset_select", &LOC))
|
||||
.with_child(
|
||||
form::select::Field::new()
|
||||
.with_name("language")
|
||||
.with_label(L10n::t("label_language", &LOC))
|
||||
.with_item(
|
||||
form::select::Item::new(
|
||||
"",
|
||||
L10n::t("select_choose", &LOC),
|
||||
)
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_group(
|
||||
form::select::Group::new(L10n::t(
|
||||
"select_group_europe",
|
||||
&LOC,
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"es",
|
||||
L10n::t("select_spanish", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"fr",
|
||||
L10n::t("select_french", &LOC),
|
||||
)),
|
||||
)
|
||||
.with_group(
|
||||
form::select::Group::new(L10n::t(
|
||||
"select_group_americas",
|
||||
&LOC,
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"en",
|
||||
L10n::t("select_english", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"pt",
|
||||
L10n::t("select_portuguese", &LOC),
|
||||
)),
|
||||
)
|
||||
.with_item(
|
||||
form::select::Item::new(
|
||||
"xx",
|
||||
L10n::t("select_disabled", &LOC),
|
||||
)
|
||||
.with_disabled(true),
|
||||
)
|
||||
.with_required(true),
|
||||
)
|
||||
.with_child(
|
||||
form::select::Field::new()
|
||||
.with_name("technologies")
|
||||
.with_label(L10n::t("label_technologies", &LOC))
|
||||
.with_item(
|
||||
form::select::Item::new(
|
||||
"rust",
|
||||
L10n::n("Rust"),
|
||||
)
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_item(
|
||||
form::select::Item::new(
|
||||
"python",
|
||||
L10n::n("Python"),
|
||||
)
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_item(form::select::Item::new(
|
||||
"javascript",
|
||||
L10n::n("JavaScript"),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"go",
|
||||
L10n::n("Go"),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"typescript",
|
||||
L10n::n("TypeScript"),
|
||||
))
|
||||
.with_multiple(true)
|
||||
.with_rows(Some(4))
|
||||
.with_help_text(L10n::t("help_technologies", &LOC)),
|
||||
),
|
||||
)
|
||||
// Etiquetas flotantes.
|
||||
.with_child(
|
||||
form::Fieldset::new()
|
||||
.with_legend(L10n::t("fieldset_floating", &LOC))
|
||||
.with_child(
|
||||
form::input::Field::text()
|
||||
.with_name("fl_name")
|
||||
.with_label(L10n::t("label_name", &LOC))
|
||||
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
||||
.with_floating_label(true)
|
||||
.with_required(true),
|
||||
)
|
||||
.with_child(
|
||||
form::Textarea::new()
|
||||
.with_name("fl_comment")
|
||||
.with_label(L10n::t("label_comment", &LOC))
|
||||
.with_placeholder(L10n::t(
|
||||
"placeholder_comment",
|
||||
&LOC,
|
||||
))
|
||||
.with_floating_label(true),
|
||||
)
|
||||
.with_child(
|
||||
form::select::Field::new()
|
||||
.with_name("fl_country")
|
||||
.with_label(L10n::t("label_country", &LOC))
|
||||
.with_item(
|
||||
form::select::Item::new(
|
||||
"",
|
||||
L10n::t("select_choose", &LOC),
|
||||
)
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_item(form::select::Item::new(
|
||||
"de",
|
||||
L10n::t("select_germany", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"es",
|
||||
L10n::t("select_spain", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"fr",
|
||||
L10n::t("select_france", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"pt",
|
||||
L10n::t("select_portugal", &LOC),
|
||||
))
|
||||
.with_floating_label(true)
|
||||
.with_required(true),
|
||||
),
|
||||
)
|
||||
// Campo oculto (form::Hidden).
|
||||
.with_child(
|
||||
form::Hidden::new()
|
||||
.with_name("origin")
|
||||
.with_value("form-lists"),
|
||||
)
|
||||
// Botones de acción.
|
||||
.with_child(
|
||||
Button::submit(L10n::t("btn_submit", &LOC))
|
||||
.with_color(ButtonColor::Background(Color::Primary)),
|
||||
)
|
||||
.with_child(
|
||||
Button::reset(L10n::t("btn_reset", &LOC))
|
||||
.with_color(ButtonColor::Outline(Color::Secondary)),
|
||||
)
|
||||
.with_child(
|
||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
||||
.with_color(ButtonColor::Link),
|
||||
),
|
||||
),
|
||||
.with_title(
|
||||
if global::SETTINGS.app.theme.eq_ignore_ascii_case("bootsier") {
|
||||
L10n::t("block_lists_floating", &LOC)
|
||||
} else {
|
||||
L10n::t("block_lists", &LOC)
|
||||
},
|
||||
)
|
||||
.with_child(form_lists()),
|
||||
),
|
||||
)
|
||||
.render()
|
||||
}
|
||||
|
||||
fn form_lists() -> Form {
|
||||
let mut form = Form::new()
|
||||
.with_id("form-lists")
|
||||
.with_action("/")
|
||||
.with_method(form::Method::Post)
|
||||
// Listas de selección (form::select::Field).
|
||||
.with_child(
|
||||
form::Fieldset::new()
|
||||
.with_legend(L10n::t("fieldset_select", &LOC))
|
||||
.with_child(
|
||||
form::select::Field::new()
|
||||
.with_name("language")
|
||||
.with_label(L10n::t("label_language", &LOC))
|
||||
.with_item(
|
||||
form::select::Item::new("", L10n::t("select_choose", &LOC))
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_group(
|
||||
form::select::Group::new(L10n::t("select_group_europe", &LOC))
|
||||
.with_item(form::select::Item::new(
|
||||
"es",
|
||||
L10n::t("select_spanish", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"fr",
|
||||
L10n::t("select_french", &LOC),
|
||||
)),
|
||||
)
|
||||
.with_group(
|
||||
form::select::Group::new(L10n::t("select_group_americas", &LOC))
|
||||
.with_item(form::select::Item::new(
|
||||
"en",
|
||||
L10n::t("select_english", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"pt",
|
||||
L10n::t("select_portuguese", &LOC),
|
||||
)),
|
||||
)
|
||||
.with_item(
|
||||
form::select::Item::new("xx", L10n::t("select_disabled", &LOC))
|
||||
.with_disabled(true),
|
||||
)
|
||||
.with_required(true),
|
||||
)
|
||||
.with_child(
|
||||
form::select::Field::new()
|
||||
.with_name("technologies")
|
||||
.with_label(L10n::t("label_technologies", &LOC))
|
||||
.with_item(
|
||||
form::select::Item::new("rust", L10n::n("Rust")).with_selected(true),
|
||||
)
|
||||
.with_item(
|
||||
form::select::Item::new("python", L10n::n("Python"))
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_item(form::select::Item::new("javascript", L10n::n("JavaScript")))
|
||||
.with_item(form::select::Item::new("go", L10n::n("Go")))
|
||||
.with_item(form::select::Item::new("typescript", L10n::n("TypeScript")))
|
||||
.with_multiple(true)
|
||||
.with_rows(Some(4))
|
||||
.with_help_text(L10n::t("help_technologies", &LOC)),
|
||||
),
|
||||
);
|
||||
|
||||
// Etiquetas flotantes: solo disponibles con el tema Bootsier.
|
||||
if global::SETTINGS.app.theme.eq_ignore_ascii_case("bootsier") {
|
||||
form = form.with_child(
|
||||
form::Fieldset::new()
|
||||
.with_legend(L10n::t("fieldset_floating", &LOC))
|
||||
.with_child(
|
||||
form::input::Field::text()
|
||||
.with_name("fl_name")
|
||||
.with_label(L10n::t("label_name", &LOC))
|
||||
.with_placeholder(L10n::t("placeholder_name", &LOC))
|
||||
.with_floating_label(true)
|
||||
.with_required(true),
|
||||
)
|
||||
.with_child(
|
||||
form::Textarea::new()
|
||||
.with_name("fl_comment")
|
||||
.with_label(L10n::t("label_comment", &LOC))
|
||||
.with_placeholder(L10n::t("placeholder_comment", &LOC))
|
||||
.with_floating_label(true),
|
||||
)
|
||||
.with_child(
|
||||
form::select::Field::new()
|
||||
.with_name("fl_country")
|
||||
.with_label(L10n::t("label_country", &LOC))
|
||||
.with_item(
|
||||
form::select::Item::new("", L10n::t("select_choose", &LOC))
|
||||
.with_selected(true),
|
||||
)
|
||||
.with_item(form::select::Item::new(
|
||||
"de",
|
||||
L10n::t("select_germany", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new("es", L10n::t("select_spain", &LOC)))
|
||||
.with_item(form::select::Item::new(
|
||||
"fr",
|
||||
L10n::t("select_france", &LOC),
|
||||
))
|
||||
.with_item(form::select::Item::new(
|
||||
"pt",
|
||||
L10n::t("select_portugal", &LOC),
|
||||
))
|
||||
.with_floating_label(true)
|
||||
.with_required(true),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
form
|
||||
// Campo oculto (form::Hidden).
|
||||
.with_child(
|
||||
form::Hidden::new()
|
||||
.with_name("origin")
|
||||
.with_value("form-lists"),
|
||||
)
|
||||
// Botones de acción.
|
||||
.with_child(
|
||||
Button::submit(L10n::t("btn_submit", &LOC)).with_prop(PropsOp::add_classes(
|
||||
classes::ButtonColor::solid(Color::Primary),
|
||||
)),
|
||||
)
|
||||
.with_child(
|
||||
Button::reset(L10n::t("btn_reset", &LOC)).with_prop(PropsOp::add_classes(
|
||||
classes::ButtonColor::outline(Color::Secondary),
|
||||
)),
|
||||
)
|
||||
.with_child(
|
||||
Button::plain(L10n::t("btn_cancel", &LOC))
|
||||
.with_prop(PropsOp::add_classes(classes::ButtonColor::link())),
|
||||
)
|
||||
}
|
||||
|
||||
#[pagetop::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
Application::prepare(&FormControls).run()?.await
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ title = Form controls
|
|||
slogan = Bootsier form components showcase
|
||||
block_selections = Checkboxes, switches and radio buttons
|
||||
block_text = Text fields, multiline and range
|
||||
block_lists = Select lists and floating labels
|
||||
block_lists = Selection lists
|
||||
block_lists_floating = Select lists and floating labels
|
||||
|
||||
fieldset_text = Text fields
|
||||
label_name = Full name
|
||||
|
|
@ -16,6 +17,8 @@ label_url = Website
|
|||
placeholder_url = https://example.com
|
||||
label_search = Search
|
||||
placeholder_search = Search term...
|
||||
help_name = Enter your full name as it appears on your ID.
|
||||
help_email = We will only use your email to send important notifications.
|
||||
|
||||
fieldset_textarea = Multiline text
|
||||
label_comment = Comment
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ title = Controles de formulario
|
|||
slogan = Componentes Bootsier para formularios
|
||||
block_selections = Casillas, interruptores y botones de opción
|
||||
block_text = Campos de texto, multilínea y rango
|
||||
block_lists = Listas de selección y etiquetas flotantes
|
||||
block_lists = Listas de selección
|
||||
block_lists_floating = Listas de selección y etiquetas flotantes
|
||||
|
||||
fieldset_text = Campos de texto
|
||||
label_name = Nombre completo
|
||||
|
|
@ -16,6 +17,8 @@ label_url = Sitio web
|
|||
placeholder_url = https://ejemplo.com
|
||||
label_search = Búsqueda
|
||||
placeholder_search = Término de búsqueda...
|
||||
help_name = Introduce tu nombre completo tal como aparece en tu documento de identidad.
|
||||
help_email = Solo usaremos tu correo para enviarte notificaciones importantes.
|
||||
|
||||
fieldset_textarea = Texto multilínea
|
||||
label_comment = Comentario
|
||||
|
|
|
|||
|
|
@ -80,10 +80,9 @@ impl Extension for SuperMenu {
|
|||
))
|
||||
.with_item(navbar::Item::nav(
|
||||
Nav::new()
|
||||
.with_classes(
|
||||
ClassesOp::Add,
|
||||
.with_prop(PropsOp::add_classes(
|
||||
classes::Margin::with(Side::Start, ScaleSize::Auto).to_class(),
|
||||
)
|
||||
))
|
||||
.with_item(nav::Item::link(L10n::t("menus_item_sign_up", &LOC), |cx| {
|
||||
cx.route("/auth/sign-up")
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -17,8 +17,5 @@ authors.workspace = true
|
|||
[dependencies]
|
||||
pagetop.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
pagetop-build.workspace = true
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@
|
|||
|
||||
</div>
|
||||
|
||||
## 🧭 Sobre PageTop
|
||||
## Sobre PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
||||
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
||||
configurables, basadas en HTML, CSS y JavaScript.
|
||||
|
||||
|
||||
## ⚡️ Guía rápida
|
||||
## Guía rápida
|
||||
|
||||
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
||||
|
||||
|
|
@ -44,11 +43,6 @@ impl Extension for MyApp {
|
|||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[pagetop::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
Application::prepare(&MyApp).run()?.await
|
||||
}
|
||||
```
|
||||
|
||||
Y **selecciona el tema en la configuración** de la aplicación:
|
||||
|
|
@ -67,10 +61,10 @@ use pagetop_aliner::Aliner;
|
|||
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||
Page::new(request)
|
||||
.with_theme(&Aliner)
|
||||
.add_child(
|
||||
.with_child(
|
||||
Block::new()
|
||||
.with_title(L10n::l("sample_title"))
|
||||
.add_child(Html::with(|cx| html! {
|
||||
.with_child(Html::with(|cx| html! {
|
||||
p { (L10n::l("sample_content").using(cx)) }
|
||||
})),
|
||||
)
|
||||
|
|
@ -78,15 +72,13 @@ async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|||
}
|
||||
```
|
||||
|
||||
|
||||
## 🚧 Advertencia
|
||||
## Advertencia
|
||||
|
||||
**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su
|
||||
ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos
|
||||
hasta que se libere la versión **1.0.0**.
|
||||
|
||||
|
||||
## 📜 Licencia
|
||||
## Licencia
|
||||
|
||||
El código está disponible bajo una doble licencia:
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
<h1>PageTop Aliner</h1>
|
||||
|
||||
<p>Tema para <strong>PageTop</strong> que muestra esquemáticamente la composición de las páginas HTML.</p>
|
||||
<p>Tema de <strong>PageTop</strong> que muestra esquemáticamente la composición de las páginas HTML.</p>
|
||||
|
||||
[](https://docs.rs/pagetop-aliner)
|
||||
[](https://crates.io/crates/pagetop-aliner)
|
||||
[](https://crates.io/crates/pagetop-aliner)
|
||||
[](https://git.cillero.es/manuelcillero/pagetop/src/branch/main/extensions/pagetop-aliner#licencia)
|
||||
|
||||
<br>
|
||||
</div>
|
||||
|
||||
## Sobre PageTop
|
||||
|
|
@ -19,8 +18,7 @@
|
|||
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
||||
configurables, basadas en HTML, CSS y JavaScript.
|
||||
|
||||
|
||||
# ⚡️ Guía rápida
|
||||
## Guía rápida
|
||||
|
||||
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
||||
|
||||
|
|
@ -46,11 +44,6 @@ impl Extension for MyApp {
|
|||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[pagetop::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
Application::prepare(&MyApp).run()?.await
|
||||
}
|
||||
```
|
||||
|
||||
Y **selecciona el tema en la configuración** de la aplicación:
|
||||
|
|
|
|||
|
|
@ -18,8 +18,5 @@ authors.workspace = true
|
|||
pagetop.workspace = true
|
||||
serde.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
pagetop-build.workspace = true
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@
|
|||
|
||||
</div>
|
||||
|
||||
## 🧭 Sobre PageTop
|
||||
## Sobre PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) es un entorno de desarrollo que reivindica la esencia de la web
|
||||
clásica para crear soluciones web SSR (*renderizadas en el servidor*) modulares, extensibles y
|
||||
configurables, basadas en HTML, CSS y JavaScript.
|
||||
|
||||
|
||||
## ⚡️ Guía rápida
|
||||
## Guía rápida
|
||||
|
||||
Igual que con otras extensiones, **añade la dependencia** a tu `Cargo.toml`:
|
||||
|
||||
|
|
@ -44,11 +43,6 @@ impl Extension for MyApp {
|
|||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[pagetop::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
Application::prepare(&MyApp).run()?.await
|
||||
}
|
||||
```
|
||||
|
||||
Y **selecciona el tema en la configuración** de la aplicación:
|
||||
|
|
@ -67,10 +61,10 @@ use pagetop_bootsier::Bootsier;
|
|||
async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
||||
Page::new(request)
|
||||
.with_theme(&Bootsier)
|
||||
.add_child(
|
||||
.with_child(
|
||||
Block::new()
|
||||
.with_title(L10n::l("sample_title"))
|
||||
.add_child(Html::with(|cx| html! {
|
||||
.with_child(Html::with(|cx| html! {
|
||||
p { (L10n::l("sample_content").using(cx)) }
|
||||
})),
|
||||
)
|
||||
|
|
@ -78,22 +72,19 @@ async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
|
|||
}
|
||||
```
|
||||
|
||||
|
||||
## 📚 Créditos
|
||||
## Créditos
|
||||
|
||||
Este *crate* integra la biblioteca de estilos [Bootstrap 5.3.8](https://getbootstrap.com/) para
|
||||
definir el comportamiento, la apariencia y los componentes de la interfaz. Bootstrap se distribuye
|
||||
bajo licencia [MIT](https://github.com/twbs/bootstrap/blob/main/LICENSE).
|
||||
|
||||
|
||||
## 🚧 Advertencia
|
||||
## Advertencia
|
||||
|
||||
**PageTop** es un proyecto personal para aprender [Rust](https://www.rust-lang.org/es) y conocer su
|
||||
ecosistema. Su API está sujeta a cambios frecuentes. No se recomienda su uso en producción, al menos
|
||||
hasta que se libere la versión **1.0.0**.
|
||||
|
||||
|
||||
## 📜 Licencia
|
||||
## Licencia
|
||||
|
||||
El código está disponible bajo una doble licencia:
|
||||
|
||||
|
|
|
|||
84
extensions/pagetop-bootsier/assets/_bootsier-custom.scss
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Bootsier CSS rules: self-hosted fonts, form components, and regions.
|
||||
|
||||
// Self-hosted Source Sans 3 (SIL OFL 1.1), served from /bootsier/fonts.
|
||||
// Required by AdminLTE 4, which declares it as the primary font family in $font-family-sans-serif.
|
||||
@font-face {
|
||||
font-family: "Source Sans 3";
|
||||
src: url("/bootsier/fonts/bootsier.font.woff2") format("woff2");
|
||||
font-weight: 200 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Source Sans 3";
|
||||
src: url("/bootsier/fonts/bootsier.font.italic.woff2") format("woff2");
|
||||
font-weight: 200 900;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// Font-relative top offset to keep the skip-link hidden at any font size.
|
||||
.skip-link {
|
||||
top: -3em;
|
||||
}
|
||||
|
||||
// Required field indicator in forms.
|
||||
.form-required {
|
||||
color: var(--bs-danger);
|
||||
margin: 0 0.25rem;
|
||||
}
|
||||
|
||||
// Form field with consistent bottom margin.
|
||||
.form-field {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Fieldset with border and floating legend.
|
||||
fieldset {
|
||||
position: relative;
|
||||
background-color: var(--bs-body-bg);
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
padding: 2rem 1rem 1rem;
|
||||
margin: 2rem 0 1rem;
|
||||
}
|
||||
|
||||
fieldset > legend {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 1rem;
|
||||
transform: translateY(-50%);
|
||||
color: var(--bs-secondary-color);
|
||||
background-color: var(--bs-body-bg);
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
padding: 0.125rem 0.75rem;
|
||||
font-size: ($font-size-sm + $font-size-base) / 2;
|
||||
font-weight: var(--bs-font-weight-normal);
|
||||
line-height: 1.25;
|
||||
width: fit-content;
|
||||
max-width: 75%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.fieldset-description {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
// Gap between group label and first inline check.
|
||||
.form-label + .form-check-inline {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
// Footer region.
|
||||
.region-footer {
|
||||
padding: 0.75rem 0 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
5
extensions/pagetop-bootsier/assets/_bootsier-icons.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Bootstrap Icons v1.13.1, fonts served from /bootsier/fonts.
|
||||
|
||||
$bootstrap-icons-font: "bootsier.icons";
|
||||
$bootstrap-icons-font-dir: "/bootsier/fonts";
|
||||
@import "bootstrap-icons-1.13.1/bootstrap-icons";
|
||||
|
|
@ -1,80 +1,14 @@
|
|||
// Enable CSS Grid
|
||||
// Bootstrap utility extensions. Imported just before utilities/api so variable changes take effect.
|
||||
|
||||
// CSS Grid (Bootstrap 5): disable legacy grid classes and enable native CSS Grid.
|
||||
$enable-grid-classes: false;
|
||||
$enable-cssgrid: true;
|
||||
|
||||
// Opacity
|
||||
.bg-opacity-0 {
|
||||
--bs-bg-opacity: 0;
|
||||
}
|
||||
|
||||
.border-opacity-0 {
|
||||
--bs-border-opacity: 0;
|
||||
}
|
||||
|
||||
.text-opacity-0 {
|
||||
--bs-text-opacity: 0;
|
||||
}
|
||||
.text-opacity-10 {
|
||||
--bs-text-opacity: 0.1;
|
||||
}
|
||||
|
||||
// FORMS
|
||||
|
||||
// Required field indicator
|
||||
.form-required {
|
||||
color: var(--bs-danger);
|
||||
margin: 0 0.25rem;
|
||||
}
|
||||
|
||||
// Form fields
|
||||
.form-field {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Fieldset
|
||||
fieldset {
|
||||
position: relative;
|
||||
background-color: var(--bs-body-bg);
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
padding: 2rem 1rem 1rem;
|
||||
margin: 2rem 0 1rem;
|
||||
}
|
||||
fieldset > legend {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 1rem;
|
||||
transform: translateY(-50%);
|
||||
background-color: var(--bs-body-bg);
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
padding: 0.125rem 0.75rem;
|
||||
font-size: $font-size-sm;
|
||||
line-height: 1.25;
|
||||
width: fit-content;
|
||||
max-width: 75%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.fieldset-description {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
// Check buttons, gap between label and first inline check
|
||||
.form-label + .form-check-inline {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
// Extending utilities
|
||||
// Extend the $utilities map with additional classes.
|
||||
$utilities: map-merge(
|
||||
$utilities,
|
||||
(
|
||||
// Individual border widths
|
||||
// Individual border widths per side.
|
||||
"border-top": (
|
||||
property: border-top-width,
|
||||
class: border-top,
|
||||
|
|
@ -95,7 +29,7 @@ $utilities: map-merge(
|
|||
class: border-start,
|
||||
values: $border-widths
|
||||
),
|
||||
// Individual rounded values
|
||||
// Individual corner radii.
|
||||
"rounded-top-start": (
|
||||
property: border-top-left-radius,
|
||||
class: rounded-top-start,
|
||||
|
|
@ -156,11 +90,18 @@ $utilities: map-merge(
|
|||
pill: var(--#{$prefix}border-radius-pill)
|
||||
)
|
||||
),
|
||||
// Opacity: add missing values (0 for bg/border/text; 10 for text) not in Bootstrap defaults.
|
||||
"bg-opacity": map-merge(
|
||||
map-get($utilities, "bg-opacity"),
|
||||
(values: map-merge(map-get(map-get($utilities, "bg-opacity"), "values"), (0: 0)))
|
||||
),
|
||||
"border-opacity": map-merge(
|
||||
map-get($utilities, "border-opacity"),
|
||||
(values: map-merge(map-get(map-get($utilities, "border-opacity"), "values"), (0: 0)))
|
||||
),
|
||||
"text-opacity": map-merge(
|
||||
map-get($utilities, "text-opacity"),
|
||||
(values: map-merge(map-get(map-get($utilities, "text-opacity"), "values"), (0: 0, 10: .1)))
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Region Footer
|
||||
.region-footer {
|
||||
padding: .75rem 0 3rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Bootsier overrides for Bootstrap variables. Imported before bootstrap/scss/variables
|
||||
// so that Bootstrap's !default declarations do not override these values.
|
||||
|
||||
$font-size-base: 1.125rem;
|
||||
1081
extensions/pagetop-bootsier/assets/adminlte-4.0.0/js/adminlte.js
Normal file
7
extensions/pagetop-bootsier/assets/adminlte-4.0.0/js/adminlte.min.js
vendored
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/* ==========================================================================
|
||||
AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
|
||||
========================================================================== */
|
||||
|
||||
/* Skip Links - WCAG 2.4.1: Bypass Blocks */
|
||||
.skip-link {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 6px;
|
||||
z-index: 999999;
|
||||
padding: 8px 16px;
|
||||
font-weight: 600;
|
||||
color: var(--bs-white);
|
||||
text-decoration: none;
|
||||
background: var(--bs-primary);
|
||||
|
||||
&:focus {
|
||||
top: 0;
|
||||
outline: 3px solid var(--bs-warning);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--bs-white);
|
||||
text-decoration: none;
|
||||
background: var(--bs-primary-emphasis);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced Focus Indicators - WCAG 2.4.7: Focus Visible */
|
||||
.focus-enhanced {
|
||||
&:focus {
|
||||
outline: 3px solid var(--bs-focus-ring-color, #0d6efd);
|
||||
outline-offset: 2px;
|
||||
box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
|
||||
}
|
||||
}
|
||||
|
||||
/* High Contrast Mode Support */
|
||||
@media (prefers-contrast: high) {
|
||||
.card {
|
||||
border: 2px solid;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-color: currentcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reduced Motion Support - WCAG 2.3.3: Animation from Interactions */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
transition-duration: .01ms !important;
|
||||
animation-duration: .01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
|
||||
.fade {
|
||||
opacity: 1 !important;
|
||||
/* stylelint-disable-next-line property-disallowed-list */
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
/* stylelint-disable-next-line property-disallowed-list */
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.modal.fade .modal-dialog {
|
||||
transform: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Screen Reader Only Content */
|
||||
.sr-only {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
padding: 0 !important;
|
||||
margin: -1px !important;
|
||||
overflow: hidden !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.sr-only-focusable:focus {
|
||||
position: static !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
padding: inherit !important;
|
||||
margin: inherit !important;
|
||||
overflow: visible !important;
|
||||
clip: auto !important;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
/* Focus Trap Utilities */
|
||||
.focus-trap {
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessible Color Combinations - WCAG 1.4.3: Contrast (Minimum) */
|
||||
.text-accessible-primary {
|
||||
color: #003d82; /* 4.5:1 contrast on white */
|
||||
}
|
||||
|
||||
.text-accessible-success {
|
||||
color: #0f5132; /* 4.5:1 contrast on white */
|
||||
}
|
||||
|
||||
.text-accessible-danger {
|
||||
color: #842029; /* 4.5:1 contrast on white */
|
||||
}
|
||||
|
||||
.text-accessible-warning {
|
||||
color: #664d03; /* 4.5:1 contrast on white */
|
||||
}
|
||||
|
||||
/* ARIA Live Regions */
|
||||
.live-region {
|
||||
position: absolute;
|
||||
left: -10000px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
|
||||
&.live-region-visible {
|
||||
position: static;
|
||||
left: auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced Error States - WCAG 3.3.1: Error Identification */
|
||||
.form-control.is-invalid {
|
||||
border-color: var(--bs-danger);
|
||||
|
||||
&:focus {
|
||||
border-color: var(--bs-danger);
|
||||
box-shadow: 0 0 0 .25rem rgba(220, 53, 69, .25);
|
||||
}
|
||||
}
|
||||
|
||||
.invalid-feedback {
|
||||
&[role="alert"] {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
/* Target Size - WCAG 2.5.8: Target Size (Minimum) */
|
||||
.touch-target {
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
|
||||
&.touch-target-small {
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Table Accessibility */
|
||||
.table-accessible {
|
||||
th {
|
||||
font-weight: 600;
|
||||
background-color: var(--bs-secondary-bg);
|
||||
|
||||
&[scope="col"] {
|
||||
border-bottom: 2px solid var(--bs-border-color);
|
||||
}
|
||||
|
||||
&[scope="row"] {
|
||||
border-right: 2px solid var(--bs-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
caption {
|
||||
padding: .75rem;
|
||||
font-weight: 600;
|
||||
color: var(--bs-secondary);
|
||||
text-align: left;
|
||||
caption-side: top;
|
||||
}
|
||||
}
|
||||
|
||||
/* Navigation Landmarks */
|
||||
nav[role="navigation"] {
|
||||
&:not([aria-label]):not([aria-labelledby]) {
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -10000px;
|
||||
content: "Navigation";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Form Fieldset Styling */
|
||||
fieldset {
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid var(--bs-border-color);
|
||||
|
||||
legend {
|
||||
padding: 0 .5rem;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading States */
|
||||
.loading[aria-busy="true"] {
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
margin-left: -10px;
|
||||
content: "";
|
||||
border: 2px solid var(--bs-primary);
|
||||
border-top-color: transparent;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
&::after {
|
||||
border-top-color: var(--bs-primary);
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark Mode Accessibility */
|
||||
[data-bs-theme="dark"] {
|
||||
.text-accessible-primary {
|
||||
color: #6ea8fe;
|
||||
}
|
||||
|
||||
.text-accessible-success {
|
||||
color: #75b798;
|
||||
}
|
||||
|
||||
.text-accessible-danger {
|
||||
color: #f1aeb5;
|
||||
}
|
||||
|
||||
.text-accessible-warning {
|
||||
color: #ffda6a;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Accessibility */
|
||||
@media print {
|
||||
.skip-link,
|
||||
.btn,
|
||||
.nav-link {
|
||||
color: #000 !important;
|
||||
background: transparent !important;
|
||||
border: 1px solid #000 !important;
|
||||
}
|
||||
|
||||
a[href^="http"]::after {
|
||||
font-size: .8em;
|
||||
content: " (" attr(href) ")";
|
||||
}
|
||||
|
||||
/* Print Layout Fix - Ensure sidebar and main content are both visible */
|
||||
.app-wrapper {
|
||||
display: grid !important;
|
||||
grid-template-rows: auto 1fr auto !important;
|
||||
grid-template-columns: auto 1fr !important;
|
||||
}
|
||||
|
||||
.sidebar-overlay {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.app-sidebar {
|
||||
position: static !important;
|
||||
display: block !important;
|
||||
min-width: 200px !important;
|
||||
max-width: 200px !important;
|
||||
max-height: none !important;
|
||||
margin-left: 0 !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.app-header {
|
||||
position: static !important;
|
||||
}
|
||||
|
||||
.app-main {
|
||||
width: auto !important;
|
||||
max-width: 100% !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.app-content {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.app-footer {
|
||||
position: static !important;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.app-content {
|
||||
padding: $lte-content-padding-y $lte-content-padding-x;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// Core: Main Footer
|
||||
//
|
||||
|
||||
.app-footer {
|
||||
grid-area: #{$lte-prefix}app-footer;
|
||||
width: inherit;
|
||||
max-width: 100vw;
|
||||
min-height: 3rem;
|
||||
padding: $lte-app-footer-padding;
|
||||
color: $lte-app-footer-color;
|
||||
background-color: $lte-app-footer-bg;
|
||||
border-top: $lte-app-footer-border-top;
|
||||
@include transition($lte-transition-speed $lte-transition-fn);
|
||||
}
|
||||
|
||||
.fixed-footer {
|
||||
.app-footer {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: $lte-zindex-fixed-footer;
|
||||
}
|
||||
|
||||
// When layout-fixed is used, app-main has overflow: auto which prevents
|
||||
// position: sticky from working on the footer. Ensure the grid keeps the
|
||||
// footer pinned at the bottom while app-main scrolls independently.
|
||||
&.layout-fixed {
|
||||
.app-main {
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Core: Main Header
|
||||
//
|
||||
|
||||
.app-header {
|
||||
z-index: $lte-zindex-app-header;
|
||||
grid-area: #{$lte-prefix}app-header;
|
||||
max-width: 100vw;
|
||||
border-bottom: $lte-app-header-bottom-border;
|
||||
@include transition($lte-transition-speed $lte-transition-fn);
|
||||
|
||||
.nav-link {
|
||||
position: relative;
|
||||
height: $nav-link-height;
|
||||
}
|
||||
}
|
||||
|
||||
// Navbar badge
|
||||
.navbar-badge {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 5px;
|
||||
padding: 2px 4px;
|
||||
font-size: .6rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.fixed-header {
|
||||
.app-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: $lte-zindex-fixed-header;
|
||||
}
|
||||
|
||||
// Fixes #6020: when only `fixed-header` is used (without `layout-fixed`),
|
||||
// the sidebar — including its branding — used to scroll with the page
|
||||
// because nothing made it sticky. Pin the sidebar so the brand and menu
|
||||
// stay visible while the page content scrolls beneath the fixed header.
|
||||
// Only applied on `sidebar-expand-*` breakpoints, since the mobile sidebar
|
||||
// is an off-canvas overlay that handles its own positioning.
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
$next: breakpoint-next($breakpoint, $grid-breakpoints);
|
||||
$infix: breakpoint-infix($next, $grid-breakpoints);
|
||||
|
||||
&.sidebar-expand#{$infix} {
|
||||
@include media-breakpoint-up($next) {
|
||||
.app-sidebar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
max-height: 100vh;
|
||||
|
||||
.sidebar-wrapper {
|
||||
height: subtract(100vh, add($lte-app-header-height, 1px));
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
.app-main {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-area: #{$lte-prefix}app-main;
|
||||
max-width: 100vw;
|
||||
padding-bottom: $lte-app-main-padding-bottom;
|
||||
@include transition($lte-transition-speed $lte-transition-fn);
|
||||
|
||||
.app-content-header {
|
||||
padding: 1rem $lte-content-padding-x;
|
||||
|
||||
.breadcrumb {
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
line-height: 2.5rem;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-content-top-area,
|
||||
.app-content-bottom-area {
|
||||
color: $lte-app-content-bottom-area-color;
|
||||
background-color: $lte-app-content-bottom-area-bg;
|
||||
}
|
||||
|
||||
.app-content-top-area {
|
||||
padding: $lte-app-content-top-area-padding-y $lte-app-content-top-area-padding-x;
|
||||
border-bottom: $lte-app-content-top-area-top-border;
|
||||
}
|
||||
|
||||
.app-content-bottom-area {
|
||||
padding: $lte-app-content-bottom-area-padding-y $lte-app-content-bottom-area-padding-x;
|
||||
margin-top: auto;
|
||||
margin-bottom: $lte-app-content-bottom-area-margin-bottom;
|
||||
border-top: $lte-app-content-bottom-area-top-border;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,619 @@
|
|||
.app-sidebar {
|
||||
--#{$lte-prefix}sidebar-hover-bg: #{$lte-sidebar-hover-bg};
|
||||
--#{$lte-prefix}sidebar-color: #{$lte-sidebar-color};
|
||||
--#{$lte-prefix}sidebar-hover-color: #{$lte-sidebar-hover-color};
|
||||
--#{$lte-prefix}sidebar-active-color: #{$lte-sidebar-active-color};
|
||||
--#{$lte-prefix}sidebar-menu-active-bg: #{$lte-sidebar-menu-active-bg};
|
||||
--#{$lte-prefix}sidebar-menu-active-color: #{$lte-sidebar-menu-active-color};
|
||||
--#{$lte-prefix}sidebar-submenu-bg: #{$lte-sidebar-submenu-bg};
|
||||
--#{$lte-prefix}sidebar-submenu-color: #{$lte-sidebar-submenu-color};
|
||||
--#{$lte-prefix}sidebar-submenu-hover-color: #{$lte-sidebar-submenu-hover-color};
|
||||
--#{$lte-prefix}sidebar-submenu-hover-bg: #{$lte-sidebar-submenu-hover-bg};
|
||||
--#{$lte-prefix}sidebar-submenu-active-color: #{$lte-sidebar-submenu-active-color};
|
||||
--#{$lte-prefix}sidebar-submenu-active-bg: #{$lte-sidebar-submenu-active-bg};
|
||||
--#{$lte-prefix}sidebar-header-color: #{$lte-sidebar-header-color};
|
||||
|
||||
z-index: $lte-zindex-sidebar;
|
||||
grid-area: #{$lte-prefix}app-sidebar;
|
||||
min-width: var(--#{$lte-prefix}sidebar-width);
|
||||
max-width: var(--#{$lte-prefix}sidebar-width);
|
||||
@include transition($lte-sidebar-transition);
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: $lte-app-header-height;
|
||||
padding: $lte-brand-link-padding-y $lte-brand-link-padding-x;
|
||||
overflow: hidden;
|
||||
font-size: $navbar-brand-font-size;
|
||||
white-space: nowrap;
|
||||
border-bottom: $lte-brand-link-border-buttom solid var(--#{$prefix}border-color);
|
||||
@include transition(width $lte-transition-speed $lte-transition-fn);
|
||||
|
||||
.brand-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
|
||||
.brand-image {
|
||||
float: left;
|
||||
width: auto;
|
||||
max-height: 33px;
|
||||
line-height: .8;
|
||||
}
|
||||
|
||||
.brand-image-xs {
|
||||
float: left;
|
||||
width: auto;
|
||||
max-height: 33px;
|
||||
margin-top: -.1rem;
|
||||
line-height: .8;
|
||||
}
|
||||
|
||||
.brand-image-xl {
|
||||
width: auto;
|
||||
max-height: 40px;
|
||||
line-height: .8;
|
||||
|
||||
&.single {
|
||||
margin-top: -.3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.brand-text {
|
||||
margin-left: .5rem;
|
||||
color: rgba(var(--#{$prefix}emphasis-color-rgb), .8);
|
||||
@include transition(flex $lte-transition-speed $lte-transition-fn, width $lte-transition-speed $lte-transition-fn);
|
||||
&:hover {
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
padding-top: $lte-sidebar-padding-y;
|
||||
padding-right: $lte-sidebar-padding-x;
|
||||
padding-bottom: $lte-sidebar-padding-y;
|
||||
padding-left: $lte-sidebar-padding-x;
|
||||
overscroll-behavior: contain;
|
||||
@include scrollbar-color-gray();
|
||||
@include scrollbar-width-thin();
|
||||
|
||||
.nav-item {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
|
||||
p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.nav-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 1.5rem;
|
||||
max-width: 1.5rem;
|
||||
}
|
||||
|
||||
// Sidebar Menu. First level links
|
||||
.sidebar-menu > .nav-item {
|
||||
// links
|
||||
> .nav-link {
|
||||
color: var(--#{$lte-prefix}sidebar-color);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: var(--#{$lte-prefix}sidebar-hover-color);
|
||||
background-color: var(--#{$lte-prefix}sidebar-hover-bg);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--#{$lte-prefix}sidebar-menu-active-color);
|
||||
background-color: var(--#{$lte-prefix}sidebar-menu-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// Open state
|
||||
&.menu-open > .nav-link {
|
||||
color: var(--#{$lte-prefix}sidebar-hover-color);
|
||||
background-color: var(--#{$lte-prefix}sidebar-hover-bg);
|
||||
|
||||
&.active {
|
||||
color: var(--#{$lte-prefix}sidebar-menu-active-color);
|
||||
background-color: var(--#{$lte-prefix}sidebar-menu-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// First Level Submenu
|
||||
> .nav-treeview {
|
||||
background-color: var(--#{$lte-prefix}sidebar-submenu-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// Section Heading
|
||||
.nav-header {
|
||||
display: inline;
|
||||
overflow: hidden;
|
||||
color: var(--#{$lte-prefix}sidebar-header-color);
|
||||
text-overflow: ellipsis;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
// All links within the sidebar menu
|
||||
a {
|
||||
color: var(--#{$lte-prefix}sidebar-color);
|
||||
}
|
||||
|
||||
// All submenus
|
||||
.nav-treeview {
|
||||
> .nav-item {
|
||||
> .nav-link {
|
||||
color: var(--#{$lte-prefix}sidebar-submenu-color);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: var(--#{$lte-prefix}sidebar-submenu-hover-color);
|
||||
background-color: var(--#{$lte-prefix}sidebar-submenu-hover-bg);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--#{$lte-prefix}sidebar-submenu-active-color);
|
||||
background-color: var(--#{$lte-prefix}sidebar-submenu-active-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar navigation menu
|
||||
.sidebar-menu {
|
||||
// All levels
|
||||
.nav-item {
|
||||
> .nav-link {
|
||||
margin-bottom: .2rem;
|
||||
|
||||
.nav-arrow {
|
||||
@include transition(transform $lte-transition-fn $lte-transition-speed);
|
||||
transform: translateY(-50%) #{"/*rtl:append:rotate(180deg)*/"};
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All levels
|
||||
.nav-link > .nav-badge,
|
||||
.nav-link > p > .nav-badge {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 1rem;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.nav-link > .nav-arrow,
|
||||
.nav-link > p > .nav-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@include transition(width $lte-transition-fn $lte-transition-speed);
|
||||
@include border-radius($border-radius);
|
||||
|
||||
p {
|
||||
display: inline;
|
||||
padding-left: .5rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: $nav-link-padding-y ($nav-link-padding-y * 1.5);
|
||||
font-size: .9rem;
|
||||
@include transition(width $lte-transition-fn $lte-transition-speed);
|
||||
}
|
||||
|
||||
// Tree view menu
|
||||
.nav-treeview {
|
||||
display: none;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu-open {
|
||||
> .nav-treeview {
|
||||
display: block;
|
||||
}
|
||||
|
||||
> .nav-link {
|
||||
.nav-arrow {
|
||||
transform: translateY(-50%) rotate(90deg) #{"/*rtl:ignore*/"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override: ensure badges/arrows are aligned to the end (right in LTR, left in RTL)
|
||||
.nav-link > .nav-badge,
|
||||
.nav-link > p > .nav-badge,
|
||||
.nav-link > .nav-arrow,
|
||||
.nav-link > p > .nav-arrow {
|
||||
right: 1rem !important; // place at end in LTR
|
||||
left: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-indent {
|
||||
.nav-treeview {
|
||||
padding-left: $lte-sidebar-padding-x;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-compact.nav-indent {
|
||||
.nav-treeview {
|
||||
padding-left: 0;
|
||||
|
||||
.nav-item {
|
||||
padding-left: $lte-sidebar-padding-x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-mini.sidebar-collapse.nav-indent {
|
||||
.app-sidebar:hover {
|
||||
.nav-treeview {
|
||||
padding-left: 0;
|
||||
|
||||
.nav-item {
|
||||
padding-left: $lte-sidebar-padding-x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-collapse {
|
||||
&.nav-compact.nav-indent {
|
||||
.nav-treeview {
|
||||
.nav-item {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-compact .nav-link {
|
||||
@include border-radius(0);
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
// A fix for text overflow while transitioning from sidebar mini to full sidebar
|
||||
.sidebar-menu,
|
||||
.sidebar-menu > .nav-header,
|
||||
.sidebar-menu .nav-link {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Logo style
|
||||
.logo-xs,
|
||||
.logo-xl {
|
||||
position: absolute;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
|
||||
&.brand-image-xs {
|
||||
top: 12px;
|
||||
left: 18px;
|
||||
}
|
||||
|
||||
&.brand-image-xl {
|
||||
top: 6px;
|
||||
left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-xs {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
|
||||
&.brand-image-xl {
|
||||
top: 8px;
|
||||
left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-link {
|
||||
&.logo-switch {
|
||||
&::before {
|
||||
content: "\00a0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-mini.sidebar-collapse {
|
||||
.app-sidebar {
|
||||
min-width: $lte-sidebar-mini-width;
|
||||
max-width: $lte-sidebar-mini-width;
|
||||
}
|
||||
|
||||
// Make the sidebar headers
|
||||
.sidebar-menu .nav-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar-menu {
|
||||
.nav-link {
|
||||
width: $lte-sidebar-mini-width - $lte-sidebar-padding-x * 2;
|
||||
|
||||
p {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.nav-badge,
|
||||
.nav-arrow {
|
||||
display: none;
|
||||
animation-name: fadeOut;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
}
|
||||
|
||||
.brand-text {
|
||||
display: inline-block;
|
||||
max-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-menu .nav-link p,
|
||||
.brand-text,
|
||||
.logo-xl,
|
||||
.nav-arrow {
|
||||
visibility: hidden;
|
||||
animation-name: fadeOut;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
|
||||
.logo-xs {
|
||||
display: inline-block;
|
||||
visibility: visible;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
&:not(.sidebar-without-hover) {
|
||||
.app-sidebar:hover {
|
||||
min-width: var(--#{$lte-prefix}sidebar-width);
|
||||
max-width: var(--#{$lte-prefix}sidebar-width);
|
||||
|
||||
.sidebar-menu .nav-header {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar-menu .nav-link {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.sidebar-menu .nav-link p,
|
||||
.brand-text,
|
||||
.logo-xl {
|
||||
width: auto;
|
||||
margin-left: 0;
|
||||
visibility: visible;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.brand-text {
|
||||
display: inline;
|
||||
max-width: inherit;
|
||||
margin-left: .5rem;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.nav-badge,
|
||||
.nav-arrow {
|
||||
display: inline-block;
|
||||
visibility: visible;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
animation-delay: $lte-transition-speed;
|
||||
}
|
||||
|
||||
.nav-link p {
|
||||
padding-left: .5rem;
|
||||
}
|
||||
|
||||
.logo-xs {
|
||||
visibility: hidden;
|
||||
animation-name: fadeOut;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-collapse:not(.sidebar-mini) {
|
||||
.app-sidebar {
|
||||
margin-left: calc(var(--#{$lte-prefix}sidebar-width) * -1); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-expand {
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
$next: breakpoint-next($breakpoint, $grid-breakpoints);
|
||||
$infix: breakpoint-infix($next, $grid-breakpoints);
|
||||
|
||||
/* stylelint-disable-next-line scss/selector-no-union-class-name */
|
||||
&#{$infix} {
|
||||
@include media-breakpoint-up($next) {
|
||||
&.layout-fixed {
|
||||
.app-main-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.app-sidebar-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
.app-main {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
}
|
||||
.app-sidebar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
max-height: 100vh;
|
||||
|
||||
.sidebar-wrapper {
|
||||
height: subtract(100vh, add($lte-app-header-height, 1px));
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.sidebar-open {
|
||||
.nav-link > .nav-badge,
|
||||
.nav-link > p > .nav-badge {
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
animation-delay: $lte-transition-speed;
|
||||
}
|
||||
.nav-link > .nav-arrow,
|
||||
.nav-link > p > .nav-arrow {
|
||||
animation-name: fadeIn;
|
||||
animation-duration: $lte-transition-speed;
|
||||
animation-fill-mode: both;
|
||||
animation-delay: $lte-transition-speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down($next) {
|
||||
$max: breakpoint-max($next);
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
content: "#{$max}";
|
||||
}
|
||||
|
||||
.app-sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
max-height: 100vh;
|
||||
margin-left: calc(var(--#{$lte-prefix}sidebar-width) * -1); // stylelint-disable-line function-disallowed-list
|
||||
|
||||
.sidebar-wrapper {
|
||||
height: subtract(100vh, add($lte-app-header-height, 1px));
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.sidebar-open {
|
||||
.app-sidebar {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.sidebar-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: $lte-zindex-sidebar-overlay;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
visibility: visible;
|
||||
background-color: rgba(0, 0, 0, .2);
|
||||
animation-name: fadeIn;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-menu .nav-link p,
|
||||
.app-sidebar .brand-text,
|
||||
.app-sidebar .logo-xs,
|
||||
.app-sidebar .logo-xl {
|
||||
@include transition(margin-left $lte-transition-speed linear, opacity $lte-transition-speed ease, visibility $lte-transition-speed ease);
|
||||
}
|
||||
|
||||
// To prevent onload transition and animation
|
||||
.app-loaded {
|
||||
&.sidebar-mini.sidebar-collapse {
|
||||
.sidebar-menu .nav-link p,
|
||||
.brand-text {
|
||||
animation-duration: $lte-transition-speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
body:not(.app-loaded) {
|
||||
.app-header,
|
||||
.app-sidebar,
|
||||
.app-main,
|
||||
.app-footer {
|
||||
@include transition(none !important);
|
||||
animation-duration: 0s !important;
|
||||
}
|
||||
}
|
||||
.hold-transition {
|
||||
.app-header,
|
||||
.app-sidebar,
|
||||
.app-main,
|
||||
.app-footer,
|
||||
.nav-arrow,
|
||||
.nav-badge {
|
||||
@include transition(none !important);
|
||||
animation-duration: 0s !important;
|
||||
}
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
&.app-sidebar,
|
||||
.app-sidebar {
|
||||
--#{$lte-prefix}sidebar-hover-bg: #{$lte-sidebar-hover-bg-dark};
|
||||
--#{$lte-prefix}sidebar-color: #{$lte-sidebar-color-dark};
|
||||
--#{$lte-prefix}sidebar-hover-color: #{$lte-sidebar-hover-color-dark};
|
||||
--#{$lte-prefix}sidebar-active-color: #{$lte-sidebar-active-color-dark};
|
||||
--#{$lte-prefix}sidebar-menu-active-bg: #{$lte-sidebar-menu-active-bg-dark};
|
||||
--#{$lte-prefix}sidebar-menu-active-color: #{$lte-sidebar-menu-active-color-dark};
|
||||
--#{$lte-prefix}sidebar-submenu-bg: #{$lte-sidebar-submenu-bg-dark};
|
||||
--#{$lte-prefix}sidebar-submenu-color: #{$lte-sidebar-submenu-color-dark};
|
||||
--#{$lte-prefix}sidebar-submenu-hover-color: #{$lte-sidebar-submenu-hover-color-dark};
|
||||
--#{$lte-prefix}sidebar-submenu-hover-bg: #{$lte-sidebar-submenu-hover-bg-dark};
|
||||
--#{$lte-prefix}sidebar-submenu-active-color: #{$lte-sidebar-submenu-active-color-dark};
|
||||
--#{$lte-prefix}sidebar-submenu-active-bg: #{$lte-sidebar-submenu-active-bg-dark};
|
||||
--#{$lte-prefix}sidebar-header-color: #{$lte-sidebar-header-color-dark};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// Core: Layout
|
||||
//
|
||||
|
||||
.app-wrapper {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"#{$lte-prefix}app-sidebar #{$lte-prefix}app-header"
|
||||
"#{$lte-prefix}app-sidebar #{$lte-prefix}app-main"
|
||||
"#{$lte-prefix}app-sidebar #{$lte-prefix}app-footer";
|
||||
grid-template-rows: min-content 1fr min-content;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-gap: 0;
|
||||
align-content: stretch;
|
||||
align-items: stretch;
|
||||
max-width: 100vw;
|
||||
min-height: 100vh;
|
||||
|
||||
> * {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// Callouts
|
||||
//
|
||||
|
||||
.callout {
|
||||
--#{$prefix}link-color-rgb: var(--#{$lte-prefix}callout-link);
|
||||
--#{$prefix}code-color: var(--#{$lte-prefix}callout-code-color);
|
||||
|
||||
padding: 1.25rem;
|
||||
color: var(--#{$lte-prefix}callout-color, inherit);
|
||||
background-color: var(--#{$lte-prefix}callout-bg, var(--bs-gray-100));
|
||||
border-left: .25rem solid var(--#{$lte-prefix}callout-border, var(--bs-gray-300));
|
||||
|
||||
.callout-link {
|
||||
font-weight: $lte-callout-link-font-weight;
|
||||
color: var(--#{$prefix}callout-link-color);
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
+ .callout {
|
||||
margin-top: -.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Variations
|
||||
@each $name, $color in $theme-colors {
|
||||
.callout-#{$name} {
|
||||
--#{$lte-prefix}callout-color: var(--#{$prefix}#{$name}-text-emphasis);
|
||||
--#{$lte-prefix}callout-bg: var(--#{$prefix}#{$name}-bg-subtle);
|
||||
--#{$lte-prefix}callout-border: var(--#{$prefix}#{$name}-border-subtle);
|
||||
--#{$prefix}callout-link-color: var(--#{$prefix}#{$name}-text-emphasis);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
//
|
||||
// Component: Cards
|
||||
//
|
||||
|
||||
// Color variants
|
||||
.card {
|
||||
@include box-shadow($lte-card-shadow);
|
||||
|
||||
&[class*="card-"]:not(.card-outline),
|
||||
&[class*="text-bg-"]:not(.card-outline) {
|
||||
> .card-header {
|
||||
color: var(--#{$lte-prefix}card-variant-color);
|
||||
background-color: var(--#{$lte-prefix}card-variant-bg);
|
||||
|
||||
.btn-tool {
|
||||
--#{$prefix}btn-color: rgba(var(--#{$lte-prefix}card-variant-color-rgb), .8);
|
||||
--#{$prefix}btn-hover-color: var(--#{$lte-prefix}card-variant-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.card-outline {
|
||||
border-top: 3px solid var(--#{$lte-prefix}card-variant-bg);
|
||||
}
|
||||
|
||||
&.maximized-card {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $zindex-modal-backdrop;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: 100% !important;
|
||||
max-height: 100% !important;
|
||||
|
||||
&.was-collapsed .card-body {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
[data-lte-toggle="card-collapse"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-lte-icon="maximize"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card-header,
|
||||
.card-footer {
|
||||
@include border-radius(0 !important);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.maximized-card) {
|
||||
[data-lte-icon="minimize"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// collapsed mode
|
||||
&.collapsed-card {
|
||||
// Use > .card-header to scope to direct card only, not nested cards
|
||||
> .card-header [data-lte-icon="collapse"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> .card-body,
|
||||
> .card-footer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.collapsed-card) {
|
||||
// Use > .card-header to scope to direct card only, not nested cards
|
||||
> .card-header [data-lte-icon="expand"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.nav.flex-column {
|
||||
> li {
|
||||
margin: 0;
|
||||
border-bottom: 1px solid $card-border-color;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fixed height to 300px
|
||||
&.height-control {
|
||||
.card-body {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.border-end {
|
||||
border-right: 1px solid $card-border-color;
|
||||
}
|
||||
|
||||
.border-start {
|
||||
border-left: 1px solid $card-border-color;
|
||||
}
|
||||
|
||||
&.card-tabs {
|
||||
&:not(.card-outline) {
|
||||
> .card-header {
|
||||
border-bottom: 0;
|
||||
|
||||
.nav-item {
|
||||
&:first-child .nav-link {
|
||||
border-left-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.card-outline {
|
||||
.nav-item {
|
||||
border-bottom: 0;
|
||||
|
||||
&:first-child .nav-link {
|
||||
margin-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-tools {
|
||||
margin: .3rem .5rem;
|
||||
}
|
||||
|
||||
&:not(.expanding-card).collapsed-card {
|
||||
.card-header {
|
||||
border-bottom: 0;
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 0;
|
||||
|
||||
.nav-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.expanding-card {
|
||||
.card-header {
|
||||
.nav-tabs {
|
||||
.nav-item {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.card-outline-tabs {
|
||||
border-top: 0;
|
||||
|
||||
.card-header {
|
||||
.nav-item {
|
||||
&:first-child .nav-link {
|
||||
margin-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
border-top: 3px solid transparent;
|
||||
|
||||
&:hover {
|
||||
border-top: 3px solid $nav-tabs-border-color;
|
||||
}
|
||||
|
||||
&.active {
|
||||
&:hover {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-tools {
|
||||
margin: .5rem .5rem .3rem;
|
||||
}
|
||||
|
||||
&:not(.expanding-card).collapsed-card .card-header {
|
||||
border-bottom: 0;
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 0;
|
||||
|
||||
.nav-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.expanding-card {
|
||||
.card-header {
|
||||
.nav-tabs {
|
||||
.nav-item {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Maximized Card Body Scroll fix
|
||||
html.maximized-card {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Add clearfix to header, body and footer
|
||||
.card-header,
|
||||
.card-body,
|
||||
.card-footer {
|
||||
@include clearfix();
|
||||
}
|
||||
|
||||
// Box header
|
||||
.card-header {
|
||||
position: relative;
|
||||
padding: (($card-spacer-y * .5) * 2) $card-spacer-x;
|
||||
background-color: transparent;
|
||||
border-bottom: 1px solid $card-border-color;
|
||||
|
||||
@if $enable-rounded {
|
||||
@include border-top-radius($border-radius);
|
||||
}
|
||||
|
||||
.collapsed-card & {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
> .card-tools {
|
||||
float: right;
|
||||
margin-right: -$card-spacer-x * .5;
|
||||
|
||||
.input-group,
|
||||
.nav,
|
||||
.pagination {
|
||||
margin-top: -$card-spacer-y * .4;
|
||||
margin-bottom: -$card-spacer-y * .4;
|
||||
}
|
||||
|
||||
[data-bs-toggle="tooltip"] {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-title {
|
||||
float: left;
|
||||
margin: 0;
|
||||
font-size: $lte-card-title-font-size;
|
||||
font-weight: $lte-card-title-font-weight;
|
||||
}
|
||||
|
||||
// Box Tools Buttons
|
||||
.btn-tool {
|
||||
--#{$prefix}btn-padding-x: .5rem;
|
||||
--#{$prefix}btn-padding-y: .25rem;
|
||||
|
||||
&:not(.btn-tool-custom) {
|
||||
--#{$prefix}btn-color: var(--#{$prefix}tertiary-color);
|
||||
--#{$prefix}btn-bg: transparent;
|
||||
--#{$prefix}btn-box-shadow: none;
|
||||
--#{$prefix}btn-hover-color: var(--#{$prefix}secondary-color);
|
||||
--#{$prefix}btn-active-border-color: transparent;
|
||||
}
|
||||
|
||||
margin: -$card-spacer-y 0;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
@each $name, $color in $theme-colors {
|
||||
.card-#{$name},
|
||||
.bg-#{$name},
|
||||
.text-bg-#{$name} {
|
||||
--#{$lte-prefix}card-variant-bg: #{$color};
|
||||
--#{$lte-prefix}card-variant-bg-rgb: #{to-rgb($color)};
|
||||
--#{$lte-prefix}card-variant-color: #{color-contrast($color)};
|
||||
--#{$lte-prefix}card-variant-color-rgb: #{to-rgb(color-contrast($color))};
|
||||
}
|
||||
}
|
||||
|
||||
// Box Body
|
||||
.card-body {
|
||||
// Tables within the box body
|
||||
> .table {
|
||||
margin-bottom: 0;
|
||||
|
||||
> thead > tr > th,
|
||||
> thead > tr > td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
.compact-mode {
|
||||
.app-header {
|
||||
max-height: $lte-app-header-height-compact;
|
||||
|
||||
.nav-link {
|
||||
max-height: $nav-link-height-compact;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
--bs-nav-link-padding-y: .25rem;
|
||||
--bs-nav-link-padding-x: .5rem;
|
||||
}
|
||||
|
||||
&.sidebar-mini.sidebar-collapse {
|
||||
.app-sidebar:not(:hover) {
|
||||
min-width: $lte-sidebar-mini-width-compact;
|
||||
max-width: $lte-sidebar-mini-width-compact;
|
||||
|
||||
.sidebar-menu {
|
||||
.nav-link {
|
||||
width: $lte-sidebar-mini-width-compact - $lte-sidebar-padding-x * 2 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo-xs,
|
||||
.logo-xl {
|
||||
max-height: $lte-app-header-height-compact;
|
||||
}
|
||||
|
||||
.brand-image {
|
||||
width: $nav-link-height-compact;
|
||||
height: $nav-link-height-compact;
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
height: $lte-app-header-height-compact;
|
||||
}
|
||||
|
||||
.app-footer {
|
||||
padding: $lte-app-footer-padding-compact;
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
.nav-icon {
|
||||
min-width: 1.1rem;
|
||||
max-width: 1.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
//
|
||||
// Component: Direct Chat
|
||||
//
|
||||
|
||||
.direct-chat {
|
||||
.card-body {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
&.chat-pane-open {
|
||||
.direct-chat-contacts {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.timestamp-light {
|
||||
.direct-chat-timestamp {
|
||||
color: rgba(var(--#{$prefix}body-color-rgb), .65);
|
||||
}
|
||||
}
|
||||
|
||||
&.timestamp-dark {
|
||||
.direct-chat-timestamp {
|
||||
color: rgba(var(--#{$prefix}body-color-rgb), .9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.direct-chat-messages {
|
||||
height: 250px;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
.direct-chat-msg,
|
||||
.direct-chat-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.direct-chat-msg {
|
||||
@include clearfix();
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.direct-chat-messages,
|
||||
.direct-chat-contacts {
|
||||
@include transition(transform .5s ease-in-out);
|
||||
}
|
||||
|
||||
.direct-chat-text {
|
||||
@if $enable-rounded {
|
||||
@include border-radius($border-radius-lg);
|
||||
}
|
||||
|
||||
position: relative;
|
||||
padding: 5px 10px;
|
||||
margin: 5px 0 0 50px;
|
||||
color: $lte-direct-chat-default-font-color;
|
||||
background-color: $lte-direct-chat-default-msg-bg;
|
||||
border: 1px solid $lte-direct-chat-default-msg-border-color;
|
||||
|
||||
//Create the arrow
|
||||
&::after,
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 100%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
content: " ";
|
||||
border: solid transparent;
|
||||
border-right-color: $lte-direct-chat-default-msg-border-color;
|
||||
}
|
||||
|
||||
&::after {
|
||||
margin-top: -5px;
|
||||
border-width: 5px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
margin-top: -6px;
|
||||
border-width: 6px;
|
||||
}
|
||||
|
||||
.end & {
|
||||
margin-right: 50px;
|
||||
margin-left: 0;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
right: auto;
|
||||
left: 100%;
|
||||
border-right-color: transparent;
|
||||
border-left-color: $lte-direct-chat-default-msg-border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.direct-chat-img {
|
||||
@include border-radius(50%);
|
||||
float: left;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
.end & {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.direct-chat-infos {
|
||||
display: block;
|
||||
margin-bottom: 2px;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
.direct-chat-name {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.direct-chat-timestamp {
|
||||
color: rgba(var(--#{$prefix}body-color-rgb), .75);
|
||||
}
|
||||
|
||||
//Direct chat contacts pane
|
||||
.direct-chat-contacts-open {
|
||||
.direct-chat-contacts {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.direct-chat-contacts {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
overflow: auto;
|
||||
color: var(--#{$prefix}body-bg);
|
||||
background-color: var(--#{$prefix}body-color);
|
||||
transform: translate(101%, 0);
|
||||
}
|
||||
|
||||
.direct-chat-contacts-light {
|
||||
background-color: var(--#{$prefix}light-bg-subtle);
|
||||
|
||||
.contacts-list-name {
|
||||
color: var(--#{$prefix}body-color);
|
||||
}
|
||||
|
||||
.contacts-list-date {
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
}
|
||||
|
||||
.contacts-list-msg {
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
//Contacts list -- for displaying contacts in direct chat contacts pane
|
||||
.contacts-list {
|
||||
@include list-unstyled();
|
||||
|
||||
> li {
|
||||
@include clearfix();
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid rgba($black, .2);
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contacts-list-img {
|
||||
@include border-radius(50%);
|
||||
float: left;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.contacts-list-info {
|
||||
margin-left: 45px;
|
||||
color: var(--#{$prefix}body-bg);
|
||||
}
|
||||
|
||||
.contacts-list-name,
|
||||
.contacts-list-status {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.contacts-list-name {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.contacts-list-status {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
.contacts-list-date {
|
||||
font-weight: 400;
|
||||
color: var(--#{$prefix}secondary-bg);
|
||||
}
|
||||
|
||||
.contacts-list-msg {
|
||||
color: var(--#{$prefix}secondary-bg);
|
||||
}
|
||||
|
||||
.end > .direct-chat-text {
|
||||
color: var(--#{$lte-prefix}direct-chat-color);
|
||||
background-color: var(--#{$lte-prefix}direct-chat-bg);
|
||||
border-color: var(--#{$lte-prefix}direct-chat-bg);
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
border-left-color: var(--#{$lte-prefix}direct-chat-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// Color variants
|
||||
@each $name, $color in $theme-colors {
|
||||
.direct-chat-#{$name} {
|
||||
--#{$lte-prefix}direct-chat-color: #{color-contrast($color)};
|
||||
--#{$lte-prefix}direct-chat-bg: #{$color};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,820 @@
|
|||
//
|
||||
// Component: Docs
|
||||
//
|
||||
// Visual treatment for documentation pages. Body class `.docs-page` opts in.
|
||||
// Demo pages are not affected.
|
||||
//
|
||||
|
||||
// Inline code blocks rendered by MDX (Astro highlight default class)
|
||||
.astro-code {
|
||||
padding: .75rem;
|
||||
@include border-radius($border-radius);
|
||||
}
|
||||
|
||||
.docs-page {
|
||||
// Constrain the docs card to a comfortable reading width.
|
||||
// Tables and code blocks inside can still scroll horizontally if needed.
|
||||
.app-content > .container-fluid {
|
||||
max-width: 60rem; // ~960px
|
||||
|
||||
@include media-breakpoint-up(xxl) {
|
||||
max-width: 64rem;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Card body — breathing room + prose typography.
|
||||
// Only applied inside docs content cards so demo-page card content
|
||||
// stays unchanged.
|
||||
//
|
||||
.card > .card-body {
|
||||
padding: 1.5rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.7;
|
||||
color: var(--#{$prefix}body-color);
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
padding: 2.5rem;
|
||||
}
|
||||
|
||||
//
|
||||
// Heading hierarchy. The MDX content in src/html/components/docs/ uses
|
||||
// ##### (h5) as the dominant section heading and ###### (h6) as a
|
||||
// sub-heading (most visible in FAQ.mdx, where h5 is a topic and h6 is
|
||||
// a question). Style h5 as a major section and h6 as a sub-section so
|
||||
// the visual hierarchy matches the semantic one.
|
||||
//
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
.h1,
|
||||
.h2,
|
||||
.h3,
|
||||
.h4,
|
||||
.h5,
|
||||
.h6 {
|
||||
margin-top: 2em;
|
||||
margin-bottom: .5em;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
scroll-margin-top: 4rem; // anchor-link friendly
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h2,
|
||||
.h2 {
|
||||
padding-bottom: .35em;
|
||||
font-size: 1.75rem;
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
}
|
||||
|
||||
h3,
|
||||
.h3 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
h4,
|
||||
.h4 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
// h5 is the dominant section heading across docs MDX files. Give it
|
||||
// a visible separator above so sections are easy to scan.
|
||||
h5,
|
||||
.h5 {
|
||||
padding-top: 1.5em;
|
||||
margin-top: 2.5em;
|
||||
font-size: 1.3rem;
|
||||
border-top: 1px solid var(--#{$prefix}border-color);
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// h6 is the sub-section / FAQ question style. Smaller than h5 but
|
||||
// still distinctly heading-like, with a touch of accent colour to
|
||||
// separate from body text.
|
||||
h6,
|
||||
.h6 {
|
||||
margin-top: 1.75em;
|
||||
font-size: 1.08rem;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
}
|
||||
|
||||
//
|
||||
// Paragraphs and lists.
|
||||
//
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
dl,
|
||||
blockquote,
|
||||
table {
|
||||
margin-bottom: 1.1rem;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5rem;
|
||||
|
||||
li {
|
||||
margin-bottom: .35rem;
|
||||
}
|
||||
|
||||
// Tighter nested lists
|
||||
ul,
|
||||
ol {
|
||||
margin-top: .35rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Lead-style first paragraph (just after a heading)
|
||||
h2 + p,
|
||||
h3 + p,
|
||||
h5 + p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Inline code — pill style that complements MDX's syntax-highlighted blocks.
|
||||
//
|
||||
p code,
|
||||
li code,
|
||||
td code,
|
||||
th code,
|
||||
h2 code,
|
||||
h3 code,
|
||||
h4 code,
|
||||
h5 code,
|
||||
h6 code {
|
||||
padding: .15em .4em;
|
||||
font-size: .875em;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius-sm);
|
||||
}
|
||||
|
||||
//
|
||||
// Code blocks.
|
||||
//
|
||||
pre.astro-code,
|
||||
pre {
|
||||
padding: 1rem 1.25rem;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 1.5rem;
|
||||
overflow-x: auto;
|
||||
font-size: .875rem;
|
||||
line-height: 1.6;
|
||||
@include border-radius($border-radius);
|
||||
|
||||
code {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tables — reference-doc styling with hairline borders.
|
||||
//
|
||||
table {
|
||||
width: 100%;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 1.5rem;
|
||||
overflow: hidden;
|
||||
font-size: .95rem;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius-sm);
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: .65rem .9rem;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 600;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Blockquotes used as info callouts.
|
||||
//
|
||||
blockquote {
|
||||
padding: .85rem 1.1rem;
|
||||
margin-top: 1.25rem;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
background: var(--#{$prefix}info-bg-subtle);
|
||||
border-left: 4px solid var(--#{$prefix}info-border-subtle);
|
||||
@include border-radius($border-radius-sm);
|
||||
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
background: rgba(0, 0, 0, .05);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Prose links — stand out more than Bootstrap defaults.
|
||||
//
|
||||
a:not(.btn):not(.nav-link) {
|
||||
color: var(--#{$prefix}primary);
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-underline-offset: 3px;
|
||||
|
||||
&:hover {
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Horizontal rule — used as additional section separator.
|
||||
//
|
||||
hr {
|
||||
margin: 2.5rem 0;
|
||||
border: 0;
|
||||
border-top: 1px solid var(--#{$prefix}border-color);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Lead paragraph — the first paragraph in any doc is a summary.
|
||||
// Visually heavier so it functions as a deck.
|
||||
//
|
||||
> p:first-child,
|
||||
> p:first-of-type {
|
||||
margin-bottom: 2rem;
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.6;
|
||||
color: var(--#{$prefix}body-color);
|
||||
}
|
||||
|
||||
//
|
||||
// FAQ / disclosure accordion — uses native <details>/<summary>.
|
||||
// Add `.faq-item` to <details> to opt in.
|
||||
//
|
||||
details.faq-item {
|
||||
margin-bottom: .5rem;
|
||||
overflow: hidden;
|
||||
background: var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius);
|
||||
@include transition(border-color .15s ease, box-shadow .15s ease);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--#{$prefix}primary-border-subtle);
|
||||
}
|
||||
|
||||
&[open] {
|
||||
background: var(--#{$prefix}body-bg);
|
||||
border-color: var(--#{$prefix}primary-border-subtle);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
|
||||
}
|
||||
|
||||
summary {
|
||||
position: relative;
|
||||
padding: .9rem 3rem .9rem 1.1rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
@include transition(color .15s ease);
|
||||
|
||||
// Hide the default disclosure triangle in Webkit/Blink
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Hide the marker in modern Firefox too
|
||||
&::marker {
|
||||
content: "";
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--#{$prefix}primary);
|
||||
}
|
||||
|
||||
// Right-side chevron, rotates on open
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 1.1rem;
|
||||
display: inline-block;
|
||||
width: .55rem;
|
||||
height: .55rem;
|
||||
margin-top: -.4rem;
|
||||
content: "";
|
||||
border-right: 2px solid currentcolor;
|
||||
border-bottom: 2px solid currentcolor;
|
||||
opacity: .55;
|
||||
transform: rotate(45deg);
|
||||
@include transition(transform .2s ease);
|
||||
}
|
||||
}
|
||||
|
||||
&[open] > summary {
|
||||
color: var(--#{$prefix}primary);
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
|
||||
&::after {
|
||||
margin-top: -.15rem;
|
||||
opacity: 1;
|
||||
transform: rotate(-135deg);
|
||||
}
|
||||
}
|
||||
|
||||
// Content (everything after <summary>) gets the inner padding
|
||||
> *:not(summary) {
|
||||
padding-right: 1.1rem;
|
||||
padding-left: 1.1rem;
|
||||
}
|
||||
|
||||
> *:not(summary):first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
> *:not(summary):last-child {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
// Tighten paragraphs/lists inside an FAQ answer
|
||||
p,
|
||||
ul,
|
||||
ol {
|
||||
margin-bottom: .65rem;
|
||||
}
|
||||
|
||||
> *:last-child p:last-child,
|
||||
> p:last-child,
|
||||
> ul:last-child,
|
||||
> ol:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Code blocks inside an FAQ answer get a less-distracting bg
|
||||
pre.astro-code,
|
||||
pre {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dark-mode tweak: blockquote info bg needs more contrast on dark
|
||||
&[data-bs-theme="dark"],
|
||||
[data-bs-theme="dark"] & {
|
||||
.card > .card-body blockquote code {
|
||||
background: rgba(255, 255, 255, .08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FAQ page — custom layout that breaks out of the standard docs card
|
||||
// to give the FAQ a more distinctive visual identity. Opt in via
|
||||
// body.faq-page (set in pages/docs/faq.astro).
|
||||
//
|
||||
|
||||
.faq-page {
|
||||
// The FAQ doesn't use the standard card wrapper used by other docs,
|
||||
// so the container can stretch wider for the chip strip and section
|
||||
// grid.
|
||||
.app-content > .container-fluid {
|
||||
max-width: 64rem;
|
||||
|
||||
@include media-breakpoint-up(xxl) {
|
||||
max-width: 72rem;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Hero -------------------------------------------------------------
|
||||
.faq-hero {
|
||||
position: relative;
|
||||
padding: 3rem 1.5rem 2.5rem;
|
||||
margin-top: 1rem;
|
||||
overflow: hidden;
|
||||
background: radial-gradient(ellipse at top left, rgba(var(--#{$prefix}primary-rgb), .12), transparent 60%), radial-gradient(ellipse at bottom right, rgba(var(--#{$prefix}info-rgb), .1), transparent 65%), var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius-xl);
|
||||
}
|
||||
|
||||
.faq-hero-eyebrow {
|
||||
display: inline-flex;
|
||||
gap: .4rem;
|
||||
align-items: center;
|
||||
padding: .35rem .85rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: .75rem;
|
||||
font-weight: 600;
|
||||
color: var(--#{$prefix}primary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .08em;
|
||||
background: var(--#{$prefix}primary-bg-subtle);
|
||||
border: 1px solid var(--#{$prefix}primary-border-subtle);
|
||||
@include border-radius(50rem);
|
||||
|
||||
.bi {
|
||||
font-size: .9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.faq-hero-title {
|
||||
margin: 0 0 .5rem;
|
||||
font-size: 2.25rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
font-size: 2.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.faq-hero-lead {
|
||||
max-width: 36rem;
|
||||
margin: 0 auto 1.75rem;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.55;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
}
|
||||
|
||||
.faq-search {
|
||||
position: relative;
|
||||
max-width: 32rem;
|
||||
margin: 0 auto;
|
||||
|
||||
.form-control {
|
||||
height: 3rem;
|
||||
padding-right: 3rem;
|
||||
padding-left: 3rem;
|
||||
font-size: 1rem;
|
||||
background: var(--#{$prefix}body-bg);
|
||||
@include border-radius(50rem);
|
||||
@include transition(box-shadow .15s ease, border-color .15s ease);
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 .25rem rgba(var(--#{$prefix}primary-rgb), .15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.faq-search-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 1.2rem;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.faq-search-clear {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: .65rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
padding: 0;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
border: 0;
|
||||
transform: translateY(-50%);
|
||||
@include border-radius(50%);
|
||||
@include transition(background .15s ease, color .15s ease);
|
||||
|
||||
&:hover {
|
||||
color: var(--#{$prefix}body-color);
|
||||
background: var(--#{$prefix}secondary-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.faq-empty-state {
|
||||
max-width: 32rem;
|
||||
padding: 1rem;
|
||||
margin: 1.5rem auto 0;
|
||||
font-size: .95rem;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
@include border-radius($border-radius);
|
||||
|
||||
.bi {
|
||||
margin-right: .35rem;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Section nav chips ------------------------------------------------
|
||||
.faq-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: .5rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.faq-chip {
|
||||
display: inline-flex;
|
||||
gap: .45rem;
|
||||
align-items: center;
|
||||
padding: .45rem .85rem;
|
||||
font-size: .875rem;
|
||||
font-weight: 500;
|
||||
color: var(--#{$prefix}body-color);
|
||||
text-decoration: none;
|
||||
background: var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius(50rem);
|
||||
@include transition(transform .15s ease, border-color .15s ease, background-color .15s ease, color .15s ease);
|
||||
|
||||
&:hover {
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.bi {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.faq-chip-count {
|
||||
padding: 0 .45rem;
|
||||
font-size: .7rem;
|
||||
font-weight: 600;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
@include border-radius(50rem);
|
||||
}
|
||||
|
||||
// Per-section chip accent on hover/active
|
||||
@each $tone in (primary, info, warning, success, danger, secondary) {
|
||||
.faq-chip-#{$tone}:hover {
|
||||
color: var(--#{$prefix}#{$tone}-text-emphasis);
|
||||
background: var(--#{$prefix}#{$tone}-bg-subtle);
|
||||
border-color: var(--#{$prefix}#{$tone}-border-subtle);
|
||||
|
||||
.faq-chip-count {
|
||||
color: var(--#{$prefix}#{$tone}-text-emphasis);
|
||||
background: rgba(0, 0, 0, .06);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Sections ---------------------------------------------------------
|
||||
.faq-section {
|
||||
margin-bottom: 2.5rem;
|
||||
scroll-margin-top: 5rem;
|
||||
}
|
||||
|
||||
.faq-section-header {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
background: var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
border-left: 4px solid var(--#{$prefix}primary);
|
||||
@include border-radius($border-radius);
|
||||
}
|
||||
|
||||
.faq-section-icon {
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
font-size: 1.35rem;
|
||||
color: var(--#{$prefix}primary);
|
||||
background: var(--#{$prefix}primary-bg-subtle);
|
||||
@include border-radius($border-radius);
|
||||
}
|
||||
|
||||
.faq-section-title {
|
||||
margin: 0;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
}
|
||||
|
||||
.faq-section-count {
|
||||
margin: .1rem 0 0;
|
||||
font-size: .8rem;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
}
|
||||
|
||||
// Per-section tone accents
|
||||
@each $tone in (primary, info, warning, success, danger, secondary) {
|
||||
.faq-section-#{$tone} {
|
||||
border-left-color: var(--#{$prefix}#{$tone});
|
||||
|
||||
.faq-section-icon {
|
||||
color: var(--#{$prefix}#{$tone}-text-emphasis);
|
||||
background: var(--#{$prefix}#{$tone}-bg-subtle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- FAQ items (override the generic .docs-page details styling) ------
|
||||
.faq-section-items .faq-item {
|
||||
margin-bottom: .5rem;
|
||||
overflow: hidden;
|
||||
background: var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius);
|
||||
@include transition(border-color .15s ease, box-shadow .15s ease, transform .15s ease);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--#{$prefix}primary-border-subtle);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
&[open] {
|
||||
border-color: var(--#{$prefix}primary-border-subtle);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, .04);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: flex;
|
||||
gap: .85rem;
|
||||
align-items: center;
|
||||
padding: 1rem 1.25rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::marker {
|
||||
content: "";
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: none; // disable the generic chevron, we use our own
|
||||
}
|
||||
}
|
||||
|
||||
.faq-q-icon {
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
font-size: .85rem;
|
||||
color: var(--#{$prefix}primary);
|
||||
background: var(--#{$prefix}primary-bg-subtle);
|
||||
@include border-radius(50%);
|
||||
}
|
||||
|
||||
.faq-q-text {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.faq-q-chevron {
|
||||
flex-shrink: 0;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
@include transition(transform .2s ease, color .2s ease);
|
||||
}
|
||||
|
||||
&[open] .faq-q-chevron {
|
||||
color: var(--#{$prefix}primary);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
&[open] summary {
|
||||
color: var(--#{$prefix}primary);
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
padding: 1.1rem 1.25rem 1.1rem 3.85rem; // align with the question text (icon + gap)
|
||||
font-size: .95rem;
|
||||
line-height: 1.65;
|
||||
color: var(--#{$prefix}body-color);
|
||||
|
||||
p:last-child,
|
||||
ul:last-child,
|
||||
ol:last-child,
|
||||
pre:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--#{$prefix}primary);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
|
||||
&:hover {
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
padding: .12em .35em;
|
||||
font-size: .875em;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
background: var(--#{$prefix}tertiary-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius-sm);
|
||||
}
|
||||
|
||||
pre.astro-code,
|
||||
pre {
|
||||
padding: .85rem 1rem;
|
||||
margin-top: .75rem;
|
||||
margin-bottom: .75rem;
|
||||
overflow-x: auto;
|
||||
font-size: .85rem;
|
||||
line-height: 1.55;
|
||||
@include border-radius($border-radius-sm);
|
||||
|
||||
code {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- CTA footer -------------------------------------------------------
|
||||
.faq-cta {
|
||||
padding: 2.5rem 1.5rem;
|
||||
text-align: center;
|
||||
background: radial-gradient(ellipse at top, rgba(var(--#{$prefix}primary-rgb), .08), transparent 60%), var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
@include border-radius($border-radius-xl);
|
||||
}
|
||||
|
||||
.faq-cta-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.6rem;
|
||||
color: var(--#{$prefix}primary);
|
||||
background: var(--#{$prefix}primary-bg-subtle);
|
||||
@include border-radius(50%);
|
||||
}
|
||||
|
||||
.faq-cta h2 {
|
||||
margin: 0 0 .5rem;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
}
|
||||
|
||||
.faq-cta p {
|
||||
max-width: 32rem;
|
||||
margin: 0 auto 1.5rem;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
}
|
||||
|
||||
.faq-cta-actions {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
gap: .5rem;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
//
|
||||
// Component: Dropdown
|
||||
//
|
||||
|
||||
// General Dropdown Rules
|
||||
|
||||
// Ensure children cannot overflow and break the dropdown border radius
|
||||
.dropdown-menu {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fs-7 {
|
||||
.dropdown-menu {
|
||||
font-size: $font-size-sm !important;
|
||||
}
|
||||
|
||||
.dropdown-toggle::after {
|
||||
vertical-align: .2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item-title {
|
||||
margin: 0;
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
|
||||
.dropdown-icon {
|
||||
&::after {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown Sizes
|
||||
.dropdown-menu-lg {
|
||||
min-width: 280px;
|
||||
max-width: 300px;
|
||||
padding: 0;
|
||||
|
||||
.dropdown-divider {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: $dropdown-padding-y $dropdown-item-padding-x;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown Submenu
|
||||
.dropdown-submenu {
|
||||
position: relative;
|
||||
|
||||
> a::after {
|
||||
@include caret-end();
|
||||
float: right;
|
||||
margin-top: .5rem;
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
> .dropdown-menu {
|
||||
top: 0;
|
||||
left: 100%;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown Hover
|
||||
.dropdown-hover {
|
||||
&:hover,
|
||||
&.nav-item.dropdown:hover,
|
||||
.dropdown-submenu:hover,
|
||||
&.dropdown-submenu:hover {
|
||||
> .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Dropdown Sizes
|
||||
.dropdown-menu-xl {
|
||||
min-width: 360px;
|
||||
max-width: 420px;
|
||||
padding: 0;
|
||||
|
||||
.dropdown-divider {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: $dropdown-padding-y $dropdown-item-padding-x;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown header and footer
|
||||
.dropdown-footer,
|
||||
.dropdown-header {
|
||||
display: block;
|
||||
padding: .5rem $dropdown-item-padding-x;
|
||||
font-size: $font-size-sm;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// Add fade animation to dropdown menus by appending
|
||||
// the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)
|
||||
.open:not(.dropup) > .animated-dropdown-menu {
|
||||
animation: flipInX .7s both;
|
||||
backface-visibility: visible !important;
|
||||
}
|
||||
|
||||
// Fix dropdown menu in navbars
|
||||
.navbar-custom-menu > .navbar-nav {
|
||||
> li {
|
||||
position: relative;
|
||||
> .dropdown-menu {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.navbar-custom-menu > .navbar-nav {
|
||||
float: right;
|
||||
> li {
|
||||
position: static;
|
||||
> .dropdown-menu {
|
||||
position: absolute;
|
||||
right: 5%;
|
||||
left: auto;
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User Menu
|
||||
.navbar-nav > .user-menu {
|
||||
> .nav-link::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
> .dropdown-menu {
|
||||
width: 280px;
|
||||
padding: 0;
|
||||
|
||||
// Header menu
|
||||
> li.user-header {
|
||||
min-height: 175px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
|
||||
// User image
|
||||
> img {
|
||||
z-index: 5;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border: 3px solid;
|
||||
border-color: transparent;
|
||||
border-color: var(--#{$prefix}border-color-translucent);
|
||||
}
|
||||
|
||||
> p {
|
||||
z-index: 5;
|
||||
margin-top: 10px;
|
||||
font-size: 17px;
|
||||
word-wrap: break-word;
|
||||
|
||||
> small {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Menu Body
|
||||
> .user-body {
|
||||
@include clearfix();
|
||||
padding: 15px;
|
||||
border-top: 1px solid var(--#{$prefix}border-color);
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color-translucent);
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Menu Footer
|
||||
> .user-footer {
|
||||
@include clearfix();
|
||||
padding: 10px;
|
||||
background-color: var(--#{$prefix}light-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.user-image {
|
||||
@include media-breakpoint-up(sm) {
|
||||
float: none;
|
||||
margin-top: -8px;
|
||||
margin-right: .4rem;
|
||||
line-height: 10px;
|
||||
}
|
||||
|
||||
float: left;
|
||||
width: $lte-sidebar-user-image-width;
|
||||
height: $lte-sidebar-user-image-width;
|
||||
margin-top: -2px;
|
||||
// margin-right: 10px;
|
||||
@include border-radius(50%);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// Component: Info Box
|
||||
//
|
||||
|
||||
.info-box {
|
||||
@include box-shadow($lte-card-shadow);
|
||||
@include border-radius($border-radius);
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 80px;
|
||||
padding: .5rem;
|
||||
margin-bottom: map-get($spacers, 3);
|
||||
color: var(--#{$prefix}body-color);
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
|
||||
.progress {
|
||||
height: 2px;
|
||||
margin: 5px 0;
|
||||
background-color: rgba(var(--#{$lte-prefix}card-variant-color-rgb), .125);
|
||||
|
||||
.progress-bar {
|
||||
background-color: var(--#{$lte-prefix}card-variant-color);
|
||||
}
|
||||
}
|
||||
|
||||
.info-box-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 70px;
|
||||
font-size: 1.875rem;
|
||||
text-align: center;
|
||||
@include border-radius($border-radius);
|
||||
|
||||
> img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-box-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.info-box-number {
|
||||
display: block;
|
||||
margin-top: .25rem;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
.progress-description,
|
||||
.info-box-text {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.info-box-more {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.progress-description {
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
.col-xl-2 &,
|
||||
.col-lg-2 &,
|
||||
.col-md-2 & {
|
||||
.progress-description {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.col-xl-3 &,
|
||||
.col-lg-3 &,
|
||||
.col-md-3 & {
|
||||
.progress-description {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
.col-xl-2 &,
|
||||
.col-lg-2 &,
|
||||
.col-md-2 & {
|
||||
.progress-description {
|
||||
@include font-size(.75rem);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.col-xl-3 &,
|
||||
.col-lg-3 &,
|
||||
.col-md-3 & {
|
||||
.progress-description {
|
||||
@include font-size(.75rem);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xl) {
|
||||
.col-xl-2 &,
|
||||
.col-lg-2 &,
|
||||
.col-md-2 & {
|
||||
.progress-description {
|
||||
@include font-size(1rem);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.col-xl-3 &,
|
||||
.col-lg-3 &,
|
||||
.col-md-3 & {
|
||||
.progress-description {
|
||||
@include font-size(1rem);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Misc: Miscellaneous
|
||||
//
|
||||
|
||||
// Image sizes
|
||||
.img-size-64,
|
||||
.img-size-50,
|
||||
.img-size-32 {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.img-size-64 {
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
.img-size-50 {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.img-size-32 {
|
||||
width: 32px;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
//
|
||||
// General: Mixins
|
||||
//
|
||||
|
||||
@import "mixins/animations";
|
||||
@import "mixins/scrollbar";
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// Component: Progress Bar
|
||||
//
|
||||
|
||||
//General CSS
|
||||
.progress {
|
||||
@include box-shadow(null);
|
||||
@include border-radius($lte-progress-bar-border-radius);
|
||||
|
||||
// Vertical bars
|
||||
&.vertical {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 200px;
|
||||
margin-right: 10px;
|
||||
|
||||
> .progress-bar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
//Sizes
|
||||
&.sm,
|
||||
&.progress-sm {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
&.xs,
|
||||
&.progress-xs {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
&.xxs,
|
||||
&.progress-xxs {
|
||||
width: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progress-group {
|
||||
margin-bottom: map-get($spacers, 2);
|
||||
}
|
||||
|
||||
// size variation
|
||||
.progress-sm {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.progress-xs {
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.progress-xxs {
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
// Remove margins from progress bars when put in a table
|
||||
.table {
|
||||
tr > td {
|
||||
.progress {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
:root,
|
||||
[data-bs-theme="light"] {
|
||||
// Sidebar
|
||||
--#{$lte-prefix}sidebar-width: #{$lte-sidebar-width};
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// Component: Small Box
|
||||
//
|
||||
|
||||
.small-box {
|
||||
@include border-radius($border-radius);
|
||||
@include box-shadow($lte-card-shadow);
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-bottom: 1.25rem;
|
||||
--bs-link-color-rgb: none;
|
||||
--bs-link-hover-color-rgb: none;
|
||||
--bs-heading-color: none;
|
||||
|
||||
// content wrapper
|
||||
> .inner {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
> .small-box-footer {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
padding: 3px 0;
|
||||
text-align: center;
|
||||
background-color: rgba($black, .07);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($black, .1);
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include font-size(2.2rem);
|
||||
padding: 0;
|
||||
margin: 0 0 10px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
.col-xl-2 &,
|
||||
.col-lg-2 &,
|
||||
.col-md-2 & {
|
||||
h3 {
|
||||
@include font-size(1.6rem);
|
||||
}
|
||||
}
|
||||
|
||||
.col-xl-3 &,
|
||||
.col-lg-3 &,
|
||||
.col-md-3 & {
|
||||
h3 {
|
||||
@include font-size(1.6rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xl) {
|
||||
.col-xl-2 &,
|
||||
.col-lg-2 &,
|
||||
.col-md-2 & {
|
||||
h3 {
|
||||
@include font-size(2.2rem);
|
||||
}
|
||||
}
|
||||
|
||||
.col-xl-3 &,
|
||||
.col-lg-3 &,
|
||||
.col-md-3 & {
|
||||
h3 {
|
||||
@include font-size(2.2rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1rem;
|
||||
|
||||
> small {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
font-size: .9rem;
|
||||
color: $gray-100;
|
||||
}
|
||||
}
|
||||
|
||||
h3,
|
||||
p {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
// the icon
|
||||
.small-box-icon {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
z-index: 0;
|
||||
height: 70px;
|
||||
font-size: 70px;
|
||||
color: rgba($black, .15);
|
||||
@include transition(transform $lte-transition-speed linear);
|
||||
}
|
||||
|
||||
// Small box hover state
|
||||
&:hover {
|
||||
// Animate icons on small box hover
|
||||
.small-box-icon {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
// No need for icons on very small devices
|
||||
.small-box {
|
||||
text-align: center;
|
||||
|
||||
.small-box-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// Component: Table
|
||||
//
|
||||
|
||||
.table {
|
||||
&:not(.table-dark) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
// fixed table head
|
||||
// Uses Bootstrap CSS variables so the sticky header follows light/dark mode
|
||||
// automatically. Fixes #6026.
|
||||
&.table-head-fixed {
|
||||
thead tr:nth-child(1) th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background-color: var(--bs-body-bg, #{$white});
|
||||
border-bottom: 0;
|
||||
box-shadow: inset 0 1px 0 var(--bs-border-color, #{$table-border-color}), inset 0 -1px 0 var(--bs-border-color, #{$table-border-color});
|
||||
}
|
||||
}
|
||||
|
||||
// no border
|
||||
&.no-border {
|
||||
&,
|
||||
td,
|
||||
th {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// .text-center in tables
|
||||
&.text-center {
|
||||
&,
|
||||
td,
|
||||
th {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&.table-valign-middle {
|
||||
thead > tr > th,
|
||||
thead > tr > td,
|
||||
tbody > tr > th,
|
||||
tbody > tr > td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.card-body.p-0 & {
|
||||
thead > tr > th,
|
||||
thead > tr > td,
|
||||
tfoot > tr > th,
|
||||
tfoot > tr > td,
|
||||
tbody > tr > th,
|
||||
tbody > tr > td {
|
||||
&:first-of-type {
|
||||
padding-left: map-get($spacers, 4);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
padding-right: map-get($spacers, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
//
|
||||
// Component: Timeline
|
||||
//
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin: 0 0 45px;
|
||||
// The line
|
||||
&::before {
|
||||
@include border-radius($border-radius);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 31px;
|
||||
width: 4px;
|
||||
margin: 0;
|
||||
content: "";
|
||||
background-color: var(--#{$prefix}border-color);
|
||||
}
|
||||
// Element
|
||||
> div {
|
||||
&::before,
|
||||
&::after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 15px;
|
||||
// The content
|
||||
> .timeline-item {
|
||||
@include box-shadow($lte-card-shadow);
|
||||
@include border-radius($border-radius);
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
margin-right: 15px;
|
||||
margin-left: 60px;
|
||||
color: var(--#{$prefix}body-color);
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
// The time and header
|
||||
> .time {
|
||||
float: right;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
}
|
||||
// Header
|
||||
> .timeline-header {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
line-height: 1.1;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
// Link in header
|
||||
> a {
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
// Item body and footer
|
||||
> .timeline-body,
|
||||
> .timeline-footer {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
> .timeline-body {
|
||||
> img {
|
||||
margin: 10px;
|
||||
}
|
||||
> dl,
|
||||
ol,
|
||||
ul {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.timeline-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 18px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
background-color: var(--#{$prefix}secondary-bg);
|
||||
border-radius: 50%; // stylelint-disable-line property-disallowed-list
|
||||
}
|
||||
}
|
||||
// Time label
|
||||
> .time-label {
|
||||
> span {
|
||||
@include border-radius(4px);
|
||||
display: inline-block;
|
||||
padding: 5px;
|
||||
font-weight: 600;
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-inverse {
|
||||
> div {
|
||||
> .timeline-item {
|
||||
@include box-shadow(none);
|
||||
background-color: var(--#{$prefix}tertiary-bg);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
|
||||
> .timeline-header {
|
||||
border-bottom-color: var(--#{$prefix}border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Toast
|
||||
//
|
||||
|
||||
@each $name, $color in $theme-colors {
|
||||
.toast-#{$name} {
|
||||
--#{$prefix}toast-header-color: #{color-contrast($color)};
|
||||
--#{$prefix}toast-header-bg: #{$color};
|
||||
--#{$prefix}toast-header-border-color: #{$color};
|
||||
--#{$prefix}toast-border-color: #{$color};
|
||||
--#{$prefix}toast-bg: var(--#{$prefix}#{$name}-bg-subtle);
|
||||
|
||||
@if color-contrast($color) == $color-contrast-light {
|
||||
.btn-close {
|
||||
@include btn-close-white();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
@each $name, $color in $theme-colors {
|
||||
.toast-#{$name} {
|
||||
@if color-contrast($color) == $color-contrast-dark {
|
||||
.btn-close {
|
||||
--#{$prefix}btn-close-white-filter: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// SIDEBAR SKINS
|
||||
// --------------------------------------------------------
|
||||
|
||||
$lte-sidebar-hover-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||
$lte-sidebar-color-dark: #c2c7d0 !default;
|
||||
$lte-sidebar-hover-color-dark: $white !default;
|
||||
$lte-sidebar-active-color-dark: $white !default;
|
||||
$lte-sidebar-menu-active-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||
$lte-sidebar-menu-active-color-dark: $white !default;
|
||||
$lte-sidebar-submenu-bg-dark: transparent !default;
|
||||
$lte-sidebar-submenu-color-dark: #c2c7d0 !default;
|
||||
$lte-sidebar-submenu-hover-color-dark: $white !default;
|
||||
$lte-sidebar-submenu-hover-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||
$lte-sidebar-submenu-active-color-dark: $white !default;
|
||||
$lte-sidebar-submenu-active-bg-dark: rgba(255, 255, 255, .1) !default;
|
||||
$lte-sidebar-header-color-dark: tint-color(#c2c7d0, 5%) !default;
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// Custom AdminLTE Variables
|
||||
//
|
||||
|
||||
// Prefix for :root CSS variables and others.
|
||||
$lte-prefix: lte- !default;
|
||||
|
||||
// TRANSITIONS SETTINGS
|
||||
// --------------------------------------------------------
|
||||
// Transition global options
|
||||
$lte-transition-speed: .3s !default;
|
||||
$lte-transition-fn: ease-in-out !default;
|
||||
|
||||
// SIDEBAR
|
||||
// --------------------------------------------------------
|
||||
$lte-sidebar-width: 250px !default;
|
||||
$lte-sidebar-breakpoint: lg !default;
|
||||
$lte-sidebar-padding-x: .5rem !default;
|
||||
$lte-sidebar-padding-x-compact: .5rem !default;
|
||||
$lte-sidebar-padding-y: .5rem !default;
|
||||
$lte-sidebar-padding-y-compact: .25rem !default;
|
||||
$lte-sidebar-transition: min-width $lte-transition-speed $lte-transition-fn,
|
||||
max-width $lte-transition-speed $lte-transition-fn,
|
||||
margin-left $lte-transition-speed $lte-transition-fn,
|
||||
margin-right $lte-transition-speed $lte-transition-fn !default;
|
||||
|
||||
// SIDEBAR SKINS
|
||||
// --------------------------------------------------------
|
||||
|
||||
$lte-sidebar-hover-bg: rgba($black, .1) !default;
|
||||
$lte-sidebar-color: $gray-800 !default;
|
||||
$lte-sidebar-hover-color: $gray-900 !default;
|
||||
$lte-sidebar-active-color: $black !default;
|
||||
$lte-sidebar-menu-active-bg: rgba($black, .1) !default;
|
||||
$lte-sidebar-menu-active-color: $black !default;
|
||||
$lte-sidebar-submenu-bg: transparent !default;
|
||||
$lte-sidebar-submenu-color: #777 !default;
|
||||
$lte-sidebar-submenu-hover-color: $black !default;
|
||||
$lte-sidebar-submenu-hover-bg: rgba($black, .1) !default;
|
||||
$lte-sidebar-submenu-active-color: $gray-900 !default;
|
||||
$lte-sidebar-submenu-active-bg: rgba($black, .1) !default;
|
||||
$lte-sidebar-header-color: shade-color($gray-800, 5%) !default;
|
||||
|
||||
// SIDEBAR MINI
|
||||
// --------------------------------------------------------
|
||||
$nav-link-padding-x-compact: .25rem !default;
|
||||
$lte-sidebar-mini-width: ($nav-link-padding-x + $lte-sidebar-padding-x + .8rem) * 2 !default;
|
||||
$lte-sidebar-mini-width-compact: ($nav-link-padding-x-compact + $lte-sidebar-padding-x-compact + .8rem) * 2 !default;
|
||||
$lte-sidebar-nav-icon-width: $lte-sidebar-mini-width - (($lte-sidebar-padding-x + $nav-link-padding-x) * 2) !default;
|
||||
$lte-sidebar-user-image-width: $lte-sidebar-nav-icon-width + ($nav-link-padding-x * .4) !default;
|
||||
|
||||
// MAIN HEADER
|
||||
// --------------------------------------------------------
|
||||
$nav-link-height-compact: 1.75rem !default;
|
||||
$lte-app-header-bottom-border-width: $border-width !default;
|
||||
$lte-app-header-bottom-border-color: var(--#{$prefix}border-color) !default;
|
||||
$lte-app-header-bottom-border: $lte-app-header-bottom-border-width solid $lte-app-header-bottom-border-color !default;
|
||||
$lte-app-header-link-padding-y: $navbar-padding-y !default;
|
||||
$lte-app-header-height: ($nav-link-height + ($lte-app-header-link-padding-y * 2)) !default;
|
||||
$lte-app-header-height-compact: ($nav-link-height-compact + ($lte-app-header-link-padding-y * 2)) !default;
|
||||
$lte-zindex-fixed-header: $zindex-fixed !default;
|
||||
|
||||
// APP MAIN
|
||||
// --------------------------------------------------------
|
||||
$lte-app-main-padding-bottom: $grid-gutter-width * .5 !default;
|
||||
|
||||
// CONTENT PADDING
|
||||
// --------------------------------------------------------
|
||||
$lte-content-padding-y: 0 !default;
|
||||
$lte-content-padding-x: .5rem !default;
|
||||
|
||||
// MAIN FOOTER
|
||||
// --------------------------------------------------------
|
||||
$lte-app-footer-padding: 1rem !default;
|
||||
$lte-app-footer-padding-compact: .5rem !default;
|
||||
$lte-app-footer-border-top-width: 1px !default;
|
||||
$lte-app-footer-border-top-color: var(--#{$prefix}border-color) !default;
|
||||
$lte-app-footer-border-top: $lte-app-footer-border-top-width solid $lte-app-footer-border-top-color !default;
|
||||
$lte-app-footer-bg: var(--#{$prefix}body-bg) !default;
|
||||
$lte-app-footer-color: var(--#{$prefix}secondary-color) !default;
|
||||
$lte-zindex-fixed-footer: $zindex-fixed !default;
|
||||
// CONTENT BOTTOM AREA
|
||||
// --------------------------------------------------------
|
||||
$lte-app-content-bottom-area-margin-bottom: -$lte-app-main-padding-bottom !default;
|
||||
$lte-app-content-bottom-area-color: $lte-app-footer-color !default;
|
||||
$lte-app-content-bottom-area-bg: $lte-app-footer-bg !default;
|
||||
$lte-app-content-bottom-area-top-border: $lte-app-footer-border-top !default;
|
||||
$lte-app-content-bottom-area-padding-y: $lte-app-footer-padding !default;
|
||||
$lte-app-content-bottom-area-padding-x: 0 !default;
|
||||
|
||||
// CONTENT TOP AREA
|
||||
// --------------------------------------------------------
|
||||
$lte-app-content-top-area-top-border: $lte-app-footer-border-top !default;
|
||||
$lte-app-content-top-area-padding-y: $lte-app-footer-padding !default;
|
||||
$lte-app-content-top-area-padding-x: 0 !default;
|
||||
|
||||
// BRAND LINK
|
||||
// --------------------------------------------------------
|
||||
$navbar-brand-padding-y-compact: $navbar-brand-padding-y * .75 !default;
|
||||
$navbar-padding-y-compact: $navbar-padding-y * .5 !default;
|
||||
$lte-brand-link-padding-y: $navbar-brand-padding-y + $navbar-padding-y !default;
|
||||
$lte-brand-link-padding-y-compact: $navbar-brand-padding-y-compact + $navbar-padding-y-compact !default;
|
||||
$lte-brand-link-padding-x: $lte-sidebar-padding-x !default;
|
||||
$lte-brand-link-padding-x-compact: $lte-sidebar-padding-x-compact !default;
|
||||
$lte-brand-link-border-buttom: 1px !default;
|
||||
|
||||
// CARDS
|
||||
// --------------------------------------------------------
|
||||
$lte-card-shadow: 0 0 1px rgba(var(--#{$prefix}body-color-rgb), .125), 0 1px 3px rgba(var(--#{$prefix}body-color-rgb), .2) !default;
|
||||
$lte-card-title-font-size: 1.1rem !default;
|
||||
$lte-card-title-font-weight: $font-weight-normal !default;
|
||||
|
||||
// PROGRESS BARS
|
||||
// --------------------------------------------------------
|
||||
$lte-progress-bar-border-radius: 1px !default;
|
||||
|
||||
// CALLOUTS
|
||||
// --------------------------------------------------------
|
||||
$lte-callout-link-font-weight: $alert-link-font-weight !default;
|
||||
|
||||
// DIRECT CHAT
|
||||
// --------------------------------------------------------
|
||||
$lte-direct-chat-default-msg-bg: var(--#{$prefix}secondary-bg) !default;
|
||||
$lte-direct-chat-default-font-color: var(--#{$prefix}emphasis-color) !default;
|
||||
$lte-direct-chat-default-msg-border-color: var(--#{$prefix}border-color) !default;
|
||||
|
||||
// Z-INDEX
|
||||
// --------------------------------------------------------
|
||||
$lte-zindex-app-header: $zindex-fixed + 4 !default;
|
||||
$lte-zindex-sidebar: $zindex-fixed + 8 !default;
|
||||
$lte-zindex-sidebar-overlay: $lte-zindex-sidebar - 1 !default;
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*!
|
||||
* AdminLTE v4.0.0
|
||||
* Author: Colorlib
|
||||
* Website: AdminLTE.io <https://adminlte.io>
|
||||
* License: Open source - MIT <https://opensource.org/licenses/MIT>
|
||||
*/
|
||||
|
||||
// Bootstrap Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "bootstrap/scss/functions";
|
||||
|
||||
// AdminLTE Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "bootstrap-variables"; // little modified are here
|
||||
|
||||
// Bootstrap Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "bootstrap/scss/variables";
|
||||
@import "bootstrap/scss/variables-dark";
|
||||
@import "bootstrap/scss/maps";
|
||||
@import "bootstrap/scss/mixins";
|
||||
@import "bootstrap/scss/utilities";
|
||||
|
||||
// Bootstrap Layout & components
|
||||
@import "bootstrap/scss/root";
|
||||
@import "bootstrap/scss/reboot";
|
||||
@import "bootstrap/scss/type";
|
||||
@import "bootstrap/scss/images";
|
||||
@import "bootstrap/scss/containers";
|
||||
@import "bootstrap/scss/grid";
|
||||
@import "bootstrap/scss/tables";
|
||||
@import "bootstrap/scss/forms";
|
||||
@import "bootstrap/scss/buttons";
|
||||
@import "bootstrap/scss/transitions";
|
||||
@import "bootstrap/scss/dropdown";
|
||||
@import "bootstrap/scss/button-group";
|
||||
@import "bootstrap/scss/nav";
|
||||
@import "bootstrap/scss/navbar";
|
||||
@import "bootstrap/scss/card";
|
||||
@import "bootstrap/scss/accordion";
|
||||
@import "bootstrap/scss/breadcrumb";
|
||||
@import "bootstrap/scss/pagination";
|
||||
@import "bootstrap/scss/badge";
|
||||
@import "bootstrap/scss/alert";
|
||||
@import "bootstrap/scss/progress";
|
||||
@import "bootstrap/scss/list-group";
|
||||
@import "bootstrap/scss/close";
|
||||
@import "bootstrap/scss/toasts";
|
||||
@import "bootstrap/scss/modal";
|
||||
@import "bootstrap/scss/tooltip";
|
||||
@import "bootstrap/scss/popover";
|
||||
@import "bootstrap/scss/carousel";
|
||||
@import "bootstrap/scss/spinners";
|
||||
@import "bootstrap/scss/offcanvas";
|
||||
@import "bootstrap/scss/placeholders";
|
||||
|
||||
// Bootstrap Helpers
|
||||
@import "bootstrap/scss/helpers";
|
||||
|
||||
// Bootstrap Utilities
|
||||
@import "bootstrap/scss/utilities/api";
|
||||
|
||||
// AdminLTE Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "variables";
|
||||
@import "variables-dark";
|
||||
@import "mixins";
|
||||
|
||||
// AdiminLTE Parts
|
||||
// ---------------------------------------------------
|
||||
@import "parts/core";
|
||||
@import "parts/components";
|
||||
@import "parts/extra-components";
|
||||
@import "parts/pages";
|
||||
@import "parts/miscellaneous";
|
||||
|
||||
// AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
|
||||
@import "accessibility";
|
||||
|
||||
// AdminLTE Documentation Styles (only applies to pages with body.docs-page)
|
||||
@import "docs";
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
//
|
||||
// Mixins: Animation
|
||||
//
|
||||
|
||||
|
||||
@keyframes flipInX {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transition-timing-function: ease-in;
|
||||
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
|
||||
}
|
||||
|
||||
40% {
|
||||
transition-timing-function: ease-in;
|
||||
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
|
||||
}
|
||||
|
||||
60% {
|
||||
opacity: 1;
|
||||
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: perspective(400px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% {
|
||||
transform: translate(2px, 1px) rotate(0deg);
|
||||
}
|
||||
10% {
|
||||
transform: translate(-1px, -2px) rotate(-2deg);
|
||||
}
|
||||
20% {
|
||||
transform: translate(-3px, 0) rotate(3deg);
|
||||
}
|
||||
30% {
|
||||
transform: translate(0, 2px) rotate(0deg);
|
||||
}
|
||||
40% {
|
||||
transform: translate(1px, -1px) rotate(1deg);
|
||||
}
|
||||
50% {
|
||||
transform: translate(-1px, 2px) rotate(-1deg);
|
||||
}
|
||||
60% {
|
||||
transform: translate(-3px, 1px) rotate(0deg);
|
||||
}
|
||||
70% {
|
||||
transform: translate(2px, 1px) rotate(-2deg);
|
||||
}
|
||||
80% {
|
||||
transform: translate(-1px, -1px) rotate(4deg);
|
||||
}
|
||||
90% {
|
||||
transform: translate(2px, 2px) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(1px, -2px) rotate(-1deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wobble {
|
||||
0% {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
15% {
|
||||
transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
|
||||
}
|
||||
|
||||
45% {
|
||||
transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Mixins: Scrollbar
|
||||
//
|
||||
|
||||
@mixin scrollbar-color-gray() {
|
||||
scrollbar-color: var(--#{$prefix}secondary-bg) transparent;
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: var(--#{$prefix}secondary-bg);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin scrollbar-width-thin() {
|
||||
scrollbar-width: thin;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: .5rem;
|
||||
height: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin scrollbar-width-none() {
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Pages: Lock Screen
|
||||
//
|
||||
|
||||
// ADD THIS CLASS TO THE <BODY> TAG
|
||||
.lockscreen {
|
||||
// User name [optional]
|
||||
.lockscreen-name {
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lockscreen-logo {
|
||||
margin-bottom: 25px;
|
||||
font-size: 35px;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
color: var(--#{$prefix}emphasis-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.lockscreen-wrapper {
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
margin-top: 10%;
|
||||
}
|
||||
|
||||
// Will contain the image and the sign in form
|
||||
.lockscreen-item {
|
||||
position: relative;
|
||||
width: 290px;
|
||||
padding: 0;
|
||||
margin: 10px auto 30px;
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
@include border-radius(4px);
|
||||
}
|
||||
|
||||
// User image
|
||||
.lockscreen-image {
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
left: -10px;
|
||||
z-index: 10;
|
||||
padding: 5px;
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
@include border-radius(50%);
|
||||
|
||||
> img {
|
||||
@include border-radius(50%);
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
// Contains the password input and the login button
|
||||
.lockscreen-credentials {
|
||||
margin-left: 70px;
|
||||
|
||||
.form-control {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0 10px;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.lockscreen-footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// Pages: Login & Register
|
||||
//
|
||||
|
||||
.login-logo,
|
||||
.register-logo {
|
||||
margin-bottom: .9rem;
|
||||
font-size: 2.1rem;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.login-page,
|
||||
.register-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.login-box,
|
||||
.register-box {
|
||||
width: 400px;
|
||||
|
||||
@media (max-width: map-get($grid-breakpoints, sm)) {
|
||||
width: 90%;
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.login-card-body,
|
||||
.register-card-body {
|
||||
padding: 20px;
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
background-color: var(--#{$prefix}body-bg);
|
||||
border-top: 0;
|
||||
|
||||
.input-group {
|
||||
.form-control {
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
|
||||
~ .input-group-prepend .input-group-text,
|
||||
~ .input-group-append .input-group-text {
|
||||
border-color: $input-focus-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-valid {
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
~ .input-group-prepend .input-group-text,
|
||||
~ .input-group-append .input-group-text {
|
||||
border-color: $success;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-invalid {
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
~ .input-group-append .input-group-text {
|
||||
border-color: $danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
color: var(--#{$prefix}secondary-color);
|
||||
background-color: transparent;
|
||||
@include border-top-end-radius($border-radius);
|
||||
@include border-bottom-end-radius($border-radius);
|
||||
@include transition($input-transition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login-box-msg,
|
||||
.register-box-msg {
|
||||
padding: 0 20px 20px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.social-auth-links {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
//
|
||||
// Part: Components
|
||||
//
|
||||
|
||||
@import "../progress-bars";
|
||||
@import "../cards";
|
||||
@import "../table";
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Part: Core
|
||||
//
|
||||
|
||||
@import "../root";
|
||||
@import "../app-wrapper";
|
||||
@import "../app-content";
|
||||
@import "../app-header";
|
||||
@import "../app-sidebar";
|
||||
@import "../app-main";
|
||||
@import "../app-footer";
|
||||
@import "../dropdown";
|
||||
@import "../callouts";
|
||||
@import "../compact-mode";
|
||||
@import "../docs";
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
//
|
||||
// Part: Extra Components
|
||||
//
|
||||
|
||||
@import "../small-box";
|
||||
@import "../info-box";
|
||||
@import "../timeline";
|
||||
@import "../direct-chat";
|
||||
@import "../toasts";
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
//
|
||||
// Part: Miscellaneous
|
||||
//
|
||||
|
||||
@import "../miscellaneous";
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
//
|
||||
// Part: Pages
|
||||
//
|
||||
|
||||
@import "../pages/login_and_register";
|
||||
@import "../pages/lockscreen";
|
||||
91
extensions/pagetop-bootsier/assets/bootsier.scss
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// AdminLTE v4.0.0 + Bootstrap 5.3.8 - PageTop Bootsier Styles.
|
||||
|
||||
// Bootstrap Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "bootstrap-5.3.8/scss/functions";
|
||||
|
||||
// AdminLTE Configuration (little modified are here)
|
||||
// ---------------------------------------------------
|
||||
@import "adminlte-4.0.0/scss/bootstrap-variables";
|
||||
|
||||
// Bootsier Bootstrap variable overrides
|
||||
// ---------------------------------------------------
|
||||
@import "bootsier-variables";
|
||||
|
||||
// Bootstrap Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "bootstrap-5.3.8/scss/variables";
|
||||
@import "bootstrap-5.3.8/scss/variables-dark";
|
||||
@import "bootstrap-5.3.8/scss/maps";
|
||||
@import "bootstrap-5.3.8/scss/mixins";
|
||||
@import "bootstrap-5.3.8/scss/utilities";
|
||||
|
||||
// Bootstrap Layout & components
|
||||
@import "bootstrap-5.3.8/scss/root";
|
||||
@import "bootstrap-5.3.8/scss/reboot";
|
||||
@import "bootstrap-5.3.8/scss/type";
|
||||
@import "bootstrap-5.3.8/scss/images";
|
||||
@import "bootstrap-5.3.8/scss/containers";
|
||||
@import "bootstrap-5.3.8/scss/grid";
|
||||
@import "bootstrap-5.3.8/scss/tables";
|
||||
@import "bootstrap-5.3.8/scss/forms";
|
||||
@import "bootstrap-5.3.8/scss/buttons";
|
||||
@import "bootstrap-5.3.8/scss/transitions";
|
||||
@import "bootstrap-5.3.8/scss/dropdown";
|
||||
@import "bootstrap-5.3.8/scss/button-group";
|
||||
@import "bootstrap-5.3.8/scss/nav";
|
||||
@import "bootstrap-5.3.8/scss/navbar";
|
||||
@import "bootstrap-5.3.8/scss/card";
|
||||
@import "bootstrap-5.3.8/scss/accordion";
|
||||
@import "bootstrap-5.3.8/scss/breadcrumb";
|
||||
@import "bootstrap-5.3.8/scss/pagination";
|
||||
@import "bootstrap-5.3.8/scss/badge";
|
||||
@import "bootstrap-5.3.8/scss/alert";
|
||||
@import "bootstrap-5.3.8/scss/progress";
|
||||
@import "bootstrap-5.3.8/scss/list-group";
|
||||
@import "bootstrap-5.3.8/scss/close";
|
||||
@import "bootstrap-5.3.8/scss/toasts";
|
||||
@import "bootstrap-5.3.8/scss/modal";
|
||||
@import "bootstrap-5.3.8/scss/tooltip";
|
||||
@import "bootstrap-5.3.8/scss/popover";
|
||||
@import "bootstrap-5.3.8/scss/carousel";
|
||||
@import "bootstrap-5.3.8/scss/spinners";
|
||||
@import "bootstrap-5.3.8/scss/offcanvas";
|
||||
@import "bootstrap-5.3.8/scss/placeholders";
|
||||
|
||||
// Bootstrap Helpers
|
||||
@import "bootstrap-5.3.8/scss/helpers";
|
||||
|
||||
// Bootsier Utilities (must precede utilities/api to extend $utilities)
|
||||
@import "bootsier-utilities";
|
||||
|
||||
// Bootstrap Utilities
|
||||
@import "bootstrap-5.3.8/scss/utilities/api";
|
||||
|
||||
// AdminLTE Configuration
|
||||
// ---------------------------------------------------
|
||||
@import "adminlte-4.0.0/scss/variables";
|
||||
@import "adminlte-4.0.0/scss/variables-dark";
|
||||
@import "adminlte-4.0.0/scss/mixins";
|
||||
|
||||
// AdminLTE Parts
|
||||
// ---------------------------------------------------
|
||||
@import "adminlte-4.0.0/scss/parts/core";
|
||||
@import "adminlte-4.0.0/scss/parts/components";
|
||||
@import "adminlte-4.0.0/scss/parts/extra-components";
|
||||
@import "adminlte-4.0.0/scss/parts/pages";
|
||||
@import "adminlte-4.0.0/scss/parts/miscellaneous";
|
||||
|
||||
// AdminLTE Accessibility Styles - WCAG 2.1 AA Compliance
|
||||
@import "adminlte-4.0.0/scss/accessibility";
|
||||
|
||||
// AdminLTE Documentation Styles (only applies to pages with body.docs-page)
|
||||
@import "adminlte-4.0.0/scss/docs";
|
||||
|
||||
// Bootstrap Icons 1.13.1
|
||||
// ---------------------------------------------------
|
||||
@import "bootsier-icons";
|
||||
|
||||
// Bootsier customizations
|
||||
// ---------------------------------------------------
|
||||
@import "bootsier-custom";
|
||||
65
extensions/pagetop-bootsier/assets/bootsier.shell.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
// Fullscreen: keeps maximize/minimize icons in sync with the actual fullscreen state.
|
||||
document.addEventListener('fullscreenchange', function () {
|
||||
var isFs = !!document.fullscreenElement;
|
||||
document.querySelectorAll('[data-lte-icon="maximize"]').forEach(function (el) {
|
||||
el.classList.toggle('d-none', isFs);
|
||||
});
|
||||
document.querySelectorAll('[data-lte-icon="minimize"]').forEach(function (el) {
|
||||
el.classList.toggle('d-none', !isFs);
|
||||
});
|
||||
});
|
||||
|
||||
// Color mode selector (light / dark / auto).
|
||||
var STORAGE_KEY = 'lte-theme';
|
||||
var getStored = function () { return localStorage.getItem(STORAGE_KEY); };
|
||||
var setStored = function (theme) { localStorage.setItem(STORAGE_KEY, theme); };
|
||||
var prefersDark = function () {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
};
|
||||
|
||||
var setTheme = function (theme) {
|
||||
var resolved = (theme === 'auto') ? (prefersDark() ? 'dark' : 'light') : theme;
|
||||
document.documentElement.setAttribute('data-bs-theme', resolved);
|
||||
};
|
||||
|
||||
var showActiveTheme = function (theme) {
|
||||
document.querySelectorAll('[data-bs-theme-value]').forEach(function (el) {
|
||||
el.classList.remove('active');
|
||||
el.setAttribute('aria-pressed', 'false');
|
||||
var check = el.querySelector('.bi-check-lg');
|
||||
if (check) { check.classList.add('d-none'); }
|
||||
});
|
||||
var active = document.querySelector('[data-bs-theme-value="' + theme + '"]');
|
||||
if (active) {
|
||||
active.classList.add('active');
|
||||
active.setAttribute('aria-pressed', 'true');
|
||||
var check = active.querySelector('.bi-check-lg');
|
||||
if (check) { check.classList.remove('d-none'); }
|
||||
}
|
||||
document.querySelectorAll('[data-lte-theme-icon]').forEach(function (icon) {
|
||||
icon.classList.toggle('d-none', icon.dataset.lteThemeIcon !== theme);
|
||||
});
|
||||
};
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function () {
|
||||
var stored = getStored();
|
||||
if (!stored || stored === 'auto') { setTheme('auto'); }
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var theme = getStored() || 'auto';
|
||||
setTheme(theme);
|
||||
showActiveTheme(theme);
|
||||
document.querySelectorAll('[data-bs-theme-value]').forEach(function (toggle) {
|
||||
toggle.addEventListener('click', function () {
|
||||
var t = toggle.getAttribute('data-bs-theme-value');
|
||||
setStored(t);
|
||||
setTheme(t);
|
||||
showActiveTheme(t);
|
||||
});
|
||||
});
|
||||
});
|
||||
}());
|
||||