@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,52 @@
1
+ "use client";
2
+ import { jsxs as a, jsx as o } from "react/jsx-runtime";
3
+ import { forwardRef as d } from "react";
4
+ import { cn as l } from "../../lib/utils.js";
5
+ const f = d(function({ logo: n, nav: e, search: r, actions: i, className: t, ...s }, m) {
6
+ return /* @__PURE__ */ a(
7
+ "header",
8
+ {
9
+ ref: m,
10
+ className: l(
11
+ "sticky top-0 z-[var(--z-sticky)] flex h-14 w-full items-center gap-4",
12
+ "border-b border-border bg-background px-4",
13
+ t
14
+ ),
15
+ ...s,
16
+ children: [
17
+ /* @__PURE__ */ a("div", { className: "flex items-center gap-6 shrink-0", children: [
18
+ n,
19
+ e && /* @__PURE__ */ o("nav", { className: "hidden md:flex items-center gap-1", children: e })
20
+ ] }),
21
+ r && /* @__PURE__ */ o("div", { className: "flex-1 max-w-md mx-auto", children: r }),
22
+ i && /* @__PURE__ */ o("div", { className: "ml-auto flex items-center gap-2 shrink-0", children: i })
23
+ ]
24
+ }
25
+ );
26
+ });
27
+ f.displayName = "TopNav";
28
+ const u = d(function({ href: n, active: e, className: r, children: i, ...t }, s) {
29
+ return /* @__PURE__ */ o(
30
+ "a",
31
+ {
32
+ ref: s,
33
+ href: n,
34
+ "aria-current": e ? "page" : void 0,
35
+ className: l(
36
+ "inline-flex h-9 items-center rounded-md px-3 text-sm font-medium outline-none",
37
+ "transition-colors duration-[var(--duration-fast)]",
38
+ e ? "text-foreground" : "text-foreground-muted hover:text-foreground",
39
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
40
+ r
41
+ ),
42
+ ...t,
43
+ children: i
44
+ }
45
+ );
46
+ });
47
+ u.displayName = "TopNavLink";
48
+ export {
49
+ f as TopNav,
50
+ u as TopNavLink
51
+ };
52
+ //# sourceMappingURL=TopNav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopNav.js","sources":["../../../src/components/ui/TopNav.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface TopNavProps extends HTMLAttributes<HTMLElement> {\n /** Logo / wordmark slot. Shown on the far left. */\n logo: ReactNode;\n /** Primary navigation links — typically a list of `<TopNavLink>`. */\n nav?: ReactNode;\n /** Search / command bar slot — fills the centre on wide screens. */\n search?: ReactNode;\n /** Right-aligned cluster — notifications, theme toggle, user menu. */\n actions?: ReactNode;\n}\n\n/**\n * App-level top bar. Layout: `logo · nav · search · actions`. Search and nav\n * are optional.\n *\n * @example\n * <TopNav\n * logo={<Logo />}\n * nav={<><TopNavLink href=\"/\" active>Home</TopNavLink>…</>}\n * search={<Input type=\"search\" placeholder=\"Search…\" />}\n * actions={<><Bell /><Avatar /></>}\n * />\n *\n * @do Pick one primary nav style — links here or in the Sidebar, not both.\n * @dont Stack two rows of navigation in the TopNav. If you need tabs as well,\n * put them below the bar inside the page content.\n */\nexport const TopNav = forwardRef<HTMLElement, TopNavProps>(function TopNav(\n { logo, nav, search, actions, className, ...props },\n ref,\n) {\n return (\n <header\n ref={ref}\n className={cn(\n 'sticky top-0 z-[var(--z-sticky)] flex h-14 w-full items-center gap-4',\n 'border-b border-border bg-background px-4',\n className,\n )}\n {...props}\n >\n <div className=\"flex items-center gap-6 shrink-0\">\n {logo}\n {nav && <nav className=\"hidden md:flex items-center gap-1\">{nav}</nav>}\n </div>\n {search && <div className=\"flex-1 max-w-md mx-auto\">{search}</div>}\n {actions && <div className=\"ml-auto flex items-center gap-2 shrink-0\">{actions}</div>}\n </header>\n );\n});\nTopNav.displayName = 'TopNav';\n\nexport interface TopNavLinkProps extends HTMLAttributes<HTMLAnchorElement> {\n href: string;\n active?: boolean;\n}\n\nexport const TopNavLink = forwardRef<HTMLAnchorElement, TopNavLinkProps>(function TopNavLink(\n { href, active, className, children, ...props },\n ref,\n) {\n return (\n <a\n ref={ref}\n href={href}\n aria-current={active ? 'page' : undefined}\n className={cn(\n 'inline-flex h-9 items-center rounded-md px-3 text-sm font-medium outline-none',\n 'transition-colors duration-[var(--duration-fast)]',\n active ? 'text-foreground' : 'text-foreground-muted hover:text-foreground',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n className,\n )}\n {...props}\n >\n {children}\n </a>\n );\n});\nTopNavLink.displayName = 'TopNavLink';\n"],"names":["TopNav","forwardRef","logo","nav","search","actions","className","props","ref","jsxs","cn","jsx","TopNavLink","href","active","children"],"mappings":";;;;AAgCO,MAAMA,IAASC,EAAqC,SACzD,EAAE,MAAAC,GAAM,KAAAC,GAAK,QAAAC,GAAQ,SAAAC,GAAS,WAAAC,GAAW,GAAGC,EAAA,GAC5CC,GACA;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAE,EAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,UAAAP;AAAA,UACAC,KAAO,gBAAAQ,EAAC,OAAA,EAAI,WAAU,qCAAqC,UAAAR,EAAA,CAAI;AAAA,QAAA,GAClE;AAAA,QACCC,KAAU,gBAAAO,EAAC,OAAA,EAAI,WAAU,2BAA2B,UAAAP,GAAO;AAAA,QAC3DC,KAAW,gBAAAM,EAAC,OAAA,EAAI,WAAU,4CAA4C,UAAAN,EAAA,CAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGrF,CAAC;AACDL,EAAO,cAAc;AAOd,MAAMY,IAAaX,EAA+C,SACvE,EAAE,MAAAY,GAAM,QAAAC,GAAQ,WAAAR,GAAW,UAAAS,GAAU,GAAGR,EAAA,GACxCC,GACA;AACA,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAH;AAAA,MACA,MAAAK;AAAA,MACA,gBAAcC,IAAS,SAAS;AAAA,MAChC,WAAWJ;AAAA,QACT;AAAA,QACA;AAAA,QACAI,IAAS,oBAAoB;AAAA,QAC7B;AAAA,QACAR;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,MAEH,UAAAQ;AAAA,IAAA;AAAA,EAAA;AAGP,CAAC;AACDH,EAAW,cAAc;"}
@@ -10,15 +10,37 @@ export interface TreeNode {
10
10
  export interface TreeProps {
11
11
  /** The root nodes. */
12
12
  data: TreeNode[];
13
- /** Ids to expand by default. */
13
+ /** Ids to expand by default (uncontrolled). */
14
14
  defaultExpanded?: string[];
15
- /** Currently selected node id. */
15
+ /** Controlled set of expanded ids. */
16
+ expanded?: string[];
17
+ /** Called with the full next set of expanded ids. */
18
+ onExpandedChange?: (next: string[]) => void;
19
+ /** Currently selected node id (controlled). Alias: `selected`. */
16
20
  selectedId?: string;
21
+ /** Controlled selected id. Takes precedence over `selectedId`. */
22
+ selected?: string;
23
+ /** Default selected id (uncontrolled). */
24
+ defaultSelected?: string;
25
+ /** Called when a node is activated (click / Enter / Space). */
17
26
  onSelect?: (id: string) => void;
27
+ /** Alias of `onSelect` for the controlled `selected` pair. */
28
+ onSelectedChange?: (id: string) => void;
29
+ /** Accessible name for the tree. */
30
+ 'aria-label'?: string;
31
+ 'aria-labelledby'?: string;
18
32
  className?: string;
19
33
  }
20
34
  /**
21
- * Expandable file-tree style list. Single selection. Keyboard a11y is
22
- * handled at the row level (`tabIndex`, Enter, ArrowRight/Left to toggle).
35
+ * Expandable file-tree style list following the WAI-ARIA tree pattern.
36
+ * Single selection, roving tabindex (one tab stop), and full arrow-key
37
+ * navigation: Up/Down move, Right expands or moves into a folder, Left
38
+ * collapses or moves to the parent, Home/End jump, Enter/Space select.
39
+ *
40
+ * Expansion and selection are uncontrolled by default; pass
41
+ * `expanded`/`onExpandedChange` and `selected`/`onSelectedChange` to control.
23
42
  */
24
- export declare function Tree({ data, defaultExpanded, selectedId, onSelect, className }: TreeProps): import("react/jsx-runtime").JSX.Element;
43
+ export declare function Tree({ data, defaultExpanded, expanded: expandedProp, onExpandedChange, selectedId, selected: selectedProp, defaultSelected, onSelect, onSelectedChange, className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, }: TreeProps): import("react/jsx-runtime").JSX.Element;
44
+ export declare namespace Tree {
45
+ var displayName: string;
46
+ }
@@ -0,0 +1,167 @@
1
+ "use client";
2
+ import { jsx as f, jsxs as L } from "react/jsx-runtime";
3
+ import { useState as A, useMemo as S, useRef as Z, useCallback as O } from "react";
4
+ import { ChevronRight as _, FolderOpen as $, Folder as P, File as C } from "../../icons/index.js";
5
+ import { cn as R } from "../../lib/utils.js";
6
+ import { useStrings as ee } from "../../hooks/use-strings.js";
7
+ function te({
8
+ data: p,
9
+ defaultExpanded: U = [],
10
+ expanded: d,
11
+ onExpandedChange: b,
12
+ selectedId: D,
13
+ selected: I,
14
+ defaultSelected: q,
15
+ onSelect: h,
16
+ onSelectedChange: g,
17
+ className: B,
18
+ "aria-label": G,
19
+ "aria-labelledby": T
20
+ }) {
21
+ var H;
22
+ const J = ee(), [j, Q] = A(
23
+ () => new Set(U)
24
+ ), o = S(
25
+ () => d ? new Set(d) : j,
26
+ [d, j]
27
+ ), [V, W] = A(q), v = I ?? D ?? V, [N, y] = A(void 0), F = Z(/* @__PURE__ */ new Map()), K = O(
28
+ (e) => {
29
+ d === void 0 && Q(e), b == null || b([...e]);
30
+ },
31
+ [d, b]
32
+ ), k = O(
33
+ (e, t) => {
34
+ if (o.has(e) === t) return;
35
+ const r = new Set(o);
36
+ t ? r.add(e) : r.delete(e), K(r);
37
+ },
38
+ [o, K]
39
+ ), M = O(
40
+ (e) => {
41
+ I === void 0 && D === void 0 && W(e), h == null || h(e), g == null || g(e);
42
+ },
43
+ [h, g, I, D]
44
+ ), a = S(() => {
45
+ const e = [], t = (r, l, c) => {
46
+ r.forEach((s, n) => {
47
+ e.push({ node: s, level: l, setSize: r.length, posInSet: n + 1, parentId: c }), s.children && o.has(s.id) && t(s.children, l + 1, s.id);
48
+ });
49
+ };
50
+ return t(p, 1, null), e;
51
+ }, [p, o]), X = N && a.some((e) => e.node.id === N) && N || v && a.some((e) => e.node.id === v) && v || ((H = a[0]) == null ? void 0 : H.node.id), u = (e) => {
52
+ var t;
53
+ e && (y(e), (t = F.current.get(e)) == null || t.focus());
54
+ }, Y = (e, t) => {
55
+ var n, m, w, x, i;
56
+ const { node: r } = t, l = !!r.children, c = o.has(r.id), s = a.findIndex((z) => z.node.id === r.id);
57
+ switch (e.key) {
58
+ case "ArrowDown":
59
+ e.preventDefault(), u((n = a[s + 1]) == null ? void 0 : n.node.id);
60
+ break;
61
+ case "ArrowUp":
62
+ e.preventDefault(), u((m = a[s - 1]) == null ? void 0 : m.node.id);
63
+ break;
64
+ case "ArrowRight":
65
+ e.preventDefault(), l && !c ? k(r.id, !0) : l && c && u((w = r.children[0]) == null ? void 0 : w.id);
66
+ break;
67
+ case "ArrowLeft":
68
+ e.preventDefault(), l && c ? k(r.id, !1) : t.parentId && u(t.parentId);
69
+ break;
70
+ case "Home":
71
+ e.preventDefault(), u((x = a[0]) == null ? void 0 : x.node.id);
72
+ break;
73
+ case "End":
74
+ e.preventDefault(), u((i = a[a.length - 1]) == null ? void 0 : i.node.id);
75
+ break;
76
+ case "Enter":
77
+ case " ":
78
+ e.preventDefault(), M(r.id), l && k(r.id, !c);
79
+ break;
80
+ default:
81
+ return;
82
+ }
83
+ e.stopPropagation();
84
+ };
85
+ function E(e, t, r, l, c) {
86
+ const s = !!e.children, n = o.has(e.id), m = v === e.id, w = s ? n ? $ : P : C, x = { node: e, parentId: c };
87
+ return /* @__PURE__ */ L(
88
+ "li",
89
+ {
90
+ ref: (i) => {
91
+ i ? F.current.set(e.id, i) : F.current.delete(e.id);
92
+ },
93
+ role: "treeitem",
94
+ "aria-expanded": s ? n : void 0,
95
+ "aria-selected": m,
96
+ "aria-level": t,
97
+ "aria-setsize": r,
98
+ "aria-posinset": l,
99
+ tabIndex: X === e.id ? 0 : -1,
100
+ onFocus: (i) => {
101
+ i.target === i.currentTarget && y(e.id);
102
+ },
103
+ onKeyDown: (i) => {
104
+ i.target === i.currentTarget && Y(i, x);
105
+ },
106
+ onClick: (i) => {
107
+ i.stopPropagation(), y(e.id), M(e.id), s && k(e.id, !n);
108
+ },
109
+ className: "outline-none",
110
+ children: [
111
+ /* @__PURE__ */ L(
112
+ "div",
113
+ {
114
+ style: { paddingLeft: (t - 1) * 16 + 8 },
115
+ className: R(
116
+ "flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-2 text-left text-sm",
117
+ "hover:bg-background-muted",
118
+ "[li:focus-visible>&]:ring-ring [li:focus-visible>&]:ring-offset-background [li:focus-visible>&]:ring-2 [li:focus-visible>&]:ring-offset-1",
119
+ m && "bg-accent-soft text-foreground"
120
+ ),
121
+ children: [
122
+ s ? /* @__PURE__ */ f(
123
+ _,
124
+ {
125
+ className: R(
126
+ "text-foreground-subtle size-3.5 shrink-0 transition-transform",
127
+ n && "rotate-90"
128
+ ),
129
+ "aria-hidden": !0
130
+ }
131
+ ) : /* @__PURE__ */ f("span", { className: "w-3.5 shrink-0", "aria-hidden": !0 }),
132
+ e.icon ?? /* @__PURE__ */ f(w, { className: "text-foreground-muted size-4 shrink-0", "aria-hidden": !0 }),
133
+ /* @__PURE__ */ f(
134
+ "span",
135
+ {
136
+ className: "truncate",
137
+ title: typeof e.label == "string" ? e.label : void 0,
138
+ children: e.label
139
+ }
140
+ )
141
+ ]
142
+ }
143
+ ),
144
+ s && n && /* @__PURE__ */ f("ul", { role: "group", className: "mt-0.5", children: e.children.map(
145
+ (i, z) => E(i, t + 1, e.children.length, z + 1, e.id)
146
+ ) })
147
+ ]
148
+ },
149
+ e.id
150
+ );
151
+ }
152
+ return /* @__PURE__ */ f(
153
+ "ul",
154
+ {
155
+ role: "tree",
156
+ "aria-label": G ?? (T ? void 0 : J.tree.label),
157
+ "aria-labelledby": T,
158
+ className: R("flex flex-col gap-0.5", B),
159
+ children: p.map((e, t) => E(e, 1, p.length, t + 1, null))
160
+ }
161
+ );
162
+ }
163
+ te.displayName = "Tree";
164
+ export {
165
+ te as Tree
166
+ };
167
+ //# sourceMappingURL=Tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tree.js","sources":["../../../src/components/ui/Tree.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { ChevronRight, File as FileIcon, Folder, FolderOpen } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\n\nexport interface TreeNode {\n id: string;\n label: ReactNode;\n /** If undefined the node is a leaf; if empty array it is an empty folder. */\n children?: TreeNode[];\n /** Optional custom icon (overrides default file/folder icons). */\n icon?: ReactNode;\n}\n\nexport interface TreeProps {\n /** The root nodes. */\n data: TreeNode[];\n /** Ids to expand by default (uncontrolled). */\n defaultExpanded?: string[];\n /** Controlled set of expanded ids. */\n expanded?: string[];\n /** Called with the full next set of expanded ids. */\n onExpandedChange?: (next: string[]) => void;\n /** Currently selected node id (controlled). Alias: `selected`. */\n selectedId?: string;\n /** Controlled selected id. Takes precedence over `selectedId`. */\n selected?: string;\n /** Default selected id (uncontrolled). */\n defaultSelected?: string;\n /** Called when a node is activated (click / Enter / Space). */\n onSelect?: (id: string) => void;\n /** Alias of `onSelect` for the controlled `selected` pair. */\n onSelectedChange?: (id: string) => void;\n /** Accessible name for the tree. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n}\n\ninterface FlatNode {\n node: TreeNode;\n level: number;\n setSize: number;\n posInSet: number;\n parentId: string | null;\n}\n\n/**\n * Expandable file-tree style list following the WAI-ARIA tree pattern.\n * Single selection, roving tabindex (one tab stop), and full arrow-key\n * navigation: Up/Down move, Right expands or moves into a folder, Left\n * collapses or moves to the parent, Home/End jump, Enter/Space select.\n *\n * Expansion and selection are uncontrolled by default; pass\n * `expanded`/`onExpandedChange` and `selected`/`onSelectedChange` to control.\n */\nexport function Tree({\n data,\n defaultExpanded = [],\n expanded: expandedProp,\n onExpandedChange,\n selectedId,\n selected: selectedProp,\n defaultSelected,\n onSelect,\n onSelectedChange,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n}: TreeProps) {\n const strings = useStrings();\n const [internalExpanded, setInternalExpanded] = useState<Set<string>>(\n () => new Set(defaultExpanded),\n );\n const expanded = useMemo(\n () => (expandedProp ? new Set(expandedProp) : internalExpanded),\n [expandedProp, internalExpanded],\n );\n\n const [internalSelected, setInternalSelected] = useState<string | undefined>(defaultSelected);\n const selected = selectedProp ?? selectedId ?? internalSelected;\n\n const [focusedId, setFocusedId] = useState<string | undefined>(undefined);\n const itemRefs = useRef(new Map<string, HTMLLIElement>());\n\n const setExpanded = useCallback(\n (next: Set<string>) => {\n if (expandedProp === undefined) setInternalExpanded(next);\n onExpandedChange?.([...next]);\n },\n [expandedProp, onExpandedChange],\n );\n\n const setOpen = useCallback(\n (id: string, open: boolean) => {\n if (expanded.has(id) === open) return;\n const next = new Set(expanded);\n if (open) next.add(id);\n else next.delete(id);\n setExpanded(next);\n },\n [expanded, setExpanded],\n );\n\n const select = useCallback(\n (id: string) => {\n if (selectedProp === undefined && selectedId === undefined) setInternalSelected(id);\n onSelect?.(id);\n onSelectedChange?.(id);\n },\n [onSelect, onSelectedChange, selectedProp, selectedId],\n );\n\n // Flatten the *visible* nodes in DOM order — this is what arrow keys walk.\n const visible = useMemo(() => {\n const out: FlatNode[] = [];\n const walk = (nodes: TreeNode[], level: number, parentId: string | null) => {\n nodes.forEach((node, i) => {\n out.push({ node, level, setSize: nodes.length, posInSet: i + 1, parentId });\n if (node.children && expanded.has(node.id)) walk(node.children, level + 1, node.id);\n });\n };\n walk(data, 1, null);\n return out;\n }, [data, expanded]);\n\n // The single tab stop: focused item if still visible, else selected, else first.\n const tabStopId =\n (focusedId && visible.some((v) => v.node.id === focusedId) && focusedId) ||\n (selected && visible.some((v) => v.node.id === selected) && selected) ||\n visible[0]?.node.id;\n\n const focusItem = (id: string | undefined) => {\n if (!id) return;\n setFocusedId(id);\n itemRefs.current.get(id)?.focus();\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLLIElement>, flat: FlatNode) => {\n const { node } = flat;\n const hasChildren = !!node.children;\n const isOpen = expanded.has(node.id);\n const index = visible.findIndex((v) => v.node.id === node.id);\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n focusItem(visible[index + 1]?.node.id);\n break;\n case 'ArrowUp':\n e.preventDefault();\n focusItem(visible[index - 1]?.node.id);\n break;\n case 'ArrowRight':\n e.preventDefault();\n if (hasChildren && !isOpen) setOpen(node.id, true);\n else if (hasChildren && isOpen) focusItem(node.children![0]?.id);\n break;\n case 'ArrowLeft':\n e.preventDefault();\n if (hasChildren && isOpen) setOpen(node.id, false);\n else if (flat.parentId) focusItem(flat.parentId);\n break;\n case 'Home':\n e.preventDefault();\n focusItem(visible[0]?.node.id);\n break;\n case 'End':\n e.preventDefault();\n focusItem(visible[visible.length - 1]?.node.id);\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n select(node.id);\n if (hasChildren) setOpen(node.id, !isOpen);\n break;\n default:\n return;\n }\n e.stopPropagation();\n };\n\n function renderNode(\n node: TreeNode,\n level: number,\n setSize: number,\n posInSet: number,\n parentId: string | null,\n ): ReactNode {\n const hasChildren = !!node.children;\n const isOpen = expanded.has(node.id);\n const isSelected = selected === node.id;\n const DefaultIcon = hasChildren ? (isOpen ? FolderOpen : Folder) : FileIcon;\n const flat: FlatNode = { node, level, setSize, posInSet, parentId };\n\n return (\n <li\n key={node.id}\n ref={(el) => {\n if (el) itemRefs.current.set(node.id, el);\n else itemRefs.current.delete(node.id);\n }}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isOpen : undefined}\n aria-selected={isSelected}\n aria-level={level}\n aria-setsize={setSize}\n aria-posinset={posInSet}\n tabIndex={tabStopId === node.id ? 0 : -1}\n onFocus={(e) => {\n if (e.target === e.currentTarget) setFocusedId(node.id);\n }}\n onKeyDown={(e) => {\n if (e.target === e.currentTarget) handleKeyDown(e, flat);\n }}\n onClick={(e) => {\n e.stopPropagation();\n setFocusedId(node.id);\n select(node.id);\n if (hasChildren) setOpen(node.id, !isOpen);\n }}\n className=\"outline-none\"\n >\n <div\n style={{ paddingLeft: (level - 1) * 16 + 8 }}\n className={cn(\n 'flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-2 text-left text-sm',\n 'hover:bg-background-muted',\n '[li:focus-visible>&]:ring-ring [li:focus-visible>&]:ring-offset-background [li:focus-visible>&]:ring-2 [li:focus-visible>&]:ring-offset-1',\n isSelected && 'bg-accent-soft text-foreground',\n )}\n >\n {hasChildren ? (\n <ChevronRight\n className={cn(\n 'text-foreground-subtle size-3.5 shrink-0 transition-transform',\n isOpen && 'rotate-90',\n )}\n aria-hidden\n />\n ) : (\n <span className=\"w-3.5 shrink-0\" aria-hidden />\n )}\n {node.icon ?? (\n <DefaultIcon className=\"text-foreground-muted size-4 shrink-0\" aria-hidden />\n )}\n <span\n className=\"truncate\"\n title={typeof node.label === 'string' ? node.label : undefined}\n >\n {node.label}\n </span>\n </div>\n {hasChildren && isOpen && (\n <ul role=\"group\" className=\"mt-0.5\">\n {node.children!.map((c, i) =>\n renderNode(c, level + 1, node.children!.length, i + 1, node.id),\n )}\n </ul>\n )}\n </li>\n );\n }\n\n return (\n <ul\n role=\"tree\"\n aria-label={ariaLabel ?? (ariaLabelledby ? undefined : strings.tree.label)}\n aria-labelledby={ariaLabelledby}\n className={cn('flex flex-col gap-0.5', className)}\n >\n {data.map((n, i) => renderNode(n, 1, data.length, i + 1, null))}\n </ul>\n );\n}\nTree.displayName = 'Tree';\n"],"names":["Tree","data","defaultExpanded","expandedProp","onExpandedChange","selectedId","selectedProp","defaultSelected","onSelect","onSelectedChange","className","ariaLabel","ariaLabelledby","strings","useStrings","internalExpanded","setInternalExpanded","useState","expanded","useMemo","internalSelected","setInternalSelected","selected","focusedId","setFocusedId","itemRefs","useRef","setExpanded","useCallback","next","setOpen","id","open","select","visible","out","walk","nodes","level","parentId","node","i","tabStopId","v","_a","focusItem","handleKeyDown","flat","hasChildren","isOpen","index","_b","_c","_d","_e","renderNode","setSize","posInSet","isSelected","DefaultIcon","FolderOpen","Folder","FileIcon","jsxs","el","e","cn","jsx","ChevronRight","c","n"],"mappings":";;;;;;AA0DO,SAASA,GAAK;AAAA,EACnB,MAAAC;AAAA,EACA,iBAAAC,IAAkB,CAAA;AAAA,EAClB,UAAUC;AAAA,EACV,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAUC;AAAA,EACV,iBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,cAAcC;AAAA,EACd,mBAAmBC;AACrB,GAAc;;AACZ,QAAMC,IAAUC,GAAA,GACV,CAACC,GAAkBC,CAAmB,IAAIC;AAAA,IAC9C,MAAM,IAAI,IAAIf,CAAe;AAAA,EAAA,GAEzBgB,IAAWC;AAAA,IACf,MAAOhB,IAAe,IAAI,IAAIA,CAAY,IAAIY;AAAA,IAC9C,CAACZ,GAAcY,CAAgB;AAAA,EAAA,GAG3B,CAACK,GAAkBC,CAAmB,IAAIJ,EAA6BV,CAAe,GACtFe,IAAWhB,KAAgBD,KAAce,GAEzC,CAACG,GAAWC,CAAY,IAAIP,EAA6B,MAAS,GAClEQ,IAAWC,EAAO,oBAAI,KAA4B,GAElDC,IAAcC;AAAA,IAClB,CAACC,MAAsB;AACrB,MAAI1B,MAAiB,UAAWa,EAAoBa,CAAI,GACxDzB,KAAA,QAAAA,EAAmB,CAAC,GAAGyB,CAAI;AAAA,IAC7B;AAAA,IACA,CAAC1B,GAAcC,CAAgB;AAAA,EAAA,GAG3B0B,IAAUF;AAAA,IACd,CAACG,GAAYC,MAAkB;AAC7B,UAAId,EAAS,IAAIa,CAAE,MAAMC,EAAM;AAC/B,YAAMH,IAAO,IAAI,IAAIX,CAAQ;AAC7B,MAAIc,IAAMH,EAAK,IAAIE,CAAE,IAChBF,EAAK,OAAOE,CAAE,GACnBJ,EAAYE,CAAI;AAAA,IAClB;AAAA,IACA,CAACX,GAAUS,CAAW;AAAA,EAAA,GAGlBM,IAASL;AAAA,IACb,CAACG,MAAe;AACd,MAAIzB,MAAiB,UAAaD,MAAe,YAA+B0B,CAAE,GAClFvB,KAAA,QAAAA,EAAWuB,IACXtB,KAAA,QAAAA,EAAmBsB;AAAA,IACrB;AAAA,IACA,CAACvB,GAAUC,GAAkBH,GAAcD,CAAU;AAAA,EAAA,GAIjD6B,IAAUf,EAAQ,MAAM;AAC5B,UAAMgB,IAAkB,CAAA,GAClBC,IAAO,CAACC,GAAmBC,GAAeC,MAA4B;AAC1E,MAAAF,EAAM,QAAQ,CAACG,GAAMC,MAAM;AACzB,QAAAN,EAAI,KAAK,EAAE,MAAAK,GAAM,OAAAF,GAAO,SAASD,EAAM,QAAQ,UAAUI,IAAI,GAAG,UAAAF,EAAA,CAAU,GACtEC,EAAK,YAAYtB,EAAS,IAAIsB,EAAK,EAAE,KAAGJ,EAAKI,EAAK,UAAUF,IAAQ,GAAGE,EAAK,EAAE;AAAA,MACpF,CAAC;AAAA,IACH;AACA,WAAAJ,EAAKnC,GAAM,GAAG,IAAI,GACXkC;AAAA,EACT,GAAG,CAAClC,GAAMiB,CAAQ,CAAC,GAGbwB,IACHnB,KAAaW,EAAQ,KAAK,CAACS,MAAMA,EAAE,KAAK,OAAOpB,CAAS,KAAKA,KAC7DD,KAAYY,EAAQ,KAAK,CAACS,MAAMA,EAAE,KAAK,OAAOrB,CAAQ,KAAKA,OAC5DsB,IAAAV,EAAQ,CAAC,MAAT,gBAAAU,EAAY,KAAK,KAEbC,IAAY,CAACd,MAA2B;;AAC5C,IAAKA,MACLP,EAAaO,CAAE,IACfa,IAAAnB,EAAS,QAAQ,IAAIM,CAAE,MAAvB,QAAAa,EAA0B;AAAA,EAC5B,GAEME,IAAgB,CAAC,GAAiCC,MAAmB;;AACzE,UAAM,EAAE,MAAAP,MAASO,GACXC,IAAc,CAAC,CAACR,EAAK,UACrBS,IAAS/B,EAAS,IAAIsB,EAAK,EAAE,GAC7BU,IAAQhB,EAAQ,UAAU,CAACS,MAAMA,EAAE,KAAK,OAAOH,EAAK,EAAE;AAE5D,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK;AACH,UAAE,eAAA,GACFK,GAAUD,IAAAV,EAAQgB,IAAQ,CAAC,MAAjB,gBAAAN,EAAoB,KAAK,EAAE;AACrC;AAAA,MACF,KAAK;AACH,UAAE,eAAA,GACFC,GAAUM,IAAAjB,EAAQgB,IAAQ,CAAC,MAAjB,gBAAAC,EAAoB,KAAK,EAAE;AACrC;AAAA,MACF,KAAK;AACH,UAAE,eAAA,GACEH,KAAe,CAACC,IAAQnB,EAAQU,EAAK,IAAI,EAAI,IACxCQ,KAAeC,KAAQJ,GAAUO,IAAAZ,EAAK,SAAU,CAAC,MAAhB,gBAAAY,EAAmB,EAAE;AAC/D;AAAA,MACF,KAAK;AACH,UAAE,eAAA,GACEJ,KAAeC,IAAQnB,EAAQU,EAAK,IAAI,EAAK,IACxCO,EAAK,YAAUF,EAAUE,EAAK,QAAQ;AAC/C;AAAA,MACF,KAAK;AACH,UAAE,eAAA,GACFF,GAAUQ,IAAAnB,EAAQ,CAAC,MAAT,gBAAAmB,EAAY,KAAK,EAAE;AAC7B;AAAA,MACF,KAAK;AACH,UAAE,eAAA,GACFR,GAAUS,IAAApB,EAAQA,EAAQ,SAAS,CAAC,MAA1B,gBAAAoB,EAA6B,KAAK,EAAE;AAC9C;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,UAAE,eAAA,GACFrB,EAAOO,EAAK,EAAE,GACVQ,KAAalB,EAAQU,EAAK,IAAI,CAACS,CAAM;AACzC;AAAA,MACF;AACE;AAAA,IAAA;AAEJ,MAAE,gBAAA;AAAA,EACJ;AAEA,WAASM,EACPf,GACAF,GACAkB,GACAC,GACAlB,GACW;AACX,UAAMS,IAAc,CAAC,CAACR,EAAK,UACrBS,IAAS/B,EAAS,IAAIsB,EAAK,EAAE,GAC7BkB,IAAapC,MAAakB,EAAK,IAC/BmB,IAAcX,IAAeC,IAASW,IAAaC,IAAUC,GAC7Df,IAAiB,EAAE,MAAAP,GAAgC,UAAAD,EAAA;AAEzD,WACE,gBAAAwB;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,KAAK,CAACC,MAAO;AACX,UAAIA,IAAIvC,EAAS,QAAQ,IAAIe,EAAK,IAAIwB,CAAE,IACnCvC,EAAS,QAAQ,OAAOe,EAAK,EAAE;AAAA,QACtC;AAAA,QACA,MAAK;AAAA,QACL,iBAAeQ,IAAcC,IAAS;AAAA,QACtC,iBAAeS;AAAA,QACf,cAAYpB;AAAA,QACZ,gBAAckB;AAAA,QACd,iBAAeC;AAAA,QACf,UAAUf,MAAcF,EAAK,KAAK,IAAI;AAAA,QACtC,SAAS,CAACyB,MAAM;AACd,UAAIA,EAAE,WAAWA,EAAE,iBAAezC,EAAagB,EAAK,EAAE;AAAA,QACxD;AAAA,QACA,WAAW,CAACyB,MAAM;AAChB,UAAIA,EAAE,WAAWA,EAAE,iBAAenB,EAAcmB,GAAGlB,CAAI;AAAA,QACzD;AAAA,QACA,SAAS,CAACkB,MAAM;AACd,UAAAA,EAAE,gBAAA,GACFzC,EAAagB,EAAK,EAAE,GACpBP,EAAOO,EAAK,EAAE,GACVQ,KAAalB,EAAQU,EAAK,IAAI,CAACS,CAAM;AAAA,QAC3C;AAAA,QACA,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA,gBAAAc;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,EAAE,cAAczB,IAAQ,KAAK,KAAK,EAAA;AAAA,cACzC,WAAW4B;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,gBACAR,KAAc;AAAA,cAAA;AAAA,cAGf,UAAA;AAAA,gBAAAV,IACC,gBAAAmB;AAAA,kBAACC;AAAA,kBAAA;AAAA,oBACC,WAAWF;AAAA,sBACT;AAAA,sBACAjB,KAAU;AAAA,oBAAA;AAAA,oBAEZ,eAAW;AAAA,kBAAA;AAAA,gBAAA,IAGb,gBAAAkB,EAAC,QAAA,EAAK,WAAU,kBAAiB,eAAW,IAAC;AAAA,gBAE9C3B,EAAK,QACJ,gBAAA2B,EAACR,KAAY,WAAU,yCAAwC,eAAW,IAAC;AAAA,gBAE7E,gBAAAQ;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAU;AAAA,oBACV,OAAO,OAAO3B,EAAK,SAAU,WAAWA,EAAK,QAAQ;AAAA,oBAEpD,UAAAA,EAAK;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACR;AAAA,YAAA;AAAA,UAAA;AAAA,UAEDQ,KAAeC,KACd,gBAAAkB,EAAC,MAAA,EAAG,MAAK,SAAQ,WAAU,UACxB,UAAA3B,EAAK,SAAU;AAAA,YAAI,CAAC6B,GAAG5B,MACtBc,EAAWc,GAAG/B,IAAQ,GAAGE,EAAK,SAAU,QAAQC,IAAI,GAAGD,EAAK,EAAE;AAAA,UAAA,EAChE,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,MA7DGA,EAAK;AAAA,IAAA;AAAA,EAiEhB;AAEA,SACE,gBAAA2B;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAYxD,MAAcC,IAAiB,SAAYC,EAAQ,KAAK;AAAA,MACpE,mBAAiBD;AAAA,MACjB,WAAWsD,EAAG,yBAAyBxD,CAAS;AAAA,MAE/C,UAAAT,EAAK,IAAI,CAACqE,GAAG7B,MAAMc,EAAWe,GAAG,GAAGrE,EAAK,QAAQwC,IAAI,GAAG,IAAI,CAAC;AAAA,IAAA;AAAA,EAAA;AAGpE;AACAzC,GAAK,cAAc;"}
@@ -0,0 +1,29 @@
1
+ export interface FieldIds {
2
+ /** Id for the control itself (`<input id>` / `<label htmlFor>`). */
3
+ fieldId: string;
4
+ /** Id for the description / helper text element. */
5
+ helperId: string;
6
+ /** Id for the validation message element. */
7
+ errorId: string;
8
+ /**
9
+ * `aria-describedby` value computed from what actually renders — the error
10
+ * wins over the helper; `undefined` when neither is present.
11
+ */
12
+ describedBy: string | undefined;
13
+ }
14
+ /**
15
+ * Shared id wiring for form fields: one stable id for the control plus
16
+ * derived helper / error ids, and an `aria-describedby` that only references
17
+ * elements that exist. Pass a consumer `id` to keep `<label htmlFor>` in sync.
18
+ *
19
+ * @example
20
+ * const { fieldId, helperId, errorId, describedBy } = useFieldIds(id, {
21
+ * hasHelper: Boolean(helperText),
22
+ * hasError: Boolean(error),
23
+ * });
24
+ */
25
+ export declare function useFieldIds(id?: string, present?: {
26
+ hasHelper?: boolean;
27
+ hasError?: boolean;
28
+ extra?: string;
29
+ }): FieldIds;
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useId as n } from "react";
3
+ function c(s, r = {}) {
4
+ const i = n(), e = s ?? i, o = `${e}-helper`, t = `${e}-error`, d = [
5
+ r.hasError ? t : r.hasHelper ? o : void 0,
6
+ r.extra
7
+ ].filter(Boolean);
8
+ return {
9
+ fieldId: e,
10
+ helperId: o,
11
+ errorId: t,
12
+ describedBy: d.length ? d.join(" ") : void 0
13
+ };
14
+ }
15
+ export {
16
+ c as useFieldIds
17
+ };
18
+ //# sourceMappingURL=use-field-ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-field-ids.js","sources":["../../src/hooks/use-field-ids.ts"],"sourcesContent":["'use client';\n\nimport { useId } from 'react';\n\nexport interface FieldIds {\n /** Id for the control itself (`<input id>` / `<label htmlFor>`). */\n fieldId: string;\n /** Id for the description / helper text element. */\n helperId: string;\n /** Id for the validation message element. */\n errorId: string;\n /**\n * `aria-describedby` value computed from what actually renders — the error\n * wins over the helper; `undefined` when neither is present.\n */\n describedBy: string | undefined;\n}\n\n/**\n * Shared id wiring for form fields: one stable id for the control plus\n * derived helper / error ids, and an `aria-describedby` that only references\n * elements that exist. Pass a consumer `id` to keep `<label htmlFor>` in sync.\n *\n * @example\n * const { fieldId, helperId, errorId, describedBy } = useFieldIds(id, {\n * hasHelper: Boolean(helperText),\n * hasError: Boolean(error),\n * });\n */\nexport function useFieldIds(\n id?: string,\n present: { hasHelper?: boolean; hasError?: boolean; extra?: string } = {},\n): FieldIds {\n const autoId = useId();\n const fieldId = id ?? autoId;\n const helperId = `${fieldId}-helper`;\n const errorId = `${fieldId}-error`;\n const parts = [\n present.hasError ? errorId : present.hasHelper ? helperId : undefined,\n present.extra,\n ].filter(Boolean);\n return {\n fieldId,\n helperId,\n errorId,\n describedBy: parts.length ? parts.join(' ') : undefined,\n };\n}\n"],"names":["useFieldIds","id","present","autoId","useId","fieldId","helperId","errorId","parts"],"mappings":";;AA6BO,SAASA,EACdC,GACAC,IAAuE,IAC7D;AACV,QAAMC,IAASC,EAAA,GACTC,IAAUJ,KAAME,GAChBG,IAAW,GAAGD,CAAO,WACrBE,IAAU,GAAGF,CAAO,UACpBG,IAAQ;AAAA,IACZN,EAAQ,WAAWK,IAAUL,EAAQ,YAAYI,IAAW;AAAA,IAC5DJ,EAAQ;AAAA,EAAA,EACR,OAAO,OAAO;AAChB,SAAO;AAAA,IACL,SAAAG;AAAA,IACA,UAAAC;AAAA,IACA,SAAAC;AAAA,IACA,aAAaC,EAAM,SAASA,EAAM,KAAK,GAAG,IAAI;AAAA,EAAA;AAElD;"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useState as s, useEffect as c } from "react";
3
+ function d(e) {
4
+ const [i, n] = s(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
5
+ return c(() => {
6
+ if (typeof window > "u") return;
7
+ const t = window.matchMedia(e), r = (o) => n(o.matches);
8
+ return n(t.matches), t.addEventListener("change", r), () => t.removeEventListener("change", r);
9
+ }, [e]), i;
10
+ }
11
+ function a() {
12
+ return d("(prefers-reduced-motion: reduce)");
13
+ }
14
+ export {
15
+ d as useMediaQuery,
16
+ a as usePrefersReducedMotion
17
+ };
18
+ //# sourceMappingURL=use-media-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-query.js","sources":["../../src/hooks/use-media-query.ts"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Subscribe to a CSS media query. SSR-safe — returns `false` on the server.\n *\n * @example\n * const isDesktop = useMediaQuery('(min-width: 1024px)');\n */\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n if (typeof window === 'undefined') return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const list = window.matchMedia(query);\n const onChange = (event: MediaQueryListEvent) => setMatches(event.matches);\n setMatches(list.matches);\n list.addEventListener('change', onChange);\n return () => list.removeEventListener('change', onChange);\n }, [query]);\n\n return matches;\n}\n\n/** Convenience: respect `prefers-reduced-motion`. */\nexport function usePrefersReducedMotion(): boolean {\n return useMediaQuery('(prefers-reduced-motion: reduce)');\n}\n"],"names":["useMediaQuery","query","matches","setMatches","useState","useEffect","list","onChange","event","usePrefersReducedMotion"],"mappings":";;AAUO,SAASA,EAAcC,GAAwB;AACpD,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAS,MACjC,OAAO,SAAW,MAAoB,KACnC,OAAO,WAAWH,CAAK,EAAE,OACjC;AAED,SAAAI,EAAU,MAAM;AACd,QAAI,OAAO,SAAW,IAAa;AACnC,UAAMC,IAAO,OAAO,WAAWL,CAAK,GAC9BM,IAAW,CAACC,MAA+BL,EAAWK,EAAM,OAAO;AACzE,WAAAL,EAAWG,EAAK,OAAO,GACvBA,EAAK,iBAAiB,UAAUC,CAAQ,GACjC,MAAMD,EAAK,oBAAoB,UAAUC,CAAQ;AAAA,EAC1D,GAAG,CAACN,CAAK,CAAC,GAEHC;AACT;AAGO,SAASO,IAAmC;AACjD,SAAOT,EAAc,kCAAkC;AACzD;"}
@@ -0,0 +1,5 @@
1
+ import { UiStrings } from '../lib/strings.js';
2
+ /** Resolved (complete) strings for the current subtree. */
3
+ export declare const StringsContext: import('react').Context<UiStrings>;
4
+ /** Read the library strings — falls back to the English defaults without a provider. */
5
+ export declare function useStrings(): UiStrings;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { useContext as t, createContext as e } from "react";
3
+ import { defaultStrings as n } from "../lib/strings.js";
4
+ const r = e(n);
5
+ function s() {
6
+ return t(r);
7
+ }
8
+ export {
9
+ r as StringsContext,
10
+ s as useStrings
11
+ };
12
+ //# sourceMappingURL=use-strings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-strings.js","sources":["../../src/hooks/use-strings.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext } from 'react';\nimport { defaultStrings, type UiStrings } from '@/lib/strings';\n\n/** Resolved (complete) strings for the current subtree. */\nexport const StringsContext = createContext<UiStrings>(defaultStrings);\n\n/** Read the library strings — falls back to the English defaults without a provider. */\nexport function useStrings(): UiStrings {\n return useContext(StringsContext);\n}\n"],"names":["StringsContext","createContext","defaultStrings","useStrings","useContext"],"mappings":";;;AAMO,MAAMA,IAAiBC,EAAyBC,CAAc;AAG9D,SAASC,IAAwB;AACtC,SAAOC,EAAWJ,CAAc;AAClC;"}
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { useState as h, useEffect as u, useCallback as n } from "react";
3
+ const i = {
4
+ toasts: [],
5
+ listeners: /* @__PURE__ */ new Set(),
6
+ emit() {
7
+ for (const s of this.listeners) s(this.toasts);
8
+ },
9
+ push(s) {
10
+ const t = s.id ?? `t_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`, o = { open: !0, duration: 5e3, variant: "default", ...s, id: t };
11
+ return this.toasts = [o, ...this.toasts].slice(0, 3), this.emit(), t;
12
+ },
13
+ dismiss(s) {
14
+ this.toasts = this.toasts.map((t) => t.id === s ? { ...t, open: !1 } : t), this.emit();
15
+ },
16
+ remove(s) {
17
+ this.toasts = this.toasts.filter((t) => t.id !== s), this.emit();
18
+ }
19
+ };
20
+ function m() {
21
+ const [s, t] = h(() => [...i.toasts]);
22
+ u(() => {
23
+ const e = (c) => t([...c]);
24
+ return i.listeners.add(e), () => {
25
+ i.listeners.delete(e);
26
+ };
27
+ }, []);
28
+ const o = n((e) => i.push(e), []), a = n((e) => i.dismiss(e), []), r = n((e) => i.remove(e), []);
29
+ return { toasts: s, push: o, dismiss: a, remove: r };
30
+ }
31
+ const d = (s) => i.push(s);
32
+ export {
33
+ d as toast,
34
+ m as useToast
35
+ };
36
+ //# sourceMappingURL=use-toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-toast.js","sources":["../../src/hooks/use-toast.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useState, type ReactNode } from 'react';\n\n/* -----------------------------------------------------------------------------\n * Minimal toast queue + hook. The host app mounts a single <ToastHub> near\n * the root which subscribes to this store; any component can call\n * `useToast().push({...})` from anywhere.\n *\n * Kept dependency-free intentionally — no external state library.\n * --------------------------------------------------------------------------- */\n\nexport type ToastVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface ToastDescriptor {\n /** Auto-generated; consumers can pass an explicit id to update an in-flight toast. */\n id?: string;\n title?: ReactNode;\n description?: ReactNode;\n variant?: ToastVariant;\n /** Milliseconds before auto-dismiss. Default 5000. Set to 0 to keep open. */\n duration?: number;\n /** Action button. The alt text is used for screen reader announcements. */\n action?: {\n label: ReactNode;\n altText: string;\n onClick: () => void;\n };\n}\n\ninterface InternalToast extends ToastDescriptor {\n id: string;\n open: boolean;\n}\n\ntype Listener = (toasts: InternalToast[]) => void;\n\ninterface ToastStore {\n toasts: InternalToast[];\n listeners: Set<Listener>;\n emit(): void;\n push(t: ToastDescriptor): string;\n dismiss(id: string): void;\n remove(id: string): void;\n}\n\nconst store: ToastStore = {\n toasts: [],\n listeners: new Set<Listener>(),\n emit() {\n for (const listener of this.listeners) listener(this.toasts);\n },\n push(t: ToastDescriptor) {\n const id = t.id ?? `t_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n const next: InternalToast = { open: true, duration: 5000, variant: 'default', ...t, id };\n this.toasts = [next, ...this.toasts].slice(0, 3);\n this.emit();\n return id;\n },\n dismiss(id: string) {\n this.toasts = this.toasts.map((t: InternalToast) => (t.id === id ? { ...t, open: false } : t));\n this.emit();\n },\n remove(id: string) {\n this.toasts = this.toasts.filter((t: InternalToast) => t.id !== id);\n this.emit();\n },\n};\n\n/**\n * Subscribe to the toast queue and dispatch new toasts.\n *\n * @example\n * const toast = useToast();\n * toast.push({ variant: 'success', title: 'Saved' });\n *\n * // With an action\n * toast.push({\n * title: 'Project archived',\n * action: { label: 'Undo', altText: 'Undo archive', onClick: undo },\n * });\n */\nexport function useToast() {\n const [toasts, setToasts] = useState<InternalToast[]>(() => [...store.toasts]);\n\n useEffect(() => {\n const listener: Listener = (next) => setToasts([...next]);\n store.listeners.add(listener);\n return () => {\n store.listeners.delete(listener);\n };\n }, []);\n\n const push = useCallback((t: ToastDescriptor) => store.push(t), []);\n const dismiss = useCallback((id: string) => store.dismiss(id), []);\n const remove = useCallback((id: string) => store.remove(id), []);\n\n return { toasts, push, dismiss, remove };\n}\n\n/** Convenience export — dispatch a toast outside React (e.g. from an API client). */\nexport const toast = (t: ToastDescriptor) => store.push(t);\n"],"names":["store","listener","t","id","next","useToast","toasts","setToasts","useState","useEffect","push","useCallback","dismiss","remove","toast"],"mappings":";;AA8CA,MAAMA,IAAoB;AAAA,EACxB,QAAQ,CAAA;AAAA,EACR,+BAAe,IAAA;AAAA,EACf,OAAO;AACL,eAAWC,KAAY,KAAK,UAAW,CAAAA,EAAS,KAAK,MAAM;AAAA,EAC7D;AAAA,EACA,KAAKC,GAAoB;AACvB,UAAMC,IAAKD,EAAE,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,IACtEE,IAAsB,EAAE,MAAM,IAAM,UAAU,KAAM,SAAS,WAAW,GAAGF,GAAG,IAAAC,EAAA;AACpF,gBAAK,SAAS,CAACC,GAAM,GAAG,KAAK,MAAM,EAAE,MAAM,GAAG,CAAC,GAC/C,KAAK,KAAA,GACED;AAAA,EACT;AAAA,EACA,QAAQA,GAAY;AAClB,SAAK,SAAS,KAAK,OAAO,IAAI,CAAC,MAAsB,EAAE,OAAOA,IAAK,EAAE,GAAG,GAAG,MAAM,GAAA,IAAU,CAAE,GAC7F,KAAK,KAAA;AAAA,EACP;AAAA,EACA,OAAOA,GAAY;AACjB,SAAK,SAAS,KAAK,OAAO,OAAO,CAAC,MAAqB,EAAE,OAAOA,CAAE,GAClE,KAAK,KAAA;AAAA,EACP;AACF;AAeO,SAASE,IAAW;AACzB,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAA0B,MAAM,CAAC,GAAGR,EAAM,MAAM,CAAC;AAE7E,EAAAS,EAAU,MAAM;AACd,UAAMR,IAAqB,CAACG,MAASG,EAAU,CAAC,GAAGH,CAAI,CAAC;AACxD,WAAAJ,EAAM,UAAU,IAAIC,CAAQ,GACrB,MAAM;AACX,MAAAD,EAAM,UAAU,OAAOC,CAAQ;AAAA,IACjC;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,QAAMS,IAAOC,EAAY,CAACT,MAAuBF,EAAM,KAAKE,CAAC,GAAG,EAAE,GAC5DU,IAAUD,EAAY,CAACR,MAAeH,EAAM,QAAQG,CAAE,GAAG,EAAE,GAC3DU,IAASF,EAAY,CAACR,MAAeH,EAAM,OAAOG,CAAE,GAAG,EAAE;AAE/D,SAAO,EAAE,QAAAG,GAAQ,MAAAI,GAAM,SAAAE,GAAS,QAAAC,EAAA;AAClC;AAGO,MAAMC,IAAQ,CAACZ,MAAuBF,EAAM,KAAKE,CAAC;"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Secondary entry — `@craftzbay/ui/icon`.
3
+ *
4
+ * Name-addressed `<Icon name="…">` plus the full `iconNames` list. Kept out of
5
+ * the main barrel because it references `lucide-react/dynamicIconImports`
6
+ * (a map of ~1500 lazy imports) which bundlers cannot tree-shake.
7
+ */
8
+ export { Icon, iconNames, type IconName, type IconProps } from './components/ui/Icon.js';
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ import { Icon as c, iconNames as n } from "./components/ui/Icon.js";
3
+ export {
4
+ c as Icon,
5
+ n as iconNames
6
+ };
7
+ //# sourceMappingURL=icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,11 +1,71 @@
1
- /**
2
- * Curated re-exports from `lucide-react`. Components should import icons from
3
- * here, never directly from `lucide-react`, so the design system can swap
4
- * icon sets later if needed and so unused icons stay tree-shakable.
5
- *
6
- * Defaults applied at the call site:
7
- * - 16px for inline-with-text usage
8
- * - 20px for use inside buttons
9
- * - strokeWidth 1.5
10
- */
11
- export { AlertCircle, AlertTriangle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpDown, AtSign, BarChart3, Bell, Bookmark, Calendar, Check, CheckCircle2, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ChevronsLeft, ChevronsRight, ChevronsUpDown, Circle, Copy, CornerDownLeft, CreditCard, Download, Edit2, Ellipsis, Eye, EyeOff, Filter, Folder, GripVertical, Home, Inbox, LayoutGrid, Lock, LogOut, HelpCircle, Info, Link2, Loader2, Mail, Menu, Minus, MoreHorizontal, Package, Plug, Plus, Search, Sparkles, Settings, Sun, Moon, Trash2, Upload, User, Users, X, XCircle, ExternalLink, type LucideIcon, type LucideProps, } from 'lucide-react';
1
+ import { LucideIcon } from 'lucide-react';
2
+ export declare const AlertCircle: LucideIcon;
3
+ export declare const AlertTriangle: LucideIcon;
4
+ export declare const ArrowDown: LucideIcon;
5
+ export declare const ArrowLeft: LucideIcon;
6
+ export declare const ArrowRight: LucideIcon;
7
+ export declare const ArrowUp: LucideIcon;
8
+ export declare const ArrowUpDown: LucideIcon;
9
+ export declare const AtSign: LucideIcon;
10
+ export declare const BarChart3: LucideIcon;
11
+ export declare const Bell: LucideIcon;
12
+ export declare const Bookmark: LucideIcon;
13
+ export declare const Calendar: LucideIcon;
14
+ export declare const Check: LucideIcon;
15
+ export declare const CheckCircle2: LucideIcon;
16
+ export declare const ChevronDown: LucideIcon;
17
+ export declare const ChevronLeft: LucideIcon;
18
+ export declare const ChevronRight: LucideIcon;
19
+ export declare const ChevronUp: LucideIcon;
20
+ export declare const ChevronsLeft: LucideIcon;
21
+ export declare const ChevronsRight: LucideIcon;
22
+ export declare const ChevronsUpDown: LucideIcon;
23
+ export declare const Circle: LucideIcon;
24
+ export declare const Copy: LucideIcon;
25
+ export declare const CornerDownLeft: LucideIcon;
26
+ export declare const CreditCard: LucideIcon;
27
+ export declare const Download: LucideIcon;
28
+ export declare const Edit2: LucideIcon;
29
+ export declare const Ellipsis: LucideIcon;
30
+ export declare const ExternalLink: LucideIcon;
31
+ export declare const Eye: LucideIcon;
32
+ export declare const EyeOff: LucideIcon;
33
+ export declare const File: LucideIcon;
34
+ export declare const FileText: LucideIcon;
35
+ export declare const Filter: LucideIcon;
36
+ export declare const Folder: LucideIcon;
37
+ export declare const FolderOpen: LucideIcon;
38
+ export declare const Github: LucideIcon;
39
+ export declare const GripVertical: LucideIcon;
40
+ export declare const Heart: LucideIcon;
41
+ export declare const HelpCircle: LucideIcon;
42
+ export declare const Home: LucideIcon;
43
+ export declare const Inbox: LucideIcon;
44
+ export declare const Info: LucideIcon;
45
+ export declare const LayoutGrid: LucideIcon;
46
+ export declare const Link2: LucideIcon;
47
+ export declare const Loader2: LucideIcon;
48
+ export declare const Lock: LucideIcon;
49
+ export declare const LogOut: LucideIcon;
50
+ export declare const Mail: LucideIcon;
51
+ export declare const Menu: LucideIcon;
52
+ export declare const Minus: LucideIcon;
53
+ export declare const Moon: LucideIcon;
54
+ export declare const MoreHorizontal: LucideIcon;
55
+ export declare const Package: LucideIcon;
56
+ export declare const Pencil: LucideIcon;
57
+ export declare const Plug: LucideIcon;
58
+ export declare const Plus: LucideIcon;
59
+ export declare const Search: LucideIcon;
60
+ export declare const Settings: LucideIcon;
61
+ export declare const ShoppingCart: LucideIcon;
62
+ export declare const Sparkles: LucideIcon;
63
+ export declare const Star: LucideIcon;
64
+ export declare const Sun: LucideIcon;
65
+ export declare const Trash2: LucideIcon;
66
+ export declare const Upload: LucideIcon;
67
+ export declare const User: LucideIcon;
68
+ export declare const Users: LucideIcon;
69
+ export declare const X: LucideIcon;
70
+ export declare const XCircle: LucideIcon;
71
+ export declare const Zap: LucideIcon;