@ttt-productions/ui-core 0.11.33 → 0.11.35

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 (238) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/index.d.ts +2 -2
  3. package/dist/browser/index.d.ts.map +1 -1
  4. package/dist/browser/index.js +1 -2
  5. package/dist/browser/index.js.map +1 -1
  6. package/dist/browser/reload-recovery-watch.d.ts +2 -6
  7. package/dist/browser/reload-recovery-watch.d.ts.map +1 -1
  8. package/dist/browser/reload-recovery-watch.js +5 -10
  9. package/dist/browser/reload-recovery-watch.js.map +1 -1
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -4
  13. package/dist/index.js.map +1 -1
  14. package/dist/lib/format-numbers.d.ts +0 -6
  15. package/dist/lib/format-numbers.d.ts.map +1 -1
  16. package/dist/lib/format-numbers.js +2 -8
  17. package/dist/lib/format-numbers.js.map +1 -1
  18. package/dist/lib/reload-recovery.d.ts +1 -9
  19. package/dist/lib/reload-recovery.d.ts.map +1 -1
  20. package/dist/lib/reload-recovery.js +14 -24
  21. package/dist/lib/reload-recovery.js.map +1 -1
  22. package/dist/lib/utils.d.ts +0 -3
  23. package/dist/lib/utils.d.ts.map +1 -1
  24. package/dist/lib/utils.js +0 -3
  25. package/dist/lib/utils.js.map +1 -1
  26. package/dist/react/components/accordion.d.ts +2 -2
  27. package/dist/react/components/accordion.d.ts.map +1 -1
  28. package/dist/react/components/accordion.js +8 -8
  29. package/dist/react/components/accordion.js.map +1 -1
  30. package/dist/react/components/action-row.d.ts +2 -9
  31. package/dist/react/components/action-row.d.ts.map +1 -1
  32. package/dist/react/components/action-row.js +7 -11
  33. package/dist/react/components/action-row.js.map +1 -1
  34. package/dist/react/components/alert-dialog.d.ts +2 -2
  35. package/dist/react/components/alert-dialog.d.ts.map +1 -1
  36. package/dist/react/components/alert-dialog.js +15 -15
  37. package/dist/react/components/alert-dialog.js.map +1 -1
  38. package/dist/react/components/alert.d.ts +2 -2
  39. package/dist/react/components/alert.d.ts.map +1 -1
  40. package/dist/react/components/alert.js +12 -12
  41. package/dist/react/components/alert.js.map +1 -1
  42. package/dist/react/components/avatar.d.ts +2 -2
  43. package/dist/react/components/avatar.d.ts.map +1 -1
  44. package/dist/react/components/avatar.js +7 -7
  45. package/dist/react/components/avatar.js.map +1 -1
  46. package/dist/react/components/badge.d.ts +2 -2
  47. package/dist/react/components/badge.d.ts.map +1 -1
  48. package/dist/react/components/badge.js +9 -9
  49. package/dist/react/components/badge.js.map +1 -1
  50. package/dist/react/components/button.d.ts +2 -12
  51. package/dist/react/components/button.d.ts.map +1 -1
  52. package/dist/react/components/button.js +30 -35
  53. package/dist/react/components/button.js.map +1 -1
  54. package/dist/react/components/card.d.ts +1 -1
  55. package/dist/react/components/card.d.ts.map +1 -1
  56. package/dist/react/components/card.js +15 -15
  57. package/dist/react/components/card.js.map +1 -1
  58. package/dist/react/components/checkbox.d.ts +2 -2
  59. package/dist/react/components/checkbox.d.ts.map +1 -1
  60. package/dist/react/components/checkbox.js +6 -6
  61. package/dist/react/components/checkbox.js.map +1 -1
  62. package/dist/react/components/collapsible.d.ts +1 -1
  63. package/dist/react/components/collapsible.d.ts.map +1 -1
  64. package/dist/react/components/collapsible.js +2 -2
  65. package/dist/react/components/collapsible.js.map +1 -1
  66. package/dist/react/components/consequence-dialog.d.ts +1 -48
  67. package/dist/react/components/consequence-dialog.d.ts.map +1 -1
  68. package/dist/react/components/consequence-dialog.js +7 -23
  69. package/dist/react/components/consequence-dialog.js.map +1 -1
  70. package/dist/react/components/date-picker.d.ts +1 -18
  71. package/dist/react/components/date-picker.d.ts.map +1 -1
  72. package/dist/react/components/date-picker.js +102 -98
  73. package/dist/react/components/date-picker.js.map +1 -1
  74. package/dist/react/components/date-time-picker.d.ts +1 -24
  75. package/dist/react/components/date-time-picker.d.ts.map +1 -1
  76. package/dist/react/components/date-time-picker.js +20 -37
  77. package/dist/react/components/date-time-picker.js.map +1 -1
  78. package/dist/react/components/dialog.d.ts +2 -2
  79. package/dist/react/components/dialog.d.ts.map +1 -1
  80. package/dist/react/components/dialog.js +14 -14
  81. package/dist/react/components/dialog.js.map +1 -1
  82. package/dist/react/components/dropdown-menu.d.ts +2 -10
  83. package/dist/react/components/dropdown-menu.d.ts.map +1 -1
  84. package/dist/react/components/dropdown-menu.js +24 -20
  85. package/dist/react/components/dropdown-menu.js.map +1 -1
  86. package/dist/react/components/end-of-list-indicator.d.ts +1 -1
  87. package/dist/react/components/end-of-list-indicator.js +3 -3
  88. package/dist/react/components/end-of-list-indicator.js.map +1 -1
  89. package/dist/react/components/form.d.ts +3 -3
  90. package/dist/react/components/form.d.ts.map +1 -1
  91. package/dist/react/components/form.js +17 -17
  92. package/dist/react/components/form.js.map +1 -1
  93. package/dist/react/components/format-control.d.ts +7 -20
  94. package/dist/react/components/format-control.d.ts.map +1 -1
  95. package/dist/react/components/format-control.js +18 -22
  96. package/dist/react/components/format-control.js.map +1 -1
  97. package/dist/react/components/input.d.ts +10 -27
  98. package/dist/react/components/input.d.ts.map +1 -1
  99. package/dist/react/components/input.js +11 -9
  100. package/dist/react/components/input.js.map +1 -1
  101. package/dist/react/components/label.d.ts +3 -3
  102. package/dist/react/components/label.d.ts.map +1 -1
  103. package/dist/react/components/label.js +6 -6
  104. package/dist/react/components/label.js.map +1 -1
  105. package/dist/react/components/layout/screen-adaptive-view.d.ts +2 -9
  106. package/dist/react/components/layout/screen-adaptive-view.d.ts.map +1 -1
  107. package/dist/react/components/layout/screen-adaptive-view.js +40 -37
  108. package/dist/react/components/layout/screen-adaptive-view.js.map +1 -1
  109. package/dist/react/components/list-pagination.d.ts +1 -31
  110. package/dist/react/components/list-pagination.d.ts.map +1 -1
  111. package/dist/react/components/list-pagination.js +10 -37
  112. package/dist/react/components/list-pagination.js.map +1 -1
  113. package/dist/react/components/menubar.d.ts +2 -2
  114. package/dist/react/components/menubar.d.ts.map +1 -1
  115. package/dist/react/components/menubar.js +17 -17
  116. package/dist/react/components/menubar.js.map +1 -1
  117. package/dist/react/components/opener-focus.d.ts +2 -8
  118. package/dist/react/components/opener-focus.d.ts.map +1 -1
  119. package/dist/react/components/opener-focus.js +4 -10
  120. package/dist/react/components/opener-focus.js.map +1 -1
  121. package/dist/react/components/pending-guard.d.ts +1 -7
  122. package/dist/react/components/pending-guard.d.ts.map +1 -1
  123. package/dist/react/components/pending-guard.js +1 -7
  124. package/dist/react/components/pending-guard.js.map +1 -1
  125. package/dist/react/components/popover.d.ts +2 -2
  126. package/dist/react/components/popover.d.ts.map +1 -1
  127. package/dist/react/components/popover.js +5 -5
  128. package/dist/react/components/popover.js.map +1 -1
  129. package/dist/react/components/progress.d.ts +2 -2
  130. package/dist/react/components/progress.d.ts.map +1 -1
  131. package/dist/react/components/progress.js +5 -5
  132. package/dist/react/components/progress.js.map +1 -1
  133. package/dist/react/components/radio-group.d.ts +2 -2
  134. package/dist/react/components/radio-group.d.ts.map +1 -1
  135. package/dist/react/components/radio-group.js +7 -7
  136. package/dist/react/components/radio-group.js.map +1 -1
  137. package/dist/react/components/relative-time.d.ts +1 -9
  138. package/dist/react/components/relative-time.d.ts.map +1 -1
  139. package/dist/react/components/relative-time.js +8 -11
  140. package/dist/react/components/relative-time.js.map +1 -1
  141. package/dist/react/components/reload-recovery-notice.d.ts +3 -17
  142. package/dist/react/components/reload-recovery-notice.d.ts.map +1 -1
  143. package/dist/react/components/reload-recovery-notice.js +7 -12
  144. package/dist/react/components/reload-recovery-notice.js.map +1 -1
  145. package/dist/react/components/scroll-area.d.ts +2 -2
  146. package/dist/react/components/scroll-area.d.ts.map +1 -1
  147. package/dist/react/components/scroll-area.js +6 -8
  148. package/dist/react/components/scroll-area.js.map +1 -1
  149. package/dist/react/components/scroll-to-top-button.d.ts +6 -30
  150. package/dist/react/components/scroll-to-top-button.d.ts.map +1 -1
  151. package/dist/react/components/scroll-to-top-button.js +9 -9
  152. package/dist/react/components/scroll-to-top-button.js.map +1 -1
  153. package/dist/react/components/search-dropdown.d.ts +0 -53
  154. package/dist/react/components/search-dropdown.d.ts.map +1 -1
  155. package/dist/react/components/search-dropdown.js +10 -39
  156. package/dist/react/components/search-dropdown.js.map +1 -1
  157. package/dist/react/components/select.d.ts +2 -9
  158. package/dist/react/components/select.d.ts.map +1 -1
  159. package/dist/react/components/select.js +19 -21
  160. package/dist/react/components/select.js.map +1 -1
  161. package/dist/react/components/separator.d.ts +2 -2
  162. package/dist/react/components/separator.d.ts.map +1 -1
  163. package/dist/react/components/separator.js +5 -5
  164. package/dist/react/components/separator.js.map +1 -1
  165. package/dist/react/components/sheet.d.ts +3 -3
  166. package/dist/react/components/sheet.d.ts.map +1 -1
  167. package/dist/react/components/sheet.js +21 -21
  168. package/dist/react/components/sheet.js.map +1 -1
  169. package/dist/react/components/show-more-toggle.d.ts +2 -18
  170. package/dist/react/components/show-more-toggle.d.ts.map +1 -1
  171. package/dist/react/components/show-more-toggle.js +6 -11
  172. package/dist/react/components/show-more-toggle.js.map +1 -1
  173. package/dist/react/components/skeleton.d.ts +1 -1
  174. package/dist/react/components/skeleton.d.ts.map +1 -1
  175. package/dist/react/components/skeleton.js +3 -3
  176. package/dist/react/components/skeleton.js.map +1 -1
  177. package/dist/react/components/slider.d.ts +2 -2
  178. package/dist/react/components/slider.d.ts.map +1 -1
  179. package/dist/react/components/slider.js +5 -5
  180. package/dist/react/components/slider.js.map +1 -1
  181. package/dist/react/components/spinner.d.ts +1 -15
  182. package/dist/react/components/spinner.d.ts.map +1 -1
  183. package/dist/react/components/spinner.js +10 -18
  184. package/dist/react/components/spinner.js.map +1 -1
  185. package/dist/react/components/switch.d.ts +2 -9
  186. package/dist/react/components/switch.d.ts.map +1 -1
  187. package/dist/react/components/switch.js +13 -10
  188. package/dist/react/components/switch.js.map +1 -1
  189. package/dist/react/components/table.d.ts +2 -12
  190. package/dist/react/components/table.d.ts.map +1 -1
  191. package/dist/react/components/table.js +24 -30
  192. package/dist/react/components/table.js.map +1 -1
  193. package/dist/react/components/tabs.d.ts +2 -2
  194. package/dist/react/components/tabs.d.ts.map +1 -1
  195. package/dist/react/components/tabs.js +7 -7
  196. package/dist/react/components/tabs.js.map +1 -1
  197. package/dist/react/components/textarea.d.ts +5 -16
  198. package/dist/react/components/textarea.d.ts.map +1 -1
  199. package/dist/react/components/textarea.js +11 -9
  200. package/dist/react/components/textarea.js.map +1 -1
  201. package/dist/react/components/toast.d.ts +4 -8
  202. package/dist/react/components/toast.d.ts.map +1 -1
  203. package/dist/react/components/toast.js +26 -47
  204. package/dist/react/components/toast.js.map +1 -1
  205. package/dist/react/components/toaster.d.ts.map +1 -1
  206. package/dist/react/components/toaster.js +5 -5
  207. package/dist/react/components/toaster.js.map +1 -1
  208. package/dist/react/components/tooltip.d.ts +2 -2
  209. package/dist/react/components/tooltip.d.ts.map +1 -1
  210. package/dist/react/components/tooltip.js +5 -5
  211. package/dist/react/components/tooltip.js.map +1 -1
  212. package/dist/react/hooks/use-async-action.d.ts +1 -21
  213. package/dist/react/hooks/use-async-action.d.ts.map +1 -1
  214. package/dist/react/hooks/use-async-action.js +3 -11
  215. package/dist/react/hooks/use-async-action.js.map +1 -1
  216. package/dist/react/hooks/use-cursor-page.d.ts +1 -63
  217. package/dist/react/hooks/use-cursor-page.d.ts.map +1 -1
  218. package/dist/react/hooks/use-cursor-page.js +3 -39
  219. package/dist/react/hooks/use-cursor-page.js.map +1 -1
  220. package/dist/react/hooks/use-media-query.js +5 -5
  221. package/dist/react/hooks/use-media-query.js.map +1 -1
  222. package/dist/react/hooks/use-paged-list.d.ts +0 -43
  223. package/dist/react/hooks/use-paged-list.d.ts.map +1 -1
  224. package/dist/react/hooks/use-paged-list.js +2 -17
  225. package/dist/react/hooks/use-paged-list.js.map +1 -1
  226. package/dist/react/hooks/use-return-scroll.d.ts +1 -10
  227. package/dist/react/hooks/use-return-scroll.d.ts.map +1 -1
  228. package/dist/react/hooks/use-return-scroll.js +13 -45
  229. package/dist/react/hooks/use-return-scroll.js.map +1 -1
  230. package/dist/react/hooks/use-toast.d.ts +3 -11
  231. package/dist/react/hooks/use-toast.d.ts.map +1 -1
  232. package/dist/react/hooks/use-toast.js +18 -21
  233. package/dist/react/hooks/use-toast.js.map +1 -1
  234. package/dist/react/index.d.ts +74 -74
  235. package/dist/react/index.d.ts.map +1 -1
  236. package/dist/react/index.js +51 -57
  237. package/dist/react/index.js.map +1 -1
  238. package/package.json +8 -6
@@ -1,12 +1,12 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
5
- import { Circle } from "lucide-react";
6
- import { cn } from "../../lib/utils.js";
7
- const RadioGroup = React.forwardRef(({ className, ...props }, ref) => (_jsx(RadioGroupPrimitive.Root, { className: cn("grid gap-2", className), ...props, ref: ref })));
3
+ import * as React from 'react';
4
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
5
+ import { Circle } from 'lucide-react';
6
+ import { cn } from '../../lib/utils.js';
7
+ const RadioGroup = React.forwardRef(({ className, ...props }, ref) => (_jsx(RadioGroupPrimitive.Root, { className: cn('grid gap-2', className), ...props, ref: ref })));
8
8
  RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
9
- const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => (_jsx(RadioGroupPrimitive.Item, { ref: ref, className: cn("aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", className), ...props, children: _jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: _jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) }) })));
9
+ const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => (_jsx(RadioGroupPrimitive.Item, { ref: ref, className: cn('aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: _jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: _jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) }) })));
10
10
  RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
11
11
  export { RadioGroup, RadioGroupItem };
12
12
  //# sourceMappingURL=radio-group.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"radio-group.js","sourceRoot":"","sources":["../../../src/react/components/radio-group.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAGjC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,mBAAmB,CAAC,IAAI,IAAC,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,KAAM,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAC1F,CAAC,CAAA;AACF,UAAU,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAA;AAE7D,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAGrC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,mBAAmB,CAAC,IAAI,IACvB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,4OAA4O,EAC5O,SAAS,CACV,KACG,KAAK,YAET,KAAC,mBAAmB,CAAC,SAAS,IAAC,SAAS,EAAC,kCAAkC,YACzE,KAAC,MAAM,IAAC,SAAS,EAAC,uCAAuC,GAAG,GAC9B,GACP,CAC5B,CAAC,CAAA;AACF,cAAc,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAA;AAEjE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,CAAA","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\"\nimport { Circle } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils.js\"\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <RadioGroupPrimitive.Root className={cn(\"grid gap-2\", className)} {...props} ref={ref} />\n))\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n \"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n <Circle className=\"h-2.5 w-2.5 fill-current text-current\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n))\nRadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName\n\nexport { RadioGroup, RadioGroupItem }\n"]}
1
+ {"version":3,"file":"radio-group.js","sourceRoot":"","sources":["../../../src/react/components/radio-group.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAExC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAGjC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,mBAAmB,CAAC,IAAI,IAAC,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,KAAM,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAC1F,CAAC,CAAC;AACH,UAAU,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC;AAE9D,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CAGrC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,KAAC,mBAAmB,CAAC,IAAI,IACvB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,4OAA4O,EAC5O,SAAS,CACV,KACG,KAAK,YAET,KAAC,mBAAmB,CAAC,SAAS,IAAC,SAAS,EAAC,kCAAkC,YACzE,KAAC,MAAM,IAAC,SAAS,EAAC,uCAAuC,GAAG,GAC9B,GACP,CAC5B,CAAC,CAAC;AACH,cAAc,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC;AAElE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group';\nimport { Circle } from 'lucide-react';\n\nimport { cn } from '../../lib/utils.js';\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <RadioGroupPrimitive.Root className={cn('grid gap-2', className)} {...props} ref={ref} />\n));\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName;\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n 'aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n <Circle className=\"h-2.5 w-2.5 fill-current text-current\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n));\nRadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport { RadioGroup, RadioGroupItem };\n"]}
@@ -1,17 +1,9 @@
1
- import * as React from "react";
1
+ import * as React from 'react';
2
2
  export interface RelativeTimeProps {
3
- /** Number (ms or seconds), ISO string, Firestore Timestamp, or Date. */
4
3
  timestamp: number | string | Date | undefined | null;
5
- /** Fallback rendered before client hydration completes. Defaults to "...". */
6
4
  placeholder?: string;
7
- /** Fallback rendered when the timestamp can't be parsed. Defaults to "a while ago". */
8
5
  fallback?: string;
9
- /** Auto-refresh interval in ms. Defaults to 60000. Set to 0 to disable. */
10
6
  refreshIntervalMs?: number;
11
7
  }
12
- /**
13
- * SSR-safe relative-time component.
14
- * Renders `placeholder` on the server and pre-mount, then the live value.
15
- */
16
8
  export declare function RelativeTime({ timestamp, placeholder, fallback, refreshIntervalMs, }: RelativeTimeProps): React.JSX.Element;
17
9
  //# sourceMappingURL=relative-time.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../../../src/react/components/relative-time.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;IACrD,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,WAAmB,EACnB,QAAwB,EACxB,iBAA0B,GAC3B,EAAE,iBAAiB,qBA8BnB"}
1
+ {"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../../../src/react/components/relative-time.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,WAAmB,EACnB,QAAwB,EACxB,iBAA0B,GAC3B,EAAE,iBAAiB,qBA8BnB"}
@@ -1,25 +1,22 @@
1
- "use client";
1
+ 'use client';
2
2
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { formatDistanceToNowStrict, toDate } from "@ttt-productions/firebase-helpers";
5
- /**
6
- * SSR-safe relative-time component.
7
- * Renders `placeholder` on the server and pre-mount, then the live value.
8
- */
9
- export function RelativeTime({ timestamp, placeholder = "...", fallback = "a while ago", refreshIntervalMs = 60_000, }) {
3
+ import * as React from 'react';
4
+ import { formatDistanceToNowStrict } from 'date-fns';
5
+ import { toDate } from '@ttt-productions/firebase-helpers';
6
+ export function RelativeTime({ timestamp, placeholder = '...', fallback = 'a while ago', refreshIntervalMs = 60_000, }) {
10
7
  const [value, setValue] = React.useState(placeholder);
11
8
  React.useEffect(() => {
12
9
  let date = null;
13
10
  if (timestamp instanceof Date) {
14
11
  date = timestamp;
15
12
  }
16
- else if (typeof timestamp === "number") {
13
+ else if (typeof timestamp === 'number') {
17
14
  date = toDate(timestamp);
18
15
  }
19
- else if (typeof timestamp === "string") {
16
+ else if (typeof timestamp === 'string') {
20
17
  date = new Date(timestamp);
21
18
  }
22
- else if (timestamp && typeof timestamp === "object" && "toDate" in timestamp) {
19
+ else if (timestamp && typeof timestamp === 'object' && 'toDate' in timestamp) {
23
20
  date = toDate(timestamp);
24
21
  }
25
22
  if (!date || isNaN(date.getTime())) {
@@ -1 +1 @@
1
- {"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../../../src/react/components/relative-time.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAatF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,SAAS,EACT,WAAW,GAAG,KAAK,EACnB,QAAQ,GAAG,aAAa,EACxB,iBAAiB,GAAG,MAAM,GACR;IAClB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAS,WAAW,CAAC,CAAC;IAE9D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,GAAgB,IAAI,CAAC;QAC7B,IAAI,SAAS,YAAY,IAAI,EAAE,CAAC;YAC9B,IAAI,GAAG,SAAS,CAAC;QACnB,CAAC;aAAM,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/E,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACnC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,iBAAiB,IAAI,CAAC;YAAE,OAAO;QACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACtB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE7C,OAAO,4BAAG,KAAK,GAAI,CAAC;AACtB,CAAC","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { formatDistanceToNowStrict, toDate } from \"@ttt-productions/firebase-helpers\";\n\nexport interface RelativeTimeProps {\n /** Number (ms or seconds), ISO string, Firestore Timestamp, or Date. */\n timestamp: number | string | Date | undefined | null;\n /** Fallback rendered before client hydration completes. Defaults to \"...\". */\n placeholder?: string;\n /** Fallback rendered when the timestamp can't be parsed. Defaults to \"a while ago\". */\n fallback?: string;\n /** Auto-refresh interval in ms. Defaults to 60000. Set to 0 to disable. */\n refreshIntervalMs?: number;\n}\n\n/**\n * SSR-safe relative-time component.\n * Renders `placeholder` on the server and pre-mount, then the live value.\n */\nexport function RelativeTime({\n timestamp,\n placeholder = \"...\",\n fallback = \"a while ago\",\n refreshIntervalMs = 60_000,\n}: RelativeTimeProps) {\n const [value, setValue] = React.useState<string>(placeholder);\n\n React.useEffect(() => {\n let date: Date | null = null;\n if (timestamp instanceof Date) {\n date = timestamp;\n } else if (typeof timestamp === \"number\") {\n date = toDate(timestamp);\n } else if (typeof timestamp === \"string\") {\n date = new Date(timestamp);\n } else if (timestamp && typeof timestamp === \"object\" && \"toDate\" in timestamp) {\n date = toDate(timestamp);\n }\n\n if (!date || isNaN(date.getTime())) {\n setValue(fallback);\n return;\n }\n\n setValue(formatDistanceToNowStrict(date, { addSuffix: true }));\n\n if (refreshIntervalMs <= 0) return;\n const interval = setInterval(() => {\n setValue(formatDistanceToNowStrict(date, { addSuffix: true }));\n }, refreshIntervalMs);\n return () => clearInterval(interval);\n }, [timestamp, fallback, refreshIntervalMs]);\n\n return <>{value}</>;\n}\n"]}
1
+ {"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../../../src/react/components/relative-time.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAS3D,MAAM,UAAU,YAAY,CAAC,EAC3B,SAAS,EACT,WAAW,GAAG,KAAK,EACnB,QAAQ,GAAG,aAAa,EACxB,iBAAiB,GAAG,MAAM,GACR;IAClB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAS,WAAW,CAAC,CAAC;IAE9D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,GAAgB,IAAI,CAAC;QAC7B,IAAI,SAAS,YAAY,IAAI,EAAE,CAAC;YAC9B,IAAI,GAAG,SAAS,CAAC;QACnB,CAAC;aAAM,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/E,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACnC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,iBAAiB,IAAI,CAAC;YAAE,OAAO;QACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACtB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE7C,OAAO,4BAAG,KAAK,GAAI,CAAC;AACtB,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { formatDistanceToNowStrict } from 'date-fns';\nimport { toDate } from '@ttt-productions/firebase-helpers';\n\nexport interface RelativeTimeProps {\n timestamp: number | string | Date | undefined | null;\n placeholder?: string;\n fallback?: string;\n refreshIntervalMs?: number;\n}\n\nexport function RelativeTime({\n timestamp,\n placeholder = '...',\n fallback = 'a while ago',\n refreshIntervalMs = 60_000,\n}: RelativeTimeProps) {\n const [value, setValue] = React.useState<string>(placeholder);\n\n React.useEffect(() => {\n let date: Date | null = null;\n if (timestamp instanceof Date) {\n date = timestamp;\n } else if (typeof timestamp === 'number') {\n date = toDate(timestamp);\n } else if (typeof timestamp === 'string') {\n date = new Date(timestamp);\n } else if (timestamp && typeof timestamp === 'object' && 'toDate' in timestamp) {\n date = toDate(timestamp);\n }\n\n if (!date || isNaN(date.getTime())) {\n setValue(fallback);\n return;\n }\n\n setValue(formatDistanceToNowStrict(date, { addSuffix: true }));\n\n if (refreshIntervalMs <= 0) return;\n const interval = setInterval(() => {\n setValue(formatDistanceToNowStrict(date, { addSuffix: true }));\n }, refreshIntervalMs);\n return () => clearInterval(interval);\n }, [timestamp, fallback, refreshIntervalMs]);\n\n return <>{value}</>;\n}\n"]}
@@ -1,27 +1,13 @@
1
- import * as React from "react";
2
- import type { ReloadRecoveryWatch } from "../../browser/reload-recovery-watch.js";
3
- import type { ReloadRecoveryKind } from "../../lib/reload-recovery.js";
1
+ import * as React from 'react';
2
+ import type { ReloadRecoveryWatch } from '../../browser/reload-recovery-watch.js';
3
+ import type { ReloadRecoveryKind } from '../../lib/reload-recovery.js';
4
4
  export interface ReloadRecoveryNoticeProps {
5
- /** The watch the app's client entry started. */
6
5
  watch: ReloadRecoveryWatch;
7
- /** The app's sentence for each failure. */
8
6
  messages: Readonly<Record<ReloadRecoveryKind, React.ReactNode>>;
9
- /** The app's label for the refresh control. */
10
7
  refreshLabel: React.ReactNode;
11
- /**
12
- * The app's own reload, which runs its unsaved-work guard first. Refresh is pending until it
13
- * settles: a reload that proceeds keeps it pending until the page unloads, and a cancelled guard
14
- * settles it with the page, its input, and the notice as they were.
15
- */
16
8
  onRefresh: () => Promise<unknown>;
17
- /** Receives anything `onRefresh` throws. */
18
9
  onRefreshError: (error: unknown) => void;
19
10
  className?: string;
20
11
  }
21
- /**
22
- * One notice pinned to the top of the screen once the page hits a failure only a reload repairs.
23
- * It cannot be dismissed and never reloads by itself: the page and every editor beneath it stay
24
- * mounted and usable until the person presses Refresh. A repeat of the failure changes nothing.
25
- */
26
12
  export declare function ReloadRecoveryNotice({ watch, messages, refreshLabel, onRefresh, onRefreshError, className, }: ReloadRecoveryNoticeProps): React.JSX.Element | null;
27
13
  //# sourceMappingURL=reload-recovery-notice.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reload-recovery-notice.d.ts","sourceRoot":"","sources":["../../../src/react/components/reload-recovery-notice.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,MAAM,WAAW,yBAAyB;IACxC,gDAAgD;IAChD,KAAK,EAAE,mBAAmB,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,+CAA+C;IAC/C,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;;OAIG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,4CAA4C;IAC5C,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,cAAc,EACd,SAAS,GACV,EAAE,yBAAyB,4BAiB3B"}
1
+ {"version":3,"file":"reload-recovery-notice.d.ts","sourceRoot":"","sources":["../../../src/react/components/reload-recovery-notice.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,cAAc,EACd,SAAS,GACV,EAAE,yBAAyB,4BAiB3B"}
@@ -1,21 +1,16 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { cn } from "../../lib/utils.js";
5
- import { useAsyncAction } from "../hooks/use-async-action.js";
6
- import { Alert, AlertDescription } from "./alert.js";
7
- import { Button } from "./button.js";
3
+ import * as React from 'react';
4
+ import { cn } from '../../lib/utils.js';
5
+ import { useAsyncAction } from '../hooks/use-async-action.js';
6
+ import { Alert, AlertDescription } from './alert.js';
7
+ import { Button } from './button.js';
8
8
  const noFailureOnServer = () => null;
9
- /**
10
- * One notice pinned to the top of the screen once the page hits a failure only a reload repairs.
11
- * It cannot be dismissed and never reloads by itself: the page and every editor beneath it stay
12
- * mounted and usable until the person presses Refresh. A repeat of the failure changes nothing.
13
- */
14
9
  export function ReloadRecoveryNotice({ watch, messages, refreshLabel, onRefresh, onRefreshError, className, }) {
15
10
  const kind = React.useSyncExternalStore(watch.subscribe, watch.current, noFailureOnServer);
16
11
  const refresh = useAsyncAction(onRefresh, { onError: onRefreshError });
17
12
  if (kind === null)
18
13
  return null;
19
- return (_jsxs(Alert, { className: cn("ui-reload-recovery-notice fixed inset-x-0 top-0 z-50 flex items-center justify-between gap-4 rounded-none border-x-0 border-t-0", className), children: [_jsx(AlertDescription, { children: messages[kind] }), _jsx(Button, { type: "button", size: "sm", pending: refresh.pending, onClick: () => void refresh.run(), children: refreshLabel })] }));
14
+ return (_jsxs(Alert, { className: cn('ui-reload-recovery-notice fixed inset-x-0 top-0 z-50 flex items-center justify-between gap-4 rounded-none border-x-0 border-t-0', className), children: [_jsx(AlertDescription, { children: messages[kind] }), _jsx(Button, { type: "button", size: "sm", pending: refresh.pending, onClick: () => void refresh.run(), children: refreshLabel })] }));
20
15
  }
21
16
  //# sourceMappingURL=reload-recovery-notice.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reload-recovery-notice.js","sourceRoot":"","sources":["../../../src/react/components/reload-recovery-notice.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAoBrC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,cAAc,EACd,SAAS,GACiB;IAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC3F,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACvE,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,CACL,MAAC,KAAK,IACJ,SAAS,EAAE,EAAE,CACX,iIAAiI,EACjI,SAAS,CACV,aAED,KAAC,gBAAgB,cAAE,QAAQ,CAAC,IAAI,CAAC,GAAoB,EACrD,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,YACxF,YAAY,GACN,IACH,CACT,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport type { ReloadRecoveryWatch } from \"../../browser/reload-recovery-watch.js\";\nimport type { ReloadRecoveryKind } from \"../../lib/reload-recovery.js\";\nimport { cn } from \"../../lib/utils.js\";\nimport { useAsyncAction } from \"../hooks/use-async-action.js\";\nimport { Alert, AlertDescription } from \"./alert.js\";\nimport { Button } from \"./button.js\";\n\nexport interface ReloadRecoveryNoticeProps {\n /** The watch the app's client entry started. */\n watch: ReloadRecoveryWatch;\n /** The app's sentence for each failure. */\n messages: Readonly<Record<ReloadRecoveryKind, React.ReactNode>>;\n /** The app's label for the refresh control. */\n refreshLabel: React.ReactNode;\n /**\n * The app's own reload, which runs its unsaved-work guard first. Refresh is pending until it\n * settles: a reload that proceeds keeps it pending until the page unloads, and a cancelled guard\n * settles it with the page, its input, and the notice as they were.\n */\n onRefresh: () => Promise<unknown>;\n /** Receives anything `onRefresh` throws. */\n onRefreshError: (error: unknown) => void;\n className?: string;\n}\n\nconst noFailureOnServer = () => null;\n\n/**\n * One notice pinned to the top of the screen once the page hits a failure only a reload repairs.\n * It cannot be dismissed and never reloads by itself: the page and every editor beneath it stay\n * mounted and usable until the person presses Refresh. A repeat of the failure changes nothing.\n */\nexport function ReloadRecoveryNotice({\n watch,\n messages,\n refreshLabel,\n onRefresh,\n onRefreshError,\n className,\n}: ReloadRecoveryNoticeProps) {\n const kind = React.useSyncExternalStore(watch.subscribe, watch.current, noFailureOnServer);\n const refresh = useAsyncAction(onRefresh, { onError: onRefreshError });\n if (kind === null) return null;\n return (\n <Alert\n className={cn(\n \"ui-reload-recovery-notice fixed inset-x-0 top-0 z-50 flex items-center justify-between gap-4 rounded-none border-x-0 border-t-0\",\n className,\n )}\n >\n <AlertDescription>{messages[kind]}</AlertDescription>\n <Button type=\"button\" size=\"sm\" pending={refresh.pending} onClick={() => void refresh.run()}>\n {refreshLabel}\n </Button>\n </Alert>\n );\n}\n"]}
1
+ {"version":3,"file":"reload-recovery-notice.js","sourceRoot":"","sources":["../../../src/react/components/reload-recovery-notice.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAWrC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;AAErC,MAAM,UAAU,oBAAoB,CAAC,EACnC,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,cAAc,EACd,SAAS,GACiB;IAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC3F,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IACvE,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,CACL,MAAC,KAAK,IACJ,SAAS,EAAE,EAAE,CACX,iIAAiI,EACjI,SAAS,CACV,aAED,KAAC,gBAAgB,cAAE,QAAQ,CAAC,IAAI,CAAC,GAAoB,EACrD,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,YACxF,YAAY,GACN,IACH,CACT,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { ReloadRecoveryWatch } from '../../browser/reload-recovery-watch.js';\nimport type { ReloadRecoveryKind } from '../../lib/reload-recovery.js';\nimport { cn } from '../../lib/utils.js';\nimport { useAsyncAction } from '../hooks/use-async-action.js';\nimport { Alert, AlertDescription } from './alert.js';\nimport { Button } from './button.js';\n\nexport interface ReloadRecoveryNoticeProps {\n watch: ReloadRecoveryWatch;\n messages: Readonly<Record<ReloadRecoveryKind, React.ReactNode>>;\n refreshLabel: React.ReactNode;\n onRefresh: () => Promise<unknown>;\n onRefreshError: (error: unknown) => void;\n className?: string;\n}\n\nconst noFailureOnServer = () => null;\n\nexport function ReloadRecoveryNotice({\n watch,\n messages,\n refreshLabel,\n onRefresh,\n onRefreshError,\n className,\n}: ReloadRecoveryNoticeProps) {\n const kind = React.useSyncExternalStore(watch.subscribe, watch.current, noFailureOnServer);\n const refresh = useAsyncAction(onRefresh, { onError: onRefreshError });\n if (kind === null) return null;\n return (\n <Alert\n className={cn(\n 'ui-reload-recovery-notice fixed inset-x-0 top-0 z-50 flex items-center justify-between gap-4 rounded-none border-x-0 border-t-0',\n className,\n )}\n >\n <AlertDescription>{messages[kind]}</AlertDescription>\n <Button type=\"button\" size=\"sm\" pending={refresh.pending} onClick={() => void refresh.run()}>\n {refreshLabel}\n </Button>\n </Alert>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
- import * as React from "react";
2
- import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
1
+ import * as React from 'react';
2
+ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
3
3
  interface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
4
4
  viewportRef?: React.Ref<HTMLDivElement>;
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-area.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-area.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAA;AAIlE,UAAU,eACR,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC;IACvE,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;CACxC;AAED,QAAA,MAAM,UAAU,wFAkBd,CAAA;AAGF,QAAA,MAAM,SAAS,wKAmBb,CAAA;AAGF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA"}
1
+ {"version":3,"file":"scroll-area.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-area.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AAInE,UAAU,eAAgB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC;IAC/F,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACzC;AAED,QAAA,MAAM,UAAU,wFAed,CAAC;AAGH,QAAA,MAAM,SAAS,wKAiBb,CAAC;AAGH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
@@ -1,13 +1,11 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
5
- import { cn } from "../../lib/utils.js";
6
- const ScrollArea = React.forwardRef(({ className, children, viewportRef, ...props }, ref) => (_jsxs(ScrollAreaPrimitive.Root, { ref: ref, className: cn("relative overflow-hidden", className), ...props, children: [_jsx(ScrollAreaPrimitive.Viewport, { ref: viewportRef, className: "h-full w-full rounded-[inherit]", children: children }), _jsx(ScrollBar, {}), _jsx(ScrollAreaPrimitive.Corner, {})] })));
3
+ import * as React from 'react';
4
+ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
5
+ import { cn } from '../../lib/utils.js';
6
+ const ScrollArea = React.forwardRef(({ className, children, viewportRef, ...props }, ref) => (_jsxs(ScrollAreaPrimitive.Root, { ref: ref, className: cn('relative overflow-hidden', className), ...props, children: [_jsx(ScrollAreaPrimitive.Viewport, { ref: viewportRef, className: "h-full w-full rounded-[inherit]", children: children }), _jsx(ScrollBar, {}), _jsx(ScrollAreaPrimitive.Corner, {})] })));
7
7
  ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
8
- const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...props }, ref) => (_jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, { ref: ref, orientation: orientation, className: cn("flex touch-none select-none transition-colors", orientation === "vertical" &&
9
- "h-full w-2.5 border-l border-l-transparent p-[1px]", orientation === "horizontal" &&
10
- "h-2.5 flex-col border-t border-t-transparent p-[1px]", className), ...props, children: _jsx(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" }) })));
8
+ const ScrollBar = React.forwardRef(({ className, orientation = 'vertical', ...props }, ref) => (_jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, { ref: ref, orientation: orientation, className: cn('flex touch-none select-none transition-colors', orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]', orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent p-[1px]', className), ...props, children: _jsx(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" }) })));
11
9
  ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
12
10
  export { ScrollArea, ScrollBar };
13
11
  //# sourceMappingURL=scroll-area.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-area.js","sourceRoot":"","sources":["../../../src/react/components/scroll-area.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAA;AAElE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAOvC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAGjC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACzD,MAAC,mBAAmB,CAAC,IAAI,IACvB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,0BAA0B,EAAE,SAAS,CAAC,KAChD,KAAK,aAET,KAAC,mBAAmB,CAAC,QAAQ,IAC3B,GAAG,EAAE,WAAW,EAChB,SAAS,EAAC,iCAAiC,YAE1C,QAAQ,GACoB,EAC/B,KAAC,SAAS,KAAG,EACb,KAAC,mBAAmB,CAAC,MAAM,KAAG,IACL,CAC5B,CAAC,CAAA;AACF,UAAU,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAA;AAE7D,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAGhC,CAAC,EAAE,SAAS,EAAE,WAAW,GAAG,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAC5D,KAAC,mBAAmB,CAAC,mBAAmB,IACtC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,EAAE,CACX,+CAA+C,EAC/C,WAAW,KAAK,UAAU;QACxB,oDAAoD,EACtD,WAAW,KAAK,YAAY;QAC1B,sDAAsD,EACxD,SAAS,CACV,KACG,KAAK,YAET,KAAC,mBAAmB,CAAC,eAAe,IAAC,SAAS,EAAC,wCAAwC,GAAG,GAClD,CAC3C,CAAC,CAAA;AACF,SAAS,CAAC,WAAW,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,WAAW,CAAA;AAE3E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"../../lib/utils.js\"\n\ninterface ScrollAreaProps\n extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {\n viewportRef?: React.Ref<HTMLDivElement>\n}\n\nconst ScrollArea = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.Root>,\n ScrollAreaProps\n>(({ className, children, viewportRef, ...props }, ref) => (\n <ScrollAreaPrimitive.Root\n ref={ref}\n className={cn(\"relative overflow-hidden\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n ref={viewportRef}\n className=\"h-full w-full rounded-[inherit]\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n))\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName\n\nconst ScrollBar = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n>(({ className, orientation = \"vertical\", ...props }, ref) => (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n ref={ref}\n orientation={orientation}\n className={cn(\n \"flex touch-none select-none transition-colors\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent p-[1px]\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent p-[1px]\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className=\"relative flex-1 rounded-full bg-border\" />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n))\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName\n\nexport { ScrollArea, ScrollBar }\n"]}
1
+ {"version":3,"file":"scroll-area.js","sourceRoot":"","sources":["../../../src/react/components/scroll-area.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAMxC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAGjC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACzD,MAAC,mBAAmB,CAAC,IAAI,IACvB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,0BAA0B,EAAE,SAAS,CAAC,KAChD,KAAK,aAET,KAAC,mBAAmB,CAAC,QAAQ,IAAC,GAAG,EAAE,WAAW,EAAE,SAAS,EAAC,iCAAiC,YACxF,QAAQ,GACoB,EAC/B,KAAC,SAAS,KAAG,EACb,KAAC,mBAAmB,CAAC,MAAM,KAAG,IACL,CAC5B,CAAC,CAAC;AACH,UAAU,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC;AAE9D,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAGhC,CAAC,EAAE,SAAS,EAAE,WAAW,GAAG,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAC5D,KAAC,mBAAmB,CAAC,mBAAmB,IACtC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,EAAE,CACX,+CAA+C,EAC/C,WAAW,KAAK,UAAU,IAAI,oDAAoD,EAClF,WAAW,KAAK,YAAY,IAAI,sDAAsD,EACtF,SAAS,CACV,KACG,KAAK,YAET,KAAC,mBAAmB,CAAC,eAAe,IAAC,SAAS,EAAC,wCAAwC,GAAG,GAClD,CAC3C,CAAC,CAAC;AACH,SAAS,CAAC,WAAW,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,WAAW,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';\n\nimport { cn } from '../../lib/utils.js';\n\ninterface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {\n viewportRef?: React.Ref<HTMLDivElement>;\n}\n\nconst ScrollArea = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.Root>,\n ScrollAreaProps\n>(({ className, children, viewportRef, ...props }, ref) => (\n <ScrollAreaPrimitive.Root\n ref={ref}\n className={cn('relative overflow-hidden', className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport ref={viewportRef} className=\"h-full w-full rounded-[inherit]\">\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n));\nScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;\n\nconst ScrollBar = React.forwardRef<\n React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,\n React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>\n>(({ className, orientation = 'vertical', ...props }, ref) => (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n ref={ref}\n orientation={orientation}\n className={cn(\n 'flex touch-none select-none transition-colors',\n orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent p-[1px]',\n orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent p-[1px]',\n className,\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb className=\"relative flex-1 rounded-full bg-border\" />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n));\nScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;\n\nexport { ScrollArea, ScrollBar };\n"]}
@@ -1,38 +1,14 @@
1
- import * as React from "react";
2
- import { type ButtonProps } from "./button.js";
3
- /**
4
- * Standard button DOM props forwarded to the rendered element, minus the props
5
- * this component owns. Owned props are excluded (not just overridden) so a
6
- * consumer can never route them through the passthrough channel: `aria-label`
7
- * is set via {@link ScrollToTopButtonProps.ariaLabel}, extra classes via the
8
- * merge-aware {@link ScrollToTopButtonProps.className}, content via
9
- * {@link ScrollToTopButtonProps.icon}, and `onClick` is fixed to scroll-to-top
10
- * (its scroll animation configurable via
11
- * {@link ScrollToTopButtonProps.scrollBehavior}). This mirrors how the sibling
12
- * `Button` destructures its owned `className` out of the forwarded `...props`.
13
- */
14
- type ScrollToTopButtonPassthrough = Omit<React.ComponentPropsWithoutRef<"button">, "className" | "onClick" | "aria-label" | "children">;
1
+ import * as React from 'react';
2
+ import { type ButtonProps } from './button.js';
3
+ type ScrollToTopButtonPassthrough = Omit<React.ComponentPropsWithoutRef<'button'>, 'className' | 'onClick' | 'aria-label' | 'children'>;
15
4
  export interface ScrollToTopButtonProps extends ScrollToTopButtonPassthrough {
16
- /** Scroll threshold (px) before the button appears. Default 400. */
17
5
  threshold?: number;
18
- /** Aria label. Default "Scroll to top". */
19
6
  ariaLabel?: string;
20
- /** Optional extra classes for the button. Merged with the component's own classes. */
21
7
  className?: string;
22
- /** Optional override for the icon. */
23
8
  icon?: React.ReactNode;
24
- /** Button variant. Forwarded to the underlying Button. Defaults to Button's own default. */
25
- variant?: ButtonProps["variant"];
26
- /** Button size. Forwarded to the underlying Button. Default "icon". */
27
- size?: ButtonProps["size"];
28
- /**
29
- * Scroll behavior passed to `window.scrollTo`. Default "smooth". Pass "auto"
30
- * to skip the smooth animation (e.g. for a reduced-motion mode). The package
31
- * stays motion-policy agnostic: the consumer decides what to pass here — an
32
- * explicit JS `behavior: "smooth"` is not overridden by a CSS
33
- * `scroll-behavior` kill-switch, so an app-level reduced-motion mode must
34
- * pass "auto" to actually stop the animation.
35
- */
9
+ variant?: ButtonProps['variant'];
10
+ size?: ButtonProps['size'];
11
+ /** An explicit JS `behavior: "smooth"` ignores a CSS `scroll-behavior` override, so a reduced-motion mode passes "auto". */
36
12
  scrollBehavior?: ScrollBehavior;
37
13
  }
38
14
  export declare function ScrollToTopButton({ threshold, ariaLabel, className, icon, variant, size, scrollBehavior, ...rest }: ScrollToTopButtonProps): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-to-top-button.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAGvD;;;;;;;;;;GAUG;AACH,KAAK,4BAA4B,GAAG,IAAI,CACtC,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EACxC,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,CACpD,CAAC;AAEF,MAAM,WAAW,sBAAuB,SAAQ,4BAA4B;IAC1E,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,uEAAuE;IACvE,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAe,EACf,SAA2B,EAC3B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAa,EACb,cAAyB,EACzB,GAAG,IAAI,EACR,EAAE,sBAAsB,qBA4BxB"}
1
+ {"version":3,"file":"scroll-to-top-button.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAGvD,KAAK,4BAA4B,GAAG,IAAI,CACtC,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EACxC,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,CACpD,CAAC;AAEF,MAAM,WAAW,sBAAuB,SAAQ,4BAA4B;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,4HAA4H;IAC5H,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAe,EACf,SAA2B,EAC3B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAa,EACb,cAAyB,EACzB,GAAG,IAAI,EACR,EAAE,sBAAsB,qBA4BxB"}
@@ -1,18 +1,18 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { ChevronUp } from "lucide-react";
5
- import { Button } from "./button.js";
6
- import { cn } from "../../lib/utils.js";
7
- export function ScrollToTopButton({ threshold = 400, ariaLabel = "Scroll to top", className, icon, variant, size = "icon", scrollBehavior = "smooth", ...rest }) {
3
+ import * as React from 'react';
4
+ import { ChevronUp } from 'lucide-react';
5
+ import { Button } from './button.js';
6
+ import { cn } from '../../lib/utils.js';
7
+ export function ScrollToTopButton({ threshold = 400, ariaLabel = 'Scroll to top', className, icon, variant, size = 'icon', scrollBehavior = 'smooth', ...rest }) {
8
8
  const [isVisible, setIsVisible] = React.useState(false);
9
9
  React.useEffect(() => {
10
10
  const toggle = () => setIsVisible(window.scrollY > threshold);
11
11
  toggle();
12
- window.addEventListener("scroll", toggle, { passive: true });
13
- return () => window.removeEventListener("scroll", toggle);
12
+ window.addEventListener('scroll', toggle, { passive: true });
13
+ return () => window.removeEventListener('scroll', toggle);
14
14
  }, [threshold]);
15
15
  const onClick = () => window.scrollTo({ top: 0, behavior: scrollBehavior });
16
- return (_jsx(Button, { ...rest, variant: variant, size: size, onClick: onClick, "aria-label": ariaLabel, className: cn("fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full elevation-raised transition-opacity duration-[var(--motion-base)] ease-[var(--motion-ease)]", isVisible ? "opacity-100" : "opacity-0 pointer-events-none", className), children: icon ?? _jsx(ChevronUp, { className: "h-5 w-5" }) }));
16
+ return (_jsx(Button, { ...rest, variant: variant, size: size, onClick: onClick, "aria-label": ariaLabel, className: cn('fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full elevation-raised transition-opacity duration-[var(--motion-base)] ease-[var(--motion-ease)]', isVisible ? 'opacity-100' : 'opacity-0 pointer-events-none', className), children: icon ?? _jsx(ChevronUp, { className: "h-5 w-5" }) }));
17
17
  }
18
18
  //# sourceMappingURL=scroll-to-top-button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-to-top-button.js","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AA0CxC,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,GAAG,GAAG,EACf,SAAS,GAAG,eAAe,EAC3B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAI,GAAG,MAAM,EACb,cAAc,GAAG,QAAQ,EACzB,GAAG,IAAI,EACgB;IACvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAE5E,OAAO,CACL,KAAC,MAAM,OACD,IAAI,EACR,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,gBACJ,SAAS,EACrB,SAAS,EAAE,EAAE,CACX,yJAAyJ,EACzJ,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,+BAA+B,EAC3D,SAAS,CACV,YAEA,IAAI,IAAI,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,GACnC,CACV,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { ChevronUp } from \"lucide-react\";\nimport { Button, type ButtonProps } from \"./button.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Standard button DOM props forwarded to the rendered element, minus the props\n * this component owns. Owned props are excluded (not just overridden) so a\n * consumer can never route them through the passthrough channel: `aria-label`\n * is set via {@link ScrollToTopButtonProps.ariaLabel}, extra classes via the\n * merge-aware {@link ScrollToTopButtonProps.className}, content via\n * {@link ScrollToTopButtonProps.icon}, and `onClick` is fixed to scroll-to-top\n * (its scroll animation configurable via\n * {@link ScrollToTopButtonProps.scrollBehavior}). This mirrors how the sibling\n * `Button` destructures its owned `className` out of the forwarded `...props`.\n */\ntype ScrollToTopButtonPassthrough = Omit<\n React.ComponentPropsWithoutRef<\"button\">,\n \"className\" | \"onClick\" | \"aria-label\" | \"children\"\n>;\n\nexport interface ScrollToTopButtonProps extends ScrollToTopButtonPassthrough {\n /** Scroll threshold (px) before the button appears. Default 400. */\n threshold?: number;\n /** Aria label. Default \"Scroll to top\". */\n ariaLabel?: string;\n /** Optional extra classes for the button. Merged with the component's own classes. */\n className?: string;\n /** Optional override for the icon. */\n icon?: React.ReactNode;\n /** Button variant. Forwarded to the underlying Button. Defaults to Button's own default. */\n variant?: ButtonProps[\"variant\"];\n /** Button size. Forwarded to the underlying Button. Default \"icon\". */\n size?: ButtonProps[\"size\"];\n /**\n * Scroll behavior passed to `window.scrollTo`. Default \"smooth\". Pass \"auto\"\n * to skip the smooth animation (e.g. for a reduced-motion mode). The package\n * stays motion-policy agnostic: the consumer decides what to pass here — an\n * explicit JS `behavior: \"smooth\"` is not overridden by a CSS\n * `scroll-behavior` kill-switch, so an app-level reduced-motion mode must\n * pass \"auto\" to actually stop the animation.\n */\n scrollBehavior?: ScrollBehavior;\n}\n\nexport function ScrollToTopButton({\n threshold = 400,\n ariaLabel = \"Scroll to top\",\n className,\n icon,\n variant,\n size = \"icon\",\n scrollBehavior = \"smooth\",\n ...rest\n}: ScrollToTopButtonProps) {\n const [isVisible, setIsVisible] = React.useState(false);\n\n React.useEffect(() => {\n const toggle = () => setIsVisible(window.scrollY > threshold);\n toggle();\n window.addEventListener(\"scroll\", toggle, { passive: true });\n return () => window.removeEventListener(\"scroll\", toggle);\n }, [threshold]);\n\n const onClick = () => window.scrollTo({ top: 0, behavior: scrollBehavior });\n\n return (\n <Button\n {...rest}\n variant={variant}\n size={size}\n onClick={onClick}\n aria-label={ariaLabel}\n className={cn(\n \"fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full elevation-raised transition-opacity duration-[var(--motion-base)] ease-[var(--motion-ease)]\",\n isVisible ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n className,\n )}\n >\n {icon ?? <ChevronUp className=\"h-5 w-5\" />}\n </Button>\n );\n}\n"]}
1
+ {"version":3,"file":"scroll-to-top-button.js","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAkBxC,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,GAAG,GAAG,EACf,SAAS,GAAG,eAAe,EAC3B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAI,GAAG,MAAM,EACb,cAAc,GAAG,QAAQ,EACzB,GAAG,IAAI,EACgB;IACvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAE5E,OAAO,CACL,KAAC,MAAM,OACD,IAAI,EACR,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,gBACJ,SAAS,EACrB,SAAS,EAAE,EAAE,CACX,yJAAyJ,EACzJ,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,+BAA+B,EAC3D,SAAS,CACV,YAEA,IAAI,IAAI,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,GACnC,CACV,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ChevronUp } from 'lucide-react';\nimport { Button, type ButtonProps } from './button.js';\nimport { cn } from '../../lib/utils.js';\n\ntype ScrollToTopButtonPassthrough = Omit<\n React.ComponentPropsWithoutRef<'button'>,\n 'className' | 'onClick' | 'aria-label' | 'children'\n>;\n\nexport interface ScrollToTopButtonProps extends ScrollToTopButtonPassthrough {\n threshold?: number;\n ariaLabel?: string;\n className?: string;\n icon?: React.ReactNode;\n variant?: ButtonProps['variant'];\n size?: ButtonProps['size'];\n /** An explicit JS `behavior: \"smooth\"` ignores a CSS `scroll-behavior` override, so a reduced-motion mode passes \"auto\". */\n scrollBehavior?: ScrollBehavior;\n}\n\nexport function ScrollToTopButton({\n threshold = 400,\n ariaLabel = 'Scroll to top',\n className,\n icon,\n variant,\n size = 'icon',\n scrollBehavior = 'smooth',\n ...rest\n}: ScrollToTopButtonProps) {\n const [isVisible, setIsVisible] = React.useState(false);\n\n React.useEffect(() => {\n const toggle = () => setIsVisible(window.scrollY > threshold);\n toggle();\n window.addEventListener('scroll', toggle, { passive: true });\n return () => window.removeEventListener('scroll', toggle);\n }, [threshold]);\n\n const onClick = () => window.scrollTo({ top: 0, behavior: scrollBehavior });\n\n return (\n <Button\n {...rest}\n variant={variant}\n size={size}\n onClick={onClick}\n aria-label={ariaLabel}\n className={cn(\n 'fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full elevation-raised transition-opacity duration-[var(--motion-base)] ease-[var(--motion-ease)]',\n isVisible ? 'opacity-100' : 'opacity-0 pointer-events-none',\n className,\n )}\n >\n {icon ?? <ChevronUp className=\"h-5 w-5\" />}\n </Button>\n );\n}\n"]}
@@ -1,75 +1,22 @@
1
1
  export interface SearchDropdownProps<T> {
2
- /** Current search value */
3
2
  value: string;
4
- /** Called when search value changes */
5
3
  onValueChange: (value: string) => void;
6
- /** Search results array */
7
4
  results: T[];
8
- /** Loading state */
9
5
  isLoading: boolean;
10
- /** The search's failure exactly as the data layer reported it; `null` or `undefined` when it did not fail. */
11
6
  error: unknown;
12
- /**
13
- * Renders a failed search inside the open dropdown. The consumer owns the failure's words and any
14
- * retry, so the dropdown never shows a failure state of its own.
15
- */
16
7
  renderError: (error: unknown) => React.ReactNode;
17
- /** Called when a result is selected */
18
8
  onSelect: (result: T) => void;
19
- /** Called when search is cleared (after the value has been reset). Optional notification hook. */
20
9
  onClear?: () => void;
21
- /** Placeholder text */
22
10
  placeholder?: string;
23
- /** Label for the input */
24
11
  label?: string;
25
- /** Custom className */
26
12
  className?: string;
27
- /** Disabled state */
28
13
  disabled?: boolean;
29
- /** Icon to show in input (default: Search) */
30
14
  icon?: React.ReactNode;
31
- /**
32
- * The search rule of the hook behind the dropdown, passed from that hook rather than restated:
33
- * `isSearchable(value)` decides whether the value is searched (and the dropdown opens), and
34
- * `minChars` is the minimum the below-minimum hint names.
35
- */
36
15
  minChars: number;
37
16
  isSearchable: (value: string) => boolean;
38
- /** Message to show when no results found */
39
17
  emptyMessage?: string;
40
- /** What assistive technology hears when results arrive (default: "1 result" / "N results"). */
41
18
  resultsAnnouncement?: (count: number) => string;
42
- /** Custom render function for each result */
43
19
  renderResult: (result: T, index: number) => React.ReactNode;
44
20
  }
45
- /**
46
- * A search box with a results dropdown, following the combobox pattern: the input keeps focus, the
47
- * results are a listbox, and the arrow-highlighted result is the input's active descendant. Every
48
- * instance carries its own ids, so several can share a page.
49
- *
50
- * Once the value is long enough the dropdown stays open through every settled state — results, an
51
- * empty answer, or a failure — until the user dismisses it (Escape, a click outside, a selection).
52
- * A dismissal holds for the value it was made on: re-rendered props never reopen it, while typing,
53
- * a new value, or ArrowDown does.
54
- *
55
- * @example
56
- * ```tsx
57
- * <SearchDropdown<User>
58
- * value={searchValue}
59
- * onValueChange={setSearchValue}
60
- * results={users}
61
- * isLoading={isLoading}
62
- * error={error}
63
- * renderError={(error) => <MyErrorState error={error} />}
64
- * minChars={SEARCH_MIN_LENGTH}
65
- * isSearchable={isSearchableText}
66
- * onSelect={(user) => console.log(user)}
67
- * placeholder="Search users..."
68
- * renderResult={(user) => (
69
- * <div>{user.displayName}</div>
70
- * )}
71
- * />
72
- * ```
73
- */
74
21
  export declare function SearchDropdown<T>({ value, onValueChange, results, isLoading, error, renderError, onSelect, onClear, placeholder, label, className, disabled, icon, minChars, isSearchable, emptyMessage, resultsAnnouncement, renderResult, }: SearchDropdownProps<T>): import("react").JSX.Element;
75
22
  //# sourceMappingURL=search-dropdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-dropdown.d.ts","sourceRoot":"","sources":["../../../src/react/components/search-dropdown.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,2BAA2B;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,oBAAoB;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,8GAA8G;IAC9G,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC;IACjD,uCAAuC;IACvC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,6CAA6C;IAC7C,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,KAAK,EACL,aAAa,EACb,OAAO,EACP,SAAS,EACT,KAAK,EACL,WAAW,EACX,QAAQ,EACR,OAAO,EACP,WAAyB,EACzB,KAAK,EACL,SAAS,EACT,QAAgB,EAChB,IAAqC,EACrC,QAAQ,EACR,YAAY,EACZ,YAAiC,EACjC,mBAAgD,EAChD,YAAY,GACb,EAAE,mBAAmB,CAAC,CAAC,CAAC,+BAkMxB"}
1
+ {"version":3,"file":"search-dropdown.d.ts","sourceRoot":"","sources":["../../../src/react/components/search-dropdown.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC;IACjD,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAC7D;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,KAAK,EACL,aAAa,EACb,OAAO,EACP,SAAS,EACT,KAAK,EACL,WAAW,EACX,QAAQ,EACR,OAAO,EACP,WAAyB,EACzB,KAAK,EACL,SAAS,EACT,QAAgB,EAChB,IAAqC,EACrC,QAAQ,EACR,YAAY,EACZ,YAAiC,EACjC,mBAAgD,EAChD,YAAY,GACb,EAAE,mBAAmB,CAAC,CAAC,CAAC,+BAqMxB"}
@@ -5,39 +5,10 @@ import { Input } from './input.js';
5
5
  import { Label } from './label.js';
6
6
  import { X, Search } from 'lucide-react';
7
7
  import { Spinner } from './spinner.js';
8
- import { cn } from "../../lib/utils.js";
8
+ import { cn } from '../../lib/utils.js';
9
9
  function defaultResultsAnnouncement(count) {
10
10
  return count === 1 ? '1 result' : `${count} results`;
11
11
  }
12
- /**
13
- * A search box with a results dropdown, following the combobox pattern: the input keeps focus, the
14
- * results are a listbox, and the arrow-highlighted result is the input's active descendant. Every
15
- * instance carries its own ids, so several can share a page.
16
- *
17
- * Once the value is long enough the dropdown stays open through every settled state — results, an
18
- * empty answer, or a failure — until the user dismisses it (Escape, a click outside, a selection).
19
- * A dismissal holds for the value it was made on: re-rendered props never reopen it, while typing,
20
- * a new value, or ArrowDown does.
21
- *
22
- * @example
23
- * ```tsx
24
- * <SearchDropdown<User>
25
- * value={searchValue}
26
- * onValueChange={setSearchValue}
27
- * results={users}
28
- * isLoading={isLoading}
29
- * error={error}
30
- * renderError={(error) => <MyErrorState error={error} />}
31
- * minChars={SEARCH_MIN_LENGTH}
32
- * isSearchable={isSearchableText}
33
- * onSelect={(user) => console.log(user)}
34
- * placeholder="Search users..."
35
- * renderResult={(user) => (
36
- * <div>{user.displayName}</div>
37
- * )}
38
- * />
39
- * ```
40
- */
41
12
  export function SearchDropdown({ value, onValueChange, results, isLoading, error, renderError, onSelect, onClear, placeholder = 'Search...', label, className, disabled = false, icon = _jsx(Search, { className: "h-4 w-4" }), minChars, isSearchable, emptyMessage = 'No results found', resultsAnnouncement = defaultResultsAnnouncement, renderResult, }) {
42
13
  const baseId = useId();
43
14
  const inputId = `${baseId}-input`;
@@ -47,8 +18,6 @@ export function SearchDropdown({ value, onValueChange, results, isLoading, error
47
18
  const hintId = `${baseId}-hint`;
48
19
  const optionId = (index) => `${baseId}-option-${index}`;
49
20
  const [dismissedFor, setDismissedFor] = useState(null);
50
- // The highlight belongs to the value it was made on, so a new query starts with none, while a
51
- // refreshed result list for the same query keeps it.
52
21
  const [highlight, setHighlight] = useState(null);
53
22
  const containerRef = useRef(null);
54
23
  const inputRef = useRef(null);
@@ -56,7 +25,9 @@ export function SearchDropdown({ value, onValueChange, results, isLoading, error
56
25
  const isOpen = searchable && dismissedFor !== value;
57
26
  const failed = error !== null && error !== undefined;
58
27
  const showOptions = isOpen && !failed && !isLoading && results.length > 0;
59
- const activeIndex = showOptions && highlight && highlight.value === value && highlight.index < results.length ? highlight.index : -1;
28
+ const activeIndex = showOptions && highlight && highlight.value === value && highlight.index < results.length
29
+ ? highlight.index
30
+ : -1;
60
31
  const showHint = value.length > 0 && !searchable;
61
32
  const announcement = !isOpen || failed
62
33
  ? ''
@@ -92,7 +63,10 @@ export function SearchDropdown({ value, onValueChange, results, isLoading, error
92
63
  }
93
64
  if (!showOptions)
94
65
  return;
95
- setHighlight({ value, index: activeIndex < results.length - 1 ? activeIndex + 1 : activeIndex });
66
+ setHighlight({
67
+ value,
68
+ index: activeIndex < results.length - 1 ? activeIndex + 1 : activeIndex,
69
+ });
96
70
  break;
97
71
  case 'ArrowUp':
98
72
  if (!showOptions)
@@ -107,8 +81,7 @@ export function SearchDropdown({ value, onValueChange, results, isLoading, error
107
81
  select(results[activeIndex]);
108
82
  break;
109
83
  case 'Escape':
110
- // Escape never falls through to the search field's own clear, which would skip onClear:
111
- // it closes an open dropdown, and clears a closed one through handleClear.
84
+ // Escape never falls through to the search field's own clear, which would skip onClear.
112
85
  e.preventDefault();
113
86
  if (isOpen)
114
87
  setDismissedFor(value);
@@ -126,8 +99,6 @@ export function SearchDropdown({ value, onValueChange, results, isLoading, error
126
99
  return (_jsxs("div", { ref: containerRef, className: cn('relative', className), children: [label && (_jsx(Label, { id: labelId, htmlFor: inputId, className: "mb-2 block", children: label })), _jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", "aria-hidden": "true", children: icon }), _jsx(Input, { ref: inputRef, id: inputId, type: "search", role: "combobox", "aria-autocomplete": "list", "aria-expanded": isOpen, "aria-controls": isOpen ? (showOptions ? listboxId : panelId) : undefined, "aria-activedescendant": activeIndex >= 0 ? optionId(activeIndex) : undefined, "aria-describedby": showHint ? hintId : undefined, autoComplete: "off", value: value, onChange: (e) => {
127
100
  setDismissedFor(null);
128
101
  onValueChange(e.target.value);
129
- }, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, className: "pl-10 pr-10 [&::-webkit-search-cancel-button]:appearance-none" }), _jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2", children: isLoading ? (_jsx(Spinner, { size: "xs", className: "text-muted-foreground" })) : value ? (_jsx("button", { type: "button", onClick: handleClear, className: "text-muted-foreground hover:text-foreground transition-colors", "aria-label": "Clear search", children: _jsx(X, { className: "h-4 w-4" }) })) : null })] }), isOpen && (_jsx("div", { id: panelId, className: "absolute z-50 w-full mt-1 bg-popover border rounded-md elevation-raised max-h-60 overflow-auto", children: failed ? (renderError(error)) : isLoading ? (_jsxs("div", { className: "px-3 py-2 text-sm text-muted-foreground flex items-center gap-2", children: [_jsx(Spinner, { size: "xs" }), "Searching..."] })) : results.length === 0 ? (_jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: emptyMessage })) : (_jsx("div", { role: "listbox", id: listboxId, "aria-labelledby": label ? labelId : undefined, "aria-label": label ? undefined : placeholder, children: results.map((result, index) => (_jsx("div", { id: optionId(index), role: "option", "aria-selected": index === activeIndex,
130
- // Keeps focus in the input, where the combobox's keyboard handling lives.
131
- onMouseDown: (e) => e.preventDefault(), onClick: () => select(result), onMouseEnter: () => setHighlight({ value, index }), className: cn('w-full text-left transition-colors cursor-pointer hover:bg-accent', index === activeIndex && 'bg-accent'), children: renderResult(result, index) }, index))) })) })), _jsx("div", { role: "status", "aria-live": "polite", className: "sr-only", children: announcement }), showHint && (_jsxs("p", { id: hintId, className: "text-xs text-muted-foreground mt-1", children: ["Type at least ", minChars, " characters to search"] }))] }));
102
+ }, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, className: "pl-10 pr-10 [&::-webkit-search-cancel-button]:appearance-none" }), _jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2", children: isLoading ? (_jsx(Spinner, { size: "xs", className: "text-muted-foreground" })) : value ? (_jsx("button", { type: "button", onClick: handleClear, className: "text-muted-foreground hover:text-foreground transition-colors", "aria-label": "Clear search", children: _jsx(X, { className: "h-4 w-4" }) })) : null })] }), isOpen && (_jsx("div", { id: panelId, className: "absolute z-50 w-full mt-1 bg-popover border rounded-md elevation-raised max-h-60 overflow-auto", children: failed ? (renderError(error)) : isLoading ? (_jsxs("div", { className: "px-3 py-2 text-sm text-muted-foreground flex items-center gap-2", children: [_jsx(Spinner, { size: "xs" }), "Searching..."] })) : results.length === 0 ? (_jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: emptyMessage })) : (_jsx("div", { role: "listbox", id: listboxId, "aria-labelledby": label ? labelId : undefined, "aria-label": label ? undefined : placeholder, children: results.map((result, index) => (_jsx("div", { id: optionId(index), role: "option", "aria-selected": index === activeIndex, onMouseDown: (e) => e.preventDefault(), onClick: () => select(result), onMouseEnter: () => setHighlight({ value, index }), className: cn('w-full text-left transition-colors cursor-pointer hover:bg-accent', index === activeIndex && 'bg-accent'), children: renderResult(result, index) }, index))) })) })), _jsx("div", { role: "status", "aria-live": "polite", className: "sr-only", children: announcement }), showHint && (_jsxs("p", { id: hintId, className: "text-xs text-muted-foreground mt-1", children: ["Type at least ", minChars, " characters to search"] }))] }));
132
103
  }
133
104
  //# sourceMappingURL=search-dropdown.js.map