@nanisoft/prism-ui 0.10.2 → 0.13.0
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/LICENSE +21 -21
- package/dist/.tsbuildinfo +1 -1
- package/dist/blocks/app-shell-01/app-shell.js +4 -4
- package/dist/blocks/app-shell-01/index.d.ts +2 -2
- package/dist/blocks/app-shell-01/index.js +1 -1
- package/dist/blocks/auth-form-01/auth-form.d.ts +11 -1
- package/dist/blocks/auth-form-01/auth-form.d.ts.map +1 -1
- package/dist/blocks/auth-form-01/auth-form.js +11 -8
- package/dist/blocks/auth-form-01/index.d.ts +2 -2
- package/dist/blocks/auth-form-01/index.js +1 -1
- package/dist/blocks/cta-01/cta.d.ts +26 -21
- package/dist/blocks/cta-01/cta.d.ts.map +1 -1
- package/dist/blocks/cta-01/cta.js +2 -2
- package/dist/blocks/cta-01/index.d.ts +2 -2
- package/dist/blocks/cta-01/index.js +1 -1
- package/dist/blocks/data-table-01/data-table.js +7 -7
- package/dist/blocks/data-table-01/index.d.ts +2 -2
- package/dist/blocks/data-table-01/index.js +1 -1
- package/dist/blocks/empty-state-01/empty-state.d.ts +143 -0
- package/dist/blocks/empty-state-01/empty-state.d.ts.map +1 -0
- package/dist/blocks/empty-state-01/empty-state.js +104 -0
- package/dist/blocks/empty-state-01/index.d.ts +3 -0
- package/dist/blocks/empty-state-01/index.d.ts.map +1 -0
- package/dist/blocks/empty-state-01/index.js +1 -0
- package/dist/blocks/feature-grid-01/feature-grid.d.ts +28 -1
- package/dist/blocks/feature-grid-01/feature-grid.d.ts.map +1 -1
- package/dist/blocks/feature-grid-01/feature-grid.js +34 -3
- package/dist/blocks/feature-grid-01/index.d.ts +2 -2
- package/dist/blocks/feature-grid-01/index.js +1 -1
- package/dist/blocks/hero-01/hero.d.ts +35 -15
- package/dist/blocks/hero-01/hero.d.ts.map +1 -1
- package/dist/blocks/hero-01/hero.js +14 -9
- package/dist/blocks/hero-01/index.d.ts +2 -1
- package/dist/blocks/hero-01/index.d.ts.map +1 -1
- package/dist/blocks/hero-01/index.js +1 -1
- package/dist/blocks/index.d.ts +20 -20
- package/dist/blocks/index.js +19 -19
- package/dist/blocks/instrument-panel-01/index.d.ts +2 -2
- package/dist/blocks/instrument-panel-01/index.js +1 -1
- package/dist/blocks/instrument-panel-01/instrument-panel.js +1 -1
- package/dist/blocks/logo-strip-01/index.d.ts +2 -2
- package/dist/blocks/logo-strip-01/index.js +1 -1
- package/dist/blocks/logo-strip-01/logo-strip.d.ts +1 -1
- package/dist/blocks/logo-strip-01/logo-strip.js +2 -2
- package/dist/blocks/note-grid-01/index.d.ts +2 -2
- package/dist/blocks/note-grid-01/index.js +1 -1
- package/dist/blocks/note-grid-01/note-grid.d.ts +1 -1
- package/dist/blocks/note-grid-01/note-grid.js +1 -1
- package/dist/blocks/page-header-01/index.d.ts +2 -2
- package/dist/blocks/page-header-01/index.js +1 -1
- package/dist/blocks/page-header-01/page-header.d.ts +1 -1
- package/dist/blocks/page-header-01/page-header.js +4 -4
- package/dist/blocks/pricing-01/index.d.ts +1 -1
- package/dist/blocks/pricing-01/index.js +1 -1
- package/dist/blocks/pricing-01/pricing.d.ts +8 -1
- package/dist/blocks/pricing-01/pricing.d.ts.map +1 -1
- package/dist/blocks/pricing-01/pricing.js +15 -5
- package/dist/blocks/process-flow-01/index.d.ts +3 -0
- package/dist/blocks/process-flow-01/index.d.ts.map +1 -0
- package/dist/blocks/process-flow-01/index.js +1 -0
- package/dist/blocks/process-flow-01/process-flow.d.ts +118 -0
- package/dist/blocks/process-flow-01/process-flow.d.ts.map +1 -0
- package/dist/blocks/process-flow-01/process-flow.js +71 -0
- package/dist/blocks/process-rail-01/index.d.ts +2 -2
- package/dist/blocks/process-rail-01/index.js +1 -1
- package/dist/blocks/process-rail-01/process-rail.d.ts +1 -1
- package/dist/blocks/process-rail-01/process-rail.js +2 -2
- package/dist/blocks/product-grid-01/index.d.ts +2 -2
- package/dist/blocks/product-grid-01/index.js +1 -1
- package/dist/blocks/product-grid-01/product-grid.d.ts +37 -5
- package/dist/blocks/product-grid-01/product-grid.d.ts.map +1 -1
- package/dist/blocks/product-grid-01/product-grid.js +20 -6
- package/dist/blocks/run-console-01/index.d.ts +3 -0
- package/dist/blocks/run-console-01/index.d.ts.map +1 -0
- package/dist/blocks/run-console-01/index.js +1 -0
- package/dist/blocks/run-console-01/run-console.d.ts +111 -0
- package/dist/blocks/run-console-01/run-console.d.ts.map +1 -0
- package/dist/blocks/run-console-01/run-console.js +48 -0
- package/dist/blocks/settings-panel-01/index.d.ts +2 -2
- package/dist/blocks/settings-panel-01/index.js +1 -1
- package/dist/blocks/settings-panel-01/settings-panel.d.ts +11 -1
- package/dist/blocks/settings-panel-01/settings-panel.d.ts.map +1 -1
- package/dist/blocks/settings-panel-01/settings-panel.js +15 -10
- package/dist/blocks/site-footer/index.d.ts +2 -2
- package/dist/blocks/site-footer/index.js +1 -1
- package/dist/blocks/site-footer/site-footer.d.ts +1 -1
- package/dist/blocks/site-footer/site-footer.js +2 -2
- package/dist/blocks/site-header/index.d.ts +2 -2
- package/dist/blocks/site-header/index.js +1 -1
- package/dist/blocks/site-header/site-header.d.ts +2 -2
- package/dist/blocks/site-header/site-header.js +3 -3
- package/dist/blocks/site-navbar/index.d.ts +3 -0
- package/dist/blocks/site-navbar/index.d.ts.map +1 -0
- package/dist/blocks/site-navbar/index.js +1 -0
- package/dist/blocks/site-navbar/mobile-nav.d.ts +48 -0
- package/dist/blocks/site-navbar/mobile-nav.d.ts.map +1 -0
- package/dist/blocks/site-navbar/mobile-nav.js +35 -0
- package/dist/blocks/site-navbar/mode-toggle.d.ts +39 -0
- package/dist/blocks/site-navbar/mode-toggle.d.ts.map +1 -0
- package/dist/blocks/site-navbar/mode-toggle.js +39 -0
- package/dist/blocks/site-navbar/navbar-controls.d.ts +79 -0
- package/dist/blocks/site-navbar/navbar-controls.d.ts.map +1 -0
- package/dist/blocks/site-navbar/navbar-controls.js +40 -0
- package/dist/blocks/site-navbar/search-entry.d.ts +29 -0
- package/dist/blocks/site-navbar/search-entry.d.ts.map +1 -0
- package/dist/blocks/site-navbar/search-entry.js +52 -0
- package/dist/blocks/site-navbar/site-navbar.d.ts +212 -0
- package/dist/blocks/site-navbar/site-navbar.d.ts.map +1 -0
- package/dist/blocks/site-navbar/site-navbar.js +61 -0
- package/dist/blocks/site-navbar/sites-menu.d.ts +40 -0
- package/dist/blocks/site-navbar/sites-menu.d.ts.map +1 -0
- package/dist/blocks/site-navbar/sites-menu.js +48 -0
- package/dist/blocks/site-navbar/theme-menu.d.ts +47 -0
- package/dist/blocks/site-navbar/theme-menu.d.ts.map +1 -0
- package/dist/blocks/site-navbar/theme-menu.js +55 -0
- package/dist/blocks/stack-grid-01/index.d.ts +2 -2
- package/dist/blocks/stack-grid-01/index.js +1 -1
- package/dist/blocks/stack-grid-01/stack-grid.d.ts +42 -11
- package/dist/blocks/stack-grid-01/stack-grid.d.ts.map +1 -1
- package/dist/blocks/stack-grid-01/stack-grid.js +15 -7
- package/dist/blocks/stats-01/index.d.ts +9 -1
- package/dist/blocks/stats-01/index.d.ts.map +1 -1
- package/dist/blocks/stats-01/index.js +8 -1
- package/dist/blocks/stats-01/stats.d.ts +1 -1
- package/dist/blocks/stats-01/stats.js +2 -2
- package/dist/blocks/status-ledger-01/index.d.ts +2 -2
- package/dist/blocks/status-ledger-01/index.js +1 -1
- package/dist/blocks/status-ledger-01/status-ledger.d.ts +1 -1
- package/dist/blocks/status-ledger-01/status-ledger.js +2 -2
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +473 -1
- package/dist/components/index.d.ts +104 -66
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +74 -40
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/alert-dialog.d.ts +119 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +82 -0
- package/dist/components/ui/alert.js +1 -1
- package/dist/components/ui/aspect-ratio.d.ts +60 -0
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.js +61 -0
- package/dist/components/ui/avatar.js +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/breadcrumb.js +1 -1
- package/dist/components/ui/button-group.d.ts +68 -0
- package/dist/components/ui/button-group.d.ts.map +1 -0
- package/dist/components/ui/button-group.js +54 -0
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/calendar.d.ts +158 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/calendar.js +216 -0
- package/dist/components/ui/card.d.ts +18 -6
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +23 -8
- package/dist/components/ui/carousel.d.ts +118 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/carousel.js +152 -0
- package/dist/components/ui/chart-frame.d.ts +216 -0
- package/dist/components/ui/chart-frame.d.ts.map +1 -0
- package/dist/components/ui/chart-frame.js +286 -0
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/collapsible.d.ts +97 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +54 -0
- package/dist/components/ui/combobox.d.ts +141 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox.js +243 -0
- package/dist/components/ui/command-palette.d.ts +106 -0
- package/dist/components/ui/command-palette.d.ts.map +1 -0
- package/dist/components/ui/command-palette.js +176 -0
- package/dist/components/ui/command.d.ts +82 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +37 -0
- package/dist/components/ui/context-menu.d.ts +151 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/context-menu.js +97 -0
- package/dist/components/ui/cta-link.js +1 -1
- package/dist/components/ui/date-picker.d.ts +111 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/date-picker.js +74 -0
- package/dist/components/ui/diagram.d.ts +84 -15
- package/dist/components/ui/diagram.d.ts.map +1 -1
- package/dist/components/ui/diagram.js +77 -7
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/diff.d.ts +105 -0
- package/dist/components/ui/diff.d.ts.map +1 -0
- package/dist/components/ui/diff.js +113 -0
- package/dist/components/ui/dropdown-menu.d.ts +18 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +1 -1
- package/dist/components/ui/fact-list.js +1 -1
- package/dist/components/ui/field.js +1 -1
- package/dist/components/ui/form.d.ts +151 -0
- package/dist/components/ui/form.d.ts.map +1 -0
- package/dist/components/ui/form.js +73 -0
- package/dist/components/ui/hover-card.d.ts +105 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/hover-card.js +49 -0
- package/dist/components/ui/input-group.d.ts +99 -0
- package/dist/components/ui/input-group.d.ts.map +1 -0
- package/dist/components/ui/input-group.js +83 -0
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/item.d.ts +113 -0
- package/dist/components/ui/item.d.ts.map +1 -0
- package/dist/components/ui/item.js +61 -0
- package/dist/components/ui/kbd.js +1 -1
- package/dist/components/ui/label.d.ts +58 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +29 -0
- package/dist/components/ui/live-region.d.ts +9 -0
- package/dist/components/ui/live-region.d.ts.map +1 -1
- package/dist/components/ui/live-region.js +10 -2
- package/dist/components/ui/mark.js +1 -1
- package/dist/components/ui/menubar.d.ts +197 -0
- package/dist/components/ui/menubar.d.ts.map +1 -0
- package/dist/components/ui/menubar.js +109 -0
- package/dist/components/ui/meter.d.ts +121 -0
- package/dist/components/ui/meter.d.ts.map +1 -0
- package/dist/components/ui/meter.js +82 -0
- package/dist/components/ui/native-select.d.ts +72 -0
- package/dist/components/ui/native-select.d.ts.map +1 -0
- package/dist/components/ui/native-select.js +55 -0
- package/dist/components/ui/navigation-menu.d.ts +186 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.js +94 -0
- package/dist/components/ui/number-field.d.ts +111 -0
- package/dist/components/ui/number-field.d.ts.map +1 -0
- package/dist/components/ui/number-field.js +84 -0
- package/dist/components/ui/one-time-code.d.ts +127 -0
- package/dist/components/ui/one-time-code.d.ts.map +1 -0
- package/dist/components/ui/one-time-code.js +57 -0
- package/dist/components/ui/pagination.js +1 -1
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/product-mark.d.ts +1 -1
- package/dist/components/ui/product-mark.js +1 -1
- package/dist/components/ui/product-switcher.d.ts +1 -1
- package/dist/components/ui/product-switcher.js +2 -2
- package/dist/components/ui/progress.js +1 -1
- package/dist/components/ui/prose.js +1 -1
- package/dist/components/ui/pulse-graph.js +1 -1
- package/dist/components/ui/pulse-series.js +1 -1
- package/dist/components/ui/radio-group.js +1 -1
- package/dist/components/ui/resizable.d.ts +129 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +205 -0
- package/dist/components/ui/scroll-area.d.ts +97 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +68 -0
- package/dist/components/ui/search-dialog.d.ts +139 -0
- package/dist/components/ui/search-dialog.d.ts.map +1 -0
- package/dist/components/ui/search-dialog.js +178 -0
- package/dist/components/ui/section.d.ts +26 -0
- package/dist/components/ui/section.d.ts.map +1 -1
- package/dist/components/ui/section.js +32 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/separator.js +1 -1
- package/dist/components/ui/sheet.d.ts +103 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +58 -0
- package/dist/components/ui/sidebar.d.ts +228 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +172 -0
- package/dist/components/ui/signal-field.js +1 -1
- package/dist/components/ui/skeleton.js +1 -1
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/spinner.d.ts +79 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/spinner.js +79 -0
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/table-sort.d.ts +97 -0
- package/dist/components/ui/table-sort.d.ts.map +1 -0
- package/dist/components/ui/table-sort.js +102 -0
- package/dist/components/ui/table.js +1 -1
- package/dist/components/ui/tabs.js +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/timeline.d.ts +106 -0
- package/dist/components/ui/timeline.d.ts.map +1 -0
- package/dist/components/ui/timeline.js +111 -0
- package/dist/components/ui/toast.d.ts +219 -0
- package/dist/components/ui/toast.d.ts.map +1 -0
- package/dist/components/ui/toast.js +270 -0
- package/dist/components/ui/toggle-group.d.ts +118 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +194 -0
- package/dist/components/ui/toggle.d.ts +73 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +44 -0
- package/dist/components/ui/tooltip.js +1 -1
- package/dist/components/ui/tree.js +1 -1
- package/dist/components/ui/typography.js +1 -1
- package/dist/fonts/Inter-OFL.txt +93 -93
- package/dist/index.d.ts +72 -70
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -60
- package/dist/lib/rank.d.ts +69 -0
- package/dist/lib/rank.d.ts.map +1 -0
- package/dist/lib/rank.js +77 -0
- package/dist/live/index.d.ts +22 -0
- package/dist/live/index.d.ts.map +1 -0
- package/dist/live/index.js +20 -0
- package/dist/live/run-stream-01/index.d.ts +3 -0
- package/dist/live/run-stream-01/index.d.ts.map +1 -0
- package/dist/live/run-stream-01/index.js +1 -0
- package/dist/live/run-stream-01/run-stream.d.ts +125 -0
- package/dist/live/run-stream-01/run-stream.d.ts.map +1 -0
- package/dist/live/run-stream-01/run-stream.js +111 -0
- package/dist/pages/auth-page/index.d.ts +15 -2
- package/dist/pages/auth-page/index.d.ts.map +1 -1
- package/dist/pages/auth-page/index.js +8 -4
- package/dist/pages/blog-post-page/index.js +5 -5
- package/dist/pages/dashboard-page/index.d.ts +4 -4
- package/dist/pages/dashboard-page/index.js +4 -4
- package/dist/pages/docs-shell/docs-shell.d.ts +37 -4
- package/dist/pages/docs-shell/docs-shell.d.ts.map +1 -1
- package/dist/pages/docs-shell/docs-shell.js +107 -16
- package/dist/pages/docs-shell/index.d.ts +2 -2
- package/dist/pages/docs-shell/index.js +1 -1
- package/dist/pages/index.d.ts +14 -14
- package/dist/pages/index.js +7 -7
- package/dist/pages/marketing-page/index.d.ts +6 -6
- package/dist/pages/marketing-page/index.js +5 -5
- package/dist/pages/not-found-page/index.js +4 -4
- package/dist/pages/settings-page/index.d.ts +3 -3
- package/dist/pages/settings-page/index.js +4 -4
- package/dist/provider/index.d.ts +4 -4
- package/dist/provider/index.js +2 -2
- package/dist/provider/provider.d.ts +1 -1
- package/dist/provider/provider.js +1 -1
- package/dist/provider/theme-script.d.ts +1 -1
- package/dist/provider/theme-script.js +1 -1
- package/dist/styles.css +689 -0
- package/package.json +9 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ProductMarkProps } from '../../components/ui/product-mark.js';
|
|
2
|
+
/** One destination in the mobile panel, which is the site's own navigation. */
|
|
3
|
+
export type MobileNavLink = {
|
|
4
|
+
/** The text of the link. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Where the link goes. */
|
|
7
|
+
href: string;
|
|
8
|
+
/** Marks this link as the page the reader is on. */
|
|
9
|
+
current?: boolean;
|
|
10
|
+
};
|
|
11
|
+
/** The props the mobile navigation takes. */
|
|
12
|
+
export type MobileNavProps = {
|
|
13
|
+
/** The product this navigation belongs to, drawn as the mark above the list. */
|
|
14
|
+
product: Pick<ProductMarkProps, 'id' | 'name' | 'pack'>;
|
|
15
|
+
/** Every destination, in the order a reader should meet them. */
|
|
16
|
+
links: readonly MobileNavLink[];
|
|
17
|
+
/** The accessible name of the panel, which is also the trigger's name. */
|
|
18
|
+
label: string;
|
|
19
|
+
/** The word on the trigger while the panel is closed. */
|
|
20
|
+
openLabel: string;
|
|
21
|
+
/** The word on the trigger while the panel is open. */
|
|
22
|
+
closeLabel: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The navigation for viewports below the row's own threshold.
|
|
26
|
+
*
|
|
27
|
+
* **It carries every destination, not a subset.** From the narrowest phone up to
|
|
28
|
+
* the width the horizontal row is authored for, this panel is the only way to reach
|
|
29
|
+
* a section of the site, so a link the row shows at `lg` and the panel omits at
|
|
30
|
+
* 640 is a route a reader on a small laptop cannot find at all. Both render the one
|
|
31
|
+
* array, so a destination added to one is in the other by construction rather than
|
|
32
|
+
* by remembering twice.
|
|
33
|
+
*
|
|
34
|
+
* **It is a Sheet rather than a disclosure panel of the navbar's own, and the
|
|
35
|
+
* difference is the overlay.** A panel that is a child of the bar sits over the
|
|
36
|
+
* page with the bar still visible and nothing above the rest of the document, so
|
|
37
|
+
* scrolling the page behind it moves content the reader thought was dismissed. A
|
|
38
|
+
* sheet owns a modal surface: the rest of the page is not reachable, Escape closes
|
|
39
|
+
* it, and focus is held inside it and handed back to the trigger on the way out.
|
|
40
|
+
* That is the behaviour a full-width menu over a long page needs, and it is the
|
|
41
|
+
* behaviour Prism's own navigation had to hand-write.
|
|
42
|
+
*
|
|
43
|
+
* The links are full width with a 44 pixel minimum height, because below the row's
|
|
44
|
+
* threshold this is a touch target and not a line of text, and the coarse-pointer
|
|
45
|
+
* floor in the design system asks for exactly that.
|
|
46
|
+
*/
|
|
47
|
+
export declare function MobileNav({ product, links, label, openLabel, closeLabel, }: MobileNavProps): import("react").JSX.Element;
|
|
48
|
+
//# sourceMappingURL=mobile-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobile-nav.d.ts","sourceRoot":"","sources":["../../../src/blocks/site-navbar/mobile-nav.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AAExE,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG;IAC1B,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG;IAC3B,gFAAgF;IAChF,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;IACvD,iEAAiE;IACjE,KAAK,EAAE,SAAS,aAAa,EAAE,CAAA;IAC/B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,UAAU,GACX,EAAE,cAAc,+BAsChB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Menu, X } from 'lucide-react';
|
|
5
|
+
import { Sheet, SheetContent, SheetTitle, SheetTrigger } from '../../components/ui/sheet.js';
|
|
6
|
+
import { ProductMark } from '../../components/ui/product-mark.js';
|
|
7
|
+
/**
|
|
8
|
+
* The navigation for viewports below the row's own threshold.
|
|
9
|
+
*
|
|
10
|
+
* **It carries every destination, not a subset.** From the narrowest phone up to
|
|
11
|
+
* the width the horizontal row is authored for, this panel is the only way to reach
|
|
12
|
+
* a section of the site, so a link the row shows at `lg` and the panel omits at
|
|
13
|
+
* 640 is a route a reader on a small laptop cannot find at all. Both render the one
|
|
14
|
+
* array, so a destination added to one is in the other by construction rather than
|
|
15
|
+
* by remembering twice.
|
|
16
|
+
*
|
|
17
|
+
* **It is a Sheet rather than a disclosure panel of the navbar's own, and the
|
|
18
|
+
* difference is the overlay.** A panel that is a child of the bar sits over the
|
|
19
|
+
* page with the bar still visible and nothing above the rest of the document, so
|
|
20
|
+
* scrolling the page behind it moves content the reader thought was dismissed. A
|
|
21
|
+
* sheet owns a modal surface: the rest of the page is not reachable, Escape closes
|
|
22
|
+
* it, and focus is held inside it and handed back to the trigger on the way out.
|
|
23
|
+
* That is the behaviour a full-width menu over a long page needs, and it is the
|
|
24
|
+
* behaviour Prism's own navigation had to hand-write.
|
|
25
|
+
*
|
|
26
|
+
* The links are full width with a 44 pixel minimum height, because below the row's
|
|
27
|
+
* threshold this is a touch target and not a line of text, and the coarse-pointer
|
|
28
|
+
* floor in the design system asks for exactly that.
|
|
29
|
+
*/
|
|
30
|
+
export function MobileNav({ product, links, label, openLabel, closeLabel, }) {
|
|
31
|
+
const [open, setOpen] = useState(false);
|
|
32
|
+
return (_jsxs(Sheet, { open: open, onOpenChange: setOpen, children: [_jsx(SheetTrigger, { "data-slot": "site-navbar-mobile-trigger", "aria-label": open ? closeLabel : openLabel, className: "border-border bg-card text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring flex size-11 shrink-0 items-center justify-center rounded-full border transition-colors focus-visible:ring-[3px] focus-visible:outline-none lg:hidden", children: open ? _jsx(X, { "aria-hidden": true, className: "size-5" }) : _jsx(Menu, { "aria-hidden": true, className: "size-5" }) }), _jsxs(SheetContent, { side: "right", className: "w-80", children: [_jsx(SheetTitle, { className: "sr-only", children: label }), _jsxs("nav", { "aria-label": label, className: "flex flex-col gap-1", children: [_jsx("div", { className: "mb-4 flex items-center", children: _jsx(ProductMark, { id: product.id, name: product.name, pack: product.pack, size: "md" }) }), links.map((link) => (_jsx("a", { href: link.href, "aria-current": link.current ? 'page' : undefined, onClick: () => setOpen(false), className: link.current
|
|
33
|
+
? 'bg-accent text-accent-foreground focus-visible:border-ring focus-visible:ring-ring flex min-h-11 items-center rounded-lg px-3 text-sm font-medium transition-colors focus-visible:ring-[3px] focus-visible:outline-none'
|
|
34
|
+
: 'text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring flex min-h-11 items-center rounded-lg px-3 text-sm font-medium transition-colors focus-visible:ring-[3px] focus-visible:outline-none', children: link.label }, link.href)))] })] })] }));
|
|
35
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** The props the mode toggle takes. */
|
|
2
|
+
export type ModeToggleProps = {
|
|
3
|
+
/** The accessible name of the control while the page is in light mode. */
|
|
4
|
+
lightLabel: string;
|
|
5
|
+
/** The accessible name of the control while the page is in dark mode. */
|
|
6
|
+
darkLabel: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* The light and dark control.
|
|
10
|
+
*
|
|
11
|
+
* One button rather than a menu, because the choice has two members and a menu is
|
|
12
|
+
* the shape a set of six belongs in. The icon states the mode the page is in and
|
|
13
|
+
* the name states the mode the button will move it to, which is the pairing that
|
|
14
|
+
* makes the control readable at a glance and unambiguous to a screen reader: a
|
|
15
|
+
* button labelled "dark mode" that is currently showing a sun is a control whose
|
|
16
|
+
* label and its state have to be reconciled before it can be used.
|
|
17
|
+
*
|
|
18
|
+
* **It reads the mode from the provider rather than from the document.** The class
|
|
19
|
+
* on `<html>` is the mode, so this could read `document.documentElement.classList`
|
|
20
|
+
* and would then hold a value the theme itself owns in two places. The provider is
|
|
21
|
+
* the single writer of that class, and a control that wrote it directly would be a
|
|
22
|
+
* second writer of a state every other part of the page reads.
|
|
23
|
+
*
|
|
24
|
+
* `aria-pressed` is on the control, and it is worth stating why a toggle rather than
|
|
25
|
+
* a pair of buttons: the button's accessible name changes with the mode, and a
|
|
26
|
+
* changing name on a pressed control is the combination that leaves a screen reader
|
|
27
|
+
* announcing "dark mode, pressed" for a page that is in light mode. The name
|
|
28
|
+
* describes the destination and the pressed state describes the current mode, so the
|
|
29
|
+
* two never contradict each other because neither claims to be the other.
|
|
30
|
+
*
|
|
31
|
+
* **The two labels are keyed to the mode they are shown in, not to the mode they
|
|
32
|
+
* name.** `lightLabel` is what the control is called while the page is in light
|
|
33
|
+
* mode, which is the word that sends a reader to dark mode. Reading them the other
|
|
34
|
+
* way round is the mistake this control shipped with and the test that found it:
|
|
35
|
+
* a page in light mode announced "Switch to light mode", which is a control that
|
|
36
|
+
* claims to do the thing the page is already doing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function ModeToggle({ lightLabel, darkLabel }: ModeToggleProps): import("react").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=mode-toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-toggle.d.ts","sourceRoot":"","sources":["../../../src/blocks/site-navbar/mode-toggle.tsx"],"names":[],"mappings":"AAMA,uCAAuC;AACvC,MAAM,MAAM,eAAe,GAAG;IAC5B,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,eAAe,+BAgBpE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Moon, Sun } from 'lucide-react';
|
|
4
|
+
import { usePrismTheme } from '../../provider/provider.js';
|
|
5
|
+
/**
|
|
6
|
+
* The light and dark control.
|
|
7
|
+
*
|
|
8
|
+
* One button rather than a menu, because the choice has two members and a menu is
|
|
9
|
+
* the shape a set of six belongs in. The icon states the mode the page is in and
|
|
10
|
+
* the name states the mode the button will move it to, which is the pairing that
|
|
11
|
+
* makes the control readable at a glance and unambiguous to a screen reader: a
|
|
12
|
+
* button labelled "dark mode" that is currently showing a sun is a control whose
|
|
13
|
+
* label and its state have to be reconciled before it can be used.
|
|
14
|
+
*
|
|
15
|
+
* **It reads the mode from the provider rather than from the document.** The class
|
|
16
|
+
* on `<html>` is the mode, so this could read `document.documentElement.classList`
|
|
17
|
+
* and would then hold a value the theme itself owns in two places. The provider is
|
|
18
|
+
* the single writer of that class, and a control that wrote it directly would be a
|
|
19
|
+
* second writer of a state every other part of the page reads.
|
|
20
|
+
*
|
|
21
|
+
* `aria-pressed` is on the control, and it is worth stating why a toggle rather than
|
|
22
|
+
* a pair of buttons: the button's accessible name changes with the mode, and a
|
|
23
|
+
* changing name on a pressed control is the combination that leaves a screen reader
|
|
24
|
+
* announcing "dark mode, pressed" for a page that is in light mode. The name
|
|
25
|
+
* describes the destination and the pressed state describes the current mode, so the
|
|
26
|
+
* two never contradict each other because neither claims to be the other.
|
|
27
|
+
*
|
|
28
|
+
* **The two labels are keyed to the mode they are shown in, not to the mode they
|
|
29
|
+
* name.** `lightLabel` is what the control is called while the page is in light
|
|
30
|
+
* mode, which is the word that sends a reader to dark mode. Reading them the other
|
|
31
|
+
* way round is the mistake this control shipped with and the test that found it:
|
|
32
|
+
* a page in light mode announced "Switch to light mode", which is a control that
|
|
33
|
+
* claims to do the thing the page is already doing.
|
|
34
|
+
*/
|
|
35
|
+
export function ModeToggle({ lightLabel, darkLabel }) {
|
|
36
|
+
const { mode, toggleMode } = usePrismTheme();
|
|
37
|
+
const dark = mode === 'dark';
|
|
38
|
+
return (_jsx("button", { type: "button", "data-slot": "site-navbar-mode-toggle", onClick: toggleMode, "aria-label": dark ? darkLabel : lightLabel, "aria-pressed": dark, className: "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring flex size-11 shrink-0 items-center justify-center rounded-full border transition-colors focus-visible:ring-[3px] focus-visible:outline-none", children: dark ? _jsx(Sun, { "aria-hidden": true, className: "size-4" }) : _jsx(Moon, { "aria-hidden": true, className: "size-4" }) }));
|
|
39
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Mode, PackId } from '../../theming/index.js';
|
|
2
|
+
import type { SearchDialogMessages } from '../../components/ui/search-dialog.js';
|
|
3
|
+
import { type ThemePack } from './theme-menu.js';
|
|
4
|
+
import type { SwitcherProduct } from '../../components/ui/product-switcher.js';
|
|
5
|
+
import type { MobileNavLink } from './mobile-nav.js';
|
|
6
|
+
/** What the control cluster was told to render. Every field is optional. */
|
|
7
|
+
export type NavbarControlsProps = {
|
|
8
|
+
/** The product whose mark heads the mobile panel. */
|
|
9
|
+
product: {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
pack?: PackId | null;
|
|
13
|
+
};
|
|
14
|
+
/** The site's own destinations, for the panel below the row's threshold. */
|
|
15
|
+
nav: readonly MobileNavLink[];
|
|
16
|
+
/** The accessible name of the panel and of its trigger. */
|
|
17
|
+
navLabel: string;
|
|
18
|
+
/** The set of sites, or nothing for a site that is the only one. */
|
|
19
|
+
sites?: readonly SwitcherProduct[];
|
|
20
|
+
/** The `id` of the site the reader is on. */
|
|
21
|
+
currentSiteId?: string;
|
|
22
|
+
/** The accessible name of the sites menu. */
|
|
23
|
+
sitesLabel?: string;
|
|
24
|
+
/** Where the search index is served from, or nothing for no search. */
|
|
25
|
+
search?: {
|
|
26
|
+
indexUrl: string;
|
|
27
|
+
label: string;
|
|
28
|
+
hint?: string;
|
|
29
|
+
messages: SearchDialogMessages;
|
|
30
|
+
};
|
|
31
|
+
/** The packs the chooser offers, or nothing for no chooser. */
|
|
32
|
+
theme?: {
|
|
33
|
+
label: string;
|
|
34
|
+
packs?: readonly ThemePack[];
|
|
35
|
+
};
|
|
36
|
+
/** The two names of the light and dark control, or nothing for no toggle. */
|
|
37
|
+
mode?: {
|
|
38
|
+
lightLabel: string;
|
|
39
|
+
darkLabel: string;
|
|
40
|
+
};
|
|
41
|
+
/** The two names of the mobile trigger. */
|
|
42
|
+
mobileLabels: {
|
|
43
|
+
open: string;
|
|
44
|
+
close: string;
|
|
45
|
+
};
|
|
46
|
+
/** The pack a reader with no stored choice gets. */
|
|
47
|
+
defaultPack: PackId;
|
|
48
|
+
/** The mode a reader with no stored choice gets. */
|
|
49
|
+
defaultMode: Mode;
|
|
50
|
+
/** A slot for controls the consumer owns, after the ones above. */
|
|
51
|
+
actions?: React.ReactNode;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The bar's controls, and the only client boundary in the navbar.
|
|
55
|
+
*
|
|
56
|
+
* Everything interactive in a site header is application state: what a reader has
|
|
57
|
+
* chosen, what is open, what a search found. None of it is a fact the bar can be
|
|
58
|
+
* told, so none of it can live in a server Component, and the boundary is drawn
|
|
59
|
+
* here rather than around the whole bar so that the brand lockup and the
|
|
60
|
+
* navigation stay server rendered. That is the arrangement that lets a site keep
|
|
61
|
+
* the rest of its page free of client JavaScript, which is the property three of
|
|
62
|
+
* the five NaniSoft sites are built around.
|
|
63
|
+
*
|
|
64
|
+
* **The provider is mounted here and not in the site's root layout, and that is
|
|
65
|
+
* deliberate.** A provider in the layout would wrap every page and every provider
|
|
66
|
+
* is context, so a page that never renders a control would still ship it. Mounted
|
|
67
|
+
* around five buttons, it ships with the buttons and stops there. It is also the
|
|
68
|
+
* only writer of the two attributes the boot script reads, so a choice made here
|
|
69
|
+
* is a choice the next page load resolves to the same theme.
|
|
70
|
+
*
|
|
71
|
+
* **The order is fixed and it is a reading order, not a preference.** Search first
|
|
72
|
+
* because it is the only control that answers a question the reader arrived with;
|
|
73
|
+
* then the two menus, which are choices about where to be rather than about what to
|
|
74
|
+
* do; then the mode, which is the choice that persists across every site in the
|
|
75
|
+
* family; then the mobile trigger, which is last because it is the only one that
|
|
76
|
+
* appears at the narrow end of the range and appears alone there.
|
|
77
|
+
*/
|
|
78
|
+
export declare function NavbarControls(props: NavbarControlsProps): import("react").JSX.Element | null;
|
|
79
|
+
//# sourceMappingURL=navbar-controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navbar-controls.d.ts","sourceRoot":"","sources":["../../../src/blocks/site-navbar/navbar-controls.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAI7E,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAA;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAIjD,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG;IAChC,qDAAqD;IACrD,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;IAC3D,4EAA4E;IAC5E,GAAG,EAAE,SAAS,aAAa,EAAE,CAAA;IAC7B,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uEAAuE;IACvE,MAAM,CAAC,EAAE;QACP,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,oBAAoB,CAAA;KAC/B,CAAA;IACD,+DAA+D;IAC/D,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;KAAE,CAAA;IACvD,6EAA6E;IAC7E,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,2CAA2C;IAC3C,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAA;IACnB,oDAAoD;IACpD,WAAW,EAAE,IAAI,CAAA;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,sCAsDxD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ModeToggle } from './mode-toggle.js';
|
|
4
|
+
import { SearchEntry } from './search-entry.js';
|
|
5
|
+
import { SitesMenu } from './sites-menu.js';
|
|
6
|
+
import { ThemeMenu } from './theme-menu.js';
|
|
7
|
+
import { MobileNav } from './mobile-nav.js';
|
|
8
|
+
import { PrismProvider } from '../../provider/provider.js';
|
|
9
|
+
/**
|
|
10
|
+
* The bar's controls, and the only client boundary in the navbar.
|
|
11
|
+
*
|
|
12
|
+
* Everything interactive in a site header is application state: what a reader has
|
|
13
|
+
* chosen, what is open, what a search found. None of it is a fact the bar can be
|
|
14
|
+
* told, so none of it can live in a server Component, and the boundary is drawn
|
|
15
|
+
* here rather than around the whole bar so that the brand lockup and the
|
|
16
|
+
* navigation stay server rendered. That is the arrangement that lets a site keep
|
|
17
|
+
* the rest of its page free of client JavaScript, which is the property three of
|
|
18
|
+
* the five NaniSoft sites are built around.
|
|
19
|
+
*
|
|
20
|
+
* **The provider is mounted here and not in the site's root layout, and that is
|
|
21
|
+
* deliberate.** A provider in the layout would wrap every page and every provider
|
|
22
|
+
* is context, so a page that never renders a control would still ship it. Mounted
|
|
23
|
+
* around five buttons, it ships with the buttons and stops there. It is also the
|
|
24
|
+
* only writer of the two attributes the boot script reads, so a choice made here
|
|
25
|
+
* is a choice the next page load resolves to the same theme.
|
|
26
|
+
*
|
|
27
|
+
* **The order is fixed and it is a reading order, not a preference.** Search first
|
|
28
|
+
* because it is the only control that answers a question the reader arrived with;
|
|
29
|
+
* then the two menus, which are choices about where to be rather than about what to
|
|
30
|
+
* do; then the mode, which is the choice that persists across every site in the
|
|
31
|
+
* family; then the mobile trigger, which is last because it is the only one that
|
|
32
|
+
* appears at the narrow end of the range and appears alone there.
|
|
33
|
+
*/
|
|
34
|
+
export function NavbarControls(props) {
|
|
35
|
+
const { product, nav, navLabel, sites, currentSiteId, sitesLabel, search, theme, mode, mobileLabels, defaultPack, defaultMode, actions, } = props;
|
|
36
|
+
const hasThemeControls = Boolean(theme) || Boolean(mode);
|
|
37
|
+
if (!search && !sites && !hasThemeControls && !actions && nav.length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
return (_jsx(PrismProvider, { defaultPack: defaultPack, defaultMode: defaultMode, children: _jsxs("div", { className: "ms-auto flex items-center gap-2", children: [search ? (_jsx(SearchEntry, { indexUrl: search.indexUrl, label: search.label, hint: search.hint, messages: search.messages })) : null, sites && sites.length > 0 && sitesLabel ? (_jsx(SitesMenu, { sites: sites, currentId: currentSiteId, label: sitesLabel })) : null, theme ? _jsx(ThemeMenu, { label: theme.label, packs: theme.packs }) : null, mode ? _jsx(ModeToggle, { lightLabel: mode.lightLabel, darkLabel: mode.darkLabel }) : null, actions, nav.length > 0 ? (_jsx(MobileNav, { product: product, links: nav, label: navLabel, openLabel: mobileLabels.open, closeLabel: mobileLabels.close })) : null] }) }));
|
|
40
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SearchDialogProps } from '../../components/ui/search-dialog.js';
|
|
2
|
+
/** The props the search entry takes. It is the dialog's props without its close. */
|
|
3
|
+
export type SearchEntryProps = Omit<SearchDialogProps, 'onClose'>;
|
|
4
|
+
/**
|
|
5
|
+
* The search trigger, and the dialog it opens.
|
|
6
|
+
*
|
|
7
|
+
* **The dialog is loaded on the first activation, so neither the dialog nor the
|
|
8
|
+
* index is part of any page's first paint.** The index is the largest single asset
|
|
9
|
+
* on a documentation site, and a statically imported dialog is in the module graph
|
|
10
|
+
* of every page whether or not the reader ever searches. The trigger is a plain
|
|
11
|
+
* button and the cost of reaching it is one click.
|
|
12
|
+
*
|
|
13
|
+
* **The shortcut is Command-K on Apple platforms and Control-K everywhere else,
|
|
14
|
+
* and it matches rather than replaces.** The listener calls `preventDefault` so the
|
|
15
|
+
* browser's own find behaviour does not also fire, and it toggles so pressing it
|
|
16
|
+
* twice leaves the reader where they started. It is registered on the document
|
|
17
|
+
* rather than on the button, because a shortcut scoped to a control only works once
|
|
18
|
+
* that control has focus, and the point of a shortcut is to save the reader from
|
|
19
|
+
* having to find the control first.
|
|
20
|
+
*
|
|
21
|
+
* **It is icon-only at every width.** The control is not a destination, so its word
|
|
22
|
+
* is the first thing that goes when the bar runs out of room, and the row it sits in
|
|
23
|
+
* is measured rather than assumed: a labelled search control is 55 pixels wider than
|
|
24
|
+
* an icon in the same slot, and on a site whose navigation is nine Sections that is
|
|
25
|
+
* the difference between fitting at the authored breakpoint and folding the brand
|
|
26
|
+
* onto two lines. The accessible name is what replaces the word.
|
|
27
|
+
*/
|
|
28
|
+
export declare function SearchEntry(props: SearchEntryProps): import("react").JSX.Element;
|
|
29
|
+
//# sourceMappingURL=search-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-entry.d.ts","sourceRoot":"","sources":["../../../src/blocks/site-navbar/search-entry.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAe1E,oFAAoF;AACpF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;AAEjE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BAwClD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { lazy, Suspense, useEffect, useState } from 'react';
|
|
4
|
+
import { Search } from 'lucide-react';
|
|
5
|
+
/**
|
|
6
|
+
* The dialog, loaded on the first activation.
|
|
7
|
+
*
|
|
8
|
+
* Declared at module scope so the import is shared by every search entry on a page
|
|
9
|
+
* rather than re-issued per call, which is what makes a second search on the same
|
|
10
|
+
* page instant. `lazy` is React's own rather than a framework's, because this
|
|
11
|
+
* package imports no framework and has to stay installable in a bundler that is
|
|
12
|
+
* not the one its own site uses.
|
|
13
|
+
*/
|
|
14
|
+
const SearchDialog = lazy(() => import('../../components/ui/search-dialog.js').then((module) => ({ default: module.SearchDialog })));
|
|
15
|
+
/**
|
|
16
|
+
* The search trigger, and the dialog it opens.
|
|
17
|
+
*
|
|
18
|
+
* **The dialog is loaded on the first activation, so neither the dialog nor the
|
|
19
|
+
* index is part of any page's first paint.** The index is the largest single asset
|
|
20
|
+
* on a documentation site, and a statically imported dialog is in the module graph
|
|
21
|
+
* of every page whether or not the reader ever searches. The trigger is a plain
|
|
22
|
+
* button and the cost of reaching it is one click.
|
|
23
|
+
*
|
|
24
|
+
* **The shortcut is Command-K on Apple platforms and Control-K everywhere else,
|
|
25
|
+
* and it matches rather than replaces.** The listener calls `preventDefault` so the
|
|
26
|
+
* browser's own find behaviour does not also fire, and it toggles so pressing it
|
|
27
|
+
* twice leaves the reader where they started. It is registered on the document
|
|
28
|
+
* rather than on the button, because a shortcut scoped to a control only works once
|
|
29
|
+
* that control has focus, and the point of a shortcut is to save the reader from
|
|
30
|
+
* having to find the control first.
|
|
31
|
+
*
|
|
32
|
+
* **It is icon-only at every width.** The control is not a destination, so its word
|
|
33
|
+
* is the first thing that goes when the bar runs out of room, and the row it sits in
|
|
34
|
+
* is measured rather than assumed: a labelled search control is 55 pixels wider than
|
|
35
|
+
* an icon in the same slot, and on a site whose navigation is nine Sections that is
|
|
36
|
+
* the difference between fitting at the authored breakpoint and folding the brand
|
|
37
|
+
* onto two lines. The accessible name is what replaces the word.
|
|
38
|
+
*/
|
|
39
|
+
export function SearchEntry(props) {
|
|
40
|
+
const [open, setOpen] = useState(false);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const onKeyDown = (event) => {
|
|
43
|
+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
setOpen((value) => !value);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
document.addEventListener('keydown', onKeyDown);
|
|
49
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
50
|
+
}, []);
|
|
51
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", "data-slot": "site-navbar-search-trigger", onClick: () => setOpen(true), "aria-label": props.label, "aria-haspopup": "dialog", "aria-expanded": open, className: "border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring flex size-11 shrink-0 items-center justify-center rounded-full border transition-colors focus-visible:ring-[3px] focus-visible:outline-none", children: _jsx(Search, { "aria-hidden": true, className: "size-4" }) }), open ? (_jsx(Suspense, { fallback: null, children: _jsx(SearchDialog, { ...props, onClose: () => setOpen(false) }) })) : null] }));
|
|
52
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type ProductMarkProps } from '../../components/ui/product-mark.js';
|
|
3
|
+
import type { SwitcherProduct } from '../../components/ui/product-switcher.js';
|
|
4
|
+
import type { SearchDialogMessages } from '../../components/ui/search-dialog.js';
|
|
5
|
+
import type { Mode, PackId } from '../../theming/index.js';
|
|
6
|
+
import type { ThemePack } from './theme-menu.js';
|
|
7
|
+
/**
|
|
8
|
+
* One destination in the bar's own navigation.
|
|
9
|
+
*
|
|
10
|
+
* `href` is required and `current` is opt-in. The bar marks the current page with
|
|
11
|
+
* `aria-current="page"` rather than with a colour, so a reader who cannot see the
|
|
12
|
+
* colour still knows where they are.
|
|
13
|
+
*/
|
|
14
|
+
export type SiteNavLink = {
|
|
15
|
+
/** The text of the link. */
|
|
16
|
+
label: string;
|
|
17
|
+
/** Where the link goes. */
|
|
18
|
+
href: string;
|
|
19
|
+
/**
|
|
20
|
+
* Marks this link as the page the reader is on. Set it on the one link whose
|
|
21
|
+
* destination is the current route.
|
|
22
|
+
*
|
|
23
|
+
* A site that renders the bar once in a root layout cannot know its own route,
|
|
24
|
+
* because a layout is handed no pathname. Such a site passes `currentPath`
|
|
25
|
+
* instead and the bar resolves the mark in the browser; see that prop.
|
|
26
|
+
*/
|
|
27
|
+
current?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Opens the destination in a new browsing context, which defaults the link
|
|
30
|
+
* relationship to `noopener noreferrer`. Prism does not decide what counts as
|
|
31
|
+
* external: a cross-origin destination is not by itself a reason to open a tab.
|
|
32
|
+
*/
|
|
33
|
+
newTab?: boolean;
|
|
34
|
+
};
|
|
35
|
+
/** The search the bar offers, which is a URL rather than an index. */
|
|
36
|
+
export type SiteNavSearch = {
|
|
37
|
+
/**
|
|
38
|
+
* Where this site's JSON index is served from, fetched on the first search and
|
|
39
|
+
* not before. A URL rather than the index itself, because the index is the
|
|
40
|
+
* largest asset on a documentation site and a value passed as a prop is
|
|
41
|
+
* serialized into the document of every route that renders the bar.
|
|
42
|
+
*/
|
|
43
|
+
indexUrl: string;
|
|
44
|
+
/** The accessible name of the trigger, of the dialog and of its field. */
|
|
45
|
+
label: string;
|
|
46
|
+
/** Every sentence the dialog can say, which a Component does not ship. */
|
|
47
|
+
messages: SearchDialogMessages;
|
|
48
|
+
/** The text shown before the reader has typed anything. */
|
|
49
|
+
hint?: string;
|
|
50
|
+
};
|
|
51
|
+
/** The colour chooser the bar offers, and whether it offers one at all. */
|
|
52
|
+
export type SiteNavTheme = {
|
|
53
|
+
/** The accessible name of the menu, and of the word on its trigger. */
|
|
54
|
+
label: string;
|
|
55
|
+
/**
|
|
56
|
+
* The packs to choose between, each with the word a reader reads for it. Omit it
|
|
57
|
+
* to offer every published pack under its own capitalised name.
|
|
58
|
+
*
|
|
59
|
+
* A product site passes nothing at all rather than passing this, because a site's
|
|
60
|
+
* ground is a property of the site and a reader who repaints it is a reader on a
|
|
61
|
+
* page that is no longer the one the site describes.
|
|
62
|
+
*/
|
|
63
|
+
packs?: readonly ThemePack[];
|
|
64
|
+
};
|
|
65
|
+
/** The light and dark control the bar offers. */
|
|
66
|
+
export type SiteNavMode = {
|
|
67
|
+
/** The control's accessible name while the page is in dark mode. */
|
|
68
|
+
lightLabel: string;
|
|
69
|
+
/** The control's accessible name while the page is in light mode. */
|
|
70
|
+
darkLabel: string;
|
|
71
|
+
};
|
|
72
|
+
/** The two names of the control that opens the navigation below the row. */
|
|
73
|
+
export type SiteNavMobileLabels = {
|
|
74
|
+
/** The word on the trigger while the panel is closed. */
|
|
75
|
+
open: string;
|
|
76
|
+
/** The word on the trigger while the panel is open. */
|
|
77
|
+
close: string;
|
|
78
|
+
};
|
|
79
|
+
/** The props a SiteNavbar takes. */
|
|
80
|
+
export type SiteNavbarProps = {
|
|
81
|
+
/**
|
|
82
|
+
* The product this bar belongs to: the id, name and pack its `ProductMark` is
|
|
83
|
+
* drawn from, and the mark that heads the mobile panel. The bar renders the mark
|
|
84
|
+
* itself rather than a slot, because a bar whose brand lockup is a slot is a bar
|
|
85
|
+
* every consumer has to reimplement.
|
|
86
|
+
*/
|
|
87
|
+
product: Pick<ProductMarkProps, 'id' | 'name' | 'pack'>;
|
|
88
|
+
/** Where the brand lockup goes. @defaultValue '/' */
|
|
89
|
+
homeHref?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The pack a reader who has never chosen a pack gets. It is passed to the theme
|
|
92
|
+
* runtime rather than read from the document, so a site states its own default in
|
|
93
|
+
* one place and the control and the page cannot disagree about it.
|
|
94
|
+
*/
|
|
95
|
+
defaultPack: PackId;
|
|
96
|
+
/**
|
|
97
|
+
* The mode a reader who has never chosen gets. Required for the same reason
|
|
98
|
+
* `defaultPack` is, and because a toggle with no stated starting mode is a
|
|
99
|
+
* control whose icon is a guess until it is pressed once.
|
|
100
|
+
*/
|
|
101
|
+
defaultMode: Mode;
|
|
102
|
+
/** This site's own destinations. Omit for a bar that carries only the lockup. */
|
|
103
|
+
nav?: readonly SiteNavLink[];
|
|
104
|
+
/**
|
|
105
|
+
* The accessible name of the site's navigation. Required, and required rather
|
|
106
|
+
* than defaulted because it is a word a reader hears: a Block that ships no copy
|
|
107
|
+
* ships no reader-facing copy either.
|
|
108
|
+
*/
|
|
109
|
+
navLabel: string;
|
|
110
|
+
/**
|
|
111
|
+
* The route the reader is on, for a site that renders the bar once in a root
|
|
112
|
+
* layout and therefore cannot mark the current link itself.
|
|
113
|
+
*
|
|
114
|
+
* A site that composes the bar per page, which is the arrangement that keeps the
|
|
115
|
+
* current link server rendered, sets `current` on the one link instead and leaves
|
|
116
|
+
* this off. The two are alternatives rather than layers, and a site that set both
|
|
117
|
+
* would have two answers to which link is current.
|
|
118
|
+
*/
|
|
119
|
+
currentPath?: string;
|
|
120
|
+
/**
|
|
121
|
+
* The set of sites to move between, rendered as a menu. Omit it on a site that is
|
|
122
|
+
* the only one; a set of one is a menu with a single item and no reason to exist.
|
|
123
|
+
*/
|
|
124
|
+
sites?: readonly SwitcherProduct[];
|
|
125
|
+
/** The `id` of the site the reader is on, marked in the menu. */
|
|
126
|
+
currentSiteId?: string;
|
|
127
|
+
/**
|
|
128
|
+
* The accessible name of the sites menu. Required whenever `sites` is passed, for
|
|
129
|
+
* the same reason `navLabel` is.
|
|
130
|
+
*/
|
|
131
|
+
sitesLabel?: string;
|
|
132
|
+
/** The search the bar offers, or nothing for no search. */
|
|
133
|
+
search?: SiteNavSearch;
|
|
134
|
+
/** The colour chooser the bar offers, or nothing for no chooser. */
|
|
135
|
+
theme?: SiteNavTheme;
|
|
136
|
+
/** The light and dark control the bar offers, or nothing for no toggle. */
|
|
137
|
+
mode?: SiteNavMode;
|
|
138
|
+
/**
|
|
139
|
+
* The two names of the mobile trigger, which is a round icon with no visible
|
|
140
|
+
* word. Required rather than defaulted, because a default would be a sentence
|
|
141
|
+
* this Block ships about a product that is not the caller's, and because a bar
|
|
142
|
+
* that renders an unlabelled round control below its own threshold has a
|
|
143
|
+
* keyboard reader reaching for something it cannot name.
|
|
144
|
+
*/
|
|
145
|
+
mobileLabels: SiteNavMobileLabels;
|
|
146
|
+
/**
|
|
147
|
+
* A slot for controls the product owns, after the ones this bar composes. A slot
|
|
148
|
+
* rather than a prop, because an account menu and a sign-in link are application
|
|
149
|
+
* state and neither is a fact a bar can be told.
|
|
150
|
+
*/
|
|
151
|
+
actions?: ReactNode;
|
|
152
|
+
/**
|
|
153
|
+
* Keeps the bar at the top of the viewport as the page scrolls. On by default,
|
|
154
|
+
* because the bar is how a reader leaves the page they are on, and a bar that
|
|
155
|
+
* scrolls away takes that with it on exactly the long pages a reader needs it.
|
|
156
|
+
*/
|
|
157
|
+
sticky?: boolean;
|
|
158
|
+
/** Layout only. Changing a Prism-owned visual property from here is prohibited. */
|
|
159
|
+
className?: string;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* The bar at the top of a product site, with the controls a reader needs on every
|
|
163
|
+
* page of it.
|
|
164
|
+
*
|
|
165
|
+
* It is `SiteHeader` plus the four controls that were missing from it, and it
|
|
166
|
+
* exists because all five NaniSoft sites had the same bar and every one of them had
|
|
167
|
+
* written the missing four separately: Prism's own site had search and a colour
|
|
168
|
+
* chooser and no way to reach its four siblings, and each of the four had a row of
|
|
169
|
+
* product marks where a menu belongs and no search, no mode control and no
|
|
170
|
+
* navigation at all below the width its own row stopped fitting. Five bars, one
|
|
171
|
+
* design language, and no two of them the same bar.
|
|
172
|
+
*
|
|
173
|
+
* Every string is a prop and the Block ships none. There is no site name, no
|
|
174
|
+
* default navigation, no "Search", no list of packs and no list of sites: a bar
|
|
175
|
+
* that hardcoded any of them would hand every consumer a claim about a product that
|
|
176
|
+
* is not theirs, which is the defect this Block exists to remove. The one piece of
|
|
177
|
+
* copy it derives is a pack's own name from its own identifier, and only when the
|
|
178
|
+
* caller names none.
|
|
179
|
+
*
|
|
180
|
+
* **The bar is one flex row that wraps, and it fits by measurement.** The brand
|
|
181
|
+
* lockup and the controls hold their ends, the navigation sits in the middle, and
|
|
182
|
+
* the navigation row is hidden below `lg` where the panel takes over. The brand
|
|
183
|
+
* lockup is the one element that never wraps: a wordmark broken across two lines is
|
|
184
|
+
* not a wordmark, and it is also the one element that yields rather than pushing a
|
|
185
|
+
* control off the right edge of the viewport, which is the harm a header-fit test
|
|
186
|
+
* exists to catch.
|
|
187
|
+
*
|
|
188
|
+
* **The navigation is a `nav` and the sites menu is a second landmark of its own.**
|
|
189
|
+
* A reader who navigates by landmark needs two regions rather than one region with
|
|
190
|
+
* two lists in it, and the two sets are different places: one is where this site
|
|
191
|
+
* goes and the other is where the family goes. The controls are not a region at
|
|
192
|
+
* all, because they are whatever this bar composed plus whatever the consumer put
|
|
193
|
+
* in `actions`, and wrapping them in a landmark would be a claim about content the
|
|
194
|
+
* Block does not own.
|
|
195
|
+
*
|
|
196
|
+
* The bottom hairline is `border-border`, so the bar separates from the page by a
|
|
197
|
+
* line rather than by a fill change, which is how every surface in this system is
|
|
198
|
+
* separated: in the base pack `background` and `card` resolve to the same value, so
|
|
199
|
+
* a fill is not available as a separator. The bar is translucent and blurred, so the
|
|
200
|
+
* content scrolling under it is legible through it rather than hidden by it, which
|
|
201
|
+
* is the reason a sticky bar can be translucent at all.
|
|
202
|
+
*
|
|
203
|
+
* **It is a server Component with one client island inside it.** The lockup and the
|
|
204
|
+
* navigation are rendered on the server and ship no JavaScript; the controls are a
|
|
205
|
+
* single boundary, because a control's state is a reader's state. A site that
|
|
206
|
+
* passes no `search`, `sites`, `theme`, `mode` or `nav` renders the whole bar on the
|
|
207
|
+
* server and ships none, which is the arrangement a static site wants and the reason
|
|
208
|
+
* those props are optional rather than required.
|
|
209
|
+
*/
|
|
210
|
+
export declare function SiteNavbar({ product, homeHref, defaultPack, defaultMode, nav, navLabel, currentPath, sites, currentSiteId, sitesLabel, search, theme, mode, mobileLabels, actions, sticky, className, }: SiteNavbarProps): import("react").JSX.Element;
|
|
211
|
+
export default SiteNavbar;
|
|
212
|
+
//# sourceMappingURL=site-navbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-navbar.d.ts","sourceRoot":"","sources":["../../../src/blocks/site-navbar/site-navbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAA;AAC3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAE7E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,sEAAsE;AACtE,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,QAAQ,EAAE,oBAAoB,CAAA;IAC9B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG;IACzB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;CAC7B,CAAA;AAED,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG;IACxB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,4EAA4E;AAC5E,MAAM,MAAM,mBAAmB,GAAG;IAChC,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,oCAAoC;AACpC,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;;OAKG;IACH,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;IACvD,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,WAAW,EAAE,IAAI,CAAA;IACjB,iFAAiF;IACjF,GAAG,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,oEAAoE;IACpE,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB;;;;;;OAMG;IACH,YAAY,EAAE,mBAAmB,CAAA;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAc,EACd,WAAW,EACX,WAAW,EACX,GAAG,EACH,QAAQ,EACR,WAAW,EACX,KAAK,EACL,aAAa,EACb,UAAU,EACV,MAAM,EACN,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,MAAa,EACb,SAAS,GACV,EAAE,eAAe,+BAkEjB;AAED,eAAe,UAAU,CAAA"}
|