@evinvest/uikit 0.26.0 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +148 -17
  2. package/dist/components/account-menu.js +70 -0
  3. package/dist/components/account-menu.js.map +1 -0
  4. package/dist/components/alert-dialog.js +4 -3
  5. package/dist/components/alert-dialog.js.map +1 -1
  6. package/dist/components/app-shell.js +11 -0
  7. package/dist/components/app-shell.js.map +1 -1
  8. package/dist/components/auth-wall.js +42 -0
  9. package/dist/components/auth-wall.js.map +1 -0
  10. package/dist/components/checkbox.js +2 -0
  11. package/dist/components/checkbox.js.map +1 -1
  12. package/dist/components/command.js +180 -25
  13. package/dist/components/command.js.map +1 -1
  14. package/dist/components/context-menu.js +8 -8
  15. package/dist/components/context-menu.js.map +1 -1
  16. package/dist/components/dialog.js +4 -3
  17. package/dist/components/dialog.js.map +1 -1
  18. package/dist/components/drawer.js +9 -5
  19. package/dist/components/drawer.js.map +1 -1
  20. package/dist/components/dropdown-menu.js +13 -10
  21. package/dist/components/dropdown-menu.js.map +1 -1
  22. package/dist/components/field.js +3 -8
  23. package/dist/components/field.js.map +1 -1
  24. package/dist/components/info-tip.js +2 -2
  25. package/dist/components/info-tip.js.map +1 -1
  26. package/dist/components/input.js +2 -0
  27. package/dist/components/input.js.map +1 -1
  28. package/dist/components/menubar.js +18 -5
  29. package/dist/components/menubar.js.map +1 -1
  30. package/dist/components/native-select.js +2 -0
  31. package/dist/components/native-select.js.map +1 -1
  32. package/dist/components/navigation-menu.js +2 -2
  33. package/dist/components/navigation-menu.js.map +1 -1
  34. package/dist/components/popover.js +2 -2
  35. package/dist/components/popover.js.map +1 -1
  36. package/dist/components/select.js +4 -2
  37. package/dist/components/select.js.map +1 -1
  38. package/dist/components/sheet.js +4 -3
  39. package/dist/components/sheet.js.map +1 -1
  40. package/dist/components/sonner.js +1 -0
  41. package/dist/components/sonner.js.map +1 -1
  42. package/dist/components/switch.js +2 -0
  43. package/dist/components/switch.js.map +1 -1
  44. package/dist/components/table.js +24 -7
  45. package/dist/components/table.js.map +1 -1
  46. package/dist/components/textarea.js +2 -0
  47. package/dist/components/textarea.js.map +1 -1
  48. package/dist/components/toggle-group.js +1 -1
  49. package/dist/components/toggle-group.js.map +1 -1
  50. package/dist/components/top-bar.js +21 -0
  51. package/dist/components/top-bar.js.map +1 -0
  52. package/dist/generated/command.js +2 -2
  53. package/dist/generated/command.js.map +1 -1
  54. package/dist/generated/context-menu.js +1 -1
  55. package/dist/generated/context-menu.js.map +1 -1
  56. package/dist/generated/dropdown-menu.js +1 -1
  57. package/dist/generated/dropdown-menu.js.map +1 -1
  58. package/dist/generated/menubar.js +1 -1
  59. package/dist/generated/menubar.js.map +1 -1
  60. package/dist/generated/table.js +20 -3
  61. package/dist/generated/table.js.map +1 -1
  62. package/dist/generated/toggle.js +2 -2
  63. package/dist/generated/toggle.js.map +1 -1
  64. package/dist/index.d.ts +179 -76
  65. package/dist/index.js +6 -4
  66. package/dist/primitives/dismissable-layer.js +80 -15
  67. package/dist/primitives/dismissable-layer.js.map +1 -1
  68. package/dist/primitives/labelable.js +24 -0
  69. package/dist/primitives/labelable.js.map +1 -0
  70. package/dist/primitives/use-roving-focus.js +13 -7
  71. package/dist/primitives/use-roving-focus.js.map +1 -1
  72. package/package.json +1 -1
  73. package/styles/ev.css +4 -2
  74. package/styles/theme.css +7 -0
  75. package/styles/tokens.css +15 -3
  76. package/dist/components/chart.js +0 -151
  77. package/dist/components/chart.js.map +0 -1
  78. package/dist/components/resizable.js +0 -193
  79. package/dist/components/resizable.js.map +0 -1
  80. package/dist/generated/chart.js +0 -9
  81. package/dist/generated/chart.js.map +0 -1
  82. package/dist/generated/resizable.js +0 -11
  83. package/dist/generated/resizable.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/sonner.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n TOAST_BASE,\n TOAST_CLOSE,\n TOAST_CONTENT,\n TOAST_TITLE,\n TOASTER_BASE,\n positionClasses,\n toastVariantClasses,\n type ToastPosition,\n type ToastVariant,\n} from \"../generated/sonner\";\n\nexport type { ToastPosition, ToastVariant };\n\n/**\n * Lifecycle phase of a toast. It is added `\"open\"` (plays the enter keyframe);\n * {@link ToastFn.dismiss} flips it to `\"closing\"` (slides it out) and the live\n * node is dropped once the exit `transitionend` fires. Mirrors Rust's\n * `ToastState` enum and the `data-state` the shared `tokens.css` keys on.\n */\nexport type ToastState = \"open\" | \"closing\";\n\nexport interface ToastOptions {\n description?: React.ReactNode;\n /**\n * Auto-dismiss delay in ms (default 4000). Pass `Infinity` for a **persistent**\n * toast that never times out — it stays until the close button, a swipe, or\n * `toast.dismiss(id)` removes it. Hovering the stack also pauses the countdown.\n */\n duration?: number;\n variant?: ToastVariant;\n}\n\nexport interface Toast {\n id: number;\n message: React.ReactNode;\n description?: React.ReactNode;\n duration: number;\n variant: ToastVariant;\n state: ToastState;\n}\n\nconst DEFAULT_DURATION = 4000;\n\n// Swipe-to-dismiss tuning (pointer physics, TS-only — Rust stays render-only).\n// Values from Sonner: a horizontal drag past 45px, or a flick faster than\n// 0.11px/ms, flings the toast off; anything short snaps back.\nconst SWIPE_THRESHOLD = 45;\nconst SWIPE_VELOCITY = 0.11;\nconst SWIPE_FLING_MS = 200;\n\n/**\n * Module-level toast store: a plain observable holding the live toast array.\n * `toast(...)` mutates it and notifies subscribers; the {@link Toaster}\n * component is the sole subscriber. This is the JS-native global the Rust\n * mirror cannot have — Dioxus has no clean cross-component mutable singleton,\n * so it uses a `ToasterProvider` + `use_toaster()` hook instead.\n */\nconst store = (() => {\n let toasts: Toast[] = [];\n let id = 0;\n const listeners = new Set<(toasts: Toast[]) => void>();\n\n const emit = () => {\n for (const listener of listeners) listener(toasts);\n };\n\n const add = (message: React.ReactNode, opts: ToastOptions = {}): number => {\n const next: Toast = {\n id: ++id,\n message,\n description: opts.description,\n duration: opts.duration ?? DEFAULT_DURATION,\n variant: opts.variant ?? \"neutral\",\n state: \"open\",\n };\n toasts = [...toasts, next];\n emit();\n return next.id;\n };\n\n // Begins the exit animation: flip the toast to `closing` (`data-state=closed`)\n // and keep it mounted so the exit keyframe can play. The live node is dropped\n // by `remove`, wired to the exit `transitionend` — no timer matched to the CSS.\n // A toast dismissed before it has ever painted mounts closed and so never\n // transitions; `ToastItem` drops that one on mount instead.\n const dismiss = (toastId: number) => {\n toasts = toasts.map((t) =>\n t.id === toastId ? { ...t, state: \"closing\" as const } : t,\n );\n emit();\n };\n\n // Drops a toast outright. Wired to the exit `transitionend`; the guard that it\n // is actually `closing` (a restack transition fires too) lives at the call\n // site in {@link ToastItem}, alongside the mount-closed path.\n const remove = (toastId: number) => {\n toasts = toasts.filter((t) => t.id !== toastId);\n emit();\n };\n\n const subscribe = (listener: (toasts: Toast[]) => void): (() => void) => {\n listeners.add(listener);\n listener(toasts);\n return () => {\n listeners.delete(listener);\n };\n };\n\n return { add, dismiss, remove, subscribe };\n})();\n\nexport interface ToastFn {\n (message: React.ReactNode, opts?: ToastOptions): number;\n positive: (message: React.ReactNode, opts?: ToastOptions) => number;\n error: (message: React.ReactNode, opts?: ToastOptions) => number;\n info: (message: React.ReactNode, opts?: ToastOptions) => number;\n warn: (message: React.ReactNode, opts?: ToastOptions) => number;\n dismiss: (id: number) => void;\n}\n\n/**\n * Global toast handle. `toast(msg)` enqueues a neutral toast; the `.positive`,\n * `.error`, `.info` and `.warn` helpers pin the variant; `toast.dismiss(id)`\n * removes one early. Mirrors Rust's `use_toaster()` handle methods.\n */\nexport const toast: ToastFn = Object.assign(\n (message: React.ReactNode, opts?: ToastOptions) => store.add(message, opts),\n {\n positive: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"positive\" }),\n error: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"error\" }),\n info: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"info\" }),\n warn: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"warn\" }),\n dismiss: (id: number) => store.dismiss(id),\n },\n);\n\n// Sonner-style stacking: only the front VISIBLE_TOASTS show collapsed; GAP is\n// the px between them once expanded.\nconst VISIBLE_TOASTS = 3;\nconst GAP = 14;\n\ninterface ToastItemProps {\n toast: Toast;\n index: number; // 0 = front / newest\n total: number;\n offset: number; // px from the pinned edge to this toast's expanded slot\n paused: boolean; // the stack is hovered/focused — hold the auto-dismiss\n reportHeight: (id: number, height: number) => void;\n removeHeight: (id: number) => void;\n}\n\nfunction ToastItem({\n toast: t,\n index,\n total,\n offset,\n paused,\n reportHeight,\n removeHeight,\n}: ToastItemProps) {\n const ref = React.useRef<HTMLLIElement>(null);\n const [height, setHeight] = React.useState(0);\n // remaining auto-dismiss budget (banked across hover pauses), the last start\n // timestamp, and the swipe-fling fallback timer.\n const remainingRef = React.useRef(t.duration);\n const startedRef = React.useRef(0);\n const flingRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const dragRef = React.useRef<{ x: number; time: number; dx: number } | null>(\n null,\n );\n\n // measure the *natural* height for the stack maths; re-measure on content\n // change. Back toasts are clamped to --front-height by the CSS, so unset the\n // height for the read (Sonner does the same) then hand it back to the CSS.\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.style.height = \"auto\";\n const h = el.getBoundingClientRect().height;\n el.style.height = \"\";\n if (h) {\n setHeight(h);\n reportHeight(t.id, h);\n }\n }, [t.id, t.message, t.description, reportHeight]);\n\n React.useEffect(() => () => removeHeight(t.id), [t.id, removeHeight]);\n\n // Dismissed before its first paint (added and dismissed in one batch), so it\n // mounts already `closing`: its computed style never changes, no transition\n // runs, and `onTransitionEnd` below would never fire — stranding it in the\n // store forever. Nothing was painted, so there is nothing to animate: drop it\n // once mounted. Mirrors the Dioxus port's mount effect.\n const mountedClosing = React.useRef(t.state === \"closing\");\n React.useEffect(() => {\n if (mountedClosing.current) store.remove(t.id);\n }, [t.id]);\n\n // Auto-dismiss, pausable on hover. While `paused` (or closing, or a persistent\n // `duration: Infinity`) no timer runs; the cleanup banks the elapsed time so a\n // resume continues from the remaining budget rather than restarting.\n React.useEffect(() => {\n if (t.duration === Infinity || t.state === \"closing\" || paused) return;\n startedRef.current = Date.now();\n const id = setTimeout(() => store.dismiss(t.id), remainingRef.current);\n return () => {\n clearTimeout(id);\n remainingRef.current = Math.max(\n 0,\n remainingRef.current - (Date.now() - startedRef.current),\n );\n };\n }, [paused, t.id, t.duration, t.state]);\n\n // cancel the swipe-fling fallback if the toast unmounts first\n React.useEffect(\n () => () => {\n if (flingRef.current) clearTimeout(flingRef.current);\n },\n [],\n );\n\n // exit rides the transition: a closing toast slides back off and is dropped on\n // the transform's `transitionend` (guarded so stack repositioning never fires\n // it). No host timer — keeps parity with the Dioxus port.\n const onTransitionEnd = (e: React.TransitionEvent<HTMLLIElement>) => {\n if (t.state === \"closing\" && e.propertyName === \"transform\") {\n store.remove(t.id);\n }\n };\n\n // ── swipe-to-dismiss (horizontal pointer drag) ──────────────────────────\n // Tracked through the `--swipe-x` var so it *composes* with the stack\n // transform (`var(--y) translateX(var(--swipe-x))`) instead of overriding it.\n const onPointerDown = (e: React.PointerEvent<HTMLLIElement>) => {\n const el = ref.current;\n if (!el || e.button > 0 || t.state === \"closing\") return;\n if ((e.target as HTMLElement).closest('[data-slot=\"toast-close\"]')) return;\n // auto-dismiss is already paused (a swipe means the pointer is over the stack)\n dragRef.current = { x: e.clientX, time: e.timeStamp, dx: 0 };\n el.setAttribute(\"data-swiping\", \"true\"); // CSS drops the transition for 1:1 tracking\n try {\n el.setPointerCapture?.(e.pointerId);\n } catch {\n // jsdom / unsupported — capture is a nice-to-have, the drag works without it\n }\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLLIElement>) => {\n const drag = dragRef.current;\n const el = ref.current;\n if (!drag || !el) return;\n const dx = e.clientX - drag.x;\n drag.dx = dx;\n const dist = el.offsetWidth || 256;\n el.style.setProperty(\"--swipe-x\", `${dx}px`);\n el.style.opacity = `${Math.max(0, 1 - Math.abs(dx) / dist)}`;\n };\n\n const onPointerEnd = (e: React.PointerEvent<HTMLLIElement>) => {\n const drag = dragRef.current;\n const el = ref.current;\n if (!drag || !el) return;\n dragRef.current = null;\n el.removeAttribute(\"data-swiping\"); // CSS restores the transition\n const dt = e.timeStamp - drag.time;\n const velocity = dt > 0 ? Math.abs(drag.dx) / dt : 0;\n if (\n drag.dx !== 0 &&\n (Math.abs(drag.dx) >= SWIPE_THRESHOLD || velocity > SWIPE_VELOCITY)\n ) {\n el.style.setProperty(\"--swipe-x\", `${drag.dx > 0 ? 150 : -150}%`);\n el.style.opacity = \"0\";\n const remove = () => store.remove(t.id);\n el.addEventListener(\"transitionend\", remove, { once: true });\n flingRef.current = setTimeout(remove, SWIPE_FLING_MS + 50); // fallback if transitionend is missed\n } else {\n // snap back: clear the swipe offset (the transition carries it home), then\n // hand styling back to the CSS. Auto-dismiss stays paused while hovered and\n // re-arms from the remaining budget once the pointer leaves.\n el.style.setProperty(\"--swipe-x\", \"0px\");\n el.style.opacity = \"1\";\n el.addEventListener(\n \"transitionend\",\n () => {\n el.style.removeProperty(\"--swipe-x\");\n el.style.opacity = \"\";\n },\n { once: true },\n );\n }\n };\n\n return (\n <li\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"toast\"\n data-variant={t.variant}\n data-state={t.state === \"closing\" ? \"closed\" : \"open\"}\n data-front={index === 0}\n data-visible={index < VISIBLE_TOASTS}\n onTransitionEnd={onTransitionEnd}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerEnd}\n onPointerCancel={onPointerEnd}\n style={\n {\n \"--index\": index,\n \"--z-index\": total - index,\n \"--offset\": `${offset}px`,\n \"--initial-height\": `${height}px`,\n } as React.CSSProperties\n }\n className={cn(\n TOAST_BASE,\n \"touch-pan-y select-none\",\n toastVariantClasses[t.variant],\n )}\n >\n <div className={TOAST_CONTENT}>\n <div className={TOAST_TITLE}>{t.message}</div>\n {t.description ? (\n <div className=\"text-ink-soft text-sm\">{t.description}</div>\n ) : null}\n </div>\n <button\n type=\"button\"\n aria-label=\"Close\"\n data-slot=\"toast-close\"\n onClick={() => store.dismiss(t.id)}\n className={TOAST_CLOSE}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n </li>\n );\n}\n\nexport interface ToasterProps extends React.ComponentProps<\"ol\"> {\n position?: ToastPosition;\n}\n\n/**\n * Renders the live toast stack from the module store. Fixed-positioned per\n * `position` (default `bottom-right`).\n *\n * Stacking mirrors Sonner: toasts pile up collapsed (the front three peeking,\n * each scaled + lifted by depth and clamped to the front toast's height) and\n * spread into a list on hover / keyboard focus — driven by the measured\n * `--front-height`/`--offset` vars and the `data-stack` CSS in `tokens.css`.\n * Each toast auto-dismisses after its `duration` (default 4000ms) via the same\n * animated `dismiss` as the close button (`data-state=\"closed\"` → slide out →\n * unmount on `transitionend`), and is swipe-to-dismiss (horizontal drag, TS-only\n * pointer physics). Single dark palette — no theme switching.\n */\nexport function Toaster({\n position = \"bottom-right\",\n className,\n ...props\n}: ToasterProps) {\n const [toasts, setToasts] = React.useState<Toast[]>([]);\n const [heights, setHeights] = React.useState<Map<number, number>>(new Map());\n const [paused, setPaused] = React.useState(false);\n\n React.useEffect(() => store.subscribe(setToasts), []);\n\n // Pause auto-dismiss while the stack is hovered or keyboard-focused (Sonner\n // does the same). pointerover/out + focusin/out bubble from the toasts, so they\n // fire even though the <ol> itself is pointer-events:none; the contains() guard\n // keeps it paused while moving *within* the stack.\n const onEnter = () => setPaused(true);\n const onLeave = (e: React.PointerEvent | React.FocusEvent) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {\n setPaused(false);\n }\n };\n\n const reportHeight = React.useCallback((id: number, h: number) => {\n setHeights((prev) => {\n if (prev.get(id) === h) return prev;\n const next = new Map(prev);\n next.set(id, h);\n return next;\n });\n }, []);\n const removeHeight = React.useCallback((id: number) => {\n setHeights((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const yPosition = position.startsWith(\"top\") ? \"top\" : \"bottom\";\n const ordered = [...toasts].reverse(); // newest first → front of the stack\n // front toast's height; until it's measured fall back to the tallest known one\n // so the back toasts don't clamp to 0 for a frame when a new toast arrives\n const known = [...heights.values()];\n const frontHeight = ordered[0]\n ? (heights.get(ordered[0].id) ?? (known.length ? Math.max(...known) : 0))\n : 0;\n\n // cumulative offset: heights of the toasts in front of this one + index * GAP\n let sum = 0;\n const offsets = ordered.map((t, i) => {\n const o = sum + i * GAP;\n sum += heights.get(t.id) ?? 0;\n return o;\n });\n\n return (\n <ol\n data-slot=\"toaster\"\n data-position={position}\n data-y-position={yPosition}\n data-stack=\"\"\n style={\n {\n \"--front-height\": `${frontHeight}px`,\n \"--gap\": `${GAP}px`,\n } as React.CSSProperties\n }\n className={cn(\n TOASTER_BASE,\n positionClasses[position],\n className,\n )}\n {...props}\n onPointerOver={onEnter}\n onPointerOut={onLeave}\n onFocus={onEnter}\n onBlur={onLeave}\n >\n {ordered.map((t, i) => (\n <ToastItem\n key={t.id}\n toast={t}\n index={i}\n total={ordered.length}\n offset={offsets[i]!}\n paused={paused}\n reportHeight={reportHeight}\n removeHeight={removeHeight}\n />\n ))}\n </ol>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/sonner.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n TOAST_BASE,\n TOAST_CLOSE,\n TOAST_CONTENT,\n TOAST_TITLE,\n TOASTER_BASE,\n positionClasses,\n toastVariantClasses,\n type ToastPosition,\n type ToastVariant,\n} from \"../generated/sonner\";\n\nexport type { ToastPosition, ToastVariant };\n\n/**\n * Lifecycle phase of a toast. It is added `\"open\"` (plays the enter keyframe);\n * {@link ToastFn.dismiss} flips it to `\"closing\"` (slides it out) and the live\n * node is dropped once the exit `transitionend` fires. Mirrors Rust's\n * `ToastState` enum and the `data-state` the shared `tokens.css` keys on.\n */\nexport type ToastState = \"open\" | \"closing\";\n\nexport interface ToastOptions {\n description?: React.ReactNode;\n /**\n * Auto-dismiss delay in ms (default 4000). Pass `Infinity` for a **persistent**\n * toast that never times out — it stays until the close button, a swipe, or\n * `toast.dismiss(id)` removes it. Hovering the stack also pauses the countdown.\n */\n duration?: number;\n variant?: ToastVariant;\n}\n\nexport interface Toast {\n id: number;\n message: React.ReactNode;\n description?: React.ReactNode;\n duration: number;\n variant: ToastVariant;\n state: ToastState;\n}\n\nconst DEFAULT_DURATION = 4000;\n\n// Swipe-to-dismiss tuning (pointer physics, TS-only — Rust stays render-only).\n// Values from Sonner: a horizontal drag past 45px, or a flick faster than\n// 0.11px/ms, flings the toast off; anything short snaps back.\nconst SWIPE_THRESHOLD = 45;\nconst SWIPE_VELOCITY = 0.11;\nconst SWIPE_FLING_MS = 200;\n\n/**\n * Module-level toast store: a plain observable holding the live toast array.\n * `toast(...)` mutates it and notifies subscribers; the {@link Toaster}\n * component is the sole subscriber. This is the JS-native global the Rust\n * mirror cannot have — Dioxus has no clean cross-component mutable singleton,\n * so it uses a `ToasterProvider` + `use_toaster()` hook instead.\n */\nconst store = (() => {\n let toasts: Toast[] = [];\n let id = 0;\n const listeners = new Set<(toasts: Toast[]) => void>();\n\n const emit = () => {\n for (const listener of listeners) listener(toasts);\n };\n\n const add = (message: React.ReactNode, opts: ToastOptions = {}): number => {\n const next: Toast = {\n id: ++id,\n message,\n description: opts.description,\n duration: opts.duration ?? DEFAULT_DURATION,\n variant: opts.variant ?? \"neutral\",\n state: \"open\",\n };\n toasts = [...toasts, next];\n emit();\n return next.id;\n };\n\n // Begins the exit animation: flip the toast to `closing` (`data-state=closed`)\n // and keep it mounted so the exit keyframe can play. The live node is dropped\n // by `remove`, wired to the exit `transitionend` — no timer matched to the CSS.\n // A toast dismissed before it has ever painted mounts closed and so never\n // transitions; `ToastItem` drops that one on mount instead.\n const dismiss = (toastId: number) => {\n toasts = toasts.map((t) =>\n t.id === toastId ? { ...t, state: \"closing\" as const } : t,\n );\n emit();\n };\n\n // Drops a toast outright. Wired to the exit `transitionend`; the guard that it\n // is actually `closing` (a restack transition fires too) lives at the call\n // site in {@link ToastItem}, alongside the mount-closed path.\n const remove = (toastId: number) => {\n toasts = toasts.filter((t) => t.id !== toastId);\n emit();\n };\n\n const subscribe = (listener: (toasts: Toast[]) => void): (() => void) => {\n listeners.add(listener);\n listener(toasts);\n return () => {\n listeners.delete(listener);\n };\n };\n\n return { add, dismiss, remove, subscribe };\n})();\n\nexport interface ToastFn {\n (message: React.ReactNode, opts?: ToastOptions): number;\n positive: (message: React.ReactNode, opts?: ToastOptions) => number;\n error: (message: React.ReactNode, opts?: ToastOptions) => number;\n info: (message: React.ReactNode, opts?: ToastOptions) => number;\n warn: (message: React.ReactNode, opts?: ToastOptions) => number;\n dismiss: (id: number) => void;\n}\n\n/**\n * Global toast handle. `toast(msg)` enqueues a neutral toast; the `.positive`,\n * `.error`, `.info` and `.warn` helpers pin the variant; `toast.dismiss(id)`\n * removes one early. Mirrors Rust's `use_toaster()` handle methods.\n */\nexport const toast: ToastFn = Object.assign(\n (message: React.ReactNode, opts?: ToastOptions) => store.add(message, opts),\n {\n positive: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"positive\" }),\n error: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"error\" }),\n info: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"info\" }),\n warn: (message: React.ReactNode, opts?: ToastOptions) =>\n store.add(message, { ...opts, variant: \"warn\" }),\n dismiss: (id: number) => store.dismiss(id),\n },\n);\n\n// Sonner-style stacking: only the front VISIBLE_TOASTS show collapsed; GAP is\n// the px between them once expanded.\nconst VISIBLE_TOASTS = 3;\nconst GAP = 14;\n\ninterface ToastItemProps {\n toast: Toast;\n index: number; // 0 = front / newest\n total: number;\n offset: number; // px from the pinned edge to this toast's expanded slot\n paused: boolean; // the stack is hovered/focused — hold the auto-dismiss\n reportHeight: (id: number, height: number) => void;\n removeHeight: (id: number) => void;\n}\n\nfunction ToastItem({\n toast: t,\n index,\n total,\n offset,\n paused,\n reportHeight,\n removeHeight,\n}: ToastItemProps) {\n const ref = React.useRef<HTMLLIElement>(null);\n const [height, setHeight] = React.useState(0);\n // remaining auto-dismiss budget (banked across hover pauses), the last start\n // timestamp, and the swipe-fling fallback timer.\n const remainingRef = React.useRef(t.duration);\n const startedRef = React.useRef(0);\n const flingRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const dragRef = React.useRef<{ x: number; time: number; dx: number } | null>(\n null,\n );\n\n // measure the *natural* height for the stack maths; re-measure on content\n // change. Back toasts are clamped to --front-height by the CSS, so unset the\n // height for the read (Sonner does the same) then hand it back to the CSS.\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.style.height = \"auto\";\n const h = el.getBoundingClientRect().height;\n el.style.height = \"\";\n if (h) {\n setHeight(h);\n reportHeight(t.id, h);\n }\n }, [t.id, t.message, t.description, reportHeight]);\n\n React.useEffect(() => () => removeHeight(t.id), [t.id, removeHeight]);\n\n // Dismissed before its first paint (added and dismissed in one batch), so it\n // mounts already `closing`: its computed style never changes, no transition\n // runs, and `onTransitionEnd` below would never fire — stranding it in the\n // store forever. Nothing was painted, so there is nothing to animate: drop it\n // once mounted. Mirrors the Dioxus port's mount effect.\n const mountedClosing = React.useRef(t.state === \"closing\");\n React.useEffect(() => {\n if (mountedClosing.current) store.remove(t.id);\n }, [t.id]);\n\n // Auto-dismiss, pausable on hover. While `paused` (or closing, or a persistent\n // `duration: Infinity`) no timer runs; the cleanup banks the elapsed time so a\n // resume continues from the remaining budget rather than restarting.\n React.useEffect(() => {\n if (t.duration === Infinity || t.state === \"closing\" || paused) return;\n startedRef.current = Date.now();\n const id = setTimeout(() => store.dismiss(t.id), remainingRef.current);\n return () => {\n clearTimeout(id);\n remainingRef.current = Math.max(\n 0,\n remainingRef.current - (Date.now() - startedRef.current),\n );\n };\n }, [paused, t.id, t.duration, t.state]);\n\n // cancel the swipe-fling fallback if the toast unmounts first\n React.useEffect(\n () => () => {\n if (flingRef.current) clearTimeout(flingRef.current);\n },\n [],\n );\n\n // exit rides the transition: a closing toast slides back off and is dropped on\n // the transform's `transitionend` (guarded so stack repositioning never fires\n // it). No host timer — keeps parity with the Dioxus port.\n const onTransitionEnd = (e: React.TransitionEvent<HTMLLIElement>) => {\n if (t.state === \"closing\" && e.propertyName === \"transform\") {\n store.remove(t.id);\n }\n };\n\n // ── swipe-to-dismiss (horizontal pointer drag) ──────────────────────────\n // Tracked through the `--swipe-x` var so it *composes* with the stack\n // transform (`var(--y) translateX(var(--swipe-x))`) instead of overriding it.\n const onPointerDown = (e: React.PointerEvent<HTMLLIElement>) => {\n const el = ref.current;\n if (!el || e.button > 0 || t.state === \"closing\") return;\n if ((e.target as HTMLElement).closest('[data-slot=\"toast-close\"]')) return;\n // auto-dismiss is already paused (a swipe means the pointer is over the stack)\n dragRef.current = { x: e.clientX, time: e.timeStamp, dx: 0 };\n el.setAttribute(\"data-swiping\", \"true\"); // CSS drops the transition for 1:1 tracking\n try {\n el.setPointerCapture?.(e.pointerId);\n } catch {\n // jsdom / unsupported — capture is a nice-to-have, the drag works without it\n }\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLLIElement>) => {\n const drag = dragRef.current;\n const el = ref.current;\n if (!drag || !el) return;\n const dx = e.clientX - drag.x;\n drag.dx = dx;\n const dist = el.offsetWidth || 256;\n el.style.setProperty(\"--swipe-x\", `${dx}px`);\n el.style.opacity = `${Math.max(0, 1 - Math.abs(dx) / dist)}`;\n };\n\n const onPointerEnd = (e: React.PointerEvent<HTMLLIElement>) => {\n const drag = dragRef.current;\n const el = ref.current;\n if (!drag || !el) return;\n dragRef.current = null;\n el.removeAttribute(\"data-swiping\"); // CSS restores the transition\n const dt = e.timeStamp - drag.time;\n const velocity = dt > 0 ? Math.abs(drag.dx) / dt : 0;\n if (\n drag.dx !== 0 &&\n (Math.abs(drag.dx) >= SWIPE_THRESHOLD || velocity > SWIPE_VELOCITY)\n ) {\n el.style.setProperty(\"--swipe-x\", `${drag.dx > 0 ? 150 : -150}%`);\n el.style.opacity = \"0\";\n const remove = () => store.remove(t.id);\n el.addEventListener(\"transitionend\", remove, { once: true });\n flingRef.current = setTimeout(remove, SWIPE_FLING_MS + 50); // fallback if transitionend is missed\n } else {\n // snap back: clear the swipe offset (the transition carries it home), then\n // hand styling back to the CSS. Auto-dismiss stays paused while hovered and\n // re-arms from the remaining budget once the pointer leaves.\n el.style.setProperty(\"--swipe-x\", \"0px\");\n el.style.opacity = \"1\";\n el.addEventListener(\n \"transitionend\",\n () => {\n el.style.removeProperty(\"--swipe-x\");\n el.style.opacity = \"\";\n },\n { once: true },\n );\n }\n };\n\n return (\n <li\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"toast\"\n data-variant={t.variant}\n data-state={t.state === \"closing\" ? \"closed\" : \"open\"}\n data-front={index === 0}\n data-visible={index < VISIBLE_TOASTS}\n onTransitionEnd={onTransitionEnd}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerEnd}\n onPointerCancel={onPointerEnd}\n style={\n {\n \"--index\": index,\n \"--z-index\": total - index,\n \"--offset\": `${offset}px`,\n \"--initial-height\": `${height}px`,\n } as React.CSSProperties\n }\n className={cn(\n TOAST_BASE,\n \"touch-pan-y select-none\",\n toastVariantClasses[t.variant],\n )}\n >\n <div className={TOAST_CONTENT}>\n <div className={TOAST_TITLE}>{t.message}</div>\n {t.description ? (\n <div className=\"text-ink-soft text-sm\">{t.description}</div>\n ) : null}\n </div>\n <button\n type=\"button\"\n aria-label=\"Close\"\n data-slot=\"toast-close\"\n onClick={() => store.dismiss(t.id)}\n className={TOAST_CLOSE}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n </li>\n );\n}\n\nexport interface ToasterProps extends React.ComponentProps<\"ol\"> {\n position?: ToastPosition;\n}\n\n/**\n * Renders the live toast stack from the module store. Fixed-positioned per\n * `position` (default `bottom-right`).\n *\n * Stacking mirrors Sonner: toasts pile up collapsed (the front three peeking,\n * each scaled + lifted by depth and clamped to the front toast's height) and\n * spread into a list on hover / keyboard focus — driven by the measured\n * `--front-height`/`--offset` vars and the `data-stack` CSS in `tokens.css`.\n * Each toast auto-dismisses after its `duration` (default 4000ms) via the same\n * animated `dismiss` as the close button (`data-state=\"closed\"` → slide out →\n * unmount on `transitionend`), and is swipe-to-dismiss (horizontal drag, TS-only\n * pointer physics). Single dark palette — no theme switching.\n */\nexport function Toaster({\n position = \"bottom-right\",\n className,\n ...props\n}: ToasterProps) {\n const [toasts, setToasts] = React.useState<Toast[]>([]);\n const [heights, setHeights] = React.useState<Map<number, number>>(new Map());\n const [paused, setPaused] = React.useState(false);\n\n React.useEffect(() => store.subscribe(setToasts), []);\n\n // Pause auto-dismiss while the stack is hovered or keyboard-focused (Sonner\n // does the same). pointerover/out + focusin/out bubble from the toasts, so they\n // fire even though the <ol> itself is pointer-events:none; the contains() guard\n // keeps it paused while moving *within* the stack.\n const onEnter = () => setPaused(true);\n const onLeave = (e: React.PointerEvent | React.FocusEvent) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {\n setPaused(false);\n }\n };\n\n const reportHeight = React.useCallback((id: number, h: number) => {\n setHeights((prev) => {\n if (prev.get(id) === h) return prev;\n const next = new Map(prev);\n next.set(id, h);\n return next;\n });\n }, []);\n const removeHeight = React.useCallback((id: number) => {\n setHeights((prev) => {\n if (!prev.has(id)) return prev;\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n }, []);\n\n const yPosition = position.startsWith(\"top\") ? \"top\" : \"bottom\";\n const ordered = [...toasts].reverse(); // newest first → front of the stack\n // front toast's height; until it's measured fall back to the tallest known one\n // so the back toasts don't clamp to 0 for a frame when a new toast arrives\n const known = [...heights.values()];\n const frontHeight = ordered[0]\n ? (heights.get(ordered[0].id) ?? (known.length ? Math.max(...known) : 0))\n : 0;\n\n // cumulative offset: heights of the toasts in front of this one + index * GAP\n let sum = 0;\n const offsets = ordered.map((t, i) => {\n const o = sum + i * GAP;\n sum += heights.get(t.id) ?? 0;\n return o;\n });\n\n return (\n <ol\n data-slot=\"toaster\"\n // LAYER_IGNORE_ATTR: a toast floats over every overlay without being\n // part of one, and a press on it is no click away from the Dialog below.\n data-dismissable-layer-ignore=\"\"\n data-position={position}\n data-y-position={yPosition}\n data-stack=\"\"\n style={\n {\n \"--front-height\": `${frontHeight}px`,\n \"--gap\": `${GAP}px`,\n } as React.CSSProperties\n }\n className={cn(\n TOASTER_BASE,\n positionClasses[position],\n className,\n )}\n {...props}\n onPointerOver={onEnter}\n onPointerOut={onLeave}\n onFocus={onEnter}\n onBlur={onLeave}\n >\n {ordered.map((t, i) => (\n <ToastItem\n key={t.id}\n toast={t}\n index={i}\n total={ordered.length}\n offset={offsets[i]!}\n paused={paused}\n reportHeight={reportHeight}\n removeHeight={removeHeight}\n />\n ))}\n </ol>\n );\n}\n"],"mappings":";AA6UM,SACE,KADF;AA3UN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAgCP,MAAM,mBAAmB;AAKzB,MAAM,kBAAkB;AACxB,MAAM,iBAAiB;AACvB,MAAM,iBAAiB;AASvB,MAAM,QAAS,uBAAM;AACnB,MAAI,SAAkB,CAAC;AACvB,MAAI,KAAK;AACT,QAAM,YAAY,oBAAI,IAA+B;AAErD,QAAM,OAAO,MAAM;AACjB,eAAW,YAAY,UAAW,UAAS,MAAM;AAAA,EACnD;AAEA,QAAM,MAAM,CAAC,SAA0B,OAAqB,CAAC,MAAc;AACzE,UAAM,OAAc;AAAA,MAClB,IAAI,EAAE;AAAA,MACN;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK,YAAY;AAAA,MAC3B,SAAS,KAAK,WAAW;AAAA,MACzB,OAAO;AAAA,IACT;AACA,aAAS,CAAC,GAAG,QAAQ,IAAI;AACzB,SAAK;AACL,WAAO,KAAK;AAAA,EACd;AAOA,QAAM,UAAU,CAAC,YAAoB;AACnC,aAAS,OAAO;AAAA,MAAI,CAAC,MACnB,EAAE,OAAO,UAAU,EAAE,GAAG,GAAG,OAAO,UAAmB,IAAI;AAAA,IAC3D;AACA,SAAK;AAAA,EACP;AAKA,QAAM,SAAS,CAAC,YAAoB;AAClC,aAAS,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,OAAO;AAC9C,SAAK;AAAA,EACP;AAEA,QAAM,YAAY,CAAC,aAAsD;AACvE,cAAU,IAAI,QAAQ;AACtB,aAAS,MAAM;AACf,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,SAAS,QAAQ,UAAU;AAC3C,GAAG;AAgBI,MAAM,QAAiB,OAAO;AAAA,EACnC,CAAC,SAA0B,SAAwB,MAAM,IAAI,SAAS,IAAI;AAAA,EAC1E;AAAA,IACE,UAAU,CAAC,SAA0B,SACnC,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM,SAAS,WAAW,CAAC;AAAA,IACrD,OAAO,CAAC,SAA0B,SAChC,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM,SAAS,QAAQ,CAAC;AAAA,IAClD,MAAM,CAAC,SAA0B,SAC/B,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM,SAAS,OAAO,CAAC;AAAA,IACjD,MAAM,CAAC,SAA0B,SAC/B,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM,SAAS,OAAO,CAAC;AAAA,IACjD,SAAS,CAAC,OAAe,MAAM,QAAQ,EAAE;AAAA,EAC3C;AACF;AAIA,MAAM,iBAAiB;AACvB,MAAM,MAAM;AAYZ,SAAS,UAAU;AAAA,EACjB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,MAAM,MAAM,OAAsB,IAAI;AAC5C,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,CAAC;AAG5C,QAAM,eAAe,MAAM,OAAO,EAAE,QAAQ;AAC5C,QAAM,aAAa,MAAM,OAAO,CAAC;AACjC,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,EACF;AACA,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,EACF;AAKA,QAAM,gBAAgB,MAAM;AAC1B,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,OAAG,MAAM,SAAS;AAClB,UAAM,IAAI,GAAG,sBAAsB,EAAE;AACrC,OAAG,MAAM,SAAS;AAClB,QAAI,GAAG;AACL,gBAAU,CAAC;AACX,mBAAa,EAAE,IAAI,CAAC;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,YAAY,CAAC;AAEjD,QAAM,UAAU,MAAM,MAAM,aAAa,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,YAAY,CAAC;AAOpE,QAAM,iBAAiB,MAAM,OAAO,EAAE,UAAU,SAAS;AACzD,QAAM,UAAU,MAAM;AACpB,QAAI,eAAe,QAAS,OAAM,OAAO,EAAE,EAAE;AAAA,EAC/C,GAAG,CAAC,EAAE,EAAE,CAAC;AAKT,QAAM,UAAU,MAAM;AACpB,QAAI,EAAE,aAAa,YAAY,EAAE,UAAU,aAAa,OAAQ;AAChE,eAAW,UAAU,KAAK,IAAI;AAC9B,UAAM,KAAK,WAAW,MAAM,MAAM,QAAQ,EAAE,EAAE,GAAG,aAAa,OAAO;AACrE,WAAO,MAAM;AACX,mBAAa,EAAE;AACf,mBAAa,UAAU,KAAK;AAAA,QAC1B;AAAA,QACA,aAAa,WAAW,KAAK,IAAI,IAAI,WAAW;AAAA,MAClD;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC;AAGtC,QAAM;AAAA,IACJ,MAAM,MAAM;AACV,UAAI,SAAS,QAAS,cAAa,SAAS,OAAO;AAAA,IACrD;AAAA,IACA,CAAC;AAAA,EACH;AAKA,QAAM,kBAAkB,CAAC,MAA4C;AACnE,QAAI,EAAE,UAAU,aAAa,EAAE,iBAAiB,aAAa;AAC3D,YAAM,OAAO,EAAE,EAAE;AAAA,IACnB;AAAA,EACF;AAKA,QAAM,gBAAgB,CAAC,MAAyC;AAC9D,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,UAAU,UAAW;AAClD,QAAK,EAAE,OAAuB,QAAQ,2BAA2B,EAAG;AAEpE,YAAQ,UAAU,EAAE,GAAG,EAAE,SAAS,MAAM,EAAE,WAAW,IAAI,EAAE;AAC3D,OAAG,aAAa,gBAAgB,MAAM;AACtC,QAAI;AACF,SAAG,oBAAoB,EAAE,SAAS;AAAA,IACpC,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,MAAyC;AAC9D,UAAM,OAAO,QAAQ;AACrB,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,QAAQ,CAAC,GAAI;AAClB,UAAM,KAAK,EAAE,UAAU,KAAK;AAC5B,SAAK,KAAK;AACV,UAAM,OAAO,GAAG,eAAe;AAC/B,OAAG,MAAM,YAAY,aAAa,GAAG,EAAE,IAAI;AAC3C,OAAG,MAAM,UAAU,GAAG,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,IAAI,IAAI,CAAC;AAAA,EAC5D;AAEA,QAAM,eAAe,CAAC,MAAyC;AAC7D,UAAM,OAAO,QAAQ;AACrB,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,QAAQ,CAAC,GAAI;AAClB,YAAQ,UAAU;AAClB,OAAG,gBAAgB,cAAc;AACjC,UAAM,KAAK,EAAE,YAAY,KAAK;AAC9B,UAAM,WAAW,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK;AACnD,QACE,KAAK,OAAO,MACX,KAAK,IAAI,KAAK,EAAE,KAAK,mBAAmB,WAAW,iBACpD;AACA,SAAG,MAAM,YAAY,aAAa,GAAG,KAAK,KAAK,IAAI,MAAM,IAAI,GAAG;AAChE,SAAG,MAAM,UAAU;AACnB,YAAM,SAAS,MAAM,MAAM,OAAO,EAAE,EAAE;AACtC,SAAG,iBAAiB,iBAAiB,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC3D,eAAS,UAAU,WAAW,QAAQ,iBAAiB,EAAE;AAAA,IAC3D,OAAO;AAIL,SAAG,MAAM,YAAY,aAAa,KAAK;AACvC,SAAG,MAAM,UAAU;AACnB,SAAG;AAAA,QACD;AAAA,QACA,MAAM;AACJ,aAAG,MAAM,eAAe,WAAW;AACnC,aAAG,MAAM,UAAU;AAAA,QACrB;AAAA,QACA,EAAE,MAAM,KAAK;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAK;AAAA,MACL,aAAU;AAAA,MACV,aAAU;AAAA,MACV,gBAAc,EAAE;AAAA,MAChB,cAAY,EAAE,UAAU,YAAY,WAAW;AAAA,MAC/C,cAAY,UAAU;AAAA,MACtB,gBAAc,QAAQ;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,iBAAiB;AAAA,MACjB,OACE;AAAA,QACE,WAAW;AAAA,QACX,aAAa,QAAQ;AAAA,QACrB,YAAY,GAAG,MAAM;AAAA,QACrB,oBAAoB,GAAG,MAAM;AAAA,MAC/B;AAAA,MAEF,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,oBAAoB,EAAE,OAAO;AAAA,MAC/B;AAAA,MAEA;AAAA,6BAAC,SAAI,WAAW,eACd;AAAA,8BAAC,SAAI,WAAW,aAAc,YAAE,SAAQ;AAAA,UACvC,EAAE,cACD,oBAAC,SAAI,WAAU,yBAAyB,YAAE,aAAY,IACpD;AAAA,WACN;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAW;AAAA,YACX,aAAU;AAAA,YACV,SAAS,MAAM,MAAM,QAAQ,EAAE,EAAE;AAAA,YACjC,WAAW;AAAA,YAEX;AAAA,cAAC;AAAA;AAAA,gBACC,OAAM;AAAA,gBACN,OAAM;AAAA,gBACN,QAAO;AAAA,gBACP,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,QAAO;AAAA,gBACP,aAAY;AAAA,gBACZ,eAAc;AAAA,gBACd,gBAAe;AAAA,gBACf,eAAY;AAAA,gBAEZ,8BAAC,UAAK,GAAE,wBAAuB;AAAA;AAAA,YACjC;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAmBO,SAAS,QAAQ;AAAA,EACtB,WAAW;AAAA,EACX;AAAA,EACA,GAAG;AACL,GAAiB;AACf,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAkB,CAAC,CAAC;AACtD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA8B,oBAAI,IAAI,CAAC;AAC3E,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAEhD,QAAM,UAAU,MAAM,MAAM,UAAU,SAAS,GAAG,CAAC,CAAC;AAMpD,QAAM,UAAU,MAAM,UAAU,IAAI;AACpC,QAAM,UAAU,CAAC,MAA6C;AAC5D,QAAI,CAAC,EAAE,cAAc,SAAS,EAAE,aAA4B,GAAG;AAC7D,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,YAAY,CAAC,IAAY,MAAc;AAChE,eAAW,CAAC,SAAS;AACnB,UAAI,KAAK,IAAI,EAAE,MAAM,EAAG,QAAO;AAC/B,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,WAAK,IAAI,IAAI,CAAC;AACd,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AACL,QAAM,eAAe,MAAM,YAAY,CAAC,OAAe;AACrD,eAAW,CAAC,SAAS;AACnB,UAAI,CAAC,KAAK,IAAI,EAAE,EAAG,QAAO;AAC1B,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,WAAK,OAAO,EAAE;AACd,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,SAAS,WAAW,KAAK,IAAI,QAAQ;AACvD,QAAM,UAAU,CAAC,GAAG,MAAM,EAAE,QAAQ;AAGpC,QAAM,QAAQ,CAAC,GAAG,QAAQ,OAAO,CAAC;AAClC,QAAM,cAAc,QAAQ,CAAC,IACxB,QAAQ,IAAI,QAAQ,CAAC,EAAE,EAAE,MAAM,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,KACpE;AAGJ,MAAI,MAAM;AACV,QAAM,UAAU,QAAQ,IAAI,CAAC,GAAG,MAAM;AACpC,UAAM,IAAI,MAAM,IAAI;AACpB,WAAO,QAAQ,IAAI,EAAE,EAAE,KAAK;AAC5B,WAAO;AAAA,EACT,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MAGV,iCAA8B;AAAA,MAC9B,iBAAe;AAAA,MACf,mBAAiB;AAAA,MACjB,cAAW;AAAA,MACX,OACE;AAAA,QACE,kBAAkB,GAAG,WAAW;AAAA,QAChC,SAAS,GAAG,GAAG;AAAA,MACjB;AAAA,MAEF,WAAW;AAAA,QACT;AAAA,QACA,gBAAgB,QAAQ;AAAA,QACxB;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MACJ,eAAe;AAAA,MACf,cAAc;AAAA,MACd,SAAS;AAAA,MACT,QAAQ;AAAA,MAEP,kBAAQ,IAAI,CAAC,GAAG,MACf;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO;AAAA,UACP,OAAO;AAAA,UACP,OAAO,QAAQ;AAAA,UACf,QAAQ,QAAQ,CAAC;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAPK,EAAE;AAAA,MAQT,CACD;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -4,6 +4,7 @@ import * as React from "react";
4
4
  import { cn } from "../lib/cn.js";
5
5
  import { SWITCH_BASE, SWITCH_THUMB } from "../generated/switch.js";
6
6
  import { useControllableState } from "../primitives/use-controllable-state.js";
7
+ import { markLabelable } from "../primitives/labelable.js";
7
8
  import { useFieldControlId } from "./field-context.js";
8
9
  function Switch({
9
10
  className,
@@ -48,6 +49,7 @@ function Switch({
48
49
  }
49
50
  );
50
51
  }
52
+ markLabelable(Switch);
51
53
  export {
52
54
  Switch
53
55
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/switch.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { SWITCH_BASE, SWITCH_THUMB } from \"../generated/switch\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { useFieldControlId } from \"./field-context\";\n\nexport interface SwitchProps\n extends Omit<React.ComponentProps<\"button\">, \"onChange\"> {\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nexport function Switch({\n className,\n checked,\n defaultChecked = false,\n onCheckedChange,\n onClick,\n disabled,\n id,\n ...props\n}: SwitchProps) {\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=\"switch\"\n data-slot=\"switch\"\n data-state={state}\n aria-checked={on}\n disabled={disabled}\n id={useFieldControlId(id)}\n className={cn(SWITCH_BASE, className)}\n onClick={(e) => {\n onClick?.(e);\n setOn(!on);\n }}\n {...props}\n >\n <span\n data-slot=\"switch-thumb\"\n data-state={state}\n className={SWITCH_THUMB}\n />\n </button>\n );\n}\n"],"mappings":";AA+CM;AA7CN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,aAAa,oBAAoB;AAC1C,SAAS,4BAA4B;AACrC,SAAS,yBAAyB;AAS3B,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgB;AACd,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,aAAa,SAAS;AAAA,MACpC,SAAS,CAAC,MAAM;AACd,kBAAU,CAAC;AACX,cAAM,CAAC,EAAE;AAAA,MACX;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,cAAY;AAAA,UACZ,WAAW;AAAA;AAAA,MACb;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/switch.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { SWITCH_BASE, SWITCH_THUMB } from \"../generated/switch\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { markLabelable } from \"../primitives/labelable\";\nimport { useFieldControlId } from \"./field-context\";\n\nexport interface SwitchProps\n extends Omit<React.ComponentProps<\"button\">, \"onChange\"> {\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nexport function Switch({\n className,\n checked,\n defaultChecked = false,\n onCheckedChange,\n onClick,\n disabled,\n id,\n ...props\n}: SwitchProps) {\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=\"switch\"\n data-slot=\"switch\"\n data-state={state}\n aria-checked={on}\n disabled={disabled}\n id={useFieldControlId(id)}\n className={cn(SWITCH_BASE, className)}\n onClick={(e) => {\n onClick?.(e);\n setOn(!on);\n }}\n {...props}\n >\n <span\n data-slot=\"switch-thumb\"\n data-state={state}\n className={SWITCH_THUMB}\n />\n </button>\n );\n}\n\nmarkLabelable(Switch);\n"],"mappings":";AAgDM;AA9CN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,aAAa,oBAAoB;AAC1C,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAS3B,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgB;AACd,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,aAAa,SAAS;AAAA,MACpC,SAAS,CAAC,MAAM;AACd,kBAAU,CAAC;AACX,cAAM,CAAC,EAAE;AAAA,MACX;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,cAAY;AAAA,UACZ,WAAW;AAAA;AAAA,MACb;AAAA;AAAA,EACF;AAEJ;AAEA,cAAc,MAAM;","names":[]}
@@ -5,14 +5,18 @@ import {
5
5
  TABLE,
6
6
  TABLE_BODY,
7
7
  TABLE_CAPTION,
8
+ TABLE_CARD,
8
9
  TABLE_CELL,
9
10
  TABLE_CONTAINER,
10
11
  TABLE_FOOTER,
11
12
  TABLE_HEAD,
12
13
  TABLE_HEADER,
13
- TABLE_ROW
14
+ TABLE_ROW,
15
+ tableAligns,
16
+ tableDensities,
17
+ tableVariants
14
18
  } from "../generated/table.js";
15
- function Table({ className, ...props }) {
19
+ function Table({ variant = "default", density = "default", className, ...props }) {
16
20
  return /* @__PURE__ */ jsx(
17
21
  "div",
18
22
  {
@@ -22,13 +26,25 @@ function Table({ className, ...props }) {
22
26
  "table",
23
27
  {
24
28
  "data-slot": "table",
25
- className: cn(TABLE, className),
29
+ "data-variant": variant,
30
+ "data-density": density,
31
+ className: cn(TABLE, tableVariants[variant], tableDensities[density], className),
26
32
  ...props
27
33
  }
28
34
  )
29
35
  }
30
36
  );
31
37
  }
38
+ function TableCard({ className, ...props }) {
39
+ return /* @__PURE__ */ jsx(
40
+ "div",
41
+ {
42
+ "data-slot": "table-card",
43
+ className: cn(TABLE_CARD, className),
44
+ ...props
45
+ }
46
+ );
47
+ }
32
48
  function TableHeader({
33
49
  className,
34
50
  ...props
@@ -78,22 +94,22 @@ function TableRow({ className, ...props }) {
78
94
  }
79
95
  );
80
96
  }
81
- function TableHead({ className, ...props }) {
97
+ function TableHead({ align, className, ...props }) {
82
98
  return /* @__PURE__ */ jsx(
83
99
  "th",
84
100
  {
85
101
  "data-slot": "table-head",
86
- className: cn(TABLE_HEAD, className),
102
+ className: cn(TABLE_HEAD, align && tableAligns[align], className),
87
103
  ...props
88
104
  }
89
105
  );
90
106
  }
91
- function TableCell({ className, ...props }) {
107
+ function TableCell({ align, className, ...props }) {
92
108
  return /* @__PURE__ */ jsx(
93
109
  "td",
94
110
  {
95
111
  "data-slot": "table-cell",
96
- className: cn(TABLE_CELL, className),
112
+ className: cn(TABLE_CELL, align && tableAligns[align], className),
97
113
  ...props
98
114
  }
99
115
  );
@@ -115,6 +131,7 @@ export {
115
131
  Table,
116
132
  TableBody,
117
133
  TableCaption,
134
+ TableCard,
118
135
  TableCell,
119
136
  TableFooter,
120
137
  TableHead,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/table.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n TABLE,\n TABLE_BODY,\n TABLE_CAPTION,\n TABLE_CELL,\n TABLE_CONTAINER,\n TABLE_FOOTER,\n TABLE_HEAD,\n TABLE_HEADER,\n TABLE_ROW,\n} from \"../generated/table\";\n\nexport function Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className={TABLE_CONTAINER}\n >\n <table\n data-slot=\"table\"\n className={cn(TABLE, className)}\n {...props}\n />\n </div>\n );\n}\n\nexport function TableHeader({\n className,\n ...props\n}: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(TABLE_HEADER, className)}\n {...props}\n />\n );\n}\n\nexport function TableBody({\n className,\n ...props\n}: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(TABLE_BODY, className)}\n {...props}\n />\n );\n}\n\nexport function TableFooter({\n className,\n ...props\n}: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(TABLE_FOOTER, className)}\n {...props}\n />\n );\n}\n\nexport function TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(TABLE_ROW, className)}\n {...props}\n />\n );\n}\n\nexport function TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(TABLE_HEAD, className)}\n {...props}\n />\n );\n}\n\nexport function TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(TABLE_CELL, className)}\n {...props}\n />\n );\n}\n\nexport function TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(TABLE_CAPTION, className)}\n {...props}\n />\n );\n}\n"],"mappings":"AAoBM;AApBN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,SAAS,MAAM,EAAE,WAAW,GAAG,MAAM,GAAkC;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,MAEX;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,WAAW,GAAG,OAAO,SAAS;AAAA,UAC7B,GAAG;AAAA;AAAA,MACN;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS;AAAA,MAClC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,WAAW,SAAS;AAAA,MACjC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,UAAU,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS;AAAA,MAClC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,UAAU,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS;AAAA,MAClC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,GAAG;AACL,GAAoC;AAClC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,SAAS;AAAA,MACrC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/table.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n TABLE,\n TABLE_BODY,\n TABLE_CAPTION,\n TABLE_CARD,\n TABLE_CELL,\n TABLE_CONTAINER,\n TABLE_FOOTER,\n TABLE_HEAD,\n TABLE_HEADER,\n TABLE_ROW,\n tableAligns,\n tableDensities,\n tableVariants,\n type TableAlign,\n type TableDensity,\n type TableVariant,\n} from \"../generated/table\";\n\nexport type { TableAlign, TableDensity, TableVariant };\n\nexport interface TableProps extends React.ComponentProps<\"table\"> {\n variant?: TableVariant;\n density?: TableDensity;\n}\n\n// `variant` and `density` only set inherited `--table-*` properties that the\n// heads and cells read — no context, so `Table` stays a Server Component and a\n// cell's own `className` still beats the table's geometry.\nexport function Table({ variant = \"default\", density = \"default\", className, ...props }: TableProps) {\n return (\n <div\n data-slot=\"table-container\"\n className={TABLE_CONTAINER}\n >\n <table\n data-slot=\"table\"\n data-variant={variant}\n data-density={density}\n className={cn(TABLE, tableVariants[variant], tableDensities[density], className)}\n {...props}\n />\n </div>\n );\n}\n\n/** The surface a `variant=\"card\"` table sits in, edge to edge. */\nexport function TableCard({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"table-card\"\n className={cn(TABLE_CARD, className)}\n {...props}\n />\n );\n}\n\nexport function TableHeader({\n className,\n ...props\n}: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(TABLE_HEADER, className)}\n {...props}\n />\n );\n}\n\nexport function TableBody({\n className,\n ...props\n}: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(TABLE_BODY, className)}\n {...props}\n />\n );\n}\n\nexport function TableFooter({\n className,\n ...props\n}: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(TABLE_FOOTER, className)}\n {...props}\n />\n );\n}\n\nexport function TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(TABLE_ROW, className)}\n {...props}\n />\n );\n}\n\n// The HTML `align` attribute is obsolete; the prop takes its name for the\n// logical start/end the Rust port uses.\nexport interface TableHeadProps extends Omit<React.ComponentProps<\"th\">, \"align\"> {\n align?: TableAlign;\n}\n\nexport function TableHead({ align, className, ...props }: TableHeadProps) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(TABLE_HEAD, align && tableAligns[align], className)}\n {...props}\n />\n );\n}\n\nexport interface TableCellProps extends Omit<React.ComponentProps<\"td\">, \"align\"> {\n align?: TableAlign;\n}\n\nexport function TableCell({ align, className, ...props }: TableCellProps) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(TABLE_CELL, align && tableAligns[align], className)}\n {...props}\n />\n );\n}\n\nexport function TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(TABLE_CAPTION, className)}\n {...props}\n />\n );\n}\n"],"mappings":"AAqCM;AArCN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;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,OAIK;AAYA,SAAS,MAAM,EAAE,UAAU,WAAW,UAAU,WAAW,WAAW,GAAG,MAAM,GAAe;AACnG,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,MAEX;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,gBAAc;AAAA,UACd,gBAAc;AAAA,UACd,WAAW,GAAG,OAAO,cAAc,OAAO,GAAG,eAAe,OAAO,GAAG,SAAS;AAAA,UAC9E,GAAG;AAAA;AAAA,MACN;AAAA;AAAA,EACF;AAEJ;AAGO,SAAS,UAAU,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC9E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS;AAAA,MAClC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS;AAAA,MAClC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,WAAW,SAAS;AAAA,MACjC,GAAG;AAAA;AAAA,EACN;AAEJ;AAQO,SAAS,UAAU,EAAE,OAAO,WAAW,GAAG,MAAM,GAAmB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS,YAAY,KAAK,GAAG,SAAS;AAAA,MAC/D,GAAG;AAAA;AAAA,EACN;AAEJ;AAMO,SAAS,UAAU,EAAE,OAAO,WAAW,GAAG,MAAM,GAAmB;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,YAAY,SAAS,YAAY,KAAK,GAAG,SAAS;AAAA,MAC/D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,GAAG;AACL,GAAoC;AAClC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,SAAS;AAAA,MACrC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -3,6 +3,7 @@ import { jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cn } from "../lib/cn.js";
5
5
  import { TEXTAREA_BASE, textareaSizeClasses } from "../generated/textarea.js";
6
+ import { markLabelable } from "../primitives/labelable.js";
6
7
  import { useFieldControlId } from "./field-context.js";
7
8
  function Textarea({ className, id, size = "md", ...props }) {
8
9
  return /* @__PURE__ */ jsx(
@@ -16,6 +17,7 @@ function Textarea({ className, id, size = "md", ...props }) {
16
17
  }
17
18
  );
18
19
  }
20
+ markLabelable(Textarea);
19
21
  export {
20
22
  Textarea
21
23
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/textarea.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { TEXTAREA_BASE, textareaSizeClasses, type TextareaSize } from \"../generated/textarea\";\nimport { useFieldControlId } from \"./field-context\";\n\nexport type { TextareaSize };\n\nexport interface TextareaProps extends React.ComponentProps<\"textarea\"> {\n size?: TextareaSize;\n}\n\nexport function Textarea({ className, id, size = \"md\", ...props }: TextareaProps) {\n return (\n <textarea\n data-slot=\"textarea\"\n data-size={size}\n id={useFieldControlId(id)}\n className={cn(TEXTAREA_BASE, textareaSizeClasses[size], className)}\n {...props}\n />\n );\n}\n"],"mappings":";AAeI;AAbJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,eAAe,2BAA8C;AACtE,SAAS,yBAAyB;AAQ3B,SAAS,SAAS,EAAE,WAAW,IAAI,OAAO,MAAM,GAAG,MAAM,GAAkB;AAChF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,aAAW;AAAA,MACX,IAAI,kBAAkB,EAAE;AAAA,MACxB,WAAW,GAAG,eAAe,oBAAoB,IAAI,GAAG,SAAS;AAAA,MAChE,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/textarea.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { TEXTAREA_BASE, textareaSizeClasses, type TextareaSize } from \"../generated/textarea\";\nimport { markLabelable } from \"../primitives/labelable\";\nimport { useFieldControlId } from \"./field-context\";\n\nexport type { TextareaSize };\n\nexport interface TextareaProps extends React.ComponentProps<\"textarea\"> {\n size?: TextareaSize;\n}\n\nexport function Textarea({ className, id, size = \"md\", ...props }: TextareaProps) {\n return (\n <textarea\n data-slot=\"textarea\"\n data-size={size}\n id={useFieldControlId(id)}\n className={cn(TEXTAREA_BASE, textareaSizeClasses[size], className)}\n {...props}\n />\n );\n}\n\nmarkLabelable(Textarea);\n"],"mappings":";AAgBI;AAdJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,eAAe,2BAA8C;AACtE,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAQ3B,SAAS,SAAS,EAAE,WAAW,IAAI,OAAO,MAAM,GAAG,MAAM,GAAkB;AAChF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,aAAW;AAAA,MACX,IAAI,kBAAkB,EAAE;AAAA,MACxB,WAAW,GAAG,eAAe,oBAAoB,IAAI,GAAG,SAAS;AAAA,MAChE,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,cAAc,QAAQ;","names":[]}
@@ -86,7 +86,7 @@ function ToggleGroupItem({
86
86
  toggleVariants({ variant: resolvedVariant, size: resolvedSize }),
87
87
  // `flex-auto`, not shadcn's `flex-1`: the group is `w-fit`, and basis-0 items
88
88
  // make Chrome split it into equal columns, so a longer label overflows its cell.
89
- "min-w-0 flex-auto shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
89
+ "min-w-0 flex-auto shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:-ml-px data-[variant=outline]:first:ml-0 data-[state=on]:z-10",
90
90
  className
91
91
  ),
92
92
  onClick: (e) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/toggle-group.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport {\n toggleVariants,\n type ToggleVariant,\n type ToggleSize,\n} from \"./toggle\";\n\ntype ToggleGroupContextValue = {\n variant: ToggleVariant;\n size: ToggleSize;\n value: string[];\n toggle: (itemValue: string) => void;\n};\n\nconst ToggleGroupContext = React.createContext<ToggleGroupContextValue>({\n variant: \"bare\",\n size: \"md\",\n value: [],\n toggle: () => {},\n});\n\nexport interface ToggleGroupProps\n extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n variant?: ToggleVariant;\n size?: ToggleSize;\n type?: \"single\" | \"multiple\";\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n}\n\nfunction toArray(v: string | string[] | undefined): string[] {\n if (v === undefined) return [];\n return Array.isArray(v) ? v : v === \"\" ? [] : [v];\n}\n\nexport function ToggleGroup({\n className,\n variant = \"bare\",\n size = \"md\",\n type = \"single\",\n value,\n defaultValue,\n onValueChange,\n children,\n ...props\n}: ToggleGroupProps) {\n const [selected, setSelected] = useControllableState<string[]>({\n ...(value !== undefined ? { value: toArray(value) } : {}),\n defaultValue: toArray(defaultValue),\n onChange: (next) =>\n onValueChange?.(type === \"single\" ? (next[0] ?? \"\") : next),\n });\n\n const toggle = React.useCallback(\n (itemValue: string) => {\n if (type === \"single\") {\n setSelected(selected.includes(itemValue) ? [] : [itemValue]);\n } else {\n setSelected(\n selected.includes(itemValue)\n ? selected.filter((v) => v !== itemValue)\n : [...selected, itemValue],\n );\n }\n },\n [type, selected, setSelected],\n );\n\n return (\n <div\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n className={cn(\n \"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs\",\n className,\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, size, value: selected, toggle }}>\n {children}\n </ToggleGroupContext.Provider>\n </div>\n );\n}\n\nexport interface ToggleGroupItemProps\n extends Omit<React.ComponentProps<\"button\">, \"value\" | \"onChange\"> {\n value: string;\n variant?: ToggleVariant;\n size?: ToggleSize;\n}\n\nexport function ToggleGroupItem({\n className,\n children,\n value,\n variant,\n size,\n onClick,\n ...props\n}: ToggleGroupItemProps) {\n const context = React.useContext(ToggleGroupContext);\n const resolvedVariant = context.variant || variant || \"bare\";\n const resolvedSize = context.size || size || \"md\";\n const on = context.value.includes(value);\n\n return (\n <button\n type=\"button\"\n data-slot=\"toggle-group-item\"\n data-variant={resolvedVariant}\n data-size={resolvedSize}\n data-state={on ? \"on\" : \"off\"}\n aria-pressed={on}\n className={cn(\n toggleVariants({ variant: resolvedVariant, size: resolvedSize }),\n // `flex-auto`, not shadcn's `flex-1`: the group is `w-fit`, and basis-0 items\n // make Chrome split it into equal columns, so a longer label overflows its cell.\n \"min-w-0 flex-auto shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l\",\n className,\n )}\n onClick={(e) => {\n onClick?.(e);\n context.toggle(value);\n }}\n {...props}\n >\n {children}\n </button>\n );\n}\n"],"mappings":";AAoFM;AAlFN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,OAGK;AASP,MAAM,qBAAqB,MAAM,cAAuC;AAAA,EACtE,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO,CAAC;AAAA,EACR,QAAQ,MAAM;AAAA,EAAC;AACjB,CAAC;AAYD,SAAS,QAAQ,GAA4C;AAC3D,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,SAAO,MAAM,QAAQ,CAAC,IAAI,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;AAClD;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAqB;AACnB,QAAM,CAAC,UAAU,WAAW,IAAI,qBAA+B;AAAA,IAC7D,GAAI,UAAU,SAAY,EAAE,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,IACvD,cAAc,QAAQ,YAAY;AAAA,IAClC,UAAU,CAAC,SACT,gBAAgB,SAAS,WAAY,KAAK,CAAC,KAAK,KAAM,IAAI;AAAA,EAC9D,CAAC;AAED,QAAM,SAAS,MAAM;AAAA,IACnB,CAAC,cAAsB;AACrB,UAAI,SAAS,UAAU;AACrB,oBAAY,SAAS,SAAS,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AAAA,MAC7D,OAAO;AACL;AAAA,UACE,SAAS,SAAS,SAAS,IACvB,SAAS,OAAO,CAAC,MAAM,MAAM,SAAS,IACtC,CAAC,GAAG,UAAU,SAAS;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,MAAM,UAAU,WAAW;AAAA,EAC9B;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,aAAW;AAAA,MACX,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,8BAAC,mBAAmB,UAAnB,EAA4B,OAAO,EAAE,SAAS,MAAM,OAAO,UAAU,OAAO,GAC1E,UACH;AAAA;AAAA,EACF;AAEJ;AASO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAyB;AACvB,QAAM,UAAU,MAAM,WAAW,kBAAkB;AACnD,QAAM,kBAAkB,QAAQ,WAAW,WAAW;AACtD,QAAM,eAAe,QAAQ,QAAQ,QAAQ;AAC7C,QAAM,KAAK,QAAQ,MAAM,SAAS,KAAK;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,aAAW;AAAA,MACX,cAAY,KAAK,OAAO;AAAA,MACxB,gBAAc;AAAA,MACd,WAAW;AAAA,QACT,eAAe,EAAE,SAAS,iBAAiB,MAAM,aAAa,CAAC;AAAA;AAAA;AAAA,QAG/D;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS,CAAC,MAAM;AACd,kBAAU,CAAC;AACX,gBAAQ,OAAO,KAAK;AAAA,MACtB;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/toggle-group.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport {\n toggleVariants,\n type ToggleVariant,\n type ToggleSize,\n} from \"./toggle\";\n\ntype ToggleGroupContextValue = {\n variant: ToggleVariant;\n size: ToggleSize;\n value: string[];\n toggle: (itemValue: string) => void;\n};\n\nconst ToggleGroupContext = React.createContext<ToggleGroupContextValue>({\n variant: \"bare\",\n size: \"md\",\n value: [],\n toggle: () => {},\n});\n\nexport interface ToggleGroupProps\n extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n variant?: ToggleVariant;\n size?: ToggleSize;\n type?: \"single\" | \"multiple\";\n value?: string | string[];\n defaultValue?: string | string[];\n onValueChange?: (value: string | string[]) => void;\n}\n\nfunction toArray(v: string | string[] | undefined): string[] {\n if (v === undefined) return [];\n return Array.isArray(v) ? v : v === \"\" ? [] : [v];\n}\n\nexport function ToggleGroup({\n className,\n variant = \"bare\",\n size = \"md\",\n type = \"single\",\n value,\n defaultValue,\n onValueChange,\n children,\n ...props\n}: ToggleGroupProps) {\n const [selected, setSelected] = useControllableState<string[]>({\n ...(value !== undefined ? { value: toArray(value) } : {}),\n defaultValue: toArray(defaultValue),\n onChange: (next) =>\n onValueChange?.(type === \"single\" ? (next[0] ?? \"\") : next),\n });\n\n const toggle = React.useCallback(\n (itemValue: string) => {\n if (type === \"single\") {\n setSelected(selected.includes(itemValue) ? [] : [itemValue]);\n } else {\n setSelected(\n selected.includes(itemValue)\n ? selected.filter((v) => v !== itemValue)\n : [...selected, itemValue],\n );\n }\n },\n [type, selected, setSelected],\n );\n\n return (\n <div\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n className={cn(\n \"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs\",\n className,\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, size, value: selected, toggle }}>\n {children}\n </ToggleGroupContext.Provider>\n </div>\n );\n}\n\nexport interface ToggleGroupItemProps\n extends Omit<React.ComponentProps<\"button\">, \"value\" | \"onChange\"> {\n value: string;\n variant?: ToggleVariant;\n size?: ToggleSize;\n}\n\nexport function ToggleGroupItem({\n className,\n children,\n value,\n variant,\n size,\n onClick,\n ...props\n}: ToggleGroupItemProps) {\n const context = React.useContext(ToggleGroupContext);\n const resolvedVariant = context.variant || variant || \"bare\";\n const resolvedSize = context.size || size || \"md\";\n const on = context.value.includes(value);\n\n return (\n <button\n type=\"button\"\n data-slot=\"toggle-group-item\"\n data-variant={resolvedVariant}\n data-size={resolvedSize}\n data-state={on ? \"on\" : \"off\"}\n aria-pressed={on}\n className={cn(\n toggleVariants({ variant: resolvedVariant, size: resolvedSize }),\n // `flex-auto`, not shadcn's `flex-1`: the group is `w-fit`, and basis-0 items\n // make Chrome split it into equal columns, so a longer label overflows its cell.\n \"min-w-0 flex-auto shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:-ml-px data-[variant=outline]:first:ml-0 data-[state=on]:z-10\",\n className,\n )}\n onClick={(e) => {\n onClick?.(e);\n context.toggle(value);\n }}\n {...props}\n >\n {children}\n </button>\n );\n}\n"],"mappings":";AAoFM;AAlFN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,OAGK;AASP,MAAM,qBAAqB,MAAM,cAAuC;AAAA,EACtE,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO,CAAC;AAAA,EACR,QAAQ,MAAM;AAAA,EAAC;AACjB,CAAC;AAYD,SAAS,QAAQ,GAA4C;AAC3D,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,SAAO,MAAM,QAAQ,CAAC,IAAI,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;AAClD;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAqB;AACnB,QAAM,CAAC,UAAU,WAAW,IAAI,qBAA+B;AAAA,IAC7D,GAAI,UAAU,SAAY,EAAE,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,IACvD,cAAc,QAAQ,YAAY;AAAA,IAClC,UAAU,CAAC,SACT,gBAAgB,SAAS,WAAY,KAAK,CAAC,KAAK,KAAM,IAAI;AAAA,EAC9D,CAAC;AAED,QAAM,SAAS,MAAM;AAAA,IACnB,CAAC,cAAsB;AACrB,UAAI,SAAS,UAAU;AACrB,oBAAY,SAAS,SAAS,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AAAA,MAC7D,OAAO;AACL;AAAA,UACE,SAAS,SAAS,SAAS,IACvB,SAAS,OAAO,CAAC,MAAM,MAAM,SAAS,IACtC,CAAC,GAAG,UAAU,SAAS;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,MAAM,UAAU,WAAW;AAAA,EAC9B;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,aAAW;AAAA,MACX,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,8BAAC,mBAAmB,UAAnB,EAA4B,OAAO,EAAE,SAAS,MAAM,OAAO,UAAU,OAAO,GAC1E,UACH;AAAA;AAAA,EACF;AAEJ;AASO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAyB;AACvB,QAAM,UAAU,MAAM,WAAW,kBAAkB;AACnD,QAAM,kBAAkB,QAAQ,WAAW,WAAW;AACtD,QAAM,eAAe,QAAQ,QAAQ,QAAQ;AAC7C,QAAM,KAAK,QAAQ,MAAM,SAAS,KAAK;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,aAAW;AAAA,MACX,cAAY,KAAK,OAAO;AAAA,MACxB,gBAAc;AAAA,MACd,WAAW;AAAA,QACT,eAAe,EAAE,SAAS,iBAAiB,MAAM,aAAa,CAAC;AAAA;AAAA;AAAA,QAG/D;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS,CAAC,MAAM;AACd,kBAAU,CAAC;AACX,gBAAQ,OAAO,KAAK;AAAA,MACtB;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -0,0 +1,21 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cn } from "../lib/cn.js";
4
+ function TopBar({ start, end, className, ...props }) {
5
+ return /* @__PURE__ */ jsxs(
6
+ "header",
7
+ {
8
+ "data-slot": "top-bar",
9
+ className: cn("flex h-14 items-center gap-3 border-b border-border bg-background px-8", className),
10
+ ...props,
11
+ children: [
12
+ /* @__PURE__ */ jsx("div", { "data-slot": "top-bar-start", className: "flex min-w-0 items-center gap-2", children: start }),
13
+ /* @__PURE__ */ jsx("div", { "data-slot": "top-bar-end", className: "ml-auto flex shrink-0 items-center gap-3", children: end })
14
+ ]
15
+ }
16
+ );
17
+ }
18
+ export {
19
+ TopBar
20
+ };
21
+ //# sourceMappingURL=top-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/top-bar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport interface TopBarProps extends React.ComponentProps<\"header\"> {\n /** The app switcher, or the service's name. */\n start?: React.ReactNode;\n /** Service stats, then an `AccountMenu` last. */\n end?: React.ReactNode;\n}\n\n/**\n * The wide screen's utility bar over the content column: who and where, never\n * product nav (that is the rail's). Layout only — `AppShell.topBar` pins it.\n */\nexport function TopBar({ start, end, className, ...props }: TopBarProps) {\n return (\n <header\n data-slot=\"top-bar\"\n className={cn(\"flex h-14 items-center gap-3 border-b border-border bg-background px-8\", className)}\n {...props}\n >\n <div data-slot=\"top-bar-start\" className=\"flex min-w-0 items-center gap-2\">\n {start}\n </div>\n <div data-slot=\"top-bar-end\" className=\"ml-auto flex shrink-0 items-center gap-3\">\n {end}\n </div>\n </header>\n );\n}\n"],"mappings":"AAgBI,SAKE,KALF;AAhBJ,YAAY,WAAW;AACvB,SAAS,UAAU;AAaZ,SAAS,OAAO,EAAE,OAAO,KAAK,WAAW,GAAG,MAAM,GAAgB;AACvE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,0EAA0E,SAAS;AAAA,MAChG,GAAG;AAAA,MAEJ;AAAA,4BAAC,SAAI,aAAU,iBAAgB,WAAU,mCACtC,iBACH;AAAA,QACA,oBAAC,SAAI,aAAU,eAAc,WAAU,4CACpC,eACH;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -4,9 +4,9 @@ const COMMAND_DIALOG_CONTENT = "fixed top-1/2 left-1/2 z-50 w-full max-w-lg -tra
4
4
  const COMMAND_DIALOG_COMMAND = "[&_[data-slot=command-input-wrapper]]:h-12 [&_[data-slot=command-input]]:h-12";
5
5
  const COMMAND_INPUT_WRAPPER = "flex h-9 items-center gap-2 border-b border-border px-3";
6
6
  const COMMAND_INPUT = "placeholder:text-ink-soft flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50";
7
- const COMMAND_LIST = "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto";
7
+ const COMMAND_LIST = "grid max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto";
8
8
  const COMMAND_EMPTY = "py-6 text-center text-sm";
9
- const COMMAND_GROUP = "text-ink [&_[data-slot=command-group-heading]]:text-ink-soft overflow-hidden p-1 [&_[data-slot=command-group-heading]]:px-2 [&_[data-slot=command-group-heading]]:py-1.5 [&_[data-slot=command-group-heading]]:text-xs [&_[data-slot=command-group-heading]]:font-medium";
9
+ const COMMAND_GROUP = "grid text-ink [&_[data-slot=command-group-heading]]:text-ink-soft overflow-hidden p-1 [&>[data-slot=command-group-heading]]:order-first [&_[data-slot=command-group-heading]]:px-2 [&_[data-slot=command-group-heading]]:py-1.5 [&_[data-slot=command-group-heading]]:text-xs [&_[data-slot=command-group-heading]]:font-medium";
10
10
  const COMMAND_ITEM = "data-[selected=true]:bg-hover data-[selected=true]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
11
11
  const COMMAND_SEPARATOR = "bg-border -mx-1 h-px";
12
12
  const COMMAND_SHORTCUT = "text-ink-soft ml-auto text-xs tracking-widest";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/command.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const COMMAND_ROOT = \"bg-popover text-ink flex h-full w-full flex-col overflow-hidden rounded-md\";\n\nexport const COMMAND_DIALOG_OVERLAY = \"fixed inset-0 z-50 bg-black/50\";\n\nexport const COMMAND_DIALOG_CONTENT = \"fixed top-1/2 left-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border border-border p-0 shadow-lg\";\n\nexport const COMMAND_DIALOG_COMMAND = \"[&_[data-slot=command-input-wrapper]]:h-12 [&_[data-slot=command-input]]:h-12\";\n\nexport const COMMAND_INPUT_WRAPPER = \"flex h-9 items-center gap-2 border-b border-border px-3\";\n\nexport const COMMAND_INPUT = \"placeholder:text-ink-soft flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\";\n\nexport const COMMAND_LIST = \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\";\n\nexport const COMMAND_EMPTY = \"py-6 text-center text-sm\";\n\nexport const COMMAND_GROUP = \"text-ink [&_[data-slot=command-group-heading]]:text-ink-soft overflow-hidden p-1 [&_[data-slot=command-group-heading]]:px-2 [&_[data-slot=command-group-heading]]:py-1.5 [&_[data-slot=command-group-heading]]:text-xs [&_[data-slot=command-group-heading]]:font-medium\";\n\nexport const COMMAND_ITEM = \"data-[selected=true]:bg-hover data-[selected=true]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const COMMAND_SEPARATOR = \"bg-border -mx-1 h-px\";\n\nexport const COMMAND_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n"],"mappings":"AAEO,MAAM,eAAe;AAErB,MAAM,yBAAyB;AAE/B,MAAM,yBAAyB;AAE/B,MAAM,yBAAyB;AAE/B,MAAM,wBAAwB;AAE9B,MAAM,gBAAgB;AAEtB,MAAM,eAAe;AAErB,MAAM,gBAAgB;AAEtB,MAAM,gBAAgB;AAEtB,MAAM,eAAe;AAErB,MAAM,oBAAoB;AAE1B,MAAM,mBAAmB;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/command.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const COMMAND_ROOT = \"bg-popover text-ink flex h-full w-full flex-col overflow-hidden rounded-md\";\n\nexport const COMMAND_DIALOG_OVERLAY = \"fixed inset-0 z-50 bg-black/50\";\n\nexport const COMMAND_DIALOG_CONTENT = \"fixed top-1/2 left-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border border-border p-0 shadow-lg\";\n\nexport const COMMAND_DIALOG_COMMAND = \"[&_[data-slot=command-input-wrapper]]:h-12 [&_[data-slot=command-input]]:h-12\";\n\nexport const COMMAND_INPUT_WRAPPER = \"flex h-9 items-center gap-2 border-b border-border px-3\";\n\nexport const COMMAND_INPUT = \"placeholder:text-ink-soft flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\";\n\nexport const COMMAND_LIST = \"grid max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\";\n\nexport const COMMAND_EMPTY = \"py-6 text-center text-sm\";\n\nexport const COMMAND_GROUP = \"grid text-ink [&_[data-slot=command-group-heading]]:text-ink-soft overflow-hidden p-1 [&>[data-slot=command-group-heading]]:order-first [&_[data-slot=command-group-heading]]:px-2 [&_[data-slot=command-group-heading]]:py-1.5 [&_[data-slot=command-group-heading]]:text-xs [&_[data-slot=command-group-heading]]:font-medium\";\n\nexport const COMMAND_ITEM = \"data-[selected=true]:bg-hover data-[selected=true]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const COMMAND_SEPARATOR = \"bg-border -mx-1 h-px\";\n\nexport const COMMAND_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n"],"mappings":"AAEO,MAAM,eAAe;AAErB,MAAM,yBAAyB;AAE/B,MAAM,yBAAyB;AAE/B,MAAM,yBAAyB;AAE/B,MAAM,wBAAwB;AAE9B,MAAM,gBAAgB;AAEtB,MAAM,eAAe;AAErB,MAAM,gBAAgB;AAEtB,MAAM,gBAAgB;AAEtB,MAAM,eAAe;AAErB,MAAM,oBAAoB;AAE1B,MAAM,mBAAmB;","names":[]}
@@ -1,6 +1,6 @@
1
1
  const CONTEXT_MENU_CONTENT = "bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md";
2
2
  const CONTEXT_MENU_SUB_CONTENT = "bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border border-border p-1 shadow-lg";
3
- const CONTEXT_MENU_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error data-[variant=destructive]:*:[svg]:!text-accent-error [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
3
+ const CONTEXT_MENU_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error-ink data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error-ink data-[variant=destructive]:*:[svg]:!text-accent-error-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
4
4
  const CONTEXT_MENU_CHECK_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
5
5
  const CONTEXT_MENU_SUB_TRIGGER = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
6
6
  const CONTEXT_MENU_LABEL = "text-ink px-2 py-1.5 text-sm font-medium data-[inset]:pl-8";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/context-menu.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const CONTEXT_MENU_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md\";\n\nexport const CONTEXT_MENU_SUB_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border border-border p-1 shadow-lg\";\n\nexport const CONTEXT_MENU_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error data-[variant=destructive]:*:[svg]:!text-accent-error [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const CONTEXT_MENU_CHECK_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const CONTEXT_MENU_SUB_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const CONTEXT_MENU_LABEL = \"text-ink px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\";\n\nexport const CONTEXT_MENU_SEPARATOR = \"bg-border -mx-1 my-1 h-px\";\n\nexport const CONTEXT_MENU_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n"],"mappings":"AAEO,MAAM,uBAAuB;AAE7B,MAAM,2BAA2B;AAEjC,MAAM,oBAAoB;AAE1B,MAAM,0BAA0B;AAEhC,MAAM,2BAA2B;AAEjC,MAAM,qBAAqB;AAE3B,MAAM,yBAAyB;AAE/B,MAAM,wBAAwB;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/context-menu.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const CONTEXT_MENU_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md\";\n\nexport const CONTEXT_MENU_SUB_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-md border border-border p-1 shadow-lg\";\n\nexport const CONTEXT_MENU_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error-ink data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error-ink data-[variant=destructive]:*:[svg]:!text-accent-error-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const CONTEXT_MENU_CHECK_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const CONTEXT_MENU_SUB_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const CONTEXT_MENU_LABEL = \"text-ink px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\";\n\nexport const CONTEXT_MENU_SEPARATOR = \"bg-border -mx-1 my-1 h-px\";\n\nexport const CONTEXT_MENU_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n"],"mappings":"AAEO,MAAM,uBAAuB;AAE7B,MAAM,2BAA2B;AAEjC,MAAM,oBAAoB;AAE1B,MAAM,0BAA0B;AAEhC,MAAM,2BAA2B;AAEjC,MAAM,qBAAqB;AAE3B,MAAM,yBAAyB;AAE/B,MAAM,wBAAwB;","names":[]}
@@ -1,6 +1,6 @@
1
1
  const DROPDOWN_MENU_CONTENT = "bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md";
2
2
  const DROPDOWN_MENU_SUB_CONTENT = "bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border border-border p-1 shadow-lg";
3
- const DROPDOWN_MENU_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error data-[variant=destructive]:*:[svg]:!text-accent-error [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
3
+ const DROPDOWN_MENU_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error-ink data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error-ink data-[variant=destructive]:*:[svg]:!text-accent-error-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
4
4
  const DROPDOWN_MENU_CHECK_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
5
5
  const DROPDOWN_MENU_SUB_TRIGGER = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
6
6
  const DROPDOWN_MENU_ITEM_INDICATOR = "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/dropdown-menu.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const DROPDOWN_MENU_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md\";\n\nexport const DROPDOWN_MENU_SUB_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border border-border p-1 shadow-lg\";\n\nexport const DROPDOWN_MENU_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error data-[variant=destructive]:*:[svg]:!text-accent-error [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const DROPDOWN_MENU_CHECK_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const DROPDOWN_MENU_SUB_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const DROPDOWN_MENU_ITEM_INDICATOR = \"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\";\n\nexport const DROPDOWN_MENU_LABEL = \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\";\n\nexport const DROPDOWN_MENU_SEPARATOR = \"bg-border -mx-1 my-1 h-px\";\n\nexport const DROPDOWN_MENU_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n"],"mappings":"AAEO,MAAM,wBAAwB;AAE9B,MAAM,4BAA4B;AAElC,MAAM,qBAAqB;AAE3B,MAAM,2BAA2B;AAEjC,MAAM,4BAA4B;AAElC,MAAM,+BAA+B;AAErC,MAAM,sBAAsB;AAE5B,MAAM,0BAA0B;AAEhC,MAAM,yBAAyB;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/dropdown-menu.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const DROPDOWN_MENU_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md\";\n\nexport const DROPDOWN_MENU_SUB_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border border-border p-1 shadow-lg\";\n\nexport const DROPDOWN_MENU_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error-ink data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error-ink data-[variant=destructive]:*:[svg]:!text-accent-error-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const DROPDOWN_MENU_CHECK_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const DROPDOWN_MENU_SUB_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink [&_svg:not([class*='text-'])]:text-ink-soft flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const DROPDOWN_MENU_ITEM_INDICATOR = \"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\";\n\nexport const DROPDOWN_MENU_LABEL = \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\";\n\nexport const DROPDOWN_MENU_SEPARATOR = \"bg-border -mx-1 my-1 h-px\";\n\nexport const DROPDOWN_MENU_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n"],"mappings":"AAEO,MAAM,wBAAwB;AAE9B,MAAM,4BAA4B;AAElC,MAAM,qBAAqB;AAE3B,MAAM,2BAA2B;AAEjC,MAAM,4BAA4B;AAElC,MAAM,+BAA+B;AAErC,MAAM,sBAAsB;AAE5B,MAAM,0BAA0B;AAEhC,MAAM,yBAAyB;","names":[]}
@@ -1,7 +1,7 @@
1
1
  const MENUBAR_ROOT = "bg-background flex h-9 items-center gap-1 rounded-md border border-border p-1 shadow-xs";
2
2
  const MENUBAR_TRIGGER = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none";
3
3
  const MENUBAR_CONTENT = "bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 absolute z-50 min-w-[12rem] overflow-hidden rounded-md border border-border p-1 shadow-md";
4
- const MENUBAR_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error data-[variant=destructive]:*:[svg]:!text-accent-error [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
4
+ const MENUBAR_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error-ink data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error-ink data-[variant=destructive]:*:[svg]:!text-accent-error-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
5
5
  const MENUBAR_CHECKBOX_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
6
6
  const MENUBAR_RADIO_ITEM = "focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
7
7
  const MENUBAR_ITEM_INDICATOR = "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/menubar.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const MENUBAR_ROOT = \"bg-background flex h-9 items-center gap-1 rounded-md border border-border p-1 shadow-xs\";\n\nexport const MENUBAR_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none\";\n\nexport const MENUBAR_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 absolute z-50 min-w-[12rem] overflow-hidden rounded-md border border-border p-1 shadow-md\";\n\nexport const MENUBAR_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error data-[variant=destructive]:*:[svg]:!text-accent-error [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const MENUBAR_CHECKBOX_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const MENUBAR_RADIO_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const MENUBAR_ITEM_INDICATOR = \"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\";\n\nexport const MENUBAR_LABEL = \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\";\n\nexport const MENUBAR_SEPARATOR = \"bg-border -mx-1 my-1 h-px\";\n\nexport const MENUBAR_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n\nexport const MENUBAR_SUB_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8\";\n\nexport const MENUBAR_SUB_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 absolute z-50 min-w-[8rem] overflow-hidden rounded-md border border-border p-1 shadow-lg\";\n"],"mappings":"AAEO,MAAM,eAAe;AAErB,MAAM,kBAAkB;AAExB,MAAM,kBAAkB;AAExB,MAAM,eAAe;AAErB,MAAM,wBAAwB;AAE9B,MAAM,qBAAqB;AAE3B,MAAM,yBAAyB;AAE/B,MAAM,gBAAgB;AAEtB,MAAM,oBAAoB;AAE1B,MAAM,mBAAmB;AAEzB,MAAM,sBAAsB;AAE5B,MAAM,sBAAsB;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/menubar.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const MENUBAR_ROOT = \"bg-background flex h-9 items-center gap-1 rounded-md border border-border p-1 shadow-xs\";\n\nexport const MENUBAR_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none\";\n\nexport const MENUBAR_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 absolute z-50 min-w-[12rem] overflow-hidden rounded-md border border-border p-1 shadow-md\";\n\nexport const MENUBAR_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[variant=destructive]:text-accent-error-ink data-[variant=destructive]:focus:bg-accent-error/10 data-[variant=destructive]:focus:text-accent-error-ink data-[variant=destructive]:*:[svg]:!text-accent-error-ink [&_svg:not([class*='text-'])]:text-ink-soft relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const MENUBAR_CHECKBOX_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const MENUBAR_RADIO_ITEM = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\";\n\nexport const MENUBAR_ITEM_INDICATOR = \"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\";\n\nexport const MENUBAR_LABEL = \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\";\n\nexport const MENUBAR_SEPARATOR = \"bg-border -mx-1 my-1 h-px\";\n\nexport const MENUBAR_SHORTCUT = \"text-ink-soft ml-auto text-xs tracking-widest\";\n\nexport const MENUBAR_SUB_TRIGGER = \"focus:bg-hover focus:text-ink focus-visible:inset-ring-2 focus-visible:inset-ring-ring data-[state=open]:bg-hover data-[state=open]:text-ink flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8\";\n\nexport const MENUBAR_SUB_CONTENT = \"bg-popover text-ink data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 absolute z-50 min-w-[8rem] overflow-hidden rounded-md border border-border p-1 shadow-lg\";\n"],"mappings":"AAEO,MAAM,eAAe;AAErB,MAAM,kBAAkB;AAExB,MAAM,kBAAkB;AAExB,MAAM,eAAe;AAErB,MAAM,wBAAwB;AAE9B,MAAM,qBAAqB;AAE3B,MAAM,yBAAyB;AAE/B,MAAM,gBAAgB;AAEtB,MAAM,oBAAoB;AAE1B,MAAM,mBAAmB;AAEzB,MAAM,sBAAsB;AAE5B,MAAM,sBAAsB;","names":[]}
@@ -1,21 +1,38 @@
1
1
  const TABLE_CONTAINER = "relative w-full overflow-x-auto";
2
2
  const TABLE = "w-full caption-bottom text-sm";
3
+ const tableVariants = {
4
+ "default": "[--table-px:initial] [--table-py:initial] [--table-head-ink:initial] [--table-head-text:initial] [--table-head-tracking:initial] [--table-head-case:initial]",
5
+ "card": "[--table-px:calc(var(--spacing)*5)] [--table-py:calc(var(--spacing)*3)] [--table-head-ink:var(--ink-soft)] [--table-head-text:var(--text-xs)] [--table-head-tracking:var(--tracking-wide)] [--table-head-case:uppercase] [&>thead>tr:hover]:bg-transparent"
6
+ };
7
+ const tableDensities = {
8
+ "default": "[--table-dense-py:initial] [--table-head-h:initial]",
9
+ "compact": "[--table-dense-py:calc(var(--spacing)*1.5)] [--table-head-h:calc(var(--spacing)*8)]"
10
+ };
11
+ const TABLE_CARD = "bg-card text-ink overflow-hidden rounded-xl border border-border shadow-sm";
3
12
  const TABLE_HEADER = "[&_tr]:border-b";
4
13
  const TABLE_BODY = "[&_tr:last-child]:border-0";
5
14
  const TABLE_FOOTER = "bg-muted/50 border-t border-border font-medium [&>tr]:last:border-b-0";
6
15
  const TABLE_ROW = "hover:bg-muted/50 data-[state=selected]:bg-muted border-b border-border transition-colors";
7
- const TABLE_HEAD = "text-ink h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]";
8
- const TABLE_CELL = "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]";
16
+ const TABLE_HEAD = "text-[color:var(--table-head-ink,var(--ink))] h-[var(--table-head-h,calc(var(--spacing)*10))] px-[var(--table-px,calc(var(--spacing)*2))] text-start align-middle font-medium whitespace-nowrap text-[length:var(--table-head-text)] tracking-[var(--table-head-tracking)] [text-transform:var(--table-head-case)] [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]";
17
+ const TABLE_CELL = "px-[var(--table-px,calc(var(--spacing)*2))] py-[var(--table-dense-py,var(--table-py,calc(var(--spacing)*2)))] align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]";
18
+ const tableAligns = {
19
+ "start": "text-start",
20
+ "end": "text-end tabular-nums"
21
+ };
9
22
  const TABLE_CAPTION = "text-ink-soft mt-4 text-sm";
10
23
  export {
11
24
  TABLE,
12
25
  TABLE_BODY,
13
26
  TABLE_CAPTION,
27
+ TABLE_CARD,
14
28
  TABLE_CELL,
15
29
  TABLE_CONTAINER,
16
30
  TABLE_FOOTER,
17
31
  TABLE_HEAD,
18
32
  TABLE_HEADER,
19
- TABLE_ROW
33
+ TABLE_ROW,
34
+ tableAligns,
35
+ tableDensities,
36
+ tableVariants
20
37
  };
21
38
  //# sourceMappingURL=table.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/table.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const TABLE_CONTAINER = \"relative w-full overflow-x-auto\";\n\nexport const TABLE = \"w-full caption-bottom text-sm\";\n\nexport const TABLE_HEADER = \"[&_tr]:border-b\";\n\nexport const TABLE_BODY = \"[&_tr:last-child]:border-0\";\n\nexport const TABLE_FOOTER = \"bg-muted/50 border-t border-border font-medium [&>tr]:last:border-b-0\";\n\nexport const TABLE_ROW = \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b border-border transition-colors\";\n\nexport const TABLE_HEAD = \"text-ink h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\";\n\nexport const TABLE_CELL = \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\";\n\nexport const TABLE_CAPTION = \"text-ink-soft mt-4 text-sm\";\n"],"mappings":"AAEO,MAAM,kBAAkB;AAExB,MAAM,QAAQ;AAEd,MAAM,eAAe;AAErB,MAAM,aAAa;AAEnB,MAAM,eAAe;AAErB,MAAM,YAAY;AAElB,MAAM,aAAa;AAEnB,MAAM,aAAa;AAEnB,MAAM,gBAAgB;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/table.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const TABLE_CONTAINER = \"relative w-full overflow-x-auto\";\n\nexport const TABLE = \"w-full caption-bottom text-sm\";\n\nexport const tableVariants = {\n \"default\": \"[--table-px:initial] [--table-py:initial] [--table-head-ink:initial] [--table-head-text:initial] [--table-head-tracking:initial] [--table-head-case:initial]\",\n \"card\": \"[--table-px:calc(var(--spacing)*5)] [--table-py:calc(var(--spacing)*3)] [--table-head-ink:var(--ink-soft)] [--table-head-text:var(--text-xs)] [--table-head-tracking:var(--tracking-wide)] [--table-head-case:uppercase] [&>thead>tr:hover]:bg-transparent\",\n} as const;\nexport type TableVariant = keyof typeof tableVariants;\n\nexport const tableDensities = {\n \"default\": \"[--table-dense-py:initial] [--table-head-h:initial]\",\n \"compact\": \"[--table-dense-py:calc(var(--spacing)*1.5)] [--table-head-h:calc(var(--spacing)*8)]\",\n} as const;\nexport type TableDensity = keyof typeof tableDensities;\n\nexport const TABLE_CARD = \"bg-card text-ink overflow-hidden rounded-xl border border-border shadow-sm\";\n\nexport const TABLE_HEADER = \"[&_tr]:border-b\";\n\nexport const TABLE_BODY = \"[&_tr:last-child]:border-0\";\n\nexport const TABLE_FOOTER = \"bg-muted/50 border-t border-border font-medium [&>tr]:last:border-b-0\";\n\nexport const TABLE_ROW = \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b border-border transition-colors\";\n\nexport const TABLE_HEAD = \"text-[color:var(--table-head-ink,var(--ink))] h-[var(--table-head-h,calc(var(--spacing)*10))] px-[var(--table-px,calc(var(--spacing)*2))] text-start align-middle font-medium whitespace-nowrap text-[length:var(--table-head-text)] tracking-[var(--table-head-tracking)] [text-transform:var(--table-head-case)] [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\";\n\nexport const TABLE_CELL = \"px-[var(--table-px,calc(var(--spacing)*2))] py-[var(--table-dense-py,var(--table-py,calc(var(--spacing)*2)))] align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\";\n\nexport const tableAligns = {\n \"start\": \"text-start\",\n \"end\": \"text-end tabular-nums\",\n} as const;\nexport type TableAlign = keyof typeof tableAligns;\n\nexport const TABLE_CAPTION = \"text-ink-soft mt-4 text-sm\";\n"],"mappings":"AAEO,MAAM,kBAAkB;AAExB,MAAM,QAAQ;AAEd,MAAM,gBAAgB;AAAA,EAC3B,WAAW;AAAA,EACX,QAAQ;AACV;AAGO,MAAM,iBAAiB;AAAA,EAC5B,WAAW;AAAA,EACX,WAAW;AACb;AAGO,MAAM,aAAa;AAEnB,MAAM,eAAe;AAErB,MAAM,aAAa;AAEnB,MAAM,eAAe;AAErB,MAAM,YAAY;AAElB,MAAM,aAAa;AAEnB,MAAM,aAAa;AAEnB,MAAM,cAAc;AAAA,EACzB,SAAS;AAAA,EACT,OAAO;AACT;AAGO,MAAM,gBAAgB;","names":[]}
@@ -1,7 +1,7 @@
1
- const TOGGLE_BASE = "inline-flex items-center justify-center gap-2 rounded-[var(--control-radius)] text-sm font-medium hover:bg-muted hover:text-ink-soft disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-hover data-[state=on]:text-ink [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-accent-error/20 aria-invalid:border-accent-error whitespace-nowrap";
1
+ const TOGGLE_BASE = "inline-flex items-center justify-center gap-2 rounded-[var(--control-radius)] text-sm font-medium hover:bg-muted hover:text-ink-soft disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-primary data-[state=on]:text-on-primary [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring outline-none transition-[color,box-shadow] aria-invalid:ring-accent-error/20 aria-invalid:border-accent-error whitespace-nowrap focus-visible:ring-0 focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring";
2
2
  const toggleVariantClasses = {
3
3
  "bare": "bg-transparent",
4
- "outline": "border border-input bg-transparent shadow-xs hover:bg-hover hover:text-ink"
4
+ "outline": "border border-input bg-transparent shadow-xs hover:bg-hover hover:text-ink data-[state=on]:border-primary"
5
5
  };
6
6
  const toggleSizeClasses = {
7
7
  "md": "h-9 px-2 min-w-9",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/toggle.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const TOGGLE_BASE = \"inline-flex items-center justify-center gap-2 rounded-[var(--control-radius)] text-sm font-medium hover:bg-muted hover:text-ink-soft disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-hover data-[state=on]:text-ink [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-accent-error/20 aria-invalid:border-accent-error whitespace-nowrap\";\n\nexport const toggleVariantClasses = {\n \"bare\": \"bg-transparent\",\n \"outline\": \"border border-input bg-transparent shadow-xs hover:bg-hover hover:text-ink\",\n} as const;\nexport type ToggleVariant = keyof typeof toggleVariantClasses;\n\nexport const toggleSizeClasses = {\n \"md\": \"h-9 px-2 min-w-9\",\n \"xs\": \"h-7 px-1 min-w-7\",\n \"sm\": \"h-8 px-1.5 min-w-8\",\n \"lg\": \"h-10 px-2.5 min-w-10\",\n \"xl\": \"h-12 px-3 min-w-12\",\n} as const;\nexport type ToggleSize = keyof typeof toggleSizeClasses;\n"],"mappings":"AAEO,MAAM,cAAc;AAEpB,MAAM,uBAAuB;AAAA,EAClC,QAAQ;AAAA,EACR,WAAW;AACb;AAGO,MAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/toggle.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const TOGGLE_BASE = \"inline-flex items-center justify-center gap-2 rounded-[var(--control-radius)] text-sm font-medium hover:bg-muted hover:text-ink-soft disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-primary data-[state=on]:text-on-primary [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring outline-none transition-[color,box-shadow] aria-invalid:ring-accent-error/20 aria-invalid:border-accent-error whitespace-nowrap focus-visible:ring-0 focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\";\n\nexport const toggleVariantClasses = {\n \"bare\": \"bg-transparent\",\n \"outline\": \"border border-input bg-transparent shadow-xs hover:bg-hover hover:text-ink data-[state=on]:border-primary\",\n} as const;\nexport type ToggleVariant = keyof typeof toggleVariantClasses;\n\nexport const toggleSizeClasses = {\n \"md\": \"h-9 px-2 min-w-9\",\n \"xs\": \"h-7 px-1 min-w-7\",\n \"sm\": \"h-8 px-1.5 min-w-8\",\n \"lg\": \"h-10 px-2.5 min-w-10\",\n \"xl\": \"h-12 px-3 min-w-12\",\n} as const;\nexport type ToggleSize = keyof typeof toggleSizeClasses;\n"],"mappings":"AAEO,MAAM,cAAc;AAEpB,MAAM,uBAAuB;AAAA,EAClC,QAAQ;AAAA,EACR,WAAW;AACb;AAGO,MAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;","names":[]}