@evinvest/uikit 0.32.0 → 0.33.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/README.md +21 -10
- package/dist/components/atomic/accordion.js +2 -1
- package/dist/components/atomic/accordion.js.map +1 -1
- package/dist/components/atomic/alert.js +4 -4
- package/dist/components/atomic/alert.js.map +1 -1
- package/dist/components/atomic/badge.js +4 -3
- package/dist/components/atomic/badge.js.map +1 -1
- package/dist/components/atomic/breadcrumb.js +7 -9
- package/dist/components/atomic/breadcrumb.js.map +1 -1
- package/dist/components/atomic/button.js +4 -3
- package/dist/components/atomic/button.js.map +1 -1
- package/dist/components/atomic/calendar.js +10 -25
- package/dist/components/atomic/calendar.js.map +1 -1
- package/dist/components/atomic/checkbox.js +2 -1
- package/dist/components/atomic/checkbox.js.map +1 -1
- package/dist/components/atomic/command.js +5 -20
- package/dist/components/atomic/command.js.map +1 -1
- package/dist/components/atomic/context-menu.js +6 -13
- package/dist/components/atomic/context-menu.js.map +1 -1
- package/dist/components/atomic/dialog.js +4 -2
- package/dist/components/atomic/dialog.js.map +1 -1
- package/dist/components/atomic/dropdown-menu.js +6 -14
- package/dist/components/atomic/dropdown-menu.js.map +1 -1
- package/dist/components/atomic/hover-card.js.map +1 -1
- package/dist/components/atomic/info-tip.js +8 -9
- package/dist/components/atomic/info-tip.js.map +1 -1
- package/dist/components/atomic/input-otp.js +2 -1
- package/dist/components/atomic/input-otp.js.map +1 -1
- package/dist/components/atomic/key-value.js +5 -4
- package/dist/components/atomic/key-value.js.map +1 -1
- package/dist/components/atomic/menubar.js +7 -18
- package/dist/components/atomic/menubar.js.map +1 -1
- package/dist/components/atomic/native-select.js +1 -1
- package/dist/components/atomic/native-select.js.map +1 -1
- package/dist/components/atomic/navigation-menu.js +6 -14
- package/dist/components/atomic/navigation-menu.js.map +1 -1
- package/dist/components/atomic/pagination.js +18 -19
- package/dist/components/atomic/pagination.js.map +1 -1
- package/dist/components/atomic/popover.js.map +1 -1
- package/dist/components/atomic/radio-group.js +5 -4
- package/dist/components/atomic/radio-group.js.map +1 -1
- package/dist/components/atomic/section-descriptor.js +5 -8
- package/dist/components/atomic/section-descriptor.js.map +1 -1
- package/dist/components/atomic/select-listbox.js +2 -2
- package/dist/components/atomic/select-listbox.js.map +1 -1
- package/dist/components/atomic/select.js +5 -13
- package/dist/components/atomic/select.js.map +1 -1
- package/dist/components/atomic/sheet.js +4 -2
- package/dist/components/atomic/sheet.js.map +1 -1
- package/dist/components/atomic/sidebar.js +7 -26
- package/dist/components/atomic/sidebar.js.map +1 -1
- package/dist/components/atomic/slider.js.map +1 -1
- package/dist/components/atomic/sonner.js +20 -18
- package/dist/components/atomic/sonner.js.map +1 -1
- package/dist/components/atomic/spinner.js +6 -3
- package/dist/components/atomic/spinner.js.map +1 -1
- package/dist/components/atomic/tabs.js.map +1 -1
- package/dist/components/atomic/toggle-group.js +2 -2
- package/dist/components/atomic/toggle-group.js.map +1 -1
- package/dist/components/atomic/toggle.js +3 -6
- package/dist/components/atomic/toggle.js.map +1 -1
- package/dist/components/atomic/tooltip.js.map +1 -1
- package/dist/components/derived/carousel.js +6 -6
- package/dist/components/derived/carousel.js.map +1 -1
- package/dist/components/derived/command-palette.js +8 -7
- package/dist/components/derived/command-palette.js.map +1 -1
- package/dist/components/derived/confirm-dialog.js +8 -13
- package/dist/components/derived/confirm-dialog.js.map +1 -1
- package/dist/components/derived/date-time-picker.js +10 -14
- package/dist/components/derived/date-time-picker.js.map +1 -1
- package/dist/components/derived/field.js.map +1 -1
- package/dist/components/derived/form.js +0 -1
- package/dist/components/derived/form.js.map +1 -1
- package/dist/components/derived/icon-button.js.map +1 -1
- package/dist/components/derived/item.js +0 -1
- package/dist/components/derived/item.js.map +1 -1
- package/dist/components/derived/popover-form.js +4 -3
- package/dist/components/derived/popover-form.js.map +1 -1
- package/dist/components/derived/settings.js +4 -4
- package/dist/components/derived/settings.js.map +1 -1
- package/dist/components/shell/account-menu-profile.js +1 -1
- package/dist/components/shell/account-menu-profile.js.map +1 -1
- package/dist/components/shell/account-settings-dialog.js +3 -2
- package/dist/components/shell/account-settings-dialog.js.map +1 -1
- package/dist/components/shell/aside.js +6 -4
- package/dist/components/shell/aside.js.map +1 -1
- package/dist/components/shell/auth-wall.js +3 -5
- package/dist/components/shell/auth-wall.js.map +1 -1
- package/dist/components/shell/bottom-tab-bar.js +3 -3
- package/dist/components/shell/bottom-tab-bar.js.map +1 -1
- package/dist/components/shell/chat-composer.js +9 -7
- package/dist/components/shell/chat-composer.js.map +1 -1
- package/dist/components/shell/chat-message.js.map +1 -1
- package/dist/components/shell/chat-typing.js +2 -1
- package/dist/components/shell/chat-typing.js.map +1 -1
- package/dist/components/shell/footer.js +26 -24
- package/dist/components/shell/footer.js.map +1 -1
- package/dist/components/shell/header-controls.js +17 -15
- package/dist/components/shell/header-controls.js.map +1 -1
- package/dist/components/shell/hotbar.js +158 -0
- package/dist/components/shell/hotbar.js.map +1 -0
- package/dist/components/shell/logo.js +3 -2
- package/dist/components/shell/logo.js.map +1 -1
- package/dist/components/shell/mobile-app-bar.js +4 -4
- package/dist/components/shell/mobile-app-bar.js.map +1 -1
- package/dist/components/shell/nav-collapse.js +6 -5
- package/dist/components/shell/nav-collapse.js.map +1 -1
- package/dist/components/shell/resource-error.js +2 -2
- package/dist/components/shell/resource-error.js.map +1 -1
- package/dist/components/shell/section-nav.js +3 -3
- package/dist/components/shell/section-nav.js.map +1 -1
- package/dist/components/shell/shell-icons.js +7 -22
- package/dist/components/shell/shell-icons.js.map +1 -1
- package/dist/components/shell/shell-nav.js +4 -4
- package/dist/components/shell/shell-nav.js.map +1 -1
- package/dist/components/shell/smart-header.js.map +1 -1
- package/dist/components/shell/status-screen.js +35 -35
- package/dist/components/shell/status-screen.js.map +1 -1
- package/dist/components/shell/system-banner.js +6 -6
- package/dist/components/shell/system-banner.js.map +1 -1
- package/dist/components/shell/workspace-tab.js +2 -1
- package/dist/components/shell/workspace-tab.js.map +1 -1
- package/dist/generated/accent.js +10 -10
- package/dist/generated/accent.js.map +1 -1
- package/dist/generated/accordion.js +6 -2
- package/dist/generated/accordion.js.map +1 -1
- package/dist/generated/account-list.js +4 -4
- package/dist/generated/account-list.js.map +1 -1
- package/dist/generated/account-settings-dialog.js +6 -2
- package/dist/generated/account-settings-dialog.js.map +1 -1
- package/dist/generated/alert-dialog.js +1 -1
- package/dist/generated/alert-dialog.js.map +1 -1
- package/dist/generated/alert.js +3 -10
- package/dist/generated/alert.js.map +1 -1
- package/dist/generated/aside.js +7 -0
- package/dist/generated/aside.js.map +1 -1
- package/dist/generated/badge.js +2 -11
- package/dist/generated/badge.js.map +1 -1
- package/dist/generated/band.js +10 -10
- package/dist/generated/band.js.map +1 -1
- package/dist/generated/breadcrumb.js +1 -1
- package/dist/generated/breadcrumb.js.map +1 -1
- package/dist/generated/button-group.js +3 -3
- package/dist/generated/button-group.js.map +1 -1
- package/dist/generated/button.js +4 -20
- package/dist/generated/button.js.map +1 -1
- package/dist/generated/calendar.js +5 -5
- package/dist/generated/calendar.js.map +1 -1
- package/dist/generated/card.js +1 -1
- package/dist/generated/card.js.map +1 -1
- package/dist/generated/carousel.js +1 -1
- package/dist/generated/carousel.js.map +1 -1
- package/dist/generated/chat-composer.js +9 -2
- package/dist/generated/chat-composer.js.map +1 -1
- package/dist/generated/chat-message.js +25 -19
- package/dist/generated/chat-message.js.map +1 -1
- package/dist/generated/checkbox.js +1 -1
- package/dist/generated/checkbox.js.map +1 -1
- package/dist/generated/command-palette.js +10 -1
- package/dist/generated/command-palette.js.map +1 -1
- package/dist/generated/command.js +8 -6
- package/dist/generated/command.js.map +1 -1
- package/dist/generated/confirm-dialog.js +8 -8
- package/dist/generated/confirm-dialog.js.map +1 -1
- package/dist/generated/context-menu.js +7 -5
- package/dist/generated/context-menu.js.map +1 -1
- package/dist/generated/copy.js +97 -0
- package/dist/generated/copy.js.map +1 -0
- package/dist/generated/date-time-picker.js +10 -0
- package/dist/generated/date-time-picker.js.map +1 -1
- package/dist/generated/dialog.js +2 -2
- package/dist/generated/dialog.js.map +1 -1
- package/dist/generated/drawer.js +6 -6
- package/dist/generated/drawer.js.map +1 -1
- package/dist/generated/dropdown-menu.js +7 -5
- package/dist/generated/dropdown-menu.js.map +1 -1
- package/dist/generated/empty.js +5 -5
- package/dist/generated/empty.js.map +1 -1
- package/dist/generated/field.js +9 -7
- package/dist/generated/field.js.map +1 -1
- package/dist/generated/footer.js +45 -0
- package/dist/generated/footer.js.map +1 -0
- package/dist/generated/header-controls.js +5 -10
- package/dist/generated/header-controls.js.map +1 -1
- package/dist/generated/hover-card.js +1 -1
- package/dist/generated/hover-card.js.map +1 -1
- package/dist/generated/icon-button.js +4 -2
- package/dist/generated/icon-button.js.map +1 -1
- package/dist/generated/icons.js +36 -0
- package/dist/generated/icons.js.map +1 -0
- package/dist/generated/info-tip.js +5 -0
- package/dist/generated/info-tip.js.map +1 -0
- package/dist/generated/input-group.js +10 -10
- package/dist/generated/input-group.js.map +1 -1
- package/dist/generated/input-otp.js +2 -2
- package/dist/generated/input-otp.js.map +1 -1
- package/dist/generated/input.js +4 -4
- package/dist/generated/input.js.map +1 -1
- package/dist/generated/item.js +11 -11
- package/dist/generated/item.js.map +1 -1
- package/dist/generated/kbd.js +1 -1
- package/dist/generated/kbd.js.map +1 -1
- package/dist/generated/key-value.js +7 -1
- package/dist/generated/key-value.js.map +1 -1
- package/dist/generated/label.js +1 -1
- package/dist/generated/label.js.map +1 -1
- package/dist/generated/logo.js +9 -0
- package/dist/generated/logo.js.map +1 -0
- package/dist/generated/menu.js +7 -0
- package/dist/generated/menu.js.map +1 -0
- package/dist/generated/menubar.js +10 -8
- package/dist/generated/menubar.js.map +1 -1
- package/dist/generated/navigation-menu.js +11 -5
- package/dist/generated/navigation-menu.js.map +1 -1
- package/dist/generated/orientation.js +5 -0
- package/dist/generated/orientation.js.map +1 -0
- package/dist/generated/pagination.js +15 -0
- package/dist/generated/pagination.js.map +1 -0
- package/dist/generated/popover-form.js +5 -0
- package/dist/generated/popover-form.js.map +1 -1
- package/dist/generated/popover.js +1 -1
- package/dist/generated/popover.js.map +1 -1
- package/dist/generated/primitives.js +7 -0
- package/dist/generated/primitives.js.map +1 -0
- package/dist/generated/radio-group.js +5 -1
- package/dist/generated/radio-group.js.map +1 -1
- package/dist/generated/section-descriptor.js +7 -0
- package/dist/generated/section-descriptor.js.map +1 -0
- package/dist/generated/select.js +16 -10
- package/dist/generated/select.js.map +1 -1
- package/dist/generated/settings.js +2 -7
- package/dist/generated/settings.js.map +1 -1
- package/dist/generated/sheet.js +1 -1
- package/dist/generated/sheet.js.map +1 -1
- package/dist/generated/sidebar.js +24 -12
- package/dist/generated/sidebar.js.map +1 -1
- package/dist/generated/size.js +12 -0
- package/dist/generated/size.js.map +1 -0
- package/dist/generated/skeleton.js +1 -1
- package/dist/generated/skeleton.js.map +1 -1
- package/dist/generated/slider.js +2 -2
- package/dist/generated/slider.js.map +1 -1
- package/dist/generated/slot.js +5 -0
- package/dist/generated/slot.js.map +1 -0
- package/dist/generated/smart-header.js +2 -0
- package/dist/generated/smart-header.js.map +1 -1
- package/dist/generated/sonner.js +11 -13
- package/dist/generated/sonner.js.map +1 -1
- package/dist/generated/spinner.js +5 -0
- package/dist/generated/spinner.js.map +1 -0
- package/dist/generated/status-screen.js +27 -0
- package/dist/generated/status-screen.js.map +1 -0
- package/dist/generated/switch.js +2 -2
- package/dist/generated/switch.js.map +1 -1
- package/dist/generated/system-banner.js +6 -16
- package/dist/generated/system-banner.js.map +1 -1
- package/dist/generated/table.js +9 -9
- package/dist/generated/table.js.map +1 -1
- package/dist/generated/tabs.js +2 -2
- package/dist/generated/tabs.js.map +1 -1
- package/dist/generated/textarea.js +1 -1
- package/dist/generated/textarea.js.map +1 -1
- package/dist/generated/toggle-group.js +9 -0
- package/dist/generated/toggle-group.js.map +1 -0
- package/dist/generated/toggle.js +1 -9
- package/dist/generated/toggle.js.map +1 -1
- package/dist/generated/tone.js +12 -0
- package/dist/generated/tone.js.map +1 -0
- package/dist/generated/tooltip.js +1 -1
- package/dist/generated/tooltip.js.map +1 -1
- package/dist/generated/workspace-tab.js +3 -3
- package/dist/generated/workspace-tab.js.map +1 -1
- package/dist/icons/icon-shapes.js +10 -0
- package/dist/icons/icon-shapes.js.map +1 -0
- package/dist/icons/select-chevron.js +2 -1
- package/dist/icons/select-chevron.js.map +1 -1
- package/dist/icons/ui-icons.js +3 -57
- package/dist/icons/ui-icons.js.map +1 -1
- package/dist/index.d.ts +203 -155
- package/dist/index.js +1 -0
- package/dist/lib/cn.js +1 -0
- package/dist/lib/cn.js.map +1 -1
- package/dist/primitives/use-floating.js.map +1 -1
- package/dist/primitives/use-roving-focus.js.map +1 -1
- package/package.json +1 -1
- package/styles/ev.css +13 -76
- package/styles/theme.css +133 -66
- package/styles/tokens.css +157 -149
package/README.md
CHANGED
|
@@ -65,17 +65,17 @@ your Tailwind v4 entrypoint — this is the load-bearing part of the kit:
|
|
|
65
65
|
| states | `hover` · `active` · `selected` — translucent tints; `scrim` — behind a modal |
|
|
66
66
|
| ink | `ink` · `ink-mid` · `ink-soft` — hierarchy, loudest first; `ink-faint` — disabled only |
|
|
67
67
|
| lines | `border-subtle` (row rule) · `border` (hairline, 14 %) · `border-strong` (state and overlay edges) · `input` (control edge, ≥ 3:1) · `ring` |
|
|
68
|
-
| roles | `brand` `primary` `secondary` `positive` `accent-trace` `accent-debug` `accent-info` `accent-warn` `accent-error`, each with `on-*` where it gets filled; `primary-ink` — the primary role as ink on a surface; `primary-hover` · `primary-border` — the primary button's
|
|
68
|
+
| roles | `brand` `primary` `secondary` `positive` `accent-trace` `accent-debug` `accent-info` `accent-warn` `accent-error`, each with `on-*` where it gets filled; `primary-ink` — the primary role as ink on a surface; `primary-hover` · `accent-*-hover` — a solid fill's hover, the fill moved away from its label by `--tint-hover`; `primary-border` — the primary button's edge |
|
|
69
69
|
| status inks | `positive-ink` · `accent-info-ink` — a quiet status role as text on a surface (derived, a palette may pin them); warn and error text wears `accent-warn` · `accent-error` itself, held to 3:1 |
|
|
70
|
-
| faces | `button-danger-*` (`bg` `hover` `border` `ink`) — the destructive `Button`; `
|
|
71
|
-
| type | `text-caption` 11/14 · `body-s` 12/16 · `body` 13/18 · `body-l` 14/20 · `h3` 14/20 · `h2` 24/30 · `h1` 32/38 · `figure-m` 20/24 · `figure-l` 28/32 (size and line height each) |
|
|
72
|
-
| scalars | `radius` (panel, 6 px) · `control-radius` (4 px) · `chip-radius` (4 px) · `depth-card` `depth-elevated` `depth-overlay` · `control-
|
|
70
|
+
| faces | `button-danger-*` (`bg` `hover` `border` `ink`) — the destructive `Button`; `tint-{neutral,primary,positive,info,warn,error,trace,debug}-{fill,edge}` — a toned `Badge`, `Toast`, `SystemBanner`, `Alert`; derived for a brand, pinned per theme by EV |
|
|
71
|
+
| type | `text-caption` 11/14 · `body-s` 12/16 · `body` 13/18 · `body-l` 14/20 · `h3` 14/20 · `h2` 24/30 · `h1` 32/38 · `figure-m` 20/24 · `figure-l` 28/32 (size and line height each), two ramps off the scalars `body-*` and `display-*` (see `docs/spec/roles.md`) |
|
|
72
|
+
| scalars | `radius` (panel, 6 px) · `control-radius` (4 px) · `chip-radius` (4 px) · `depth-card` `depth-elevated` `depth-overlay` · `control-h` `control-step` `control-inset` `control-px` `control-text` `disabled-opacity` `body-size` `body-step` `body-leading` `display-base` `display-step` `display-leading` `figure-leading` `display-scale` `band-py` `page-max` `page-px` `shell-rail-w` `shell-tab-bar-h` · `font-*` |
|
|
73
73
|
| motion | `ev-ease-out` `ev-ease-in-out` `ev-dur-fast` `ev-dur-base` `ev-dur-slow` `ev-rise` `ev-stagger` `ev-stagger-section` |
|
|
74
74
|
| charts | `chart-1` … `chart-6` |
|
|
75
75
|
|
|
76
|
-
A palette owes **
|
|
76
|
+
A palette owes **28 names**: the colours that are not derived, which is every
|
|
77
77
|
role and surface above plus `chart-1` … `chart-6`. The states, lines, inks,
|
|
78
|
-
status inks, faces and
|
|
78
|
+
status inks, faces, chips and `on-secondary` (the ink) are derived from them with formulas, so a brand
|
|
79
79
|
file that pins none of them still renders.
|
|
80
80
|
|
|
81
81
|
Custom properties inherit, so a scope class on a `<section>` re-themes its
|
|
@@ -154,7 +154,7 @@ It has two halves, each also shipped as a flat sheet of its own —
|
|
|
154
154
|
|
|
155
155
|
### Brand palettes
|
|
156
156
|
|
|
157
|
-
A second brand is a palette against the same names (
|
|
157
|
+
A second brand is a palette against the same names (28 of them, `chart-6` among them), scoped to
|
|
158
158
|
`[data-brand="<slug>"]`; light is its default and `.light` / `.dark` beneath it
|
|
159
159
|
pick a polarity, so a `<Section polarity="dark">` inside the brand takes the
|
|
160
160
|
brand's dark values. The package ships a generator for it, reading the
|
|
@@ -226,7 +226,7 @@ under a brand under another brand may match either.
|
|
|
226
226
|
|
|
227
227
|
### Fonts
|
|
228
228
|
|
|
229
|
-
The families are parameters, one per role, and not part of the
|
|
229
|
+
The families are parameters, one per role, and not part of the 28 colour names:
|
|
230
230
|
a palette is complete without them, and the generator only carries what a
|
|
231
231
|
brand file's `[fonts]` declares. Unset, each is EV's, and Oldschool carries the
|
|
232
232
|
families the navy look shipped with:
|
|
@@ -454,6 +454,16 @@ export function Nav() {
|
|
|
454
454
|
linkComponent?, hideFrom = "lg", labels: { back } }` — sticky under
|
|
455
455
|
`--ev-shell-offset`; with `back` the title centres.
|
|
456
456
|
- **`TopBar`** `{ start?, end? }` — layout only, server-safe.
|
|
457
|
+
- **`Hotbar`** `{ actions: { id, label, icon, shortcut?: "N" | "mod+K", onSelect,
|
|
458
|
+
pressed?, pinned? }[], status?, takeover?: { tone: "warn" | "error", message,
|
|
459
|
+
action? }, labels }` — the bottom strip of a terminal-style app; the app docks
|
|
460
|
+
it. Shortcuts are bound while it is mounted, pinned or not: a plain key skips
|
|
461
|
+
a focused field, `mod+` (⌘ on Apple, Ctrl elsewhere) fires anywhere, a key
|
|
462
|
+
another handler took is left alone. Which actions are pinned is the user's,
|
|
463
|
+
set in its Customize popover and kept in this browser's `localStorage`
|
|
464
|
+
(`ev-hotbar`). `pressed` is a toggle the app owns. Under a 64rem strip (a
|
|
465
|
+
container query, not the viewport) it is a sideways-scrolling chip row with
|
|
466
|
+
no status. A `takeover` tints the strip and replaces the actions until cleared.
|
|
457
467
|
- **`AccountMenu`** `{ account: { name?, email }, manageHref?, switchHref,
|
|
458
468
|
groups?: NavGroup[], onSignOut, linkComponent?, labels: { trigger, manage,
|
|
459
469
|
switchAccount, signOut } }` — an initials avatar opening the menu.
|
|
@@ -804,7 +814,7 @@ a button step only — `Input` and `SelectTrigger` already clear it at `lg`.
|
|
|
804
814
|
Oldschool); the kit ships no font files.
|
|
805
815
|
- The font role `display` is `serif`: `--brand-font-display` / `font-display`
|
|
806
816
|
become `--brand-font-serif` / `font-serif` (see [Fonts](#fonts)).
|
|
807
|
-
- A brand file must add `chart-6` (
|
|
817
|
+
- A brand file must add `chart-6` (28 names now); `evinvest-palette` names it.
|
|
808
818
|
- Panel radius is 6 px at every width (the `sm` bump to 8 px is gone), controls
|
|
809
819
|
and chips 4 px, and the depth tiers are flat. **Aquafix, vifnet and any other
|
|
810
820
|
brand take these and lose their card shadow** unless their scope overrides
|
|
@@ -923,7 +933,8 @@ measuring needs host-only `web-sys`). Known gaps:
|
|
|
923
933
|
`SelectValue` labels, `ListRows` / `ListRow` (a table's phone form), the
|
|
924
934
|
rest of the [app shell](#app-shell) (`AppShell`, `ShellNav`, `BottomTabBar`,
|
|
925
935
|
`NavBadge` / `NavDot`, `AccountMenu` and its profile form, `MobileAppBar`,
|
|
926
|
-
`PageFrame` / `PageHeading`, `SectionNav`, `ResourceError`, `Settled
|
|
936
|
+
`PageFrame` / `PageHeading`, `SectionNav`, `ResourceError`, `Settled`,
|
|
937
|
+
`Hotbar`) and
|
|
927
938
|
the parts that need a browser API Rust does not wrap: `AnimatedNumber` /
|
|
928
939
|
`useCountTween` (a frame loop and `Intl`), `ChatStreamText` (word diffing and
|
|
929
940
|
timers), and `ChatPanel` / `ChatDock` (`ResizeObserver`, scroll pinning).
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
ACCORDION_ITEM,
|
|
11
11
|
ACCORDION_TRIGGER
|
|
12
12
|
} from "../../generated/accordion.js";
|
|
13
|
+
import { iconShapes } from "../../icons/icon-shapes.js";
|
|
13
14
|
const AccordionContext = React.createContext(null);
|
|
14
15
|
function useAccordion() {
|
|
15
16
|
const ctx = React.useContext(AccordionContext);
|
|
@@ -101,7 +102,7 @@ function AccordionTrigger({
|
|
|
101
102
|
strokeLinecap: "round",
|
|
102
103
|
strokeLinejoin: "round",
|
|
103
104
|
className: "text-ink-soft pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200",
|
|
104
|
-
children:
|
|
105
|
+
children: iconShapes("chevron-down")
|
|
105
106
|
}
|
|
106
107
|
)
|
|
107
108
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/accordion.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { useControllableState } from \"../../primitives/use-controllable-state\";\nimport {\n ACCORDION_CONTENT,\n ACCORDION_CONTENT_INNER,\n ACCORDION_HEADER,\n ACCORDION_ITEM,\n ACCORDION_TRIGGER,\n} from \"../../generated/accordion\";\
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/accordion.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { useControllableState } from \"../../primitives/use-controllable-state\";\nimport {\n ACCORDION_CONTENT,\n ACCORDION_CONTENT_INNER,\n ACCORDION_HEADER,\n ACCORDION_ITEM,\n ACCORDION_TRIGGER,\n} from \"../../generated/accordion\";\nimport type { AccordionType } from \"../../generated/accordion\";\nimport { iconShapes } from \"../../icons/icon-shapes\";\n\n\ninterface AccordionContextValue {\n isOpen: (value: string) => boolean;\n toggle: (value: string) => void;\n}\n\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\nfunction useAccordion(): AccordionContextValue {\n const ctx = React.useContext(AccordionContext);\n if (!ctx) throw new Error(\"Accordion parts must be used within <Accordion>\");\n return ctx;\n}\n\nconst ItemContext = React.createContext<string | null>(null);\n\nfunction useItemValue(): string {\n const value = React.useContext(ItemContext);\n if (value === null)\n throw new Error(\"AccordionTrigger/Content must be used within <AccordionItem>\");\n return value;\n}\n\nexport interface AccordionProps\n extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n type?: AccordionType;\n collapsible?: boolean;\n value?: string[];\n defaultValue?: string[];\n onValueChange?: (value: string[]) => void;\n}\n\nexport function Accordion({\n type = \"single\",\n collapsible = false,\n value,\n defaultValue = [],\n onValueChange,\n children,\n ...props\n}: AccordionProps) {\n const [open, setOpen] = useControllableState<string[]>({\n ...(value !== undefined ? { value } : {}),\n defaultValue,\n ...(onValueChange ? { onChange: onValueChange } : {}),\n });\n\n const isOpen = (v: string) => open.includes(v);\n const toggle = (v: string) => {\n if (type === \"multiple\") {\n setOpen(open.includes(v) ? open.filter((x) => x !== v) : [...open, v]);\n return;\n }\n if (open.includes(v)) setOpen(collapsible ? [] : open);\n else setOpen([v]);\n };\n\n return (\n <AccordionContext.Provider value={{ isOpen, toggle }}>\n <div data-slot=\"accordion\" {...props}>\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\nexport interface AccordionItemProps extends React.ComponentProps<\"div\"> {\n value: string;\n}\n\nexport function AccordionItem({\n className,\n value,\n children,\n ...props\n}: AccordionItemProps) {\n return (\n <ItemContext.Provider value={value}>\n <div\n data-slot=\"accordion-item\"\n className={cn(ACCORDION_ITEM, className)}\n {...props}\n >\n {children}\n </div>\n </ItemContext.Provider>\n );\n}\n\nexport function AccordionTrigger({\n className,\n children,\n onClick,\n ...props\n}: React.ComponentProps<\"button\">) {\n const { isOpen, toggle } = useAccordion();\n const value = useItemValue();\n const open = isOpen(value);\n return (\n <h3 className={ACCORDION_HEADER} data-slot=\"accordion-header\">\n <button\n type=\"button\"\n data-slot=\"accordion-trigger\"\n data-state={open ? \"open\" : \"closed\"}\n aria-expanded={open}\n className={cn(ACCORDION_TRIGGER, className)}\n onClick={(e) => {\n onClick?.(e);\n toggle(value);\n }}\n {...props}\n >\n {children}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-ink-soft pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200\"\n >\n {iconShapes(\"chevron-down\")}\n </svg>\n </button>\n </h3>\n );\n}\n\nexport function AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\">) {\n const { isOpen } = useAccordion();\n const value = useItemValue();\n if (!isOpen(value)) return null;\n return (\n <div\n data-slot=\"accordion-content\"\n data-state=\"open\"\n className={ACCORDION_CONTENT}\n {...props}\n >\n <div className={cn(ACCORDION_CONTENT_INNER, className)}>{children}</div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,16 +4,16 @@ import { cn } from "../../lib/cn.js";
|
|
|
4
4
|
import {
|
|
5
5
|
ALERT_BASE,
|
|
6
6
|
ALERT_DESCRIPTION,
|
|
7
|
-
ALERT_TITLE
|
|
8
|
-
alertVariants
|
|
7
|
+
ALERT_TITLE
|
|
9
8
|
} from "../../generated/alert.js";
|
|
10
|
-
|
|
9
|
+
import { toneClasses } from "../../generated/tone.js";
|
|
10
|
+
function Alert({ className, tone = "neutral", ...props }) {
|
|
11
11
|
return /* @__PURE__ */ jsx(
|
|
12
12
|
"div",
|
|
13
13
|
{
|
|
14
14
|
"data-slot": "alert",
|
|
15
15
|
role: "alert",
|
|
16
|
-
className: cn(ALERT_BASE,
|
|
16
|
+
className: cn(ALERT_BASE, toneClasses[tone], className),
|
|
17
17
|
...props
|
|
18
18
|
}
|
|
19
19
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport {\n ALERT_BASE,\n ALERT_DESCRIPTION,\n ALERT_TITLE,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport {\n ALERT_BASE,\n ALERT_DESCRIPTION,\n ALERT_TITLE,\n} from \"../../generated/alert\";\nimport { toneClasses, type Tone } from \"../../generated/tone\";\n\nexport interface AlertProps extends React.ComponentProps<\"div\"> {\n tone?: Tone;\n}\n\nexport function Alert({ className, tone = \"neutral\", ...props }: AlertProps) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(ALERT_BASE, toneClasses[tone], className)}\n {...props}\n />\n );\n}\n\nexport function AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(ALERT_TITLE, className)}\n {...props}\n />\n );\n}\n\nexport function AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(ALERT_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n"],"mappings":"AAeI;AAfJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAA8B;AAMhC,SAAS,MAAM,EAAE,WAAW,OAAO,WAAW,GAAG,MAAM,GAAe;AAC3E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAW,GAAG,YAAY,YAAY,IAAI,GAAG,SAAS;AAAA,MACrD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC/E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,aAAa,SAAS;AAAA,MACnC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,mBAAmB,SAAS;AAAA,MACzC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -2,10 +2,11 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cn } from "../../lib/cn.js";
|
|
4
4
|
import { Slot } from "../../primitives/slot.js";
|
|
5
|
-
import { BADGE_BASE
|
|
5
|
+
import { BADGE_BASE } from "../../generated/badge.js";
|
|
6
|
+
import { toneClasses } from "../../generated/tone.js";
|
|
6
7
|
function Badge({
|
|
7
8
|
className,
|
|
8
|
-
|
|
9
|
+
tone = "neutral",
|
|
9
10
|
asChild = false,
|
|
10
11
|
...props
|
|
11
12
|
}) {
|
|
@@ -14,7 +15,7 @@ function Badge({
|
|
|
14
15
|
Comp,
|
|
15
16
|
{
|
|
16
17
|
"data-slot": "badge",
|
|
17
|
-
className: cn(BADGE_BASE,
|
|
18
|
+
className: cn(BADGE_BASE, toneClasses[tone], className),
|
|
18
19
|
...props
|
|
19
20
|
}
|
|
20
21
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/badge.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Slot } from \"../../primitives/slot\";\nimport { BADGE_BASE
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/badge.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Slot } from \"../../primitives/slot\";\nimport { BADGE_BASE } from \"../../generated/badge\";\nimport { toneClasses, type Tone } from \"../../generated/tone\";\n\nexport interface BadgeProps extends React.ComponentProps<\"span\"> {\n tone?: Tone;\n asChild?: boolean;\n}\n\nexport function Badge({\n className,\n tone = \"neutral\",\n asChild = false,\n ...props\n}: BadgeProps) {\n const Comp = asChild ? Slot : \"span\";\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(BADGE_BASE, toneClasses[tone], className)}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n"],"mappings":"AAmBI;AAnBJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAC3B,SAAS,mBAA8B;AAOhC,SAAS,MAAM;AAAA,EACpB;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL,GAAe;AACb,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,YAAY,IAAI,GAAG,SAAS;AAAA,MACrD,GAAI;AAAA;AAAA,EACP;AAEJ;","names":[]}
|
|
@@ -10,8 +10,10 @@ import {
|
|
|
10
10
|
BREADCRUMB_PAGE,
|
|
11
11
|
BREADCRUMB_SEPARATOR
|
|
12
12
|
} from "../../generated/breadcrumb.js";
|
|
13
|
+
import * as copy from "../../generated/copy.js";
|
|
14
|
+
import { iconShapes } from "../../icons/icon-shapes.js";
|
|
13
15
|
function Breadcrumb({ ...props }) {
|
|
14
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label":
|
|
16
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": copy.BREADCRUMB, "data-slot": "breadcrumb", ...props });
|
|
15
17
|
}
|
|
16
18
|
function BreadcrumbList({
|
|
17
19
|
className,
|
|
@@ -83,7 +85,7 @@ function BreadcrumbSeparator({
|
|
|
83
85
|
"aria-hidden": "true",
|
|
84
86
|
className: cn(BREADCRUMB_SEPARATOR, className),
|
|
85
87
|
...props,
|
|
86
|
-
children: children ?? /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children:
|
|
88
|
+
children: children ?? /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: iconShapes("chevron-right") })
|
|
87
89
|
}
|
|
88
90
|
);
|
|
89
91
|
}
|
|
@@ -100,7 +102,7 @@ function BreadcrumbEllipsis({
|
|
|
100
102
|
className: cn(BREADCRUMB_ELLIPSIS, className),
|
|
101
103
|
...props,
|
|
102
104
|
children: [
|
|
103
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ jsx(
|
|
104
106
|
"svg",
|
|
105
107
|
{
|
|
106
108
|
className: "size-4",
|
|
@@ -108,14 +110,10 @@ function BreadcrumbEllipsis({
|
|
|
108
110
|
fill: "none",
|
|
109
111
|
stroke: "currentColor",
|
|
110
112
|
strokeWidth: 2,
|
|
111
|
-
children:
|
|
112
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1" }),
|
|
113
|
-
/* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1" }),
|
|
114
|
-
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "1" })
|
|
115
|
-
]
|
|
113
|
+
children: iconShapes("ellipsis")
|
|
116
114
|
}
|
|
117
115
|
),
|
|
118
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children:
|
|
116
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: copy.BREADCRUMB_MORE })
|
|
119
117
|
]
|
|
120
118
|
}
|
|
121
119
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/breadcrumb.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Slot } from \"../../primitives/slot\";\nimport {\n BREADCRUMB_ELLIPSIS,\n BREADCRUMB_ITEM,\n BREADCRUMB_LINK,\n BREADCRUMB_LIST,\n BREADCRUMB_PAGE,\n BREADCRUMB_SEPARATOR,\n} from \"../../generated/breadcrumb\";\n\nexport function Breadcrumb({ ...props }: React.ComponentProps<\"nav\">) {\n return <nav aria-label
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/breadcrumb.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Slot } from \"../../primitives/slot\";\nimport {\n BREADCRUMB_ELLIPSIS,\n BREADCRUMB_ITEM,\n BREADCRUMB_LINK,\n BREADCRUMB_LIST,\n BREADCRUMB_PAGE,\n BREADCRUMB_SEPARATOR,\n} from \"../../generated/breadcrumb\";\nimport * as copy from \"../../generated/copy\";\nimport { iconShapes } from \"../../icons/icon-shapes\";\n\nexport function Breadcrumb({ ...props }: React.ComponentProps<\"nav\">) {\n return <nav aria-label={copy.BREADCRUMB} data-slot=\"breadcrumb\" {...props} />;\n}\n\nexport function BreadcrumbList({\n className,\n ...props\n}: React.ComponentProps<\"ol\">) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(BREADCRUMB_LIST, className)}\n {...props}\n />\n );\n}\n\nexport function BreadcrumbItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn(BREADCRUMB_ITEM, className)}\n {...props}\n />\n );\n}\n\nexport interface BreadcrumbLinkProps extends React.ComponentProps<\"a\"> {\n asChild?: boolean;\n}\n\nexport function BreadcrumbLink({\n asChild,\n className,\n ...props\n}: BreadcrumbLinkProps) {\n const Comp = asChild ? Slot : \"a\";\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn(BREADCRUMB_LINK, className)}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport function BreadcrumbPage({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(BREADCRUMB_PAGE, className)}\n {...props}\n />\n );\n}\n\nexport function BreadcrumbSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(BREADCRUMB_SEPARATOR, className)}\n {...props}\n >\n {children ?? (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n {iconShapes(\"chevron-right\")}\n </svg>\n )}\n </li>\n );\n}\n\nexport function BreadcrumbEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(BREADCRUMB_ELLIPSIS, className)}\n {...props}\n >\n <svg\n className=\"size-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n {iconShapes(\"ellipsis\")}\n </svg>\n <span className=\"sr-only\">{copy.BREADCRUMB_MORE}</span>\n </span>\n );\n}\n"],"mappings":"AAeS,cA2FL,YA3FK;AAfT,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,YAAY,UAAU;AACtB,SAAS,kBAAkB;AAEpB,SAAS,WAAW,EAAE,GAAG,MAAM,GAAgC;AACpE,SAAO,oBAAC,SAAI,cAAY,KAAK,YAAY,aAAU,cAAc,GAAG,OAAO;AAC7E;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,GAAG;AACL,GAA+B;AAC7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iBAAiB,SAAS;AAAA,MACvC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,GAAG;AACL,GAA+B;AAC7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iBAAiB,SAAS;AAAA,MACvC,GAAG;AAAA;AAAA,EACN;AAEJ;AAMO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAwB;AACtB,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iBAAiB,SAAS;AAAA,MACvC,GAAI;AAAA;AAAA,EACP;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,GAAG;AACL,GAAiC;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,iBAAc;AAAA,MACd,gBAAa;AAAA,MACb,WAAW,GAAG,iBAAiB,SAAS;AAAA,MACvC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA+B;AAC7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,sBAAsB,SAAS;AAAA,MAC5C,GAAG;AAAA,MAEH,sBACC,oBAAC,SAAI,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAa,GACrE,qBAAW,eAAe,GAC7B;AAAA;AAAA,EAEJ;AAEJ;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,GAAG;AACL,GAAiC;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW,GAAG,qBAAqB,SAAS;AAAA,MAC3C,GAAG;AAAA,MAEJ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,QAAO;AAAA,YACP,aAAa;AAAA,YAEZ,qBAAW,UAAU;AAAA;AAAA,QACxB;AAAA,QACA,oBAAC,UAAK,WAAU,WAAW,eAAK,iBAAgB;AAAA;AAAA;AAAA,EAClD;AAEJ;","names":[]}
|
|
@@ -2,11 +2,11 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cn } from "../../lib/cn.js";
|
|
4
4
|
import { Slot } from "../../primitives/slot.js";
|
|
5
|
+
import { sizeClasses } from "../../generated/size.js";
|
|
5
6
|
import { accentFillClasses, accentOutlineClasses } from "../../generated/accent.js";
|
|
6
7
|
import {
|
|
7
8
|
BUTTON_BASE,
|
|
8
|
-
|
|
9
|
-
buttonSizeClasses,
|
|
9
|
+
BUTTON_ICON,
|
|
10
10
|
buttonVariantClasses
|
|
11
11
|
} from "../../generated/button.js";
|
|
12
12
|
function buttonVariants({
|
|
@@ -19,7 +19,8 @@ function buttonVariants({
|
|
|
19
19
|
return cn(
|
|
20
20
|
BUTTON_BASE,
|
|
21
21
|
buttonVariantClasses[variant],
|
|
22
|
-
|
|
22
|
+
sizeClasses[size],
|
|
23
|
+
icon ? BUTTON_ICON : void 0,
|
|
23
24
|
accent === void 0 ? void 0 : accentClass(accent, variant),
|
|
24
25
|
className
|
|
25
26
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/button.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Slot } from \"../../primitives/slot\";\nimport { accentFillClasses, accentOutlineClasses, type Accent } from \"../../generated/accent\";\nimport {\n BUTTON_BASE,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/button.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Slot } from \"../../primitives/slot\";\nimport { sizeClasses, type Size } from \"../../generated/size\";\nimport { accentFillClasses, accentOutlineClasses, type Accent } from \"../../generated/accent\";\nimport {\n BUTTON_BASE,\n BUTTON_ICON,\n buttonVariantClasses,\n type ButtonVariant,\n} from \"../../generated/button\";\n\nexport type ButtonSize = Size;\nexport type { Accent, ButtonVariant };\n\nexport interface ButtonVariantsOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** A square button holding a bare glyph; `size` still picks the magnitude. */\n icon?: boolean;\n /** Recolours the button at an accent rung; unset is the normal case. */\n accent?: Accent | undefined;\n className?: string;\n}\n\n/**\n * Returns the fused canonical button class string. Reused by `pagination` so a\n * non-`Button` element can adopt the same styling, mirroring Rust's\n * `button_classes`.\n *\n * The accent fuses after the variant so it recolours whatever the variant set.\n */\nexport function buttonVariants({\n variant = \"primary\",\n size = \"md\",\n icon = false,\n accent,\n className,\n}: ButtonVariantsOptions = {}): string {\n return cn(\n BUTTON_BASE,\n buttonVariantClasses[variant],\n sizeClasses[size],\n icon ? BUTTON_ICON : undefined,\n accent === undefined ? undefined : accentClass(accent, variant),\n className,\n );\n}\n\n// Which face an accent wears is the variant's business — an outlined button tints\n// what it already has, anything else repaints. Mirrors Rust's `button_accent_class`.\nfunction accentClass(accent: Accent, variant: ButtonVariant): string {\n return variant === \"outline\" ? accentOutlineClasses[accent] : accentFillClasses[accent];\n}\n\nexport interface ButtonProps extends React.ComponentPropsWithoutRef<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n icon?: boolean;\n accent?: Accent;\n asChild?: boolean;\n /** Renders an `<a>` wearing the button's classes — a link that looks like a\n * call to action is still a link. */\n href?: string;\n}\n\n// `forwardRef` so `asChild` triggers (Popover, Tooltip, Dialog) get their anchor under React 18 too.\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n { className, variant = \"primary\", size = \"md\", icon = false, accent, asChild = false, href, ...props },\n ref,\n) {\n const Comp = asChild ? Slot : href !== undefined ? \"a\" : \"button\";\n return (\n <Comp\n data-slot=\"button\"\n href={href}\n ref={ref as React.Ref<never>}\n className={cn(buttonVariants({ variant, size, icon, accent }), className)}\n {...(props as Record<string, unknown>)}\n />\n );\n});\n"],"mappings":"AAyEI;AAzEJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,YAAY;AACrB,SAAS,mBAA8B;AACvC,SAAS,mBAAmB,4BAAyC;AACrE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAsBA,SAAS,eAAe;AAAA,EAC7B,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AACF,IAA2B,CAAC,GAAW;AACrC,SAAO;AAAA,IACL;AAAA,IACA,qBAAqB,OAAO;AAAA,IAC5B,YAAY,IAAI;AAAA,IAChB,OAAO,cAAc;AAAA,IACrB,WAAW,SAAY,SAAY,YAAY,QAAQ,OAAO;AAAA,IAC9D;AAAA,EACF;AACF;AAIA,SAAS,YAAY,QAAgB,SAAgC;AACnE,SAAO,YAAY,YAAY,qBAAqB,MAAM,IAAI,kBAAkB,MAAM;AACxF;AAcO,MAAM,SAAS,MAAM,WAA2C,SAASA,QAC9E,EAAE,WAAW,UAAU,WAAW,OAAO,MAAM,OAAO,OAAO,QAAQ,UAAU,OAAO,MAAM,GAAG,MAAM,GACrG,KACA;AACA,QAAM,OAAO,UAAU,OAAO,SAAS,SAAY,MAAM;AACzD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,MAAM,OAAO,CAAC,GAAG,SAAS;AAAA,MACvE,GAAI;AAAA;AAAA,EACP;AAEJ,CAAC;","names":["Button"]}
|
|
@@ -18,24 +18,9 @@ import {
|
|
|
18
18
|
CALENDAR_WEEKDAY,
|
|
19
19
|
CALENDAR_WEEKDAY_ROW
|
|
20
20
|
} from "../../generated/calendar.js";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"March",
|
|
25
|
-
"April",
|
|
26
|
-
"May",
|
|
27
|
-
"June",
|
|
28
|
-
"July",
|
|
29
|
-
"August",
|
|
30
|
-
"September",
|
|
31
|
-
"October",
|
|
32
|
-
"November",
|
|
33
|
-
"December"
|
|
34
|
-
];
|
|
35
|
-
const WEEKDAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
|
36
|
-
const CHEVRON_LEFT = "m15 18-6-6 6-6";
|
|
37
|
-
const CHEVRON_RIGHT = "m9 18 6-6-6-6";
|
|
38
|
-
function Chevron({ d }) {
|
|
21
|
+
import * as copy from "../../generated/copy.js";
|
|
22
|
+
import { iconShapes } from "../../icons/icon-shapes.js";
|
|
23
|
+
function Chevron({ icon }) {
|
|
39
24
|
return /* @__PURE__ */ jsx(
|
|
40
25
|
"svg",
|
|
41
26
|
{
|
|
@@ -50,7 +35,7 @@ function Chevron({ d }) {
|
|
|
50
35
|
strokeLinecap: "round",
|
|
51
36
|
strokeLinejoin: "round",
|
|
52
37
|
"aria-hidden": true,
|
|
53
|
-
children:
|
|
38
|
+
children: iconShapes(icon)
|
|
54
39
|
}
|
|
55
40
|
);
|
|
56
41
|
}
|
|
@@ -94,8 +79,8 @@ function Calendar({
|
|
|
94
79
|
min,
|
|
95
80
|
max,
|
|
96
81
|
disabled = false,
|
|
97
|
-
previousMonthLabel =
|
|
98
|
-
nextMonthLabel =
|
|
82
|
+
previousMonthLabel = copy.CALENDAR_PREVIOUS_MONTH,
|
|
83
|
+
nextMonthLabel = copy.CALENDAR_NEXT_MONTH,
|
|
99
84
|
locale,
|
|
100
85
|
className
|
|
101
86
|
}) {
|
|
@@ -110,8 +95,8 @@ function Calendar({
|
|
|
110
95
|
};
|
|
111
96
|
const year = view.getFullYear();
|
|
112
97
|
const monthIndex = view.getMonth();
|
|
113
|
-
const caption = locale ? new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(view) : `${MONTHS[monthIndex]} ${year}`;
|
|
114
|
-
const weekdays = locale ? localisedWeekdays(locale) : WEEKDAYS;
|
|
98
|
+
const caption = locale ? new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(view) : `${copy.MONTHS[monthIndex]} ${year}`;
|
|
99
|
+
const weekdays = locale ? localisedWeekdays(locale) : copy.WEEKDAYS;
|
|
115
100
|
const lead = mondayIndex(view);
|
|
116
101
|
const total = new Date(year, monthIndex + 1, 0).getDate();
|
|
117
102
|
const cells = [];
|
|
@@ -142,7 +127,7 @@ function Calendar({
|
|
|
142
127
|
"aria-label": previousMonthLabel,
|
|
143
128
|
disabled,
|
|
144
129
|
onClick: () => go(-1),
|
|
145
|
-
children: /* @__PURE__ */ jsx(Chevron, {
|
|
130
|
+
children: /* @__PURE__ */ jsx(Chevron, { icon: "chevron-left" })
|
|
146
131
|
}
|
|
147
132
|
),
|
|
148
133
|
/* @__PURE__ */ jsx("div", { "data-slot": "calendar-caption", className: CALENDAR_CAPTION, children: caption }),
|
|
@@ -154,7 +139,7 @@ function Calendar({
|
|
|
154
139
|
"aria-label": nextMonthLabel,
|
|
155
140
|
disabled,
|
|
156
141
|
onClick: () => go(1),
|
|
157
|
-
children: /* @__PURE__ */ jsx(Chevron, {
|
|
142
|
+
children: /* @__PURE__ */ jsx(Chevron, { icon: "chevron-right" })
|
|
158
143
|
}
|
|
159
144
|
)
|
|
160
145
|
] }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { buttonVariants } from \"./button\";\nimport {\n CALENDAR_CAPTION,\n CALENDAR_DAY,\n CALENDAR_DAY_CELL,\n CALENDAR_DAY_EMPTY,\n CALENDAR_DAY_SELECTED,\n CALENDAR_DAY_TODAY,\n CALENDAR_GRID,\n CALENDAR_NAV,\n CALENDAR_NAV_BUTTON,\n CALENDAR_ROOT,\n CALENDAR_WEEK,\n CALENDAR_WEEKDAY,\n CALENDAR_WEEKDAY_ROW,\n} from \"../../generated/calendar\";\n\nconst MONTHS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n] as const;\n\n// Week starts Monday.\nconst WEEKDAYS = [\"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\", \"Su\"] as const;\n\nconst CHEVRON_LEFT = \"m15 18-6-6 6-6\";\nconst CHEVRON_RIGHT = \"m9 18 6-6-6-6\";\n\nfunction Chevron({ d }: { d: string }) {\n return (\n <svg\n className=\"size-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d={d} />\n </svg>\n );\n}\n\nfunction startOfMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1);\n}\n\n// Monday = 0 … Sunday = 6 (the built-in `Date.getDay` is Sunday = 0).\nfunction mondayIndex(d: Date): number {\n return (d.getDay() + 6) % 7;\n}\n\nfunction sameDay(a: Date | undefined, b: Date): boolean {\n return (\n !!a &&\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n// Day-granular: `min`/`max` may carry a time, but the grid only knows days.\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\nfunction outOfRange(day: Date, min: Date | undefined, max: Date | undefined): boolean {\n const t = day.getTime();\n return (\n (!!min && t < startOfDay(min).getTime()) ||\n (!!max && t > startOfDay(max).getTime())\n );\n}\n\n// Intl reads the weekday off the reference date; 2024-01-01 is a Monday.\nconst MONDAY = new Date(2024, 0, 1);\n\nfunction formatWeekdays(locale: string, weekday: \"short\" | \"narrow\"): string[] {\n const fmt = new Intl.DateTimeFormat(locale, { weekday });\n return Array.from({ length: 7 }, (_, i) =>\n fmt.format(new Date(MONDAY.getFullYear(), MONDAY.getMonth(), MONDAY.getDate() + i)),\n );\n}\n\n// `short` is what every locale wants, except where CLDR spells it as two words\n// (\"Thứ 2\" in Chrome/CLDR, \"Th 2\" in Node ICU 76 — vi either way) and the fixed\n// 36px column wraps it onto a second line. There the `narrow` form (\"T2\") is\n// used, but only while it still tells the days apart: en/ru/de/fr narrow\n// collapses to repeated single letters, and a locale like that keeps `short`\n// (which `whitespace-nowrap` on the header cell holds on one line anyway).\nfunction localisedWeekdays(locale: string): string[] {\n const short = formatWeekdays(locale, \"short\");\n if (!short.some(label => /\\s/.test(label))) return short;\n const narrow = formatWeekdays(locale, \"narrow\");\n return new Set(narrow).size === narrow.length ? narrow : short;\n}\n\nexport interface CalendarProps {\n /** The currently selected day, if any. */\n selected?: Date;\n /** Fired with the day a user activates. */\n onSelect?: (date: Date) => void;\n /** Controlled displayed month (any day in it is fine). */\n month?: Date;\n /** Uncontrolled initial displayed month. */\n defaultMonth?: Date;\n /** Fired when the displayed month changes via the nav buttons. */\n onMonthChange?: (month: Date) => void;\n /** \"Today\", highlighted in the grid; defaults to the real current date. */\n today?: Date;\n /** Earliest selectable day (inclusive, day granularity); earlier days render disabled. */\n min?: Date;\n /** Latest selectable day (inclusive, day granularity); later days render disabled. */\n max?: Date;\n /** Disables the whole grid and the nav buttons; every day renders `data-disabled`. */\n disabled?: boolean;\n /** `aria-label` of the previous-month button; \"Previous month\" by default. */\n previousMonthLabel?: string;\n /** `aria-label` of the next-month button; \"Next month\" by default. */\n nextMonthLabel?: string;\n /**\n * BCP-47 tag for the month caption and weekday headers via `Intl`\n * (Monday-first). Absent → the English constants, byte-identical to Rust.\n */\n locale?: string;\n className?: string;\n}\n\n/**\n * A dep-light single-month, single-date picker. Mirrors the landing `Calendar`'s\n * class names while replacing `react-day-picker` with a hand-rolled month grid.\n * Uses the built-in `Date` (a language built-in, not a dependency) for the date\n * math; the Rust mirror does the same math by hand.\n *\n * Simplifications versus the source: one month only (no multi-month), a single\n * selected date (no range/multi), no dropdown captions; `locale` only swaps the\n * caption and weekday strings through `Intl` — see the package README.\n */\nexport function Calendar({\n selected,\n onSelect,\n month,\n defaultMonth,\n onMonthChange,\n today = new Date(),\n min,\n max,\n disabled = false,\n previousMonthLabel = \"Previous month\",\n nextMonthLabel = \"Next month\",\n locale,\n className,\n}: CalendarProps) {\n const [internal, setInternal] = React.useState(() =>\n startOfMonth(defaultMonth ?? new Date()),\n );\n const view = month ? startOfMonth(month) : internal;\n\n const go = (delta: number) => {\n const next = new Date(view.getFullYear(), view.getMonth() + delta, 1);\n if (!month) setInternal(next);\n onMonthChange?.(next);\n };\n\n const year = view.getFullYear();\n const monthIndex = view.getMonth();\n const caption = locale\n ? new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" }).format(view)\n : `${MONTHS[monthIndex]} ${year}`;\n const weekdays: readonly string[] = locale ? localisedWeekdays(locale) : WEEKDAYS;\n\n const lead = mondayIndex(view);\n const total = new Date(year, monthIndex + 1, 0).getDate();\n\n // Pad leading blanks then the days, then pad out to a fixed 6 weeks (42\n // cells): 6 rows is the most any month needs with a Monday-first week, and a\n // constant row count keeps the popover height from jumping as the user\n // flips months. Mirrors Rust.\n const cells: (number | null)[] = [];\n for (let i = 0; i < lead; i += 1) cells.push(null);\n for (let day = 1; day <= total; day += 1) cells.push(day);\n while (cells.length < 42) cells.push(null);\n\n const weeks: (number | null)[][] = [];\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));\n\n const navClass = buttonVariants({\n variant: \"ghost\",\n size: \"md\",\n icon: true,\n className: CALENDAR_NAV_BUTTON,\n });\n\n return (\n <div\n data-slot=\"calendar\"\n role=\"application\"\n className={cn(CALENDAR_ROOT, className)}\n >\n <div className={CALENDAR_NAV}>\n <button\n type=\"button\"\n className={navClass}\n aria-label={previousMonthLabel}\n disabled={disabled}\n onClick={() => go(-1)}\n >\n <Chevron d={CHEVRON_LEFT} />\n </button>\n <div data-slot=\"calendar-caption\" className={CALENDAR_CAPTION}>\n {caption}\n </div>\n <button\n type=\"button\"\n className={navClass}\n aria-label={nextMonthLabel}\n disabled={disabled}\n onClick={() => go(1)}\n >\n <Chevron d={CHEVRON_RIGHT} />\n </button>\n </div>\n <table className={CALENDAR_GRID} role=\"grid\">\n <thead>\n <tr className={CALENDAR_WEEKDAY_ROW}>\n {weekdays.map((wd, i) => (\n <th\n key={i}\n scope=\"col\"\n className={CALENDAR_WEEKDAY}\n >\n {wd}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeks.map((week, wi) => (\n <tr key={wi} className={CALENDAR_WEEK}>\n {week.map((cell, ci) => {\n if (cell === null) {\n return (\n <td\n key={ci}\n className={CALENDAR_DAY_EMPTY}\n />\n );\n }\n const date = new Date(year, monthIndex, cell);\n const isSelected = sameDay(selected, date);\n const isToday = sameDay(today, date);\n const isDisabled = disabled || outOfRange(date, min, max);\n return (\n <td\n key={ci}\n role=\"gridcell\"\n aria-selected={isSelected}\n className={CALENDAR_DAY_CELL}\n >\n <button\n type=\"button\"\n data-slot=\"calendar-day\"\n data-selected={isSelected}\n data-today={isToday}\n // Absent rather than \"false\", so the unbounded grid renders as before.\n {...(isDisabled ? { \"data-disabled\": \"true\", disabled: true } : {})}\n onClick={() => {\n if (!isDisabled) onSelect?.(date);\n }}\n className={cn(\n buttonVariants({\n variant: \"ghost\",\n size: \"md\",\n icon: true,\n className: CALENDAR_DAY,\n }),\n isSelected\n ? CALENDAR_DAY_SELECTED\n : isToday\n ? CALENDAR_DAY_TODAY\n : undefined,\n )}\n >\n {cell}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { buttonVariants } from \"./button\";\nimport {\n CALENDAR_CAPTION,\n CALENDAR_DAY,\n CALENDAR_DAY_CELL,\n CALENDAR_DAY_EMPTY,\n CALENDAR_DAY_SELECTED,\n CALENDAR_DAY_TODAY,\n CALENDAR_GRID,\n CALENDAR_NAV,\n CALENDAR_NAV_BUTTON,\n CALENDAR_ROOT,\n CALENDAR_WEEK,\n CALENDAR_WEEKDAY,\n CALENDAR_WEEKDAY_ROW,\n} from \"../../generated/calendar\";\nimport * as copy from \"../../generated/copy\";\nimport type { IconName } from \"../../generated/icons\";\nimport { iconShapes } from \"../../icons/icon-shapes\";\n\n\nfunction Chevron({ icon }: { icon: IconName }) {\n return (\n <svg\n className=\"size-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n {iconShapes(icon)}\n </svg>\n );\n}\n\nfunction startOfMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1);\n}\n\n// Monday = 0 … Sunday = 6 (the built-in `Date.getDay` is Sunday = 0).\nfunction mondayIndex(d: Date): number {\n return (d.getDay() + 6) % 7;\n}\n\nfunction sameDay(a: Date | undefined, b: Date): boolean {\n return (\n !!a &&\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n// Day-granular: `min`/`max` may carry a time, but the grid only knows days.\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\nfunction outOfRange(day: Date, min: Date | undefined, max: Date | undefined): boolean {\n const t = day.getTime();\n return (\n (!!min && t < startOfDay(min).getTime()) ||\n (!!max && t > startOfDay(max).getTime())\n );\n}\n\n// Intl reads the weekday off the reference date; 2024-01-01 is a Monday.\nconst MONDAY = new Date(2024, 0, 1);\n\nfunction formatWeekdays(locale: string, weekday: \"short\" | \"narrow\"): string[] {\n const fmt = new Intl.DateTimeFormat(locale, { weekday });\n return Array.from({ length: 7 }, (_, i) =>\n fmt.format(new Date(MONDAY.getFullYear(), MONDAY.getMonth(), MONDAY.getDate() + i)),\n );\n}\n\n// `short` is what every locale wants, except where CLDR spells it as two words\n// (\"Thứ 2\" in Chrome/CLDR, \"Th 2\" in Node ICU 76 — vi either way) and the fixed\n// 36px column wraps it onto a second line. There the `narrow` form (\"T2\") is\n// used, but only while it still tells the days apart: en/ru/de/fr narrow\n// collapses to repeated single letters, and a locale like that keeps `short`\n// (which `whitespace-nowrap` on the header cell holds on one line anyway).\nfunction localisedWeekdays(locale: string): string[] {\n const short = formatWeekdays(locale, \"short\");\n if (!short.some(label => /\\s/.test(label))) return short;\n const narrow = formatWeekdays(locale, \"narrow\");\n return new Set(narrow).size === narrow.length ? narrow : short;\n}\n\nexport interface CalendarProps {\n /** The currently selected day, if any. */\n selected?: Date;\n /** Fired with the day a user activates. */\n onSelect?: (date: Date) => void;\n /** Controlled displayed month (any day in it is fine). */\n month?: Date;\n /** Uncontrolled initial displayed month. */\n defaultMonth?: Date;\n /** Fired when the displayed month changes via the nav buttons. */\n onMonthChange?: (month: Date) => void;\n /** \"Today\", highlighted in the grid; defaults to the real current date. */\n today?: Date;\n /** Earliest selectable day (inclusive, day granularity); earlier days render disabled. */\n min?: Date;\n /** Latest selectable day (inclusive, day granularity); later days render disabled. */\n max?: Date;\n /** Disables the whole grid and the nav buttons; every day renders `data-disabled`. */\n disabled?: boolean;\n /** `aria-label` of the previous-month button; \"Previous month\" by default. */\n previousMonthLabel?: string;\n /** `aria-label` of the next-month button; \"Next month\" by default. */\n nextMonthLabel?: string;\n /**\n * BCP-47 tag for the month caption and weekday headers via `Intl`\n * (Monday-first). Absent → the English constants, byte-identical to Rust.\n */\n locale?: string;\n className?: string;\n}\n\n/**\n * A dep-light single-month, single-date picker. Mirrors the landing `Calendar`'s\n * class names while replacing `react-day-picker` with a hand-rolled month grid.\n * Uses the built-in `Date` (a language built-in, not a dependency) for the date\n * math; the Rust mirror does the same math by hand.\n *\n * Simplifications versus the source: one month only (no multi-month), a single\n * selected date (no range/multi), no dropdown captions; `locale` only swaps the\n * caption and weekday strings through `Intl` — see the package README.\n */\nexport function Calendar({\n selected,\n onSelect,\n month,\n defaultMonth,\n onMonthChange,\n today = new Date(),\n min,\n max,\n disabled = false,\n previousMonthLabel = copy.CALENDAR_PREVIOUS_MONTH,\n nextMonthLabel = copy.CALENDAR_NEXT_MONTH,\n locale,\n className,\n}: CalendarProps) {\n const [internal, setInternal] = React.useState(() =>\n startOfMonth(defaultMonth ?? new Date()),\n );\n const view = month ? startOfMonth(month) : internal;\n\n const go = (delta: number) => {\n const next = new Date(view.getFullYear(), view.getMonth() + delta, 1);\n if (!month) setInternal(next);\n onMonthChange?.(next);\n };\n\n const year = view.getFullYear();\n const monthIndex = view.getMonth();\n const caption = locale\n ? new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" }).format(view)\n : `${copy.MONTHS[monthIndex]} ${year}`;\n const weekdays: readonly string[] = locale ? localisedWeekdays(locale) : copy.WEEKDAYS;\n\n const lead = mondayIndex(view);\n const total = new Date(year, monthIndex + 1, 0).getDate();\n\n // Pad leading blanks then the days, then pad out to a fixed 6 weeks (42\n // cells): 6 rows is the most any month needs with a Monday-first week, and a\n // constant row count keeps the popover height from jumping as the user\n // flips months. Mirrors Rust.\n const cells: (number | null)[] = [];\n for (let i = 0; i < lead; i += 1) cells.push(null);\n for (let day = 1; day <= total; day += 1) cells.push(day);\n while (cells.length < 42) cells.push(null);\n\n const weeks: (number | null)[][] = [];\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));\n\n const navClass = buttonVariants({\n variant: \"ghost\",\n size: \"md\",\n icon: true,\n className: CALENDAR_NAV_BUTTON,\n });\n\n return (\n <div\n data-slot=\"calendar\"\n role=\"application\"\n className={cn(CALENDAR_ROOT, className)}\n >\n <div className={CALENDAR_NAV}>\n <button\n type=\"button\"\n className={navClass}\n aria-label={previousMonthLabel}\n disabled={disabled}\n onClick={() => go(-1)}\n >\n <Chevron icon=\"chevron-left\" />\n </button>\n <div data-slot=\"calendar-caption\" className={CALENDAR_CAPTION}>\n {caption}\n </div>\n <button\n type=\"button\"\n className={navClass}\n aria-label={nextMonthLabel}\n disabled={disabled}\n onClick={() => go(1)}\n >\n <Chevron icon=\"chevron-right\" />\n </button>\n </div>\n <table className={CALENDAR_GRID} role=\"grid\">\n <thead>\n <tr className={CALENDAR_WEEKDAY_ROW}>\n {weekdays.map((wd, i) => (\n <th\n key={i}\n scope=\"col\"\n className={CALENDAR_WEEKDAY}\n >\n {wd}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeks.map((week, wi) => (\n <tr key={wi} className={CALENDAR_WEEK}>\n {week.map((cell, ci) => {\n if (cell === null) {\n return (\n <td\n key={ci}\n className={CALENDAR_DAY_EMPTY}\n />\n );\n }\n const date = new Date(year, monthIndex, cell);\n const isSelected = sameDay(selected, date);\n const isToday = sameDay(today, date);\n const isDisabled = disabled || outOfRange(date, min, max);\n return (\n <td\n key={ci}\n role=\"gridcell\"\n aria-selected={isSelected}\n className={CALENDAR_DAY_CELL}\n >\n <button\n type=\"button\"\n data-slot=\"calendar-day\"\n data-selected={isSelected}\n data-today={isToday}\n // Absent rather than \"false\", so the unbounded grid renders as before.\n {...(isDisabled ? { \"data-disabled\": \"true\", disabled: true } : {})}\n onClick={() => {\n if (!isDisabled) onSelect?.(date);\n }}\n className={cn(\n buttonVariants({\n variant: \"ghost\",\n size: \"md\",\n icon: true,\n className: CALENDAR_DAY,\n }),\n isSelected\n ? CALENDAR_DAY_SELECTED\n : isToday\n ? CALENDAR_DAY_TODAY\n : undefined,\n )}\n >\n {cell}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":";AA2BI,cA8KE,YA9KF;AAzBJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,YAAY,UAAU;AAEtB,SAAS,kBAAkB;AAG3B,SAAS,QAAQ,EAAE,KAAK,GAAuB;AAC7C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAM;AAAA,MACN,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAW;AAAA,MAEV,qBAAW,IAAI;AAAA;AAAA,EAClB;AAEJ;AAEA,SAAS,aAAa,GAAe;AACnC,SAAO,IAAI,KAAK,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,CAAC;AAClD;AAGA,SAAS,YAAY,GAAiB;AACpC,UAAQ,EAAE,OAAO,IAAI,KAAK;AAC5B;AAEA,SAAS,QAAQ,GAAqB,GAAkB;AACtD,SACE,CAAC,CAAC,KACF,EAAE,YAAY,MAAM,EAAE,YAAY,KAClC,EAAE,SAAS,MAAM,EAAE,SAAS,KAC5B,EAAE,QAAQ,MAAM,EAAE,QAAQ;AAE9B;AAGA,SAAS,WAAW,GAAe;AACjC,SAAO,IAAI,KAAK,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAC5D;AAEA,SAAS,WAAW,KAAW,KAAuB,KAAgC;AACpF,QAAM,IAAI,IAAI,QAAQ;AACtB,SACG,CAAC,CAAC,OAAO,IAAI,WAAW,GAAG,EAAE,QAAQ,KACrC,CAAC,CAAC,OAAO,IAAI,WAAW,GAAG,EAAE,QAAQ;AAE1C;AAGA,MAAM,SAAS,IAAI,KAAK,MAAM,GAAG,CAAC;AAElC,SAAS,eAAe,QAAgB,SAAuC;AAC7E,QAAM,MAAM,IAAI,KAAK,eAAe,QAAQ,EAAE,QAAQ,CAAC;AACvD,SAAO,MAAM;AAAA,IAAK,EAAE,QAAQ,EAAE;AAAA,IAAG,CAAC,GAAG,MACnC,IAAI,OAAO,IAAI,KAAK,OAAO,YAAY,GAAG,OAAO,SAAS,GAAG,OAAO,QAAQ,IAAI,CAAC,CAAC;AAAA,EACpF;AACF;AAQA,SAAS,kBAAkB,QAA0B;AACnD,QAAM,QAAQ,eAAe,QAAQ,OAAO;AAC5C,MAAI,CAAC,MAAM,KAAK,WAAS,KAAK,KAAK,KAAK,CAAC,EAAG,QAAO;AACnD,QAAM,SAAS,eAAe,QAAQ,QAAQ;AAC9C,SAAO,IAAI,IAAI,MAAM,EAAE,SAAS,OAAO,SAAS,SAAS;AAC3D;AA2CO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,oBAAI,KAAK;AAAA,EACjB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,qBAAqB,KAAK;AAAA,EAC1B,iBAAiB,KAAK;AAAA,EACtB;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM;AAAA,IAAS,MAC7C,aAAa,gBAAgB,oBAAI,KAAK,CAAC;AAAA,EACzC;AACA,QAAM,OAAO,QAAQ,aAAa,KAAK,IAAI;AAE3C,QAAM,KAAK,CAAC,UAAkB;AAC5B,UAAM,OAAO,IAAI,KAAK,KAAK,YAAY,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC;AACpE,QAAI,CAAC,MAAO,aAAY,IAAI;AAC5B,oBAAgB,IAAI;AAAA,EACtB;AAEA,QAAM,OAAO,KAAK,YAAY;AAC9B,QAAM,aAAa,KAAK,SAAS;AACjC,QAAM,UAAU,SACZ,IAAI,KAAK,eAAe,QAAQ,EAAE,OAAO,QAAQ,MAAM,UAAU,CAAC,EAAE,OAAO,IAAI,IAC/E,GAAG,KAAK,OAAO,UAAU,CAAC,IAAI,IAAI;AACtC,QAAM,WAA8B,SAAS,kBAAkB,MAAM,IAAI,KAAK;AAE9E,QAAM,OAAO,YAAY,IAAI;AAC7B,QAAM,QAAQ,IAAI,KAAK,MAAM,aAAa,GAAG,CAAC,EAAE,QAAQ;AAMxD,QAAM,QAA2B,CAAC;AAClC,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK,EAAG,OAAM,KAAK,IAAI;AACjD,WAAS,MAAM,GAAG,OAAO,OAAO,OAAO,EAAG,OAAM,KAAK,GAAG;AACxD,SAAO,MAAM,SAAS,GAAI,OAAM,KAAK,IAAI;AAEzC,QAAM,QAA6B,CAAC;AACpC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,EAAG,OAAM,KAAK,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC;AAE1E,QAAM,WAAW,eAAe;AAAA,IAC9B,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAW,GAAG,eAAe,SAAS;AAAA,MAEtC;AAAA,6BAAC,SAAI,WAAW,cACd;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW;AAAA,cACX,cAAY;AAAA,cACZ;AAAA,cACA,SAAS,MAAM,GAAG,EAAE;AAAA,cAEpB,8BAAC,WAAQ,MAAK,gBAAe;AAAA;AAAA,UAC/B;AAAA,UACA,oBAAC,SAAI,aAAU,oBAAmB,WAAW,kBAC1C,mBACH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAW;AAAA,cACX,cAAY;AAAA,cACZ;AAAA,cACA,SAAS,MAAM,GAAG,CAAC;AAAA,cAEnB,8BAAC,WAAQ,MAAK,iBAAgB;AAAA;AAAA,UAChC;AAAA,WACF;AAAA,QACA,qBAAC,WAAM,WAAW,eAAe,MAAK,QACpC;AAAA,8BAAC,WACC,8BAAC,QAAG,WAAW,sBACZ,mBAAS,IAAI,CAAC,IAAI,MACjB;AAAA,YAAC;AAAA;AAAA,cAEC,OAAM;AAAA,cACN,WAAW;AAAA,cAEV;AAAA;AAAA,YAJI;AAAA,UAKP,CACD,GACH,GACF;AAAA,UACA,oBAAC,WACE,gBAAM,IAAI,CAAC,MAAM,OAChB,oBAAC,QAAY,WAAW,eACrB,eAAK,IAAI,CAAC,MAAM,OAAO;AACtB,gBAAI,SAAS,MAAM;AACjB,qBACE;AAAA,gBAAC;AAAA;AAAA,kBAEC,WAAW;AAAA;AAAA,gBADN;AAAA,cAEP;AAAA,YAEJ;AACA,kBAAM,OAAO,IAAI,KAAK,MAAM,YAAY,IAAI;AAC5C,kBAAM,aAAa,QAAQ,UAAU,IAAI;AACzC,kBAAM,UAAU,QAAQ,OAAO,IAAI;AACnC,kBAAM,aAAa,YAAY,WAAW,MAAM,KAAK,GAAG;AACxD,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,iBAAe;AAAA,gBACf,WAAW;AAAA,gBAEX;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,aAAU;AAAA,oBACV,iBAAe;AAAA,oBACf,cAAY;AAAA,oBAEX,GAAI,aAAa,EAAE,iBAAiB,QAAQ,UAAU,KAAK,IAAI,CAAC;AAAA,oBACjE,SAAS,MAAM;AACb,0BAAI,CAAC,WAAY,YAAW,IAAI;AAAA,oBAClC;AAAA,oBACA,WAAW;AAAA,sBACT,eAAe;AAAA,wBACb,SAAS;AAAA,wBACT,MAAM;AAAA,wBACN,MAAM;AAAA,wBACN,WAAW;AAAA,sBACb,CAAC;AAAA,sBACD,aACI,wBACA,UACE,qBACA;AAAA,oBACR;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA;AAAA,cA9BK;AAAA,YA+BP;AAAA,UAEJ,CAAC,KAjDM,EAkDT,CACD,GACH;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -6,6 +6,7 @@ import { CHECKBOX_BASE, CHECKBOX_INDICATOR } from "../../generated/checkbox.js";
|
|
|
6
6
|
import { useControllableState } from "../../primitives/use-controllable-state.js";
|
|
7
7
|
import { markLabelable } from "../../primitives/labelable.js";
|
|
8
8
|
import { useFieldControlId } from "./field-context.js";
|
|
9
|
+
import { iconShapes } from "../../icons/icon-shapes.js";
|
|
9
10
|
function Checkbox({
|
|
10
11
|
className,
|
|
11
12
|
checked,
|
|
@@ -55,7 +56,7 @@ function Checkbox({
|
|
|
55
56
|
strokeLinejoin: "round",
|
|
56
57
|
className: "size-3.5",
|
|
57
58
|
"aria-hidden": "true",
|
|
58
|
-
children:
|
|
59
|
+
children: iconShapes("check")
|
|
59
60
|
}
|
|
60
61
|
)
|
|
61
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/atomic/checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { CHECKBOX_BASE, CHECKBOX_INDICATOR } from \"../../generated/checkbox\";\nimport { useControllableState } from \"../../primitives/use-controllable-state\";\nimport { markLabelable } from \"../../primitives/labelable\";\nimport { useFieldControlId } from \"./field-context\";\n\nexport interface CheckboxProps\n extends Omit<React.ComponentProps<\"button\">, \"onChange\"> {\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nexport function Checkbox({\n className,\n checked,\n defaultChecked = false,\n onCheckedChange,\n onClick,\n disabled,\n id,\n ...props\n}: CheckboxProps) {\n const [on, setOn] = useControllableState<boolean>({\n ...(checked !== undefined ? { value: checked } : {}),\n defaultValue: defaultChecked,\n ...(onCheckedChange ? { onChange: onCheckedChange } : {}),\n });\n const state = on ? \"checked\" : \"unchecked\";\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n data-slot=\"checkbox\"\n data-state={state}\n aria-checked={on}\n disabled={disabled}\n id={useFieldControlId(id)}\n className={cn(CHECKBOX_BASE, className)}\n onClick={(e) => {\n onClick?.(e);\n setOn(!on);\n }}\n {...props}\n >\n {on && (\n <span\n data-slot=\"checkbox-indicator\"\n className={CHECKBOX_INDICATOR}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"size-3.5\"\n aria-hidden=\"true\"\n >\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/atomic/checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { CHECKBOX_BASE, CHECKBOX_INDICATOR } from \"../../generated/checkbox\";\nimport { useControllableState } from \"../../primitives/use-controllable-state\";\nimport { markLabelable } from \"../../primitives/labelable\";\nimport { useFieldControlId } from \"./field-context\";\nimport { iconShapes } from \"../../icons/icon-shapes\";\n\nexport interface CheckboxProps\n extends Omit<React.ComponentProps<\"button\">, \"onChange\"> {\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nexport function Checkbox({\n className,\n checked,\n defaultChecked = false,\n onCheckedChange,\n onClick,\n disabled,\n id,\n ...props\n}: CheckboxProps) {\n const [on, setOn] = useControllableState<boolean>({\n ...(checked !== undefined ? { value: checked } : {}),\n defaultValue: defaultChecked,\n ...(onCheckedChange ? { onChange: onCheckedChange } : {}),\n });\n const state = on ? \"checked\" : \"unchecked\";\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n data-slot=\"checkbox\"\n data-state={state}\n aria-checked={on}\n disabled={disabled}\n id={useFieldControlId(id)}\n className={cn(CHECKBOX_BASE, className)}\n onClick={(e) => {\n onClick?.(e);\n setOn(!on);\n }}\n {...props}\n >\n {on && (\n <span\n data-slot=\"checkbox-indicator\"\n className={CHECKBOX_INDICATOR}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"size-3.5\"\n aria-hidden=\"true\"\n >\n {iconShapes(\"check\")}\n </svg>\n </span>\n )}\n </button>\n );\n}\n\nmarkLabelable(Checkbox);\n"],"mappings":";AAsDU;AApDV,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,eAAe,0BAA0B;AAClD,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AASpB,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkB;AAChB,QAAM,CAAC,IAAI,KAAK,IAAI,qBAA8B;AAAA,IAChD,GAAI,YAAY,SAAY,EAAE,OAAO,QAAQ,IAAI,CAAC;AAAA,IAClD,cAAc;AAAA,IACd,GAAI,kBAAkB,EAAE,UAAU,gBAAgB,IAAI,CAAC;AAAA,EACzD,CAAC;AACD,QAAM,QAAQ,KAAK,YAAY;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,gBAAc;AAAA,MACd;AAAA,MACA,IAAI,kBAAkB,EAAE;AAAA,MACxB,WAAW,GAAG,eAAe,SAAS;AAAA,MACtC,SAAS,CAAC,MAAM;AACd,kBAAU,CAAC;AACX,cAAM,CAAC,EAAE;AAAA,MACX;AAAA,MACC,GAAG;AAAA,MAEH,gBACC;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,WAAW;AAAA,UAEX;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,QAAO;AAAA,cACP,aAAY;AAAA,cACZ,eAAc;AAAA,cACd,gBAAe;AAAA,cACf,WAAU;AAAA,cACV,eAAY;AAAA,cAEX,qBAAW,OAAO;AAAA;AAAA,UACrB;AAAA;AAAA,MACF;AAAA;AAAA,EAEJ;AAEJ;AAEA,cAAc,QAAQ;","names":[]}
|
|
@@ -7,20 +7,8 @@ import { DismissableLayerScope, useDismissableLayer, useModalScrimStyle } from "
|
|
|
7
7
|
import { useFocusScope } from "../../primitives/focus-scope.js";
|
|
8
8
|
import { mergeRefs } from "../../primitives/merge-refs.js";
|
|
9
9
|
import { Portal } from "../../primitives/portal.js";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
COMMAND_DIALOG_CONTENT,
|
|
13
|
-
COMMAND_DIALOG_OVERLAY,
|
|
14
|
-
COMMAND_EMPTY,
|
|
15
|
-
COMMAND_GROUP,
|
|
16
|
-
COMMAND_INPUT,
|
|
17
|
-
COMMAND_INPUT_WRAPPER,
|
|
18
|
-
COMMAND_ITEM,
|
|
19
|
-
COMMAND_LIST,
|
|
20
|
-
COMMAND_ROOT,
|
|
21
|
-
COMMAND_SEPARATOR,
|
|
22
|
-
COMMAND_SHORTCUT
|
|
23
|
-
} from "../../generated/command.js";
|
|
10
|
+
import { COMMAND_DIALOG_COMMAND, COMMAND_DIALOG_CONTENT, COMMAND_DIALOG_OVERLAY, COMMAND_EMPTY, COMMAND_GROUP, COMMAND_INPUT, COMMAND_INPUT_ICON, COMMAND_INPUT_WRAPPER, COMMAND_ITEM, COMMAND_LIST, COMMAND_ROOT, COMMAND_SEPARATOR, COMMAND_SHORTCUT } from "../../generated/command.js";
|
|
11
|
+
import { iconShapes } from "../../icons/icon-shapes.js";
|
|
24
12
|
const CommandContext = React.createContext(null);
|
|
25
13
|
function useCommand() {
|
|
26
14
|
const ctx = React.useContext(CommandContext);
|
|
@@ -268,7 +256,7 @@ function CommandInput({
|
|
|
268
256
|
}) {
|
|
269
257
|
const { search, setSearch, listId, activeId } = useCommand();
|
|
270
258
|
return /* @__PURE__ */ jsxs("div", { className: COMMAND_INPUT_WRAPPER, "data-slot": "command-input-wrapper", children: [
|
|
271
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ jsx(
|
|
272
260
|
"svg",
|
|
273
261
|
{
|
|
274
262
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -280,12 +268,9 @@ function CommandInput({
|
|
|
280
268
|
strokeWidth: "2",
|
|
281
269
|
strokeLinecap: "round",
|
|
282
270
|
strokeLinejoin: "round",
|
|
283
|
-
className:
|
|
271
|
+
className: COMMAND_INPUT_ICON,
|
|
284
272
|
"aria-hidden": "true",
|
|
285
|
-
children:
|
|
286
|
-
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
|
|
287
|
-
/* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })
|
|
288
|
-
]
|
|
273
|
+
children: iconShapes("search")
|
|
289
274
|
}
|
|
290
275
|
),
|
|
291
276
|
/* @__PURE__ */ jsx(
|