admin-lte 4.1.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -1
- package/README.md +23 -7
- package/dist/css/adminlte-docs.css +1 -1
- package/dist/css/adminlte-docs.css.map +1 -1
- package/dist/css/adminlte-docs.min.css +1 -1
- package/dist/css/adminlte-docs.min.css.map +1 -1
- package/dist/css/adminlte-docs.rtl.css +1 -1
- package/dist/css/adminlte-docs.rtl.css.map +1 -1
- package/dist/css/adminlte-docs.rtl.min.css +1 -1
- package/dist/css/adminlte-docs.rtl.min.css.map +1 -1
- package/dist/css/adminlte-select2.css +329 -0
- package/dist/css/adminlte-select2.css.map +1 -0
- package/dist/css/adminlte-select2.min.css +12 -0
- package/dist/css/adminlte-select2.min.css.map +1 -0
- package/dist/css/adminlte-select2.rtl.css +328 -0
- package/dist/css/adminlte-select2.rtl.css.map +1 -0
- package/dist/css/adminlte-select2.rtl.min.css +12 -0
- package/dist/css/adminlte-select2.rtl.min.css.map +1 -0
- package/dist/css/adminlte.css +332 -131
- package/dist/css/adminlte.css.map +1 -1
- package/dist/css/adminlte.min.css +2 -2
- package/dist/css/adminlte.min.css.map +1 -1
- package/dist/css/adminlte.rtl.css +332 -131
- package/dist/css/adminlte.rtl.css.map +1 -1
- package/dist/css/adminlte.rtl.min.css +2 -2
- package/dist/css/adminlte.rtl.min.css.map +1 -1
- package/dist/js/adminlte.esm.js +300 -109
- package/dist/js/adminlte.esm.js.map +1 -1
- package/dist/js/adminlte.esm.min.js +2 -2
- package/dist/js/adminlte.esm.min.js.map +1 -1
- package/dist/js/adminlte.js +302 -108
- package/dist/js/adminlte.js.map +1 -1
- package/dist/js/adminlte.min.js +2 -2
- package/dist/js/adminlte.min.js.map +1 -1
- package/dist/js/types/adminlte.d.ts +3 -1
- package/dist/js/types/base-component.d.ts +24 -0
- package/dist/js/types/color-mode.d.ts +24 -6
- package/dist/js/types/push-menu.d.ts +21 -0
- package/dist/js/types/sidebar-search.d.ts +46 -0
- package/dist/js/types/util/index.d.ts +38 -1
- package/package.json +24 -23
- package/src/scss/_app-sidebar.scss +12 -0
- package/src/scss/_ribbon.scss +75 -0
- package/src/scss/_variables.scss +28 -0
- package/src/scss/_widgets.scss +192 -0
- package/src/scss/adminlte-docs.scss +1 -1
- package/src/scss/adminlte-select2.scss +31 -0
- package/src/scss/adminlte.scss +1 -1
- package/src/scss/compat/_select2.scss +476 -0
- package/src/scss/parts/_extra-components.scss +2 -0
- package/src/ts/accessibility.ts +31 -15
- package/src/ts/adminlte.ts +7 -3
- package/src/ts/base-component.ts +30 -3
- package/src/ts/color-mode.ts +100 -20
- package/src/ts/push-menu.ts +37 -7
- package/src/ts/sidebar-search.ts +252 -0
- package/src/ts/util/index.ts +79 -15
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
* --------------------------------------------
|
|
3
3
|
* @file AdminLTE color-mode.ts
|
|
4
4
|
* @description Color mode (light/dark/auto) switcher for AdminLTE.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* [data-
|
|
5
|
+
* Resolves the theme from, in order: the visitor's stored choice, the theme
|
|
6
|
+
* the page itself declared in <html data-bs-theme="…">, and finally the OS
|
|
7
|
+
* preference. Keeps [data-bs-theme-value] toggles and [data-lte-theme-icon]
|
|
8
|
+
* indicator icons in sync.
|
|
8
9
|
*
|
|
9
10
|
* Ships in the bundle so applications no longer need to copy the demo's
|
|
10
11
|
* inline script. The tiny no-flash snippet in <head> (see _head.astro)
|
|
11
|
-
* remains inline by design — it must run before first paint.
|
|
12
|
+
* remains inline by design — it must run before first paint. That snippet
|
|
13
|
+
* flags the values it computes itself with [data-lte-theme-resolved], so a
|
|
14
|
+
* theme authored in the markup can be told apart from one it resolved.
|
|
15
|
+
*
|
|
16
|
+
* Applications with their own theming opt out entirely with
|
|
17
|
+
* <html data-lte-color-mode="off">.
|
|
12
18
|
* @license MIT
|
|
13
19
|
* --------------------------------------------
|
|
14
20
|
*/
|
|
@@ -24,8 +30,17 @@ declare class ColorMode {
|
|
|
24
30
|
*/
|
|
25
31
|
getStoredTheme(): Theme | null;
|
|
26
32
|
/**
|
|
27
|
-
* The
|
|
28
|
-
*
|
|
33
|
+
* The theme declared in the markup, for applications that render it
|
|
34
|
+
* server-side from a cookie or a user record. Null when the page declared
|
|
35
|
+
* none, or when the value is a custom Bootstrap theme ColorMode cannot
|
|
36
|
+
* resolve — see `isDisabled` for those.
|
|
37
|
+
*/
|
|
38
|
+
getMarkupTheme(): Theme | null;
|
|
39
|
+
/**
|
|
40
|
+
* The user's effective choice: the stored theme, then the theme declared in
|
|
41
|
+
* the markup, falling back to the OS preference. Storage comes first because
|
|
42
|
+
* it is the visitor's own click on this device; markup is only the default
|
|
43
|
+
* the page shipped with.
|
|
29
44
|
*/
|
|
30
45
|
getPreferredTheme(): Theme;
|
|
31
46
|
/**
|
|
@@ -42,6 +57,9 @@ declare class ColorMode {
|
|
|
42
57
|
* changes while in "auto" mode.
|
|
43
58
|
*/
|
|
44
59
|
_applyTheme(theme: Theme): void;
|
|
60
|
+
/**
|
|
61
|
+
* Whether the OS preference is currently dark.
|
|
62
|
+
*/
|
|
45
63
|
_prefersDark(): boolean;
|
|
46
64
|
/**
|
|
47
65
|
* Sync the [data-bs-theme-value] toggles (active state, pressed state,
|
|
@@ -27,9 +27,30 @@ type Config = {
|
|
|
27
27
|
*/
|
|
28
28
|
declare class PushMenu extends BaseComponent {
|
|
29
29
|
static get NAME(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Look up the PushMenu already attached to the given element.
|
|
32
|
+
*
|
|
33
|
+
* @param element The sidebar element to look up.
|
|
34
|
+
* @returns The existing instance, or null if the sidebar has none yet.
|
|
35
|
+
*/
|
|
30
36
|
static getInstance(element: Element | null | undefined): PushMenu | null;
|
|
37
|
+
/**
|
|
38
|
+
* Look up the PushMenu attached to the given element, creating one when the
|
|
39
|
+
* element has none. `config` is ignored if an instance already exists.
|
|
40
|
+
*
|
|
41
|
+
* @param element The sidebar element.
|
|
42
|
+
* @param config Overrides merged over the defaults for a new instance.
|
|
43
|
+
* @returns The existing or newly created instance.
|
|
44
|
+
*/
|
|
31
45
|
static getOrCreateInstance(element: HTMLElement, config?: Partial<Config>): PushMenu;
|
|
46
|
+
/**
|
|
47
|
+
* The defaults merged with the overrides this instance was created with.
|
|
48
|
+
*/
|
|
32
49
|
_config: Config;
|
|
50
|
+
/**
|
|
51
|
+
* @param element The sidebar element to attach to.
|
|
52
|
+
* @param config Overrides merged over the defaults.
|
|
53
|
+
*/
|
|
33
54
|
constructor(element: HTMLElement, config?: Partial<Config>);
|
|
34
55
|
/**
|
|
35
56
|
* Check if the sidebar is collapsed.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --------------------------------------------
|
|
3
|
+
* @file AdminLTE sidebar-search.ts
|
|
4
|
+
* @description Live filter for the sidebar menu.
|
|
5
|
+
* @license MIT
|
|
6
|
+
* --------------------------------------------
|
|
7
|
+
*/
|
|
8
|
+
import { BaseComponent } from './base-component';
|
|
9
|
+
/**
|
|
10
|
+
* A submenu's resting state, captured before the first keystroke so clearing
|
|
11
|
+
* the field can put the menu back exactly as the user left it. The inline
|
|
12
|
+
* `display` matters as well as the class: Treeview's slide animation writes
|
|
13
|
+
* one, and it would otherwise win over `.menu-open > .nav-treeview`.
|
|
14
|
+
*/
|
|
15
|
+
type SubmenuState = {
|
|
16
|
+
open: boolean;
|
|
17
|
+
display: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Class Definition
|
|
21
|
+
* ============================================================================
|
|
22
|
+
*/
|
|
23
|
+
declare class SidebarSearch extends BaseComponent {
|
|
24
|
+
static get NAME(): string;
|
|
25
|
+
static getInstance(element: Element | null | undefined): SidebarSearch | null;
|
|
26
|
+
static getOrCreateInstance(element: HTMLElement): SidebarSearch;
|
|
27
|
+
_menu: HTMLElement | null;
|
|
28
|
+
_emptyState: HTMLElement | null;
|
|
29
|
+
_snapshot: Map<HTMLElement, SubmenuState> | null;
|
|
30
|
+
constructor(element: HTMLElement);
|
|
31
|
+
/**
|
|
32
|
+
* Show only the menu entries matching `term`, expanding whatever has to be
|
|
33
|
+
* expanded to reveal them. An empty term restores the menu.
|
|
34
|
+
*
|
|
35
|
+
* @param term The text to match against nav-link labels, case-insensitively.
|
|
36
|
+
*/
|
|
37
|
+
search(term: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Drop the filter: every entry becomes visible again and each submenu goes
|
|
40
|
+
* back to the open/closed state it had before the search started.
|
|
41
|
+
*/
|
|
42
|
+
clear(): void;
|
|
43
|
+
dispose(): void;
|
|
44
|
+
_takeSnapshot(menu: HTMLElement): Map<HTMLElement, SubmenuState>;
|
|
45
|
+
}
|
|
46
|
+
export default SidebarSearch;
|
|
@@ -16,6 +16,18 @@
|
|
|
16
16
|
* cycle's listeners before the callbacks run again. Listeners bound to elements
|
|
17
17
|
* inside <body> don't need the signal — Turbo discards the old <body>, so they
|
|
18
18
|
* are cleaned up automatically.
|
|
19
|
+
*
|
|
20
|
+
* Turbo is not the only environment that renders after `DOMContentLoaded`:
|
|
21
|
+
* client-side frameworks that build the layout themselves (GWT, and other
|
|
22
|
+
* imperative widget toolkits) have an empty <body> when the initial batch runs,
|
|
23
|
+
* so the per-page init pass finds no sidebar and no menu. Those consumers call
|
|
24
|
+
* the exported `initialize()` once the layout is attached — it performs the same
|
|
25
|
+
* reset-then-replay cycle Turbo gets, without faking Turbo events.
|
|
26
|
+
*
|
|
27
|
+
* Unlike Turbo, such frameworks keep the same <body> across a re-init, so
|
|
28
|
+
* element-level listeners are NOT discarded for them. Callbacks should therefore
|
|
29
|
+
* pass `getLifecycleSignal()` to every `addEventListener` they make — including
|
|
30
|
+
* ones on elements — whenever the element can outlive the cycle.
|
|
19
31
|
*/
|
|
20
32
|
/**
|
|
21
33
|
* The AbortSignal for the current lifecycle. Pass it as the
|
|
@@ -24,6 +36,31 @@
|
|
|
24
36
|
*/
|
|
25
37
|
declare const getLifecycleSignal: () => AbortSignal;
|
|
26
38
|
declare const onDOMContentLoaded: (callback: () => void) => void;
|
|
39
|
+
/**
|
|
40
|
+
* End the current lifecycle: abort the cycle's signal so listeners registered
|
|
41
|
+
* with it are removed, then arm a fresh cycle for the next replay.
|
|
42
|
+
*
|
|
43
|
+
* Exported for SPA containers that unmount the AdminLTE layout: calling it
|
|
44
|
+
* drops the window/document listeners the current cycle added without
|
|
45
|
+
* immediately re-initialising. Internally it is also the first half of
|
|
46
|
+
* `initialize()` and the `turbo:before-render` handler.
|
|
47
|
+
*/
|
|
48
|
+
declare const teardown: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Re-run every plugin's initialisation against the DOM as it stands right now.
|
|
51
|
+
*
|
|
52
|
+
* Intended for frameworks that render the layout after `DOMContentLoaded` has
|
|
53
|
+
* already fired — call it once the sidebar and menu are attached, and PushMenu,
|
|
54
|
+
* Treeview and ColorMode pick them up as if they had been in the initial HTML.
|
|
55
|
+
* Delegated click handling never needs this; only the per-page init pass does.
|
|
56
|
+
*
|
|
57
|
+
* The previous cycle is torn down first, so calling it repeatedly does not stack
|
|
58
|
+
* listeners registered with `getLifecycleSignal()`. Calling it before the
|
|
59
|
+
* initial batch has run (while `document.readyState === 'loading'`) runs that
|
|
60
|
+
* batch early, against whatever DOM exists at the time — the initial
|
|
61
|
+
* `DOMContentLoaded` pass below still replays against the complete DOM.
|
|
62
|
+
*/
|
|
63
|
+
declare const initialize: () => void;
|
|
27
64
|
/**
|
|
28
65
|
* Check if an element has a specific data attribute using ES2022 Object.hasOwn()
|
|
29
66
|
*/
|
|
@@ -39,4 +76,4 @@ declare const safePropertyAccess: (obj: Record<string, unknown>, property: strin
|
|
|
39
76
|
declare const slideUp: (target: HTMLElement, duration?: number) => void;
|
|
40
77
|
declare const slideDown: (target: HTMLElement, duration?: number) => void;
|
|
41
78
|
declare const slideToggle: (target: HTMLElement, duration?: number) => void;
|
|
42
|
-
export { onDOMContentLoaded, getLifecycleSignal, slideUp, slideDown, slideToggle, hasDataAttribute, getLastElement, safePropertyAccess };
|
|
79
|
+
export { onDOMContentLoaded, getLifecycleSignal, initialize, teardown, slideUp, slideDown, slideToggle, hasDataAttribute, getLastElement, safePropertyAccess };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "admin-lte",
|
|
3
3
|
"description": "Responsive open source admin dashboard and control panel.",
|
|
4
|
-
"version": "4.1
|
|
4
|
+
"version": "4.3.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Colorlib <https://colorlib.com>",
|
|
@@ -99,51 +99,52 @@
|
|
|
99
99
|
"bootstrap": "^5.3.8"
|
|
100
100
|
},
|
|
101
101
|
"overrides": {
|
|
102
|
-
"axios": "0.
|
|
102
|
+
"axios": "^0.33.0",
|
|
103
|
+
"shell-quote": "^1.10.0",
|
|
103
104
|
"stylelint-config-twbs-bootstrap": {
|
|
104
105
|
"stylelint": "$stylelint"
|
|
105
106
|
},
|
|
106
107
|
"yaml": "^2.9.0"
|
|
107
108
|
},
|
|
108
109
|
"devDependencies": {
|
|
109
|
-
"@astrojs/check": "^0.9.
|
|
110
|
-
"@astrojs/mdx": "^7.0.
|
|
110
|
+
"@astrojs/check": "^0.9.10",
|
|
111
|
+
"@astrojs/mdx": "^7.0.5",
|
|
111
112
|
"@eslint/js": "^10.0.1",
|
|
112
113
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
113
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
114
|
-
"@typescript-eslint/parser": "^8.
|
|
115
|
-
"astro": "^7.
|
|
116
|
-
"autoprefixer": "^10.5.
|
|
114
|
+
"@typescript-eslint/eslint-plugin": "^8.66.0",
|
|
115
|
+
"@typescript-eslint/parser": "^8.66.0",
|
|
116
|
+
"astro": "^7.1.6",
|
|
117
|
+
"autoprefixer": "^10.5.4",
|
|
117
118
|
"axe-core": "^4.12.1",
|
|
118
119
|
"bootstrap": "^5.3.8",
|
|
119
120
|
"bundlewatch": "^0.4.2",
|
|
120
121
|
"clean-css-cli": "^5.6.3",
|
|
121
|
-
"concurrently": "^10.0.
|
|
122
|
+
"concurrently": "^10.0.4",
|
|
122
123
|
"cross-env": "^10.1.0",
|
|
123
|
-
"eslint": "^10.
|
|
124
|
-
"eslint-plugin-astro": "^
|
|
125
|
-
"eslint-plugin-unicorn": "^
|
|
126
|
-
"fs-extra": "^11.
|
|
127
|
-
"globals": "^17.
|
|
128
|
-
"happy-dom": "^20.
|
|
124
|
+
"eslint": "^10.8.0",
|
|
125
|
+
"eslint-plugin-astro": "^3.1.0",
|
|
126
|
+
"eslint-plugin-unicorn": "^73.0.0",
|
|
127
|
+
"fs-extra": "^11.4.0",
|
|
128
|
+
"globals": "^17.9.0",
|
|
129
|
+
"happy-dom": "^20.11.1",
|
|
129
130
|
"lockfile-lint": "^5.0.0",
|
|
130
131
|
"nodemon": "^3.1.14",
|
|
131
132
|
"npm-run-all": "^4.1.5",
|
|
132
|
-
"postcss": "^8.5.
|
|
133
|
+
"postcss": "^8.5.25",
|
|
133
134
|
"postcss-cli": "^11.0.1",
|
|
134
|
-
"prettier": "^3.9.
|
|
135
|
+
"prettier": "^3.9.6",
|
|
135
136
|
"prettier-plugin-astro": "^0.14.1",
|
|
136
137
|
"rimraf": "^6.1.3",
|
|
137
|
-
"rollup": "^4.62.
|
|
138
|
+
"rollup": "^4.62.4",
|
|
138
139
|
"rtlcss": "^4.3.0",
|
|
139
|
-
"sass": "^1.
|
|
140
|
+
"sass": "^1.102.0",
|
|
140
141
|
"shx": "^0.4.0",
|
|
141
|
-
"stylelint": "^17.14.
|
|
142
|
+
"stylelint": "^17.14.1",
|
|
142
143
|
"stylelint-config-twbs-bootstrap": "^16.1.0",
|
|
143
|
-
"terser": "^5.
|
|
144
|
+
"terser": "^5.49.2",
|
|
144
145
|
"tslib": "^2.8.1",
|
|
145
146
|
"typescript": "^6.0.3",
|
|
146
|
-
"typescript-eslint": "^8.
|
|
147
|
-
"vitest": "^4.1.
|
|
147
|
+
"typescript-eslint": "^8.66.0",
|
|
148
|
+
"vitest": "^4.1.10"
|
|
148
149
|
}
|
|
149
150
|
}
|
|
@@ -309,6 +309,12 @@
|
|
|
309
309
|
white-space: nowrap;
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
+
// Sidebar search: the filter field above the menu. It sits outside
|
|
313
|
+
// .sidebar-wrapper so it stays put while the menu scrolls under it.
|
|
314
|
+
.sidebar-search {
|
|
315
|
+
padding: $lte-sidebar-padding-y ($lte-sidebar-padding-x * 2);
|
|
316
|
+
}
|
|
317
|
+
|
|
312
318
|
// Logo style
|
|
313
319
|
.logo-xs,
|
|
314
320
|
.logo-xl {
|
|
@@ -356,6 +362,12 @@
|
|
|
356
362
|
display: none;
|
|
357
363
|
}
|
|
358
364
|
|
|
365
|
+
// A text field can't render usefully in the mini rail; it returns on hover
|
|
366
|
+
// together with the labels it filters.
|
|
367
|
+
.app-sidebar:not(:hover) .sidebar-search {
|
|
368
|
+
display: none;
|
|
369
|
+
}
|
|
370
|
+
|
|
359
371
|
.sidebar-menu {
|
|
360
372
|
.nav-link {
|
|
361
373
|
width: $lte-sidebar-mini-width - $lte-sidebar-padding-x * 2;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Component: Ribbon
|
|
3
|
+
//
|
|
4
|
+
// A diagonal banner pinned to the top corner of a positioned parent. `.card` is
|
|
5
|
+
// already `position: relative`; anything else needs `.position-relative`.
|
|
6
|
+
//
|
|
7
|
+
// The wrapper is a square that clips the band. The band is NOT centred on that
|
|
8
|
+
// square — a corner ribbon has to hug the corner, and the square's centre is
|
|
9
|
+
// the point furthest from it, which would leave the corner bare. Instead the
|
|
10
|
+
// band's centre sits on the corner's bisector at ~46% of the square's side,
|
|
11
|
+
// which is the proportion v3 used and the one that leaves room for the label.
|
|
12
|
+
// rtlcss mirrors the offsets and the rotation, so no direction-specific rules
|
|
13
|
+
// are needed here.
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
.ribbon-wrapper {
|
|
17
|
+
// Width is the chord across the corner at the band's inner edge, so the band
|
|
18
|
+
// reaches both edges of the square and its ends are cut flush. Derived here
|
|
19
|
+
// rather than with calc() so a theme only ever overrides the size.
|
|
20
|
+
--#{$lte-prefix}ribbon-size: #{$lte-ribbon-size};
|
|
21
|
+
--#{$lte-prefix}ribbon-width: #{$lte-ribbon-size * 1.3};
|
|
22
|
+
--#{$lte-prefix}ribbon-font-size: #{$lte-ribbon-font-size};
|
|
23
|
+
|
|
24
|
+
position: absolute;
|
|
25
|
+
top: 0;
|
|
26
|
+
right: 0;
|
|
27
|
+
z-index: 1;
|
|
28
|
+
width: var(--#{$lte-prefix}ribbon-size);
|
|
29
|
+
height: var(--#{$lte-prefix}ribbon-size);
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
// Inheriting the parent's corner radius makes the clip follow a rounded
|
|
32
|
+
// card instead of cutting a square out of it.
|
|
33
|
+
@include border-top-end-radius(inherit);
|
|
34
|
+
|
|
35
|
+
&.ribbon-lg {
|
|
36
|
+
--#{$lte-prefix}ribbon-size: #{$lte-ribbon-size-lg};
|
|
37
|
+
--#{$lte-prefix}ribbon-width: #{$lte-ribbon-size-lg * 1.3};
|
|
38
|
+
--#{$lte-prefix}ribbon-font-size: #{$lte-ribbon-font-size-lg};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&.ribbon-xl {
|
|
42
|
+
--#{$lte-prefix}ribbon-size: #{$lte-ribbon-size-xl};
|
|
43
|
+
--#{$lte-prefix}ribbon-width: #{$lte-ribbon-size-xl * 1.3};
|
|
44
|
+
--#{$lte-prefix}ribbon-font-size: #{$lte-ribbon-font-size-xl};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.ribbon {
|
|
48
|
+
position: absolute;
|
|
49
|
+
// 32.5% / 67.5% puts the band's centre on the corner bisector, close enough
|
|
50
|
+
// to the corner to cover it; 50%/50% would park it at the far diagonal.
|
|
51
|
+
top: 32.5%;
|
|
52
|
+
left: 67.5%;
|
|
53
|
+
width: var(--#{$lte-prefix}ribbon-width);
|
|
54
|
+
padding: $lte-ribbon-padding;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
font-size: var(--#{$lte-prefix}ribbon-font-size);
|
|
57
|
+
font-weight: $lte-ribbon-font-weight;
|
|
58
|
+
line-height: 1.2;
|
|
59
|
+
color: var(--#{$prefix}emphasis-color);
|
|
60
|
+
text-align: center;
|
|
61
|
+
text-overflow: ellipsis;
|
|
62
|
+
text-transform: uppercase;
|
|
63
|
+
white-space: nowrap;
|
|
64
|
+
background-color: var(--#{$prefix}secondary-bg);
|
|
65
|
+
box-shadow: $lte-ribbon-shadow;
|
|
66
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
67
|
+
|
|
68
|
+
// Ribbons carry a `.text-bg-*` utility for colour, so the link only needs
|
|
69
|
+
// to inherit whatever contrast colour that utility picked.
|
|
70
|
+
a {
|
|
71
|
+
color: inherit;
|
|
72
|
+
text-decoration: none;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
package/src/scss/_variables.scss
CHANGED
|
@@ -118,6 +118,34 @@ $lte-progress-bar-border-radius: 1px !default;
|
|
|
118
118
|
// --------------------------------------------------------
|
|
119
119
|
$lte-callout-link-font-weight: $alert-link-font-weight !default;
|
|
120
120
|
|
|
121
|
+
// RIBBONS
|
|
122
|
+
// --------------------------------------------------------
|
|
123
|
+
// The size is the side of the square that clips the band; the band's own width
|
|
124
|
+
// is derived from it, so these are the only three values a theme has to change.
|
|
125
|
+
$lte-ribbon-size: 70px !default;
|
|
126
|
+
$lte-ribbon-size-lg: 110px !default;
|
|
127
|
+
$lte-ribbon-size-xl: 145px !default;
|
|
128
|
+
$lte-ribbon-font-size: .8rem !default;
|
|
129
|
+
$lte-ribbon-font-size-lg: 1rem !default;
|
|
130
|
+
$lte-ribbon-font-size-xl: 1.25rem !default;
|
|
131
|
+
$lte-ribbon-padding: .375rem 0 !default;
|
|
132
|
+
$lte-ribbon-font-weight: $font-weight-normal !default;
|
|
133
|
+
$lte-ribbon-shadow: 0 0 3px rgba(var(--#{$prefix}body-color-rgb), .3) !default;
|
|
134
|
+
|
|
135
|
+
// WIDGETS
|
|
136
|
+
// --------------------------------------------------------
|
|
137
|
+
$lte-user-block-avatar-size: 2.5rem !default;
|
|
138
|
+
$lte-user-block-avatar-size-sm: 1.75rem !default;
|
|
139
|
+
$lte-user-block-username-font-size: 1rem !default;
|
|
140
|
+
$lte-user-block-username-font-weight: $font-weight-semibold !default;
|
|
141
|
+
$lte-user-block-description-font-size: .8125rem !default;
|
|
142
|
+
// Kept in rem so the avatar's overhang past the header — half its own height —
|
|
143
|
+
// stays computable in Sass rather than needing calc() at runtime.
|
|
144
|
+
$lte-widget-user-header-padding: 1rem !default;
|
|
145
|
+
$lte-widget-user-header-height: 8.4375rem !default;
|
|
146
|
+
$lte-widget-user-image-size: 5.625rem !default;
|
|
147
|
+
$lte-widget-user-2-image-size: 4.0625rem !default;
|
|
148
|
+
|
|
121
149
|
// DIRECT CHAT
|
|
122
150
|
// --------------------------------------------------------
|
|
123
151
|
$lte-direct-chat-default-msg-bg: var(--#{$prefix}secondary-bg) !default;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Component: Widgets
|
|
3
|
+
//
|
|
4
|
+
// Social and post widgets: the profile cards and activity-feed blocks that v3
|
|
5
|
+
// shipped. The class names are kept from v3 so migrating markup keeps working,
|
|
6
|
+
// but the implementations are grid/flex rather than the original floats, and
|
|
7
|
+
// colour comes from Bootstrap utilities (`.text-bg-*`, `.rounded-circle`,
|
|
8
|
+
// `.shadow`) instead of AdminLTE-specific ones.
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
// A user's avatar, name and a line of meta, laid out from flat markup: the
|
|
12
|
+
// avatar spans both text rows, so no wrapper element is needed around them.
|
|
13
|
+
.user-block {
|
|
14
|
+
--#{$lte-prefix}user-block-avatar-size: #{$lte-user-block-avatar-size};
|
|
15
|
+
|
|
16
|
+
display: grid;
|
|
17
|
+
grid-template-columns: auto 1fr;
|
|
18
|
+
column-gap: .75rem;
|
|
19
|
+
align-items: center;
|
|
20
|
+
|
|
21
|
+
> img {
|
|
22
|
+
grid-row: 1 / span 2;
|
|
23
|
+
align-self: center;
|
|
24
|
+
width: var(--#{$lte-prefix}user-block-avatar-size);
|
|
25
|
+
height: var(--#{$lte-prefix}user-block-avatar-size);
|
|
26
|
+
object-fit: cover;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.username,
|
|
30
|
+
.description,
|
|
31
|
+
.comment {
|
|
32
|
+
grid-column: 2;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.username {
|
|
36
|
+
align-self: end;
|
|
37
|
+
font-size: $lte-user-block-username-font-size;
|
|
38
|
+
font-weight: $lte-user-block-username-font-weight;
|
|
39
|
+
|
|
40
|
+
a {
|
|
41
|
+
color: var(--#{$prefix}emphasis-color);
|
|
42
|
+
text-decoration: none;
|
|
43
|
+
|
|
44
|
+
&:hover,
|
|
45
|
+
&:focus-visible {
|
|
46
|
+
text-decoration: underline;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.description {
|
|
52
|
+
align-self: start;
|
|
53
|
+
font-size: $lte-user-block-description-font-size;
|
|
54
|
+
color: var(--#{$prefix}secondary-color);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.comment {
|
|
58
|
+
margin-top: .5rem;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// In a card header a user block stands in for .card-title, so it floats the
|
|
62
|
+
// same way — otherwise the grid box claims the full line and the floated
|
|
63
|
+
// .card-tools drop below it.
|
|
64
|
+
.card-header > & {
|
|
65
|
+
float: left;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&.user-block-sm {
|
|
69
|
+
--#{$lte-prefix}user-block-avatar-size: #{$lte-user-block-avatar-size-sm};
|
|
70
|
+
|
|
71
|
+
.username {
|
|
72
|
+
font-size: $lte-user-block-description-font-size;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.description {
|
|
76
|
+
font-size: .75rem;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// One entry in an activity feed. Dividers sit between entries only, so the last
|
|
82
|
+
// post doesn't add trailing space inside its card.
|
|
83
|
+
.post {
|
|
84
|
+
padding-bottom: 1rem;
|
|
85
|
+
margin-bottom: 1rem;
|
|
86
|
+
border-bottom: 1px solid var(--#{$prefix}border-color);
|
|
87
|
+
|
|
88
|
+
&:last-of-type {
|
|
89
|
+
padding-bottom: 0;
|
|
90
|
+
margin-bottom: 0;
|
|
91
|
+
border-bottom: 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.user-block {
|
|
95
|
+
margin-bottom: .75rem;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// A labelled figure, typically repeated across a card footer's grid columns.
|
|
100
|
+
.description-block {
|
|
101
|
+
display: block;
|
|
102
|
+
margin: .625rem 0;
|
|
103
|
+
text-align: center;
|
|
104
|
+
|
|
105
|
+
.description-header {
|
|
106
|
+
padding: 0;
|
|
107
|
+
margin: 0;
|
|
108
|
+
font-size: 1.0625rem;
|
|
109
|
+
font-weight: $font-weight-bold;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.description-text {
|
|
113
|
+
font-size: $lte-user-block-description-font-size;
|
|
114
|
+
color: var(--#{$prefix}secondary-color);
|
|
115
|
+
text-transform: uppercase;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Profile card with a banner header and an avatar straddling the seam between
|
|
120
|
+
// the header and the footer.
|
|
121
|
+
.widget-user {
|
|
122
|
+
.widget-user-header {
|
|
123
|
+
height: $lte-widget-user-header-height;
|
|
124
|
+
padding: $lte-widget-user-header-padding;
|
|
125
|
+
text-align: center;
|
|
126
|
+
background-position: center;
|
|
127
|
+
background-size: cover;
|
|
128
|
+
@include border-top-radius(inherit);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.widget-user-username {
|
|
132
|
+
margin-top: 0;
|
|
133
|
+
margin-bottom: .3125rem;
|
|
134
|
+
font-size: 1.5625rem;
|
|
135
|
+
font-weight: $font-weight-light;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.widget-user-desc {
|
|
139
|
+
margin-top: 0;
|
|
140
|
+
font-size: 1rem;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.widget-user-image {
|
|
144
|
+
position: absolute;
|
|
145
|
+
top: $lte-widget-user-header-height - ($lte-widget-user-image-size * .5);
|
|
146
|
+
right: 0;
|
|
147
|
+
left: 0;
|
|
148
|
+
width: $lte-widget-user-image-size;
|
|
149
|
+
margin-inline: auto;
|
|
150
|
+
|
|
151
|
+
> img {
|
|
152
|
+
width: 100%;
|
|
153
|
+
height: auto;
|
|
154
|
+
border: 3px solid var(--#{$prefix}body-bg);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Clear the half of the avatar that overhangs the header.
|
|
159
|
+
> .card-footer {
|
|
160
|
+
padding-top: ($lte-widget-user-image-size * .5) + .75rem;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Same idea with the avatar inline in the header — shorter, and it survives
|
|
165
|
+
// long names better because the text column can wrap.
|
|
166
|
+
.widget-user-2 {
|
|
167
|
+
.widget-user-header {
|
|
168
|
+
display: flex;
|
|
169
|
+
column-gap: 1rem;
|
|
170
|
+
align-items: center;
|
|
171
|
+
padding: $lte-widget-user-header-padding;
|
|
172
|
+
@include border-top-radius(inherit);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.widget-user-image > img {
|
|
176
|
+
width: $lte-widget-user-2-image-size;
|
|
177
|
+
height: $lte-widget-user-2-image-size;
|
|
178
|
+
object-fit: cover;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.widget-user-username {
|
|
182
|
+
margin-top: 0;
|
|
183
|
+
margin-bottom: .3125rem;
|
|
184
|
+
font-size: 1.5625rem;
|
|
185
|
+
font-weight: $font-weight-light;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.widget-user-desc {
|
|
189
|
+
margin-top: 0;
|
|
190
|
+
font-size: 1rem;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* AdminLTE v4.
|
|
2
|
+
* AdminLTE v4.3.1 — documentation styles
|
|
3
3
|
* Styles for the documentation and FAQ pages only (body.docs-page /
|
|
4
4
|
* body.faq-page). Applications never need this file; it is loaded by the
|
|
5
5
|
* docs pages in addition to adminlte.css.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* AdminLTE v4.2.0 — Select2 compatibility theme
|
|
3
|
+
* Styling only. AdminLTE bundles neither Select2 nor jQuery; this optional
|
|
4
|
+
* sheet makes a Select2 you load yourself match Bootstrap 5.3 form controls,
|
|
5
|
+
* including `data-bs-theme` dark mode. Load it AFTER select2.css.
|
|
6
|
+
* New code should prefer Tom Select — see docs/integrations.html.
|
|
7
|
+
*
|
|
8
|
+
* Author: Colorlib
|
|
9
|
+
* Website: AdminLTE.io <https://adminlte.io>
|
|
10
|
+
* License: Open source - MIT <https://opensource.org/licenses/MIT>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Bootstrap Configuration
|
|
14
|
+
// ---------------------------------------------------
|
|
15
|
+
@import "bootstrap/scss/functions";
|
|
16
|
+
@import "bootstrap-overrides";
|
|
17
|
+
@import "bootstrap/scss/variables";
|
|
18
|
+
@import "bootstrap/scss/variables-dark";
|
|
19
|
+
@import "bootstrap/scss/maps";
|
|
20
|
+
@import "bootstrap/scss/mixins";
|
|
21
|
+
|
|
22
|
+
// AdminLTE Configuration
|
|
23
|
+
// ---------------------------------------------------
|
|
24
|
+
// `mixins` is deliberately not imported: it emits AdminLTE's @keyframes, and
|
|
25
|
+
// this sheet only uses Bootstrap's own mixins.
|
|
26
|
+
@import "variables";
|
|
27
|
+
@import "variables-dark";
|
|
28
|
+
|
|
29
|
+
// Select2 compatibility styles
|
|
30
|
+
// ---------------------------------------------------
|
|
31
|
+
@import "compat/select2";
|
package/src/scss/adminlte.scss
CHANGED