@franco_roura/module-01 0.0.0-stage → 1.0.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 (222) hide show
  1. package/LICENSE-APACHE +202 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +64 -2
  4. package/dist/charts.d.ts +3 -0
  5. package/dist/charts.js +3 -0
  6. package/dist/components/alert-dialog.d.ts +19 -0
  7. package/dist/components/alert-dialog.js +101 -0
  8. package/dist/components/alert-dialog.js.map +1 -0
  9. package/dist/components/amount.d.ts +24 -0
  10. package/dist/components/amount.js +27 -0
  11. package/dist/components/amount.js.map +1 -0
  12. package/dist/components/appearance-pickers.d.ts +9 -0
  13. package/dist/components/appearance-pickers.js +65 -0
  14. package/dist/components/appearance-pickers.js.map +1 -0
  15. package/dist/components/badge.d.ts +10 -0
  16. package/dist/components/badge.js +28 -0
  17. package/dist/components/badge.js.map +1 -0
  18. package/dist/components/budget-meter.d.ts +18 -0
  19. package/dist/components/budget-meter.js +38 -0
  20. package/dist/components/budget-meter.js.map +1 -0
  21. package/dist/components/button.d.ts +13 -0
  22. package/dist/components/button.js +54 -0
  23. package/dist/components/button.js.map +1 -0
  24. package/dist/components/calendar.d.ts +7 -0
  25. package/dist/components/calendar.js +52 -0
  26. package/dist/components/calendar.js.map +1 -0
  27. package/dist/components/category-icon.d.ts +33 -0
  28. package/dist/components/category-icon.js +49 -0
  29. package/dist/components/category-icon.js.map +1 -0
  30. package/dist/components/chart.d.ts +44 -0
  31. package/dist/components/chart.js +147 -0
  32. package/dist/components/chart.js.map +1 -0
  33. package/dist/components/charts.d.ts +52 -0
  34. package/dist/components/charts.js +482 -0
  35. package/dist/components/charts.js.map +1 -0
  36. package/dist/components/checkbox.d.ts +5 -0
  37. package/dist/components/checkbox.js +21 -0
  38. package/dist/components/checkbox.js.map +1 -0
  39. package/dist/components/combobox.d.ts +32 -0
  40. package/dist/components/combobox.js +100 -0
  41. package/dist/components/combobox.js.map +1 -0
  42. package/dist/components/command.d.ts +19 -0
  43. package/dist/components/command.js +86 -0
  44. package/dist/components/command.js.map +1 -0
  45. package/dist/components/cta-banner.d.ts +14 -0
  46. package/dist/components/cta-banner.js +39 -0
  47. package/dist/components/cta-banner.js.map +1 -0
  48. package/dist/components/date-picker.d.ts +19 -0
  49. package/dist/components/date-picker.js +107 -0
  50. package/dist/components/date-picker.js.map +1 -0
  51. package/dist/components/dialog.d.ts +18 -0
  52. package/dist/components/dialog.js +99 -0
  53. package/dist/components/dialog.js.map +1 -0
  54. package/dist/components/dropdown-menu.d.ts +26 -0
  55. package/dist/components/dropdown-menu.js +123 -0
  56. package/dist/components/dropdown-menu.js.map +1 -0
  57. package/dist/components/field.d.ts +30 -0
  58. package/dist/components/field.js +53 -0
  59. package/dist/components/field.js.map +1 -0
  60. package/dist/components/footer.d.ts +18 -0
  61. package/dist/components/footer.js +40 -0
  62. package/dist/components/footer.js.map +1 -0
  63. package/dist/components/fx-converter.d.ts +22 -0
  64. package/dist/components/fx-converter.js +91 -0
  65. package/dist/components/fx-converter.js.map +1 -0
  66. package/dist/components/hero.d.ts +28 -0
  67. package/dist/components/hero.js +83 -0
  68. package/dist/components/hero.js.map +1 -0
  69. package/dist/components/hud.d.ts +41 -0
  70. package/dist/components/hud.js +108 -0
  71. package/dist/components/hud.js.map +1 -0
  72. package/dist/components/input.d.ts +4 -0
  73. package/dist/components/input.js +14 -0
  74. package/dist/components/input.js.map +1 -0
  75. package/dist/components/label.d.ts +5 -0
  76. package/dist/components/label.js +15 -0
  77. package/dist/components/label.js.map +1 -0
  78. package/dist/components/media-card.d.ts +29 -0
  79. package/dist/components/media-card.js +80 -0
  80. package/dist/components/media-card.js.map +1 -0
  81. package/dist/components/money-input.d.ts +10 -0
  82. package/dist/components/money-input.js +30 -0
  83. package/dist/components/money-input.js.map +1 -0
  84. package/dist/components/multi-combobox.d.ts +27 -0
  85. package/dist/components/multi-combobox.js +101 -0
  86. package/dist/components/multi-combobox.js.map +1 -0
  87. package/dist/components/nav-bar.d.ts +21 -0
  88. package/dist/components/nav-bar.js +44 -0
  89. package/dist/components/nav-bar.js.map +1 -0
  90. package/dist/components/panel.d.ts +27 -0
  91. package/dist/components/panel.js +49 -0
  92. package/dist/components/panel.js.map +1 -0
  93. package/dist/components/popover.d.ts +11 -0
  94. package/dist/components/popover.js +56 -0
  95. package/dist/components/popover.js.map +1 -0
  96. package/dist/components/select.d.ts +16 -0
  97. package/dist/components/select.js +128 -0
  98. package/dist/components/select.js.map +1 -0
  99. package/dist/components/separator.d.ts +5 -0
  100. package/dist/components/separator.js +17 -0
  101. package/dist/components/separator.js.map +1 -0
  102. package/dist/components/sheet.d.ts +15 -0
  103. package/dist/components/sheet.js +87 -0
  104. package/dist/components/sheet.js.map +1 -0
  105. package/dist/components/skeleton.d.ts +3 -0
  106. package/dist/components/skeleton.js +13 -0
  107. package/dist/components/skeleton.js.map +1 -0
  108. package/dist/components/sonner.d.ts +5 -0
  109. package/dist/components/sonner.js +44 -0
  110. package/dist/components/sonner.js.map +1 -0
  111. package/dist/components/spec-readout.d.ts +11 -0
  112. package/dist/components/spec-readout.js +25 -0
  113. package/dist/components/spec-readout.js.map +1 -0
  114. package/dist/components/split-flap.d.ts +12 -0
  115. package/dist/components/split-flap.js +77 -0
  116. package/dist/components/split-flap.js.map +1 -0
  117. package/dist/components/tabs.d.ts +12 -0
  118. package/dist/components/tabs.js +47 -0
  119. package/dist/components/tabs.js.map +1 -0
  120. package/dist/components/tag.d.ts +16 -0
  121. package/dist/components/tag.js +26 -0
  122. package/dist/components/tag.js.map +1 -0
  123. package/dist/components/terminal.d.ts +10 -0
  124. package/dist/components/terminal.js +20 -0
  125. package/dist/components/terminal.js.map +1 -0
  126. package/dist/components/textarea.d.ts +4 -0
  127. package/dist/components/textarea.js +13 -0
  128. package/dist/components/textarea.js.map +1 -0
  129. package/dist/components/timeline-entry.d.ts +26 -0
  130. package/dist/components/timeline-entry.js +63 -0
  131. package/dist/components/timeline-entry.js.map +1 -0
  132. package/dist/components/toggle-group.d.ts +10 -0
  133. package/dist/components/toggle-group.js +49 -0
  134. package/dist/components/toggle-group.js.map +1 -0
  135. package/dist/components/toggle.d.ts +10 -0
  136. package/dist/components/toggle.js +37 -0
  137. package/dist/components/toggle.js.map +1 -0
  138. package/dist/components/tooltip.d.ts +8 -0
  139. package/dist/components/tooltip.js +36 -0
  140. package/dist/components/tooltip.js.map +1 -0
  141. package/dist/finance.d.ts +10 -0
  142. package/dist/finance.js +10 -0
  143. package/dist/index.d.ts +33 -0
  144. package/dist/index.js +33 -0
  145. package/dist/lib/category-icons.d.ts +80 -0
  146. package/dist/lib/category-icons.js +102 -0
  147. package/dist/lib/category-icons.js.map +1 -0
  148. package/dist/lib/fault.d.ts +7 -0
  149. package/dist/lib/fault.js +28 -0
  150. package/dist/lib/fault.js.map +1 -0
  151. package/dist/lib/form-flow.d.ts +15 -0
  152. package/dist/lib/form-flow.js +50 -0
  153. package/dist/lib/form-flow.js.map +1 -0
  154. package/dist/lib/fx.d.ts +39 -0
  155. package/dist/lib/fx.js +98 -0
  156. package/dist/lib/fx.js.map +1 -0
  157. package/dist/lib/money.d.ts +19 -0
  158. package/dist/lib/money.js +55 -0
  159. package/dist/lib/money.js.map +1 -0
  160. package/dist/lib/use-media-query.d.ts +3 -0
  161. package/dist/lib/use-media-query.js +15 -0
  162. package/dist/lib/use-media-query.js.map +1 -0
  163. package/dist/lib/utils.d.ts +3 -0
  164. package/dist/lib/utils.js +26 -0
  165. package/dist/lib/utils.js.map +1 -0
  166. package/dist/site.d.ts +10 -0
  167. package/dist/site.js +10 -0
  168. package/dist/styles.css +2 -0
  169. package/dist/theme.css +391 -0
  170. package/dist/tokens.css +181 -0
  171. package/guidelines/AlertDialog.md +9 -0
  172. package/guidelines/Amount.md +10 -0
  173. package/guidelines/AppearancePickers.md +8 -0
  174. package/guidelines/Badge.md +11 -0
  175. package/guidelines/BudgetMeter.md +11 -0
  176. package/guidelines/Button.md +16 -0
  177. package/guidelines/Calendar.md +8 -0
  178. package/guidelines/CategoryIcon.md +10 -0
  179. package/guidelines/Charts.md +12 -0
  180. package/guidelines/Checkbox.md +8 -0
  181. package/guidelines/Combobox.md +18 -0
  182. package/guidelines/Command.md +8 -0
  183. package/guidelines/Crosshair.md +7 -0
  184. package/guidelines/CtaBanner.md +8 -0
  185. package/guidelines/DatePicker.md +11 -0
  186. package/guidelines/Dialog.md +9 -0
  187. package/guidelines/DropdownMenu.md +9 -0
  188. package/guidelines/Field.md +22 -0
  189. package/guidelines/Footer.md +7 -0
  190. package/guidelines/FxConverter.md +12 -0
  191. package/guidelines/GlassPanel.md +8 -0
  192. package/guidelines/Grill.md +7 -0
  193. package/guidelines/Hero.md +9 -0
  194. package/guidelines/HudLabel.md +8 -0
  195. package/guidelines/Input.md +9 -0
  196. package/guidelines/Label.md +7 -0
  197. package/guidelines/MediaCard.md +8 -0
  198. package/guidelines/MoneyInput.md +10 -0
  199. package/guidelines/MultiCombobox.md +11 -0
  200. package/guidelines/NavBar.md +10 -0
  201. package/guidelines/Panel.md +10 -0
  202. package/guidelines/Popover.md +8 -0
  203. package/guidelines/README.md +100 -0
  204. package/guidelines/SectionHeader.md +9 -0
  205. package/guidelines/Select.md +9 -0
  206. package/guidelines/Separator.md +8 -0
  207. package/guidelines/Sheet.md +9 -0
  208. package/guidelines/Skeleton.md +8 -0
  209. package/guidelines/SpecReadout.md +7 -0
  210. package/guidelines/SplitFlap.md +9 -0
  211. package/guidelines/StatusLed.md +8 -0
  212. package/guidelines/Tabs.md +9 -0
  213. package/guidelines/Tag.md +9 -0
  214. package/guidelines/Terminal.md +7 -0
  215. package/guidelines/Textarea.md +8 -0
  216. package/guidelines/TickRuler.md +8 -0
  217. package/guidelines/TimelineEntry.md +8 -0
  218. package/guidelines/Toaster.md +9 -0
  219. package/guidelines/Toggle.md +9 -0
  220. package/guidelines/Tooltip.md +8 -0
  221. package/package.json +103 -4
  222. package/tokens/tokens.json +739 -0
@@ -0,0 +1,100 @@
1
+ "use client";
2
+ import { focusNextField } from "../lib/form-flow.js";
3
+ import { cn } from "../lib/utils.js";
4
+ import { Button } from "./button.js";
5
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "./command.js";
6
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Check, ChevronsUpDown } from "lucide-react";
9
+ import { useRef, useState } from "react";
10
+ // src/components/combobox.tsx
11
+ /**
12
+ * Searchable single-choice picker. Part of the form flow: typing on the focused trigger opens it
13
+ * with that text as the search, and picking an option moves focus to the next field.
14
+ */
15
+ function Combobox({ id, value, onChange, options, groups, getKey, getSearchText, renderOption, renderValue, placeholder = "Choose…", searchPlaceholder = "Search…", emptyText = "Nothing found.", footer, invalid, disabled, className, contentClassName }) {
16
+ const [open, setOpen] = useState(false);
17
+ const [query, setQuery] = useState("");
18
+ const trigger = useRef(null);
19
+ const committed = useRef(false);
20
+ const sections = groups ?? [{ options: options ?? [] }];
21
+ const current = sections.flatMap((g) => g.options).find((o) => getKey(o) === value);
22
+ const search = getSearchText ?? getKey;
23
+ function openWith(text) {
24
+ setQuery(text);
25
+ setOpen(true);
26
+ }
27
+ function pick(option) {
28
+ committed.current = true;
29
+ onChange(getKey(option));
30
+ setOpen(false);
31
+ }
32
+ return /* @__PURE__ */ jsxs(Popover, {
33
+ open,
34
+ onOpenChange: (next) => {
35
+ if (next) setQuery("");
36
+ setOpen(next);
37
+ },
38
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
39
+ asChild: true,
40
+ children: /* @__PURE__ */ jsxs(Button, {
41
+ ref: trigger,
42
+ id,
43
+ type: "button",
44
+ variant: "outline",
45
+ role: "combobox",
46
+ "data-flow-autoopen": value ? void 0 : "",
47
+ "aria-expanded": open,
48
+ "aria-invalid": invalid || void 0,
49
+ disabled,
50
+ className: cn("w-full justify-between px-3", className),
51
+ onKeyDown: (e) => {
52
+ if (!open && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && e.key !== " ") {
53
+ e.preventDefault();
54
+ openWith(e.key);
55
+ }
56
+ },
57
+ children: [current ? /* @__PURE__ */ jsx("span", {
58
+ className: "flex min-w-0 items-center gap-2",
59
+ children: (renderValue ?? renderOption)(current)
60
+ }) : /* @__PURE__ */ jsx("span", {
61
+ className: "text-ink-soft",
62
+ children: placeholder
63
+ }), /* @__PURE__ */ jsx(ChevronsUpDown, {
64
+ className: "size-4 shrink-0 text-ink-soft",
65
+ strokeWidth: 1.25
66
+ })]
67
+ })
68
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
69
+ align: "start",
70
+ className: cn("w-(--radix-popover-trigger-width) min-w-64 p-0", contentClassName),
71
+ onCloseAutoFocus: (e) => {
72
+ if (!committed.current) return;
73
+ committed.current = false;
74
+ e.preventDefault();
75
+ focusNextField(trigger.current);
76
+ },
77
+ children: [/* @__PURE__ */ jsxs(Command, { children: [/* @__PURE__ */ jsx(CommandInput, {
78
+ placeholder: searchPlaceholder,
79
+ value: query,
80
+ onValueChange: setQuery
81
+ }), /* @__PURE__ */ jsxs(CommandList, { children: [/* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }), sections.map((g, i) => /* @__PURE__ */ jsx(CommandGroup, {
82
+ heading: g.heading,
83
+ children: g.options.map((o) => /* @__PURE__ */ jsxs(CommandItem, {
84
+ value: `${search(o)} ${getKey(o)}`,
85
+ onSelect: () => pick(o),
86
+ children: [renderOption(o), getKey(o) === value && /* @__PURE__ */ jsx(Check, {
87
+ className: "ml-auto size-4",
88
+ strokeWidth: 1.25
89
+ })]
90
+ }, getKey(o)))
91
+ }, g.heading ?? i))] })] }), footer && /* @__PURE__ */ jsx("div", {
92
+ className: "border-t border-seam p-2",
93
+ children: footer
94
+ })]
95
+ })]
96
+ });
97
+ }
98
+ export { Combobox };
99
+
100
+ //# sourceMappingURL=combobox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox.js","names":[],"sources":["../../src/components/combobox.tsx"],"sourcesContent":["\"use client\";\n\nimport { focusNextField } from \"../lib/form-flow\";\nimport { cn } from \"../lib/utils\";\nimport { Check, ChevronsUpDown } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { Button } from \"./button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"./command\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport type ComboboxGroup<T> = { heading?: string; options: T[] };\n\n/**\n * Searchable single-choice picker. Part of the form flow: typing on the focused trigger opens it\n * with that text as the search, and picking an option moves focus to the next field.\n */\nexport function Combobox<T>({\n id,\n value,\n onChange,\n options,\n groups,\n getKey,\n getSearchText,\n renderOption,\n renderValue,\n placeholder = \"Choose…\",\n searchPlaceholder = \"Search…\",\n emptyText = \"Nothing found.\",\n footer,\n invalid,\n disabled,\n className,\n contentClassName,\n}: {\n id?: string;\n value: string;\n onChange: (key: string) => void;\n /** Flat options; or pass `groups` for headed sections. */\n options?: T[];\n groups?: ComboboxGroup<T>[];\n getKey: (option: T) => string;\n /** Text the search matches against (defaults to the key). */\n getSearchText?: (option: T) => string;\n renderOption: (option: T) => React.ReactNode;\n /** The selected option on the trigger (defaults to renderOption). */\n renderValue?: (option: T) => React.ReactNode;\n placeholder?: React.ReactNode;\n searchPlaceholder?: string;\n emptyText?: React.ReactNode;\n /** Shown under the list, e.g. a link to manage the options. */\n footer?: React.ReactNode;\n invalid?: boolean;\n disabled?: boolean;\n className?: string;\n contentClassName?: string;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const trigger = useRef<HTMLButtonElement>(null);\n const committed = useRef(false);\n\n const sections: ComboboxGroup<T>[] = groups ?? [{ options: options ?? [] }];\n const current = sections.flatMap((g) => g.options).find((o) => getKey(o) === value);\n const search = getSearchText ?? getKey;\n\n function openWith(text: string) {\n setQuery(text);\n setOpen(true);\n }\n\n function pick(option: T) {\n committed.current = true;\n onChange(getKey(option));\n setOpen(false);\n }\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n if (next) setQuery(\"\");\n setOpen(next);\n }}\n >\n <PopoverTrigger asChild>\n <Button\n ref={trigger}\n id={id}\n type=\"button\"\n variant=\"outline\"\n role=\"combobox\"\n data-flow-autoopen={value ? undefined : \"\"}\n aria-expanded={open}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n className={cn(\"w-full justify-between px-3\", className)}\n onKeyDown={(e) => {\n // Type to search: a printable key on the closed trigger opens it with that letter.\n if (\n !open &&\n e.key.length === 1 &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey &&\n e.key !== \" \"\n ) {\n e.preventDefault();\n openWith(e.key);\n }\n }}\n >\n {current ? (\n <span className=\"flex min-w-0 items-center gap-2\">\n {(renderValue ?? renderOption)(current)}\n </span>\n ) : (\n <span className=\"text-ink-soft\">{placeholder}</span>\n )}\n <ChevronsUpDown className=\"size-4 shrink-0 text-ink-soft\" strokeWidth={1.25} />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className={cn(\"w-(--radix-popover-trigger-width) min-w-64 p-0\", contentClassName)}\n onCloseAutoFocus={(e) => {\n // Form flow: after a pick, move on to the next field (Escape returns to the trigger).\n if (!committed.current) return;\n committed.current = false;\n e.preventDefault();\n focusNextField(trigger.current);\n }}\n >\n <Command>\n <CommandInput placeholder={searchPlaceholder} value={query} onValueChange={setQuery} />\n <CommandList>\n <CommandEmpty>{emptyText}</CommandEmpty>\n {sections.map((g, i) => (\n <CommandGroup key={g.heading ?? i} heading={g.heading}>\n {g.options.map((o) => (\n <CommandItem\n key={getKey(o)}\n value={`${search(o)} ${getKey(o)}`}\n onSelect={() => pick(o)}\n >\n {renderOption(o)}\n {getKey(o) === value && <Check className=\"ml-auto size-4\" strokeWidth={1.25} />}\n </CommandItem>\n ))}\n </CommandGroup>\n ))}\n </CommandList>\n </Command>\n {footer && <div className=\"border-t border-seam p-2\">{footer}</div>}\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAuBA,SAAgB,SAAY,EAC1B,IACA,OACA,UACA,SACA,QACA,QACA,eACA,cACA,aACA,cAAc,WACd,oBAAoB,WACpB,YAAY,kBACZ,QACA,SACA,UACA,WACA,oBAuBC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,UAAU,OAA0B,IAAI;CAC9C,MAAM,YAAY,OAAO,KAAK;CAE9B,MAAM,WAA+B,UAAU,CAAC,EAAE,SAAS,WAAW,CAAC,EAAE,CAAC;CAC1E,MAAM,UAAU,SAAS,SAAS,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,MAAM,OAAO,CAAC,MAAM,KAAK;CAClF,MAAM,SAAS,iBAAiB;CAEhC,SAAS,SAAS,MAAc;EAC9B,SAAS,IAAI;EACb,QAAQ,IAAI;CACd;CAEA,SAAS,KAAK,QAAW;EACvB,UAAU,UAAU;EACpB,SAAS,OAAO,MAAM,CAAC;EACvB,QAAQ,KAAK;CACf;CAEA,OACE,qBAAC,SAAD;EACQ;EACN,eAAe,SAAS;GACtB,IAAI,MAAM,SAAS,EAAE;GACrB,QAAQ,IAAI;EACd;EALF,UAAA,CAOE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,QAAD;IACE,KAAK;IACD;IACJ,MAAK;IACL,SAAQ;IACR,MAAK;IACL,sBAAoB,QAAQ,KAAA,IAAY;IACxC,iBAAe;IACf,gBAAc,WAAW,KAAA;IACf;IACV,WAAW,GAAG,+BAA+B,SAAS;IACtD,YAAY,MAAM;KAEhB,IACE,CAAC,QACD,EAAE,IAAI,WAAW,KACjB,CAAC,EAAE,WACH,CAAC,EAAE,WACH,CAAC,EAAE,UACH,EAAE,QAAQ,KACV;MACA,EAAE,eAAe;MACjB,SAAS,EAAE,GAAG;KAChB;IACF;IAxBF,UAAA,CA0BG,UACC,oBAAC,QAAD;KAAM,WAAU;KACZ,WAAA,eAAe,aAAA,CAAc,OAAO;IAClC,CAAA,IAEN,oBAAC,QAAD;KAAM,WAAU;KAAiB,UAAA;IAAkB,CAAA,GAErD,oBAAC,gBAAD;KAAgB,WAAU;KAAgC,aAAa;IAAO,CAAA,CACxE;;EACM,CAAA,GAChB,qBAAC,gBAAD;GACE,OAAM;GACN,WAAW,GAAG,kDAAkD,gBAAgB;GAChF,mBAAmB,MAAM;IAEvB,IAAI,CAAC,UAAU,SAAS;IACxB,UAAU,UAAU;IACpB,EAAE,eAAe;IACjB,eAAe,QAAQ,OAAO;GAChC;GATF,UAAA,CAWE,qBAAC,SAAD,EAAA,UAAA,CACE,oBAAC,cAAD;IAAc,aAAa;IAAmB,OAAO;IAAO,eAAe;GAAW,CAAA,GACtF,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,cAAD,EAAA,UAAe,UAAwB,CAAA,GACtC,SAAS,KAAK,GAAG,MAChB,oBAAC,cAAD;IAAmC,SAAS,EAAE;IAC3C,UAAA,EAAE,QAAQ,KAAK,MACd,qBAAC,aAAD;KAEE,OAAO,GAAG,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC;KAC/B,gBAAgB,KAAK,CAAC;KAHxB,UAAA,CAKG,aAAa,CAAC,GACd,OAAO,CAAC,MAAM,SAAS,oBAAC,OAAD;MAAO,WAAU;MAAiB,aAAa;KAAO,CAAA,CACnE;IANN,GAAA,OAAO,CAAC,CAMF,CACd;GACW,GAXK,EAAE,WAAW,CAWlB,CACf,CACU,EAAA,CAAA,CACN,EAAA,CAAA,GACR,UAAU,oBAAC,OAAD;IAAK,WAAU;IAA4B,UAAA;GAAY,CAAA,CACpD;EACT,CAAA,CAAA;;AAEb"}
@@ -0,0 +1,19 @@
1
+ import { Dialog } from "./dialog.js";
2
+ import * as React from "react";
3
+ import { Command } from "cmdk";
4
+ declare function Command$1({ className, ...props }: React.ComponentProps<typeof Command>): React.JSX.Element;
5
+ declare function CommandDialog({ title, description, children, className, showCloseButton, ...props }: React.ComponentProps<typeof Dialog> & {
6
+ title?: string;
7
+ description?: string;
8
+ className?: string;
9
+ showCloseButton?: boolean;
10
+ }): React.JSX.Element;
11
+ declare function CommandInput({ className, ...props }: React.ComponentProps<typeof Command.Input>): React.JSX.Element;
12
+ declare function CommandList({ className, ...props }: React.ComponentProps<typeof Command.List>): React.JSX.Element;
13
+ declare function CommandEmpty({ ...props }: React.ComponentProps<typeof Command.Empty>): React.JSX.Element;
14
+ declare function CommandGroup({ className, ...props }: React.ComponentProps<typeof Command.Group>): React.JSX.Element;
15
+ declare function CommandSeparator({ className, ...props }: React.ComponentProps<typeof Command.Separator>): React.JSX.Element;
16
+ declare function CommandItem({ className, ...props }: React.ComponentProps<typeof Command.Item>): React.JSX.Element;
17
+ declare function CommandShortcut({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
18
+ export { Command$1 as Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
19
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1,86 @@
1
+ "use client";
2
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./dialog.js";
3
+ import { cn } from "../lib/utils.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { SearchIcon } from "lucide-react";
6
+ import { Command } from "cmdk";
7
+ // src/components/command.tsx
8
+ function Command$1({ className, ...props }) {
9
+ return /* @__PURE__ */ jsx(Command, {
10
+ "data-slot": "command",
11
+ className: cn("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground", className),
12
+ ...props
13
+ });
14
+ }
15
+ function CommandDialog({ title = "Command Palette", description = "Search for a command to run...", children, className, showCloseButton = true, ...props }) {
16
+ return /* @__PURE__ */ jsxs(Dialog, {
17
+ ...props,
18
+ children: [/* @__PURE__ */ jsxs(DialogHeader, {
19
+ className: "sr-only",
20
+ children: [/* @__PURE__ */ jsx(DialogTitle, { children: title }), /* @__PURE__ */ jsx(DialogDescription, { children: description })]
21
+ }), /* @__PURE__ */ jsx(DialogContent, {
22
+ className: cn("overflow-hidden p-0", className),
23
+ showCloseButton,
24
+ children: /* @__PURE__ */ jsx(Command$1, {
25
+ className: "**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5",
26
+ children
27
+ })
28
+ })]
29
+ });
30
+ }
31
+ function CommandInput({ className, ...props }) {
32
+ return /* @__PURE__ */ jsxs("div", {
33
+ "data-slot": "command-input-wrapper",
34
+ className: "flex h-9 items-center gap-2 border-b px-3",
35
+ children: [/* @__PURE__ */ jsx(SearchIcon, { className: "size-4 shrink-0 opacity-50" }), /* @__PURE__ */ jsx(Command.Input, {
36
+ "data-slot": "command-input",
37
+ className: cn("flex h-10 w-full rounded-md bg-transparent py-3 text-body-md outline-hidden sm:text-body-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50", className),
38
+ ...props
39
+ })]
40
+ });
41
+ }
42
+ function CommandList({ className, ...props }) {
43
+ return /* @__PURE__ */ jsx(Command.List, {
44
+ "data-slot": "command-list",
45
+ className: cn("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", className),
46
+ ...props
47
+ });
48
+ }
49
+ function CommandEmpty({ ...props }) {
50
+ return /* @__PURE__ */ jsx(Command.Empty, {
51
+ "data-slot": "command-empty",
52
+ className: "py-6 text-center text-sm",
53
+ ...props
54
+ });
55
+ }
56
+ function CommandGroup({ className, ...props }) {
57
+ return /* @__PURE__ */ jsx(Command.Group, {
58
+ "data-slot": "command-group",
59
+ className: cn("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground", className),
60
+ ...props
61
+ });
62
+ }
63
+ function CommandSeparator({ className, ...props }) {
64
+ return /* @__PURE__ */ jsx(Command.Separator, {
65
+ "data-slot": "command-separator",
66
+ className: cn("-mx-1 h-px bg-border", className),
67
+ ...props
68
+ });
69
+ }
70
+ function CommandItem({ className, ...props }) {
71
+ return /* @__PURE__ */ jsx(Command.Item, {
72
+ "data-slot": "command-item",
73
+ className: cn("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 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground", className),
74
+ ...props
75
+ });
76
+ }
77
+ function CommandShortcut({ className, ...props }) {
78
+ return /* @__PURE__ */ jsx("span", {
79
+ "data-slot": "command-shortcut",
80
+ className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
81
+ ...props
82
+ });
83
+ }
84
+ export { Command$1 as Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
85
+
86
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","names":["Command","CommandPrimitive"],"sources":["../../src/components/command.tsx"],"sourcesContent":["\"use client\";\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"./dialog\";\nimport { cn } from \"../lib/utils\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { SearchIcon } from \"lucide-react\";\nimport type * as React from \"react\";\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string;\n description?: string;\n className?: string;\n showCloseButton?: boolean;\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\"overflow-hidden p-0\", className)}\n showCloseButton={showCloseButton}\n >\n <Command className=\"**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div data-slot=\"command-input-wrapper\" className=\"flex h-9 items-center gap-2 border-b px-3\">\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"flex h-10 w-full rounded-md bg-transparent py-3 text-body-md outline-hidden sm:text-body-sm placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\", className)}\n {...props}\n />\n );\n}\n\nfunction CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"-mx-1 h-px bg-border\", className)}\n {...props}\n />\n );\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"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 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\"ml-auto text-xs tracking-widest text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n};\n"],"mappings":";;;;;;;AAQA,SAASA,UAAQ,EAAE,WAAW,GAAG,SAAwD;CACvF,OACE,oBAACC,SAAD;EACE,aAAU;EACV,WAAW,GACT,6FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EACrB,QAAQ,mBACR,cAAc,kCACd,UACA,WACA,kBAAkB,MAClB,GAAG,SAMF;CACD,OACE,qBAAC,QAAD;EAAQ,GAAI;EAAZ,UAAA,CACE,qBAAC,cAAD;GAAc,WAAU;GAAxB,UAAA,CACE,oBAAC,aAAD,EAAA,UAAc,MAAmB,CAAA,GACjC,oBAAC,mBAAD,EAAA,UAAoB,YAA+B,CAAA,CACvC;EACd,CAAA,GAAA,oBAAC,eAAD;GACE,WAAW,GAAG,uBAAuB,SAAS;GAC7B;GAEjB,UAAA,oBAACD,WAAD;IAAS,WAAU;IAChB;GACM,CAAA;EACI,CAAA,CACT;;AAEZ;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,qBAAC,OAAD;EAAK,aAAU;EAAwB,WAAU;EAAjD,UAAA,CACE,oBAAC,YAAD,EAAY,WAAU,6BAA8B,CAAA,GACpD,oBAACC,QAAiB,OAAlB;GACE,aAAU;GACV,WAAW,GACT,iLACA,SACF;GACA,GAAI;EACL,CAAA,CACE;;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GAAG,+DAA+D,SAAS;EACtF,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EAAE,GAAG,SAA8D;CACvF,OACE,oBAACA,QAAiB,OAAlB;EACE,aAAU;EACV,WAAU;EACV,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,GAAG,SACmD;CACtD,OACE,oBAACA,QAAiB,OAAlB;EACE,aAAU;EACV,WAAW,GACT,0NACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,iBAAiB,EACxB,WACA,GAAG,SACuD;CAC1D,OACE,oBAACA,QAAiB,WAAlB;EACE,aAAU;EACV,WAAW,GAAG,wBAAwB,SAAS;EAC/C,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,QAAiB,MAAlB;EACE,aAAU;EACV,WAAW,GACT,uYACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAuC;CAC9E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,yDAAyD,SAAS;EAChF,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,14 @@
1
+ import * as React from "react";
2
+ export type CtaBannerProps = {
3
+ title: React.ReactNode;
4
+ id?: string;
5
+ text?: React.ReactNode;
6
+ /** Microprint above the title, e.g. "S-05 · START". */
7
+ code?: string;
8
+ /** The call to action, usually a secondary Button (shell on signal). */
9
+ action?: React.ReactNode;
10
+ className?: string;
11
+ };
12
+ /** The whole-signal call to action that closes a page. Text on it is ink, never white. */
13
+ export declare function CtaBanner({ title, id, text, code, action, className }: CtaBannerProps): React.JSX.Element;
14
+ //# sourceMappingURL=cta-banner.d.ts.map
@@ -0,0 +1,39 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Grill } from "./hud.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ // src/components/cta-banner.tsx
5
+ /** The whole-signal call to action that closes a page. Text on it is ink, never white. */
6
+ function CtaBanner({ title, id, text, code, action, className }) {
7
+ return /* @__PURE__ */ jsx("section", {
8
+ id,
9
+ className: cn("relative drop-float", className),
10
+ children: /* @__PURE__ */ jsxs("div", {
11
+ className: "grid items-end gap-8 rounded-xl bg-signal notch-lg p-8 md:grid-cols-[1fr_auto] md:p-12",
12
+ children: [/* @__PURE__ */ jsxs("div", { children: [
13
+ code && /* @__PURE__ */ jsx("div", {
14
+ className: "hud-sm mb-4 text-ink",
15
+ children: code
16
+ }),
17
+ /* @__PURE__ */ jsx("h2", {
18
+ className: "font-display text-display-md text-ink",
19
+ children: title
20
+ }),
21
+ text && /* @__PURE__ */ jsx("p", {
22
+ className: "mt-3 max-w-[32em] text-body-md text-ink",
23
+ children: text
24
+ })
25
+ ] }), /* @__PURE__ */ jsxs("div", {
26
+ className: "flex flex-col items-start gap-6 md:items-end",
27
+ children: [/* @__PURE__ */ jsx(Grill, {
28
+ count: 6,
29
+ tone: "on-signal",
30
+ slotWidth: 30,
31
+ gap: "8px"
32
+ }), action]
33
+ })]
34
+ })
35
+ });
36
+ }
37
+ export { CtaBanner };
38
+
39
+ //# sourceMappingURL=cta-banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cta-banner.js","names":[],"sources":["../../src/components/cta-banner.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Grill } from \"./hud\";\n\nexport type CtaBannerProps = {\n title: React.ReactNode;\n id?: string;\n text?: React.ReactNode;\n /** Microprint above the title, e.g. \"S-05 · START\". */\n code?: string;\n /** The call to action, usually a secondary Button (shell on signal). */\n action?: React.ReactNode;\n className?: string;\n};\n\n/** The whole-signal call to action that closes a page. Text on it is ink, never white. */\nexport function CtaBanner({ title, id, text, code, action, className }: CtaBannerProps) {\n return (\n <section id={id} className={cn(\"relative drop-float\", className)}>\n <div className=\"grid items-end gap-8 rounded-xl bg-signal notch-lg p-8 md:grid-cols-[1fr_auto] md:p-12\">\n <div>\n {code && <div className=\"hud-sm mb-4 text-ink\">{code}</div>}\n <h2 className=\"font-display text-display-md text-ink\">{title}</h2>\n {text && <p className=\"mt-3 max-w-[32em] text-body-md text-ink\">{text}</p>}\n </div>\n <div className=\"flex flex-col items-start gap-6 md:items-end\">\n <Grill count={6} tone=\"on-signal\" slotWidth={30} gap=\"8px\" />\n {action}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;AAgBA,SAAgB,UAAU,EAAE,OAAO,IAAI,MAAM,MAAM,QAAQ,aAA6B;CACtF,OACE,oBAAC,WAAD;EAAa;EAAI,WAAW,GAAG,uBAAuB,SAAS;EAC7D,UAAA,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,qBAAC,OAAD,EAAA,UAAA;IACG,QAAQ,oBAAC,OAAD;KAAK,WAAU;KAAwB,UAAA;IAAU,CAAA;IAC1D,oBAAC,MAAD;KAAI,WAAU;KAAyC,UAAA;IAAU,CAAA;IAChE,QAAQ,oBAAC,KAAD;KAAG,WAAU;KAA2C,UAAA;IAAQ,CAAA;GACtE,EAAA,CAAA,GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,OAAD;KAAO,OAAO;KAAG,MAAK;KAAY,WAAW;KAAI,KAAI;IAAO,CAAA,GAC3D,MACE;GACF,CAAA,CAAA;;CACE,CAAA;AAEb"}
@@ -0,0 +1,19 @@
1
+ /** "YYYY-MM-DD" -> local Date (no time-zone shift). */
2
+ export declare function parseISODate(value: string): Date | undefined;
3
+ /** Local Date -> "YYYY-MM-DD". */
4
+ export declare function toISODate(date: Date): string;
5
+ /** Short field label: "Today, Oct 29", "Yesterday, Oct 28", "Tue, Oct 20", "Mon, Dec 1, 2025". */
6
+ export declare function dateLabel(date: Date, today: Date): string;
7
+ /**
8
+ * A calendar date in a sunken well, opening a Module/01 Calendar with Today and Yesterday
9
+ * shortcuts. Value and onChange use "YYYY-MM-DD" strings.
10
+ */
11
+ export declare function DatePicker({ id, value, onChange, placeholder, disabled, className }: {
12
+ id?: string;
13
+ value: string;
14
+ onChange: (value: string) => void;
15
+ placeholder?: string;
16
+ disabled?: boolean;
17
+ className?: string;
18
+ }): import("react").JSX.Element;
19
+ //# sourceMappingURL=date-picker.d.ts.map
@@ -0,0 +1,107 @@
1
+ "use client";
2
+ import { focusNextField } from "../lib/form-flow.js";
3
+ import { cn } from "../lib/utils.js";
4
+ import { Button } from "./button.js";
5
+ import { Calendar } from "./calendar.js";
6
+ import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { CalendarDays } from "lucide-react";
9
+ import { useRef, useState } from "react";
10
+ import { addDays, format, isSameDay } from "date-fns";
11
+ // src/components/date-picker.tsx
12
+ /** "YYYY-MM-DD" -> local Date (no time-zone shift). */
13
+ function parseISODate(value) {
14
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
15
+ if (!m) return void 0;
16
+ return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
17
+ }
18
+ /** Local Date -> "YYYY-MM-DD". */
19
+ function toISODate(date) {
20
+ return format(date, "yyyy-MM-dd");
21
+ }
22
+ /** Short field label: "Today, Oct 29", "Yesterday, Oct 28", "Tue, Oct 20", "Mon, Dec 1, 2025". */
23
+ function dateLabel(date, today) {
24
+ if (isSameDay(date, today)) return `Today, ${format(date, "MMM d")}`;
25
+ if (isSameDay(date, addDays(today, -1))) return `Yesterday, ${format(date, "MMM d")}`;
26
+ return format(date, date.getFullYear() === today.getFullYear() ? "EEE, MMM d" : "EEE, MMM d, yyyy");
27
+ }
28
+ /**
29
+ * A calendar date in a sunken well, opening a Module/01 Calendar with Today and Yesterday
30
+ * shortcuts. Value and onChange use "YYYY-MM-DD" strings.
31
+ */
32
+ function DatePicker({ id, value, onChange, placeholder = "Pick a date", disabled, className }) {
33
+ const [open, setOpen] = useState(false);
34
+ const selected = parseISODate(value);
35
+ const [month, setMonth] = useState(selected ?? /* @__PURE__ */ new Date());
36
+ const today = /* @__PURE__ */ new Date();
37
+ const trigger = useRef(null);
38
+ const committed = useRef(false);
39
+ function openChange(next) {
40
+ if (next) setMonth(selected ?? /* @__PURE__ */ new Date());
41
+ setOpen(next);
42
+ }
43
+ function pick(date) {
44
+ onChange(toISODate(date));
45
+ committed.current = true;
46
+ setOpen(false);
47
+ }
48
+ const label = selected ? dateLabel(selected, today) : placeholder;
49
+ return /* @__PURE__ */ jsxs(Popover, {
50
+ open,
51
+ onOpenChange: openChange,
52
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
53
+ asChild: true,
54
+ children: /* @__PURE__ */ jsxs("button", {
55
+ ref: trigger,
56
+ "data-flow-field": true,
57
+ id,
58
+ type: "button",
59
+ disabled,
60
+ className: cn("flex h-control-height w-full min-w-0 cursor-pointer items-center gap-3 rounded-md border border-transparent bg-shell-recess px-4 text-left text-body-md text-ink shadow-press outline-none transition-[box-shadow,border-color] disabled:pointer-events-none disabled:opacity-50", "focus-visible:border-signal-ink focus-visible:ring-[3px] focus-visible:ring-ring/30 data-[state=open]:border-signal-ink", className),
61
+ children: [/* @__PURE__ */ jsx(CalendarDays, {
62
+ className: "size-4 shrink-0 text-ink-soft",
63
+ strokeWidth: 1.25
64
+ }), /* @__PURE__ */ jsx("span", {
65
+ className: cn("truncate", !selected && "text-ink-soft"),
66
+ children: label
67
+ })]
68
+ })
69
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
70
+ align: "start",
71
+ className: "w-auto rounded-lg p-3",
72
+ onCloseAutoFocus: (e) => {
73
+ if (!committed.current) return;
74
+ committed.current = false;
75
+ e.preventDefault();
76
+ focusNextField(trigger.current);
77
+ },
78
+ children: [/* @__PURE__ */ jsx(Calendar, {
79
+ mode: "single",
80
+ required: true,
81
+ selected,
82
+ onSelect: pick,
83
+ month,
84
+ onMonthChange: setMonth,
85
+ autoFocus: true
86
+ }), /* @__PURE__ */ jsxs("div", {
87
+ className: "mt-3 flex gap-2 border-t border-seam pt-3",
88
+ children: [/* @__PURE__ */ jsx(Button, {
89
+ type: "button",
90
+ size: "xs",
91
+ variant: "secondary",
92
+ onClick: () => pick(today),
93
+ children: "Today"
94
+ }), /* @__PURE__ */ jsx(Button, {
95
+ type: "button",
96
+ size: "xs",
97
+ variant: "secondary",
98
+ onClick: () => pick(addDays(today, -1)),
99
+ children: "Yesterday"
100
+ })]
101
+ })]
102
+ })]
103
+ });
104
+ }
105
+ export { DatePicker, dateLabel, parseISODate, toISODate };
106
+
107
+ //# sourceMappingURL=date-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-picker.js","names":[],"sources":["../../src/components/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { focusNextField } from \"../lib/form-flow\";\nimport { cn } from \"../lib/utils\";\nimport { addDays, format, isSameDay } from \"date-fns\";\nimport { CalendarDays } from \"lucide-react\";\nimport { useRef, useState } from \"react\";\nimport { Button } from \"./button\";\nimport { Calendar } from \"./calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\n/** \"YYYY-MM-DD\" -> local Date (no time-zone shift). */\nexport function parseISODate(value: string): Date | undefined {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!m) return undefined;\n return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n}\n\n/** Local Date -> \"YYYY-MM-DD\". */\nexport function toISODate(date: Date): string {\n return format(date, \"yyyy-MM-dd\");\n}\n\n/** Short field label: \"Today, Oct 29\", \"Yesterday, Oct 28\", \"Tue, Oct 20\", \"Mon, Dec 1, 2025\". */\nexport function dateLabel(date: Date, today: Date): string {\n if (isSameDay(date, today)) return `Today, ${format(date, \"MMM d\")}`;\n if (isSameDay(date, addDays(today, -1))) return `Yesterday, ${format(date, \"MMM d\")}`;\n return format(\n date,\n date.getFullYear() === today.getFullYear() ? \"EEE, MMM d\" : \"EEE, MMM d, yyyy\",\n );\n}\n\n/**\n * A calendar date in a sunken well, opening a Module/01 Calendar with Today and Yesterday\n * shortcuts. Value and onChange use \"YYYY-MM-DD\" strings.\n */\nexport function DatePicker({\n id,\n value,\n onChange,\n placeholder = \"Pick a date\",\n disabled,\n className,\n}: {\n id?: string;\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n}) {\n const [open, setOpen] = useState(false);\n const selected = parseISODate(value);\n const [month, setMonth] = useState<Date>(selected ?? new Date());\n const today = new Date();\n const trigger = useRef<HTMLButtonElement>(null);\n const committed = useRef(false);\n\n function openChange(next: boolean) {\n if (next) setMonth(selected ?? new Date());\n setOpen(next);\n }\n\n function pick(date: Date) {\n onChange(toISODate(date));\n committed.current = true;\n setOpen(false);\n }\n\n const label = selected ? dateLabel(selected, today) : placeholder;\n\n return (\n <Popover open={open} onOpenChange={openChange}>\n <PopoverTrigger asChild>\n <button\n ref={trigger}\n data-flow-field\n id={id}\n type=\"button\"\n disabled={disabled}\n className={cn(\n \"flex h-control-height w-full min-w-0 cursor-pointer items-center gap-3 rounded-md border border-transparent bg-shell-recess px-4 text-left text-body-md text-ink shadow-press outline-none transition-[box-shadow,border-color] disabled:pointer-events-none disabled:opacity-50\",\n \"focus-visible:border-signal-ink focus-visible:ring-[3px] focus-visible:ring-ring/30 data-[state=open]:border-signal-ink\",\n className,\n )}\n >\n <CalendarDays className=\"size-4 shrink-0 text-ink-soft\" strokeWidth={1.25} />\n <span className={cn(\"truncate\", !selected && \"text-ink-soft\")}>{label}</span>\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-auto rounded-lg p-3\"\n onCloseAutoFocus={(e) => {\n // Form flow: after picking a date, move on to the next field.\n if (!committed.current) return;\n committed.current = false;\n e.preventDefault();\n focusNextField(trigger.current);\n }}\n >\n <Calendar\n mode=\"single\"\n required\n selected={selected}\n onSelect={pick}\n month={month}\n onMonthChange={setMonth}\n autoFocus\n />\n <div className=\"mt-3 flex gap-2 border-t border-seam pt-3\">\n <Button type=\"button\" size=\"xs\" variant=\"secondary\" onClick={() => pick(today)}>\n Today\n </Button>\n <Button\n type=\"button\"\n size=\"xs\"\n variant=\"secondary\"\n onClick={() => pick(addDays(today, -1))}\n >\n Yesterday\n </Button>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,aAAa,OAAiC;CAC5D,MAAM,IAAI,4BAA4B,KAAK,KAAK;CAChD,IAAI,CAAC,GAAG,OAAO,KAAA;CACf,OAAO,IAAI,KAAK,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,IAAI,GAAG,OAAO,EAAE,EAAE,CAAC;AAC9D;;AAGA,SAAgB,UAAU,MAAoB;CAC5C,OAAO,OAAO,MAAM,YAAY;AAClC;;AAGA,SAAgB,UAAU,MAAY,OAAqB;CACzD,IAAI,UAAU,MAAM,KAAK,GAAG,OAAO,UAAU,OAAO,MAAM,OAAO;CACjE,IAAI,UAAU,MAAM,QAAQ,OAAO,EAAE,CAAC,GAAG,OAAO,cAAc,OAAO,MAAM,OAAO;CAClF,OAAO,OACL,MACA,KAAK,YAAY,MAAM,MAAM,YAAY,IAAI,eAAe,kBAC9D;AACF;;;;;AAMA,SAAgB,WAAW,EACzB,IACA,OACA,UACA,cAAc,eACd,UACA,aAQC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,WAAW,aAAa,KAAK;CACnC,MAAM,CAAC,OAAO,YAAY,SAAe,4BAAY,IAAI,KAAK,CAAC;CAC/D,MAAM,wBAAQ,IAAI,KAAK;CACvB,MAAM,UAAU,OAA0B,IAAI;CAC9C,MAAM,YAAY,OAAO,KAAK;CAE9B,SAAS,WAAW,MAAe;EACjC,IAAI,MAAM,SAAS,4BAAY,IAAI,KAAK,CAAC;EACzC,QAAQ,IAAI;CACd;CAEA,SAAS,KAAK,MAAY;EACxB,SAAS,UAAU,IAAI,CAAC;EACxB,UAAU,UAAU;EACpB,QAAQ,KAAK;CACf;CAEA,MAAM,QAAQ,WAAW,UAAU,UAAU,KAAK,IAAI;CAEtD,OACE,qBAAC,SAAD;EAAe;EAAM,cAAc;EAAnC,UAAA,CACE,oBAAC,gBAAD;GAAgB,SAAA;GACd,UAAA,qBAAC,UAAD;IACE,KAAK;IACL,mBAAA;IACI;IACJ,MAAK;IACK;IACV,WAAW,GACT,oRACA,2HACA,SACF;IAVF,UAAA,CAYE,oBAAC,cAAD;KAAc,WAAU;KAAgC,aAAa;IAAO,CAAA,GAC5E,oBAAC,QAAD;KAAM,WAAW,GAAG,YAAY,CAAC,YAAY,eAAe;KAAI,UAAA;IAAY,CAAA,CACtE;;EACM,CAAA,GAChB,qBAAC,gBAAD;GACE,OAAM;GACN,WAAU;GACV,mBAAmB,MAAM;IAEvB,IAAI,CAAC,UAAU,SAAS;IACxB,UAAU,UAAU;IACpB,EAAE,eAAe;IACjB,eAAe,QAAQ,OAAO;GAChC;GATF,UAAA,CAWE,oBAAC,UAAD;IACE,MAAK;IACL,UAAA;IACU;IACV,UAAU;IACH;IACP,eAAe;IACf,WAAA;GACD,CAAA,GACD,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,QAAD;KAAQ,MAAK;KAAS,MAAK;KAAK,SAAQ;KAAY,eAAe,KAAK,KAAK;KAAG,UAAA;IAExE,CAAA,GACR,oBAAC,QAAD;KACE,MAAK;KACL,MAAK;KACL,SAAQ;KACR,eAAe,KAAK,QAAQ,OAAO,EAAE,CAAC;KACvC,UAAA;IAEO,CAAA,CACL;GACS,CAAA,CAAA;EACT,CAAA,CAAA;;AAEb"}
@@ -0,0 +1,18 @@
1
+ import { Dialog } from "radix-ui";
2
+ import * as React from "react";
3
+ declare function Dialog$1({ ...props }: React.ComponentProps<typeof Dialog.Root>): React.JSX.Element;
4
+ declare function DialogTrigger({ ...props }: React.ComponentProps<typeof Dialog.Trigger>): React.JSX.Element;
5
+ declare function DialogPortal({ ...props }: React.ComponentProps<typeof Dialog.Portal>): React.JSX.Element;
6
+ declare function DialogClose({ ...props }: React.ComponentProps<typeof Dialog.Close>): React.JSX.Element;
7
+ declare function DialogOverlay({ className, ...props }: React.ComponentProps<typeof Dialog.Overlay>): React.JSX.Element;
8
+ declare function DialogContent({ className, children, showCloseButton, onOpenAutoFocus, ...props }: React.ComponentProps<typeof Dialog.Content> & {
9
+ showCloseButton?: boolean;
10
+ }): React.JSX.Element;
11
+ declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
12
+ declare function DialogFooter({ className, showCloseButton, children, ...props }: React.ComponentProps<"div"> & {
13
+ showCloseButton?: boolean;
14
+ }): React.JSX.Element;
15
+ declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof Dialog.Title>): React.JSX.Element;
16
+ declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof Dialog.Description>): React.JSX.Element;
17
+ export { Dialog$1 as Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger };
18
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import { Button } from "./button.js";
3
+ import { focusFirstField } from "../lib/form-flow.js";
4
+ import { cn } from "../lib/utils.js";
5
+ import { Dialog } from "radix-ui";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { XIcon } from "lucide-react";
8
+ // src/components/dialog.tsx
9
+ function Dialog$1({ ...props }) {
10
+ return /* @__PURE__ */ jsx(Dialog.Root, {
11
+ "data-slot": "dialog",
12
+ ...props
13
+ });
14
+ }
15
+ function DialogTrigger({ ...props }) {
16
+ return /* @__PURE__ */ jsx(Dialog.Trigger, {
17
+ "data-slot": "dialog-trigger",
18
+ ...props
19
+ });
20
+ }
21
+ function DialogPortal({ ...props }) {
22
+ return /* @__PURE__ */ jsx(Dialog.Portal, {
23
+ "data-slot": "dialog-portal",
24
+ ...props
25
+ });
26
+ }
27
+ function DialogClose({ ...props }) {
28
+ return /* @__PURE__ */ jsx(Dialog.Close, {
29
+ "data-slot": "dialog-close",
30
+ ...props
31
+ });
32
+ }
33
+ function DialogOverlay({ className, ...props }) {
34
+ return /* @__PURE__ */ jsx(Dialog.Overlay, {
35
+ "data-slot": "dialog-overlay",
36
+ className: cn("fixed inset-0 z-50 bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0", className),
37
+ ...props
38
+ });
39
+ }
40
+ function DialogContent({ className, children, showCloseButton = true, onOpenAutoFocus, ...props }) {
41
+ return /* @__PURE__ */ jsxs(DialogPortal, {
42
+ "data-slot": "dialog-portal",
43
+ children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(Dialog.Content, {
44
+ "data-slot": "dialog-content",
45
+ className: cn("fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-float duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg", className),
46
+ ...props,
47
+ onOpenAutoFocus: (e) => {
48
+ onOpenAutoFocus?.(e);
49
+ if (!e.defaultPrevented && focusFirstField(e.currentTarget)) e.preventDefault();
50
+ },
51
+ children: [children, showCloseButton && /* @__PURE__ */ jsxs(Dialog.Close, {
52
+ "data-slot": "dialog-close",
53
+ className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
54
+ children: [/* @__PURE__ */ jsx(XIcon, {}), /* @__PURE__ */ jsx("span", {
55
+ className: "sr-only",
56
+ children: "Close"
57
+ })]
58
+ })]
59
+ })]
60
+ });
61
+ }
62
+ function DialogHeader({ className, ...props }) {
63
+ return /* @__PURE__ */ jsx("div", {
64
+ "data-slot": "dialog-header",
65
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
66
+ ...props
67
+ });
68
+ }
69
+ function DialogFooter({ className, showCloseButton = false, children, ...props }) {
70
+ return /* @__PURE__ */ jsxs("div", {
71
+ "data-slot": "dialog-footer",
72
+ className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
73
+ ...props,
74
+ children: [children, showCloseButton && /* @__PURE__ */ jsx(Dialog.Close, {
75
+ asChild: true,
76
+ children: /* @__PURE__ */ jsx(Button, {
77
+ variant: "outline",
78
+ children: "Close"
79
+ })
80
+ })]
81
+ });
82
+ }
83
+ function DialogTitle({ className, ...props }) {
84
+ return /* @__PURE__ */ jsx(Dialog.Title, {
85
+ "data-slot": "dialog-title",
86
+ className: cn("text-lg leading-none font-semibold", className),
87
+ ...props
88
+ });
89
+ }
90
+ function DialogDescription({ className, ...props }) {
91
+ return /* @__PURE__ */ jsx(Dialog.Description, {
92
+ "data-slot": "dialog-description",
93
+ className: cn("text-sm text-muted-foreground", className),
94
+ ...props
95
+ });
96
+ }
97
+ export { Dialog$1 as Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger };
98
+
99
+ //# sourceMappingURL=dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","names":["Dialog","DialogPrimitive"],"sources":["../../src/components/dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { Button } from \"./button\";\nimport { focusFirstField } from \"../lib/form-flow\";\nimport { cn } from \"../lib/utils\";\nimport { XIcon } from \"lucide-react\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\n\nfunction Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n onOpenAutoFocus,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-float duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg\",\n className,\n )}\n {...props}\n onOpenAutoFocus={(e) => {\n // Form flow: open on the first field rather than the close button or tabs.\n onOpenAutoFocus?.(e);\n if (!e.defaultPrevented && focusFirstField(e.currentTarget as HTMLElement)) {\n e.preventDefault();\n }\n }}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean;\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close asChild>\n <Button variant=\"outline\">Close</Button>\n </DialogPrimitive.Close>\n )}\n </div>\n );\n}\n\nfunction DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n"],"mappings":";;;;;;;;AASA,SAASA,SAAO,EAAE,GAAG,SAA4D;CAC/E,OAAO,oBAACC,OAAgB,MAAjB;EAAsB,aAAU;EAAS,GAAI;CAAQ,CAAA;AAC9D;AAEA,SAAS,cAAc,EAAE,GAAG,SAA+D;CACzF,OAAO,oBAACA,OAAgB,SAAjB;EAAyB,aAAU;EAAiB,GAAI;CAAQ,CAAA;AACzE;AAEA,SAAS,aAAa,EAAE,GAAG,SAA8D;CACvF,OAAO,oBAACA,OAAgB,QAAjB;EAAwB,aAAU;EAAgB,GAAI;CAAQ,CAAA;AACvE;AAEA,SAAS,YAAY,EAAE,GAAG,SAA6D;CACrF,OAAO,oBAACA,OAAgB,OAAjB;EAAuB,aAAU;EAAe,GAAI;CAAQ,CAAA;AACrE;AAEA,SAAS,cAAc,EACrB,WACA,GAAG,SACoD;CACvD,OACE,oBAACA,OAAgB,SAAjB;EACE,aAAU;EACV,WAAW,GACT,yJACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EACrB,WACA,UACA,kBAAkB,MAClB,iBACA,GAAG,SAGF;CACD,OACE,qBAAC,cAAD;EAAc,aAAU;EAAxB,UAAA,CACE,oBAAC,eAAD,CAAgB,CAAA,GAChB,qBAACA,OAAgB,SAAjB;GACE,aAAU;GACV,WAAW,GACT,+XACA,SACF;GACA,GAAI;GACJ,kBAAkB,MAAM;IAEtB,kBAAkB,CAAC;IACnB,IAAI,CAAC,EAAE,oBAAoB,gBAAgB,EAAE,aAA4B,GACvE,EAAE,eAAe;GAErB;GAbF,UAAA,CAeG,UACA,mBACC,qBAACA,OAAgB,OAAjB;IACE,aAAU;IACV,WAAU;IAFZ,UAAA,CAIE,oBAAC,OAAD,CAAQ,CAAA,GACR,oBAAC,QAAD;KAAM,WAAU;KAAU,UAAA;IAAW,CAAA,CAChB;GAEF,CAAA,CAAA;EACb,CAAA,CAAA;;AAElB;AAEA,SAAS,aAAa,EAAE,WAAW,GAAG,SAAsC;CAC1E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,gDAAgD,SAAS;EACvE,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,aAAa,EACpB,WACA,kBAAkB,OAClB,UACA,GAAG,SAGF;CACD,OACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,0DAA0D,SAAS;EACjF,GAAI;EAHN,UAAA,CAKG,UACA,mBACC,oBAACA,OAAgB,OAAjB;GAAuB,SAAA;GACrB,UAAA,oBAAC,QAAD;IAAQ,SAAQ;IAAU,UAAA;GAAa,CAAA;EAClB,CAAA,CAEtB;;AAET;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,OACE,oBAACA,OAAgB,OAAjB;EACE,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,kBAAkB,EACzB,WACA,GAAG,SACwD;CAC3D,OACE,oBAACA,OAAgB,aAAjB;EACE,aAAU;EACV,WAAW,GAAG,iCAAiC,SAAS;EACxD,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,26 @@
1
+ import { DropdownMenu } from "radix-ui";
2
+ import * as React from "react";
3
+ declare function DropdownMenu$1({ ...props }: React.ComponentProps<typeof DropdownMenu.Root>): React.JSX.Element;
4
+ declare function DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenu.Portal>): React.JSX.Element;
5
+ declare function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenu.Trigger>): React.JSX.Element;
6
+ declare function DropdownMenuContent({ className, sideOffset, ...props }: React.ComponentProps<typeof DropdownMenu.Content>): React.JSX.Element;
7
+ declare function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenu.Group>): React.JSX.Element;
8
+ declare function DropdownMenuItem({ className, inset, variant, ...props }: React.ComponentProps<typeof DropdownMenu.Item> & {
9
+ inset?: boolean;
10
+ variant?: "default" | "destructive";
11
+ }): React.JSX.Element;
12
+ declare function DropdownMenuCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof DropdownMenu.CheckboxItem>): React.JSX.Element;
13
+ declare function DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenu.RadioGroup>): React.JSX.Element;
14
+ declare function DropdownMenuRadioItem({ className, children, ...props }: React.ComponentProps<typeof DropdownMenu.RadioItem>): React.JSX.Element;
15
+ declare function DropdownMenuLabel({ className, inset, ...props }: React.ComponentProps<typeof DropdownMenu.Label> & {
16
+ inset?: boolean;
17
+ }): React.JSX.Element;
18
+ declare function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenu.Separator>): React.JSX.Element;
19
+ declare function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
20
+ declare function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenu.Sub>): React.JSX.Element;
21
+ declare function DropdownMenuSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof DropdownMenu.SubTrigger> & {
22
+ inset?: boolean;
23
+ }): React.JSX.Element;
24
+ declare function DropdownMenuSubContent({ className, ...props }: React.ComponentProps<typeof DropdownMenu.SubContent>): React.JSX.Element;
25
+ export { DropdownMenu$1 as DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
26
+ //# sourceMappingURL=dropdown-menu.d.ts.map