@krizaka/ui 2.0.0-beta.1 → 2.0.0-beta.3

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 (210) hide show
  1. package/README.md +44 -3
  2. package/dist/alert.d.ts +2 -0
  3. package/dist/alert.js.map +1 -1
  4. package/dist/avatar.d.ts +5 -0
  5. package/dist/avatar.js.map +1 -1
  6. package/dist/badge.d.ts +12 -0
  7. package/dist/badge.js.map +1 -1
  8. package/dist/button-8La7l0V4.d.ts +83 -0
  9. package/dist/button.d.ts +19 -0
  10. package/dist/button.js.map +1 -1
  11. package/dist/card.d.ts +24 -1
  12. package/dist/card.js +1 -1
  13. package/dist/card.js.map +1 -1
  14. package/dist/checkbox.d.ts +52 -0
  15. package/dist/checkbox.js +42 -0
  16. package/dist/checkbox.js.map +1 -0
  17. package/dist/chip.d.ts +120 -0
  18. package/dist/chip.js +93 -0
  19. package/dist/chip.js.map +1 -0
  20. package/dist/chunk-3X5MVH54.js +121 -0
  21. package/dist/chunk-3X5MVH54.js.map +1 -0
  22. package/dist/{chunk-RLOXWF2G.js → chunk-5AXLA4LK.js} +1 -1
  23. package/dist/chunk-5AXLA4LK.js.map +1 -0
  24. package/dist/{chunk-CPMZS4XA.js → chunk-FJDSLNXK.js} +1 -1
  25. package/dist/chunk-FJDSLNXK.js.map +1 -0
  26. package/dist/{chunk-QRG5RYEI.js → chunk-ZUD4U22H.js} +1 -1
  27. package/dist/chunk-ZUD4U22H.js.map +1 -0
  28. package/dist/cn.d.ts +3 -0
  29. package/dist/cn.js +1 -1
  30. package/dist/command.d.ts +159 -0
  31. package/dist/command.js +111 -0
  32. package/dist/command.js.map +1 -0
  33. package/dist/confirm-button.d.ts +23 -0
  34. package/dist/confirm-button.js +85 -0
  35. package/dist/confirm-button.js.map +1 -0
  36. package/dist/countdown.d.ts +3 -0
  37. package/dist/countdown.js.map +1 -1
  38. package/dist/dialog-GQ4Nvuyf.d.ts +157 -0
  39. package/dist/dialog.d.ts +12 -131
  40. package/dist/dialog.js +27 -91
  41. package/dist/dialog.js.map +1 -1
  42. package/dist/dropdown-menu.d.ts +1 -0
  43. package/dist/dropdown-menu.js +1 -1
  44. package/dist/dropdown-menu.js.map +1 -1
  45. package/dist/empty-state.d.ts +2 -0
  46. package/dist/empty-state.js.map +1 -1
  47. package/dist/field.js +1 -1
  48. package/dist/kbd.d.ts +7 -1
  49. package/dist/kbd.js.map +1 -1
  50. package/dist/motion.css +7 -1
  51. package/dist/page-header.d.ts +2 -0
  52. package/dist/page-header.js.map +1 -1
  53. package/dist/popover.js +1 -1
  54. package/dist/progress.d.ts +92 -0
  55. package/dist/progress.js +85 -0
  56. package/dist/progress.js.map +1 -0
  57. package/dist/radio-group.d.ts +77 -0
  58. package/dist/radio-group.js +48 -0
  59. package/dist/radio-group.js.map +1 -0
  60. package/dist/skeleton.d.ts +7 -1
  61. package/dist/skeleton.js.map +1 -1
  62. package/dist/slider.d.ts +90 -0
  63. package/dist/slider.js +82 -0
  64. package/dist/slider.js.map +1 -0
  65. package/dist/spinner.d.ts +5 -0
  66. package/dist/spinner.js.map +1 -1
  67. package/dist/stat.d.ts +2 -0
  68. package/dist/stat.js.map +1 -1
  69. package/dist/switch.d.ts +76 -0
  70. package/dist/switch.js +38 -0
  71. package/dist/switch.js.map +1 -0
  72. package/dist/tabs.d.ts +86 -0
  73. package/dist/tabs.js +60 -0
  74. package/dist/tabs.js.map +1 -0
  75. package/dist/theme.d.ts +11 -60
  76. package/dist/theme.js +4 -2
  77. package/dist/theme.js.map +1 -1
  78. package/dist/toast.js +1 -1
  79. package/dist/tooltip.d.ts +3 -0
  80. package/dist/tooltip.js +1 -1
  81. package/dist/tooltip.js.map +1 -1
  82. package/package.json +146 -6
  83. package/registry/alert.json +59 -0
  84. package/registry/avatar.json +114 -0
  85. package/registry/badge.json +59 -0
  86. package/registry/button.json +115 -0
  87. package/registry/card.json +154 -0
  88. package/registry/checkbox.json +46 -0
  89. package/registry/chip.json +164 -0
  90. package/registry/cn.json +21 -0
  91. package/registry/command.json +162 -0
  92. package/registry/confirm-button.json +104 -0
  93. package/registry/countdown.json +84 -0
  94. package/registry/demos/alert.d.ts +5 -0
  95. package/registry/demos/alert.js +12 -0
  96. package/registry/demos/alert.tsx +15 -0
  97. package/registry/demos/avatar.d.ts +5 -0
  98. package/registry/demos/avatar.js +14 -0
  99. package/registry/demos/avatar.tsx +13 -0
  100. package/registry/demos/badge.d.ts +5 -0
  101. package/registry/demos/badge.js +11 -0
  102. package/registry/demos/badge.tsx +5 -0
  103. package/registry/demos/button.d.ts +5 -0
  104. package/registry/demos/button.js +11 -0
  105. package/registry/demos/button.tsx +5 -0
  106. package/registry/demos/card.d.ts +5 -0
  107. package/registry/demos/card.js +30 -0
  108. package/registry/demos/card.tsx +37 -0
  109. package/registry/demos/checkbox.d.ts +5 -0
  110. package/registry/demos/checkbox.js +11 -0
  111. package/registry/demos/checkbox.tsx +5 -0
  112. package/registry/demos/chip.d.ts +5 -0
  113. package/registry/demos/chip.js +15 -0
  114. package/registry/demos/chip.tsx +11 -0
  115. package/registry/demos/cn.d.ts +7 -0
  116. package/registry/demos/cn.js +17 -0
  117. package/registry/demos/cn.tsx +9 -0
  118. package/registry/demos/command.d.ts +5 -0
  119. package/registry/demos/command.js +32 -0
  120. package/registry/demos/command.tsx +28 -0
  121. package/registry/demos/confirm-button.d.ts +5 -0
  122. package/registry/demos/confirm-button.js +12 -0
  123. package/registry/demos/confirm-button.tsx +13 -0
  124. package/registry/demos/countdown.d.ts +5 -0
  125. package/registry/demos/countdown.js +13 -0
  126. package/registry/demos/countdown.tsx +10 -0
  127. package/registry/demos/dialog.d.ts +7 -0
  128. package/registry/demos/dialog.js +29 -0
  129. package/registry/demos/dialog.tsx +31 -0
  130. package/registry/demos/dropdown-menu.d.ts +7 -0
  131. package/registry/demos/dropdown-menu.js +36 -0
  132. package/registry/demos/dropdown-menu.tsx +27 -0
  133. package/registry/demos/empty-state.d.ts +5 -0
  134. package/registry/demos/empty-state.js +15 -0
  135. package/registry/demos/empty-state.tsx +12 -0
  136. package/registry/demos/field.d.ts +5 -0
  137. package/registry/demos/field.js +15 -0
  138. package/registry/demos/field.tsx +11 -0
  139. package/registry/demos/kbd.d.ts +5 -0
  140. package/registry/demos/kbd.js +11 -0
  141. package/registry/demos/kbd.tsx +5 -0
  142. package/registry/demos/page-header.d.ts +5 -0
  143. package/registry/demos/page-header.js +11 -0
  144. package/registry/demos/page-header.tsx +5 -0
  145. package/registry/demos/popover.d.ts +7 -0
  146. package/registry/demos/popover.js +25 -0
  147. package/registry/demos/popover.tsx +31 -0
  148. package/registry/demos/progress.d.ts +5 -0
  149. package/registry/demos/progress.js +11 -0
  150. package/registry/demos/progress.tsx +5 -0
  151. package/registry/demos/radio-group.d.ts +5 -0
  152. package/registry/demos/radio-group.js +16 -0
  153. package/registry/demos/radio-group.tsx +14 -0
  154. package/registry/demos/separator.d.ts +5 -0
  155. package/registry/demos/separator.js +15 -0
  156. package/registry/demos/separator.tsx +11 -0
  157. package/registry/demos/skeleton.d.ts +5 -0
  158. package/registry/demos/skeleton.js +20 -0
  159. package/registry/demos/skeleton.tsx +16 -0
  160. package/registry/demos/slider.d.ts +5 -0
  161. package/registry/demos/slider.js +11 -0
  162. package/registry/demos/slider.tsx +5 -0
  163. package/registry/demos/slot.d.ts +5 -0
  164. package/registry/demos/slot.js +14 -0
  165. package/registry/demos/slot.tsx +13 -0
  166. package/registry/demos/spinner.d.ts +5 -0
  167. package/registry/demos/spinner.js +11 -0
  168. package/registry/demos/spinner.tsx +5 -0
  169. package/registry/demos/stat.d.ts +5 -0
  170. package/registry/demos/stat.js +11 -0
  171. package/registry/demos/stat.tsx +5 -0
  172. package/registry/demos/switch.d.ts +5 -0
  173. package/registry/demos/switch.js +11 -0
  174. package/registry/demos/switch.tsx +5 -0
  175. package/registry/demos/tabs.d.ts +5 -0
  176. package/registry/demos/tabs.js +22 -0
  177. package/registry/demos/tabs.tsx +28 -0
  178. package/registry/demos/theme.d.ts +5 -0
  179. package/registry/demos/theme.js +11 -0
  180. package/registry/demos/theme.tsx +9 -0
  181. package/registry/demos/toast.d.ts +8 -0
  182. package/registry/demos/toast.js +29 -0
  183. package/registry/demos/toast.tsx +31 -0
  184. package/registry/demos/tooltip.d.ts +7 -0
  185. package/registry/demos/tooltip.js +15 -0
  186. package/registry/demos/tooltip.tsx +15 -0
  187. package/registry/dialog.json +218 -0
  188. package/registry/dropdown-menu.json +63 -0
  189. package/registry/empty-state.json +59 -0
  190. package/registry/field.json +66 -0
  191. package/registry/index.json +320 -0
  192. package/registry/kbd.json +38 -0
  193. package/registry/page-header.json +66 -0
  194. package/registry/popover.json +44 -0
  195. package/registry/progress.json +80 -0
  196. package/registry/radio-group.json +64 -0
  197. package/registry/separator.json +25 -0
  198. package/registry/skeleton.json +38 -0
  199. package/registry/slider.json +95 -0
  200. package/registry/slot.json +31 -0
  201. package/registry/spinner.json +45 -0
  202. package/registry/stat.json +66 -0
  203. package/registry/switch.json +53 -0
  204. package/registry/tabs.json +44 -0
  205. package/registry/theme.json +78 -0
  206. package/registry/toast.json +54 -0
  207. package/registry/tooltip.json +91 -0
  208. package/dist/chunk-CPMZS4XA.js.map +0 -1
  209. package/dist/chunk-QRG5RYEI.js.map +0 -1
  210. package/dist/chunk-RLOXWF2G.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ "use client";
2
+ import {
3
+ DialogContent
4
+ } from "./chunk-3X5MVH54.js";
5
+ import "./chunk-ZUD4U22H.js";
6
+ import {
7
+ cn
8
+ } from "./chunk-5AXLA4LK.js";
9
+
10
+ // src/command/command.tsx
11
+ import { Command as CommandPrimitive } from "cmdk";
12
+ import { Dialog as DialogPrimitive } from "radix-ui";
13
+ import { tv } from "tailwind-variants";
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+ var command = tv({
16
+ slots: {
17
+ root: "flex h-full w-full flex-col overflow-hidden bg-surface-1 text-fg",
18
+ inputWrap: "flex items-center gap-3 border-b border-border-default px-4",
19
+ icon: "h-5 w-5 shrink-0 text-fg-secondary",
20
+ input: "h-13 w-full min-w-0 flex-1 bg-transparent text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:text-base",
21
+ list: "max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2",
22
+ empty: "px-3 py-8 text-center text-sm text-fg-secondary",
23
+ loading: "px-3 py-6 text-center text-sm text-fg-secondary",
24
+ group: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-fg-secondary",
25
+ item: "relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40",
26
+ separator: "-mx-2 my-1 h-px bg-border-subtle",
27
+ shortcut: "ml-auto text-xs tracking-widest text-fg-secondary"
28
+ }
29
+ });
30
+ var s = command();
31
+ function SearchIcon({ className }) {
32
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className, fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
33
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
34
+ /* @__PURE__ */ jsx("path", { d: "m20 20-3.5-3.5" })
35
+ ] });
36
+ }
37
+ function CommandRoot({ className, ...props }) {
38
+ return /* @__PURE__ */ jsx(CommandPrimitive, { className: s.root({ className }), ...props });
39
+ }
40
+ function CommandInput({ className, placeholder, trailing, ...props }) {
41
+ return /* @__PURE__ */ jsxs("div", { className: s.inputWrap(), "cmdk-input-wrapper": "", children: [
42
+ /* @__PURE__ */ jsx(SearchIcon, { className: s.icon() }),
43
+ /* @__PURE__ */ jsx(CommandPrimitive.Input, { placeholder, className: s.input({ className }), ...props }),
44
+ trailing
45
+ ] });
46
+ }
47
+ function CommandList({ className, ...props }) {
48
+ return /* @__PURE__ */ jsx(CommandPrimitive.List, { className: s.list({ className }), ...props });
49
+ }
50
+ function CommandEmpty({ className, emptyLabel, ...props }) {
51
+ return /* @__PURE__ */ jsx(CommandPrimitive.Empty, { className: s.empty({ className }), ...props, children: emptyLabel });
52
+ }
53
+ function CommandLoading({ className, ...props }) {
54
+ return /* @__PURE__ */ jsx(CommandPrimitive.Loading, { className: s.loading({ className }), ...props });
55
+ }
56
+ function CommandGroup({ className, ...props }) {
57
+ return /* @__PURE__ */ jsx(CommandPrimitive.Group, { className: s.group({ className }), ...props });
58
+ }
59
+ function CommandItem({ className, ...props }) {
60
+ return /* @__PURE__ */ jsx(CommandPrimitive.Item, { className: s.item({ className }), ...props });
61
+ }
62
+ function CommandSeparator({ className, ...props }) {
63
+ return /* @__PURE__ */ jsx("div", { role: "none", className: s.separator({ className }), ...props });
64
+ }
65
+ function CommandShortcut({ className, ...props }) {
66
+ return /* @__PURE__ */ jsx("span", { className: s.shortcut({ className }), ...props });
67
+ }
68
+ var Command = {
69
+ Root: CommandRoot,
70
+ Input: CommandInput,
71
+ List: CommandList,
72
+ Empty: CommandEmpty,
73
+ Loading: CommandLoading,
74
+ Group: CommandGroup,
75
+ Item: CommandItem,
76
+ Separator: CommandSeparator,
77
+ Shortcut: CommandShortcut
78
+ };
79
+ function CommandDialog({ open, defaultOpen, onOpenChange, footer, contentProps, label, className, children, ...props }) {
80
+ const { className: contentClassName, ...content } = contentProps ?? {};
81
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { open, defaultOpen, onOpenChange, children: /* @__PURE__ */ jsxs(
82
+ DialogContent,
83
+ {
84
+ hideClose: true,
85
+ size: "lg",
86
+ "aria-describedby": void 0,
87
+ className: cn("top-[12dvh] translate-y-0 sm:top-[14dvh]", contentClassName),
88
+ ...content,
89
+ children: [
90
+ /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: "sr-only", children: label }),
91
+ /* @__PURE__ */ jsx(CommandRoot, { label, className, ...props, children }),
92
+ footer
93
+ ]
94
+ }
95
+ ) });
96
+ }
97
+ export {
98
+ Command,
99
+ CommandDialog,
100
+ CommandEmpty,
101
+ CommandGroup,
102
+ CommandInput,
103
+ CommandItem,
104
+ CommandList,
105
+ CommandLoading,
106
+ CommandRoot,
107
+ CommandSeparator,
108
+ CommandShortcut,
109
+ command
110
+ };
111
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/command/command.tsx"],"sourcesContent":["// Client. A command palette on cmdk: the combobox / listbox roles, the active option (aria-activedescendant), the\n// arrows, Home / End, Enter, and the filtering (turn it off with `shouldFilter={false}` when the server searches).\n// `CommandDialog` puts it in the platform's Dialog. Words arrive as props.\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { DialogContent, type DialogContentProps } from \"../dialog/dialog\";\n\nexport const command = tv({\n slots: {\n root: \"flex h-full w-full flex-col overflow-hidden bg-surface-1 text-fg\",\n inputWrap: \"flex items-center gap-3 border-b border-border-default px-4\",\n icon: \"h-5 w-5 shrink-0 text-fg-secondary\",\n input:\n \"h-13 w-full min-w-0 flex-1 bg-transparent text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed disabled:opacity-50 sm:text-base\",\n list: \"max-h-[min(60dvh,26rem)] scroll-py-2 overflow-y-auto overscroll-contain p-2\",\n empty: \"px-3 py-8 text-center text-sm text-fg-secondary\",\n loading: \"px-3 py-6 text-center text-sm text-fg-secondary\",\n group:\n \"[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-xs \" +\n \"[&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:tracking-wider [&_[cmdk-group-heading]]:text-fg-secondary\",\n item:\n \"relative flex cursor-pointer select-none items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-fg outline-hidden transition-colors \" +\n \"before:absolute before:inset-y-2 before:left-0 before:w-0.5 before:rounded-full before:bg-transparent \" +\n \"data-[selected=true]:bg-surface-2 data-[selected=true]:before:bg-accent data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40\",\n separator: \"-mx-2 my-1 h-px bg-border-subtle\",\n shortcut: \"ml-auto text-xs tracking-widest text-fg-secondary\",\n },\n});\nconst s = command();\n\nfunction SearchIcon({ className }: { className?: string }) {\n return (\n <svg viewBox=\"0 0 24 24\" className={className} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n );\n}\n\nexport type CommandRootProps = React.ComponentProps<typeof CommandPrimitive> & {\n /** The accessible name of the palette — passed translated (\"Search\", \"Commands\"). */\n label: string;\n};\n\n/** The palette: `value` / `onValueChange` (the active item), `shouldFilter`, `filter`, `loop`. */\nexport function CommandRoot({ className, ...props }: CommandRootProps) {\n return <CommandPrimitive className={s.root({ className })} {...props} />;\n}\n\nexport type CommandInputProps = Omit<React.ComponentProps<typeof CommandPrimitive.Input>, \"placeholder\"> & {\n /** What to type — passed translated. The input is named by the palette's `label`. */\n placeholder: string;\n /** After the input, inside the bar: a spinner, a clear button. */\n trailing?: React.ReactNode;\n};\n\n/** The search field (`value` / `onValueChange` for the query), with a magnifier. */\nexport function CommandInput({ className, placeholder, trailing, ...props }: CommandInputProps) {\n return (\n <div className={s.inputWrap()} cmdk-input-wrapper=\"\">\n <SearchIcon className={s.icon()} />\n <CommandPrimitive.Input placeholder={placeholder} className={s.input({ className })} {...props} />\n {trailing}\n </div>\n );\n}\n\nexport type CommandListProps = React.ComponentProps<typeof CommandPrimitive.List> & {\n /** The accessible name of the list of results — passed translated (\"Suggestions\", \"Results\"). */\n label: string;\n};\n\nexport function CommandList({ className, ...props }: CommandListProps) {\n return <CommandPrimitive.List className={s.list({ className })} {...props} />;\n}\n\nexport type CommandEmptyProps = Omit<React.ComponentProps<typeof CommandPrimitive.Empty>, \"children\"> & {\n /** Shown when nothing matches — passed translated. */\n emptyLabel: React.ReactNode;\n};\n\n/** Shown by cmdk only when no item matches. */\nexport function CommandEmpty({ className, emptyLabel, ...props }: CommandEmptyProps) {\n return (\n <CommandPrimitive.Empty className={s.empty({ className })} {...props}>\n {emptyLabel}\n </CommandPrimitive.Empty>\n );\n}\n\n/** While results load (`label` is announced). */\nexport function CommandLoading({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Loading>) {\n return <CommandPrimitive.Loading className={s.loading({ className })} {...props} />;\n}\n\n/** A group of items under a `heading`. */\nexport function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return <CommandPrimitive.Group className={s.group({ className })} {...props} />;\n}\n\n/** An option: `onSelect` on Enter or click, `value` and `keywords` for the filter, `disabled`. */\nexport function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return <CommandPrimitive.Item className={s.item({ className })} {...props} />;\n}\n\n/** A line between groups. Decorative (`role=\"none\"`): cmdk's own separator is a role a listbox may not hold (axe). */\nexport function CommandSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div role=\"none\" className={s.separator({ className })} {...props} />;\n}\n\n/** A keyboard hint at the end of an item. */\nexport function CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return <span className={s.shortcut({ className })} {...props} />;\n}\n\n/** `Command.Root/Input/List/Empty/Loading/Group/Item/Separator/Shortcut`. */\nexport const Command = {\n Root: CommandRoot,\n Input: CommandInput,\n List: CommandList,\n Empty: CommandEmpty,\n Loading: CommandLoading,\n Group: CommandGroup,\n Item: CommandItem,\n Separator: CommandSeparator,\n Shortcut: CommandShortcut,\n};\n\nexport type CommandDialogProps = Omit<CommandRootProps, \"title\"> & {\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes (Escape, a click outside, a shortcut of the product). */\n onOpenChange?: (open: boolean) => void;\n /** Under the palette, inside the dialog: shortcuts, a \"see all results\" link. */\n footer?: React.ReactNode;\n /** Passed to `Dialog.Content`: `size`, `container`, `className` of the dialog. */\n contentProps?: Omit<Extract<DialogContentProps, { hideClose: true }>, \"hideClose\" | \"children\" | \"placement\">;\n};\n\n/**\n * The palette in a dialog (Radix: focus trap, Escape, focus return). The dialog is named by `label`; it has no close\n * button — Escape and a click outside close it — and the input takes the focus when it opens.\n */\nexport function CommandDialog({ open, defaultOpen, onOpenChange, footer, contentProps, label, className, children, ...props }: CommandDialogProps) {\n const { className: contentClassName, ...content } = contentProps ?? {};\n return (\n <DialogPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <DialogContent\n hideClose\n size=\"lg\"\n aria-describedby={undefined}\n className={cn(\"top-[12dvh] translate-y-0 sm:top-[14dvh]\", contentClassName)}\n {...content}\n >\n <DialogPrimitive.Title className=\"sr-only\">{label}</DialogPrimitive.Title>\n <CommandRoot label={label} className={className} {...props}>\n {children}\n </CommandRoot>\n {footer}\n </DialogContent>\n </DialogPrimitive.Root>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { B as ButtonProps } from './button-8La7l0V4.js';
3
+ import 'tailwind-variants';
4
+
5
+ declare const confirmArmed = "border border-danger bg-danger/20 text-fg hover:border-danger hover:bg-danger/30";
6
+ type ConfirmButtonProps = Omit<ButtonProps, "onClick" | "asChild"> & {
7
+ /** What the second press does, in words — shown and announced once armed ("Delete for good?"). Passed translated. */
8
+ confirmLabel: string;
9
+ /** The accessible name while idle, for an icon-only button (the confirm label names it once armed). */
10
+ label?: string;
11
+ /** Runs on the second press. */
12
+ onConfirm: () => void;
13
+ /** Disarms after this many milliseconds (4000 by default). */
14
+ timeoutMs?: number;
15
+ /** What it shows once armed (default: its children, then `confirmLabel`). */
16
+ armedContent?: React.ReactNode;
17
+ /** Notified when it arms and disarms. */
18
+ onArmedChange?: (armed: boolean) => void;
19
+ };
20
+ /** A two-step button: press to arm, press again within `timeoutMs` to confirm. State: `data-armed`. */
21
+ declare function ConfirmButton({ confirmLabel, label, onConfirm, timeoutMs, onArmedChange, armedContent, variant, className, children, onBlur, onKeyDown, ...props }: ConfirmButtonProps): React.JSX.Element;
22
+
23
+ export { ConfirmButton, type ConfirmButtonProps, confirmArmed };
@@ -0,0 +1,85 @@
1
+ "use client";
2
+ import {
3
+ Button
4
+ } from "./chunk-ZUD4U22H.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-5AXLA4LK.js";
8
+
9
+ // src/confirm-button/confirm-button.tsx
10
+ import { VisuallyHidden } from "radix-ui";
11
+ import * as React from "react";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ var confirmArmed = "border border-danger bg-danger/20 text-fg hover:border-danger hover:bg-danger/30";
14
+ function ConfirmButton({
15
+ confirmLabel,
16
+ label,
17
+ onConfirm,
18
+ timeoutMs = 4e3,
19
+ onArmedChange,
20
+ armedContent,
21
+ variant = "ghost",
22
+ className,
23
+ children,
24
+ onBlur,
25
+ onKeyDown,
26
+ ...props
27
+ }) {
28
+ const [armed, setArmedState] = React.useState(false);
29
+ const armedRef = React.useRef(false);
30
+ const onArmedChangeRef = React.useRef(onArmedChange);
31
+ React.useEffect(() => {
32
+ onArmedChangeRef.current = onArmedChange;
33
+ }, [onArmedChange]);
34
+ const setArmed = React.useCallback((next) => {
35
+ if (armedRef.current === next) return;
36
+ armedRef.current = next;
37
+ setArmedState(next);
38
+ onArmedChangeRef.current?.(next);
39
+ }, []);
40
+ React.useEffect(() => {
41
+ if (!armed) return;
42
+ const timer = window.setTimeout(() => setArmed(false), timeoutMs);
43
+ return () => window.clearTimeout(timer);
44
+ }, [armed, timeoutMs, setArmed]);
45
+ const name = armed ? confirmLabel : label;
46
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
47
+ /* @__PURE__ */ jsx(
48
+ Button,
49
+ {
50
+ variant,
51
+ "aria-label": name,
52
+ title: name,
53
+ "data-armed": armed ? "" : void 0,
54
+ className: cn(armed && confirmArmed, className),
55
+ onClick: () => {
56
+ if (!armed) return setArmed(true);
57
+ setArmed(false);
58
+ onConfirm();
59
+ },
60
+ onBlur: (event) => {
61
+ onBlur?.(event);
62
+ setArmed(false);
63
+ },
64
+ onKeyDown: (event) => {
65
+ onKeyDown?.(event);
66
+ if (armed && event.key === "Escape") {
67
+ event.stopPropagation();
68
+ setArmed(false);
69
+ }
70
+ },
71
+ ...props,
72
+ children: armed ? armedContent ?? /* @__PURE__ */ jsxs(Fragment, { children: [
73
+ children,
74
+ /* @__PURE__ */ jsx("span", { children: confirmLabel })
75
+ ] }) : children
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsx(VisuallyHidden.Root, { "aria-live": "polite", children: armed ? confirmLabel : "" })
79
+ ] });
80
+ }
81
+ export {
82
+ ConfirmButton,
83
+ confirmArmed
84
+ };
85
+ //# sourceMappingURL=confirm-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/confirm-button/confirm-button.tsx"],"sourcesContent":["// Client (a state). A destructive action confirmed by a second press, never `window.confirm`: the first press arms it\n// and says what will happen (`confirmLabel`, announced politely), the second runs `onConfirm`. It disarms by itself\n// after `timeoutMs`, on Escape, and when the focus leaves. The danger is the border and the tint; the words stay a\n// text role (contrast AA in both themes).\nimport { VisuallyHidden } from \"radix-ui\";\nimport * as React from \"react\";\n\nimport { Button, type ButtonProps } from \"../button/button\";\nimport { cn } from \"../cn\";\n\nexport const confirmArmed = \"border border-danger bg-danger/20 text-fg hover:border-danger hover:bg-danger/30\";\n\nexport type ConfirmButtonProps = Omit<ButtonProps, \"onClick\" | \"asChild\"> & {\n /** What the second press does, in words — shown and announced once armed (\"Delete for good?\"). Passed translated. */\n confirmLabel: string;\n /** The accessible name while idle, for an icon-only button (the confirm label names it once armed). */\n label?: string;\n /** Runs on the second press. */\n onConfirm: () => void;\n /** Disarms after this many milliseconds (4000 by default). */\n timeoutMs?: number;\n /** What it shows once armed (default: its children, then `confirmLabel`). */\n armedContent?: React.ReactNode;\n /** Notified when it arms and disarms. */\n onArmedChange?: (armed: boolean) => void;\n};\n\n/** A two-step button: press to arm, press again within `timeoutMs` to confirm. State: `data-armed`. */\nexport function ConfirmButton({\n confirmLabel,\n label,\n onConfirm,\n timeoutMs = 4000,\n onArmedChange,\n armedContent,\n variant = \"ghost\",\n className,\n children,\n onBlur,\n onKeyDown,\n ...props\n}: ConfirmButtonProps) {\n const [armed, setArmedState] = React.useState(false);\n const armedRef = React.useRef(false);\n const onArmedChangeRef = React.useRef(onArmedChange);\n React.useEffect(() => {\n onArmedChangeRef.current = onArmedChange;\n }, [onArmedChange]);\n const setArmed = React.useCallback((next: boolean) => {\n if (armedRef.current === next) return;\n armedRef.current = next;\n setArmedState(next);\n onArmedChangeRef.current?.(next);\n }, []);\n React.useEffect(() => {\n if (!armed) return;\n const timer = window.setTimeout(() => setArmed(false), timeoutMs);\n return () => window.clearTimeout(timer);\n }, [armed, timeoutMs, setArmed]);\n const name = armed ? confirmLabel : label;\n return (\n <>\n <Button\n variant={variant}\n aria-label={name}\n title={name}\n data-armed={armed ? \"\" : undefined}\n className={cn(armed && confirmArmed, className)}\n onClick={() => {\n if (!armed) return setArmed(true);\n setArmed(false);\n onConfirm();\n }}\n onBlur={(event) => {\n onBlur?.(event);\n setArmed(false);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (armed && event.key === \"Escape\") {\n event.stopPropagation();\n setArmed(false);\n }\n }}\n {...props}\n >\n {armed\n ? (armedContent ?? (\n <>\n {children}\n <span>{confirmLabel}</span>\n </>\n ))\n : children}\n </Button>\n <VisuallyHidden.Root aria-live=\"polite\">{armed ? confirmLabel : \"\"}</VisuallyHidden.Root>\n </>\n );\n}\n"],"mappings":";;;;;;;;;AAIA,SAAS,sBAAsB;AAC/B,YAAY,WAAW;AAmFT,mBAEE,KAFF;AA9EP,IAAM,eAAe;AAkBrB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,CAAC,OAAO,aAAa,IAAU,eAAS,KAAK;AACnD,QAAM,WAAiB,aAAO,KAAK;AACnC,QAAM,mBAAyB,aAAO,aAAa;AACnD,EAAM,gBAAU,MAAM;AACpB,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,aAAa,CAAC;AAClB,QAAM,WAAiB,kBAAY,CAAC,SAAkB;AACpD,QAAI,SAAS,YAAY,KAAM;AAC/B,aAAS,UAAU;AACnB,kBAAc,IAAI;AAClB,qBAAiB,UAAU,IAAI;AAAA,EACjC,GAAG,CAAC,CAAC;AACL,EAAM,gBAAU,MAAM;AACpB,QAAI,CAAC,MAAO;AACZ,UAAM,QAAQ,OAAO,WAAW,MAAM,SAAS,KAAK,GAAG,SAAS;AAChE,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,OAAO,WAAW,QAAQ,CAAC;AAC/B,QAAM,OAAO,QAAQ,eAAe;AACpC,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,cAAY;AAAA,QACZ,OAAO;AAAA,QACP,cAAY,QAAQ,KAAK;AAAA,QACzB,WAAW,GAAG,SAAS,cAAc,SAAS;AAAA,QAC9C,SAAS,MAAM;AACb,cAAI,CAAC,MAAO,QAAO,SAAS,IAAI;AAChC,mBAAS,KAAK;AACd,oBAAU;AAAA,QACZ;AAAA,QACA,QAAQ,CAAC,UAAU;AACjB,mBAAS,KAAK;AACd,mBAAS,KAAK;AAAA,QAChB;AAAA,QACA,WAAW,CAAC,UAAU;AACpB,sBAAY,KAAK;AACjB,cAAI,SAAS,MAAM,QAAQ,UAAU;AACnC,kBAAM,gBAAgB;AACtB,qBAAS,KAAK;AAAA,UAChB;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH,kBACI,gBACC,iCACG;AAAA;AAAA,UACD,oBAAC,UAAM,wBAAa;AAAA,WACtB,IAEF;AAAA;AAAA,IACN;AAAA,IACA,oBAAC,eAAe,MAAf,EAAoB,aAAU,UAAU,kBAAQ,eAAe,IAAG;AAAA,KACrE;AAEJ;","names":[]}
@@ -20,6 +20,7 @@ type CountdownUnits = {
20
20
  declare function countdownParts(ms: number, units: CountdownUnits): [number, string][];
21
21
 
22
22
  type CountdownProps = {
23
+ /** The moment it counts down to: a Date, an ISO string or epoch milliseconds. */
23
24
  target: Date | string | number;
24
25
  /** Server clock − this clock, in milliseconds. */
25
26
  skewMs?: number;
@@ -27,9 +28,11 @@ type CountdownProps = {
27
28
  units: CountdownUnits;
28
29
  /** Below this many milliseconds it turns urgent (`text-danger`, the last segment pulses). Default 60 s. */
29
30
  urgentBelowMs?: number;
31
+ /** sm · md · lg (the danger role is large-text safe from `md`). */
30
32
  size?: "sm" | "md" | "lg";
31
33
  /** Accessible name, e.g. "Ends in". */
32
34
  label: string;
35
+ /** Classes merged last, over the primitive's. */
33
36
  className?: string;
34
37
  };
35
38
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/countdown/core.ts","../src/countdown/countdown.tsx"],"sourcesContent":["// The countdown's clock, shared by the web (`@krizaka/ui/countdown`) and native renders: no DOM import.\nimport { useSyncExternalStore } from \"react\";\n\n// One clock for every countdown on the page: it ticks each second while someone listens.\nconst listeners = new Set<() => void>();\nlet timer: ReturnType<typeof setInterval> | null = null;\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n timer ??= setInterval(() => listeners.forEach((l) => l()), 1000);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0 && timer) {\n clearInterval(timer);\n timer = null;\n }\n };\n}\n\nconst nowSecond = () => Math.floor(Date.now() / 1000) * 1000;\n\n/** Milliseconds left until `target` (never negative), ticking every second. `skewMs` = server clock − this clock. */\nexport function useCountdown(target: Date | string | number, skewMs = 0): number {\n const now = useSyncExternalStore(subscribe, nowSecond, nowSecond);\n return Math.max(0, new Date(target).getTime() - (now + skewMs));\n}\n\n/** Splits a duration into days, hours, minutes and seconds. */\nexport function splitDuration(ms: number): { d: number; h: number; m: number; s: number } {\n const total = Math.max(0, Math.floor(ms / 1000));\n return { d: Math.floor(total / 86400), h: Math.floor((total % 86400) / 3600), m: Math.floor((total % 3600) / 60), s: total % 60 };\n}\n\n/** The short unit labels, passed translated (e.g. `{ d: \"d\", h: \"h\", m: \"m\", s: \"s\" }`). */\nexport type CountdownUnits = { d: string; h: string; m: string; s: string };\n\n/** The three segments shown: days, hours, minutes when there are days; else hours, minutes, seconds. */\nexport function countdownParts(ms: number, units: CountdownUnits): [number, string][] {\n const { d, h, m, s } = splitDuration(ms);\n return d > 0 ? [[d, units.d], [h, units.h], [m, units.m]] : [[h, units.h], [m, units.m], [s, units.s]];\n}\n","// Client: the clock is a hook.\nimport { tv } from \"tailwind-variants\";\n\nimport { countdownParts, type CountdownUnits, useCountdown } from \"./core\";\n\nconst countdown = tv({\n slots: {\n root: \"inline-flex items-baseline gap-1.5 font-display font-black tabular-nums tracking-tight text-fg\",\n segment: \"inline-flex items-baseline\",\n unit: \"ml-0.5 text-[0.5em] font-bold uppercase text-fg-secondary\",\n },\n variants: {\n size: { sm: { root: \"text-sm\" }, md: { root: \"text-xl\" }, lg: { root: \"text-3xl sm:text-4xl\" } },\n urgent: { true: { root: \"text-danger\" } },\n },\n defaultVariants: { size: \"md\" },\n});\n\nexport type CountdownProps = {\n target: Date | string | number;\n /** Server clock − this clock, in milliseconds. */\n skewMs?: number;\n /** The short unit labels, passed translated. */\n units: CountdownUnits;\n /** Below this many milliseconds it turns urgent (`text-danger`, the last segment pulses). Default 60 s. */\n urgentBelowMs?: number;\n size?: \"sm\" | \"md\" | \"lg\";\n /** Accessible name, e.g. \"Ends in\". */\n label: string;\n className?: string;\n};\n\n/**\n * Time left until a moment, as segments (2d 04h 13m 09s — days only when there are some) in tabular figures. Under\n * `urgentBelowMs` it turns to the danger role and its last segment pulses (no motion under prefers-reduced-motion).\n * Words come from the app: `units` are the short unit labels. `role=\"timer\"` without live announcements — the app\n * announces what matters. State: `data-urgent`, `data-ended`.\n *\n * The danger role is large-text safe (≥ 3:1) from `size=\"md\"`; at `size=\"sm\"` an urgent countdown in light mode is\n * under the 4.5:1 of small text.\n */\nexport function Countdown({ target, skewMs = 0, units, urgentBelowMs = 60_000, size = \"md\", label, className }: CountdownProps) {\n const ms = useCountdown(target, skewMs);\n const urgent = ms > 0 && ms < urgentBelowMs;\n const parts = countdownParts(ms, units);\n const s = countdown({ size, urgent });\n return (\n <span\n role=\"timer\"\n aria-label={label}\n data-urgent={urgent ? \"\" : undefined}\n data-ended={ms === 0 ? \"\" : undefined}\n suppressHydrationWarning\n className={s.root({ className })}\n >\n {parts.map(([value, unit], i) => (\n <span key={unit} className={s.segment({ className: urgent && i === parts.length - 1 ? \"motion-safe:animate-pulse\" : undefined })}>\n {String(value).padStart(2, \"0\")}\n <span className={s.unit()}>{unit}</span>\n </span>\n ))}\n </span>\n );\n}\n"],"mappings":";;;AACA,SAAS,4BAA4B;AAGrC,IAAM,YAAY,oBAAI,IAAgB;AACtC,IAAI,QAA+C;AAEnD,SAAS,UAAU,UAAsB;AACvC,YAAU,IAAI,QAAQ;AACtB,YAAU,YAAY,MAAM,UAAU,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,GAAI;AAC/D,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AACzB,QAAI,UAAU,SAAS,KAAK,OAAO;AACjC,oBAAc,KAAK;AACnB,cAAQ;AAAA,IACV;AAAA,EACF;AACF;AAEA,IAAM,YAAY,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI;AAGjD,SAAS,aAAa,QAAgC,SAAS,GAAW;AAC/E,QAAM,MAAM,qBAAqB,WAAW,WAAW,SAAS;AAChE,SAAO,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,EAAE,QAAQ,KAAK,MAAM,OAAO;AAChE;AAGO,SAAS,cAAc,IAA4D;AACxF,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;AAC/C,SAAO,EAAE,GAAG,KAAK,MAAM,QAAQ,KAAK,GAAG,GAAG,KAAK,MAAO,QAAQ,QAAS,IAAI,GAAG,GAAG,KAAK,MAAO,QAAQ,OAAQ,EAAE,GAAG,GAAG,QAAQ,GAAG;AAClI;AAMO,SAAS,eAAe,IAAY,OAA2C;AACpF,QAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,cAAc,EAAE;AACvC,SAAO,IAAI,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;AACvG;;;ACvCA,SAAS,UAAU;AAuDX,SAEE,KAFF;AAnDR,IAAM,YAAY,GAAG;AAAA,EACnB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,uBAAuB,EAAE;AAAA,IAC/F,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,EAAE;AAAA,EAC1C;AAAA,EACA,iBAAiB,EAAE,MAAM,KAAK;AAChC,CAAC;AAyBM,SAAS,UAAU,EAAE,QAAQ,SAAS,GAAG,OAAO,gBAAgB,KAAQ,OAAO,MAAM,OAAO,UAAU,GAAmB;AAC9H,QAAM,KAAK,aAAa,QAAQ,MAAM;AACtC,QAAM,SAAS,KAAK,KAAK,KAAK;AAC9B,QAAM,QAAQ,eAAe,IAAI,KAAK;AACtC,QAAM,IAAI,UAAU,EAAE,MAAM,OAAO,CAAC;AACpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,eAAa,SAAS,KAAK;AAAA,MAC3B,cAAY,OAAO,IAAI,KAAK;AAAA,MAC5B,0BAAwB;AAAA,MACxB,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC;AAAA,MAE9B,gBAAM,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,MACzB,qBAAC,UAAgB,WAAW,EAAE,QAAQ,EAAE,WAAW,UAAU,MAAM,MAAM,SAAS,IAAI,8BAA8B,OAAU,CAAC,GAC5H;AAAA,eAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AAAA,QAC9B,oBAAC,UAAK,WAAW,EAAE,KAAK,GAAI,gBAAK;AAAA,WAFxB,IAGX,CACD;AAAA;AAAA,EACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/countdown/core.ts","../src/countdown/countdown.tsx"],"sourcesContent":["// The countdown's clock, shared by the web (`@krizaka/ui/countdown`) and native renders: no DOM import.\nimport { useSyncExternalStore } from \"react\";\n\n// One clock for every countdown on the page: it ticks each second while someone listens.\nconst listeners = new Set<() => void>();\nlet timer: ReturnType<typeof setInterval> | null = null;\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n timer ??= setInterval(() => listeners.forEach((l) => l()), 1000);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0 && timer) {\n clearInterval(timer);\n timer = null;\n }\n };\n}\n\nconst nowSecond = () => Math.floor(Date.now() / 1000) * 1000;\n\n/** Milliseconds left until `target` (never negative), ticking every second. `skewMs` = server clock − this clock. */\nexport function useCountdown(target: Date | string | number, skewMs = 0): number {\n const now = useSyncExternalStore(subscribe, nowSecond, nowSecond);\n return Math.max(0, new Date(target).getTime() - (now + skewMs));\n}\n\n/** Splits a duration into days, hours, minutes and seconds. */\nexport function splitDuration(ms: number): { d: number; h: number; m: number; s: number } {\n const total = Math.max(0, Math.floor(ms / 1000));\n return { d: Math.floor(total / 86400), h: Math.floor((total % 86400) / 3600), m: Math.floor((total % 3600) / 60), s: total % 60 };\n}\n\n/** The short unit labels, passed translated (e.g. `{ d: \"d\", h: \"h\", m: \"m\", s: \"s\" }`). */\nexport type CountdownUnits = { d: string; h: string; m: string; s: string };\n\n/** The three segments shown: days, hours, minutes when there are days; else hours, minutes, seconds. */\nexport function countdownParts(ms: number, units: CountdownUnits): [number, string][] {\n const { d, h, m, s } = splitDuration(ms);\n return d > 0 ? [[d, units.d], [h, units.h], [m, units.m]] : [[h, units.h], [m, units.m], [s, units.s]];\n}\n","// Client: the clock is a hook.\nimport { tv } from \"tailwind-variants\";\n\nimport { countdownParts, type CountdownUnits, useCountdown } from \"./core\";\n\nconst countdown = tv({\n slots: {\n root: \"inline-flex items-baseline gap-1.5 font-display font-black tabular-nums tracking-tight text-fg\",\n segment: \"inline-flex items-baseline\",\n unit: \"ml-0.5 text-[0.5em] font-bold uppercase text-fg-secondary\",\n },\n variants: {\n size: { sm: { root: \"text-sm\" }, md: { root: \"text-xl\" }, lg: { root: \"text-3xl sm:text-4xl\" } },\n urgent: { true: { root: \"text-danger\" } },\n },\n defaultVariants: { size: \"md\" },\n});\n\nexport type CountdownProps = {\n /** The moment it counts down to: a Date, an ISO string or epoch milliseconds. */\n target: Date | string | number;\n /** Server clock − this clock, in milliseconds. */\n skewMs?: number;\n /** The short unit labels, passed translated. */\n units: CountdownUnits;\n /** Below this many milliseconds it turns urgent (`text-danger`, the last segment pulses). Default 60 s. */\n urgentBelowMs?: number;\n /** sm · md · lg (the danger role is large-text safe from `md`). */\n size?: \"sm\" | \"md\" | \"lg\";\n /** Accessible name, e.g. \"Ends in\". */\n label: string;\n /** Classes merged last, over the primitive's. */\n className?: string;\n};\n\n/**\n * Time left until a moment, as segments (2d 04h 13m 09s — days only when there are some) in tabular figures. Under\n * `urgentBelowMs` it turns to the danger role and its last segment pulses (no motion under prefers-reduced-motion).\n * Words come from the app: `units` are the short unit labels. `role=\"timer\"` without live announcements — the app\n * announces what matters. State: `data-urgent`, `data-ended`.\n *\n * The danger role is large-text safe (≥ 3:1) from `size=\"md\"`; at `size=\"sm\"` an urgent countdown in light mode is\n * under the 4.5:1 of small text.\n */\nexport function Countdown({ target, skewMs = 0, units, urgentBelowMs = 60_000, size = \"md\", label, className }: CountdownProps) {\n const ms = useCountdown(target, skewMs);\n const urgent = ms > 0 && ms < urgentBelowMs;\n const parts = countdownParts(ms, units);\n const s = countdown({ size, urgent });\n return (\n <span\n role=\"timer\"\n aria-label={label}\n data-urgent={urgent ? \"\" : undefined}\n data-ended={ms === 0 ? \"\" : undefined}\n suppressHydrationWarning\n className={s.root({ className })}\n >\n {parts.map(([value, unit], i) => (\n <span key={unit} className={s.segment({ className: urgent && i === parts.length - 1 ? \"motion-safe:animate-pulse\" : undefined })}>\n {String(value).padStart(2, \"0\")}\n <span className={s.unit()}>{unit}</span>\n </span>\n ))}\n </span>\n );\n}\n"],"mappings":";;;AACA,SAAS,4BAA4B;AAGrC,IAAM,YAAY,oBAAI,IAAgB;AACtC,IAAI,QAA+C;AAEnD,SAAS,UAAU,UAAsB;AACvC,YAAU,IAAI,QAAQ;AACtB,YAAU,YAAY,MAAM,UAAU,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,GAAI;AAC/D,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AACzB,QAAI,UAAU,SAAS,KAAK,OAAO;AACjC,oBAAc,KAAK;AACnB,cAAQ;AAAA,IACV;AAAA,EACF;AACF;AAEA,IAAM,YAAY,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,IAAI;AAGjD,SAAS,aAAa,QAAgC,SAAS,GAAW;AAC/E,QAAM,MAAM,qBAAqB,WAAW,WAAW,SAAS;AAChE,SAAO,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,EAAE,QAAQ,KAAK,MAAM,OAAO;AAChE;AAGO,SAAS,cAAc,IAA4D;AACxF,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;AAC/C,SAAO,EAAE,GAAG,KAAK,MAAM,QAAQ,KAAK,GAAG,GAAG,KAAK,MAAO,QAAQ,QAAS,IAAI,GAAG,GAAG,KAAK,MAAO,QAAQ,OAAQ,EAAE,GAAG,GAAG,QAAQ,GAAG;AAClI;AAMO,SAAS,eAAe,IAAY,OAA2C;AACpF,QAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,cAAc,EAAE;AACvC,SAAO,IAAI,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;AACvG;;;ACvCA,SAAS,UAAU;AA0DX,SAEE,KAFF;AAtDR,IAAM,YAAY,GAAG;AAAA,EACnB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,uBAAuB,EAAE;AAAA,IAC/F,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,EAAE;AAAA,EAC1C;AAAA,EACA,iBAAiB,EAAE,MAAM,KAAK;AAChC,CAAC;AA4BM,SAAS,UAAU,EAAE,QAAQ,SAAS,GAAG,OAAO,gBAAgB,KAAQ,OAAO,MAAM,OAAO,UAAU,GAAmB;AAC9H,QAAM,KAAK,aAAa,QAAQ,MAAM;AACtC,QAAM,SAAS,KAAK,KAAK,KAAK;AAC9B,QAAM,QAAQ,eAAe,IAAI,KAAK;AACtC,QAAM,IAAI,UAAU,EAAE,MAAM,OAAO,CAAC;AACpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,eAAa,SAAS,KAAK;AAAA,MAC3B,cAAY,OAAO,IAAI,KAAK;AAAA,MAC5B,0BAAwB;AAAA,MACxB,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC;AAAA,MAE9B,gBAAM,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,MACzB,qBAAC,UAAgB,WAAW,EAAE,QAAQ,EAAE,WAAW,UAAU,MAAM,MAAM,SAAS,IAAI,8BAA8B,OAAU,CAAC,GAC5H;AAAA,eAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AAAA,QAC9B,oBAAC,UAAK,WAAW,EAAE,KAAK,GAAI,gBAAK;AAAA,WAFxB,IAGX,CACD;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -0,0 +1,157 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { VariantProps } from 'tailwind-variants';
3
+ import { Dialog as Dialog$1 } from 'radix-ui';
4
+ import * as React from 'react';
5
+
6
+ declare const dialog: tailwind_variants.TVReturnType<{
7
+ placement: {
8
+ center: {
9
+ content: string;
10
+ };
11
+ bottom: {
12
+ content: string;
13
+ };
14
+ right: {
15
+ content: string;
16
+ };
17
+ };
18
+ size: {
19
+ sm: {
20
+ content: string;
21
+ };
22
+ md: {
23
+ content: string;
24
+ };
25
+ lg: {
26
+ content: string;
27
+ };
28
+ };
29
+ }, {
30
+ overlay: string;
31
+ content: string;
32
+ close: string;
33
+ header: string;
34
+ title: string;
35
+ description: string;
36
+ body: string;
37
+ footer: string;
38
+ }, undefined, {
39
+ placement: {
40
+ center: {
41
+ content: string;
42
+ };
43
+ bottom: {
44
+ content: string;
45
+ };
46
+ right: {
47
+ content: string;
48
+ };
49
+ };
50
+ size: {
51
+ sm: {
52
+ content: string;
53
+ };
54
+ md: {
55
+ content: string;
56
+ };
57
+ lg: {
58
+ content: string;
59
+ };
60
+ };
61
+ }, {
62
+ overlay: string;
63
+ content: string;
64
+ close: string;
65
+ header: string;
66
+ title: string;
67
+ description: string;
68
+ body: string;
69
+ footer: string;
70
+ }, tailwind_variants.TVReturnTypeLike<{
71
+ placement: {
72
+ center: {
73
+ content: string;
74
+ };
75
+ bottom: {
76
+ content: string;
77
+ };
78
+ right: {
79
+ content: string;
80
+ };
81
+ };
82
+ size: {
83
+ sm: {
84
+ content: string;
85
+ };
86
+ md: {
87
+ content: string;
88
+ };
89
+ lg: {
90
+ content: string;
91
+ };
92
+ };
93
+ }, {
94
+ overlay: string;
95
+ content: string;
96
+ close: string;
97
+ header: string;
98
+ title: string;
99
+ description: string;
100
+ body: string;
101
+ footer: string;
102
+ }>>;
103
+ type DialogVariants = VariantProps<typeof dialog>;
104
+ type CloseButtonProps = {
105
+ /** The accessible name of the close button — passed translated. */
106
+ closeLabel: string;
107
+ /** Leaves the close button out (the content brings its own way out, or none: see `dismissible`). */
108
+ hideClose?: false;
109
+ } | {
110
+ closeLabel?: string;
111
+ hideClose: true;
112
+ };
113
+ type DialogContentProps = React.ComponentProps<typeof Dialog$1.Content> & DialogVariants & CloseButtonProps & {
114
+ /**
115
+ * center · bottom (a sheet on a phone, centred from `sm` up) · right (a side panel, full height).
116
+ * @default "center"
117
+ */
118
+ placement?: DialogVariants["placement"];
119
+ /**
120
+ * sm · md · lg: the width of the dialog.
121
+ * @default "md"
122
+ */
123
+ size?: DialogVariants["size"];
124
+ /**
125
+ * `false`: Escape and a click outside do not close it (a gate the user must answer: age, terms). It still closes
126
+ * through `open` / `onOpenChange` and any `Dialog.Close` inside. Default `true`.
127
+ */
128
+ dismissible?: boolean;
129
+ /** The element the portal renders into (default: document.body). */
130
+ container?: HTMLElement | null;
131
+ };
132
+ /** The dialog itself, portalled over a dimmed overlay, with a close button. Give it a `Dialog.Title`. */
133
+ declare function DialogContent({ placement, size, closeLabel, hideClose, dismissible, container, className, children, onEscapeKeyDown, onPointerDownOutside, onInteractOutside, ...props }: DialogContentProps): React.JSX.Element;
134
+ declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
135
+ declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof Dialog$1.Title>): React.JSX.Element;
136
+ declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof Dialog$1.Description>): React.JSX.Element;
137
+ declare function DialogBody({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
138
+ declare function DialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
139
+ /** `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close`. `open`/`defaultOpen` + `onOpenChange`. */
140
+ declare const Dialog: {
141
+ Root: React.FC<Dialog$1.DialogProps>;
142
+ Trigger: React.ForwardRefExoticComponent<Dialog$1.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
143
+ Close: React.ForwardRefExoticComponent<Dialog$1.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
144
+ Content: typeof DialogContent;
145
+ Header: typeof DialogHeader;
146
+ Title: typeof DialogTitle;
147
+ Description: typeof DialogDescription;
148
+ Body: typeof DialogBody;
149
+ Footer: typeof DialogFooter;
150
+ };
151
+ /** `Omit` that keeps the close-button union (`closeLabel` required unless `hideClose`). */
152
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
153
+ type SheetProps = DistributiveOmit<DialogContentProps, "placement">;
154
+ /** A sheet is a dialog anchored at the bottom (centred from `sm` up): `Dialog.Content placement="bottom"`. */
155
+ declare function Sheet(props: SheetProps): React.JSX.Element;
156
+
157
+ export { type DialogContentProps as D, Sheet as S, Dialog as a, DialogBody as b, DialogContent as c, DialogDescription as d, DialogFooter as e, DialogHeader as f, DialogTitle as g, type DialogVariants as h, type SheetProps as i, dialog as j };
package/dist/dialog.d.ts CHANGED
@@ -1,19 +1,26 @@
1
1
  import * as React from 'react';
2
- import * as tailwind_variants from 'tailwind-variants';
3
- import { VariantProps } from 'tailwind-variants';
4
- import { Dialog as Dialog$1 } from 'radix-ui';
2
+ export { a as Dialog, b as DialogBody, c as DialogContent, D as DialogContentProps, d as DialogDescription, e as DialogFooter, f as DialogHeader, g as DialogTitle, h as DialogVariants, S as Sheet, i as SheetProps, j as dialog } from './dialog-GQ4Nvuyf.js';
3
+ import 'tailwind-variants';
4
+ import 'radix-ui';
5
5
 
6
6
  type AlertDialogProps = {
7
+ /** Open or closed (controlled), with `onOpenChange`. */
7
8
  open?: boolean;
9
+ /** Open at first, uncontrolled. */
8
10
  defaultOpen?: boolean;
11
+ /** Called when it opens or closes (never while `onConfirm` is pending). */
9
12
  onOpenChange?: (open: boolean) => void;
10
13
  /** The element that opens the dialog (rendered as is, `asChild`): a Button, an IconButton. */
11
14
  trigger?: React.ReactNode;
15
+ /** The question asked ("Delete this video?"): the dialog's accessible name. */
12
16
  title: React.ReactNode;
17
+ /** What the action does and what it costs: the dialog's description. */
13
18
  description?: React.ReactNode;
14
19
  /** More content between the description and the actions. */
15
20
  children?: React.ReactNode;
21
+ /** The words of the confirm button — passed translated. */
16
22
  confirmLabel: string;
23
+ /** The words of the cancel button (it takes the focus at open) — passed translated. */
17
24
  cancelLabel: string;
18
25
  /** `danger` for a destructive action (delete, leave, cancel a payment). */
19
26
  tone?: "danger" | "primary";
@@ -21,135 +28,9 @@ type AlertDialogProps = {
21
28
  onConfirm: () => void | Promise<unknown>;
22
29
  /** The element the portal renders into (default: document.body). */
23
30
  container?: HTMLElement | null;
31
+ /** Classes of the dialog's content, merged last. */
24
32
  className?: string;
25
33
  };
26
34
  declare function AlertDialog({ open: openProp, defaultOpen, onOpenChange, trigger, title, description, children, confirmLabel, cancelLabel, tone, onConfirm, container, className, }: AlertDialogProps): React.JSX.Element;
27
35
 
28
- declare const dialog: tailwind_variants.TVReturnType<{
29
- placement: {
30
- center: {
31
- content: string;
32
- };
33
- bottom: {
34
- content: string;
35
- };
36
- right: {
37
- content: string;
38
- };
39
- };
40
- size: {
41
- sm: {
42
- content: string;
43
- };
44
- md: {
45
- content: string;
46
- };
47
- lg: {
48
- content: string;
49
- };
50
- };
51
- }, {
52
- overlay: string;
53
- content: string;
54
- close: string;
55
- header: string;
56
- title: string;
57
- description: string;
58
- body: string;
59
- footer: string;
60
- }, undefined, {
61
- placement: {
62
- center: {
63
- content: string;
64
- };
65
- bottom: {
66
- content: string;
67
- };
68
- right: {
69
- content: string;
70
- };
71
- };
72
- size: {
73
- sm: {
74
- content: string;
75
- };
76
- md: {
77
- content: string;
78
- };
79
- lg: {
80
- content: string;
81
- };
82
- };
83
- }, {
84
- overlay: string;
85
- content: string;
86
- close: string;
87
- header: string;
88
- title: string;
89
- description: string;
90
- body: string;
91
- footer: string;
92
- }, tailwind_variants.TVReturnTypeLike<{
93
- placement: {
94
- center: {
95
- content: string;
96
- };
97
- bottom: {
98
- content: string;
99
- };
100
- right: {
101
- content: string;
102
- };
103
- };
104
- size: {
105
- sm: {
106
- content: string;
107
- };
108
- md: {
109
- content: string;
110
- };
111
- lg: {
112
- content: string;
113
- };
114
- };
115
- }, {
116
- overlay: string;
117
- content: string;
118
- close: string;
119
- header: string;
120
- title: string;
121
- description: string;
122
- body: string;
123
- footer: string;
124
- }>>;
125
- type DialogVariants = VariantProps<typeof dialog>;
126
- type DialogContentProps = React.ComponentProps<typeof Dialog$1.Content> & DialogVariants & {
127
- /** The accessible name of the close button — passed translated. */
128
- closeLabel: string;
129
- /** The element the portal renders into (default: document.body). */
130
- container?: HTMLElement | null;
131
- };
132
- /** The dialog itself, portalled over a dimmed overlay, with a close button. Give it a `Dialog.Title`. */
133
- declare function DialogContent({ placement, size, closeLabel, container, className, children, ...props }: DialogContentProps): React.JSX.Element;
134
- declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
135
- declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof Dialog$1.Title>): React.JSX.Element;
136
- declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof Dialog$1.Description>): React.JSX.Element;
137
- declare function DialogBody({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
138
- declare function DialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
139
- /** `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close`. `open`/`defaultOpen` + `onOpenChange`. */
140
- declare const Dialog: {
141
- Root: React.FC<Dialog$1.DialogProps>;
142
- Trigger: React.ForwardRefExoticComponent<Dialog$1.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
143
- Close: React.ForwardRefExoticComponent<Dialog$1.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
144
- Content: typeof DialogContent;
145
- Header: typeof DialogHeader;
146
- Title: typeof DialogTitle;
147
- Description: typeof DialogDescription;
148
- Body: typeof DialogBody;
149
- Footer: typeof DialogFooter;
150
- };
151
- type SheetProps = Omit<DialogContentProps, "placement">;
152
- /** A sheet is a dialog anchored at the bottom (centred from `sm` up): `Dialog.Content placement="bottom"`. */
153
- declare function Sheet(props: SheetProps): React.JSX.Element;
154
-
155
- export { AlertDialog, type AlertDialogProps, Dialog, DialogBody, DialogContent, type DialogContentProps, DialogDescription, DialogFooter, DialogHeader, DialogTitle, type DialogVariants, Sheet, type SheetProps, dialog };
36
+ export { AlertDialog, type AlertDialogProps };