@craftzbay/ui 0.8.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/README.md +72 -6
  2. package/dist-lib/components/ui/Accordion.js +60 -0
  3. package/dist-lib/components/ui/Accordion.js.map +1 -0
  4. package/dist-lib/components/ui/Alert.d.ts +1 -1
  5. package/dist-lib/components/ui/Alert.js +66 -0
  6. package/dist-lib/components/ui/Alert.js.map +1 -0
  7. package/dist-lib/components/ui/Avatar.d.ts +2 -2
  8. package/dist-lib/components/ui/Avatar.js +96 -0
  9. package/dist-lib/components/ui/Avatar.js.map +1 -0
  10. package/dist-lib/components/ui/Badge.d.ts +1 -1
  11. package/dist-lib/components/ui/Badge.js +67 -0
  12. package/dist-lib/components/ui/Badge.js.map +1 -0
  13. package/dist-lib/components/ui/Breadcrumbs.js +34 -0
  14. package/dist-lib/components/ui/Breadcrumbs.js.map +1 -0
  15. package/dist-lib/components/ui/Button.d.ts +1 -1
  16. package/dist-lib/components/ui/Button.js +117 -0
  17. package/dist-lib/components/ui/Button.js.map +1 -0
  18. package/dist-lib/components/ui/Calendar.d.ts +7 -1
  19. package/dist-lib/components/ui/Calendar.js +111 -0
  20. package/dist-lib/components/ui/Calendar.js.map +1 -0
  21. package/dist-lib/components/ui/Card.d.ts +1 -1
  22. package/dist-lib/components/ui/Card.js +116 -0
  23. package/dist-lib/components/ui/Card.js.map +1 -0
  24. package/dist-lib/components/ui/Carousel.d.ts +5 -1
  25. package/dist-lib/components/ui/Carousel.js +143 -0
  26. package/dist-lib/components/ui/Carousel.js.map +1 -0
  27. package/dist-lib/components/ui/Chart.d.ts +26 -4
  28. package/dist-lib/components/ui/Chart.js +253 -0
  29. package/dist-lib/components/ui/Chart.js.map +1 -0
  30. package/dist-lib/components/ui/Checkbox.js +56 -0
  31. package/dist-lib/components/ui/Checkbox.js.map +1 -0
  32. package/dist-lib/components/ui/Combobox.d.ts +7 -0
  33. package/dist-lib/components/ui/Combobox.js +164 -0
  34. package/dist-lib/components/ui/Combobox.js.map +1 -0
  35. package/dist-lib/components/ui/CommandPalette.d.ts +3 -3
  36. package/dist-lib/components/ui/CommandPalette.js +174 -0
  37. package/dist-lib/components/ui/CommandPalette.js.map +1 -0
  38. package/dist-lib/components/ui/ContextMenu.js +150 -0
  39. package/dist-lib/components/ui/ContextMenu.js.map +1 -0
  40. package/dist-lib/components/ui/DataGrid.js +84 -0
  41. package/dist-lib/components/ui/DataGrid.js.map +1 -0
  42. package/dist-lib/components/ui/DatePicker.d.ts +16 -13
  43. package/dist-lib/components/ui/DatePicker.js +174 -0
  44. package/dist-lib/components/ui/DatePicker.js.map +1 -0
  45. package/dist-lib/components/ui/DesignSystemProvider.d.ts +8 -1
  46. package/dist-lib/components/ui/DesignSystemProvider.js +79 -0
  47. package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -0
  48. package/dist-lib/components/ui/Dialog.d.ts +1 -1
  49. package/dist-lib/components/ui/Dialog.js +140 -0
  50. package/dist-lib/components/ui/Dialog.js.map +1 -0
  51. package/dist-lib/components/ui/Drawer.d.ts +6 -0
  52. package/dist-lib/components/ui/Drawer.js +98 -0
  53. package/dist-lib/components/ui/Drawer.js.map +1 -0
  54. package/dist-lib/components/ui/DropdownMenu.js +164 -0
  55. package/dist-lib/components/ui/DropdownMenu.js.map +1 -0
  56. package/dist-lib/components/ui/EmptyState.js +32 -0
  57. package/dist-lib/components/ui/EmptyState.js.map +1 -0
  58. package/dist-lib/components/ui/ErrorState.js +48 -0
  59. package/dist-lib/components/ui/ErrorState.js.map +1 -0
  60. package/dist-lib/components/ui/FileUpload.d.ts +3 -0
  61. package/dist-lib/components/ui/FileUpload.js +108 -0
  62. package/dist-lib/components/ui/FileUpload.js.map +1 -0
  63. package/dist-lib/components/ui/Form.d.ts +1 -0
  64. package/dist-lib/components/ui/Form.js +105 -0
  65. package/dist-lib/components/ui/Form.js.map +1 -0
  66. package/dist-lib/components/ui/Icon.d.ts +34 -0
  67. package/dist-lib/components/ui/Icon.js +26 -0
  68. package/dist-lib/components/ui/Icon.js.map +1 -0
  69. package/dist-lib/components/ui/IconButton.d.ts +1 -1
  70. package/dist-lib/components/ui/IconButton.js +56 -0
  71. package/dist-lib/components/ui/IconButton.js.map +1 -0
  72. package/dist-lib/components/ui/Input.d.ts +6 -3
  73. package/dist-lib/components/ui/Input.js +135 -0
  74. package/dist-lib/components/ui/Input.js.map +1 -0
  75. package/dist-lib/components/ui/Kbd.js +24 -0
  76. package/dist-lib/components/ui/Kbd.js.map +1 -0
  77. package/dist-lib/components/ui/MultiSelect.d.ts +3 -1
  78. package/dist-lib/components/ui/MultiSelect.js +196 -0
  79. package/dist-lib/components/ui/MultiSelect.js.map +1 -0
  80. package/dist-lib/components/ui/Pagination.d.ts +23 -0
  81. package/dist-lib/components/ui/Pagination.js +148 -0
  82. package/dist-lib/components/ui/Pagination.js.map +1 -0
  83. package/dist-lib/components/ui/Popover.js +35 -0
  84. package/dist-lib/components/ui/Popover.js.map +1 -0
  85. package/dist-lib/components/ui/Progress.js +95 -0
  86. package/dist-lib/components/ui/Progress.js.map +1 -0
  87. package/dist-lib/components/ui/RadioGroup.js +64 -0
  88. package/dist-lib/components/ui/RadioGroup.js.map +1 -0
  89. package/dist-lib/components/ui/ScrollArea.js +44 -0
  90. package/dist-lib/components/ui/ScrollArea.js.map +1 -0
  91. package/dist-lib/components/ui/Select.js +131 -0
  92. package/dist-lib/components/ui/Select.js.map +1 -0
  93. package/dist-lib/components/ui/Separator.js +26 -0
  94. package/dist-lib/components/ui/Separator.js.map +1 -0
  95. package/dist-lib/components/ui/Sheet.d.ts +1 -1
  96. package/dist-lib/components/ui/Sheet.js +113 -0
  97. package/dist-lib/components/ui/Sheet.js.map +1 -0
  98. package/dist-lib/components/ui/Sidebar.d.ts +18 -6
  99. package/dist-lib/components/ui/Sidebar.js +169 -0
  100. package/dist-lib/components/ui/Sidebar.js.map +1 -0
  101. package/dist-lib/components/ui/Skeleton.js +28 -0
  102. package/dist-lib/components/ui/Skeleton.js.map +1 -0
  103. package/dist-lib/components/ui/Slider.js +52 -0
  104. package/dist-lib/components/ui/Slider.js.map +1 -0
  105. package/dist-lib/components/ui/Snackbar.d.ts +1 -1
  106. package/dist-lib/components/ui/Snackbar.js +56 -0
  107. package/dist-lib/components/ui/Snackbar.js.map +1 -0
  108. package/dist-lib/components/ui/Spinner.js +42 -0
  109. package/dist-lib/components/ui/Spinner.js.map +1 -0
  110. package/dist-lib/components/ui/Stepper.js +88 -0
  111. package/dist-lib/components/ui/Stepper.js.map +1 -0
  112. package/dist-lib/components/ui/Switch.js +77 -0
  113. package/dist-lib/components/ui/Switch.js.map +1 -0
  114. package/dist-lib/components/ui/Table.d.ts +9 -1
  115. package/dist-lib/components/ui/Table.js +157 -0
  116. package/dist-lib/components/ui/Table.js.map +1 -0
  117. package/dist-lib/components/ui/Tabs.d.ts +1 -1
  118. package/dist-lib/components/ui/Tabs.js +89 -0
  119. package/dist-lib/components/ui/Tabs.js.map +1 -0
  120. package/dist-lib/components/ui/TagInput.d.ts +17 -2
  121. package/dist-lib/components/ui/TagInput.js +111 -0
  122. package/dist-lib/components/ui/TagInput.js.map +1 -0
  123. package/dist-lib/components/ui/Textarea.js +77 -0
  124. package/dist-lib/components/ui/Textarea.js.map +1 -0
  125. package/dist-lib/components/ui/Timeline.d.ts +16 -6
  126. package/dist-lib/components/ui/Timeline.js +52 -0
  127. package/dist-lib/components/ui/Timeline.js.map +1 -0
  128. package/dist-lib/components/ui/Toast.d.ts +1 -1
  129. package/dist-lib/components/ui/Toast.js +171 -0
  130. package/dist-lib/components/ui/Toast.js.map +1 -0
  131. package/dist-lib/components/ui/Tooltip.js +58 -0
  132. package/dist-lib/components/ui/Tooltip.js.map +1 -0
  133. package/dist-lib/components/ui/TopNav.js +52 -0
  134. package/dist-lib/components/ui/TopNav.js.map +1 -0
  135. package/dist-lib/components/ui/Tree.d.ts +27 -5
  136. package/dist-lib/components/ui/Tree.js +167 -0
  137. package/dist-lib/components/ui/Tree.js.map +1 -0
  138. package/dist-lib/hooks/use-field-ids.d.ts +29 -0
  139. package/dist-lib/hooks/use-field-ids.js +18 -0
  140. package/dist-lib/hooks/use-field-ids.js.map +1 -0
  141. package/dist-lib/hooks/use-media-query.js +18 -0
  142. package/dist-lib/hooks/use-media-query.js.map +1 -0
  143. package/dist-lib/hooks/use-strings.d.ts +5 -0
  144. package/dist-lib/hooks/use-strings.js +12 -0
  145. package/dist-lib/hooks/use-strings.js.map +1 -0
  146. package/dist-lib/hooks/use-toast.js +36 -0
  147. package/dist-lib/hooks/use-toast.js.map +1 -0
  148. package/dist-lib/icon.d.ts +8 -0
  149. package/dist-lib/icon.js +7 -0
  150. package/dist-lib/icon.js.map +1 -0
  151. package/dist-lib/icons/index.d.ts +71 -11
  152. package/dist-lib/icons/index.js +145 -0
  153. package/dist-lib/icons/index.js.map +1 -0
  154. package/dist-lib/illustrations/index.js +105 -0
  155. package/dist-lib/illustrations/index.js.map +1 -0
  156. package/dist-lib/index.d.ts +62 -58
  157. package/dist-lib/index.js +268 -4386
  158. package/dist-lib/index.js.map +1 -1
  159. package/dist-lib/lib/strings.d.ts +129 -0
  160. package/dist-lib/lib/strings.js +85 -0
  161. package/dist-lib/lib/strings.js.map +1 -0
  162. package/dist-lib/lib/strings.mn.d.ts +3 -0
  163. package/dist-lib/lib/strings.mn.js +70 -0
  164. package/dist-lib/lib/strings.mn.js.map +1 -0
  165. package/dist-lib/lib/utils.d.ts +0 -1
  166. package/dist-lib/lib/utils.js +10 -0
  167. package/dist-lib/lib/utils.js.map +1 -0
  168. package/dist-lib/styles.css +1 -1
  169. package/dist-lib/theme.css +777 -0
  170. package/package.json +31 -8
  171. package/dist-lib/index.cjs +0 -8
  172. package/dist-lib/index.cjs.map +0 -1
@@ -0,0 +1,111 @@
1
+ "use client";
2
+ import { jsxs as u, jsx as o } from "react/jsx-runtime";
3
+ import { forwardRef as q, useState as I, useCallback as A } from "react";
4
+ import { X as G } from "../../icons/index.js";
5
+ import { cn as f } from "../../lib/utils.js";
6
+ import { useStrings as J } from "../../hooks/use-strings.js";
7
+ import { formatString as L } from "../../lib/strings.js";
8
+ import { useFieldIds as O } from "../../hooks/use-field-ids.js";
9
+ const P = q(function({
10
+ value: a,
11
+ defaultValue: N = [],
12
+ onChange: i,
13
+ label: m,
14
+ hideLabel: k,
15
+ description: s,
16
+ placeholder: B,
17
+ max: g,
18
+ disabled: p,
19
+ error: l,
20
+ separators: E = ["Enter", ","],
21
+ id: D,
22
+ "aria-describedby": S,
23
+ "aria-label": T,
24
+ className: j
25
+ }, F) {
26
+ const [K, $] = I(N), [n, d] = I(""), r = a ?? K, h = J(), z = B ?? h.tagInput.placeholder, c = !!l, b = c && l !== !0, { fieldId: x, helperId: H, errorId: M, describedBy: R } = O(D, {
27
+ hasHelper: !!s,
28
+ hasError: b,
29
+ extra: S
30
+ }), v = A(
31
+ (e) => {
32
+ a === void 0 && $(e), i == null || i(e);
33
+ },
34
+ [i, a]
35
+ ), y = (e) => {
36
+ const t = e.trim();
37
+ !t || r.includes(t) || g !== void 0 && r.length >= g || v([...r, t]);
38
+ }, w = (e) => v(r.filter((t, _) => _ !== e)), X = (e) => {
39
+ E.includes(e.key) ? (e.preventDefault(), y(n), d("")) : e.key === "Backspace" && !n && r.length && w(r.length - 1);
40
+ };
41
+ return /* @__PURE__ */ u("div", { ref: F, className: f("flex flex-col gap-1.5", j), children: [
42
+ m && /* @__PURE__ */ o(
43
+ "label",
44
+ {
45
+ htmlFor: x,
46
+ className: f("text-foreground text-sm font-medium", k && "sr-only"),
47
+ children: m
48
+ }
49
+ ),
50
+ /* @__PURE__ */ u(
51
+ "div",
52
+ {
53
+ className: f(
54
+ // Cap growth at ~3 chip rows and scroll inside — an unbounded field
55
+ // pushes the surrounding layout around as tags are added.
56
+ "bg-card flex max-h-24 min-h-9 w-full flex-wrap items-center gap-1.5 overflow-y-auto rounded-md border px-2 py-1.5",
57
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
58
+ "focus-within:ring-offset-background focus-within:ring-2 focus-within:ring-offset-2",
59
+ c ? "border-danger focus-within:border-danger focus-within:ring-danger" : "border-border focus-within:border-accent focus-within:ring-ring",
60
+ p && "pointer-events-none opacity-50"
61
+ ),
62
+ children: [
63
+ r.map((e, t) => /* @__PURE__ */ u(
64
+ "span",
65
+ {
66
+ className: "bg-background-muted inline-flex items-center gap-1 rounded-sm px-2 py-0.5 text-xs",
67
+ children: [
68
+ e,
69
+ /* @__PURE__ */ o(
70
+ "button",
71
+ {
72
+ type: "button",
73
+ onClick: () => w(t),
74
+ className: "text-foreground-muted hover:bg-background-subtle hover:text-foreground focus-visible:ring-ring rounded-sm p-0.5 outline-none focus-visible:ring-2",
75
+ "aria-label": L(h.tagInput.remove, { tag: e }),
76
+ children: /* @__PURE__ */ o(G, { className: "size-3", "aria-hidden": !0 })
77
+ }
78
+ )
79
+ ]
80
+ },
81
+ `${e}-${t}`
82
+ )),
83
+ /* @__PURE__ */ o(
84
+ "input",
85
+ {
86
+ id: x,
87
+ value: n,
88
+ disabled: p,
89
+ onChange: (e) => d(e.target.value),
90
+ onKeyDown: X,
91
+ onBlur: () => {
92
+ n && (y(n), d(""));
93
+ },
94
+ placeholder: r.length === 0 ? z : void 0,
95
+ "aria-label": T,
96
+ "aria-invalid": c || void 0,
97
+ "aria-describedby": R,
98
+ className: "placeholder:text-foreground-subtle min-w-[8ch] flex-1 bg-transparent text-sm outline-none"
99
+ }
100
+ )
101
+ ]
102
+ }
103
+ ),
104
+ b ? /* @__PURE__ */ o("p", { id: M, role: "alert", className: "text-danger-text text-xs", children: l }) : s ? /* @__PURE__ */ o("p", { id: H, className: "text-foreground-subtle text-xs", children: s }) : null
105
+ ] });
106
+ });
107
+ P.displayName = "TagInput";
108
+ export {
109
+ P as TagInput
110
+ };
111
+ //# sourceMappingURL=TagInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagInput.js","sources":["../../../src/components/ui/TagInput.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useCallback, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { formatString } from '@/lib/strings';\nimport { useFieldIds } from '@/hooks/use-field-ids';\n\nexport interface TagInputProps {\n /** Controlled list of tags. */\n value?: string[];\n /** Default tags when uncontrolled. */\n defaultValue?: string[];\n /** Called when the tag list changes. */\n onChange?: (tags: string[]) => void;\n /** Visible label rendered above the field. */\n label?: ReactNode;\n /** Visually conceal the label while keeping it for screen readers. */\n hideLabel?: boolean;\n /** Hint below the field. Hidden while `error` is set. */\n description?: ReactNode;\n /** Placeholder shown inside the inline input. */\n placeholder?: string;\n /** Maximum number of tags. */\n max?: number;\n /** Disable the editor. */\n disabled?: boolean;\n /**\n * Validation state. `true` only paints the danger border; a ReactNode also\n * renders the message below the field and wires `aria-describedby`.\n */\n error?: boolean | ReactNode;\n /** Treat these characters as separators (default: Enter + comma). */\n separators?: string[];\n /** Consumer-supplied id for the inline input. */\n id?: string;\n /** Extra ids to append to `aria-describedby`. */\n 'aria-describedby'?: string;\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * Chip-based multi-value input. Press Enter or comma to add. Backspace on an\n * empty input removes the last tag.\n */\nexport const TagInput = forwardRef<HTMLDivElement, TagInputProps>(function TagInput(\n {\n value,\n defaultValue = [],\n onChange,\n label,\n hideLabel,\n description,\n placeholder: placeholderProp,\n max,\n disabled,\n error,\n separators = ['Enter', ','],\n id,\n 'aria-describedby': ariaDescribedby,\n 'aria-label': ariaLabel,\n className,\n },\n ref,\n) {\n const [internal, setInternal] = useState<string[]>(defaultValue);\n const [draft, setDraft] = useState('');\n const tags = value ?? internal;\n\n const strings = useStrings();\n const placeholder = placeholderProp ?? strings.tagInput.placeholder;\n const isError = Boolean(error);\n const hasErrorMessage = isError && error !== true;\n const { fieldId, helperId, errorId, describedBy } = useFieldIds(id, {\n hasHelper: Boolean(description),\n hasError: hasErrorMessage,\n extra: ariaDescribedby,\n });\n\n const update = useCallback(\n (next: string[]) => {\n if (value === undefined) setInternal(next);\n onChange?.(next);\n },\n [onChange, value],\n );\n\n const commit = (raw: string) => {\n const t = raw.trim();\n if (!t || tags.includes(t) || (max !== undefined && tags.length >= max)) return;\n update([...tags, t]);\n };\n\n const remove = (idx: number) => update(tags.filter((_, i) => i !== idx));\n\n const onKey = (e: KeyboardEvent<HTMLInputElement>) => {\n if (separators.includes(e.key)) {\n e.preventDefault();\n commit(draft);\n setDraft('');\n } else if (e.key === 'Backspace' && !draft && tags.length) {\n remove(tags.length - 1);\n }\n };\n\n return (\n <div ref={ref} className={cn('flex flex-col gap-1.5', className)}>\n {label && (\n <label\n htmlFor={fieldId}\n className={cn('text-foreground text-sm font-medium', hideLabel && 'sr-only')}\n >\n {label}\n </label>\n )}\n <div\n className={cn(\n // Cap growth at ~3 chip rows and scroll inside — an unbounded field\n // pushes the surrounding layout around as tags are added.\n 'bg-card flex max-h-24 min-h-9 w-full flex-wrap items-center gap-1.5 overflow-y-auto rounded-md border px-2 py-1.5',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'focus-within:ring-offset-background focus-within:ring-2 focus-within:ring-offset-2',\n isError\n ? 'border-danger focus-within:border-danger focus-within:ring-danger'\n : 'border-border focus-within:border-accent focus-within:ring-ring',\n disabled && 'pointer-events-none opacity-50',\n )}\n >\n {tags.map((t, i) => (\n <span\n key={`${t}-${i}`}\n className=\"bg-background-muted inline-flex items-center gap-1 rounded-sm px-2 py-0.5 text-xs\"\n >\n {t}\n <button\n type=\"button\"\n onClick={() => remove(i)}\n className=\"text-foreground-muted hover:bg-background-subtle hover:text-foreground focus-visible:ring-ring rounded-sm p-0.5 outline-none focus-visible:ring-2\"\n aria-label={formatString(strings.tagInput.remove, { tag: t })}\n >\n <X className=\"size-3\" aria-hidden />\n </button>\n </span>\n ))}\n <input\n id={fieldId}\n value={draft}\n disabled={disabled}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKey}\n onBlur={() => {\n if (draft) {\n commit(draft);\n setDraft('');\n }\n }}\n placeholder={tags.length === 0 ? placeholder : undefined}\n aria-label={ariaLabel}\n aria-invalid={isError || undefined}\n aria-describedby={describedBy}\n className=\"placeholder:text-foreground-subtle min-w-[8ch] flex-1 bg-transparent text-sm outline-none\"\n />\n </div>\n {hasErrorMessage ? (\n <p id={errorId} role=\"alert\" className=\"text-danger-text text-xs\">\n {error}\n </p>\n ) : description ? (\n <p id={helperId} className=\"text-foreground-subtle text-xs\">\n {description}\n </p>\n ) : null}\n </div>\n );\n});\nTagInput.displayName = 'TagInput';\n"],"names":["TagInput","forwardRef","value","defaultValue","onChange","label","hideLabel","description","placeholderProp","max","disabled","error","separators","id","ariaDescribedby","ariaLabel","className","ref","internal","setInternal","useState","draft","setDraft","tags","strings","useStrings","placeholder","isError","hasErrorMessage","fieldId","helperId","errorId","describedBy","useFieldIds","update","useCallback","next","commit","raw","remove","idx","_","i","onKey","cn","jsx","jsxs","t","formatString","X"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import { jsxs as $, jsx as s } from "react/jsx-runtime";
3
+ import { forwardRef as j, useId as k, useRef as F, useCallback as B, useEffect as E } from "react";
4
+ import { cn as c } from "../../lib/utils.js";
5
+ const M = j(function({
6
+ className: h,
7
+ label: a,
8
+ helperText: n,
9
+ error: r,
10
+ autoResize: t,
11
+ minRows: v = 3,
12
+ maxRows: f = 12,
13
+ hideLabel: y,
14
+ id: H,
15
+ onChange: l,
16
+ value: u,
17
+ defaultValue: g,
18
+ ...N
19
+ }, i) {
20
+ const I = k(), o = H ?? I, m = `${o}-helper`, b = `${o}-error`, x = F(null), w = (e) => {
21
+ x.current = e, typeof i == "function" ? i(e) : i && (i.current = e);
22
+ }, d = B(() => {
23
+ const e = x.current;
24
+ if (!e || !t) return;
25
+ e.style.height = "auto";
26
+ const p = (parseFloat(getComputedStyle(e).lineHeight) || 20) * f;
27
+ e.style.height = `${Math.min(e.scrollHeight, p)}px`, e.style.overflowY = e.scrollHeight > p ? "auto" : "hidden";
28
+ }, [t, f]);
29
+ return E(() => {
30
+ t && d();
31
+ }, [t, d, u, g]), /* @__PURE__ */ $("div", { className: c("flex flex-col gap-1.5", h), children: [
32
+ a && /* @__PURE__ */ s(
33
+ "label",
34
+ {
35
+ htmlFor: o,
36
+ className: c(
37
+ "text-sm font-medium text-foreground",
38
+ y && "sr-only"
39
+ ),
40
+ children: a
41
+ }
42
+ ),
43
+ /* @__PURE__ */ s(
44
+ "textarea",
45
+ {
46
+ ref: w,
47
+ id: o,
48
+ rows: v,
49
+ value: u,
50
+ defaultValue: g,
51
+ onChange: (e) => {
52
+ l == null || l(e), t && d();
53
+ },
54
+ "aria-invalid": !!r || void 0,
55
+ "aria-describedby": r ? b : n ? m : void 0,
56
+ className: c(
57
+ "rounded-md border bg-card px-3 py-2 text-lg md:text-sm text-foreground",
58
+ "placeholder:text-foreground-subtle",
59
+ "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
60
+ "outline-none",
61
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
62
+ "focus-visible:ring-offset-background",
63
+ "disabled:opacity-50 disabled:cursor-not-allowed",
64
+ r ? "border-danger focus-visible:border-danger focus-visible:ring-danger" : "border-border-input focus-visible:border-accent",
65
+ t ? "resize-none" : "resize-y min-h-20"
66
+ ),
67
+ ...N
68
+ }
69
+ ),
70
+ r ? /* @__PURE__ */ s("p", { id: b, role: "alert", className: "text-xs text-danger-text", children: r }) : n ? /* @__PURE__ */ s("p", { id: m, className: "text-xs text-foreground-subtle", children: n }) : null
71
+ ] });
72
+ });
73
+ M.displayName = "Textarea";
74
+ export {
75
+ M as Textarea
76
+ };
77
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.js","sources":["../../../src/components/ui/Textarea.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n type TextareaHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface TextareaProps\n extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n /** Visible label above the field. */\n label?: ReactNode;\n /** Hint below the field. Hidden when `error` is set. */\n helperText?: ReactNode;\n /** Validation message. Sets `aria-invalid`. */\n error?: ReactNode;\n /** Grow vertically as content is added. */\n autoResize?: boolean;\n /** Minimum rows when `autoResize`. Defaults to 3. */\n minRows?: number;\n /** Maximum rows before scrolling when `autoResize`. Defaults to 12. */\n maxRows?: number;\n /** Visually hide the label while keeping it accessible. */\n hideLabel?: boolean;\n}\n\n/**\n * Multi-line text input. With `autoResize`, height tracks content from\n * `minRows` to `maxRows`. Without it, behaves like a native `<textarea>`.\n *\n * @example Comment box\n * <Textarea label=\"Note\" autoResize minRows={3} maxRows={10} />\n *\n * @example With error\n * <Textarea label=\"Description\"\n * error={errors.description?.message}\n * {...register('description')} />\n *\n * @do Default to `autoResize` for multi-line free-form input.\n * @dont Add `resize-none` without auto-resize — users will be stuck with a\n * 3-line box for long content.\n */\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n {\n className,\n label,\n helperText,\n error,\n autoResize,\n minRows = 3,\n maxRows = 12,\n hideLabel,\n id,\n onChange,\n value,\n defaultValue,\n ...props\n },\n ref,\n) {\n const autoId = useId();\n const fieldId = id ?? autoId;\n const helperId = `${fieldId}-helper`;\n const errorId = `${fieldId}-error`;\n const innerRef = useRef<HTMLTextAreaElement | null>(null);\n\n // Stash a ref locally and forward to the consumer.\n const setRef = (node: HTMLTextAreaElement | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLTextAreaElement | null>).current = node;\n };\n\n const recompute = useCallback(() => {\n const el = innerRef.current;\n if (!el || !autoResize) return;\n el.style.height = 'auto';\n const lineHeight = parseFloat(getComputedStyle(el).lineHeight) || 20;\n const maxH = lineHeight * maxRows;\n el.style.height = `${Math.min(el.scrollHeight, maxH)}px`;\n el.style.overflowY = el.scrollHeight > maxH ? 'auto' : 'hidden';\n }, [autoResize, maxRows]);\n\n useEffect(() => {\n if (autoResize) recompute();\n }, [autoResize, recompute, value, defaultValue]);\n\n return (\n <div className={cn('flex flex-col gap-1.5', className)}>\n {label && (\n <label\n htmlFor={fieldId}\n className={cn(\n 'text-sm font-medium text-foreground',\n hideLabel && 'sr-only',\n )}\n >\n {label}\n </label>\n )}\n <textarea\n ref={setRef}\n id={fieldId}\n rows={minRows}\n value={value}\n defaultValue={defaultValue}\n onChange={(e) => {\n onChange?.(e);\n if (autoResize) recompute();\n }}\n aria-invalid={Boolean(error) || undefined}\n aria-describedby={error ? errorId : helperText ? helperId : undefined}\n className={cn(\n 'rounded-md border bg-card px-3 py-2 text-lg md:text-sm text-foreground',\n 'placeholder:text-foreground-subtle',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'outline-none',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'focus-visible:ring-offset-background',\n 'disabled:opacity-50 disabled:cursor-not-allowed',\n error\n ? 'border-danger focus-visible:border-danger focus-visible:ring-danger'\n : 'border-border-input focus-visible:border-accent',\n autoResize ? 'resize-none' : 'resize-y min-h-20',\n )}\n {...props}\n />\n {error ? (\n <p id={errorId} role=\"alert\" className=\"text-xs text-danger-text\">\n {error}\n </p>\n ) : helperText ? (\n <p id={helperId} className=\"text-xs text-foreground-subtle\">\n {helperText}\n </p>\n ) : null}\n </div>\n );\n});\n\nTextarea.displayName = 'Textarea';\n"],"names":["Textarea","forwardRef","className","label","helperText","error","autoResize","minRows","maxRows","hideLabel","id","onChange","value","defaultValue","props","ref","autoId","useId","fieldId","helperId","errorId","innerRef","useRef","setRef","node","recompute","useCallback","el","maxH","useEffect","cn","jsx"],"mappings":";;;;AA+CO,MAAMA,IAAWC,EAA+C,SACrE;AAAA,EACE,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,YAAAC;AAAA,EACA,OAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,SAAAC,IAAU;AAAA,EACV,WAAAC;AAAA,EACA,IAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAASC,EAAA,GACTC,IAAUR,KAAMM,GAChBG,IAAW,GAAGD,CAAO,WACrBE,IAAU,GAAGF,CAAO,UACpBG,IAAWC,EAAmC,IAAI,GAGlDC,IAAS,CAACC,MAAqC;AACnD,IAAAH,EAAS,UAAUG,GACf,OAAOT,KAAQ,aAAYA,EAAIS,CAAI,IAC9BT,MAAMA,EAA2D,UAAUS;AAAA,EACtF,GAEMC,IAAYC,EAAY,MAAM;AAClC,UAAMC,IAAKN,EAAS;AACpB,QAAI,CAACM,KAAM,CAACrB,EAAY;AACxB,IAAAqB,EAAG,MAAM,SAAS;AAElB,UAAMC,KADa,WAAW,iBAAiBD,CAAE,EAAE,UAAU,KAAK,MACxCnB;AAC1B,IAAAmB,EAAG,MAAM,SAAS,GAAG,KAAK,IAAIA,EAAG,cAAcC,CAAI,CAAC,MACpDD,EAAG,MAAM,YAAYA,EAAG,eAAeC,IAAO,SAAS;AAAA,EACzD,GAAG,CAACtB,GAAYE,CAAO,CAAC;AAExB,SAAAqB,EAAU,MAAM;AACd,IAAIvB,KAAYmB,EAAA;AAAA,EAClB,GAAG,CAACnB,GAAYmB,GAAWb,GAAOC,CAAY,CAAC,qBAG5C,OAAA,EAAI,WAAWiB,EAAG,yBAAyB5B,CAAS,GAClD,UAAA;AAAA,IAAAC,KACC,gBAAA4B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAASb;AAAA,QACT,WAAWY;AAAA,UACT;AAAA,UACArB,KAAa;AAAA,QAAA;AAAA,QAGd,UAAAN;AAAA,MAAA;AAAA,IAAA;AAAA,IAGL,gBAAA4B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKR;AAAA,QACL,IAAIL;AAAA,QACJ,MAAMX;AAAA,QACN,OAAAK;AAAA,QACA,cAAAC;AAAA,QACA,UAAU,CAAC,MAAM;AACf,UAAAF,KAAA,QAAAA,EAAW,IACPL,KAAYmB,EAAA;AAAA,QAClB;AAAA,QACA,gBAAc,EAAQpB,KAAU;AAAA,QAChC,oBAAkBA,IAAQe,IAAUhB,IAAae,IAAW;AAAA,QAC5D,WAAWW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACAzB,IACI,wEACA;AAAA,UACJC,IAAa,gBAAgB;AAAA,QAAA;AAAA,QAE9B,GAAGQ;AAAA,MAAA;AAAA,IAAA;AAAA,IAELT,IACC,gBAAA0B,EAAC,KAAA,EAAE,IAAIX,GAAS,MAAK,SAAQ,WAAU,4BACpC,aACH,IACEhB,sBACD,KAAA,EAAE,IAAIe,GAAU,WAAU,kCACxB,aACH,IACE;AAAA,EAAA,GACN;AAEJ,CAAC;AAEDnB,EAAS,cAAc;"}
@@ -1,6 +1,5 @@
1
- import { HTMLAttributes, ReactNode } from 'react';
2
- export interface TimelineProps extends HTMLAttributes<HTMLOListElement> {
3
- }
1
+ import { HTMLAttributes, ReactNode, TimeHTMLAttributes } from 'react';
2
+ export type TimelineProps = HTMLAttributes<HTMLOListElement>;
4
3
  export declare const Timeline: import('react').ForwardRefExoticComponent<TimelineProps & import('react').RefAttributes<HTMLOListElement>>;
5
4
  export interface TimelineItemProps extends HTMLAttributes<HTMLLIElement> {
6
5
  /** Optional bullet override. Default: small accent dot. */
@@ -9,15 +8,26 @@ export interface TimelineItemProps extends HTMLAttributes<HTMLLIElement> {
9
8
  isLast?: boolean;
10
9
  }
11
10
  export declare const TimelineItem: import('react').ForwardRefExoticComponent<TimelineItemProps & import('react').RefAttributes<HTMLLIElement>>;
12
- export declare function TimelineTime({ className, children }: {
13
- className?: string;
11
+ export interface TimelineTimeProps extends TimeHTMLAttributes<HTMLTimeElement> {
12
+ /** Machine-readable value (ISO 8601). Defaults to `children` when it is a string. */
13
+ dateTime?: string;
14
14
  children: ReactNode;
15
- }): import("react/jsx-runtime").JSX.Element;
15
+ }
16
+ export declare function TimelineTime({ className, children, dateTime, ...props }: TimelineTimeProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare namespace TimelineTime {
18
+ var displayName: string;
19
+ }
16
20
  export declare function TimelineTitle({ className, children, }: {
17
21
  className?: string;
18
22
  children: ReactNode;
19
23
  }): import("react/jsx-runtime").JSX.Element;
24
+ export declare namespace TimelineTitle {
25
+ var displayName: string;
26
+ }
20
27
  export declare function TimelineDescription({ className, children, }: {
21
28
  className?: string;
22
29
  children: ReactNode;
23
30
  }): import("react/jsx-runtime").JSX.Element;
31
+ export declare namespace TimelineDescription {
32
+ var displayName: string;
33
+ }
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ import { jsx as i, jsxs as s } from "react/jsx-runtime";
3
+ import { forwardRef as a } from "react";
4
+ import { cn as n } from "../../lib/utils.js";
5
+ const d = a(function({ className: e, children: l, ...m }, r) {
6
+ return /* @__PURE__ */ i("ol", { ref: r, className: n("relative flex flex-col gap-6", e), ...m, children: l });
7
+ });
8
+ d.displayName = "Timeline";
9
+ const f = a(function({ bullet: e, isLast: l, className: m, children: r, ...o }, c) {
10
+ return /* @__PURE__ */ s("li", { ref: c, className: n("relative flex gap-4 pb-1", m), ...o, children: [
11
+ /* @__PURE__ */ s("div", { className: "relative flex shrink-0 flex-col items-center", children: [
12
+ /* @__PURE__ */ i("div", { className: "border-border bg-card text-foreground-muted flex size-6 items-center justify-center rounded-full border", children: e ?? /* @__PURE__ */ i("span", { className: "bg-accent size-2 rounded-full", "aria-hidden": !0 }) }),
13
+ !l && /* @__PURE__ */ i("span", { className: "bg-border mt-1 w-px flex-1", "aria-hidden": !0 })
14
+ ] }),
15
+ /* @__PURE__ */ i("div", { className: "min-w-0 flex-1 pb-4", children: r })
16
+ ] });
17
+ });
18
+ f.displayName = "TimelineItem";
19
+ function u({ className: t, children: e, dateTime: l, ...m }) {
20
+ return /* @__PURE__ */ i(
21
+ "time",
22
+ {
23
+ dateTime: l ?? (typeof e == "string" ? e : void 0),
24
+ className: n("text-foreground-subtle block text-xs", t),
25
+ ...m,
26
+ children: e
27
+ }
28
+ );
29
+ }
30
+ u.displayName = "TimelineTime";
31
+ function p({
32
+ className: t,
33
+ children: e
34
+ }) {
35
+ return /* @__PURE__ */ i("p", { className: n("text-sm font-medium", t), children: e });
36
+ }
37
+ p.displayName = "TimelineTitle";
38
+ function x({
39
+ className: t,
40
+ children: e
41
+ }) {
42
+ return /* @__PURE__ */ i("p", { className: n("text-foreground-muted mt-0.5 text-sm", t), children: e });
43
+ }
44
+ x.displayName = "TimelineDescription";
45
+ export {
46
+ d as Timeline,
47
+ x as TimelineDescription,
48
+ f as TimelineItem,
49
+ u as TimelineTime,
50
+ p as TimelineTitle
51
+ };
52
+ //# sourceMappingURL=Timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Timeline.js","sources":["../../../src/components/ui/Timeline.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes, type ReactNode, type TimeHTMLAttributes } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport type TimelineProps = HTMLAttributes<HTMLOListElement>;\n\nexport const Timeline = forwardRef<HTMLOListElement, TimelineProps>(function Timeline(\n { className, children, ...props },\n ref,\n) {\n return (\n <ol ref={ref} className={cn('relative flex flex-col gap-6', className)} {...props}>\n {children}\n </ol>\n );\n});\nTimeline.displayName = 'Timeline';\n\nexport interface TimelineItemProps extends HTMLAttributes<HTMLLIElement> {\n /** Optional bullet override. Default: small accent dot. */\n bullet?: ReactNode;\n /** Hide the connector line below this item — use for the last item. */\n isLast?: boolean;\n}\n\nexport const TimelineItem = forwardRef<HTMLLIElement, TimelineItemProps>(function TimelineItem(\n { bullet, isLast, className, children, ...props },\n ref,\n) {\n return (\n <li ref={ref} className={cn('relative flex gap-4 pb-1', className)} {...props}>\n <div className=\"relative flex shrink-0 flex-col items-center\">\n <div className=\"border-border bg-card text-foreground-muted flex size-6 items-center justify-center rounded-full border\">\n {bullet ?? <span className=\"bg-accent size-2 rounded-full\" aria-hidden />}\n </div>\n {!isLast && <span className=\"bg-border mt-1 w-px flex-1\" aria-hidden />}\n </div>\n <div className=\"min-w-0 flex-1 pb-4\">{children}</div>\n </li>\n );\n});\nTimelineItem.displayName = 'TimelineItem';\n\nexport interface TimelineTimeProps extends TimeHTMLAttributes<HTMLTimeElement> {\n /** Machine-readable value (ISO 8601). Defaults to `children` when it is a string. */\n dateTime?: string;\n children: ReactNode;\n}\n\nexport function TimelineTime({ className, children, dateTime, ...props }: TimelineTimeProps) {\n return (\n <time\n dateTime={dateTime ?? (typeof children === 'string' ? children : undefined)}\n className={cn('text-foreground-subtle block text-xs', className)}\n {...props}\n >\n {children}\n </time>\n );\n}\nTimelineTime.displayName = 'TimelineTime';\n\nexport function TimelineTitle({\n className,\n children,\n}: {\n className?: string;\n children: ReactNode;\n}) {\n return <p className={cn('text-sm font-medium', className)}>{children}</p>;\n}\nTimelineTitle.displayName = 'TimelineTitle';\n\nexport function TimelineDescription({\n className,\n children,\n}: {\n className?: string;\n children: ReactNode;\n}) {\n return <p className={cn('text-foreground-muted mt-0.5 text-sm', className)}>{children}</p>;\n}\nTimelineDescription.displayName = 'TimelineDescription';\n"],"names":["Timeline","forwardRef","className","children","props","ref","jsx","cn","TimelineItem","bullet","isLast","jsxs","TimelineTime","dateTime","TimelineTitle","TimelineDescription"],"mappings":";;;;AAOO,MAAMA,IAAWC,EAA4C,SAClE,EAAE,WAAAC,GAAW,UAAAC,GAAU,GAAGC,EAAA,GAC1BC,GACA;AACA,SACE,gBAAAC,EAAC,MAAA,EAAG,KAAAD,GAAU,WAAWE,EAAG,gCAAgCL,CAAS,GAAI,GAAGE,GACzE,UAAAD,EAAA,CACH;AAEJ,CAAC;AACDH,EAAS,cAAc;AAShB,MAAMQ,IAAeP,EAA6C,SACvE,EAAE,QAAAQ,GAAQ,QAAAC,GAAQ,WAAAR,GAAW,UAAAC,GAAU,GAAGC,EAAA,GAC1CC,GACA;AACA,SACE,gBAAAM,EAAC,QAAG,KAAAN,GAAU,WAAWE,EAAG,4BAA4BL,CAAS,GAAI,GAAGE,GACtE,UAAA;AAAA,IAAA,gBAAAO,EAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,MAAA,gBAAAL,EAAC,OAAA,EAAI,WAAU,2GACZ,UAAAG,KAAU,gBAAAH,EAAC,UAAK,WAAU,iCAAgC,eAAW,GAAA,CAAC,EAAA,CACzE;AAAA,MACC,CAACI,KAAU,gBAAAJ,EAAC,UAAK,WAAU,8BAA6B,eAAW,GAAA,CAAC;AAAA,IAAA,GACvE;AAAA,IACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uBAAuB,UAAAH,EAAA,CAAS;AAAA,EAAA,GACjD;AAEJ,CAAC;AACDK,EAAa,cAAc;AAQpB,SAASI,EAAa,EAAE,WAAAV,GAAW,UAAAC,GAAU,UAAAU,GAAU,GAAGT,KAA4B;AAC3F,SACE,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,UAAUO,MAAa,OAAOV,KAAa,WAAWA,IAAW;AAAA,MACjE,WAAWI,EAAG,wCAAwCL,CAAS;AAAA,MAC9D,GAAGE;AAAA,MAEH,UAAAD;AAAA,IAAA;AAAA,EAAA;AAGP;AACAS,EAAa,cAAc;AAEpB,SAASE,EAAc;AAAA,EAC5B,WAAAZ;AAAA,EACA,UAAAC;AACF,GAGG;AACD,2BAAQ,KAAA,EAAE,WAAWI,EAAG,uBAAuBL,CAAS,GAAI,UAAAC,GAAS;AACvE;AACAW,EAAc,cAAc;AAErB,SAASC,EAAoB;AAAA,EAClC,WAAAb;AAAA,EACA,UAAAC;AACF,GAGG;AACD,2BAAQ,KAAA,EAAE,WAAWI,EAAG,wCAAwCL,CAAS,GAAI,UAAAC,GAAS;AACxF;AACAY,EAAoB,cAAc;"}
@@ -1,5 +1,5 @@
1
1
  import { ComponentPropsWithoutRef } from 'react';
2
- import { VariantProps } from '../../lib/cva';
2
+ import { VariantProps } from '../../lib/cva.js';
3
3
  import * as ToastPrimitive from '@radix-ui/react-toast';
4
4
  export declare const ToastProvider: import('react').FC<ToastPrimitive.ToastProviderProps>;
5
5
  export declare const ToastViewport: import('react').ForwardRefExoticComponent<Omit<ToastPrimitive.ToastViewportProps & import('react').RefAttributes<HTMLOListElement>, "ref"> & import('react').RefAttributes<HTMLOListElement>>;
@@ -0,0 +1,171 @@
1
+ "use client";
2
+ import { jsxs as f, jsx as s } from "react/jsx-runtime";
3
+ import { forwardRef as n, useEffect as T } from "react";
4
+ import * as r from "@radix-ui/react-toast";
5
+ import { X as v, Info as w, XCircle as N, AlertTriangle as y, CheckCircle2 as C } from "../../icons/index.js";
6
+ import { cn as c } from "../../lib/utils.js";
7
+ import { useStrings as m } from "../../hooks/use-strings.js";
8
+ import { useToast as k } from "../../hooks/use-toast.js";
9
+ import { cva as z } from "class-variance-authority";
10
+ const A = r.Provider, u = n(function({ className: o, ...e }, a) {
11
+ return /* @__PURE__ */ s(
12
+ r.Viewport,
13
+ {
14
+ ref: a,
15
+ className: c(
16
+ "fixed bottom-0 right-0 z-[var(--z-toast)] flex max-h-screen w-full flex-col-reverse gap-2 p-6",
17
+ "sm:bottom-auto sm:top-4 sm:right-4 sm:max-w-sm sm:flex-col",
18
+ o
19
+ ),
20
+ ...e
21
+ }
22
+ );
23
+ });
24
+ u.displayName = "ToastViewport";
25
+ const V = z(
26
+ [
27
+ "group pointer-events-auto relative flex w-full items-start gap-3",
28
+ "overflow-hidden rounded-lg border p-4 pr-8 shadow-md",
29
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
30
+ "data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-right-full",
31
+ "data-[state=closed]:slide-out-to-right-full",
32
+ "data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]",
33
+ "data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-transform",
34
+ "data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)]"
35
+ ],
36
+ {
37
+ variants: {
38
+ variant: {
39
+ default: "border-border bg-card text-card-foreground",
40
+ success: "border-success-border-soft bg-success-soft text-success-text",
41
+ warning: "border-warning-border-soft bg-warning-soft text-warning-text",
42
+ danger: "border-danger-border-soft bg-danger-soft text-danger-text",
43
+ info: "border-info-border-soft bg-info-soft text-info-text"
44
+ }
45
+ },
46
+ defaultVariants: { variant: "default" }
47
+ }
48
+ ), j = {
49
+ default: null,
50
+ success: /* @__PURE__ */ s(C, { className: "size-5 text-success-text shrink-0 mt-0.5", "aria-hidden": !0 }),
51
+ warning: /* @__PURE__ */ s(y, { className: "size-5 text-warning-text shrink-0 mt-0.5", "aria-hidden": !0 }),
52
+ danger: /* @__PURE__ */ s(N, { className: "size-5 text-danger-text shrink-0 mt-0.5", "aria-hidden": !0 }),
53
+ info: /* @__PURE__ */ s(w, { className: "size-5 text-info-text shrink-0 mt-0.5", "aria-hidden": !0 })
54
+ }, p = n(
55
+ function({ className: o, variant: e = "default", children: a, ...t }, l) {
56
+ return /* @__PURE__ */ f(r.Root, { ref: l, className: c(V({ variant: e }), o), ...t, children: [
57
+ j[e ?? "default"],
58
+ /* @__PURE__ */ s("div", { className: "flex-1 space-y-1", children: a })
59
+ ] });
60
+ }
61
+ );
62
+ p.displayName = "Toast";
63
+ const g = n(function({ className: o, ...e }, a) {
64
+ return /* @__PURE__ */ s(
65
+ r.Title,
66
+ {
67
+ ref: a,
68
+ className: c("text-sm font-medium", o),
69
+ ...e
70
+ }
71
+ );
72
+ });
73
+ g.displayName = "ToastTitle";
74
+ const x = n(function({ className: o, ...e }, a) {
75
+ return /* @__PURE__ */ s(
76
+ r.Description,
77
+ {
78
+ ref: a,
79
+ className: c("text-sm opacity-90", o),
80
+ ...e
81
+ }
82
+ );
83
+ });
84
+ x.displayName = "ToastDescription";
85
+ const b = n(function({ className: o, ...e }, a) {
86
+ return /* @__PURE__ */ s(
87
+ r.Action,
88
+ {
89
+ ref: a,
90
+ className: c(
91
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border border-current bg-transparent px-3 text-sm font-medium",
92
+ "transition-colors hover:bg-current/10 outline-none",
93
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card",
94
+ o
95
+ ),
96
+ ...e
97
+ }
98
+ );
99
+ });
100
+ b.displayName = "ToastAction";
101
+ const h = n(function({ className: o, ...e }, a) {
102
+ const t = m();
103
+ return /* @__PURE__ */ s(
104
+ r.Close,
105
+ {
106
+ ref: a,
107
+ "aria-label": e["aria-label"] ?? t.toast.close,
108
+ className: c(
109
+ "absolute right-2 top-2 inline-flex size-7 items-center justify-center rounded-md text-foreground-subtle",
110
+ "opacity-0 transition-opacity group-hover:opacity-100 hover:text-foreground",
111
+ "outline-none focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring",
112
+ o
113
+ ),
114
+ "toast-close": "",
115
+ ...e,
116
+ children: /* @__PURE__ */ s(v, { className: "size-4", "aria-hidden": !0 })
117
+ }
118
+ );
119
+ });
120
+ h.displayName = "ToastClose";
121
+ function D() {
122
+ const { toasts: i, dismiss: o, remove: e } = k();
123
+ T(() => {
124
+ const t = i.filter((d) => !d.open);
125
+ if (t.length === 0) return;
126
+ const l = t.map((d) => window.setTimeout(() => e(d.id), 200));
127
+ return () => l.forEach((d) => window.clearTimeout(d));
128
+ }, [i, e]);
129
+ const a = m();
130
+ return /* @__PURE__ */ f(A, { label: a.toast.region, children: [
131
+ i.map((t) => /* @__PURE__ */ f(
132
+ p,
133
+ {
134
+ variant: t.variant ?? "default",
135
+ open: t.open,
136
+ duration: t.duration,
137
+ onOpenChange: (l) => {
138
+ l || o(t.id);
139
+ },
140
+ children: [
141
+ t.title && /* @__PURE__ */ s(g, { children: t.title }),
142
+ t.description && /* @__PURE__ */ s(x, { children: t.description }),
143
+ t.action && /* @__PURE__ */ s(
144
+ b,
145
+ {
146
+ altText: t.action.altText,
147
+ onClick: t.action.onClick,
148
+ className: "mt-1",
149
+ children: t.action.label
150
+ }
151
+ ),
152
+ /* @__PURE__ */ s(h, {})
153
+ ]
154
+ },
155
+ t.id
156
+ )),
157
+ /* @__PURE__ */ s(u, {})
158
+ ] });
159
+ }
160
+ D.displayName = "Toaster";
161
+ export {
162
+ p as Toast,
163
+ b as ToastAction,
164
+ h as ToastClose,
165
+ x as ToastDescription,
166
+ A as ToastProvider,
167
+ g as ToastTitle,
168
+ u as ToastViewport,
169
+ D as Toaster
170
+ };
171
+ //# sourceMappingURL=Toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.js","sources":["../../../src/components/ui/Toast.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useEffect,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactElement,\n} from 'react';\nimport * as ToastPrimitive from '@radix-ui/react-toast';\nimport { AlertTriangle, CheckCircle2, Info, X, XCircle } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { cva, type VariantProps } from '@/lib/cva';\nimport { useToast } from '@/hooks/use-toast';\n\nexport const ToastProvider = ToastPrimitive.Provider;\n\nexport const ToastViewport = forwardRef<\n ElementRef<typeof ToastPrimitive.Viewport>,\n ComponentPropsWithoutRef<typeof ToastPrimitive.Viewport>\n>(function ToastViewport({ className, ...props }, ref) {\n return (\n <ToastPrimitive.Viewport\n ref={ref}\n className={cn(\n 'fixed bottom-0 right-0 z-[var(--z-toast)] flex max-h-screen w-full flex-col-reverse gap-2 p-6',\n 'sm:bottom-auto sm:top-4 sm:right-4 sm:max-w-sm sm:flex-col',\n className,\n )}\n {...props}\n />\n );\n});\nToastViewport.displayName = 'ToastViewport';\n\nconst toast = cva(\n [\n 'group pointer-events-auto relative flex w-full items-start gap-3',\n 'overflow-hidden rounded-lg border p-4 pr-8 shadow-md',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-right-full',\n 'data-[state=closed]:slide-out-to-right-full',\n 'data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]',\n 'data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-transform',\n 'data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)]',\n ],\n {\n variants: {\n variant: {\n default: 'border-border bg-card text-card-foreground',\n success: 'border-success-border-soft bg-success-soft text-success-text',\n warning: 'border-warning-border-soft bg-warning-soft text-warning-text',\n danger: 'border-danger-border-soft bg-danger-soft text-danger-text',\n info: 'border-info-border-soft bg-info-soft text-info-text',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n);\n\nconst iconMap = {\n default: null,\n success: <CheckCircle2 className=\"size-5 text-success-text shrink-0 mt-0.5\" aria-hidden />,\n warning: <AlertTriangle className=\"size-5 text-warning-text shrink-0 mt-0.5\" aria-hidden />,\n danger: <XCircle className=\"size-5 text-danger-text shrink-0 mt-0.5\" aria-hidden />,\n info: <Info className=\"size-5 text-info-text shrink-0 mt-0.5\" aria-hidden />,\n} satisfies Record<'default' | 'success' | 'warning' | 'danger' | 'info', ReactElement | null>;\n\nexport interface ToastProps\n extends ComponentPropsWithoutRef<typeof ToastPrimitive.Root>,\n VariantProps<typeof toast> {}\n\nexport const Toast = forwardRef<ElementRef<typeof ToastPrimitive.Root>, ToastProps>(\n function Toast({ className, variant = 'default', children, ...props }, ref) {\n return (\n <ToastPrimitive.Root ref={ref} className={cn(toast({ variant }), className)} {...props}>\n {iconMap[variant ?? 'default']}\n <div className=\"flex-1 space-y-1\">{children}</div>\n </ToastPrimitive.Root>\n );\n },\n);\nToast.displayName = 'Toast';\n\nexport const ToastTitle = forwardRef<\n ElementRef<typeof ToastPrimitive.Title>,\n ComponentPropsWithoutRef<typeof ToastPrimitive.Title>\n>(function ToastTitle({ className, ...props }, ref) {\n return (\n <ToastPrimitive.Title\n ref={ref}\n className={cn('text-sm font-medium', className)}\n {...props}\n />\n );\n});\nToastTitle.displayName = 'ToastTitle';\n\nexport const ToastDescription = forwardRef<\n ElementRef<typeof ToastPrimitive.Description>,\n ComponentPropsWithoutRef<typeof ToastPrimitive.Description>\n>(function ToastDescription({ className, ...props }, ref) {\n return (\n <ToastPrimitive.Description\n ref={ref}\n className={cn('text-sm opacity-90', className)}\n {...props}\n />\n );\n});\nToastDescription.displayName = 'ToastDescription';\n\nexport const ToastAction = forwardRef<\n ElementRef<typeof ToastPrimitive.Action>,\n ComponentPropsWithoutRef<typeof ToastPrimitive.Action>\n>(function ToastAction({ className, ...props }, ref) {\n return (\n <ToastPrimitive.Action\n ref={ref}\n className={cn(\n 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border border-current bg-transparent px-3 text-sm font-medium',\n 'transition-colors hover:bg-current/10 outline-none',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card',\n className,\n )}\n {...props}\n />\n );\n});\nToastAction.displayName = 'ToastAction';\n\nexport const ToastClose = forwardRef<\n ElementRef<typeof ToastPrimitive.Close>,\n ComponentPropsWithoutRef<typeof ToastPrimitive.Close>\n>(function ToastClose({ className, ...props }, ref) {\n const strings = useStrings();\n return (\n <ToastPrimitive.Close\n ref={ref}\n aria-label={props[\"aria-label\"] ?? strings.toast.close}\n className={cn(\n 'absolute right-2 top-2 inline-flex size-7 items-center justify-center rounded-md text-foreground-subtle',\n 'opacity-0 transition-opacity group-hover:opacity-100 hover:text-foreground',\n 'outline-none focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring',\n className,\n )}\n toast-close=\"\"\n {...props}\n >\n <X className=\"size-4\" aria-hidden />\n </ToastPrimitive.Close>\n );\n});\nToastClose.displayName = 'ToastClose';\n\n/**\n * Drop-in host that connects the `useToast()` queue to the Radix primitives.\n * Mount it once near your app root — then `useToast().push({...})` (or the\n * standalone `toast()`) from anywhere renders here. Self-contained: it brings\n * its own ToastProvider + Viewport, so no other Toast wiring is needed.\n *\n * @example\n * function App() {\n * return (\n * <>\n * <Routes />\n * <Toaster />\n * </>\n * );\n * }\n */\nexport function Toaster() {\n const { toasts, dismiss, remove } = useToast();\n\n // Closing a toast sets open:false so Radix can play the slide-out; drop it\n // from the queue once that animation has had time to finish.\n useEffect(() => {\n const closing = toasts.filter((t) => !t.open);\n if (closing.length === 0) return;\n const timers = closing.map((t) => window.setTimeout(() => remove(t.id), 200));\n return () => timers.forEach((id) => window.clearTimeout(id));\n }, [toasts, remove]);\n\n const strings = useStrings();\n return (\n <ToastProvider label={strings.toast.region}>\n {toasts.map((t) => (\n <Toast\n key={t.id}\n variant={t.variant ?? 'default'}\n open={t.open}\n duration={t.duration}\n onOpenChange={(open) => {\n if (!open) dismiss(t.id);\n }}\n >\n {t.title && <ToastTitle>{t.title}</ToastTitle>}\n {t.description && <ToastDescription>{t.description}</ToastDescription>}\n {t.action && (\n <ToastAction\n altText={t.action.altText}\n onClick={t.action.onClick}\n className=\"mt-1\"\n >\n {t.action.label}\n </ToastAction>\n )}\n <ToastClose />\n </Toast>\n ))}\n <ToastViewport />\n </ToastProvider>\n );\n}\nToaster.displayName = 'Toaster';\n\n/**\n * @example\n * <ToastProvider>\n * …app…\n * <Toast variant=\"success\">\n * <ToastTitle>Saved</ToastTitle>\n * <ToastDescription>Your changes are live.</ToastDescription>\n * <ToastAction altText=\"Undo\">Undo</ToastAction>\n * <ToastClose />\n * </Toast>\n * <ToastViewport />\n * </ToastProvider>\n *\n * @do Use the `useToast()` hook (in `src/hooks/use-toast.ts`) in app code —\n * the components here are the primitives the hook renders.\n * @dont Stack more than two toasts at a time. Newer toasts replace older ones.\n */\n"],"names":["ToastProvider","ToastPrimitive","ToastViewport","forwardRef","className","props","ref","jsx","cn","toast","cva","iconMap","CheckCircle2","AlertTriangle","XCircle","Info","Toast","variant","children","jsxs","ToastTitle","ToastDescription","ToastAction","ToastClose","strings","useStrings","X","Toaster","toasts","dismiss","remove","useToast","useEffect","closing","t","timers","id","open"],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { jsx as t, Fragment as p, jsxs as l } from "react/jsx-runtime";
3
+ import { forwardRef as m } from "react";
4
+ import * as a from "@radix-ui/react-tooltip";
5
+ import { cn as c } from "../../lib/utils.js";
6
+ const v = ({
7
+ delayDuration: o = 500,
8
+ skipDelayDuration: e = 200,
9
+ ...i
10
+ }) => /* @__PURE__ */ t(
11
+ a.Provider,
12
+ {
13
+ delayDuration: o,
14
+ skipDelayDuration: e,
15
+ ...i
16
+ }
17
+ ), f = a.Root, u = a.Trigger, d = m(function({ className: e, sideOffset: i = 4, ...n }, r) {
18
+ return /* @__PURE__ */ t(a.Portal, { children: /* @__PURE__ */ t(
19
+ a.Content,
20
+ {
21
+ ref: r,
22
+ sideOffset: i,
23
+ className: c(
24
+ "z-[var(--z-tooltip)] overflow-hidden rounded-md px-2 py-1 text-xs font-medium",
25
+ "bg-tooltip text-tooltip-foreground",
26
+ "shadow-sm max-w-xs",
27
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
28
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
29
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
30
+ e
31
+ ),
32
+ ...n
33
+ }
34
+ ) });
35
+ });
36
+ d.displayName = "TooltipContent";
37
+ function T({
38
+ children: o,
39
+ label: e,
40
+ side: i = "top",
41
+ align: n = "center",
42
+ disabled: r,
43
+ delayDuration: s
44
+ }) {
45
+ return r ? /* @__PURE__ */ t(p, { children: o }) : /* @__PURE__ */ l(f, { delayDuration: s, children: [
46
+ /* @__PURE__ */ t(u, { asChild: !0, children: o }),
47
+ /* @__PURE__ */ t(d, { side: i, align: n, children: e })
48
+ ] });
49
+ }
50
+ T.displayName = "Tooltip";
51
+ export {
52
+ T as Tooltip,
53
+ d as TooltipContent,
54
+ v as TooltipProvider,
55
+ f as TooltipRoot,
56
+ u as TooltipTrigger
57
+ };
58
+ //# sourceMappingURL=Tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../src/components/ui/Tooltip.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport { cn } from '@/lib/utils';\n\n/**\n * Wrap the app in a single `<TooltipProvider>` near the root. All Tooltips\n * share the same `delayDuration` and `skipDelayDuration`.\n */\nexport const TooltipProvider = ({\n delayDuration = 500,\n skipDelayDuration = 200,\n ...props\n}: ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>) => (\n <TooltipPrimitive.Provider\n delayDuration={delayDuration}\n skipDelayDuration={skipDelayDuration}\n {...props}\n />\n);\n\nexport const TooltipRoot = TooltipPrimitive.Root;\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\nexport const TooltipContent = forwardRef<\n ElementRef<typeof TooltipPrimitive.Content>,\n ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(function TooltipContent({ className, sideOffset = 4, ...props }, ref) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-[var(--z-tooltip)] overflow-hidden rounded-md px-2 py-1 text-xs font-medium',\n 'bg-tooltip text-tooltip-foreground',\n 'shadow-sm max-w-xs',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n className,\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n );\n});\nTooltipContent.displayName = 'TooltipContent';\n\nexport interface TooltipProps {\n children: ReactNode;\n label: ReactNode;\n side?: 'top' | 'right' | 'bottom' | 'left';\n align?: 'start' | 'center' | 'end';\n /** Disable showing the tooltip (e.g. when text is not truncated). */\n disabled?: boolean;\n /** Override the global delay. */\n delayDuration?: number;\n}\n\n/**\n * Shorthand for the most common Tooltip case.\n *\n * @example\n * <Tooltip label=\"Copy link\"><IconButton aria-label=\"Copy\" icon={<Copy/>} /></Tooltip>\n *\n * @do Keep tooltip text short — one line, no full sentences. Use a Popover\n * for any content that needs structure.\n * @dont Wrap disabled buttons in Tooltip without `asChild + tabIndex={0}`.\n * Disabled elements don't receive focus, so the tooltip never opens.\n */\nexport function Tooltip({\n children,\n label,\n side = 'top',\n align = 'center',\n disabled,\n delayDuration,\n}: TooltipProps) {\n if (disabled) return <>{children}</>;\n return (\n <TooltipRoot delayDuration={delayDuration}>\n <TooltipTrigger asChild>{children}</TooltipTrigger>\n <TooltipContent side={side} align={align}>\n {label}\n </TooltipContent>\n </TooltipRoot>\n );\n}\nTooltip.displayName = 'Tooltip';\n"],"names":["TooltipProvider","delayDuration","skipDelayDuration","props","jsx","TooltipPrimitive","TooltipRoot","TooltipTrigger","TooltipContent","forwardRef","className","sideOffset","ref","cn","Tooltip","children","label","side","align","disabled","Fragment","jsxs"],"mappings":";;;;;AAeO,MAAMA,IAAkB,CAAC;AAAA,EAC9B,eAAAC,IAAgB;AAAA,EAChB,mBAAAC,IAAoB;AAAA,EACpB,GAAGC;AACL,MACE,gBAAAC;AAAA,EAACC,EAAiB;AAAA,EAAjB;AAAA,IACC,eAAAJ;AAAA,IACA,mBAAAC;AAAA,IACC,GAAGC;AAAA,EAAA;AACN,GAGWG,IAAcD,EAAiB,MAC/BE,IAAiBF,EAAiB,SAElCG,IAAiBC,EAG5B,SAAwB,EAAE,WAAAC,GAAW,YAAAC,IAAa,GAAG,GAAGR,EAAA,GAASS,GAAK;AACtE,SACE,gBAAAR,EAACC,EAAiB,QAAjB,EACC,UAAA,gBAAAD;AAAA,IAACC,EAAiB;AAAA,IAAjB;AAAA,MACC,KAAAO;AAAA,MACA,YAAAD;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAH;AAAA,MAAA;AAAA,MAED,GAAGP;AAAA,IAAA;AAAA,EAAA,GAER;AAEJ,CAAC;AACDK,EAAe,cAAc;AAwBtB,SAASM,EAAQ;AAAA,EACtB,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,eAAAlB;AACF,GAAiB;AACf,SAAIkB,IAAiB,gBAAAf,EAAAgB,GAAA,EAAG,UAAAL,EAAA,CAAS,IAE/B,gBAAAM,EAACf,KAAY,eAAAL,GACX,UAAA;AAAA,IAAA,gBAAAG,EAACG,GAAA,EAAe,SAAO,IAAE,UAAAQ,EAAA,CAAS;AAAA,IAClC,gBAAAX,EAACI,GAAA,EAAe,MAAAS,GAAY,OAAAC,GACzB,UAAAF,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;AACAF,EAAQ,cAAc;"}