mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-12 05:47:51 +08:00
🦄 Sync 2026-07-26 23:49:39
This commit is contained in:
1 parent
2450ea7cca
commit
bf03fd23d8
20 files changed
+482
-145
No files matched your search
@@ -1,5 +1,9 @@
|
||||
/* The bar carries no colour transition: one would ease its bg/text over
|
||||
--mega-menu-duration on every data-darkmode flip, lagging the bar behind
|
||||
the untransitioned page in all three nav modes. The mega-menu wipe colour
|
||||
lives on .desktop-menu-sheet below, which owns its transition. */
|
||||
header {
|
||||
@apply bg-bg sticky top-0 z-40 mb-2 transition-colors duration-(--mega-menu-duration,300ms) ease-[cubic-bezier(0.4,0,0.6,1)];
|
||||
@apply bg-bg sticky top-0 z-40 mb-2;
|
||||
|
||||
& .header-content {
|
||||
@apply relative z-10 flex h-14 items-center justify-between px-6 py-3 max-md:px-4 max-md:py-2;
|
||||
@@ -266,9 +270,11 @@ header {
|
||||
@apply md:flex;
|
||||
}
|
||||
|
||||
/* D1 底线呼吸:展开态沿用短底线汉堡;折叠后底线伸满(三线齐整 =
|
||||
侧栏收纳完毕)。dasharray 只改可见长度,线帽形状不受影响。 */
|
||||
[data-nav-type="sidebar"].sidebar-collapsed
|
||||
/* D1 底线呼吸(2026-07 反转):展开后底线伸满 —— 三线齐整 = 内容
|
||||
全部亮出;折叠态回落到短底线 = 还有内容收着,缺口招手可展开。
|
||||
与耦合滑动同向:侧栏进场线补齐,退场线让位。dasharray 只改可见
|
||||
长度,线帽形状不受影响。 */
|
||||
[data-nav-type="sidebar"]:not(.sidebar-collapsed)
|
||||
&
|
||||
.navigation-toggle-line-bottom {
|
||||
@apply md:[stroke-dasharray:15_15];
|
||||
@@ -284,6 +290,12 @@ header {
|
||||
& .navigation-toggle-line {
|
||||
transform-box: fill-box;
|
||||
@apply origin-center transition-[transform,opacity,stroke-dasharray] duration-150 ease-in-out;
|
||||
|
||||
/* Desktop sidebar: the dasharray breath runs in step with the
|
||||
250ms coupled slide (the mobile X morph keeps its snappy 150). */
|
||||
[data-nav-type="sidebar"] & {
|
||||
@apply md:duration-[250ms];
|
||||
}
|
||||
}
|
||||
|
||||
/* Tabler menu-2 geometry: all three lines are full-length equals.
|
||||
@@ -356,8 +368,11 @@ body[data-nav-type="sidebar"] {
|
||||
overflow-x-clip keeps the sliding sidebar out of horizontal overflow. */
|
||||
|
||||
/* Single source of truth for the sidebar column, so collapsing only has to
|
||||
zero this one value instead of restating the grid template. */
|
||||
--sidebar-w: 17rem;
|
||||
zero this one value instead of restating the grid template.
|
||||
--sidebar-w-full stays constant: the inner panel width and the slide
|
||||
keyframes read it, and must not see the zeroed collapsed value. */
|
||||
--sidebar-w-full: 17rem;
|
||||
--sidebar-w: var(--sidebar-w-full);
|
||||
|
||||
@apply md:grid md:grid-cols-[var(--sidebar-w)_minmax(0,1fr)] md:grid-rows-[auto_minmax(0,1fr)] md:overflow-x-clip;
|
||||
|
||||
@@ -410,29 +425,60 @@ body[data-nav-type="sidebar"] {
|
||||
}
|
||||
|
||||
& .sidebar-panel {
|
||||
@apply border-hairline sticky top-0 hidden h-dvh w-full overflow-hidden rounded-none border-r transition-[visibility] duration-[250ms] md:block;
|
||||
@apply sticky top-0 hidden h-dvh w-full overflow-hidden rounded-none md:block;
|
||||
}
|
||||
|
||||
/* The grid column snaps closed to avoid a full-page layout animation.
|
||||
Visibility removes collapsed controls from the tab order; on expansion,
|
||||
the inner panel still enters via compositor-only translate + opacity. */
|
||||
/* The grid column still snaps (one reflow, never a per-frame layout
|
||||
animation); visibility removes collapsed controls from the tab order.
|
||||
The hairline lives on the inner panel, not the frame, so it tracks the
|
||||
sliding edge during the run animations below. */
|
||||
&.sidebar-collapsed .sidebar-panel {
|
||||
@apply invisible;
|
||||
}
|
||||
|
||||
& .sidebar-panel-inner {
|
||||
@apply bg-bg flex h-full w-68 flex-col overflow-hidden transition-[translate,opacity] duration-[250ms];
|
||||
@apply bg-bg border-hairline flex h-full w-(--sidebar-w-full) flex-col overflow-hidden border-r;
|
||||
}
|
||||
|
||||
&.sidebar-collapsed .sidebar-panel-inner {
|
||||
@apply -translate-x-full opacity-0;
|
||||
@apply -translate-x-full;
|
||||
}
|
||||
|
||||
/* Coupled slide: the column width snaps in the same frame the
|
||||
sidebar-anim-* class lands, then the sidebar and the whole content
|
||||
column (header + #maincontent) slide the same 17rem with the same
|
||||
curve — compositor-only, so the seam moves as one wall with zero
|
||||
per-frame reflow. menu-aurora.js swaps the class per direction
|
||||
(distinct animation-names restart cleanly on rapid toggles) and
|
||||
clears it after the run. */
|
||||
&.sidebar-anim-open > header,
|
||||
&.sidebar-anim-open > #maincontent,
|
||||
&.sidebar-anim-open .sidebar-panel-inner {
|
||||
@apply md:animate-[sidebar-run-in_250ms_var(--ease-in-out)_both];
|
||||
}
|
||||
|
||||
&.sidebar-anim-close > header,
|
||||
&.sidebar-anim-close > #maincontent {
|
||||
@apply md:animate-[sidebar-run-back_250ms_var(--ease-in-out)_both];
|
||||
}
|
||||
|
||||
/* Closing: the column is already zero, so the panel holds its old spot
|
||||
as a fixed overlay for one run while its content slides off. */
|
||||
&.sidebar-anim-close .sidebar-panel {
|
||||
@apply md:visible md:fixed md:top-0 md:left-0 md:w-(--sidebar-w-full);
|
||||
}
|
||||
|
||||
&.sidebar-anim-close .sidebar-panel-inner {
|
||||
@apply md:animate-[sidebar-run-out_250ms_var(--ease-in-out)_both];
|
||||
}
|
||||
|
||||
/* Sidebar head: logo + hostname. h-14 matches the header row so its
|
||||
bottom hairline continues the header's border in one unbroken line
|
||||
across the viewport. */
|
||||
across the viewport. box-content: the header is auto-height (56px
|
||||
content + border OUTSIDE), so this border must sit outside its 56px
|
||||
too — border-box would paint it one pixel higher than the header's. */
|
||||
& .sidebar-head {
|
||||
@apply border-hairline flex h-14 shrink-0 items-center gap-2.5 border-b px-4;
|
||||
@apply border-hairline box-content flex h-14 shrink-0 items-center gap-2.5 border-b px-4;
|
||||
|
||||
& .sidebar-logo {
|
||||
@apply size-5 shrink-0 rounded-md;
|
||||
@@ -475,6 +521,26 @@ body[data-nav-type="sidebar"] {
|
||||
}
|
||||
}
|
||||
|
||||
/* Shared travel distance for the coupled sidebar slide: content column and
|
||||
panel move the same 17rem, so the seam between them never separates. */
|
||||
@keyframes sidebar-run-in {
|
||||
from {
|
||||
translate: calc(-1 * var(--sidebar-w-full)) 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sidebar-run-back {
|
||||
from {
|
||||
translate: var(--sidebar-w-full) 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sidebar-run-out {
|
||||
to {
|
||||
translate: calc(-1 * var(--sidebar-w-full)) 0;
|
||||
}
|
||||
}
|
||||
|
||||
#maincontent {
|
||||
/* Centred shells (top-bar navigation) clamp here and gutter the remainder.
|
||||
The sidebar shell overrides this — it caps the shell instead, see
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
}
|
||||
|
||||
.navigation-group-toggle {
|
||||
@apply after:size-3.5 after:shrink-0 after:bg-current after:opacity-55 after:transition-[transform,opacity] after:duration-[250ms] after:content-[''] after:[mask:var(--icon-arrow-right)_center/cover_no-repeat] hover:after:opacity-100;
|
||||
/* size-4.5 ≈ the row's text height — 3.5 read as undersized next to the
|
||||
text-lg category labels, on desktop and in the mobile drawer alike. */
|
||||
@apply after:size-4.5 after:shrink-0 after:bg-current after:opacity-55 after:transition-[transform,opacity] after:duration-[250ms] after:content-[''] after:[mask:var(--icon-arrow-right)_center/cover_no-repeat] hover:after:opacity-100;
|
||||
}
|
||||
|
||||
.nav-category-label {
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
}
|
||||
|
||||
.cmdk-panel {
|
||||
@apply border-hairline bg-surface/85 fixed top-24 left-1/2 z-120 w-[min(36rem,calc(100vw-2.5rem))] -translate-x-1/2 overflow-hidden rounded-3xl border shadow-xl backdrop-blur-xl backdrop-saturate-150 transition-[opacity,translate] duration-150 ease-out starting:-translate-y-2 starting:opacity-0;
|
||||
@apply border-hairline bg-surface/85 fixed top-24 left-1/2 z-120 w-[min(36rem,calc(100vw-2.5rem))] -translate-x-1/2 overflow-hidden rounded-2xl border shadow-xl backdrop-blur-xl backdrop-saturate-150 transition-[opacity,translate] duration-150 ease-out starting:-translate-y-2 starting:opacity-0;
|
||||
|
||||
/* <md: the same panel becomes a full-screen takeover (Algolia DocSearch
|
||||
manner) — opaque page background (no full-screen blur cost on phones),
|
||||
|
||||
@@ -30,6 +30,7 @@ return baseclass.extend({
|
||||
const mobileList = overlay.querySelector("#mobile-nav-list");
|
||||
const desktop = window.matchMedia("(min-width: 768px)");
|
||||
const SIDEBAR_COLLAPSED_KEY = "aurora.sidebarCollapsed";
|
||||
let sidebarAnimTimer;
|
||||
|
||||
const isDesktopSidebar = () =>
|
||||
desktop.matches && document.body.dataset.navType === "sidebar";
|
||||
@@ -79,7 +80,23 @@ return baseclass.extend({
|
||||
closeMobileNavigation();
|
||||
|
||||
const collapsed = !expanded;
|
||||
document.body.classList.toggle("sidebar-collapsed", collapsed);
|
||||
const body = document.body;
|
||||
|
||||
// Coupled slide (_layout.css): the class must land in the same
|
||||
// frame as the column snap. Open/close carry distinct
|
||||
// animation-names, so alternating toggles restart the run without
|
||||
// a forced reflow; the timer (not animationend — three elements
|
||||
// animate) clears the class once the 250ms run is over.
|
||||
body.classList.remove("sidebar-anim-open", "sidebar-anim-close");
|
||||
body.classList.add(
|
||||
collapsed ? "sidebar-anim-close" : "sidebar-anim-open",
|
||||
);
|
||||
clearTimeout(sidebarAnimTimer);
|
||||
sidebarAnimTimer = setTimeout(() => {
|
||||
body.classList.remove("sidebar-anim-open", "sidebar-anim-close");
|
||||
}, 300);
|
||||
|
||||
body.classList.toggle("sidebar-collapsed", collapsed);
|
||||
localStorage.setItem(SIDEBAR_COLLAPSED_KEY, collapsed);
|
||||
updateToggleState(expanded);
|
||||
return;
|
||||
@@ -488,7 +505,7 @@ return baseclass.extend({
|
||||
this.bindNavigationAccordion(list);
|
||||
|
||||
crumb.forEach((title, i) => {
|
||||
if (i) crumbEl?.appendChild(E("li", { class: "crumb-sep" }, ["›"]));
|
||||
if (i) crumbEl?.appendChild(E("li", { class: "crumb-sep" }, ["/"]));
|
||||
crumbEl?.appendChild(
|
||||
E("li", { class: i === crumb.length - 1 ? "current" : "" }, [title]),
|
||||
);
|
||||
@@ -533,12 +550,14 @@ return baseclass.extend({
|
||||
// index — matched and rendered like pages, grouped under _("Design")
|
||||
// (the System → Language and Style label) — but execute header.ut's
|
||||
// global setTheme() instead of navigating, so the panel stays open and
|
||||
// previews the switch live. luci-base has no Light/Dark msgids — they
|
||||
// stay English literals, wrapped in _() so a future catalog entry would
|
||||
// take effect (the same trade the icon-only switcher makes).
|
||||
// previews the switch live. luci-base carries no mode msgids, so the
|
||||
// labels borrow luci-app-aurora-config's already-translated "Light
|
||||
// Mode"/"Dark Mode" — matching its msgids verbatim is what makes the
|
||||
// palette follow the UI language wherever the config app is installed,
|
||||
// and they fall back to English where it isn't.
|
||||
[
|
||||
["light", _("Light")],
|
||||
["dark", _("Dark")],
|
||||
["light", _("Light Mode")],
|
||||
["dark", _("Dark Mode")],
|
||||
["device", _("Automatic")],
|
||||
].forEach(([mode, title]) =>
|
||||
this.paletteIndex.push({
|
||||
@@ -549,8 +568,9 @@ return baseclass.extend({
|
||||
}),
|
||||
);
|
||||
|
||||
// Only msgids that already exist in the luci-base catalog are used —
|
||||
// the theme intentionally ships no translations of its own.
|
||||
// Only msgids that already exist in a shipped catalog (luci-base, or the
|
||||
// config app's as above) are used — the theme intentionally ships no
|
||||
// translations of its own.
|
||||
const isMac = /Mac|iP(ad|hone|od)/.test(navigator.platform);
|
||||
this.paletteKey = isMac ? "⌘K" : "Ctrl+K";
|
||||
toggle.setAttribute("aria-keyshortcuts", isMac ? "Meta+K" : "Control+K");
|
||||
@@ -1039,8 +1059,9 @@ return baseclass.extend({
|
||||
);
|
||||
}
|
||||
// Both vars live on the header, not the container: the container
|
||||
// inherits the height, and the header's own transition-colors reads
|
||||
// the duration so the bar colour fades in lockstep with the wipe.
|
||||
// inherits both, and the close fallback timer reads the duration
|
||||
// back off the header (the bar itself must stay transition-free so
|
||||
// theme flips repaint it in the same frame as the page).
|
||||
header.style.setProperty("--mega-menu-height", `${canvasHeight}px`);
|
||||
header.style.setProperty("--mega-menu-duration", `${revealDuration}ms`);
|
||||
};
|
||||
|
||||
@@ -729,7 +729,7 @@ test("renders sidebar items, logout, and translated crumbs without duplication",
|
||||
assert.equal(crumb.children.length, 3);
|
||||
assert.deepEqual(
|
||||
crumb.children.map((child) => textContent(child)),
|
||||
["translated:Network", "›", "translated:Wireless"],
|
||||
["translated:Network", "/", "translated:Wireless"],
|
||||
);
|
||||
assert.equal(crumb.children[2].getAttribute("class"), "current");
|
||||
assert.equal(list.dataset.accordionBound, "true");
|
||||
|
||||
@@ -83,7 +83,7 @@ test("shared navigation styles define active and expanded states", () => {
|
||||
assertIncludesUtilities(sublink, [
|
||||
"font-medium",
|
||||
"hover:bg-hover-faint",
|
||||
"rounded-lg",
|
||||
"rounded-xl",
|
||||
]);
|
||||
assertIncludesUtilities(activeSublink, [
|
||||
"text-brand",
|
||||
@@ -212,6 +212,20 @@ test("mega-menu reveal and retract share the page-top origin", () => {
|
||||
assert.doesNotMatch(headerLift ?? "", /bg-mega-menu-bg/);
|
||||
});
|
||||
|
||||
test("theme flips repaint the bar in the same frame as the page", () => {
|
||||
const headerDeclaration = layoutStyles.match(
|
||||
/^header \{\s*@apply ([^;]+);/m,
|
||||
)?.[1];
|
||||
|
||||
assert.ok(headerDeclaration, "Missing header root declaration");
|
||||
assertIncludesUtilities(headerDeclaration, ["bg-bg", "sticky"]);
|
||||
// A colour transition on the bar itself would ease its bg/text over
|
||||
// --mega-menu-duration on every data-darkmode flip, lagging the bar behind
|
||||
// the untransitioned page in all three nav modes. The mega-menu wipe colour
|
||||
// lives on .desktop-menu-sheet, which carries its own transition.
|
||||
assert.doesNotMatch(headerDeclaration, /\btransition/);
|
||||
});
|
||||
|
||||
test("mega-menu category masks use Tailwind arbitrary utilities", () => {
|
||||
const title = getBlock(layoutStyles, "& .desktop-nav-title");
|
||||
const icon = getBlock(title, "&::before");
|
||||
|
||||
@@ -167,7 +167,8 @@ test("content dropdowns stay above the closed header and below the open mega-men
|
||||
/\[data-nav-type="mega-menu"\]\s*&:has\([\s\S]*?\.desktop-menu-container[\s\S]*?\.active[\s\S]*?\)\s*\{\s*@apply\s+([^;]+);/,
|
||||
)?.[1] ?? "";
|
||||
const dropdownRule = dropdown.match(/&\.dropdown\s*\{\s*@apply\s+([^;]+);/)?.[1] ?? "";
|
||||
const messageRule = message.match(/\.alert-message\s*\{\s*@apply\s+([^;]+);/)?.[1] ?? "";
|
||||
const messageRule =
|
||||
message.match(/\.alert-message\s*\{[\s\S]*?@apply\s+([^;]+);/)?.[1] ?? "";
|
||||
const overlayRule =
|
||||
overlay.match(/& \.desktop-menu-overlay\s*\{\s*@apply\s+([^;]+);/)?.[1] ?? "";
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
|
||||
LUCI_TITLE:=Aurora Theme (A modern browser theme built with Vite and Tailwind CSS)
|
||||
LUCI_DEPENDS:=+luci-base
|
||||
|
||||
PKG_VERSION:=1.1.4
|
||||
PKG_RELEASE:=58
|
||||
PKG_VERSION:=1.1.6
|
||||
PKG_RELEASE:=59
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
LUCI_MINIFY_CSS:=
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
|
||||
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-border-style:solid;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-content:"";--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-border-spacing-x:0;--tw-border-spacing-y:0}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:var(--spacing);--container-xs:20rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-md:12px;--blur-lg:16px;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1Line truncated
|
||||
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-border-style:solid;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-content:"";--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-border-spacing-x:0;--tw-border-spacing-y:0}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:var(--spacing);--container-xs:20rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--blur-md:12px;--blur-lg:16px;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1Line truncated
|
||||
@@ -1 +1 @@
|
||||
"use strict";"require baseclass";"require ui";return baseclass.extend({__init__(){ui.menu.load().then(e=>this.render(e)),this.initNavigationControls(),this.initUciIndicator()},initUciIndicator(){const e=ui.changes?.setIndicator;e&&(ui.changes.setIndicator=function(t){e.call(this,t),document.querySelector('[data-indicator="uci-changes"]')?.setAttribute("data-count",t||0)})},initNavigationControls(){const e=document.querySelector("#mobile-menu-overlay"),t=document.querySelector("#navigation-toggle");if(!t||!e)return;const i=e.querySelector("#mobile-nav-list"),n=window.matchMedia("(min-width: 768px)"),a="aurora.sidebarCollapsed",s=()=>n.matches&&"sidebar"===document.body.dataset.navType,o=e=>{const i=s();t.classList.toggle("is-expanded",e&&!n.matches),t.setAttribute("aria-expanded",e?"true":"false"),t.setAttribute("aria-controls",i?"sidebar-panel":"mobile-menu-overlay");const a=e&&!i?_("Close"):_("Navigation");t.setAttribute("title",a),t.setAttribute("aria-label",a)},l=()=>{e.classList.remove("mobile-menu-open"),document.body.classList.remove("mobile-navigation-open"),document.body.style.overflow="",this.resetNavigationGroups(i)},r=t=>{if(s()){l();const e=!t;return document.body.classList.toggle("sidebar-collapsed",e),localStorage.setItem(a,e),void o(t)}if(n.matches)return l(),void o(!1);e.classList.toggle("mobile-menu-open",t),document.body.classList.toggle("mobile-navigation-open",t),document.body.style.overflow=t?"hidden":"",t?this.expandActiveNavigationGroup(i):this.resetNavigationGroups(i),o(t)},c=()=>{if(l(),s()){const e="true"===localStorage.getItem(a);return document.body.classList.toggle("sidebar-collapsed",e),void o(!e)}o(!1)};t.addEventListener("click",t=>{t.stopPropagation(),r(!(s()?!document.body.classList.contains("sidebar-collapsed"):!n.matches&&e.classList.contains("mobile-menu-open")))}),e.addEventListener("click",t=>{t.target===e&&r(!1)}),document.addEventListener("keydown",t=>{"Escape"===t.key&&e.classList.contains("mobile-menu-open")&&r(!1)}),n.addEventListener("change",c),c(),document.addEventListener("click",t=>{const i=t.target?.closest?.(".navigation-direct, .navigation-sublink, .mobile-nav-logout");i&&e.contains(i)&&r(!1)})},renderMobileMenu(e){const t=document.querySelector("#mobile-nav-list"),i=document.querySelector("#mobile-nav-footer-action");t&&(t.innerHTML=""),i&&(i.innerHTML=""),t&&(e.forEach(e=>{e.isLogout?i&&i.appendChild(E("a",{class:"mobile-nav-logout",href:e.href},[e.title])):t.appendChild(this.renderNavigationItem(e,"mobile"))}),this.bindNavigationAccordion(t))},render(e){if(this.renderModeMenu(e),L.env.dispatchpath.length>=3){let t=e,i="";for(let e=0;e<3&&t;e++){const n=L.env.dispatchpath[e];t=t.children?.[n],i+=(i?"/":"")+n}t&&this.renderTabMenu(t,i)}},renderTabMenu(e,t,i=0){const n=document.querySelector("#tabmenu"),a=E("ul",{class:"tabs"}),s=ui.menu.getChildren(e);let o=null;return s.forEach(e=>{const n=L.env.dispatchpath[3+i]===e.name;a.appendChild(E("li",{class:`tabmenu-item-${e.name}${n?" active":""}`},[E("a",{href:L.url(t,e.name)},[_(e.title)])])),n&&(o=e)}),a.children.length?(n.appendChild(a),n.style.display="",o&&this.renderTabMenu(o,`${t}/${o.name}`,i+1),a):E([])},renderMainMenu(e,t,i=0,n=null){const a=i?E("ul",{class:"desktop-nav-list"}):document.querySelector("#topmenu"),s=ui.menu.getChildren(e);if(i>1)return E([]);if(0===i){const e=document.body?.dataset?.navType||"mega-menu";if("sidebar"===e)return this.renderSidebar(n||[]),a||E([]);if(!a||!s.length)return E([]);"mega-menu"===e?this.initMegaMenu(s,t,a):this.initDropdown(s,t,a)}else{if(!s.length)return E([]);s.forEach(i=>{const n=this.isActivePath(e.name,i.name),s={class:n?"is-active-page":"",href:L.url(t,i.name)};n&&(s["aria-current"]="page"),a.appendChild(E("li",{},[E("a",s,[_(i.title)])]))})}return a.style.display="",a},isActivePath:(e,t)=>L.env.dispatchpath[1]===e&&(null==t||L.env.dispatchpath[2]===t),buildNavigationModel(e,t){return e.filter(e=>e?.name).map(e=>{const i=ui.menu.getChildren(e).filter(e=>e?.name).map(i=>({name:i.name,title:_(i.title),href:L.url(t,e.name,i.name),isActivePage:this.isActivePath(e.name,i.name)})),n=i.length>0,a=this.isActivePath(e.name);return{name:e.name,title:_(e.title),href:L.url(t,e.name),hasChildren:n,isLogout:"logout"===e.name,isActiveGroup:n&&a,isActivePage:!n&&a,activePage:i.find(e=>e.isActivePage)||null,pages:i}})},navigationSubmenuId:(e,t)=>`${e}-submenu-${encodeURIComponent(String(t))}`,renderNavigationItem(e,t){const i="mobile"===t,n=i?"mobile-nav-item":"",a=i?"navigation-direct mobile-nav-link":"navigation-direct nav-link";if(!e.hasChildren){const t={class:`${a}${e.isActivePage?" is-active-page":""}`,href:e.href};return e.isActivePage&&(t["aria-current"]="page"),E("li",{class:n},[E("a",t,[e.title])])}const s=this.navigationSubmenuId(t,e.name),o=["navigation-group",i?"mobile-nav-item":"sidebar-group",e.isActiveGroup?"is-active-group":"",e.isActiveGroup?"is-expanded":""].filter(Boolean),l={class:i?"navigation-group-toggle mobile-nav-link mobile-nav-toggle":"navigatLine truncated
|
||||
"use strict";"require baseclass";"require ui";return baseclass.extend({__init__(){ui.menu.load().then(e=>this.render(e)),this.initNavigationControls(),this.initUciIndicator()},initUciIndicator(){const e=ui.changes?.setIndicator;e&&(ui.changes.setIndicator=function(t){e.call(this,t),document.querySelector('[data-indicator="uci-changes"]')?.setAttribute("data-count",t||0)})},initNavigationControls(){const e=document.querySelector("#mobile-menu-overlay"),t=document.querySelector("#navigation-toggle");if(!t||!e)return;const i=e.querySelector("#mobile-nav-list"),a=window.matchMedia("(min-width: 768px)"),n="aurora.sidebarCollapsed";let s;const o=()=>a.matches&&"sidebar"===document.body.dataset.navType,l=e=>{const i=o();t.classList.toggle("is-expanded",e&&!a.matches),t.setAttribute("aria-expanded",e?"true":"false"),t.setAttribute("aria-controls",i?"sidebar-panel":"mobile-menu-overlay");const n=e&&!i?_("Close"):_("Navigation");t.setAttribute("title",n),t.setAttribute("aria-label",n)},r=()=>{e.classList.remove("mobile-menu-open"),document.body.classList.remove("mobile-navigation-open"),document.body.style.overflow="",this.resetNavigationGroups(i)},c=t=>{if(o()){r();const e=!t,i=document.body;return i.classList.remove("sidebar-anim-open","sidebar-anim-close"),i.classList.add(e?"sidebar-anim-close":"sidebar-anim-open"),clearTimeout(s),s=setTimeout(()=>{i.classList.remove("sidebar-anim-open","sidebar-anim-close")},300),i.classList.toggle("sidebar-collapsed",e),localStorage.setItem(n,e),void l(t)}if(a.matches)return r(),void l(!1);e.classList.toggle("mobile-menu-open",t),document.body.classList.toggle("mobile-navigation-open",t),document.body.style.overflow=t?"hidden":"",t?this.expandActiveNavigationGroup(i):this.resetNavigationGroups(i),l(t)},d=()=>{if(r(),o()){const e="true"===localStorage.getItem(n);return document.body.classList.toggle("sidebar-collapsed",e),void l(!e)}l(!1)};t.addEventListener("click",t=>{t.stopPropagation(),c(!(o()?!document.body.classList.contains("sidebar-collapsed"):!a.matches&&e.classList.contains("mobile-menu-open")))}),e.addEventListener("click",t=>{t.target===e&&c(!1)}),document.addEventListener("keydown",t=>{"Escape"===t.key&&e.classList.contains("mobile-menu-open")&&c(!1)}),a.addEventListener("change",d),d(),document.addEventListener("click",t=>{const i=t.target?.closest?.(".navigation-direct, .navigation-sublink, .mobile-nav-logout");i&&e.contains(i)&&c(!1)})},renderMobileMenu(e){const t=document.querySelector("#mobile-nav-list"),i=document.querySelector("#mobile-nav-footer-action");t&&(t.innerHTML=""),i&&(i.innerHTML=""),t&&(e.forEach(e=>{e.isLogout?i&&i.appendChild(E("a",{class:"mobile-nav-logout",href:e.href},[e.title])):t.appendChild(this.renderNavigationItem(e,"mobile"))}),this.bindNavigationAccordion(t))},render(e){if(this.renderModeMenu(e),L.env.dispatchpath.length>=3){let t=e,i="";for(let e=0;e<3&&t;e++){const a=L.env.dispatchpath[e];t=t.children?.[a],i+=(i?"/":"")+a}t&&this.renderTabMenu(t,i)}},renderTabMenu(e,t,i=0){const a=document.querySelector("#tabmenu"),n=E("ul",{class:"tabs"}),s=ui.menu.getChildren(e);let o=null;return s.forEach(e=>{const a=L.env.dispatchpath[3+i]===e.name;n.appendChild(E("li",{class:`tabmenu-item-${e.name}${a?" active":""}`},[E("a",{href:L.url(t,e.name)},[_(e.title)])])),a&&(o=e)}),n.children.length?(a.appendChild(n),a.style.display="",o&&this.renderTabMenu(o,`${t}/${o.name}`,i+1),n):E([])},renderMainMenu(e,t,i=0,a=null){const n=i?E("ul",{class:"desktop-nav-list"}):document.querySelector("#topmenu"),s=ui.menu.getChildren(e);if(i>1)return E([]);if(0===i){const e=document.body?.dataset?.navType||"mega-menu";if("sidebar"===e)return this.renderSidebar(a||[]),n||E([]);if(!n||!s.length)return E([]);"mega-menu"===e?this.initMegaMenu(s,t,n):this.initDropdown(s,t,n)}else{if(!s.length)return E([]);s.forEach(i=>{const a=this.isActivePath(e.name,i.name),s={class:a?"is-active-page":"",href:L.url(t,i.name)};a&&(s["aria-current"]="page"),n.appendChild(E("li",{},[E("a",s,[_(i.title)])]))})}return n.style.display="",n},isActivePath:(e,t)=>L.env.dispatchpath[1]===e&&(null==t||L.env.dispatchpath[2]===t),buildNavigationModel(e,t){return e.filter(e=>e?.name).map(e=>{const i=ui.menu.getChildren(e).filter(e=>e?.name).map(i=>({name:i.name,title:_(i.title),href:L.url(t,e.name,i.name),isActivePage:this.isActivePath(e.name,i.name)})),a=i.length>0,n=this.isActivePath(e.name);return{name:e.name,title:_(e.title),href:L.url(t,e.name),hasChildren:a,isLogout:"logout"===e.name,isActiveGroup:a&&n,isActivePage:!a&&n,activePage:i.find(e=>e.isActivePage)||null,pages:i}})},navigationSubmenuId:(e,t)=>`${e}-submenu-${encodeURIComponent(String(t))}`,renderNavigationItem(e,t){const i="mobile"===t,a=i?"mobile-nav-item":"",n=i?"navigation-direct mobile-nav-link":"navigation-direct nav-link";if(!e.hasChildren){const t={class:`${n}${e.isActivePage?" is-active-page":""}`,href:e.href};return e.isActivePage&&(t["aria-current"]="page"),E("li",{class:a},[E("a",t,[e.title])])}const s=this.navigationSubmenLine truncated
|
||||
Reference in new issue
Block a user