@craftzbay/ui 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +18 -12
  2. package/dist-lib/__tests__/helpers/color.d.ts +9 -0
  3. package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
  4. package/dist-lib/components/ui/Accordion.js +18 -7
  5. package/dist-lib/components/ui/Accordion.js.map +1 -1
  6. package/dist-lib/components/ui/Alert.d.ts +16 -0
  7. package/dist-lib/components/ui/Alert.js +47 -34
  8. package/dist-lib/components/ui/Alert.js.map +1 -1
  9. package/dist-lib/components/ui/Avatar.d.ts +1 -1
  10. package/dist-lib/components/ui/Avatar.js +45 -47
  11. package/dist-lib/components/ui/Avatar.js.map +1 -1
  12. package/dist-lib/components/ui/Badge.d.ts +3 -1
  13. package/dist-lib/components/ui/Badge.js +24 -15
  14. package/dist-lib/components/ui/Badge.js.map +1 -1
  15. package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
  16. package/dist-lib/components/ui/Breadcrumbs.js +46 -28
  17. package/dist-lib/components/ui/Breadcrumbs.js.map +1 -1
  18. package/dist-lib/components/ui/Button.d.ts +5 -3
  19. package/dist-lib/components/ui/Button.js +59 -45
  20. package/dist-lib/components/ui/Button.js.map +1 -1
  21. package/dist-lib/components/ui/Calendar.d.ts +1 -1
  22. package/dist-lib/components/ui/Calendar.js +87 -59
  23. package/dist-lib/components/ui/Calendar.js.map +1 -1
  24. package/dist-lib/components/ui/Card.d.ts +2 -0
  25. package/dist-lib/components/ui/Card.js +48 -67
  26. package/dist-lib/components/ui/Card.js.map +1 -1
  27. package/dist-lib/components/ui/Carousel.d.ts +6 -6
  28. package/dist-lib/components/ui/Carousel.js +133 -102
  29. package/dist-lib/components/ui/Carousel.js.map +1 -1
  30. package/dist-lib/components/ui/Chart.d.ts +49 -10
  31. package/dist-lib/components/ui/Chart.js +415 -181
  32. package/dist-lib/components/ui/Chart.js.map +1 -1
  33. package/dist-lib/components/ui/Checkbox.js +42 -28
  34. package/dist-lib/components/ui/Checkbox.js.map +1 -1
  35. package/dist-lib/components/ui/Combobox.d.ts +2 -0
  36. package/dist-lib/components/ui/Combobox.js +142 -111
  37. package/dist-lib/components/ui/Combobox.js.map +1 -1
  38. package/dist-lib/components/ui/CommandPalette.d.ts +6 -3
  39. package/dist-lib/components/ui/CommandPalette.js +92 -87
  40. package/dist-lib/components/ui/CommandPalette.js.map +1 -1
  41. package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
  42. package/dist-lib/components/ui/ContextMenu.js +77 -62
  43. package/dist-lib/components/ui/ContextMenu.js.map +1 -1
  44. package/dist-lib/components/ui/DataGrid.d.ts +17 -4
  45. package/dist-lib/components/ui/DataGrid.js +65 -50
  46. package/dist-lib/components/ui/DataGrid.js.map +1 -1
  47. package/dist-lib/components/ui/DatePicker.js +118 -99
  48. package/dist-lib/components/ui/DatePicker.js.map +1 -1
  49. package/dist-lib/components/ui/DesignSystemProvider.d.ts +94 -40
  50. package/dist-lib/components/ui/DesignSystemProvider.js +111 -55
  51. package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -1
  52. package/dist-lib/components/ui/Dialog.d.ts +18 -3
  53. package/dist-lib/components/ui/Dialog.js +105 -80
  54. package/dist-lib/components/ui/Dialog.js.map +1 -1
  55. package/dist-lib/components/ui/Drawer.d.ts +17 -2
  56. package/dist-lib/components/ui/Drawer.js +89 -55
  57. package/dist-lib/components/ui/Drawer.js.map +1 -1
  58. package/dist-lib/components/ui/DropdownMenu.js +14 -9
  59. package/dist-lib/components/ui/DropdownMenu.js.map +1 -1
  60. package/dist-lib/components/ui/EmptyState.d.ts +2 -0
  61. package/dist-lib/components/ui/EmptyState.js +30 -16
  62. package/dist-lib/components/ui/EmptyState.js.map +1 -1
  63. package/dist-lib/components/ui/ErrorState.d.ts +13 -2
  64. package/dist-lib/components/ui/ErrorState.js +44 -23
  65. package/dist-lib/components/ui/ErrorState.js.map +1 -1
  66. package/dist-lib/components/ui/FileUpload.js +59 -56
  67. package/dist-lib/components/ui/FileUpload.js.map +1 -1
  68. package/dist-lib/components/ui/Form.d.ts +15 -2
  69. package/dist-lib/components/ui/Form.js +97 -71
  70. package/dist-lib/components/ui/Form.js.map +1 -1
  71. package/dist-lib/components/ui/Icon.d.ts +1 -1
  72. package/dist-lib/components/ui/Icon.js +20 -14
  73. package/dist-lib/components/ui/Icon.js.map +1 -1
  74. package/dist-lib/components/ui/IconButton.d.ts +2 -2
  75. package/dist-lib/components/ui/IconButton.js +28 -20
  76. package/dist-lib/components/ui/IconButton.js.map +1 -1
  77. package/dist-lib/components/ui/Input.d.ts +3 -1
  78. package/dist-lib/components/ui/Input.js +102 -79
  79. package/dist-lib/components/ui/Input.js.map +1 -1
  80. package/dist-lib/components/ui/Kbd.js +1 -1
  81. package/dist-lib/components/ui/Kbd.js.map +1 -1
  82. package/dist-lib/components/ui/MultiSelect.js +121 -107
  83. package/dist-lib/components/ui/MultiSelect.js.map +1 -1
  84. package/dist-lib/components/ui/Pagination.js +67 -62
  85. package/dist-lib/components/ui/Pagination.js.map +1 -1
  86. package/dist-lib/components/ui/Popover.js +14 -14
  87. package/dist-lib/components/ui/Popover.js.map +1 -1
  88. package/dist-lib/components/ui/Progress.d.ts +3 -3
  89. package/dist-lib/components/ui/Progress.js +77 -72
  90. package/dist-lib/components/ui/Progress.js.map +1 -1
  91. package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
  92. package/dist-lib/components/ui/RadioGroup.js +69 -52
  93. package/dist-lib/components/ui/RadioGroup.js.map +1 -1
  94. package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
  95. package/dist-lib/components/ui/RelativeTime.js +31 -0
  96. package/dist-lib/components/ui/RelativeTime.js.map +1 -0
  97. package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
  98. package/dist-lib/components/ui/ScrollArea.js +43 -27
  99. package/dist-lib/components/ui/ScrollArea.js.map +1 -1
  100. package/dist-lib/components/ui/Select.d.ts +6 -1
  101. package/dist-lib/components/ui/Select.js +79 -71
  102. package/dist-lib/components/ui/Select.js.map +1 -1
  103. package/dist-lib/components/ui/Separator.js +1 -1
  104. package/dist-lib/components/ui/Separator.js.map +1 -1
  105. package/dist-lib/components/ui/Sheet.d.ts +9 -0
  106. package/dist-lib/components/ui/Sheet.js +69 -46
  107. package/dist-lib/components/ui/Sheet.js.map +1 -1
  108. package/dist-lib/components/ui/Sidebar.d.ts +12 -9
  109. package/dist-lib/components/ui/Sidebar.js +152 -109
  110. package/dist-lib/components/ui/Sidebar.js.map +1 -1
  111. package/dist-lib/components/ui/Skeleton.d.ts +13 -2
  112. package/dist-lib/components/ui/Skeleton.js +15 -14
  113. package/dist-lib/components/ui/Skeleton.js.map +1 -1
  114. package/dist-lib/components/ui/Slider.js +41 -29
  115. package/dist-lib/components/ui/Slider.js.map +1 -1
  116. package/dist-lib/components/ui/Snackbar.js +23 -22
  117. package/dist-lib/components/ui/Snackbar.js.map +1 -1
  118. package/dist-lib/components/ui/Spinner.js +18 -6
  119. package/dist-lib/components/ui/Spinner.js.map +1 -1
  120. package/dist-lib/components/ui/Stepper.d.ts +6 -0
  121. package/dist-lib/components/ui/Stepper.js +71 -48
  122. package/dist-lib/components/ui/Stepper.js.map +1 -1
  123. package/dist-lib/components/ui/Switch.js +46 -43
  124. package/dist-lib/components/ui/Switch.js.map +1 -1
  125. package/dist-lib/components/ui/Table.d.ts +33 -5
  126. package/dist-lib/components/ui/Table.js +141 -119
  127. package/dist-lib/components/ui/Table.js.map +1 -1
  128. package/dist-lib/components/ui/Tabs.js +50 -48
  129. package/dist-lib/components/ui/Tabs.js.map +1 -1
  130. package/dist-lib/components/ui/TagInput.js +45 -45
  131. package/dist-lib/components/ui/TagInput.js.map +1 -1
  132. package/dist-lib/components/ui/Textarea.js +65 -54
  133. package/dist-lib/components/ui/Textarea.js.map +1 -1
  134. package/dist-lib/components/ui/Timeline.js +39 -35
  135. package/dist-lib/components/ui/Timeline.js.map +1 -1
  136. package/dist-lib/components/ui/Toast.js +44 -57
  137. package/dist-lib/components/ui/Toast.js.map +1 -1
  138. package/dist-lib/components/ui/Tooltip.d.ts +4 -1
  139. package/dist-lib/components/ui/Tooltip.js +24 -22
  140. package/dist-lib/components/ui/Tooltip.js.map +1 -1
  141. package/dist-lib/components/ui/TopNav.d.ts +7 -3
  142. package/dist-lib/components/ui/TopNav.js +39 -22
  143. package/dist-lib/components/ui/TopNav.js.map +1 -1
  144. package/dist-lib/components/ui/Tree.d.ts +15 -10
  145. package/dist-lib/components/ui/Tree.js +82 -79
  146. package/dist-lib/components/ui/Tree.js.map +1 -1
  147. package/dist-lib/hooks/use-debounce.d.ts +19 -0
  148. package/dist-lib/hooks/use-debounce.js +36 -0
  149. package/dist-lib/hooks/use-debounce.js.map +1 -0
  150. package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
  151. package/dist-lib/hooks/use-delayed-loading.js +20 -0
  152. package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
  153. package/dist-lib/hooks/use-field-ids.d.ts +2 -1
  154. package/dist-lib/hooks/use-field-ids.js +9 -9
  155. package/dist-lib/hooks/use-field-ids.js.map +1 -1
  156. package/dist-lib/hooks/use-media-query.d.ts +3 -1
  157. package/dist-lib/hooks/use-media-query.js +16 -12
  158. package/dist-lib/hooks/use-media-query.js.map +1 -1
  159. package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
  160. package/dist-lib/hooks/use-modifier-key.js +19 -0
  161. package/dist-lib/hooks/use-modifier-key.js.map +1 -0
  162. package/dist-lib/hooks/use-toast.d.ts +7 -2
  163. package/dist-lib/hooks/use-toast.js +61 -30
  164. package/dist-lib/hooks/use-toast.js.map +1 -1
  165. package/dist-lib/icons/index.d.ts +9 -0
  166. package/dist-lib/icons/index.js +148 -130
  167. package/dist-lib/icons/index.js.map +1 -1
  168. package/dist-lib/illustrations/index.d.ts +1 -0
  169. package/dist-lib/illustrations/index.js +15 -6
  170. package/dist-lib/illustrations/index.js.map +1 -1
  171. package/dist-lib/index.d.ts +6 -0
  172. package/dist-lib/index.js +280 -260
  173. package/dist-lib/index.js.map +1 -1
  174. package/dist-lib/lib/format.d.ts +65 -0
  175. package/dist-lib/lib/format.js +95 -0
  176. package/dist-lib/lib/format.js.map +1 -0
  177. package/dist-lib/lib/return-focus.d.ts +11 -0
  178. package/dist-lib/lib/return-focus.js +12 -0
  179. package/dist-lib/lib/return-focus.js.map +1 -0
  180. package/dist-lib/lib/strings.d.ts +62 -1
  181. package/dist-lib/lib/strings.js +75 -19
  182. package/dist-lib/lib/strings.js.map +1 -1
  183. package/dist-lib/lib/strings.mn.js +50 -5
  184. package/dist-lib/lib/strings.mn.js.map +1 -1
  185. package/dist-lib/styles.css +1 -1
  186. package/dist-lib/theme.css +141 -78
  187. package/package.json +11 -4
@@ -2,17 +2,18 @@
2
2
  import { jsxs as d, jsx as o } from "react/jsx-runtime";
3
3
  import { forwardRef as n } from "react";
4
4
  import * as t from "@radix-ui/react-dialog";
5
- import { X as h } from "../../icons/index.js";
5
+ import { X as g } from "../../icons/index.js";
6
6
  import { cn as i } from "../../lib/utils.js";
7
- import { useStrings as p } from "../../hooks/use-strings.js";
8
- import { cva as g } from "class-variance-authority";
9
- const P = t.Root, F = t.Trigger, H = t.Close, b = t.Portal, l = n(function({ className: e, ...r }, s) {
7
+ import { useStrings as b } from "../../hooks/use-strings.js";
8
+ import { withReturnFocus as x } from "../../lib/return-focus.js";
9
+ import { cva as v } from "class-variance-authority";
10
+ const k = t.Root, A = t.Trigger, V = t.Close, S = t.Portal, l = n(function({ className: e, ...r }, s) {
10
11
  return /* @__PURE__ */ o(
11
12
  t.Overlay,
12
13
  {
13
14
  ref: s,
14
15
  className: i(
15
- "fixed inset-0 z-[var(--z-overlay)] bg-overlay",
16
+ "bg-overlay fixed inset-0 z-[var(--z-overlay)]",
16
17
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
17
18
  "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0",
18
19
  e
@@ -22,10 +23,12 @@ const P = t.Root, F = t.Trigger, H = t.Close, b = t.Portal, l = n(function({ cla
22
23
  );
23
24
  });
24
25
  l.displayName = "SheetOverlay";
25
- const x = g(
26
+ const y = v(
26
27
  [
27
28
  "fixed z-[var(--z-modal)] bg-card text-card-foreground shadow-lg",
28
29
  "flex flex-col gap-4 p-6",
30
+ // Safe-area insets for notched devices (consumers set viewport-fit=cover).
31
+ "pb-[max(1.5rem,env(safe-area-inset-bottom))] pl-[max(1.5rem,env(safe-area-inset-left))] pr-[max(1.5rem,env(safe-area-inset-right))]",
29
32
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
30
33
  "data-[state=closed]:duration-[var(--duration-base)] data-[state=open]:duration-[var(--duration-slow)]"
31
34
  ],
@@ -40,74 +43,94 @@ const x = g(
40
43
  },
41
44
  defaultVariants: { side: "right" }
42
45
  }
43
- ), v = n(function({ className: e, children: r, side: s = "right", showClose: c = !0, ...f }, m) {
44
- const u = p();
45
- return /* @__PURE__ */ d(b, { children: [
46
+ ), N = n(function({
47
+ className: e,
48
+ children: r,
49
+ side: s = "right",
50
+ showClose: m = !0,
51
+ returnFocusTo: f,
52
+ onCloseAutoFocus: c,
53
+ ...u
54
+ }, h) {
55
+ const p = b();
56
+ return /* @__PURE__ */ d(S, { children: [
46
57
  /* @__PURE__ */ o(l, {}),
47
- /* @__PURE__ */ d(t.Content, { ref: m, className: i(x({ side: s }), e), ...f, children: [
48
- r,
49
- c && /* @__PURE__ */ o(
50
- t.Close,
51
- {
52
- "aria-label": u.sheet.close,
53
- className: i(
54
- "absolute right-4 top-4 inline-flex size-8 items-center justify-center rounded-md text-foreground-subtle",
55
- "hover:bg-background-muted hover:text-foreground",
56
- "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card",
57
- "transition-colors duration-[var(--duration-fast)]"
58
- ),
59
- children: /* @__PURE__ */ o(h, { className: "size-4", "aria-hidden": !0 })
60
- }
61
- )
62
- ] })
58
+ /* @__PURE__ */ d(
59
+ t.Content,
60
+ {
61
+ ref: h,
62
+ className: i(y({ side: s }), e),
63
+ onCloseAutoFocus: x(f, c),
64
+ ...u,
65
+ children: [
66
+ r,
67
+ m && /* @__PURE__ */ o(
68
+ t.Close,
69
+ {
70
+ "aria-label": p.sheet.close,
71
+ className: i(
72
+ "text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md",
73
+ "hover:bg-background-muted hover:text-foreground",
74
+ "focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
75
+ "transition-colors duration-[var(--duration-fast)]"
76
+ ),
77
+ children: /* @__PURE__ */ o(g, { className: "size-4", "aria-hidden": !0 })
78
+ }
79
+ )
80
+ ]
81
+ }
82
+ )
63
83
  ] });
64
84
  });
65
- v.displayName = "SheetContent";
66
- function S({ className: a, ...e }) {
85
+ N.displayName = "SheetContent";
86
+ function w({ className: a, ...e }) {
67
87
  return /* @__PURE__ */ o("div", { className: i("flex flex-col gap-1", a), ...e });
68
88
  }
69
- S.displayName = "SheetHeader";
70
- function y({ className: a, ...e }) {
89
+ w.displayName = "SheetHeader";
90
+ function C({ className: a, ...e }) {
71
91
  return /* @__PURE__ */ o(
72
92
  "div",
73
93
  {
74
- className: i("mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end", a),
94
+ className: i(
95
+ "mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end",
96
+ a
97
+ ),
75
98
  ...e
76
99
  }
77
100
  );
78
101
  }
79
- y.displayName = "SheetFooter";
80
- const N = n(function({ className: e, ...r }, s) {
102
+ C.displayName = "SheetFooter";
103
+ const z = n(function({ className: e, ...r }, s) {
81
104
  return /* @__PURE__ */ o(
82
105
  t.Title,
83
106
  {
84
107
  ref: s,
85
- className: i("text-lg font-semibold text-foreground leading-tight", e),
108
+ className: i("text-foreground text-lg leading-tight font-semibold", e),
86
109
  ...r
87
110
  }
88
111
  );
89
112
  });
90
- N.displayName = "SheetTitle";
91
- const w = n(function({ className: e, ...r }, s) {
113
+ z.displayName = "SheetTitle";
114
+ const T = n(function({ className: e, ...r }, s) {
92
115
  return /* @__PURE__ */ o(
93
116
  t.Description,
94
117
  {
95
118
  ref: s,
96
- className: i("text-sm text-foreground-muted", e),
119
+ className: i("text-foreground-muted text-sm", e),
97
120
  ...r
98
121
  }
99
122
  );
100
123
  });
101
- w.displayName = "SheetDescription";
124
+ T.displayName = "SheetDescription";
102
125
  export {
103
- P as Sheet,
104
- H as SheetClose,
105
- v as SheetContent,
106
- w as SheetDescription,
107
- y as SheetFooter,
108
- S as SheetHeader,
109
- b as SheetPortal,
110
- N as SheetTitle,
111
- F as SheetTrigger
126
+ k as Sheet,
127
+ V as SheetClose,
128
+ N as SheetContent,
129
+ T as SheetDescription,
130
+ C as SheetFooter,
131
+ w as SheetHeader,
132
+ S as SheetPortal,
133
+ z as SheetTitle,
134
+ A as SheetTrigger
112
135
  };
113
136
  //# sourceMappingURL=Sheet.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Sheet.js","sources":["../../../src/components/ui/Sheet.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { cva, type VariantProps } from '@/lib/cva';\n\n/* -----------------------------------------------------------------------------\n * Sheet — drawer-style overlay. Built on Radix Dialog (focus trap, escape,\n * click-outside come from there). Slides in from one of four sides.\n * --------------------------------------------------------------------------- */\n\nexport const Sheet = DialogPrimitive.Root;\nexport const SheetTrigger = DialogPrimitive.Trigger;\nexport const SheetClose = DialogPrimitive.Close;\nexport const SheetPortal = DialogPrimitive.Portal;\n\nconst SheetOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(function SheetOverlay({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'fixed inset-0 z-[var(--z-overlay)] bg-overlay',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0',\n className,\n )}\n {...props}\n />\n );\n});\nSheetOverlay.displayName = 'SheetOverlay';\n\nconst sheet = cva(\n [\n 'fixed z-[var(--z-modal)] bg-card text-card-foreground shadow-lg',\n 'flex flex-col gap-4 p-6',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:duration-[var(--duration-base)] data-[state=open]:duration-[var(--duration-slow)]',\n ],\n {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b border-border data-[state=open]:slide-in-from-top data-[state=closed]:slide-out-to-top',\n bottom:\n 'inset-x-0 bottom-0 border-t border-border data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom',\n left: 'inset-y-0 left-0 h-full w-3/4 max-w-md border-r border-border data-[state=open]:slide-in-from-left data-[state=closed]:slide-out-to-left',\n right:\n 'inset-y-0 right-0 h-full w-3/4 max-w-md border-l border-border data-[state=open]:slide-in-from-right data-[state=closed]:slide-out-to-right',\n },\n },\n defaultVariants: { side: 'right' },\n },\n);\n\nexport interface SheetContentProps\n extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,\n VariantProps<typeof sheet> {\n showClose?: boolean;\n}\n\nexport const SheetContent = forwardRef<\n ElementRef<typeof DialogPrimitive.Content>,\n SheetContentProps\n>(function SheetContent({ className, children, side = 'right', showClose = true, ...props }, ref) {\n const strings = useStrings();\n return (\n <SheetPortal>\n <SheetOverlay />\n <DialogPrimitive.Content ref={ref} className={cn(sheet({ side }), className)} {...props}>\n {children}\n {showClose && (\n <DialogPrimitive.Close\n aria-label={strings.sheet.close}\n className={cn(\n 'absolute right-4 top-4 inline-flex size-8 items-center justify-center rounded-md text-foreground-subtle',\n 'hover:bg-background-muted hover:text-foreground',\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n <X className=\"size-4\" aria-hidden />\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </SheetPortal>\n );\n});\nSheetContent.displayName = 'SheetContent';\n\nexport function SheetHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col gap-1', className)} {...props} />;\n}\nSheetHeader.displayName = 'SheetHeader';\n\nexport function SheetFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n );\n}\nSheetFooter.displayName = 'SheetFooter';\n\nexport const SheetTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(function SheetTitle({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold text-foreground leading-tight', className)}\n {...props}\n />\n );\n});\nSheetTitle.displayName = 'SheetTitle';\n\nexport const SheetDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(function SheetDescription({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-foreground-muted', className)}\n {...props}\n />\n );\n});\nSheetDescription.displayName = 'SheetDescription';\n\n/**\n * @example Right-side filter drawer\n * <Sheet>\n * <SheetTrigger asChild><Button variant=\"outline\">Filters</Button></SheetTrigger>\n * <SheetContent side=\"right\">\n * <SheetHeader>\n * <SheetTitle>Filters</SheetTitle>\n * <SheetDescription>Refine the result set.</SheetDescription>\n * </SheetHeader>\n * …\n * <SheetFooter>\n * <SheetClose asChild><Button variant=\"outline\">Cancel</Button></SheetClose>\n * <Button>Apply</Button>\n * </SheetFooter>\n * </SheetContent>\n * </Sheet>\n *\n * @do Use right side for filters/inspectors, left for navigation, bottom for\n * mobile sheets.\n * @dont Use a full-screen sheet on desktop — prefer Dialog or a dedicated page.\n */\n"],"names":["Sheet","DialogPrimitive","SheetTrigger","SheetClose","SheetPortal","SheetOverlay","forwardRef","className","props","ref","jsx","cn","sheet","cva","SheetContent","children","side","showClose","strings","useStrings","jsxs","X","SheetHeader","SheetFooter","SheetTitle","SheetDescription"],"mappings":";;;;;;;;AAmBO,MAAMA,IAAQC,EAAgB,MACxBC,IAAeD,EAAgB,SAC/BE,IAAaF,EAAgB,OAC7BG,IAAcH,EAAgB,QAErCI,IAAeC,EAGnB,SAAsB,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,GAAK;AACpD,SACE,gBAAAC;AAAA,IAACT,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAQ;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDH,EAAa,cAAc;AAE3B,MAAMO,IAAQC;AAAA,EACZ;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,KAAK;AAAA,QACL,QACE;AAAA,QACF,MAAM;AAAA,QACN,OACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB,EAAE,MAAM,QAAA;AAAA,EAAQ;AAErC,GAQaC,IAAeR,EAG1B,SAAsB,EAAE,WAAAC,GAAW,UAAAQ,GAAU,MAAAC,IAAO,SAAS,WAAAC,IAAY,IAAM,GAAGT,EAAA,GAASC,GAAK;AAChG,QAAMS,IAAUC,EAAA;AAChB,2BACGf,GAAA,EACC,UAAA;AAAA,IAAA,gBAAAM,EAACL,GAAA,EAAa;AAAA,IACd,gBAAAe,EAACnB,EAAgB,SAAhB,EAAwB,KAAAQ,GAAU,WAAWE,EAAGC,EAAM,EAAE,MAAAI,GAAM,GAAGT,CAAS,GAAI,GAAGC,GAC/E,UAAA;AAAA,MAAAO;AAAA,MACAE,KACC,gBAAAP;AAAA,QAACT,EAAgB;AAAA,QAAhB;AAAA,UACC,cAAYiB,EAAQ,MAAM;AAAA,UAC1B,WAAWP;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,UAGF,UAAA,gBAAAD,EAACW,GAAA,EAAE,WAAU,UAAS,eAAW,GAAA,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,IACpC,EAAA,CAEJ;AAAA,EAAA,GACF;AAEJ,CAAC;AACDP,EAAa,cAAc;AAEpB,SAASQ,EAAY,EAAE,WAAAf,GAAW,GAAGC,KAAyC;AACnF,SAAO,gBAAAE,EAAC,SAAI,WAAWC,EAAG,uBAAuBJ,CAAS,GAAI,GAAGC,GAAO;AAC1E;AACAc,EAAY,cAAc;AAEnB,SAASC,EAAY,EAAE,WAAAhB,GAAW,GAAGC,KAAyC;AACnF,SACE,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,uEAAuEJ,CAAS;AAAA,MAC7F,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV;AACAe,EAAY,cAAc;AAEnB,MAAMC,IAAalB,EAGxB,SAAoB,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,GAAK;AAClD,SACE,gBAAAC;AAAA,IAACT,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAQ;AAAA,MACA,WAAWE,EAAG,uDAAuDJ,CAAS;AAAA,MAC7E,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDgB,EAAW,cAAc;AAElB,MAAMC,IAAmBnB,EAG9B,SAA0B,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,GAAK;AACxD,SACE,gBAAAC;AAAA,IAACT,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAQ;AAAA,MACA,WAAWE,EAAG,iCAAiCJ,CAAS;AAAA,MACvD,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDiB,EAAiB,cAAc;"}
1
+ {"version":3,"file":"Sheet.js","sources":["../../../src/components/ui/Sheet.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { cva, type VariantProps } from '@/lib/cva';\nimport { withReturnFocus, type ReturnFocusRef } from '@/lib/return-focus';\n\n/* -----------------------------------------------------------------------------\n * Sheet — drawer-style overlay. Built on Radix Dialog (focus trap, escape,\n * click-outside come from there). Slides in from one of four sides.\n * --------------------------------------------------------------------------- */\n\nexport const Sheet = DialogPrimitive.Root;\nexport const SheetTrigger = DialogPrimitive.Trigger;\nexport const SheetClose = DialogPrimitive.Close;\nexport const SheetPortal = DialogPrimitive.Portal;\n\nconst SheetOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(function SheetOverlay({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'bg-overlay fixed inset-0 z-[var(--z-overlay)]',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0',\n className,\n )}\n {...props}\n />\n );\n});\nSheetOverlay.displayName = 'SheetOverlay';\n\nconst sheet = cva(\n [\n 'fixed z-[var(--z-modal)] bg-card text-card-foreground shadow-lg',\n 'flex flex-col gap-4 p-6',\n // Safe-area insets for notched devices (consumers set viewport-fit=cover).\n 'pb-[max(1.5rem,env(safe-area-inset-bottom))] pl-[max(1.5rem,env(safe-area-inset-left))] pr-[max(1.5rem,env(safe-area-inset-right))]',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:duration-[var(--duration-base)] data-[state=open]:duration-[var(--duration-slow)]',\n ],\n {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b border-border data-[state=open]:slide-in-from-top data-[state=closed]:slide-out-to-top',\n bottom:\n 'inset-x-0 bottom-0 border-t border-border data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom',\n left: 'inset-y-0 left-0 h-full w-3/4 max-w-md border-r border-border data-[state=open]:slide-in-from-left data-[state=closed]:slide-out-to-left',\n right:\n 'inset-y-0 right-0 h-full w-3/4 max-w-md border-l border-border data-[state=open]:slide-in-from-right data-[state=closed]:slide-out-to-right',\n },\n },\n defaultVariants: { side: 'right' },\n },\n);\n\nexport interface SheetContentProps\n extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheet> {\n showClose?: boolean;\n /**\n * Element to focus when the overlay closes. Overrides Radix's default\n * (the element focused when the content mounted), which is `<body>` for\n * controlled overlays opened from a pointer click on a non-focusable /\n * tooltip-wrapped trigger. A consumer `onCloseAutoFocus` runs first and\n * wins if it calls `preventDefault()`.\n */\n returnFocusTo?: ReturnFocusRef;\n}\n\nexport const SheetContent = forwardRef<\n ElementRef<typeof DialogPrimitive.Content>,\n SheetContentProps\n>(function SheetContent(\n {\n className,\n children,\n side = 'right',\n showClose = true,\n returnFocusTo,\n onCloseAutoFocus,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n return (\n <SheetPortal>\n <SheetOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(sheet({ side }), className)}\n onCloseAutoFocus={withReturnFocus(returnFocusTo, onCloseAutoFocus)}\n {...props}\n >\n {children}\n {showClose && (\n <DialogPrimitive.Close\n aria-label={strings.sheet.close}\n className={cn(\n 'text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md',\n 'hover:bg-background-muted hover:text-foreground',\n 'focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n <X className=\"size-4\" aria-hidden />\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </SheetPortal>\n );\n});\nSheetContent.displayName = 'SheetContent';\n\nexport function SheetHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col gap-1', className)} {...props} />;\n}\nSheetHeader.displayName = 'SheetHeader';\n\nexport function SheetFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn(\n 'mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n );\n}\nSheetFooter.displayName = 'SheetFooter';\n\nexport const SheetTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(function SheetTitle({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-foreground text-lg leading-tight font-semibold', className)}\n {...props}\n />\n );\n});\nSheetTitle.displayName = 'SheetTitle';\n\nexport const SheetDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(function SheetDescription({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-foreground-muted text-sm', className)}\n {...props}\n />\n );\n});\nSheetDescription.displayName = 'SheetDescription';\n\n/**\n * @example Right-side filter drawer\n * <Sheet>\n * <SheetTrigger asChild><Button variant=\"outline\">Filters</Button></SheetTrigger>\n * <SheetContent side=\"right\">\n * <SheetHeader>\n * <SheetTitle>Filters</SheetTitle>\n * <SheetDescription>Refine the result set.</SheetDescription>\n * </SheetHeader>\n * …\n * <SheetFooter>\n * <SheetClose asChild><Button variant=\"outline\">Cancel</Button></SheetClose>\n * <Button>Apply</Button>\n * </SheetFooter>\n * </SheetContent>\n * </Sheet>\n *\n * @do Use right side for filters/inspectors, left for navigation, bottom for\n * mobile sheets.\n * @dont Use a full-screen sheet on desktop — prefer Dialog or a dedicated page.\n */\n"],"names":["Sheet","DialogPrimitive","SheetTrigger","SheetClose","SheetPortal","SheetOverlay","forwardRef","className","props","ref","jsx","cn","sheet","cva","SheetContent","children","side","showClose","returnFocusTo","onCloseAutoFocus","strings","useStrings","jsxs","withReturnFocus","X","SheetHeader","SheetFooter","SheetTitle","SheetDescription"],"mappings":"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"}
@@ -60,6 +60,11 @@ interface SidebarItemBaseProps {
60
60
  * when that is a plain string.
61
61
  */
62
62
  tooltip?: ReactNode;
63
+ /**
64
+ * Render the child element (router `<Link>`) instead of `<a>`/`<button>`.
65
+ * The child receives className, aria-current and the item content.
66
+ */
67
+ asChild?: boolean;
63
68
  }
64
69
  type SidebarItemAnchorProps = SidebarItemBaseProps & AnchorHTMLAttributes<HTMLAnchorElement> & {
65
70
  /** Renders an `<a>`. Omit to render a `<button>`. */
@@ -70,19 +75,17 @@ type SidebarItemButtonProps = SidebarItemBaseProps & ButtonHTMLAttributes<HTMLBu
70
75
  };
71
76
  /** Discriminated on `href`: with it the item is an anchor, without it a button. */
72
77
  export type SidebarItemProps = SidebarItemAnchorProps | SidebarItemButtonProps;
73
- export declare function SidebarItem(props: SidebarItemProps): import("react/jsx-runtime").JSX.Element;
74
- export declare namespace SidebarItem {
75
- var displayName: string;
76
- }
78
+ export declare const SidebarItem: import('react').ForwardRefExoticComponent<SidebarItemProps & import('react').RefAttributes<HTMLElement>>;
77
79
  /** Lightweight collapsible sub-section inside the sidebar. */
78
- export interface SidebarGroupProps {
80
+ export interface SidebarGroupProps extends Omit<HTMLAttributes<HTMLLIElement>, 'children'> {
79
81
  icon?: ReactNode;
80
82
  label: ReactNode;
83
+ /** Initial open state (uncontrolled). */
81
84
  defaultOpen?: boolean;
85
+ /** Controlled open state. */
86
+ open?: boolean;
87
+ onOpenChange?: (open: boolean) => void;
82
88
  children: ReactNode;
83
89
  }
84
- export declare function SidebarGroup({ icon, label, defaultOpen, children }: SidebarGroupProps): import("react/jsx-runtime").JSX.Element;
85
- export declare namespace SidebarGroup {
86
- var displayName: string;
87
- }
90
+ export declare const SidebarGroup: import('react').ForwardRefExoticComponent<SidebarGroupProps & import('react').RefAttributes<HTMLLIElement>>;
88
91
  export {};
@@ -1,58 +1,62 @@
1
1
  "use client";
2
- import { jsx as e, jsxs as m, Fragment as S } from "react/jsx-runtime";
3
- import { forwardRef as z, useState as y, useContext as N, createContext as j } from "react";
4
- import { ChevronsRight as I, ChevronsLeft as P, ChevronDown as _ } from "../../icons/index.js";
2
+ import { jsx as e, jsxs as x, Fragment as _ } from "react/jsx-runtime";
3
+ import { forwardRef as j, useState as P, useContext as k, useId as G, createContext as T } from "react";
4
+ import { Slot as R } from "@radix-ui/react-slot";
5
+ import { ChevronsRight as D, ChevronsLeft as F, ChevronDown as L } from "../../icons/index.js";
5
6
  import { cn as u } from "../../lib/utils.js";
6
- import { useStrings as G } from "../../hooks/use-strings.js";
7
- import { Tooltip as R } from "./Tooltip.js";
8
- const g = j({ collapsed: !1 });
9
- function H() {
10
- return N(g);
7
+ import { useStrings as q } from "../../hooks/use-strings.js";
8
+ import { Tooltip as A } from "./Tooltip.js";
9
+ const y = T({ collapsed: !1 });
10
+ function Y() {
11
+ return k(y);
11
12
  }
12
- const T = z(function({
13
- defaultCollapsed: n = !1,
14
- collapsed: s,
15
- onCollapsedChange: t,
16
- header: o,
17
- footer: a,
18
- className: b,
19
- children: l,
20
- ...f
21
- }, c) {
22
- const d = G(), [x, h] = y(n), r = s ?? x, v = (p) => {
23
- s === void 0 && h(p), t == null || t(p);
13
+ const B = j(function({
14
+ defaultCollapsed: d = !1,
15
+ collapsed: a,
16
+ onCollapsedChange: l,
17
+ header: t,
18
+ footer: s,
19
+ className: v,
20
+ children: b,
21
+ "aria-label": g,
22
+ ...h
23
+ }, i) {
24
+ const o = q(), [c, n] = P(d), r = a ?? c, p = (f) => {
25
+ a === void 0 && n(f), l == null || l(f);
24
26
  };
25
- return /* @__PURE__ */ e(g.Provider, { value: { collapsed: r }, children: /* @__PURE__ */ m(
26
- "aside",
27
+ return /* @__PURE__ */ e(y.Provider, { value: { collapsed: r }, children: /* @__PURE__ */ x(
28
+ "nav",
27
29
  {
28
- ref: c,
29
- "aria-label": f["aria-label"] ?? d.sidebar.label,
30
+ ref: i,
31
+ "aria-label": g ?? o.sidebar.label,
30
32
  className: u(
31
- "border-border bg-background-subtle sticky top-0 hidden h-screen shrink-0 flex-col gap-2 border-r md:flex",
32
- "transition-[width] duration-[var(--duration-base)] ease-[var(--ease-out)]",
33
+ "border-border bg-background-subtle sticky top-0 hidden h-dvh shrink-0 flex-col gap-2 border-r md:flex",
34
+ // Deliberate motion exception: the rail's own width transitions (layout).
35
+ // Only the rail and the main column it flanks move; no content inside reflows.
36
+ "transition-[width] duration-[var(--duration-base)] ease-[var(--ease-out)] motion-reduce:transition-none",
33
37
  r ? "w-14" : "w-60",
34
- b
38
+ v
35
39
  ),
36
- ...f,
40
+ ...h,
37
41
  children: [
38
- o && /* @__PURE__ */ e(
42
+ t && /* @__PURE__ */ e(
39
43
  "div",
40
44
  {
41
45
  className: u(
42
46
  "border-border flex h-14 shrink-0 items-center overflow-hidden border-b",
43
47
  r ? "justify-center px-2" : "px-3"
44
48
  ),
45
- children: o
49
+ children: t
46
50
  }
47
51
  ),
48
- /* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto py-3", children: l }),
49
- a && /* @__PURE__ */ e("div", { className: "border-border border-t p-2", children: a }),
50
- /* @__PURE__ */ m(
52
+ /* @__PURE__ */ e("div", { className: "flex-1 overflow-y-auto py-3", children: b }),
53
+ s && /* @__PURE__ */ e("div", { className: "border-border border-t p-2", children: s }),
54
+ /* @__PURE__ */ x(
51
55
  "button",
52
56
  {
53
57
  type: "button",
54
- onClick: () => v(!r),
55
- "aria-label": r ? d.sidebar.expand : d.sidebar.collapse,
58
+ onClick: () => p(!r),
59
+ "aria-label": r ? o.sidebar.expand : o.sidebar.collapse,
56
60
  "aria-expanded": !r,
57
61
  className: u(
58
62
  "text-foreground-subtle mx-2 mb-2 flex h-8 items-center gap-2 rounded-md px-2",
@@ -61,8 +65,8 @@ const T = z(function({
61
65
  "transition-colors duration-[var(--duration-fast)]"
62
66
  ),
63
67
  children: [
64
- r ? /* @__PURE__ */ e(I, { className: "size-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(P, { className: "size-4", "aria-hidden": !0 }),
65
- !r && /* @__PURE__ */ e("span", { className: "text-xs font-medium", children: d.sidebar.collapseShort })
68
+ r ? /* @__PURE__ */ e(D, { className: "size-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(F, { className: "size-4", "aria-hidden": !0 }),
69
+ !r && /* @__PURE__ */ e("span", { className: "text-xs font-medium", children: o.sidebar.collapseShort })
66
70
  ]
67
71
  }
68
72
  )
@@ -70,72 +74,111 @@ const T = z(function({
70
74
  }
71
75
  ) });
72
76
  });
73
- T.displayName = "Sidebar";
74
- function C({ label: i, className: n, children: s, ...t }) {
75
- const { collapsed: o } = N(g);
76
- return /* @__PURE__ */ m("div", { className: u("mb-3", n), ...t, children: [
77
- i && !o && /* @__PURE__ */ e("div", { className: "text-foreground-subtle px-4 pt-2 pb-1 text-xs font-medium tracking-wide uppercase", children: i }),
78
- /* @__PURE__ */ e("ul", { className: "flex flex-col gap-px", children: s })
79
- ] });
80
- }
81
- C.displayName = "SidebarSection";
82
- function D(i) {
83
- const { icon: n, active: s, trailing: t, sub: o, tooltip: a, className: b, children: l, ...f } = i, { collapsed: c } = N(g), d = u(
84
- "flex h-8 w-full items-center gap-2 rounded-md px-2 text-sm outline-none",
85
- "transition-colors duration-[var(--duration-fast)]",
86
- "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
87
- s ? "bg-background-muted text-foreground font-medium" : "text-foreground-muted hover:bg-background-muted hover:text-foreground",
88
- o && !c && "ml-6",
89
- c && "justify-center",
90
- b
91
- ), x = typeof l == "string" ? l : void 0, h = /* @__PURE__ */ m(S, { children: [
92
- n && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: n }),
93
- c ? /* @__PURE__ */ e("span", { className: "sr-only", children: l }) : /* @__PURE__ */ e("span", { className: "flex-1 truncate text-left", title: x, children: l }),
94
- !c && t && /* @__PURE__ */ e("span", { className: "ml-auto", children: t })
95
- ] });
96
- let r;
97
- if (f.href !== void 0) {
98
- const { href: p, ...k } = f;
99
- r = /* @__PURE__ */ e(
100
- "a",
101
- {
102
- href: p,
103
- "aria-current": s ? "page" : void 0,
104
- className: d,
105
- ...k,
106
- children: h
107
- }
108
- );
109
- } else {
110
- const {
111
- href: p,
112
- type: k,
113
- ...w
114
- } = f;
115
- r = /* @__PURE__ */ e(
116
- "button",
77
+ B.displayName = "Sidebar";
78
+ function E({ label: m, className: d, children: a, ...l }) {
79
+ const { collapsed: t } = k(y), s = G();
80
+ return /* @__PURE__ */ x("div", { className: u("mb-3", d), ...l, children: [
81
+ m && // Kept in the DOM (sr-only) while collapsed so the list stays labelled.
82
+ /* @__PURE__ */ e(
83
+ "div",
117
84
  {
118
- type: k ?? "button",
119
- "aria-current": s ? "page" : void 0,
120
- className: d,
121
- ...w,
122
- children: h
85
+ id: s,
86
+ className: u(
87
+ "text-foreground-subtle px-4 pt-2 pb-1 text-xs font-medium",
88
+ t && "sr-only"
89
+ ),
90
+ children: m
123
91
  }
124
- );
125
- }
126
- const v = a ?? x;
127
- return /* @__PURE__ */ e("li", { className: "px-2", children: c && v ? /* @__PURE__ */ e(R, { label: v, side: "right", children: r }) : r });
92
+ ),
93
+ /* @__PURE__ */ e("ul", { "aria-labelledby": m ? s : void 0, className: "flex flex-col gap-px", children: a })
94
+ ] });
128
95
  }
129
- D.displayName = "SidebarItem";
130
- function F({ icon: i, label: n, defaultOpen: s = !0, children: t }) {
131
- const { collapsed: o } = N(g), [a, b] = y(s);
132
- return o ? /* @__PURE__ */ e(S, { children: t }) : /* @__PURE__ */ m("li", { children: [
133
- /* @__PURE__ */ m(
96
+ E.displayName = "SidebarSection";
97
+ const H = j(
98
+ function(d, a) {
99
+ const { icon: l, active: t, trailing: s, sub: v, tooltip: b, asChild: g, className: h, children: i, ...o } = d, { collapsed: c } = k(y), n = u(
100
+ "flex h-8 w-full items-center gap-2 rounded-md px-2 text-sm outline-none",
101
+ "transition-colors duration-[var(--duration-fast)]",
102
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
103
+ t ? "bg-background-muted text-foreground font-medium" : "text-foreground-muted hover:bg-background-muted hover:text-foreground",
104
+ v && !c && "ml-6",
105
+ c && "justify-center",
106
+ h
107
+ ), r = typeof i == "string" ? i : void 0, p = b ?? r, f = c && !!p, z = /* @__PURE__ */ x(_, { children: [
108
+ l && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: l }),
109
+ c ? /* @__PURE__ */ e("span", { className: "sr-only", children: i }) : /* @__PURE__ */ e("span", { className: "flex-1 truncate text-left", title: r, children: i }),
110
+ !c && s && /* @__PURE__ */ e("span", { className: "ml-auto", children: s })
111
+ ] });
112
+ let N;
113
+ if (g) {
114
+ const { href: w, type: S, ...I } = o;
115
+ N = /* @__PURE__ */ e(
116
+ R,
117
+ {
118
+ ref: a,
119
+ "aria-current": t ? "page" : void 0,
120
+ className: n,
121
+ ...I,
122
+ children: i && typeof i == "object" && "props" in i ? i : null
123
+ }
124
+ );
125
+ } else if (o.href !== void 0) {
126
+ const { href: w, ...S } = o;
127
+ N = /* @__PURE__ */ e(
128
+ "a",
129
+ {
130
+ ref: a,
131
+ href: w,
132
+ "aria-current": t ? "page" : void 0,
133
+ className: n,
134
+ ...S,
135
+ children: z
136
+ }
137
+ );
138
+ } else {
139
+ const {
140
+ href: w,
141
+ type: S,
142
+ ...I
143
+ } = o;
144
+ N = /* @__PURE__ */ e(
145
+ "button",
146
+ {
147
+ ref: a,
148
+ type: S ?? "button",
149
+ "aria-current": t ? "page" : void 0,
150
+ className: n,
151
+ ...I,
152
+ children: z
153
+ }
154
+ );
155
+ }
156
+ return /* @__PURE__ */ e("li", { className: "px-2", children: f ? /* @__PURE__ */ e(A, { label: p, side: "right", children: N }) : N });
157
+ }
158
+ );
159
+ H.displayName = "SidebarItem";
160
+ const J = j(function({
161
+ icon: d,
162
+ label: a,
163
+ defaultOpen: l = !0,
164
+ open: t,
165
+ onOpenChange: s,
166
+ className: v,
167
+ children: b,
168
+ ...g
169
+ }, h) {
170
+ const { collapsed: i } = k(y), [o, c] = P(l), n = t ?? o, r = G(), p = () => {
171
+ const f = !n;
172
+ t === void 0 && c(f), s == null || s(f);
173
+ };
174
+ return i ? /* @__PURE__ */ e(_, { children: b }) : /* @__PURE__ */ x("li", { ref: h, className: v, ...g, children: [
175
+ /* @__PURE__ */ x(
134
176
  "button",
135
177
  {
136
178
  type: "button",
137
- onClick: () => b((l) => !l),
138
- "aria-expanded": a,
179
+ onClick: p,
180
+ "aria-controls": n ? r : void 0,
181
+ "aria-expanded": n,
139
182
  className: u(
140
183
  "text-foreground-muted mx-2 flex h-8 w-[calc(100%-1rem)] items-center gap-2 rounded-md px-2 text-sm outline-none",
141
184
  "transition-colors duration-[var(--duration-fast)]",
@@ -143,27 +186,27 @@ function F({ icon: i, label: n, defaultOpen: s = !0, children: t }) {
143
186
  "focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2"
144
187
  ),
145
188
  children: [
146
- i && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: i }),
147
- /* @__PURE__ */ e("span", { className: "flex-1 text-left", children: n }),
189
+ d && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: d }),
190
+ /* @__PURE__ */ e("span", { className: "flex-1 text-left", children: a }),
148
191
  /* @__PURE__ */ e(
149
- _,
192
+ L,
150
193
  {
151
- className: u("size-3.5 transition-transform", a && "rotate-180"),
194
+ className: u("size-3.5 transition-transform", n && "rotate-180"),
152
195
  "aria-hidden": !0
153
196
  }
154
197
  )
155
198
  ]
156
199
  }
157
200
  ),
158
- a && /* @__PURE__ */ e("ul", { className: "flex flex-col gap-px", children: t })
201
+ n && /* @__PURE__ */ e("ul", { id: r, className: "flex flex-col gap-px", children: b })
159
202
  ] });
160
- }
161
- F.displayName = "SidebarGroup";
203
+ });
204
+ J.displayName = "SidebarGroup";
162
205
  export {
163
- T as Sidebar,
164
- F as SidebarGroup,
165
- D as SidebarItem,
166
- C as SidebarSection,
167
- H as useSidebar
206
+ B as Sidebar,
207
+ J as SidebarGroup,
208
+ H as SidebarItem,
209
+ E as SidebarSection,
210
+ Y as useSidebar
168
211
  };
169
212
  //# sourceMappingURL=Sidebar.js.map