@nocoo/basalt 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/README.md +2 -0
  2. package/ai/COMPATIBILITY.md +11 -1
  3. package/ai/DESIGN.md +342 -0
  4. package/ai/INTEGRATION.md +179 -128
  5. package/ai/RECIPES.md +51 -26
  6. package/ai/USAGE.md +4 -4
  7. package/ai/registry.json +2836 -270
  8. package/dist/charts/config.d.ts +11 -11
  9. package/dist/charts/config.js +4 -4
  10. package/dist/charts/config.js.map +1 -1
  11. package/dist/charts/date-navigation.js +10 -10
  12. package/dist/charts/date-navigation.js.map +1 -1
  13. package/dist/charts/donut.js +1 -1
  14. package/dist/charts/donut.js.map +1 -1
  15. package/dist/charts/frame.d.ts +1 -1
  16. package/dist/charts/frame.js +4 -4
  17. package/dist/charts/frame.js.map +1 -1
  18. package/dist/charts/gauge.js +5 -5
  19. package/dist/charts/gauge.js.map +1 -1
  20. package/dist/charts/heatmap-calendar.js +11 -11
  21. package/dist/charts/heatmap-calendar.js.map +1 -1
  22. package/dist/charts/heatmap-matrix.js +8 -8
  23. package/dist/charts/heatmap-matrix.js.map +1 -1
  24. package/dist/charts/item-list.js +1 -1
  25. package/dist/charts/item-list.js.map +1 -1
  26. package/dist/charts/legend.js +19 -19
  27. package/dist/charts/legend.js.map +1 -1
  28. package/dist/charts/palette.js +2 -2
  29. package/dist/charts/palette.js.map +1 -1
  30. package/dist/charts/slot-bar.js +2 -2
  31. package/dist/charts/slot-bar.js.map +1 -1
  32. package/dist/charts/sparkline.js +38 -23
  33. package/dist/charts/sparkline.js.map +1 -1
  34. package/dist/charts/stat-card.d.ts +2 -2
  35. package/dist/charts/stat-card.js +61 -58
  36. package/dist/charts/stat-card.js.map +1 -1
  37. package/dist/charts/timeline.js +18 -9
  38. package/dist/charts/timeline.js.map +1 -1
  39. package/dist/charts/tooltip.js +16 -16
  40. package/dist/charts/tooltip.js.map +1 -1
  41. package/dist/components/accordion.js +1 -1
  42. package/dist/components/accordion.js.map +1 -1
  43. package/dist/components/alert-dialog.js +4 -4
  44. package/dist/components/alert-dialog.js.map +1 -1
  45. package/dist/components/app-header.js +8 -8
  46. package/dist/components/app-header.js.map +1 -1
  47. package/dist/components/app-shell.js +1 -1
  48. package/dist/components/app-shell.js.map +1 -1
  49. package/dist/components/approval-card.d.ts +13 -0
  50. package/dist/components/approval-card.js +161 -0
  51. package/dist/components/approval-card.js.map +1 -0
  52. package/dist/components/avatar.d.ts +12 -0
  53. package/dist/components/avatar.js +39 -18
  54. package/dist/components/avatar.js.map +1 -1
  55. package/dist/components/badge.js +8 -8
  56. package/dist/components/badge.js.map +1 -1
  57. package/dist/components/banner.d.ts +2 -2
  58. package/dist/components/banner.js +9 -8
  59. package/dist/components/banner.js.map +1 -1
  60. package/dist/components/basalt-mark.js +1 -1
  61. package/dist/components/basalt-mark.js.map +1 -1
  62. package/dist/components/battery-meter.js +5 -5
  63. package/dist/components/battery-meter.js.map +1 -1
  64. package/dist/components/breadcrumbs.js +6 -6
  65. package/dist/components/breadcrumbs.js.map +1 -1
  66. package/dist/components/button.js +10 -10
  67. package/dist/components/button.js.map +1 -1
  68. package/dist/components/chat-bubble.js +4 -3
  69. package/dist/components/chat-bubble.js.map +1 -1
  70. package/dist/components/chat-composer.d.ts +21 -3
  71. package/dist/components/chat-composer.js +126 -60
  72. package/dist/components/chat-composer.js.map +1 -1
  73. package/dist/components/chat-header.js +6 -6
  74. package/dist/components/chat-header.js.map +1 -1
  75. package/dist/components/chat-inbox.js +34 -30
  76. package/dist/components/chat-inbox.js.map +1 -1
  77. package/dist/components/chat-markdown.d.ts +8 -0
  78. package/dist/components/chat-markdown.js +122 -0
  79. package/dist/components/chat-markdown.js.map +1 -0
  80. package/dist/components/chat-message.d.ts +26 -0
  81. package/dist/components/chat-message.js +145 -0
  82. package/dist/components/chat-message.js.map +1 -0
  83. package/dist/components/checkbox.js +11 -11
  84. package/dist/components/checkbox.js.map +1 -1
  85. package/dist/components/clipboard-text.js +3 -3
  86. package/dist/components/clipboard-text.js.map +1 -1
  87. package/dist/components/code.d.ts +22 -20
  88. package/dist/components/code.js +94 -32
  89. package/dist/components/code.js.map +1 -1
  90. package/dist/components/collapsible.js +8 -4
  91. package/dist/components/collapsible.js.map +1 -1
  92. package/dist/components/command-palette.js +73 -47
  93. package/dist/components/command-palette.js.map +1 -1
  94. package/dist/components/context-cards.d.ts +15 -0
  95. package/dist/components/context-cards.js +148 -0
  96. package/dist/components/context-cards.js.map +1 -0
  97. package/dist/components/context-menu.d.ts +1 -1
  98. package/dist/components/context-menu.js +18 -14
  99. package/dist/components/context-menu.js.map +1 -1
  100. package/dist/components/data-table.d.ts +8 -2
  101. package/dist/components/data-table.js +161 -106
  102. package/dist/components/data-table.js.map +1 -1
  103. package/dist/components/date-picker.js +13 -13
  104. package/dist/components/date-picker.js.map +1 -1
  105. package/dist/components/delete-resource.js +1 -1
  106. package/dist/components/delete-resource.js.map +1 -1
  107. package/dist/components/description-list.js +3 -3
  108. package/dist/components/description-list.js.map +1 -1
  109. package/dist/components/dialog.d.ts +2 -2
  110. package/dist/components/dialog.js +8 -8
  111. package/dist/components/dialog.js.map +1 -1
  112. package/dist/components/diff-table.d.ts +15 -0
  113. package/dist/components/diff-table.js +146 -0
  114. package/dist/components/diff-table.js.map +1 -0
  115. package/dist/components/dock.js +2 -2
  116. package/dist/components/dock.js.map +1 -1
  117. package/dist/components/dropdown-menu.js +23 -18
  118. package/dist/components/dropdown-menu.js.map +1 -1
  119. package/dist/components/editable-nav-item.js +63 -58
  120. package/dist/components/editable-nav-item.js.map +1 -1
  121. package/dist/components/empty.js +6 -6
  122. package/dist/components/empty.js.map +1 -1
  123. package/dist/components/fab.js +1 -1
  124. package/dist/components/fab.js.map +1 -1
  125. package/dist/components/field.js +3 -3
  126. package/dist/components/field.js.map +1 -1
  127. package/dist/components/file-dropzone.js +7 -7
  128. package/dist/components/file-dropzone.js.map +1 -1
  129. package/dist/components/filter-bar.js +6 -6
  130. package/dist/components/filter-bar.js.map +1 -1
  131. package/dist/components/flow.js +4 -3
  132. package/dist/components/flow.js.map +1 -1
  133. package/dist/components/grid.d.ts +3 -1
  134. package/dist/components/grid.js +15 -8
  135. package/dist/components/grid.js.map +1 -1
  136. package/dist/components/hover-card.js +1 -1
  137. package/dist/components/hover-card.js.map +1 -1
  138. package/dist/components/icon-picker.d.ts +8 -2
  139. package/dist/components/icon-picker.js +75 -47
  140. package/dist/components/icon-picker.js.map +1 -1
  141. package/dist/components/inline-editable.js +6 -6
  142. package/dist/components/inline-editable.js.map +1 -1
  143. package/dist/components/input-area.js +3 -3
  144. package/dist/components/input-area.js.map +1 -1
  145. package/dist/components/input-group.js +5 -5
  146. package/dist/components/input-group.js.map +1 -1
  147. package/dist/components/input.js +4 -4
  148. package/dist/components/input.js.map +1 -1
  149. package/dist/components/label.js +3 -3
  150. package/dist/components/label.js.map +1 -1
  151. package/dist/components/layer-card.d.ts +9 -4
  152. package/dist/components/layer-card.js +72 -67
  153. package/dist/components/layer-card.js.map +1 -1
  154. package/dist/components/loader.d.ts +16 -10
  155. package/dist/components/loader.js +46 -53
  156. package/dist/components/loader.js.map +1 -1
  157. package/dist/components/loading-screen.js +3 -3
  158. package/dist/components/loading-screen.js.map +1 -1
  159. package/dist/components/menu-bar.js +32 -27
  160. package/dist/components/menu-bar.js.map +1 -1
  161. package/dist/components/meter.d.ts +5 -5
  162. package/dist/components/meter.js +25 -12
  163. package/dist/components/meter.js.map +1 -1
  164. package/dist/components/multi-select.js +66 -62
  165. package/dist/components/multi-select.js.map +1 -1
  166. package/dist/components/navigation-menu.d.ts +2 -2
  167. package/dist/components/navigation-menu.js +22 -8
  168. package/dist/components/navigation-menu.js.map +1 -1
  169. package/dist/components/overlay.js +2 -2
  170. package/dist/components/overlay.js.map +1 -1
  171. package/dist/components/page-header.d.ts +3 -1
  172. package/dist/components/page-header.js +12 -12
  173. package/dist/components/page-header.js.map +1 -1
  174. package/dist/components/pagination.js +3 -3
  175. package/dist/components/pagination.js.map +1 -1
  176. package/dist/components/popover.js +18 -23
  177. package/dist/components/popover.js.map +1 -1
  178. package/dist/components/prompt-bar.d.ts +16 -0
  179. package/dist/components/prompt-bar.js +49 -0
  180. package/dist/components/prompt-bar.js.map +1 -0
  181. package/dist/components/radio.js +9 -9
  182. package/dist/components/radio.js.map +1 -1
  183. package/dist/components/recommendation-card.d.ts +13 -0
  184. package/dist/components/recommendation-card.js +123 -0
  185. package/dist/components/recommendation-card.js.map +1 -0
  186. package/dist/components/resource-list.js +1 -1
  187. package/dist/components/resource-list.js.map +1 -1
  188. package/dist/components/responsive-master-detail.js +4 -4
  189. package/dist/components/responsive-master-detail.js.map +1 -1
  190. package/dist/components/scroll-area.js +3 -3
  191. package/dist/components/scroll-area.js.map +1 -1
  192. package/dist/components/section-rule.d.ts +5 -3
  193. package/dist/components/section-rule.js +12 -12
  194. package/dist/components/section-rule.js.map +1 -1
  195. package/dist/components/segment-control.js +3 -3
  196. package/dist/components/segment-control.js.map +1 -1
  197. package/dist/components/select.js +47 -32
  198. package/dist/components/select.js.map +1 -1
  199. package/dist/components/sensitive-input.js +17 -19
  200. package/dist/components/sensitive-input.js.map +1 -1
  201. package/dist/components/sheet.d.ts +4 -4
  202. package/dist/components/sheet.js +11 -10
  203. package/dist/components/sheet.js.map +1 -1
  204. package/dist/components/sidebar.js +146 -137
  205. package/dist/components/sidebar.js.map +1 -1
  206. package/dist/components/skeleton-line.d.ts +1 -1
  207. package/dist/components/skeleton-line.js +2 -2
  208. package/dist/components/skeleton-line.js.map +1 -1
  209. package/dist/components/slider.js +2 -2
  210. package/dist/components/slider.js.map +1 -1
  211. package/dist/components/stat-strip.js +5 -4
  212. package/dist/components/stat-strip.js.map +1 -1
  213. package/dist/components/switch.js +6 -6
  214. package/dist/components/switch.js.map +1 -1
  215. package/dist/components/table-of-contents.js +5 -5
  216. package/dist/components/table-of-contents.js.map +1 -1
  217. package/dist/components/table-pager.js +2 -2
  218. package/dist/components/table-pager.js.map +1 -1
  219. package/dist/components/table.js +4 -4
  220. package/dist/components/table.js.map +1 -1
  221. package/dist/components/tabs.js +7 -6
  222. package/dist/components/tabs.js.map +1 -1
  223. package/dist/components/tag-badge.d.ts +10 -10
  224. package/dist/components/tag-badge.js +11 -11
  225. package/dist/components/tag-badge.js.map +1 -1
  226. package/dist/components/tag-color-picker.d.ts +8 -1
  227. package/dist/components/tag-color-picker.js +33 -25
  228. package/dist/components/tag-color-picker.js.map +1 -1
  229. package/dist/components/text.js +5 -5
  230. package/dist/components/text.js.map +1 -1
  231. package/dist/components/theme-toggle.js +1 -1
  232. package/dist/components/theme-toggle.js.map +1 -1
  233. package/dist/components/thinking.d.ts +16 -0
  234. package/dist/components/thinking.js +85 -0
  235. package/dist/components/thinking.js.map +1 -0
  236. package/dist/components/toast.js +25 -20
  237. package/dist/components/toast.js.map +1 -1
  238. package/dist/components/toggle-group.js +6 -5
  239. package/dist/components/toggle-group.js.map +1 -1
  240. package/dist/components/toggle.js +6 -6
  241. package/dist/components/toggle.js.map +1 -1
  242. package/dist/components/tool-chips.d.ts +12 -0
  243. package/dist/components/tool-chips.js +138 -0
  244. package/dist/components/tool-chips.js.map +1 -0
  245. package/dist/components/toolbar.js +3 -3
  246. package/dist/components/toolbar.js.map +1 -1
  247. package/dist/components/tooltip.js +1 -1
  248. package/dist/components/tooltip.js.map +1 -1
  249. package/dist/components/typeahead-field.js +59 -56
  250. package/dist/components/typeahead-field.js.map +1 -1
  251. package/dist/components/upload-queue.js +15 -14
  252. package/dist/components/upload-queue.js.map +1 -1
  253. package/dist/models/agent-feedback.d.ts +44 -0
  254. package/dist/models/agent-feedback.js +28 -0
  255. package/dist/models/agent-feedback.js.map +1 -0
  256. package/dist/models/avatar.d.ts +2 -0
  257. package/dist/models/avatar.js +15 -0
  258. package/dist/models/avatar.js.map +1 -0
  259. package/dist/models/code.d.ts +6 -0
  260. package/dist/models/code.js +24 -0
  261. package/dist/models/code.js.map +1 -0
  262. package/dist/models/context-cards.d.ts +13 -0
  263. package/dist/models/context-cards.js +17 -0
  264. package/dist/models/context-cards.js.map +1 -0
  265. package/dist/models/diff-table.d.ts +12 -0
  266. package/dist/models/diff-table.js +9 -0
  267. package/dist/models/diff-table.js.map +1 -0
  268. package/dist/models/recommendation.d.ts +26 -0
  269. package/dist/models/recommendation.js +23 -0
  270. package/dist/models/recommendation.js.map +1 -0
  271. package/dist/styles/base.css +14 -2
  272. package/dist/styles/standalone.css +1865 -929
  273. package/dist/styles/tailwind.css +179 -13
  274. package/dist/styles/tokens.css +679 -20
  275. package/dist/utils/cn.js +25 -4
  276. package/dist/utils/cn.js.map +1 -1
  277. package/dist/utils/control-surface.d.ts +1 -1
  278. package/dist/utils/control-surface.js +1 -1
  279. package/dist/utils/control-surface.js.map +1 -1
  280. package/dist/utils/navigation.d.ts +3 -0
  281. package/dist/utils/navigation.js +8 -0
  282. package/dist/utils/navigation.js.map +1 -0
  283. package/dist/utils/selection-indicator.d.ts +1 -1
  284. package/dist/utils/selection-indicator.js +49 -72
  285. package/dist/utils/selection-indicator.js.map +1 -1
  286. package/dist/utils/use-hover-highlight.d.ts +4 -0
  287. package/dist/utils/use-hover-highlight.js +80 -0
  288. package/dist/utils/use-hover-highlight.js.map +1 -0
  289. package/dist/viewmodels/use-approval-card.d.ts +20 -0
  290. package/dist/viewmodels/use-approval-card.js +83 -0
  291. package/dist/viewmodels/use-approval-card.js.map +1 -0
  292. package/dist/viewmodels/use-chat-composer.d.ts +16 -0
  293. package/dist/viewmodels/use-chat-composer.js +34 -0
  294. package/dist/viewmodels/use-chat-composer.js.map +1 -0
  295. package/dist/viewmodels/use-chat-message.d.ts +16 -0
  296. package/dist/viewmodels/use-chat-message.js +26 -0
  297. package/dist/viewmodels/use-chat-message.js.map +1 -0
  298. package/dist/viewmodels/use-code-block.d.ts +8 -0
  299. package/dist/viewmodels/use-code-block.js +38 -0
  300. package/dist/viewmodels/use-code-block.js.map +1 -0
  301. package/dist/viewmodels/use-context-cards.d.ts +17 -0
  302. package/dist/viewmodels/use-context-cards.js +18 -0
  303. package/dist/viewmodels/use-context-cards.js.map +1 -0
  304. package/dist/viewmodels/use-diff-table.d.ts +16 -0
  305. package/dist/viewmodels/use-diff-table.js +42 -0
  306. package/dist/viewmodels/use-diff-table.js.map +1 -0
  307. package/dist/viewmodels/use-loader.d.ts +4 -0
  308. package/dist/viewmodels/use-loader.js +22 -0
  309. package/dist/viewmodels/use-loader.js.map +1 -0
  310. package/dist/viewmodels/use-recommendation-card.d.ts +17 -0
  311. package/dist/viewmodels/use-recommendation-card.js +41 -0
  312. package/dist/viewmodels/use-recommendation-card.js.map +1 -0
  313. package/dist/viewmodels/use-thinking.d.ts +13 -0
  314. package/dist/viewmodels/use-thinking.js +18 -0
  315. package/dist/viewmodels/use-thinking.js.map +1 -0
  316. package/dist/viewmodels/use-tool-chips.d.ts +10 -0
  317. package/dist/viewmodels/use-tool-chips.js +20 -0
  318. package/dist/viewmodels/use-tool-chips.js.map +1 -0
  319. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"typeahead-field.js","names":["PopoverPrimitive","TypeaheadField","ariaLabel","ariaDescribedBy","ariaInvalid","rest","uncontrolled","setUncontrolled","useState","defaultValue","selected","value","query","setQuery","displayOf","items","prevValue","setPrevValue","open","setOpen","active","setActive","listId","useId","inputRef","useRef","skipFocusOpen","lastPointerPos","selectedDisplay","prevDisplay","setPrevDisplay","latestConfigRef","useEffect","form","disposed","timers","onReset","timer","event","cfg","filtered","filterItems","allowFreeform","activeIndex","activeItem","listOpen","busy","disabled","loading","optionElement","nextLen","current","commitValue","next","display","onValueChange","restoreFocus","commitItem","item","commitFreeform","trimmed","text","match","onKey","nextOpen","cn","className","related","listbox","name","Input","id","placeholder","evt","target","overlayPanelClass","index","overlayItemClass","clientX","clientY","needle","showAllWhenEmpty"],"sources":["../../src/components/typeahead-field.tsx"],"sourcesContent":["import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { type ComponentPropsWithoutRef, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { Input, type InputSize } from \"./input\";\nimport { OVERLAY_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\nexport type TypeaheadItem = {\n\tvalue: string;\n\tlabel: string;\n\tdisabled?: boolean;\n};\n\nexport function TypeaheadField({\n\titems,\n\tvalue,\n\tdefaultValue = \"\",\n\tonValueChange,\n\tname,\n\tplaceholder = \"Select…\",\n\tdisabled = false,\n\tloading = false,\n\tsize = \"default\",\n\tclassName,\n\tid,\n\tallowFreeform,\n\t\"aria-label\": ariaLabel,\n\t\"aria-describedby\": ariaDescribedBy,\n\t\"aria-invalid\": ariaInvalid,\n\tonBlur,\n\t...rest\n}: {\n\titems: TypeaheadItem[];\n\tvalue?: string;\n\tdefaultValue?: string;\n\tonValueChange?: (value: string) => void;\n\tname?: string;\n\tplaceholder?: string;\n\tdisabled?: boolean;\n\tloading?: boolean;\n\tsize?: InputSize;\n\tclassName?: string;\n\tid?: string;\n\tallowFreeform: boolean;\n\t\"aria-label\"?: string;\n\t\"aria-describedby\"?: string;\n\t\"aria-invalid\"?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\";\n} & Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"defaultValue\" | \"onChange\">) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultValue);\n\tconst selected = value ?? uncontrolled;\n\tconst [query, setQuery] = useState(displayOf(items, selected));\n\tconst [prevValue, setPrevValue] = useState(value);\n\tconst [open, setOpen] = useState(false);\n\tconst [active, setActive] = useState<number | null>(null);\n\tconst listId = useId();\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\tconst skipFocusOpen = useRef(false);\n\tconst lastPointerPos = useRef<{ x: number; y: number } | null>(null);\n\tif (value !== prevValue) {\n\t\tsetPrevValue(value);\n\t\tif (value !== undefined) {\n\t\t\tsetQuery(displayOf(items, value));\n\t\t} else if (prevValue !== undefined) {\n\t\t\tsetUncontrolled(prevValue);\n\t\t\tsetQuery(displayOf(items, prevValue));\n\t\t}\n\t}\n\tconst selectedDisplay = displayOf(items, selected);\n\tconst [prevDisplay, setPrevDisplay] = useState(selectedDisplay);\n\tif (selectedDisplay !== prevDisplay) {\n\t\tsetPrevDisplay(selectedDisplay);\n\t\tif (!open || query === prevDisplay) {\n\t\t\tsetQuery(selectedDisplay);\n\t\t}\n\t}\n\tconst latestConfigRef = useRef({\n\t\tdefaultValue,\n\t\titems,\n\t\tvalue,\n\t});\n\tuseEffect(() => {\n\t\tlatestConfigRef.current = {\n\t\t\tdefaultValue,\n\t\t\titems,\n\t\t\tvalue,\n\t\t};\n\t});\n\n\tuseEffect(() => {\n\t\tconst node = inputRef.current;\n\t\tconst form = node?.form;\n\t\tif (!form) {\n\t\t\treturn;\n\t\t}\n\t\tlet disposed = false;\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tconst onReset = (event: Event) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer);\n\t\t\t\tif (disposed || event.defaultPrevented) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst cfg = latestConfigRef.current;\n\t\t\t\tif (cfg.value === undefined) {\n\t\t\t\t\tsetUncontrolled(cfg.defaultValue);\n\t\t\t\t\tsetQuery(displayOf(cfg.items, cfg.defaultValue));\n\t\t\t\t} else {\n\t\t\t\t\tsetQuery(displayOf(cfg.items, cfg.value));\n\t\t\t\t}\n\t\t\t\tsetOpen(false);\n\t\t\t\tsetActive(null);\n\t\t\t}, 0);\n\t\t\ttimers.add(timer);\n\t\t};\n\t\tform.addEventListener(\"reset\", onReset);\n\t\treturn () => {\n\t\t\tdisposed = true;\n\t\t\tfor (const timer of timers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\ttimers.clear();\n\t\t\tform.removeEventListener(\"reset\", onReset);\n\t\t};\n\t}, []);\n\tconst filtered = filterItems(items, query, !allowFreeform);\n\tconst activeIndex =\n\t\tactive === null || filtered.length === 0 ? null : Math.min(active, filtered.length - 1);\n\tconst activeItem = activeIndex === null ? undefined : filtered[activeIndex];\n\tconst listOpen = open && filtered.length > 0;\n\tconst busy = disabled || loading;\n\n\tuseEffect(() => {\n\t\tif (!listOpen || activeIndex === null) {\n\t\t\treturn;\n\t\t}\n\t\tconst optionElement = document.getElementById(`${listId}-opt-${activeIndex}`);\n\t\tif (typeof optionElement?.scrollIntoView === \"function\") {\n\t\t\toptionElement.scrollIntoView({ block: \"nearest\" });\n\t\t}\n\t}, [activeIndex, listId, listOpen]);\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\treturn;\n\t\t}\n\t\tconst nextLen = filterItems(items, query, !allowFreeform).length;\n\t\tsetActive((current) => {\n\t\t\tif (current === null || nextLen === 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn Math.min(current, nextLen - 1);\n\t\t});\n\t}, [allowFreeform, items, open, query]);\n\n\tfunction commitValue(next: string, display: string, restoreFocus = true) {\n\t\tif (value === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t\tsetQuery(display);\n\t\t} else {\n\t\t\tsetQuery(displayOf(items, value));\n\t\t}\n\t\tsetOpen(false);\n\t\tsetActive(null);\n\t\tonValueChange?.(next);\n\t\tif (restoreFocus && inputRef.current && document.activeElement !== inputRef.current) {\n\t\t\tskipFocusOpen.current = true;\n\t\t\tinputRef.current.focus();\n\t\t}\n\t}\n\n\tfunction commitItem(item: TypeaheadItem, restoreFocus = true) {\n\t\tif (item.disabled) {\n\t\t\treturn;\n\t\t}\n\t\tcommitValue(item.value, item.label, restoreFocus);\n\t}\n\n\tfunction commitFreeform(text: string, restoreFocus = true) {\n\t\tconst trimmed = text.trim();\n\t\tconst match = items.find(\n\t\t\t(item) =>\n\t\t\t\t!item.disabled &&\n\t\t\t\t(item.label.toLowerCase() === trimmed.toLowerCase() || item.value === trimmed),\n\t\t);\n\t\tif (match) {\n\t\t\tcommitItem(match, restoreFocus);\n\t\t\treturn;\n\t\t}\n\t\tcommitValue(trimmed, trimmed, restoreFocus);\n\t}\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\treturn;\n\t\t}\n\t\tconst onKey = (event: KeyboardEvent) => {\n\t\t\tif (event.key !== \"Escape\" || event.isComposing) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\tevent.stopImmediatePropagation();\n\t\t\tsetOpen(false);\n\t\t\tsetQuery(displayOf(items, selected));\n\t\t\tsetActive(null);\n\t\t};\n\t\twindow.addEventListener(\"keydown\", onKey, true);\n\t\tdocument.addEventListener(\"keydown\", onKey, true);\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"keydown\", onKey, true);\n\t\t\tdocument.removeEventListener(\"keydown\", onKey, true);\n\t\t};\n\t}, [items, open, selected]);\n\n\treturn (\n\t\t<PopoverPrimitive.Root\n\t\t\topen={listOpen}\n\t\t\tonOpenChange={(nextOpen) => {\n\t\t\t\tif (!nextOpen) {\n\t\t\t\t\tsetOpen(false);\n\t\t\t\t\tsetActive(null);\n\t\t\t\t\tif (!allowFreeform) {\n\t\t\t\t\t\tsetQuery(displayOf(items, selected));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\t{...rest}\n\t\t\t\tclassName={cn(\"relative w-full\", className)}\n\t\t\t\tonBlur={(event) => {\n\t\t\t\t\tonBlur?.(event);\n\t\t\t\t\tconst related = event.relatedTarget as Node | null;\n\t\t\t\t\tconst listbox = document.getElementById(listId);\n\t\t\t\t\tif (!event.currentTarget.contains(related) && !listbox?.contains(related)) {\n\t\t\t\t\t\tif (allowFreeform) {\n\t\t\t\t\t\t\tif (query.trim() !== displayOf(items, selected)) {\n\t\t\t\t\t\t\t\tcommitFreeform(query, false);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsetQuery(displayOf(items, selected));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{name ? <input type=\"hidden\" name={name} value={selected} disabled={busy} /> : null}\n\t\t\t\t<PopoverPrimitive.Anchor asChild>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={inputRef}\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\taria-busy={loading || undefined}\n\t\t\t\t\t\taria-invalid={ariaInvalid}\n\t\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tsetQuery(event.target.value);\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\tif (busy) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (skipFocusOpen.current) {\n\t\t\t\t\t\t\t\tskipFocusOpen.current = false;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tif (busy) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!open) {\n\t\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing || event.key === \"Process\") {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\t\tif (filtered.length === 0) {\n\t\t\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tsetActive((current) => (current === null ? 0 : (current + 1) % filtered.length));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\t\tif (filtered.length === 0) {\n\t\t\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tsetActive((current) =>\n\t\t\t\t\t\t\t\t\tcurrent === null\n\t\t\t\t\t\t\t\t\t\t? filtered.length - 1\n\t\t\t\t\t\t\t\t\t\t: (current - 1 + filtered.length) % filtered.length,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tif (open && activeItem) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tcommitItem(activeItem);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (allowFreeform && query.trim() !== displayOf(items, selected)) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tcommitFreeform(query);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-label={ariaLabel ?? (id ? undefined : placeholder)}\n\t\t\t\t\t\taria-expanded={listOpen}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\taria-controls={listOpen ? listId : undefined}\n\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\tlistOpen && activeItem && activeIndex !== null\n\t\t\t\t\t\t\t\t? `${listId}-opt-${activeIndex}`\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</PopoverPrimitive.Anchor>\n\t\t\t\t{listOpen ? (\n\t\t\t\t\t<PopoverPrimitive.Portal>\n\t\t\t\t\t\t<PopoverPrimitive.Content\n\t\t\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\t\t\tsideOffset={OVERLAY_GAP}\n\t\t\t\t\t\t\talign=\"start\"\n\t\t\t\t\t\t\tavoidCollisions\n\t\t\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\tlastPointerPos.current &&\n\t\t\t\t\t\t\t\t\tlastPointerPos.current.x === event.clientX &&\n\t\t\t\t\t\t\t\t\tlastPointerPos.current.y === event.clientY\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tlastPointerPos.current = { x: event.clientX, y: event.clientY };\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonEscapeKeyDown={(e) => {\n\t\t\t\t\t\t\t\tconst evt = e as unknown as {\n\t\t\t\t\t\t\t\t\tisComposing?: boolean;\n\t\t\t\t\t\t\t\t\tnativeEvent?: { isComposing?: boolean };\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tif (evt.isComposing || evt.nativeEvent?.isComposing) {\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonOpenAutoFocus={(e) => e.preventDefault()}\n\t\t\t\t\t\t\tonCloseAutoFocus={(e) => e.preventDefault()}\n\t\t\t\t\t\t\tonInteractOutside={(e) => {\n\t\t\t\t\t\t\t\tconst target = e.target as Node | null;\n\t\t\t\t\t\t\t\tif (inputRef.current?.contains(target)) {\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tid={listId}\n\t\t\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\t\t\tclassName={overlayPanelClass(\n\t\t\t\t\t\t\t\t\"w-[var(--radix-popover-trigger-width)] max-h-[var(--radix-popover-content-available-height)] overflow-y-auto\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{filtered.map((item, index) => (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tkey={`${listId}-opt-${index}`}\n\t\t\t\t\t\t\t\t\tid={`${listId}-opt-${index}`}\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\tdisabled={item.disabled}\n\t\t\t\t\t\t\t\t\taria-disabled={item.disabled || undefined}\n\t\t\t\t\t\t\t\t\taria-selected={index === activeIndex}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\toverlayItemClass(\"hover:bg-basalt-accent\"),\n\t\t\t\t\t\t\t\t\t\tindex === activeIndex && \"bg-basalt-accent\",\n\t\t\t\t\t\t\t\t\t\titem.disabled && \"opacity-50\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\t\t\tif (item.disabled) {\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tconst { clientX, clientY } = event;\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tlastPointerPos.current &&\n\t\t\t\t\t\t\t\t\t\t\tlastPointerPos.current.x === clientX &&\n\t\t\t\t\t\t\t\t\t\t\tlastPointerPos.current.y === clientY\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tlastPointerPos.current = { x: clientX, y: clientY };\n\t\t\t\t\t\t\t\t\t\tsetActive(index);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\t\t\t\tonClick={() => commitItem(item)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</PopoverPrimitive.Content>\n\t\t\t\t\t</PopoverPrimitive.Portal>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t</PopoverPrimitive.Root>\n\t);\n}\n\nfunction displayOf(items: TypeaheadItem[], value: string) {\n\treturn items.find((item) => item.value === value)?.label ?? value;\n}\n\nfunction filterItems(items: TypeaheadItem[], query: string, showAllWhenEmpty: boolean) {\n\tconst needle = query.trim().toLowerCase();\n\tif (needle === \"\") {\n\t\treturn showAllWhenEmpty ? items : [];\n\t}\n\treturn items.filter((item) => item.label.toLowerCase().includes(needle));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"typeahead-field.js","names":["PopoverPrimitive","TypeaheadField","ariaLabel","ariaDescribedBy","ariaInvalid","rest","uncontrolled","setUncontrolled","useState","defaultValue","selected","value","query","setQuery","displayOf","items","prevValue","setPrevValue","open","setOpen","active","setActive","listId","useId","inputRef","useRef","highlightRef","useHoverHighlight","skipFocusOpen","lastPointerPos","selectedDisplay","prevDisplay","setPrevDisplay","latestConfigRef","useEffect","form","disposed","timers","onReset","timer","event","cfg","filtered","filterItems","allowFreeform","activeIndex","activeItem","listOpen","busy","disabled","loading","optionElement","nextLen","current","commitValue","next","display","onValueChange","restoreFocus","commitItem","item","commitFreeform","trimmed","text","match","onKey","nextOpen","cn","className","related","listbox","name","Input","id","placeholder","evt","target","overlayPanelClass","index","overlayItemClass","clientX","clientY","needle","showAllWhenEmpty"],"sources":["../../src/components/typeahead-field.tsx"],"sourcesContent":["import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { type ComponentPropsWithoutRef, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { Input, type InputSize } from \"./input\";\nimport { OVERLAY_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\nexport type TypeaheadItem = {\n\tvalue: string;\n\tlabel: string;\n\tdisabled?: boolean;\n};\n\nexport function TypeaheadField({\n\titems,\n\tvalue,\n\tdefaultValue = \"\",\n\tonValueChange,\n\tname,\n\tplaceholder = \"Select…\",\n\tdisabled = false,\n\tloading = false,\n\tsize = \"default\",\n\tclassName,\n\tid,\n\tallowFreeform,\n\t\"aria-label\": ariaLabel,\n\t\"aria-describedby\": ariaDescribedBy,\n\t\"aria-invalid\": ariaInvalid,\n\tonBlur,\n\t...rest\n}: {\n\titems: TypeaheadItem[];\n\tvalue?: string;\n\tdefaultValue?: string;\n\tonValueChange?: (value: string) => void;\n\tname?: string;\n\tplaceholder?: string;\n\tdisabled?: boolean;\n\tloading?: boolean;\n\tsize?: InputSize;\n\tclassName?: string;\n\tid?: string;\n\tallowFreeform: boolean;\n\t\"aria-label\"?: string;\n\t\"aria-describedby\"?: string;\n\t\"aria-invalid\"?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\";\n} & Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"defaultValue\" | \"onChange\">) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultValue);\n\tconst selected = value ?? uncontrolled;\n\tconst [query, setQuery] = useState(displayOf(items, selected));\n\tconst [prevValue, setPrevValue] = useState(value);\n\tconst [open, setOpen] = useState(false);\n\tconst [active, setActive] = useState<number | null>(null);\n\tconst listId = useId();\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\tconst highlightRef = useHoverHighlight();\n\tconst skipFocusOpen = useRef(false);\n\tconst lastPointerPos = useRef<{ x: number; y: number } | null>(null);\n\tif (value !== prevValue) {\n\t\tsetPrevValue(value);\n\t\tif (value !== undefined) {\n\t\t\tsetQuery(displayOf(items, value));\n\t\t} else if (prevValue !== undefined) {\n\t\t\tsetUncontrolled(prevValue);\n\t\t\tsetQuery(displayOf(items, prevValue));\n\t\t}\n\t}\n\tconst selectedDisplay = displayOf(items, selected);\n\tconst [prevDisplay, setPrevDisplay] = useState(selectedDisplay);\n\tif (selectedDisplay !== prevDisplay) {\n\t\tsetPrevDisplay(selectedDisplay);\n\t\tif (!open || query === prevDisplay) {\n\t\t\tsetQuery(selectedDisplay);\n\t\t}\n\t}\n\tconst latestConfigRef = useRef({\n\t\tdefaultValue,\n\t\titems,\n\t\tvalue,\n\t});\n\tuseEffect(() => {\n\t\tlatestConfigRef.current = {\n\t\t\tdefaultValue,\n\t\t\titems,\n\t\t\tvalue,\n\t\t};\n\t});\n\n\tuseEffect(() => {\n\t\tconst node = inputRef.current;\n\t\tconst form = node?.form;\n\t\tif (!form) {\n\t\t\treturn;\n\t\t}\n\t\tlet disposed = false;\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tconst onReset = (event: Event) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer);\n\t\t\t\tif (disposed || event.defaultPrevented) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst cfg = latestConfigRef.current;\n\t\t\t\tif (cfg.value === undefined) {\n\t\t\t\t\tsetUncontrolled(cfg.defaultValue);\n\t\t\t\t\tsetQuery(displayOf(cfg.items, cfg.defaultValue));\n\t\t\t\t} else {\n\t\t\t\t\tsetQuery(displayOf(cfg.items, cfg.value));\n\t\t\t\t}\n\t\t\t\tsetOpen(false);\n\t\t\t\tsetActive(null);\n\t\t\t}, 0);\n\t\t\ttimers.add(timer);\n\t\t};\n\t\tform.addEventListener(\"reset\", onReset);\n\t\treturn () => {\n\t\t\tdisposed = true;\n\t\t\tfor (const timer of timers) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\ttimers.clear();\n\t\t\tform.removeEventListener(\"reset\", onReset);\n\t\t};\n\t}, []);\n\tconst filtered = filterItems(items, query, !allowFreeform);\n\tconst activeIndex =\n\t\tactive === null || filtered.length === 0 ? null : Math.min(active, filtered.length - 1);\n\tconst activeItem = activeIndex === null ? undefined : filtered[activeIndex];\n\tconst listOpen = open && filtered.length > 0;\n\tconst busy = disabled || loading;\n\n\tuseEffect(() => {\n\t\tif (!listOpen || activeIndex === null) {\n\t\t\treturn;\n\t\t}\n\t\tconst optionElement = document.getElementById(`${listId}-opt-${activeIndex}`);\n\t\tif (typeof optionElement?.scrollIntoView === \"function\") {\n\t\t\toptionElement.scrollIntoView({ block: \"nearest\" });\n\t\t}\n\t}, [activeIndex, listId, listOpen]);\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\treturn;\n\t\t}\n\t\tconst nextLen = filterItems(items, query, !allowFreeform).length;\n\t\tsetActive((current) => {\n\t\t\tif (current === null || nextLen === 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn Math.min(current, nextLen - 1);\n\t\t});\n\t}, [allowFreeform, items, open, query]);\n\n\tfunction commitValue(next: string, display: string, restoreFocus = true) {\n\t\tif (value === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t\tsetQuery(display);\n\t\t} else {\n\t\t\tsetQuery(displayOf(items, value));\n\t\t}\n\t\tsetOpen(false);\n\t\tsetActive(null);\n\t\tonValueChange?.(next);\n\t\tif (restoreFocus && inputRef.current && document.activeElement !== inputRef.current) {\n\t\t\tskipFocusOpen.current = true;\n\t\t\tinputRef.current.focus();\n\t\t}\n\t}\n\n\tfunction commitItem(item: TypeaheadItem, restoreFocus = true) {\n\t\tif (item.disabled) {\n\t\t\treturn;\n\t\t}\n\t\tcommitValue(item.value, item.label, restoreFocus);\n\t}\n\n\tfunction commitFreeform(text: string, restoreFocus = true) {\n\t\tconst trimmed = text.trim();\n\t\tconst match = items.find(\n\t\t\t(item) =>\n\t\t\t\t!item.disabled &&\n\t\t\t\t(item.label.toLowerCase() === trimmed.toLowerCase() || item.value === trimmed),\n\t\t);\n\t\tif (match) {\n\t\t\tcommitItem(match, restoreFocus);\n\t\t\treturn;\n\t\t}\n\t\tcommitValue(trimmed, trimmed, restoreFocus);\n\t}\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\treturn;\n\t\t}\n\t\tconst onKey = (event: KeyboardEvent) => {\n\t\t\tif (event.key !== \"Escape\" || event.isComposing) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\tevent.stopImmediatePropagation();\n\t\t\tsetOpen(false);\n\t\t\tsetQuery(displayOf(items, selected));\n\t\t\tsetActive(null);\n\t\t};\n\t\twindow.addEventListener(\"keydown\", onKey, true);\n\t\tdocument.addEventListener(\"keydown\", onKey, true);\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"keydown\", onKey, true);\n\t\t\tdocument.removeEventListener(\"keydown\", onKey, true);\n\t\t};\n\t}, [items, open, selected]);\n\n\treturn (\n\t\t<PopoverPrimitive.Root\n\t\t\topen={listOpen}\n\t\t\tonOpenChange={(nextOpen) => {\n\t\t\t\tif (!nextOpen) {\n\t\t\t\t\tsetOpen(false);\n\t\t\t\t\tsetActive(null);\n\t\t\t\t\tif (!allowFreeform) {\n\t\t\t\t\t\tsetQuery(displayOf(items, selected));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\t{...rest}\n\t\t\t\tclassName={cn(\"relative w-full\", className)}\n\t\t\t\tonBlur={(event) => {\n\t\t\t\t\tonBlur?.(event);\n\t\t\t\t\tconst related = event.relatedTarget as Node | null;\n\t\t\t\t\tconst listbox = document.getElementById(listId);\n\t\t\t\t\tif (!event.currentTarget.contains(related) && !listbox?.contains(related)) {\n\t\t\t\t\t\tif (allowFreeform) {\n\t\t\t\t\t\t\tif (query.trim() !== displayOf(items, selected)) {\n\t\t\t\t\t\t\t\tcommitFreeform(query, false);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsetQuery(displayOf(items, selected));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{name ? <input type=\"hidden\" name={name} value={selected} disabled={busy} /> : null}\n\t\t\t\t<PopoverPrimitive.Anchor asChild>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={inputRef}\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tsize={size}\n\t\t\t\t\t\taria-busy={loading || undefined}\n\t\t\t\t\t\taria-invalid={ariaInvalid}\n\t\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tsetQuery(event.target.value);\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonFocus={() => {\n\t\t\t\t\t\t\tif (busy) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (skipFocusOpen.current) {\n\t\t\t\t\t\t\t\tskipFocusOpen.current = false;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tif (busy) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!open) {\n\t\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing || event.key === \"Process\") {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\t\tif (filtered.length === 0) {\n\t\t\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tsetActive((current) => (current === null ? 0 : (current + 1) % filtered.length));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\t\tif (filtered.length === 0) {\n\t\t\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tsetActive((current) =>\n\t\t\t\t\t\t\t\t\tcurrent === null\n\t\t\t\t\t\t\t\t\t\t? filtered.length - 1\n\t\t\t\t\t\t\t\t\t\t: (current - 1 + filtered.length) % filtered.length,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tif (open && activeItem) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tcommitItem(activeItem);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (allowFreeform && query.trim() !== displayOf(items, selected)) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tcommitFreeform(query);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-label={ariaLabel ?? (id ? undefined : placeholder)}\n\t\t\t\t\t\taria-expanded={listOpen}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\taria-controls={listOpen ? listId : undefined}\n\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\tlistOpen && activeItem && activeIndex !== null\n\t\t\t\t\t\t\t\t? `${listId}-opt-${activeIndex}`\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</PopoverPrimitive.Anchor>\n\t\t\t\t<PopoverPrimitive.Portal>\n\t\t\t\t\t<PopoverPrimitive.Content\n\t\t\t\t\t\tref={highlightRef}\n\t\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\t\tsideOffset={OVERLAY_GAP}\n\t\t\t\t\t\talign=\"start\"\n\t\t\t\t\t\tavoidCollisions\n\t\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tlastPointerPos.current &&\n\t\t\t\t\t\t\t\tlastPointerPos.current.x === event.clientX &&\n\t\t\t\t\t\t\t\tlastPointerPos.current.y === event.clientY\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlastPointerPos.current = { x: event.clientX, y: event.clientY };\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonEscapeKeyDown={(e) => {\n\t\t\t\t\t\t\tconst evt = e as unknown as {\n\t\t\t\t\t\t\t\tisComposing?: boolean;\n\t\t\t\t\t\t\t\tnativeEvent?: { isComposing?: boolean };\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tif (evt.isComposing || evt.nativeEvent?.isComposing) {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(e) => e.preventDefault()}\n\t\t\t\t\t\tonCloseAutoFocus={(e) => e.preventDefault()}\n\t\t\t\t\t\tonInteractOutside={(e) => {\n\t\t\t\t\t\t\tconst target = e.target as Node | null;\n\t\t\t\t\t\t\tif (inputRef.current?.contains(target)) {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tid={listId}\n\t\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\t\tclassName={overlayPanelClass(\n\t\t\t\t\t\t\t\"basalt-hover-list w-[var(--radix-popover-trigger-width)] max-h-[var(--radix-popover-content-available-height)] overflow-y-auto\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{filtered.map((item, index) => (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tkey={`${listId}-opt-${index}`}\n\t\t\t\t\t\t\t\tid={`${listId}-opt-${index}`}\n\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\tdata-basalt-hover-item=\"\"\n\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\tdisabled={item.disabled}\n\t\t\t\t\t\t\t\taria-disabled={item.disabled || undefined}\n\t\t\t\t\t\t\t\taria-selected={index === activeIndex}\n\t\t\t\t\t\t\t\tclassName={cn(overlayItemClass(), item.disabled && \"opacity-50\")}\n\t\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\t\tif (item.disabled) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst { clientX, clientY } = event;\n\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\tlastPointerPos.current &&\n\t\t\t\t\t\t\t\t\t\tlastPointerPos.current.x === clientX &&\n\t\t\t\t\t\t\t\t\t\tlastPointerPos.current.y === clientY\n\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tlastPointerPos.current = { x: clientX, y: clientY };\n\t\t\t\t\t\t\t\t\tsetActive(index);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\t\t\tonClick={() => commitItem(item)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</PopoverPrimitive.Content>\n\t\t\t\t</PopoverPrimitive.Portal>\n\t\t\t</div>\n\t\t</PopoverPrimitive.Root>\n\t);\n}\n\nfunction displayOf(items: TypeaheadItem[], value: string) {\n\treturn items.find((item) => item.value === value)?.label ?? value;\n}\n\nfunction filterItems(items: TypeaheadItem[], query: string, showAllWhenEmpty: boolean) {\n\tconst needle = query.trim().toLowerCase();\n\tif (needle === \"\") {\n\t\treturn showAllWhenEmpty ? items : [];\n\t}\n\treturn items.filter((item) => item.label.toLowerCase().includes(needle));\n}\n"],"mappings":"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"}
@@ -21,24 +21,25 @@ function d({ file: d, onCancel: f, onRetry: p, onRemove: m, labels: h, className
21
21
  ...h
22
22
  }, v = typeof d.progress == "number" && Number.isFinite(d.progress) ? Math.max(0, Math.min(100, d.progress)) : void 0, y = d.status === "queued" || d.status === "uploading";
23
23
  return /* @__PURE__ */ l("div", {
24
- className: e(t, "flex min-w-0 items-start gap-3 rounded-basalt-lg border border-basalt-border bg-basalt-card p-3", g),
24
+ "data-basalt-surface": "",
25
+ className: e(t, "flex min-w-0 items-start gap-basalt-space-lg rounded-basalt-lg border border-basalt-border p-basalt-card-sm", g),
25
26
  children: [
26
27
  /* @__PURE__ */ c("span", {
27
- className: "flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-basalt-md bg-basalt-accent",
28
+ className: "flex size-basalt-10 shrink-0 items-center justify-center overflow-hidden rounded-basalt-md bg-basalt-accent",
28
29
  children: d.preview ?? /* @__PURE__ */ c(i, {
29
- className: "size-5 text-basalt-muted-foreground",
30
+ className: "size-basalt-5 text-basalt-muted-foreground",
30
31
  "aria-hidden": "true"
31
32
  })
32
33
  }),
33
34
  /* @__PURE__ */ l("div", {
34
- className: "min-w-0 flex-1 space-y-1",
35
+ className: "min-w-0 flex-1 space-y-basalt-space-sm",
35
36
  children: [
36
37
  /* @__PURE__ */ c("p", {
37
- className: "break-words text-sm font-medium",
38
+ className: "break-words text-basalt-base font-medium",
38
39
  children: d.name
39
40
  }),
40
41
  /* @__PURE__ */ l("p", {
41
- className: "text-xs text-basalt-muted-foreground",
42
+ className: "text-basalt-sm text-basalt-muted-foreground",
42
43
  children: [d.size !== void 0 && `${Math.ceil(d.size / 1024).toLocaleString()} KB · `, _[d.status]]
43
44
  }),
44
45
  d.status === "uploading" && /* @__PURE__ */ c("div", {
@@ -47,24 +48,24 @@ function d({ file: d, onCancel: f, onRetry: p, onRemove: m, labels: h, className
47
48
  "aria-valuemin": 0,
48
49
  "aria-valuemax": 100,
49
50
  "aria-valuenow": v,
50
- className: "h-1.5 overflow-hidden rounded-full bg-basalt-accent",
51
+ className: "h-basalt-1_5 overflow-hidden rounded-basalt-full bg-basalt-accent",
51
52
  children: /* @__PURE__ */ c("div", {
52
53
  style: { width: v === void 0 ? "40%" : `${v}%` },
53
- className: e("h-full rounded-full bg-basalt-primary", v === void 0 && "animate-pulse motion-reduce:animate-none")
54
+ className: e("h-full rounded-basalt-full bg-basalt-primary", v === void 0 && "animate-pulse motion-reduce:animate-none")
54
55
  })
55
56
  }),
56
57
  d.status === "error" && d.error && /* @__PURE__ */ c("p", {
57
58
  role: "alert",
58
- className: "break-words text-xs text-basalt-destructive",
59
+ className: "break-words text-basalt-sm text-basalt-destructive",
59
60
  children: d.error
60
61
  })
61
62
  ]
62
63
  }),
63
64
  /* @__PURE__ */ l("div", {
64
- className: "flex shrink-0 items-center gap-1",
65
+ className: "flex shrink-0 items-center gap-basalt-space-sm",
65
66
  children: [
66
67
  d.status === "success" && /* @__PURE__ */ c(r, {
67
- className: "size-4 text-basalt-success",
68
+ className: "size-basalt-icon-lg text-basalt-success",
68
69
  "aria-hidden": "true"
69
70
  }),
70
71
  y && f && /* @__PURE__ */ c(n, {
@@ -95,14 +96,14 @@ function d({ file: d, onCancel: f, onRetry: p, onRemove: m, labels: h, className
95
96
  }
96
97
  function f({ label: n, files: r, emptyLabel: i = "No files selected.", className: a, ...o }) {
97
98
  return /* @__PURE__ */ c("div", {
98
- className: e(t, "min-w-0 space-y-2", a),
99
+ className: e(t, "min-w-0 space-y-basalt-space-lg", a),
99
100
  children: r.length === 0 ? /* @__PURE__ */ c("p", {
100
101
  role: "status",
101
- className: "text-sm text-basalt-muted-foreground",
102
+ className: "text-basalt-base text-basalt-muted-foreground",
102
103
  children: i
103
104
  }) : /* @__PURE__ */ c("ul", {
104
105
  "aria-label": n,
105
- className: "m-0 list-none space-y-2 p-0",
106
+ className: "m-0 list-none space-y-basalt-space-lg p-0",
106
107
  children: r.map((e) => /* @__PURE__ */ c("li", { children: /* @__PURE__ */ c(d, {
107
108
  file: e,
108
109
  ...o
@@ -1 +1 @@
1
- {"version":3,"file":"upload-queue.js","names":["DEFAULT_LABELS","UploadItem","text","labels","progress","file","active","cn","BASALT_UI_CLASS","className","FileText","Check","onCancel","Button","X","onRetry","RotateCcw","onRemove","Trash2","UploadQueue","actions","files","emptyLabel","label"],"sources":["../../src/components/upload-queue.tsx"],"sourcesContent":["import { Check, FileText, RotateCcw, Trash2, X } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nexport interface UploadFile {\n\t/** Stable queue identifier. */\n\tid: string;\n\t/** Display filename. */\n\tname: string;\n\t/** Optional size in bytes. */\n\tsize?: number;\n\t/** Application-owned transport state. */\n\tstatus: \"queued\" | \"uploading\" | \"success\" | \"error\" | \"cancelled\";\n\t/** Progress percentage; omitted means indeterminate. */\n\tprogress?: number;\n\t/** Application's error message. */\n\terror?: string;\n\t/** Optional image/icon. The caller creates and revokes any object URLs. */\n\tpreview?: ReactNode;\n}\nexport interface UploadLabels {\n\tqueued?: string;\n\tuploading?: string;\n\tsuccess?: string;\n\terror?: string;\n\tcancelled?: string;\n\tcancel?: string;\n\tretry?: string;\n\tremove?: string;\n}\nconst DEFAULT_LABELS = {\n\tqueued: \"Queued\",\n\tuploading: \"Uploading\",\n\tsuccess: \"Uploaded\",\n\terror: \"Upload failed\",\n\tcancelled: \"Cancelled\",\n\tcancel: \"Cancel\",\n\tretry: \"Retry\",\n\tremove: \"Remove\",\n};\n\nexport interface UploadItemProps {\n\t/** Current queue entry. The component does not start a network request. */\n\tfile: UploadFile;\n\t/** Cancel a queued or uploading entry. */\n\tonCancel?: (id: string) => void;\n\t/** Retry a failed or cancelled entry. */\n\tonRetry?: (id: string) => void;\n\t/** Remove an entry that is not currently uploading. */\n\tonRemove?: (id: string) => void;\n\t/** Localized statuses and action labels. */\n\tlabels?: UploadLabels;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function UploadItem({\n\tfile,\n\tonCancel,\n\tonRetry,\n\tonRemove,\n\tlabels,\n\tclassName,\n}: UploadItemProps) {\n\tconst text = { ...DEFAULT_LABELS, ...labels };\n\tconst progress =\n\t\ttypeof file.progress === \"number\" && Number.isFinite(file.progress)\n\t\t\t? Math.max(0, Math.min(100, file.progress))\n\t\t\t: undefined;\n\tconst active = file.status === \"queued\" || file.status === \"uploading\";\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex min-w-0 items-start gap-3 rounded-basalt-lg border border-basalt-border bg-basalt-card p-3\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-basalt-md bg-basalt-accent\">\n\t\t\t\t{file.preview ?? (\n\t\t\t\t\t<FileText className=\"size-5 text-basalt-muted-foreground\" aria-hidden=\"true\" />\n\t\t\t\t)}\n\t\t\t</span>\n\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t<p className=\"break-words text-sm font-medium\">{file.name}</p>\n\t\t\t\t<p className=\"text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t{file.size !== undefined && `${Math.ceil(file.size / 1024).toLocaleString()} KB · `}\n\t\t\t\t\t{text[file.status]}\n\t\t\t\t</p>\n\t\t\t\t{file.status === \"uploading\" && (\n\t\t\t\t\t<div\n\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\taria-label={file.name}\n\t\t\t\t\t\taria-valuemin={0}\n\t\t\t\t\t\taria-valuemax={100}\n\t\t\t\t\t\taria-valuenow={progress}\n\t\t\t\t\t\tclassName=\"h-1.5 overflow-hidden rounded-full bg-basalt-accent\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{ width: progress === undefined ? \"40%\" : `${progress}%` }}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"h-full rounded-full bg-basalt-primary\",\n\t\t\t\t\t\t\t\tprogress === undefined && \"animate-pulse motion-reduce:animate-none\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{file.status === \"error\" && file.error && (\n\t\t\t\t\t<p role=\"alert\" className=\"break-words text-xs text-basalt-destructive\">\n\t\t\t\t\t\t{file.error}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<div className=\"flex shrink-0 items-center gap-1\">\n\t\t\t\t{file.status === \"success\" && (\n\t\t\t\t\t<Check className=\"size-4 text-basalt-success\" aria-hidden=\"true\" />\n\t\t\t\t)}\n\t\t\t\t{active && onCancel && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\taria-label={`${text.cancel} ${file.name}`}\n\t\t\t\t\t\tonClick={() => onCancel(file.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t\t{(file.status === \"error\" || file.status === \"cancelled\") && onRetry && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\taria-label={`${text.retry} ${file.name}`}\n\t\t\t\t\t\tonClick={() => onRetry(file.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RotateCcw />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t\t{file.status !== \"uploading\" && onRemove && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\taria-label={`${text.remove} ${file.name}`}\n\t\t\t\t\t\tonClick={() => onRemove(file.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Trash2 />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport interface UploadQueueProps extends Omit<UploadItemProps, \"file\"> {\n\t/** Accessible queue name. */\n\tlabel: string;\n\t/** Application-owned queue entries. */\n\tfiles: readonly UploadFile[];\n\t/** Empty queue text. @default \"No files selected.\" */\n\temptyLabel?: string;\n}\n\nexport function UploadQueue({\n\tlabel,\n\tfiles,\n\temptyLabel = \"No files selected.\",\n\tclassName,\n\t...actions\n}: UploadQueueProps) {\n\treturn (\n\t\t<div className={cn(BASALT_UI_CLASS, \"min-w-0 space-y-2\", className)}>\n\t\t\t{files.length === 0 ? (\n\t\t\t\t<p role=\"status\" className=\"text-sm text-basalt-muted-foreground\">\n\t\t\t\t\t{emptyLabel}\n\t\t\t\t</p>\n\t\t\t) : (\n\t\t\t\t<ul aria-label={label} className=\"m-0 list-none space-y-2 p-0\">\n\t\t\t\t\t{files.map((file) => (\n\t\t\t\t\t\t<li key={file.id}>\n\t\t\t\t\t\t\t<UploadItem file={file} {...actions} />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"upload-queue.js","names":["DEFAULT_LABELS","UploadItem","text","labels","progress","file","active","cn","BASALT_UI_CLASS","className","FileText","Check","onCancel","Button","X","onRetry","RotateCcw","onRemove","Trash2","UploadQueue","actions","files","emptyLabel","label"],"sources":["../../src/components/upload-queue.tsx"],"sourcesContent":["import { Check, FileText, RotateCcw, Trash2, X } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nexport interface UploadFile {\n\t/** Stable queue identifier. */\n\tid: string;\n\t/** Display filename. */\n\tname: string;\n\t/** Optional size in bytes. */\n\tsize?: number;\n\t/** Application-owned transport state. */\n\tstatus: \"queued\" | \"uploading\" | \"success\" | \"error\" | \"cancelled\";\n\t/** Progress percentage; omitted means indeterminate. */\n\tprogress?: number;\n\t/** Application's error message. */\n\terror?: string;\n\t/** Optional image/icon. The caller creates and revokes any object URLs. */\n\tpreview?: ReactNode;\n}\nexport interface UploadLabels {\n\tqueued?: string;\n\tuploading?: string;\n\tsuccess?: string;\n\terror?: string;\n\tcancelled?: string;\n\tcancel?: string;\n\tretry?: string;\n\tremove?: string;\n}\nconst DEFAULT_LABELS = {\n\tqueued: \"Queued\",\n\tuploading: \"Uploading\",\n\tsuccess: \"Uploaded\",\n\terror: \"Upload failed\",\n\tcancelled: \"Cancelled\",\n\tcancel: \"Cancel\",\n\tretry: \"Retry\",\n\tremove: \"Remove\",\n};\n\nexport interface UploadItemProps {\n\t/** Current queue entry. The component does not start a network request. */\n\tfile: UploadFile;\n\t/** Cancel a queued or uploading entry. */\n\tonCancel?: (id: string) => void;\n\t/** Retry a failed or cancelled entry. */\n\tonRetry?: (id: string) => void;\n\t/** Remove an entry that is not currently uploading. */\n\tonRemove?: (id: string) => void;\n\t/** Localized statuses and action labels. */\n\tlabels?: UploadLabels;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function UploadItem({\n\tfile,\n\tonCancel,\n\tonRetry,\n\tonRemove,\n\tlabels,\n\tclassName,\n}: UploadItemProps) {\n\tconst text = { ...DEFAULT_LABELS, ...labels };\n\tconst progress =\n\t\ttypeof file.progress === \"number\" && Number.isFinite(file.progress)\n\t\t\t? Math.max(0, Math.min(100, file.progress))\n\t\t\t: undefined;\n\tconst active = file.status === \"queued\" || file.status === \"uploading\";\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex min-w-0 items-start gap-basalt-space-lg rounded-basalt-lg border border-basalt-border p-basalt-card-sm\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"flex size-basalt-10 shrink-0 items-center justify-center overflow-hidden rounded-basalt-md bg-basalt-accent\">\n\t\t\t\t{file.preview ?? (\n\t\t\t\t\t<FileText className=\"size-basalt-5 text-basalt-muted-foreground\" aria-hidden=\"true\" />\n\t\t\t\t)}\n\t\t\t</span>\n\t\t\t<div className=\"min-w-0 flex-1 space-y-basalt-space-sm\">\n\t\t\t\t<p className=\"break-words text-basalt-base font-medium\">{file.name}</p>\n\t\t\t\t<p className=\"text-basalt-sm text-basalt-muted-foreground\">\n\t\t\t\t\t{file.size !== undefined && `${Math.ceil(file.size / 1024).toLocaleString()} KB · `}\n\t\t\t\t\t{text[file.status]}\n\t\t\t\t</p>\n\t\t\t\t{file.status === \"uploading\" && (\n\t\t\t\t\t<div\n\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\taria-label={file.name}\n\t\t\t\t\t\taria-valuemin={0}\n\t\t\t\t\t\taria-valuemax={100}\n\t\t\t\t\t\taria-valuenow={progress}\n\t\t\t\t\t\tclassName=\"h-basalt-1_5 overflow-hidden rounded-basalt-full bg-basalt-accent\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{ width: progress === undefined ? \"40%\" : `${progress}%` }}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"h-full rounded-basalt-full bg-basalt-primary\",\n\t\t\t\t\t\t\t\tprogress === undefined && \"animate-pulse motion-reduce:animate-none\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{file.status === \"error\" && file.error && (\n\t\t\t\t\t<p role=\"alert\" className=\"break-words text-basalt-sm text-basalt-destructive\">\n\t\t\t\t\t\t{file.error}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<div className=\"flex shrink-0 items-center gap-basalt-space-sm\">\n\t\t\t\t{file.status === \"success\" && (\n\t\t\t\t\t<Check className=\"size-basalt-icon-lg text-basalt-success\" aria-hidden=\"true\" />\n\t\t\t\t)}\n\t\t\t\t{active && onCancel && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\taria-label={`${text.cancel} ${file.name}`}\n\t\t\t\t\t\tonClick={() => onCancel(file.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<X />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t\t{(file.status === \"error\" || file.status === \"cancelled\") && onRetry && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\taria-label={`${text.retry} ${file.name}`}\n\t\t\t\t\t\tonClick={() => onRetry(file.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RotateCcw />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t\t{file.status !== \"uploading\" && onRemove && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\taria-label={`${text.remove} ${file.name}`}\n\t\t\t\t\t\tonClick={() => onRemove(file.id)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Trash2 />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport interface UploadQueueProps extends Omit<UploadItemProps, \"file\"> {\n\t/** Accessible queue name. */\n\tlabel: string;\n\t/** Application-owned queue entries. */\n\tfiles: readonly UploadFile[];\n\t/** Empty queue text. @default \"No files selected.\" */\n\temptyLabel?: string;\n}\n\nexport function UploadQueue({\n\tlabel,\n\tfiles,\n\temptyLabel = \"No files selected.\",\n\tclassName,\n\t...actions\n}: UploadQueueProps) {\n\treturn (\n\t\t<div className={cn(BASALT_UI_CLASS, \"min-w-0 space-y-basalt-space-lg\", className)}>\n\t\t\t{files.length === 0 ? (\n\t\t\t\t<p role=\"status\" className=\"text-basalt-base text-basalt-muted-foreground\">\n\t\t\t\t\t{emptyLabel}\n\t\t\t\t</p>\n\t\t\t) : (\n\t\t\t\t<ul aria-label={label} className=\"m-0 list-none space-y-basalt-space-lg p-0\">\n\t\t\t\t\t{files.map((file) => (\n\t\t\t\t\t\t<li key={file.id}>\n\t\t\t\t\t\t\t<UploadItem file={file} {...actions} />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export type AgentStepStatus = "pending" | "running" | "complete" | "error";
2
+ export type ThinkingStep = {
3
+ id: string;
4
+ label: string;
5
+ detail?: string;
6
+ status: AgentStepStatus;
7
+ };
8
+ export type ThinkingVariant = "steps" | "reasoning" | "search" | "coding";
9
+ export type ToolStep = ThinkingStep & {
10
+ kind: "think" | "read" | "write" | "run";
11
+ target?: string;
12
+ };
13
+ export type ToolDiff = {
14
+ file: string;
15
+ added: number;
16
+ removed: number;
17
+ content?: string;
18
+ };
19
+ export declare function summarizeSteps(steps: readonly ThinkingStep[]): {
20
+ completed: number;
21
+ total: number;
22
+ status: AgentStepStatus;
23
+ };
24
+ export type ApprovalQuestion = {
25
+ id: string;
26
+ label: string;
27
+ type: "single" | "multiple";
28
+ options: readonly {
29
+ id: string;
30
+ label: string;
31
+ disabled?: boolean;
32
+ }[];
33
+ /** Required questions cannot be skipped. @default true */
34
+ required?: boolean;
35
+ allowCustom?: boolean;
36
+ };
37
+ export type ApprovalAnswer = {
38
+ selected: string[];
39
+ custom?: string;
40
+ skipped?: boolean;
41
+ };
42
+ export type ApprovalAnswers = Record<string, ApprovalAnswer>;
43
+ export declare function validApprovalAnswer(question: ApprovalQuestion, answer: ApprovalAnswer | undefined): boolean;
44
+ export declare function approvalSnapshot(questions: readonly ApprovalQuestion[], answers: ApprovalAnswers): ApprovalAnswers;
@@ -0,0 +1,28 @@
1
+ "use client";
2
+ //#region src/models/agent-feedback.ts
3
+ function e(e) {
4
+ let t = e.filter((e) => e.status === "complete").length, n = e.some((e) => e.status === "error") ? "error" : e.some((e) => e.status === "running") ? "running" : e.length > 0 && t === e.length ? "complete" : "pending";
5
+ return {
6
+ completed: t,
7
+ total: e.length,
8
+ status: n
9
+ };
10
+ }
11
+ function t(e, t) {
12
+ let n = t?.selected.filter((t) => e.options.some((e) => e.id === t && !e.disabled)) ?? [], r = e.allowCustom ? t?.custom?.trim() ?? "" : "";
13
+ return (e.type === "multiple" || n.length <= 1) && (n.length > 0 || r.length > 0 || e.required === !1 && t?.skipped === !0);
14
+ }
15
+ function n(e, t) {
16
+ return Object.fromEntries(e.map((e) => {
17
+ let n = t[e.id], r = n?.selected.filter((t) => e.options.some((e) => e.id === t && !e.disabled)) ?? [];
18
+ return [e.id, {
19
+ selected: e.type === "single" ? r.slice(0, 1) : r,
20
+ ...e.allowCustom ? { custom: n?.custom?.trim() ?? "" } : {},
21
+ ...n?.skipped ? { skipped: !0 } : {}
22
+ }];
23
+ }));
24
+ }
25
+ //#endregion
26
+ export { n as approvalSnapshot, e as summarizeSteps, t as validApprovalAnswer };
27
+
28
+ //# sourceMappingURL=agent-feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-feedback.js","names":["summarizeSteps","completed","steps","step","status","validApprovalAnswer","selected","answer","question","option","id","custom","approvalSnapshot","questions","answers"],"sources":["../../src/models/agent-feedback.ts"],"sourcesContent":["export type AgentStepStatus = \"pending\" | \"running\" | \"complete\" | \"error\";\nexport type ThinkingStep = { id: string; label: string; detail?: string; status: AgentStepStatus };\nexport type ThinkingVariant = \"steps\" | \"reasoning\" | \"search\" | \"coding\";\nexport type ToolStep = ThinkingStep & { kind: \"think\" | \"read\" | \"write\" | \"run\"; target?: string };\nexport type ToolDiff = { file: string; added: number; removed: number; content?: string };\n\nexport function summarizeSteps(steps: readonly ThinkingStep[]) {\n\tconst completed = steps.filter((step) => step.status === \"complete\").length;\n\tconst status: AgentStepStatus = steps.some((step) => step.status === \"error\")\n\t\t? \"error\"\n\t\t: steps.some((step) => step.status === \"running\")\n\t\t\t? \"running\"\n\t\t\t: steps.length > 0 && completed === steps.length\n\t\t\t\t? \"complete\"\n\t\t\t\t: \"pending\";\n\treturn { completed, total: steps.length, status };\n}\n\nexport type ApprovalQuestion = {\n\tid: string;\n\tlabel: string;\n\ttype: \"single\" | \"multiple\";\n\toptions: readonly { id: string; label: string; disabled?: boolean }[];\n\t/** Required questions cannot be skipped. @default true */\n\trequired?: boolean;\n\tallowCustom?: boolean;\n};\nexport type ApprovalAnswer = { selected: string[]; custom?: string; skipped?: boolean };\nexport type ApprovalAnswers = Record<string, ApprovalAnswer>;\n\nexport function validApprovalAnswer(\n\tquestion: ApprovalQuestion,\n\tanswer: ApprovalAnswer | undefined,\n) {\n\tconst selected =\n\t\tanswer?.selected.filter((id) =>\n\t\t\tquestion.options.some((option) => option.id === id && !option.disabled),\n\t\t) ?? [];\n\tconst custom = question.allowCustom ? (answer?.custom?.trim() ?? \"\") : \"\";\n\treturn (\n\t\t(question.type === \"multiple\" || selected.length <= 1) &&\n\t\t(selected.length > 0 ||\n\t\t\tcustom.length > 0 ||\n\t\t\t(question.required === false && answer?.skipped === true))\n\t);\n}\n\nexport function approvalSnapshot(\n\tquestions: readonly ApprovalQuestion[],\n\tanswers: ApprovalAnswers,\n): ApprovalAnswers {\n\treturn Object.fromEntries(\n\t\tquestions.map((question) => {\n\t\t\tconst answer = answers[question.id];\n\t\t\tconst selected =\n\t\t\t\tanswer?.selected.filter((id) =>\n\t\t\t\t\tquestion.options.some((option) => option.id === id && !option.disabled),\n\t\t\t\t) ?? [];\n\t\t\treturn [\n\t\t\t\tquestion.id,\n\t\t\t\t{\n\t\t\t\t\tselected: question.type === \"single\" ? selected.slice(0, 1) : selected,\n\t\t\t\t\t...(question.allowCustom ? { custom: answer?.custom?.trim() ?? \"\" } : {}),\n\t\t\t\t\t...(answer?.skipped ? { skipped: true } : {}),\n\t\t\t\t},\n\t\t\t];\n\t\t}),\n\t);\n}\n"],"mappings":";;AAMA,SAAgBA,EAAe,GAAgC;CAC9D,IAAMC,IAAYC,EAAM,QAAQ,MAASC,EAAK,WAAW,UAAU,CAAC,CAAC,QAC/DC,IAA0BF,EAAM,MAAM,MAASC,EAAK,WAAW,OAAO,IACzE,UACAD,EAAM,MAAM,MAASC,EAAK,WAAW,SAAS,IAC7C,YACAD,EAAM,SAAS,KAAKD,MAAcC,EAAM,SACvC,aACA;CACL,OAAO;EAAE;EAAW,OAAOA,EAAM;EAAQ;CAAO;AACjD;AAcA,SAAgBG,EACf,GACA,GACC;CACD,IAAMC,IACLC,GAAQ,SAAS,QAAQ,MACxBC,EAAS,QAAQ,MAAM,MAAWC,EAAO,OAAOC,KAAM,CAACD,EAAO,QAAQ,CACvE,KAAK,CAAC,GACDE,IAASH,EAAS,cAAeD,GAAQ,QAAQ,KAAK,KAAK,KAAM;CACvE,QACEC,EAAS,SAAS,cAAcF,EAAS,UAAU,OACnDA,EAAS,SAAS,KAClBK,EAAO,SAAS,KACfH,EAAS,aAAa,MAASD,GAAQ,YAAY;AAEvD;AAEA,SAAgBK,EACf,GACA,GACkB;CAClB,OAAO,OAAO,YACbC,EAAU,KAAK,MAAa;EAC3B,IAAMN,IAASO,EAAQN,EAAS,KAC1BF,IACLC,GAAQ,SAAS,QAAQ,MACxBC,EAAS,QAAQ,MAAM,MAAWC,EAAO,OAAOC,KAAM,CAACD,EAAO,QAAQ,CACvE,KAAK,CAAC;EACP,OAAO,CACND,EAAS,IACT;GACC,UAAUA,EAAS,SAAS,WAAWF,EAAS,MAAM,GAAG,CAAC,IAAIA;GAC9D,GAAIE,EAAS,cAAc,EAAE,QAAQD,GAAQ,QAAQ,KAAK,KAAK,GAAG,IAAI,CAAC;GACvE,GAAIA,GAAQ,UAAU,EAAE,SAAS,GAAK,IAAI,CAAC;EAC5C,CACD;CACD,CAAC,CACF;AACD"}
@@ -0,0 +1,2 @@
1
+ export declare function avatarInitials(name: string): string;
2
+ export declare function avatarColorIndex(key: string): number;
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ //#region src/models/avatar.ts
3
+ function e(e) {
4
+ let t = e.trim().split(/[\s—–-]+/u).filter(Boolean), n = t.length > 1 ? [Array.from(t[0])[0], Array.from(t[1])[0]] : Array.from(t[0] ?? "").slice(0, 2);
5
+ return Array.from(n.join("").toLocaleUpperCase("en-US")).slice(0, 2).join("") || "?";
6
+ }
7
+ function t(e) {
8
+ let t = 2166136261;
9
+ for (let n of e) t = Math.imul(t ^ (n.codePointAt(0) ?? 0), 16777619);
10
+ return (t >>> 0) % 6;
11
+ }
12
+ //#endregion
13
+ export { t as avatarColorIndex, e as avatarInitials };
14
+
15
+ //# sourceMappingURL=avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar.js","names":["avatarInitials","words","name","letters","avatarColorIndex","hash","char","key"],"sources":["../../src/models/avatar.ts"],"sourcesContent":["export function avatarInitials(name: string): string {\n\tconst words = name\n\t\t.trim()\n\t\t.split(/[\\s—–-]+/u)\n\t\t.filter(Boolean);\n\tconst letters =\n\t\twords.length > 1\n\t\t\t? [Array.from(words[0])[0], Array.from(words[1])[0]]\n\t\t\t: Array.from(words[0] ?? \"\").slice(0, 2);\n\treturn Array.from(letters.join(\"\").toLocaleUpperCase(\"en-US\")).slice(0, 2).join(\"\") || \"?\";\n}\n\nexport function avatarColorIndex(key: string): number {\n\tlet hash = 2166136261;\n\tfor (const char of key) hash = Math.imul(hash ^ (char.codePointAt(0) ?? 0), 16777619);\n\treturn (hash >>> 0) % 6;\n}\n"],"mappings":";;AAAA,SAAgBA,EAAe,GAAsB;CACpD,IAAMC,IAAQC,EACZ,KAAK,CAAC,CACN,MAAM,WAAW,CAAC,CAClB,OAAO,OAAO,GACVC,IACLF,EAAM,SAAS,IACZ,CAAC,MAAM,KAAKA,EAAM,EAAE,CAAC,CAAC,IAAI,MAAM,KAAKA,EAAM,EAAE,CAAC,CAAC,EAAE,IACjD,MAAM,KAAKA,EAAM,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;CACzC,OAAO,MAAM,KAAKE,EAAQ,KAAK,EAAE,CAAC,CAAC,kBAAkB,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK;AACxF;AAEA,SAAgBC,EAAiB,GAAqB;CACrD,IAAIC,IAAO;CACX,KAAK,IAAMC,KAAQC,GAAK,IAAO,KAAK,KAAKF,KAAQC,EAAK,YAAY,CAAC,KAAK,IAAI,QAAQ;CACpF,QAAQD,MAAS,KAAK;AACvB"}
@@ -0,0 +1,6 @@
1
+ type CodeToken = {
2
+ text: string;
3
+ className?: string;
4
+ };
5
+ export declare function codeLines(code: string, highlighted: boolean): CodeToken[][];
6
+ export {};
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ //#region src/models/code.ts
3
+ var e = /(\/\/[^\n]*)|("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`[^`]*`)|\b(import|from|export|default|async|await|function|return|const|let|var|type|interface|as|if|else|throw|new|typeof|null|true|false|undefined)\b|(\b\d+\b)|(<\/?[A-Za-z][\w.-]*)/g;
4
+ function t(t, n) {
5
+ let r = [], i = 0;
6
+ if (n) for (let n of t.matchAll(e)) {
7
+ let e = n.index;
8
+ e > i && r.push({ text: t.slice(i, e) }), r.push({
9
+ text: n[0],
10
+ className: n[1] ? "text-basalt-muted-foreground" : n[2] ? "text-basalt-chart-5" : n[4] ? "text-basalt-chart-4" : "text-basalt-primary"
11
+ }), i = e + n[0].length;
12
+ }
13
+ i < t.length && r.push({ text: t.slice(i) });
14
+ let a = [[]];
15
+ for (let e of r) for (let [t, n] of e.text.split(/\r\n|\r|\n/).entries()) t > 0 && a.push([]), n && a[a.length - 1].push({
16
+ text: n,
17
+ className: e.className
18
+ });
19
+ return a;
20
+ }
21
+ //#endregion
22
+ export { t as codeLines };
23
+
24
+ //# sourceMappingURL=code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.js","names":["TOKEN","codeLines","tokens","offset","highlighted","match","code","index","lines","token","text"],"sources":["../../src/models/code.ts"],"sourcesContent":["const TOKEN =\n\t/(\\/\\/[^\\n]*)|(\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`[^`]*`)|\\b(import|from|export|default|async|await|function|return|const|let|var|type|interface|as|if|else|throw|new|typeof|null|true|false|undefined)\\b|(\\b\\d+\\b)|(<\\/?[A-Za-z][\\w.-]*)/g;\n\ntype CodeToken = { text: string; className?: string };\n\nexport function codeLines(code: string, highlighted: boolean): CodeToken[][] {\n\tconst tokens: CodeToken[] = [];\n\tlet offset = 0;\n\tif (highlighted) {\n\t\tfor (const match of code.matchAll(TOKEN)) {\n\t\t\tconst index = match.index;\n\t\t\tif (index > offset) tokens.push({ text: code.slice(offset, index) });\n\t\t\ttokens.push({\n\t\t\t\ttext: match[0],\n\t\t\t\tclassName: match[1]\n\t\t\t\t\t? \"text-basalt-muted-foreground\"\n\t\t\t\t\t: match[2]\n\t\t\t\t\t\t? \"text-basalt-chart-5\"\n\t\t\t\t\t\t: match[4]\n\t\t\t\t\t\t\t? \"text-basalt-chart-4\"\n\t\t\t\t\t\t\t: \"text-basalt-primary\",\n\t\t\t});\n\t\t\toffset = index + match[0].length;\n\t\t}\n\t}\n\tif (offset < code.length) tokens.push({ text: code.slice(offset) });\n\tconst lines: CodeToken[][] = [[]];\n\tfor (const token of tokens) {\n\t\tfor (const [index, text] of token.text.split(/\\r\\n|\\r|\\n/).entries()) {\n\t\t\tif (index > 0) lines.push([]);\n\t\t\tif (text) lines[lines.length - 1].push({ text, className: token.className });\n\t\t}\n\t}\n\treturn lines;\n}\n"],"mappings":";;AAAA,IAAMA,IACL;AAID,SAAgBC,EAAU,GAAc,GAAqC;CAC5E,IAAMC,IAAsB,CAAC,GACzBC,IAAS;CACb,IAAIC,GACH,KAAK,IAAMC,KAASC,EAAK,SAASN,CAAK,GAAG;EACzC,IAAMO,IAAQF,EAAM;EAYpB,AAXIE,IAAQJ,KAAQD,EAAO,KAAK,EAAE,MAAMI,EAAK,MAAMH,GAAQI,CAAK,EAAE,CAAC,GACnEL,EAAO,KAAK;GACX,MAAMG,EAAM;GACZ,WAAWA,EAAM,KACd,iCACAA,EAAM,KACL,wBACAA,EAAM,KACL,wBACA;EACN,CAAC,GACD,IAASE,IAAQF,EAAM,EAAE,CAAC;CAC3B;CAED,AAAIF,IAASG,EAAK,UAAQJ,EAAO,KAAK,EAAE,MAAMI,EAAK,MAAMH,CAAM,EAAE,CAAC;CAClE,IAAMK,IAAuB,CAAC,CAAC,CAAC;CAChC,KAAK,IAAMC,KAASP,GACnB,KAAK,IAAM,CAACK,GAAOG,MAASD,EAAM,KAAK,MAAM,YAAY,CAAC,CAAC,QAAQ,GAElE,AADIF,IAAQ,KAAGC,EAAM,KAAK,CAAC,CAAC,GACxBE,KAAMF,EAAMA,EAAM,SAAS,EAAE,CAAC,KAAK;EAAE;EAAM,WAAWC,EAAM;CAAU,CAAC;CAG7E,OAAOD;AACR"}
@@ -0,0 +1,13 @@
1
+ export type ContextChunk = {
2
+ id: string;
3
+ title: string;
4
+ body: string;
5
+ source: {
6
+ name: string;
7
+ type: string;
8
+ href?: string;
9
+ };
10
+ /** Optional full-document character count; defaults to the displayed text length. */
11
+ characters?: number;
12
+ };
13
+ export declare function contextSourceHref(href: string | undefined): string | undefined;
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ //#region src/models/context-cards.ts
3
+ function e(e) {
4
+ if (e && e === e.trim() && !Array.from(e).some((e) => e.charCodeAt(0) <= 32 || e === "\\")) {
5
+ if (e.startsWith("/") && !e.startsWith("//")) return e;
6
+ try {
7
+ let t = new URL(e);
8
+ return (t.protocol === "https:" || t.protocol === "http:") && !t.username && !t.password ? t.href : void 0;
9
+ } catch {
10
+ return;
11
+ }
12
+ }
13
+ }
14
+ //#endregion
15
+ export { e as contextSourceHref };
16
+
17
+ //# sourceMappingURL=context-cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-cards.js","names":["contextSourceHref","href","char","url"],"sources":["../../src/models/context-cards.ts"],"sourcesContent":["export type ContextChunk = {\n\tid: string;\n\ttitle: string;\n\tbody: string;\n\tsource: { name: string; type: string; href?: string };\n\t/** Optional full-document character count; defaults to the displayed text length. */\n\tcharacters?: number;\n};\n\nexport function contextSourceHref(href: string | undefined): string | undefined {\n\tif (\n\t\t!href ||\n\t\thref !== href.trim() ||\n\t\tArray.from(href).some((char) => char.charCodeAt(0) <= 32 || char === \"\\\\\")\n\t)\n\t\treturn undefined;\n\tif (href.startsWith(\"/\") && !href.startsWith(\"//\")) return href;\n\ttry {\n\t\tconst url = new URL(href);\n\t\treturn (url.protocol === \"https:\" || url.protocol === \"http:\") && !url.username && !url.password\n\t\t\t? url.href\n\t\t\t: undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"],"mappings":";;AASA,SAAgBA,EAAkB,GAA8C;CAC/E,IACEC,KACDA,MAASA,EAAK,KAAK,KACnB,OAAM,KAAKA,CAAI,CAAC,CAAC,MAAM,MAASC,EAAK,WAAW,CAAC,KAAK,MAAMA,MAAS,IAAI,GAG1E;MAAID,EAAK,WAAW,GAAG,KAAK,CAACA,EAAK,WAAW,IAAI,GAAG,OAAOA;EAC3D,IAAI;GACH,IAAME,IAAM,IAAI,IAAIF,CAAI;GACxB,QAAQE,EAAI,aAAa,YAAYA,EAAI,aAAa,YAAY,CAACA,EAAI,YAAY,CAACA,EAAI,WACrFA,EAAI,OACJ,KAAA;EACJ,QAAQ;GACP;EACD;CAR2D;AAS5D"}
@@ -0,0 +1,12 @@
1
+ export type DiffTableColumn = {
2
+ id: string;
3
+ label: string;
4
+ width?: number;
5
+ };
6
+ export type DiffTableRow = {
7
+ id: string;
8
+ label: string;
9
+ change: "add" | "remove" | "unchanged";
10
+ values: Readonly<Record<string, string | number>>;
11
+ };
12
+ export declare function selectedDiffRows(rows: readonly DiffTableRow[], excluded: readonly string[]): DiffTableRow[];
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ //#region src/models/diff-table.ts
3
+ function e(e, t) {
4
+ return e.filter((e) => e.change !== "unchanged" && !t.includes(e.id));
5
+ }
6
+ //#endregion
7
+ export { e as selectedDiffRows };
8
+
9
+ //# sourceMappingURL=diff-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-table.js","names":["selectedDiffRows","rows","row","excluded"],"sources":["../../src/models/diff-table.ts"],"sourcesContent":["export type DiffTableColumn = { id: string; label: string; width?: number };\nexport type DiffTableRow = {\n\tid: string;\n\tlabel: string;\n\tchange: \"add\" | \"remove\" | \"unchanged\";\n\tvalues: Readonly<Record<string, string | number>>;\n};\n\nexport function selectedDiffRows(rows: readonly DiffTableRow[], excluded: readonly string[]) {\n\treturn rows.filter((row) => row.change !== \"unchanged\" && !excluded.includes(row.id));\n}\n"],"mappings":";;AAQA,SAAgBA,EAAiB,GAA+B,GAA6B;CAC5F,OAAOC,EAAK,QAAQ,MAAQC,EAAI,WAAW,eAAe,CAACC,EAAS,SAASD,EAAI,EAAE,CAAC;AACrF"}
@@ -0,0 +1,26 @@
1
+ export type RecommendationConfidence = "high" | "review" | "none";
2
+ export type RecommendationOption = {
3
+ id: string;
4
+ label: string;
5
+ description: string;
6
+ confidence: RecommendationConfidence;
7
+ actionLabel?: string;
8
+ disabled?: boolean;
9
+ };
10
+ export declare const RECOMMENDATION_CONFIDENCE: {
11
+ readonly high: {
12
+ readonly label: "High confidence";
13
+ readonly bars: 3;
14
+ readonly className: "text-basalt-info";
15
+ };
16
+ readonly review: {
17
+ readonly label: "Needs review";
18
+ readonly bars: 2;
19
+ readonly className: "text-basalt-warning";
20
+ };
21
+ readonly none: {
22
+ readonly label: "No signal";
23
+ readonly bars: 0;
24
+ readonly className: "text-basalt-muted-foreground";
25
+ };
26
+ };
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ //#region src/models/recommendation.ts
3
+ var e = {
4
+ high: {
5
+ label: "High confidence",
6
+ bars: 3,
7
+ className: "text-basalt-info"
8
+ },
9
+ review: {
10
+ label: "Needs review",
11
+ bars: 2,
12
+ className: "text-basalt-warning"
13
+ },
14
+ none: {
15
+ label: "No signal",
16
+ bars: 0,
17
+ className: "text-basalt-muted-foreground"
18
+ }
19
+ };
20
+ //#endregion
21
+ export { e as RECOMMENDATION_CONFIDENCE };
22
+
23
+ //# sourceMappingURL=recommendation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendation.js","names":["RECOMMENDATION_CONFIDENCE"],"sources":["../../src/models/recommendation.ts"],"sourcesContent":["export type RecommendationConfidence = \"high\" | \"review\" | \"none\";\n\nexport type RecommendationOption = {\n\tid: string;\n\tlabel: string;\n\tdescription: string;\n\tconfidence: RecommendationConfidence;\n\tactionLabel?: string;\n\tdisabled?: boolean;\n};\n\nexport const RECOMMENDATION_CONFIDENCE = {\n\thigh: { label: \"High confidence\", bars: 3, className: \"text-basalt-info\" },\n\treview: { label: \"Needs review\", bars: 2, className: \"text-basalt-warning\" },\n\tnone: { label: \"No signal\", bars: 0, className: \"text-basalt-muted-foreground\" },\n} as const;\n"],"mappings":";;AAWA,IAAaA,IAA4B;CACxC,MAAM;EAAE,OAAO;EAAmB,MAAM;EAAG,WAAW;CAAmB;CACzE,QAAQ;EAAE,OAAO;EAAgB,MAAM;EAAG,WAAW;CAAsB;CAC3E,MAAM;EAAE,OAAO;EAAa,MAAM;EAAG,WAAW;CAA+B;AAChF"}
@@ -69,6 +69,16 @@
69
69
  margin-left: 0;
70
70
  }
71
71
 
72
+ :where(.basalt-ui:is(fieldset), .basalt-ui fieldset) {
73
+ min-width: 0;
74
+ margin: 0;
75
+ padding: 0;
76
+ }
77
+
78
+ :where(.basalt-ui:is(legend), .basalt-ui legend) {
79
+ padding: 0;
80
+ }
81
+
72
82
  :where(.basalt-ui:is(ol, ul, menu), .basalt-ui :is(ol, ul, menu)) {
73
83
  list-style: none;
74
84
  margin: 0;
@@ -189,11 +199,13 @@
189
199
  background: inherit;
190
200
  pointer-events: none;
191
201
  }
202
+ }
192
203
 
204
+ @layer components {
193
205
  [data-basalt-header][data-density="compact"]
194
206
  :where([data-basalt-header-leading], [data-basalt-header-actions])
195
207
  :where(button, a, [role="button"]) {
196
- min-height: 44px;
197
- min-width: 44px;
208
+ min-height: var(--basalt-size-touch);
209
+ min-width: var(--basalt-size-touch);
198
210
  }
199
211
  }