mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(ui): quiet the dark sidebar and theme brand surfaces
- Make the dark sidebar a flat neutral #0d0d0d with neutral tiles, text, search, and account button; only the current item stays purple. - Remove the resource row and spacer at the top of the main menu, so Dashboard sits under Search, and drop the unused nav context name. - Route hard-coded brand purple, canvas, and card colors through tokens that the custom theme overrides, so sidebar, buttons, accents, cards, and tables follow the picked color. - Paint page-level button and view-toggle tints over the canvas so the floating navigation dots do not show through. - Document the new sidebar and token rules in DESIGN.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9a8b4eb53c
commit
7de0e4cee8
@@ -37,8 +37,9 @@ change.
|
||||
- **One accent.** Coolify purple in both themes (`#6b16ed`, hover `#7317ff`,
|
||||
pressed `#5a12c7`, depth `#4a0fa3`, light text and icons `#a391ff`). Yellow
|
||||
is only for real warnings. The dark sidebar, including the logo cell, is
|
||||
purple-black (`#120e1a`) with a faint brand wash. The dark command palette
|
||||
has a light purple tint. The page canvas stays neutral.
|
||||
quiet neutral near-black (`#0d0d0d`), so the content keeps the focus; only
|
||||
the current item's tile is purple. The dark command palette has a
|
||||
light purple tint. The page canvas stays neutral.
|
||||
- **Quiet text.** Sentence case. A clear text ladder: primary, dim, faint.
|
||||
No em dashes in UI copy.
|
||||
|
||||
@@ -126,7 +127,7 @@ follow the theme.
|
||||
--ui-accent-edge: #4a0fa3;
|
||||
--ui-accent-fg: #ffffff;
|
||||
--ui-accent-light: #a391ff;
|
||||
--ui-sidebar: #120e1a;
|
||||
--ui-sidebar: #0d0d0d;
|
||||
--ui-card: #121212;
|
||||
--ui-success: oklch(72.27% 0.192 149.58);
|
||||
--ui-warning: oklch(88.13% 0.1507 91.7);
|
||||
@@ -143,9 +144,8 @@ Rules for the tokens:
|
||||
- Floating surfaces (menus, popovers, tooltips, modals) must be opaque. Use
|
||||
`--ui-menu-bg`, never a translucent value, or the content behind shows
|
||||
through.
|
||||
- Keep the page canvas, cards, menus, and logs pure neutral (chroma 0). The
|
||||
dark sidebar, the logo cell above it, and the dark command palette are the
|
||||
tinted surfaces.
|
||||
- Keep the page canvas, cards, menus, logs, and the sidebar pure neutral
|
||||
(chroma 0). The dark command palette is the only tinted surface.
|
||||
- **Dark lightness level.** The canvas is at 14.48% and the header panel at
|
||||
19.13%. To
|
||||
change the level, move every dark surface and border token by the same
|
||||
@@ -154,6 +154,25 @@ Rules for the tokens:
|
||||
hover fill can become darker than its menu.
|
||||
- Primary buttons, focus rings, and active navigation use purple in both
|
||||
themes. Warning yellow is not an accent.
|
||||
- Do not hard-code the brand purple (`#6b16ed`, `rgb(107 22 237 / …)`,
|
||||
`rgb(163 145 255 / …)`, `#8a4dff`), the dark canvas (`#0a0a0a`), or the
|
||||
card color (`#121212`) in component CSS. Use the tokens: `--color-brand`,
|
||||
`-hover`, `-press`, `-depth`, `-light`, `-ring`, `-foreground`,
|
||||
`--color-sidebar`, `--color-app`, and `--color-card`. For a translucent tint, use
|
||||
`color-mix(in srgb, var(--color-brand) 14%, transparent)`. A custom theme
|
||||
(`html[data-theme="custom"]`) overrides only these tokens, so a hard-coded
|
||||
value stays purple when the user picks another color.
|
||||
- The custom theme derives every token from the picked color: the brand fill
|
||||
and its hover, press, depth, and ring shades; `--color-brand-foreground`
|
||||
(the computed `--theme-accent-foreground`, so text stays readable on a light
|
||||
color such as yellow); `--color-card` (the tinted surface step); and
|
||||
`--color-sidebar` (between the tinted canvas and panel). When you add a
|
||||
dark-theme color token, give it a custom-theme value in the same block.
|
||||
- A translucent fill on a control that sits directly on the page (not in a
|
||||
card or table) shows the floating-navigation dots through it. Mix the tint
|
||||
with the canvas instead:
|
||||
`color-mix(in srgb, var(--color-brand) 6%, var(--color-app))`. Controls in
|
||||
cards keep the translucent tint, so they blend with the card.
|
||||
|
||||
## P3. Scales
|
||||
|
||||
@@ -198,13 +217,13 @@ Class names below are examples. Keep the values and structure.
|
||||
for the header row and `--ui-panel` for the rows.
|
||||
- In light mode the sidebar is the canvas color and has a 1px
|
||||
`--ui-chrome-border` right edge. In dark mode the sidebar column, including
|
||||
the logo cell, is `#120e1a` with a faint lavender right edge
|
||||
(`rgb(163 145 255 / 0.10)`). The nav has a brand-purple wash that starts at
|
||||
9% and fades out; the logo cell has a flat 9% wash, so the two read as one
|
||||
surface.
|
||||
the logo cell, is a flat neutral `#0d0d0d` (one step above the `#0a0a0a`
|
||||
canvas) with a faint `rgb(255 255 255 / 0.06)` right edge. Do not add a
|
||||
brand tint or wash to the sidebar: a colored sidebar competes with the
|
||||
content for attention.
|
||||
- The top bar matches the canvas. It has no bottom border at rest. After the
|
||||
page scrolls under it, dark mode draws a lavender hairline
|
||||
(`rgb(163 145 255 / 0.12)`), a translucent bar, blur, and a soft shadow.
|
||||
page scrolls under it, dark mode draws a neutral hairline
|
||||
(`rgb(255 255 255 / 0.06)`), a translucent bar, blur, and a soft shadow.
|
||||
The logo cell stays the solid sidebar color.
|
||||
- Keep the chrome borders faint. A strong border on near-black looks like a
|
||||
line drawn on the page.
|
||||
@@ -259,9 +278,9 @@ Class names below are examples. Keep the values and structure.
|
||||
transition: transform 80ms, box-shadow 80ms, border-color 120ms, background-color 120ms;
|
||||
}
|
||||
.dark .nav-tile {
|
||||
border-color: rgb(163 145 255 / 0.13);
|
||||
background: rgb(107 22 237 / 0.07);
|
||||
color: #b9adff;
|
||||
border-color: rgb(255 255 255 / 0.07);
|
||||
background: rgb(255 255 255 / 0.03);
|
||||
color: oklch(72% 0 0);
|
||||
}
|
||||
.nav-item:hover .nav-tile { transform: translateY(-1px); box-shadow: 0 3px 0 var(--ui-depth-color); }
|
||||
.nav-item:active .nav-tile { transform: translateY(2px); box-shadow: none; }
|
||||
@@ -279,18 +298,15 @@ Class names below are examples. Keep the values and structure.
|
||||
- Rows with a submenu end in a 12px chevron. In dark mode the chevron is
|
||||
hidden until the row is hovered, focused, or current.
|
||||
- Group rows under section labels (11px in light mode; 10.5px uppercase muted
|
||||
lavender in dark mode), and separate groups with a 1px divider.
|
||||
gray in dark mode), and separate groups with a 1px divider.
|
||||
- Do not put a glow (a blurred `box-shadow`) on a tile. The current row clips
|
||||
it, so it shows as a dim square behind the tile.
|
||||
- In the collapsed sidebar, Search is a tile like the other items: no row fill
|
||||
and no frame around it. Only the expanded sidebar shows Search as an input.
|
||||
- A menu that replaces another menu in place starts with a back row: a
|
||||
centered label and a 12px chevron on the side of the direction. The back row
|
||||
points left (`‹ Dashboard`). The row that opens the resource menu again from
|
||||
the main menu points right (`adonisjs ›`) and shows the resource name.
|
||||
- Keep the menu items in the same place on every page. When a page has no
|
||||
resource menu, keep an empty row of the same height where the resource row
|
||||
would be.
|
||||
centered label and a 12px left chevron (`‹ Dashboard`).
|
||||
- The main menu has no row above its items. Dashboard is the first item, right
|
||||
under Search, on every page.
|
||||
|
||||
### Card (outer box, title row, well)
|
||||
|
||||
@@ -655,18 +671,18 @@ lift off the content:
|
||||
- **Topbar chrome** uses the canvas color in dark (`#0a0a0a`) and `bg-white`
|
||||
in light. It has no bottom border until the page scrolls under it. Scrolling
|
||||
adds `is-scrolled` on `<html>` (see `layouts/app.blade.php`) and the dark bar
|
||||
becomes `rgb(10 10 10 / 0.72)` with blur and a lavender hairline. In dark
|
||||
becomes `rgb(10 10 10 / 0.72)` with blur and a neutral hairline. In dark
|
||||
mode, top-level card wells and table rows use `--color-card` (`#121212`),
|
||||
not the top bar.
|
||||
- **Desktop sidebar and the topbar brand block** (Coolify name and version)
|
||||
use the canvas color in light mode. In dark mode they use `--color-sidebar`
|
||||
(`#120e1a`): a vertical brand wash on the nav, a flat 9% wash on the logo
|
||||
cell (the same color as the top of the nav wash), and a lavender right
|
||||
edge. Section labels are 10.5px uppercase mono in
|
||||
muted lavender. Chevrons are hidden until the row is hovered, focused, or
|
||||
current. The Admin icon stays neutral. The footer is transparent so the
|
||||
wash continues. Do not use `dark:border-white/[0.06]` on these chrome edges;
|
||||
a global rule forces that utility to the solid hairline grey.
|
||||
(`#0d0d0d`), flat and neutral, with a `rgb(255 255 255 / 0.06)` right edge.
|
||||
Inactive icon tiles, Search, the account button in the footer, and section
|
||||
labels (10.5px uppercase mono, `--color-nav-muted`) are neutral gray. Only
|
||||
the current item's tile uses the brand purple, so the sidebar does not
|
||||
compete with the content. Chevrons are hidden until the row is hovered,
|
||||
focused, or current. Do not use `dark:border-white/[0.06]` on these chrome
|
||||
edges; a global rule forces that utility to the solid hairline grey.
|
||||
|
||||
Dark surface tokens are exact oklch equivalents of chosen sRGB steps. oklch
|
||||
lightness compresses toward pure black below ~15%, so check the rendered sRGB
|
||||
@@ -676,8 +692,9 @@ value. The dark ladder is `--color-app` 10, `--color-panel` 20,
|
||||
|
||||
Temperature: the page canvas, cards, menus, listboxes, modals, and logs stay
|
||||
**pure neutral gray** (r=g=b). Do not tint those. The dark sidebar
|
||||
(`--color-sidebar`, `#120e1a`) and the dark command palette are the exceptions:
|
||||
they carry a faint brand-purple wash. The light page canvas uses `bg-neutral-50` (not
|
||||
(`--color-sidebar`, `#0d0d0d`) is neutral too. The dark command palette is the
|
||||
only exception: it carries a faint brand-purple wash. A custom theme tints all
|
||||
of these surfaces with the picked color (see the token rules in P2). The light page canvas uses `bg-neutral-50` (not
|
||||
`bg-gray-50`, which is faintly cool) so it matches the neutral cards and chrome.
|
||||
The only intentional color is the purple brand accent. Yellow is for warnings.
|
||||
- **Layer cards** use the outer box and inset well from section 5.
|
||||
@@ -775,12 +792,9 @@ state because it can disappear after polling or a Livewire morph.
|
||||
From `xl`, the resource menu replaces the main menu in the main sidebar
|
||||
(`x-main-nav-menu`, `registerMainNavContext()`, `components/navbar.blade.php`).
|
||||
Its back row (`‹ Dashboard`, `‹ Servers`, `‹ Service`) shows the menu one depth
|
||||
lower, without a page load. The main menu then starts with a row that opens the
|
||||
deepest resource menu again: the resource name with a right chevron
|
||||
(`adonisjs ›`). Pass the name as `name` to `registerMainNavContext()` or
|
||||
`<x-main-nav-menu :name>`; without a name the row says "Resource menu". Pages
|
||||
with no resource menu keep an invisible row of the same height, so the main
|
||||
menu items do not move between pages.
|
||||
lower, without a page load. The main menu has no row that opens the resource
|
||||
menu again; to get back to it, open the resource again. Dashboard is always the
|
||||
first item under Search.
|
||||
|
||||
The global topbar owns the current resource identity, its compact status
|
||||
badges, configuration warnings (`#configuration-warning-hud-slot`), and the
|
||||
|
||||
@@ -4626,12 +4626,11 @@ function wireNavigate(): string
|
||||
* Registers a resource menu that the main sidebar shows in place of its main menu on wide screens
|
||||
* (see components/navbar.blade.php). The menu teleports itself into #main-nav-context-{depth}.
|
||||
* Back on a menu shows the menu one depth lower, and Back at depth 0 shows the main menu.
|
||||
* The main menu then shows a row (labelled with $name) that opens the deepest resource menu again.
|
||||
*/
|
||||
function registerMainNavContext(int $depth, string $label, string $backTitle, ?string $name = null): void
|
||||
function registerMainNavContext(int $depth, string $label, string $backTitle): void
|
||||
{
|
||||
$levels = request()->attributes->get('mainNavContext', []);
|
||||
$levels[$depth] = ['label' => $label, 'backTitle' => $backTitle, 'name' => $name];
|
||||
$levels[$depth] = ['label' => $label, 'backTitle' => $backTitle];
|
||||
ksort($levels);
|
||||
|
||||
request()->attributes->set('mainNavContext', $levels);
|
||||
|
||||
+79
-95
@@ -109,15 +109,15 @@
|
||||
}
|
||||
|
||||
.dark .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) {
|
||||
--button-depth-color: rgb(107 22 237 / 0.35);
|
||||
background-color: rgb(107 22 237 / 0.14);
|
||||
border-color: rgb(163 145 255 / 0.24);
|
||||
color: #ece8ff;
|
||||
--button-depth-color: color-mix(in srgb, var(--color-brand) 35%, transparent);
|
||||
background-color: color-mix(in srgb, var(--color-brand) 14%, transparent);
|
||||
border-color: color-mix(in srgb, var(--color-brand-light) 24%, transparent);
|
||||
color: oklch(from var(--color-brand-light) 93.5% 0.03 h);
|
||||
}
|
||||
|
||||
.dark .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):hover {
|
||||
background-color: rgb(107 22 237 / 0.18);
|
||||
border-color: rgb(163 145 255 / 0.34);
|
||||
background-color: color-mix(in srgb, var(--color-brand) 18%, transparent);
|
||||
border-color: color-mix(in srgb, var(--color-brand-light) 34%, transparent);
|
||||
}
|
||||
|
||||
.dark .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) svg {
|
||||
@@ -129,7 +129,7 @@
|
||||
.dark .button[isHighlighted]:not(:disabled) {
|
||||
background: var(--color-brand);
|
||||
border-color: transparent;
|
||||
color: #fff;
|
||||
color: var(--color-brand-foreground);
|
||||
--button-depth-color: var(--color-brand-depth);
|
||||
}
|
||||
|
||||
@@ -1298,6 +1298,9 @@ html:not(.dark) .application-console-shell[data-console-theme="system"] .termina
|
||||
4.46, recessed 4.24, fill 3.76) to 50% so muted text clears 4.5:1 on
|
||||
every light surface above white. Dark stays 70.8% (already passes). */
|
||||
--coollabs-subtle: oklch(50% 0 0);
|
||||
/* Border of brand fills and the text on them. A custom theme overrides both. */
|
||||
--color-brand-ring: #8a4dff;
|
||||
--color-brand-foreground: #fff;
|
||||
}
|
||||
|
||||
.dark {
|
||||
@@ -1307,7 +1310,7 @@ html:not(.dark) .application-console-shell[data-console-theme="system"] .termina
|
||||
/* Cards sit one step above the #0a0a0a canvas. The top bar uses the canvas,
|
||||
not this color. The sidebar uses --color-sidebar. */
|
||||
--color-card: #121212;
|
||||
--color-sidebar: #120e1a;
|
||||
--color-sidebar: #0d0d0d;
|
||||
/* Dark surface ladder in hex (sRGB), not oklch: oklch lightness compresses
|
||||
to near-black below ~15%, so oklch(15%) rendered as sRGB 11 and cards
|
||||
could not lift off the content canvas (sRGB 10). These give clear,
|
||||
@@ -1384,11 +1387,19 @@ html[data-theme="custom"] {
|
||||
--color-coollabs-300: color-mix(in oklab, var(--theme-bright-color) 72%, oklch(0% 0 0));
|
||||
/* Legacy dark-theme accent utilities use warning as the brand color. */
|
||||
--color-warning: var(--theme-bright-color);
|
||||
/* Accent text, icons, and rings (brand-light) follow the picked color in the
|
||||
readable foreground band. --color-brand stays purple here because the
|
||||
brand button gradient (hover/press/depth) is not themed; brand fills and
|
||||
tints are remapped per element below. */
|
||||
/* Brand fills, tints, and accent text follow the picked color. Text on a
|
||||
brand fill uses the computed foreground, so light colors stay readable. */
|
||||
--color-brand: var(--theme-bright-color);
|
||||
--color-brand-hover: color-mix(in oklab, var(--theme-bright-color) 88%, oklch(100% 0 0));
|
||||
--color-brand-press: color-mix(in oklab, var(--theme-bright-color) 85%, oklch(0% 0 0));
|
||||
--color-brand-depth: color-mix(in oklab, var(--theme-bright-color) 65%, oklch(0% 0 0));
|
||||
--color-brand-ring: color-mix(in oklab, var(--theme-bright-color) 75%, oklch(100% 0 0));
|
||||
--color-brand-foreground: var(--theme-accent-foreground);
|
||||
--color-brand-light: var(--theme-fg-on-surface);
|
||||
/* Card wells, tables, and tiles (#121212 in the neutral dark theme). */
|
||||
--color-card: var(--color-surface);
|
||||
/* Sidebar: one step above the canvas, like the neutral dark theme. */
|
||||
--color-sidebar: color-mix(in oklab, var(--color-app) 70%, var(--color-panel));
|
||||
--color-accent-foreground: var(--theme-accent-foreground);
|
||||
--color-app: color-mix(in oklab, var(--theme-base-color) 12%, oklch(14.03% 0.0022 286.11));
|
||||
--color-panel: color-mix(in oklab, var(--theme-base-color) 14%, oklch(15.48% 0.0021 286.15));
|
||||
@@ -1537,17 +1548,6 @@ html[data-theme="custom"] :is(
|
||||
color: var(--theme-fg-on-surface) !important;
|
||||
}
|
||||
|
||||
/* Brand fills and tints (chips, selected rows, checked boxes, active app tabs)
|
||||
take the picked color. Scoped to the elements that use them so the purple
|
||||
brand buttons keep their matching hover/press/depth tokens. */
|
||||
html[data-theme="custom"] :is(
|
||||
[class*=":bg-brand"],
|
||||
[class*=":border-brand"],
|
||||
.application-heading-actions .app-tab
|
||||
) {
|
||||
--color-brand: var(--theme-bright-color);
|
||||
}
|
||||
|
||||
html.dark[data-theme="custom"] [class~="dark:bg-brand"] {
|
||||
color: var(--theme-accent-foreground) !important;
|
||||
}
|
||||
@@ -5832,8 +5832,8 @@ html:where(:not([data-nav-items="flat"])) :is(.menu-item-active, .menu-subitem-a
|
||||
}
|
||||
|
||||
html.dark:where(:not([data-nav-items="flat"])) :is(.menu-item-active, .menu-subitem-active) .menu-item-icon:not(.text-error) {
|
||||
color: #fff;
|
||||
border-color: #8a4dff !important;
|
||||
color: var(--color-brand-foreground);
|
||||
border-color: var(--color-brand-ring) !important;
|
||||
background: linear-gradient(180deg, var(--color-brand-hover) 0%, var(--color-brand-press) 100%) !important;
|
||||
--button-depth-color: var(--color-brand-depth) !important;
|
||||
box-shadow: 0 2px 0 var(--color-brand-depth) !important;
|
||||
@@ -5944,10 +5944,10 @@ html:where(:not([data-nav-items="flat"])) :is(.menu-item, .menu-subitem):not(.si
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
html.dark:where(:not([data-nav-items="flat"])) :is(.app-sidebar, .mobile-sidebar-sheet) :is(.menu-item, .menu-subitem):not(.sidebar-toggle):not(.menu-search):not(.nav-admin):not(.menu-item-active):not(.menu-subitem-active) .menu-item-icon {
|
||||
border-color: rgb(163 145 255 / 0.13);
|
||||
background: rgb(107 22 237 / 0.07);
|
||||
color: #b9adff;
|
||||
html.dark:where(:not([data-nav-items="flat"])) :is(.app-sidebar, .mobile-sidebar-sheet) :is(.menu-item, .menu-subitem):not(.sidebar-toggle):not(.menu-search):not(.menu-item-active):not(.menu-subitem-active) .menu-item-icon {
|
||||
border-color: rgb(255 255 255 / 0.07);
|
||||
background: rgb(255 255 255 / 0.03);
|
||||
color: oklch(72% 0 0);
|
||||
--button-depth-color: rgb(255 255 255 / 0.05);
|
||||
}
|
||||
|
||||
@@ -5963,13 +5963,6 @@ html.dark:where(:not([data-nav-items="flat"])) :is(.menu-item, .menu-subitem):no
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Admin stays a neutral tile unless it is the current page. */
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .nav-admin:not(.menu-item-active) .menu-item-icon {
|
||||
color: oklch(72% 0 0);
|
||||
background: rgb(255 255 255 / 0.03);
|
||||
border-color: rgb(255 255 255 / 0.07);
|
||||
}
|
||||
|
||||
/* Search keeps its original input look while the sidebar is expanded (always on
|
||||
mobile, where the rail never collapses). Only the collapsed rail shows the 3D tile.
|
||||
The icon resets use .menu-search.menu-item to beat the html.dark tile rules. */
|
||||
@@ -6257,22 +6250,20 @@ html.dark .canvas-zoom-max {
|
||||
}
|
||||
}
|
||||
|
||||
/* Brand shell (dark): black canvas and top bar, purple-black sidebar, scroll hairline.
|
||||
Light mode keeps the neutral shell. Floating navigation keeps its own frame. */
|
||||
/* Brand shell (dark): black canvas and top bar, quiet neutral sidebar, scroll hairline.
|
||||
The sidebar stays neutral so the content keeps the focus; only the current item
|
||||
uses the brand purple. Light mode keeps the neutral shell. Floating navigation
|
||||
keeps its own frame. */
|
||||
html.dark .app-sidebar nav.sidebar-nav,
|
||||
html.dark .mobile-sidebar-sheet [role="dialog"] {
|
||||
background-color: var(--color-sidebar);
|
||||
background-image: linear-gradient(180deg, rgb(107 22 237 / 0.09), transparent 520px);
|
||||
border-right-color: rgb(163 145 255 / 0.10);
|
||||
--color-nav-text: oklch(80% 0.02 300);
|
||||
--color-nav-muted: oklch(58% 0.04 300);
|
||||
border-right-color: rgb(255 255 255 / 0.06);
|
||||
}
|
||||
|
||||
/* Same color as the top of the sidebar gradient, so the brand and sidebar read as one surface. */
|
||||
/* Same color as the sidebar, so the brand and sidebar read as one surface. */
|
||||
html.dark .app-topbar-brand {
|
||||
background-color: var(--color-sidebar);
|
||||
background-image: linear-gradient(rgb(107 22 237 / 0.09), rgb(107 22 237 / 0.09));
|
||||
border-right-color: rgb(163 145 255 / 0.10);
|
||||
border-right-color: rgb(255 255 255 / 0.06);
|
||||
}
|
||||
|
||||
/* The drawer carries the brand surface; its nav must not paint over it. */
|
||||
@@ -6285,21 +6276,24 @@ html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer {
|
||||
}
|
||||
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search {
|
||||
background-color: rgb(163 145 255 / 0.06) !important;
|
||||
box-shadow: inset 0 0 0 1px rgb(163 145 255 / 0.10) !important;
|
||||
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06) !important;
|
||||
}
|
||||
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search:hover {
|
||||
background-color: rgb(163 145 255 / 0.10) !important;
|
||||
/* The account button is a .button, which is purple in dark mode; keep it neutral in the sidebar. */
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) {
|
||||
--button-depth-color: rgb(255 255 255 / 0.05);
|
||||
background-color: rgb(255 255 255 / 0.04);
|
||||
border-color: rgb(255 255 255 / 0.08);
|
||||
color: var(--color-nav-text);
|
||||
}
|
||||
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .menu-search kbd {
|
||||
border-color: rgb(163 145 255 / 0.18) !important;
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):hover {
|
||||
background-color: rgb(255 255 255 / 0.07);
|
||||
border-color: rgb(255 255 255 / 0.12);
|
||||
}
|
||||
|
||||
/* Group dividers use the lavender sidebar edge: the neutral hairline looks olive on the purple-black sidebar. */
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-nav :is([class~="dark:border-white/[0.06]"], [class~="dark:border-white/[0.07]"], [class~="dark:border-white/[0.08]"]) {
|
||||
border-color: rgb(163 145 255 / 0.10) !important;
|
||||
html.dark :is(.app-sidebar, .mobile-sidebar-sheet) .sidebar-footer .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled) svg {
|
||||
color: var(--color-nav-muted);
|
||||
}
|
||||
|
||||
/* The collapsed rail shows Search as a tile like the other items: no row frame (the fill is
|
||||
@@ -6309,9 +6303,9 @@ html.dark .app-sidebar nav.sidebar-collapsed .menu-search {
|
||||
}
|
||||
|
||||
html.dark:where(:not([data-nav-items="flat"])) .app-sidebar nav.sidebar-collapsed .menu-search.menu-item .menu-item-icon {
|
||||
border-color: rgb(163 145 255 / 0.13);
|
||||
background: rgb(107 22 237 / 0.07);
|
||||
color: #b9adff;
|
||||
border-color: rgb(255 255 255 / 0.07);
|
||||
background: rgb(255 255 255 / 0.03);
|
||||
color: oklch(72% 0 0);
|
||||
--button-depth-color: rgb(255 255 255 / 0.05);
|
||||
}
|
||||
|
||||
@@ -6321,7 +6315,7 @@ html.dark :is(.app-sidebar, .mobile-sidebar-sheet) nav:not(.sidebar-collapsed) .
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: rgb(163 145 255 / 0.55);
|
||||
color: var(--color-nav-muted);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -6334,7 +6328,7 @@ html.dark .app-sidebar .menu-item:not(:hover):not(:focus-visible):not(.menu-item
|
||||
}
|
||||
|
||||
html.dark:not([data-nav-style="floating"]) .app-topbar {
|
||||
background-color: #0a0a0a;
|
||||
background-color: var(--color-app);
|
||||
backdrop-filter: none;
|
||||
transition: background-color 180ms ease;
|
||||
}
|
||||
@@ -6345,7 +6339,7 @@ html.dark:not([data-nav-style="floating"]) .app-topbar > div:not(.app-topbar-bra
|
||||
}
|
||||
|
||||
html.dark.is-scrolled:not([data-nav-style="floating"]) .app-topbar {
|
||||
background-color: rgb(10 10 10 / 0.72);
|
||||
background-color: color-mix(in srgb, var(--color-app) 72%, transparent);
|
||||
backdrop-filter: blur(12px) saturate(140%);
|
||||
}
|
||||
|
||||
@@ -6354,8 +6348,8 @@ html.dark.is-scrolled:not([data-nav-style="floating"]) .app-topbar > .app-topbar
|
||||
}
|
||||
|
||||
html.dark.is-scrolled:not([data-nav-style="floating"]) .app-topbar > div:not(.app-topbar-brand) {
|
||||
border-bottom-color: rgb(163 145 255 / 0.12);
|
||||
box-shadow: 0 10px 30px -14px rgb(0 0 0 / 0.95), 0 1px 0 rgb(107 22 237 / 0.06);
|
||||
border-bottom-color: rgb(255 255 255 / 0.06);
|
||||
box-shadow: 0 10px 30px -14px rgb(0 0 0 / 0.95);
|
||||
}
|
||||
|
||||
/* Canvases (default navigation): the canvas runs under a clear top bar, and the
|
||||
@@ -6398,12 +6392,12 @@ html.dark.is-scrolled:not([data-nav-style="floating"]) .app-topbar > div:not(.ap
|
||||
html.dark .view-toggle {
|
||||
gap: 2px;
|
||||
padding: 2px;
|
||||
background-color: rgb(107 22 237 / 0.06);
|
||||
border-color: rgb(163 145 255 / 0.16);
|
||||
background-color: color-mix(in srgb, var(--color-brand) 6%, transparent);
|
||||
border-color: color-mix(in srgb, var(--color-brand-light) 16%, transparent);
|
||||
}
|
||||
|
||||
html.dark .view-toggle > :is(a, button) {
|
||||
color: oklch(80% 0.02 300);
|
||||
color: oklch(from var(--color-brand-light) 80% 0.02 h);
|
||||
}
|
||||
|
||||
html.dark .view-toggle > :is(a, button) svg {
|
||||
@@ -6411,23 +6405,23 @@ html.dark .view-toggle > :is(a, button) svg {
|
||||
}
|
||||
|
||||
html.dark .view-toggle > :is(a, button):not(.is-selected):hover {
|
||||
background-color: rgb(107 22 237 / 0.14);
|
||||
background-color: color-mix(in srgb, var(--color-brand) 14%, transparent);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
html.dark .view-toggle > .is-selected {
|
||||
background: linear-gradient(180deg, var(--color-brand-hover), var(--color-brand-press));
|
||||
color: #fff;
|
||||
box-shadow: 0 1px 0 var(--color-brand-depth), inset 0 0 0 1px #8a4dff;
|
||||
color: var(--color-brand-foreground);
|
||||
box-shadow: 0 1px 0 var(--color-brand-depth), inset 0 0 0 1px var(--color-brand-ring);
|
||||
}
|
||||
|
||||
html.dark .view-toggle > .is-selected svg {
|
||||
color: #fff;
|
||||
color: var(--color-brand-foreground);
|
||||
}
|
||||
|
||||
html.dark .view-toggle .bg-coollabs {
|
||||
background-color: rgb(163 145 255 / 0.18);
|
||||
color: #d9d0ff;
|
||||
background-color: color-mix(in srgb, var(--color-brand-light) 18%, transparent);
|
||||
color: oklch(from var(--color-brand-light) 87.5% 0.06 h);
|
||||
}
|
||||
|
||||
/* Toasts: a faint edge that blends into the toast background. */
|
||||
@@ -6443,18 +6437,8 @@ html.dark .toast-card {
|
||||
|
||||
/* Command palette: the purple brand tint of the dark shell. */
|
||||
html.dark .command-palette {
|
||||
background: color-mix(in oklab, #6b16ed 10%, var(--coollabs-elevated));
|
||||
box-shadow: 0 0 0 1px rgb(163 145 255 / 0.22), var(--shadow-dropdown);
|
||||
}
|
||||
|
||||
/* Sidebar account menu: the purple tint of the sidebar it opens from. */
|
||||
html.dark .listbox-panel.top-user-menu-panel-sidebar {
|
||||
background: color-mix(in oklab, #6b16ed 10%, var(--coollabs-elevated));
|
||||
border-color: rgb(163 145 255 / 0.22);
|
||||
}
|
||||
|
||||
html.dark .top-user-menu-panel-sidebar .listbox-option:hover {
|
||||
background: rgb(163 145 255 / 0.10);
|
||||
background: color-mix(in oklab, var(--color-brand) 10%, var(--coollabs-elevated));
|
||||
box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-brand-light) 22%, transparent), var(--shadow-dropdown);
|
||||
}
|
||||
|
||||
html.dark .command-palette-header {
|
||||
@@ -6466,12 +6450,12 @@ html.dark .command-palette-header-icon:not(.is-loading) {
|
||||
}
|
||||
|
||||
html.dark .command-palette-input::placeholder {
|
||||
color: oklch(72% 0.05 300);
|
||||
color: oklch(from var(--color-brand-light) 72% 0.05 h);
|
||||
}
|
||||
|
||||
html.dark .command-palette-body {
|
||||
background: color-mix(in oklab, #6b16ed 6%, var(--coollabs-base));
|
||||
box-shadow: 0 0 0 1px rgb(163 145 255 / 0.12);
|
||||
background: color-mix(in oklab, var(--color-brand) 6%, var(--coollabs-base));
|
||||
box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-brand-light) 12%, transparent);
|
||||
}
|
||||
|
||||
html.dark .command-palette-item:is(:focus, :focus-visible) :is(.command-palette-quickcommand, .command-palette-type-badge, .command-palette-item-chevron, .command-palette-item-icon) {
|
||||
@@ -6479,8 +6463,8 @@ html.dark .command-palette-item:is(:focus, :focus-visible) :is(.command-palette-
|
||||
}
|
||||
|
||||
html.dark .resource-glyph {
|
||||
border-color: rgb(163 145 255 / 0.20);
|
||||
background: rgb(107 22 237 / 0.10);
|
||||
border-color: color-mix(in srgb, var(--color-brand-light) 20%, transparent);
|
||||
background: color-mix(in srgb, var(--color-brand) 10%, transparent);
|
||||
color: var(--color-brand-light);
|
||||
}
|
||||
|
||||
@@ -6489,7 +6473,7 @@ html.dark .card-icon-button {
|
||||
}
|
||||
|
||||
html.dark .card-icon-button:hover {
|
||||
background-color: rgb(107 22 237 / 0.16);
|
||||
background-color: color-mix(in srgb, var(--color-brand) 16%, transparent);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -6500,7 +6484,7 @@ html.dark .app-main :is(article.group, a.group).rounded-xl {
|
||||
}
|
||||
|
||||
html.dark .app-main :is(article.group, a.group).rounded-xl:hover {
|
||||
border-color: rgb(163 145 255 / 0.30) !important;
|
||||
border-color: color-mix(in srgb, var(--color-brand-light) 30%, transparent) !important;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@@ -6540,7 +6524,7 @@ html.dark .project-card-stats-dot {
|
||||
.dark .application-settings-workspace :is(.input, select, textarea):focus,
|
||||
.dark .application-settings-workspace :is(.input, select, textarea):focus-visible {
|
||||
border-color: var(--color-brand);
|
||||
box-shadow: 0 0 0 3px rgb(107 22 237 / 0.25) !important;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-brand) 25%, transparent) !important;
|
||||
}
|
||||
|
||||
/* One page of results: the bar is noise. !important beats the flex utility and Alpine x-show. */
|
||||
@@ -6579,8 +6563,8 @@ html.dark .project-card-stats-dot {
|
||||
html.dark .app-main [class*="dark:bg-white/[0.09]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: color-mix(in oklab, #fff 9%, var(--color-app)) !important; }
|
||||
html.dark .app-main [class*="dark:bg-white/[0.14]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: color-mix(in oklab, #fff 14%, var(--color-app)) !important; }
|
||||
html.dark .app-main [class*="dark:bg-white/[0.1]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: color-mix(in oklab, #fff 10%, var(--color-app)) !important; }
|
||||
html.dark .app-main .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: rgb(107 22 237 / 0.14) !important; border-color: rgb(163 145 255 / 0.24) !important; color: #ece8ff !important; }
|
||||
html.dark .app-main .view-toggle:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: rgb(107 22 237 / 0.06) !important; border-color: rgb(163 145 255 / 0.16) !important; }
|
||||
html.dark .app-main .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: color-mix(in srgb, var(--color-brand) 14%, var(--color-app)) !important; border-color: color-mix(in srgb, var(--color-brand-light) 24%, transparent) !important; color: oklch(from var(--color-brand-light) 93.5% 0.03 h) !important; }
|
||||
html.dark .app-main .view-toggle:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) { background-color: color-mix(in srgb, var(--color-brand) 6%, var(--color-app)) !important; border-color: color-mix(in srgb, var(--color-brand-light) 16%, transparent) !important; }
|
||||
html.dark .app-main [class*="dark:hover:bg-white/10"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in oklab, #fff 10%, var(--color-app)) !important; }
|
||||
html.dark .app-main [class*="dark:hover:bg-white/[0.025]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in oklab, #fff 2.5%, var(--color-app)) !important; }
|
||||
html.dark .app-main [class*="dark:hover:bg-white/[0.035]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in oklab, #fff 3.5%, var(--color-app)) !important; }
|
||||
@@ -6592,11 +6576,11 @@ html.dark .project-card-stats-dot {
|
||||
html.dark .app-main [class*="dark:hover:bg-white/[0.08]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in oklab, #fff 8%, var(--color-app)) !important; }
|
||||
html.dark .app-main [class*="dark:hover:bg-white/[0.12]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in oklab, #fff 12%, var(--color-app)) !important; }
|
||||
html.dark .app-main [class*="dark:hover:bg-white/[0.1]"]:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in oklab, #fff 10%, var(--color-app)) !important; }
|
||||
html.dark .app-main .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: rgb(107 22 237 / 0.18) !important; border-color: rgb(163 145 255 / 0.34) !important; }
|
||||
html.dark .app-main .button:not(.button-highlighted):not(.button-error):not([isHighlighted]):not(:disabled):not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *):hover { background-color: color-mix(in srgb, var(--color-brand) 18%, var(--color-app)) !important; border-color: color-mix(in srgb, var(--color-brand-light) 34%, transparent) !important; }
|
||||
|
||||
/* Collection shells are #121212. Same selector as the 5% mix, plus .rounded-xl, so it wins. */
|
||||
html.dark .app-main [class*="dark:bg-white/[0.05]"].rounded-xl:not(:is([class*="dark:bg-"]:not(.app-main), .button, .view-toggle, .application-settings-section, .application-settings-section-body, .box, .coolbox, .data-table, .resource-view, .empty-state, .loading-state-card, .runtime-log-shell, .logs-viewer) *) {
|
||||
background-color: #121212 !important;
|
||||
background-color: var(--color-card) !important;
|
||||
border-color: rgb(255 255 255 / 0.08) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@
|
||||
|
||||
@php
|
||||
// The main sidebar shows this menu on wide screens (see components/navbar.blade.php).
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu', $application->name);
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu');
|
||||
@endphp
|
||||
|
||||
{{-- Rendered twice: in the page (below xl), and teleported into the main sidebar (xl and up).
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
@php
|
||||
// The main sidebar shows this menu on wide screens (see components/navbar.blade.php).
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu', $database->name);
|
||||
registerMainNavContext(0, 'Dashboard', 'Back to the main menu');
|
||||
@endphp
|
||||
|
||||
{{-- Rendered twice: in the page (below xl), and teleported into the main sidebar (xl and up).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@props(['backLabel', 'backTitle' => 'Back to the main menu', 'depth' => 0, 'name' => null, 'navOnly' => false])
|
||||
@props(['backLabel', 'backTitle' => 'Back to the main menu', 'depth' => 0, 'navOnly' => false])
|
||||
@php
|
||||
// The main sidebar replaces its menu with this one on wide screens (see components/navbar.blade.php).
|
||||
registerMainNavContext($depth, $backLabel, $backTitle, $name);
|
||||
registerMainNavContext($depth, $backLabel, $backTitle);
|
||||
@endphp
|
||||
{{-- A page menu, rendered twice: in the page (below xl, CSS hides it on xl), and teleported into the
|
||||
main sidebar (xl and up). The slot must not contain Livewire components (they would render twice).
|
||||
|
||||
@@ -178,7 +178,6 @@
|
||||
// components/main-nav-menu.blade.php). Each one teleports itself into #main-nav-context-{depth};
|
||||
// only the desktop sidebar has the slots.
|
||||
$navContext = $desktop ? request()->attributes->get('mainNavContext', []) : [];
|
||||
$navContextName = collect($navContext)->pluck('name')->filter()->last() ?? 'Resource menu';
|
||||
@endphp
|
||||
{{-- Wide screens on a resource page: the deepest resource menu replaces the main menu. Back shows the
|
||||
menu one depth lower, and then the main menu (or its submenu), without leaving the page. --}}
|
||||
@@ -256,25 +255,6 @@
|
||||
@endforeach
|
||||
<li x-show="!submenu" @if ($activeSubmenu) x-cloak @endif @class(['contents', 'xl:hidden' => $navContext]) :class="{ 'xl:hidden': navLevel !== -1 }">
|
||||
<ul role="list" class="flex flex-col gap-y-0.5" :class="navSwap && 'nav-swap-' + navSwap">
|
||||
@if ($navContext)
|
||||
{{-- Wide screens: the main menu of a resource page opens the deepest resource menu again.
|
||||
Other pages keep an empty row, so the menu items do not move between pages. --}}
|
||||
<li class="mb-1 hidden xl:block">
|
||||
<button type="button" @click="navLevel = {{ array_key_last($navContext) }}; navSwap = 'forward'"
|
||||
title="Back to the {{ $navContextName }} menu" aria-label="Back to the {{ $navContextName }} menu"
|
||||
class="menu-item menu-back bg-transparent! hover:bg-neutral-100! dark:hover:bg-white/[0.06]!" :class="collapsed && 'lg:justify-center lg:px-0'">
|
||||
<span class="flex-1 truncate pl-6 text-center font-medium text-black dark:text-fg"
|
||||
:class="collapsed && 'lg:hidden'">{{ $navContextName }}</span>
|
||||
<span class="menu-back-icon flex shrink-0 items-center justify-center">
|
||||
<x-reicon name="chevron-down" class="size-3 -rotate-90 text-coollabs dark:text-fg-dim" />
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
@elseif ($desktop)
|
||||
<li class="mb-1 hidden xl:block" aria-hidden="true">
|
||||
<span class="menu-item menu-back invisible"><span class="menu-back-icon"></span><span class="font-medium"> </span></span>
|
||||
</li>
|
||||
@endif
|
||||
@foreach ($navSections as $sectionLabel => $sectionItems)
|
||||
{{-- The first section needs no title. --}}
|
||||
@unless ($loop->first)
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
|
||||
@php
|
||||
// The main sidebar shows this menu on wide screens (see components/navbar.blade.php).
|
||||
registerMainNavContext(0, 'Servers', 'Back to the main menu', $server->name);
|
||||
registerMainNavContext(0, 'Servers', 'Back to the main menu');
|
||||
@endphp
|
||||
|
||||
{{-- Rendered twice: in the page (below xl), and teleported into the main sidebar (xl and up).
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
->filter(fn ($items) => $items->isNotEmpty());
|
||||
@endphp
|
||||
|
||||
<x-main-nav-menu back-label="Dashboard" :name="$service->name" :nav-only="$navOnly"
|
||||
<x-main-nav-menu back-label="Dashboard" :nav-only="$navOnly"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems($groupedItems, $serviceRouteParameters)) }}">
|
||||
<nav aria-label="Service settings"
|
||||
class="grid grid-cols-2 gap-0.5 border-y border-neutral-200 py-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-1 xl:border-y-0 xl:py-0 dark:border-white/[0.06]">
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
])->filter();
|
||||
@endphp
|
||||
|
||||
<x-main-nav-menu back-label="Destinations" back-title="Back to Integrations" :name="$destination->name"
|
||||
<x-main-nav-menu back-label="Destinations" back-title="Back to Integrations"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems(['Destination' => $destinationMenuItems], $destinationRouteParameters)) }}">
|
||||
<nav aria-label="Destination settings"
|
||||
class="grid grid-cols-2 gap-0.5 border-y border-neutral-200 py-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-1 xl:border-y-0 xl:py-0 dark:border-white/[0.06]">
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
@if ($showSettingsSidebar)
|
||||
<section class="application-settings-workspace mt-4 w-full max-w-none lg:mt-0">
|
||||
<div class="grid min-w-0 gap-8 xl:grid-cols-[210px_minmax(0,1fr)] xl:gap-8">
|
||||
<x-main-nav-menu back-label="Sources" back-title="Back to Integrations" :name="$github_app->name ?: 'GitHub App'"
|
||||
<x-main-nav-menu back-label="Sources" back-title="Back to Integrations"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems(['GitHub App' => $settingsMenuItems], $githubAppRouteParameters)) }}">
|
||||
<nav aria-label="GitHub App settings"
|
||||
class="grid grid-cols-2 gap-0.5 border-y border-neutral-200 py-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-1 xl:border-y-0 xl:py-0 dark:border-white/[0.06]">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
@if ($showSettingsSidebar)
|
||||
<section class="application-settings-workspace mt-4 w-full max-w-none lg:mt-0">
|
||||
<div class="grid min-w-0 gap-8 xl:grid-cols-[210px_minmax(0,1fr)] xl:gap-8">
|
||||
<x-main-nav-menu back-label="S3 Storage" back-title="Back to Integrations" :name="$storage->name"
|
||||
<x-main-nav-menu back-label="S3 Storage" back-title="Back to Integrations"
|
||||
data-settings-search-items="{{ json_encode(settingsSearchItems(['S3 storage' => $settingsMenuItems], $storageRouteParameters)) }}">
|
||||
<nav aria-label="S3 storage settings"
|
||||
class="grid grid-cols-2 gap-0.5 border-y border-neutral-200 py-3 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-1 xl:border-y-0 xl:py-0 dark:border-white/[0.06]">
|
||||
|
||||
@@ -58,7 +58,7 @@ test('an application page teleports its menu into the main sidebar ', function (
|
||||
->toContain('x-teleport="#main-nav-context-0"')
|
||||
->toContain('application-settings-navigation in-main-nav')
|
||||
->toMatch('#<button type="button" @click="navLevel = -1; navSwap = \'back\'"\s+title="Back to the main menu"#')
|
||||
->toMatch('#@click="navLevel = 0; navSwap = \'forward\'"\s+title="Back to the Navbar Menu App menu"#')
|
||||
->not->toContain('Back to the Navbar Menu App menu')
|
||||
->not->toContain('id="main-nav-context-1"')
|
||||
->and(substr_count($html, 'id="main-nav-context-0"'))->toBe(1);
|
||||
});
|
||||
@@ -144,7 +144,7 @@ test('a database backup page keeps the database menu one back away in the main s
|
||||
->toContain('x-teleport="#main-nav-context-1"')
|
||||
->toMatch('#@click="navLevel = -1; navSwap = \'back\'"\s+title="Back to the main menu"#')
|
||||
->toMatch('#@click="navLevel = 0; navSwap = \'back\'"\s+title="Back to the database menu"#')
|
||||
->toMatch('#@click="navLevel = 1; navSwap = \'forward\'"\s+title="Back to the orders-db menu"#')
|
||||
->not->toContain('Back to the orders-db menu')
|
||||
->and(substr_count($html, 'aria-label="Database settings"'))->toBe(1)
|
||||
->and(substr_count($html, 'aria-label="Backup settings"'))->toBe(2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user