@grampro/kit 0.0.0-stage → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/.gbs/skills/gbs-components/SKILL.md +190 -0
  2. package/.gbs/skills/gbs-components/references/accessibility.md +102 -0
  3. package/.gbs/skills/gbs-components/references/data-display.md +185 -0
  4. package/.gbs/skills/gbs-components/references/data-grid.md +116 -0
  5. package/.gbs/skills/gbs-components/references/forms.md +202 -0
  6. package/.gbs/skills/gbs-components/references/install.md +211 -0
  7. package/.gbs/skills/gbs-components/references/overlays.md +206 -0
  8. package/.gbs/skills/gbs-components/references/pickers.md +83 -0
  9. package/.gbs/skills/gbs-components/references/styling.md +246 -0
  10. package/.gbs/skills/gbs-components/references/toaster.md +57 -0
  11. package/CHANGELOG.md +173 -0
  12. package/LICENSE +15 -0
  13. package/README.md +193 -2
  14. package/index.cjs +1410 -0
  15. package/package.json +77 -6
  16. package/schema/passport-v1.schema.json +204 -0
  17. package/source/components/accordion/README.md +45 -0
  18. package/source/components/accordion/core/index.ts +2 -0
  19. package/source/components/accordion/core/open.ts +56 -0
  20. package/source/components/accordion/core/types.ts +17 -0
  21. package/source/components/accordion/index.ts +8 -0
  22. package/source/components/accordion/passport.json +259 -0
  23. package/source/components/accordion/react/Accordion.tsx +133 -0
  24. package/source/components/accordion/react/AccordionItem.tsx +120 -0
  25. package/source/components/accordion/react/context.ts +20 -0
  26. package/source/components/accordion/react/props.ts +13 -0
  27. package/source/components/accordion/styles.css +207 -0
  28. package/source/components/alert/README.md +39 -0
  29. package/source/components/alert/core/index.ts +2 -0
  30. package/source/components/alert/core/live.ts +25 -0
  31. package/source/components/alert/core/types.ts +7 -0
  32. package/source/components/alert/index.ts +5 -0
  33. package/source/components/alert/passport.json +250 -0
  34. package/source/components/alert/react/Alert.tsx +113 -0
  35. package/source/components/alert/react/icons.tsx +21 -0
  36. package/source/components/alert/react/locale.ts +5 -0
  37. package/source/components/alert/react/props.ts +11 -0
  38. package/source/components/alert/styles.css +154 -0
  39. package/source/components/avatar/core/identity.ts +103 -0
  40. package/source/components/avatar/core/index.ts +2 -0
  41. package/source/components/avatar/core/types.ts +12 -0
  42. package/source/components/avatar/index.ts +7 -0
  43. package/source/components/avatar/passport.json +294 -0
  44. package/source/components/avatar/react/Avatar.tsx +118 -0
  45. package/source/components/avatar/react/AvatarGroup.tsx +74 -0
  46. package/source/components/avatar/react/locale.ts +11 -0
  47. package/source/components/avatar/react/props.ts +6 -0
  48. package/source/components/avatar/styles.css +225 -0
  49. package/source/components/badge/README.md +37 -0
  50. package/source/components/badge/core/count.ts +37 -0
  51. package/source/components/badge/core/index.ts +2 -0
  52. package/source/components/badge/core/types.ts +11 -0
  53. package/source/components/badge/index.ts +7 -0
  54. package/source/components/badge/passport.json +332 -0
  55. package/source/components/badge/react/Badge.tsx +89 -0
  56. package/source/components/badge/react/Tag.tsx +82 -0
  57. package/source/components/badge/react/locale.ts +5 -0
  58. package/source/components/badge/react/props.ts +6 -0
  59. package/source/components/badge/styles.css +203 -0
  60. package/source/components/breadcrumb/README.md +34 -0
  61. package/source/components/breadcrumb/core/index.ts +4 -0
  62. package/source/components/breadcrumb/core/trail.ts +42 -0
  63. package/source/components/breadcrumb/core/types.ts +20 -0
  64. package/source/components/breadcrumb/index.ts +5 -0
  65. package/source/components/breadcrumb/passport.json +243 -0
  66. package/source/components/breadcrumb/react/Breadcrumb.tsx +177 -0
  67. package/source/components/breadcrumb/react/locale.ts +6 -0
  68. package/source/components/breadcrumb/react/props.ts +14 -0
  69. package/source/components/breadcrumb/styles.css +138 -0
  70. package/source/components/button/README.md +32 -0
  71. package/source/components/button/core/index.ts +3 -0
  72. package/source/components/button/core/state.ts +16 -0
  73. package/source/components/button/core/types.ts +28 -0
  74. package/source/components/button/index.ts +5 -0
  75. package/source/components/button/passport.json +402 -0
  76. package/source/components/button/passport.manual.json +31 -0
  77. package/source/components/button/react/Button.tsx +173 -0
  78. package/source/components/button/react/locale.ts +5 -0
  79. package/source/components/button/react/props.ts +23 -0
  80. package/source/components/button/styles.css +232 -0
  81. package/source/components/card/README.md +60 -0
  82. package/source/components/card/core/index.ts +4 -0
  83. package/source/components/card/core/trend.ts +32 -0
  84. package/source/components/card/core/types.ts +5 -0
  85. package/source/components/card/index.ts +5 -0
  86. package/source/components/card/passport.json +337 -0
  87. package/source/components/card/react/Card.tsx +133 -0
  88. package/source/components/card/react/Stat.tsx +127 -0
  89. package/source/components/card/react/props.ts +4 -0
  90. package/source/components/card/styles.css +230 -0
  91. package/source/components/checkbox/README.md +36 -0
  92. package/source/components/checkbox/core/group.ts +30 -0
  93. package/source/components/checkbox/core/index.ts +3 -0
  94. package/source/components/checkbox/core/types.ts +17 -0
  95. package/source/components/checkbox/index.ts +9 -0
  96. package/source/components/checkbox/passport.json +456 -0
  97. package/source/components/checkbox/react/Checkbox.tsx +147 -0
  98. package/source/components/checkbox/react/CheckboxGroup.tsx +149 -0
  99. package/source/components/checkbox/react/context.ts +16 -0
  100. package/source/components/checkbox/react/locale.ts +5 -0
  101. package/source/components/checkbox/react/props.ts +6 -0
  102. package/source/components/checkbox/styles.css +211 -0
  103. package/source/components/combobox/README.md +170 -0
  104. package/source/components/combobox/core/filter.ts +155 -0
  105. package/source/components/combobox/core/index.ts +16 -0
  106. package/source/components/combobox/core/types.ts +48 -0
  107. package/source/components/combobox/core/virtual.ts +67 -0
  108. package/source/components/combobox/index.ts +13 -0
  109. package/source/components/combobox/passport.json +456 -0
  110. package/source/components/combobox/react/Listbox.tsx +310 -0
  111. package/source/components/combobox/react/MultiSelect.tsx +265 -0
  112. package/source/components/combobox/react/Popover.tsx +38 -0
  113. package/source/components/combobox/react/Select.tsx +200 -0
  114. package/source/components/combobox/react/icons.tsx +11 -0
  115. package/source/components/combobox/react/locale.ts +16 -0
  116. package/source/components/combobox/react/props.ts +88 -0
  117. package/source/components/combobox/react/useCombobox.ts +409 -0
  118. package/source/components/combobox/styles.css +419 -0
  119. package/source/components/data-grid/README.md +233 -0
  120. package/source/components/data-grid/agent/coerce.ts +368 -0
  121. package/source/components/data-grid/agent/contract.ts +410 -0
  122. package/source/components/data-grid/agent/dataset.ts +92 -0
  123. package/source/components/data-grid/agent/engine.ts +470 -0
  124. package/source/components/data-grid/agent/executors.ts +155 -0
  125. package/source/components/data-grid/agent/index.ts +79 -0
  126. package/source/components/data-grid/agent/intent.ts +324 -0
  127. package/source/components/data-grid/agent/operations.ts +335 -0
  128. package/source/components/data-grid/agent/validate.ts +630 -0
  129. package/source/components/data-grid/agent/webmcp.ts +107 -0
  130. package/source/components/data-grid/core/columnHelper.ts +21 -0
  131. package/source/components/data-grid/core/columns.ts +288 -0
  132. package/source/components/data-grid/core/filtering.ts +237 -0
  133. package/source/components/data-grid/core/grid.ts +638 -0
  134. package/source/components/data-grid/core/index.ts +14 -0
  135. package/source/components/data-grid/core/rows.ts +64 -0
  136. package/source/components/data-grid/core/sorting.ts +133 -0
  137. package/source/components/data-grid/core/state.ts +82 -0
  138. package/source/components/data-grid/core/store.ts +52 -0
  139. package/source/components/data-grid/core/types.ts +302 -0
  140. package/source/components/data-grid/core/values.ts +98 -0
  141. package/source/components/data-grid/core/virtual.ts +85 -0
  142. package/source/components/data-grid/export/csv.ts +32 -0
  143. package/source/components/data-grid/export/download.ts +12 -0
  144. package/source/components/data-grid/export/pdf-font.ts +139 -0
  145. package/source/components/data-grid/export/pdf-writer.ts +113 -0
  146. package/source/components/data-grid/export/pdf.ts +379 -0
  147. package/source/components/data-grid/export/table.ts +73 -0
  148. package/source/components/data-grid/export/xlsx.ts +145 -0
  149. package/source/components/data-grid/export/zip.ts +87 -0
  150. package/source/components/data-grid/index.ts +14 -0
  151. package/source/components/data-grid/passport.json +1051 -0
  152. package/source/components/data-grid/passport.manual.json +255 -0
  153. package/source/components/data-grid/react/AskGrid.tsx +164 -0
  154. package/source/components/data-grid/react/Cell.tsx +282 -0
  155. package/source/components/data-grid/react/ColumnMenu.tsx +135 -0
  156. package/source/components/data-grid/react/DataGrid.tsx +335 -0
  157. package/source/components/data-grid/react/FilterForm.tsx +142 -0
  158. package/source/components/data-grid/react/HeaderRow.tsx +332 -0
  159. package/source/components/data-grid/react/Pagination.tsx +107 -0
  160. package/source/components/data-grid/react/Popover.tsx +35 -0
  161. package/source/components/data-grid/react/Row.tsx +85 -0
  162. package/source/components/data-grid/react/Toolbar.tsx +267 -0
  163. package/source/components/data-grid/react/Viewport.tsx +167 -0
  164. package/source/components/data-grid/react/context.ts +57 -0
  165. package/source/components/data-grid/react/hooks.ts +83 -0
  166. package/source/components/data-grid/react/icons.tsx +45 -0
  167. package/source/components/data-grid/react/keyboard.ts +110 -0
  168. package/source/components/data-grid/react/locale.ts +130 -0
  169. package/source/components/data-grid/styles.css +874 -0
  170. package/source/components/date-picker/README.md +141 -0
  171. package/source/components/date-picker/core/calendar.ts +266 -0
  172. package/source/components/date-picker/core/format.ts +170 -0
  173. package/source/components/date-picker/core/index.ts +41 -0
  174. package/source/components/date-picker/core/today.ts +72 -0
  175. package/source/components/date-picker/core/types.ts +68 -0
  176. package/source/components/date-picker/index.ts +16 -0
  177. package/source/components/date-picker/passport.json +407 -0
  178. package/source/components/date-picker/react/Calendar.tsx +160 -0
  179. package/source/components/date-picker/react/CalendarPanel.tsx +170 -0
  180. package/source/components/date-picker/react/DatePicker.tsx +249 -0
  181. package/source/components/date-picker/react/DateRangePicker.tsx +291 -0
  182. package/source/components/date-picker/react/MonthYearPanels.tsx +123 -0
  183. package/source/components/date-picker/react/Popover.tsx +45 -0
  184. package/source/components/date-picker/react/icons.tsx +15 -0
  185. package/source/components/date-picker/react/locale.ts +23 -0
  186. package/source/components/date-picker/react/props.ts +76 -0
  187. package/source/components/date-picker/react/useDatePicker.ts +557 -0
  188. package/source/components/date-picker/styles.css +445 -0
  189. package/source/components/dialog/README.md +39 -0
  190. package/source/components/dialog/core/api.ts +34 -0
  191. package/source/components/dialog/core/dialog.ts +11 -0
  192. package/source/components/dialog/core/index.ts +7 -0
  193. package/source/components/dialog/core/store.ts +81 -0
  194. package/source/components/dialog/core/types.ts +59 -0
  195. package/source/components/dialog/index.ts +7 -0
  196. package/source/components/dialog/passport.json +344 -0
  197. package/source/components/dialog/react/Dialog.tsx +279 -0
  198. package/source/components/dialog/react/DialogHost.tsx +45 -0
  199. package/source/components/dialog/react/icons.tsx +20 -0
  200. package/source/components/dialog/react/locale.ts +8 -0
  201. package/source/components/dialog/react/props.ts +13 -0
  202. package/source/components/dialog/styles.css +280 -0
  203. package/source/components/file-uploader/README.md +99 -0
  204. package/source/components/file-uploader/core/format.ts +79 -0
  205. package/source/components/file-uploader/core/index.ts +26 -0
  206. package/source/components/file-uploader/core/store.ts +432 -0
  207. package/source/components/file-uploader/core/transport.ts +154 -0
  208. package/source/components/file-uploader/core/types.ts +126 -0
  209. package/source/components/file-uploader/core/validate.ts +83 -0
  210. package/source/components/file-uploader/index.ts +7 -0
  211. package/source/components/file-uploader/passport.json +518 -0
  212. package/source/components/file-uploader/react/FileRow.tsx +268 -0
  213. package/source/components/file-uploader/react/FileUploader.tsx +511 -0
  214. package/source/components/file-uploader/react/icons.tsx +60 -0
  215. package/source/components/file-uploader/react/locale.ts +33 -0
  216. package/source/components/file-uploader/react/props.ts +31 -0
  217. package/source/components/file-uploader/react/useFileUploader.ts +32 -0
  218. package/source/components/file-uploader/styles.css +394 -0
  219. package/source/components/input/README.md +44 -0
  220. package/source/components/input/core/count.ts +5 -0
  221. package/source/components/input/core/index.ts +11 -0
  222. package/source/components/input/core/otp.ts +64 -0
  223. package/source/components/input/core/types.ts +14 -0
  224. package/source/components/input/index.ts +8 -0
  225. package/source/components/input/passport.json +536 -0
  226. package/source/components/input/react/Input.tsx +219 -0
  227. package/source/components/input/react/OtpInput.tsx +256 -0
  228. package/source/components/input/react/dom.ts +10 -0
  229. package/source/components/input/react/icons.tsx +17 -0
  230. package/source/components/input/react/locale.ts +9 -0
  231. package/source/components/input/react/props.ts +6 -0
  232. package/source/components/input/styles.css +295 -0
  233. package/source/components/menu/README.md +68 -0
  234. package/source/components/menu/core/index.ts +11 -0
  235. package/source/components/menu/core/navigation.ts +84 -0
  236. package/source/components/menu/core/types.ts +32 -0
  237. package/source/components/menu/index.ts +19 -0
  238. package/source/components/menu/passport.json +322 -0
  239. package/source/components/menu/react/Menu.tsx +371 -0
  240. package/source/components/menu/react/context.ts +31 -0
  241. package/source/components/menu/react/items.tsx +268 -0
  242. package/source/components/menu/react/locale.ts +6 -0
  243. package/source/components/menu/react/props.ts +4 -0
  244. package/source/components/menu/react/useMenuKeys.ts +124 -0
  245. package/source/components/menu/styles.css +224 -0
  246. package/source/components/modal/README.md +51 -0
  247. package/source/components/modal/core/dismiss.ts +29 -0
  248. package/source/components/modal/core/index.ts +3 -0
  249. package/source/components/modal/core/types.ts +27 -0
  250. package/source/components/modal/index.ts +5 -0
  251. package/source/components/modal/passport.json +289 -0
  252. package/source/components/modal/react/Modal.tsx +242 -0
  253. package/source/components/modal/react/icons.tsx +1 -0
  254. package/source/components/modal/react/locale.ts +5 -0
  255. package/source/components/modal/react/props.ts +17 -0
  256. package/source/components/modal/styles.css +241 -0
  257. package/source/components/number-input/README.md +53 -0
  258. package/source/components/number-input/core/format.ts +37 -0
  259. package/source/components/number-input/core/index.ts +4 -0
  260. package/source/components/number-input/core/parse.ts +118 -0
  261. package/source/components/number-input/core/step.ts +73 -0
  262. package/source/components/number-input/core/types.ts +32 -0
  263. package/source/components/number-input/index.ts +5 -0
  264. package/source/components/number-input/passport.json +541 -0
  265. package/source/components/number-input/react/NumberInput.tsx +465 -0
  266. package/source/components/number-input/react/icons.tsx +17 -0
  267. package/source/components/number-input/react/locale.ts +7 -0
  268. package/source/components/number-input/react/props.ts +11 -0
  269. package/source/components/number-input/styles.css +230 -0
  270. package/source/components/popover/README.md +44 -0
  271. package/source/components/popover/core/index.ts +2 -0
  272. package/source/components/popover/core/types.ts +12 -0
  273. package/source/components/popover/index.ts +4 -0
  274. package/source/components/popover/passport.json +238 -0
  275. package/source/components/popover/react/Popover.tsx +202 -0
  276. package/source/components/popover/react/locale.ts +5 -0
  277. package/source/components/popover/react/props.ts +4 -0
  278. package/source/components/popover/styles.css +148 -0
  279. package/source/components/progress/README.md +38 -0
  280. package/source/components/progress/core/index.ts +2 -0
  281. package/source/components/progress/core/progress.ts +40 -0
  282. package/source/components/progress/core/types.ts +23 -0
  283. package/source/components/progress/index.ts +7 -0
  284. package/source/components/progress/passport.json +270 -0
  285. package/source/components/progress/react/CircularProgress.tsx +106 -0
  286. package/source/components/progress/react/Progress.tsx +113 -0
  287. package/source/components/progress/react/locale.ts +7 -0
  288. package/source/components/progress/react/props.ts +6 -0
  289. package/source/components/progress/styles.css +200 -0
  290. package/source/components/radio-group/README.md +58 -0
  291. package/source/components/radio-group/core/group.ts +36 -0
  292. package/source/components/radio-group/core/index.ts +2 -0
  293. package/source/components/radio-group/core/types.ts +20 -0
  294. package/source/components/radio-group/index.ts +9 -0
  295. package/source/components/radio-group/passport.json +477 -0
  296. package/source/components/radio-group/react/Radio.tsx +144 -0
  297. package/source/components/radio-group/react/RadioGroup.tsx +179 -0
  298. package/source/components/radio-group/react/context.ts +18 -0
  299. package/source/components/radio-group/react/locale.ts +5 -0
  300. package/source/components/radio-group/react/props.ts +12 -0
  301. package/source/components/radio-group/styles.css +269 -0
  302. package/source/components/shared/README.md +54 -0
  303. package/source/components/shared/core/agent/adapter.ts +65 -0
  304. package/source/components/shared/core/agent/history.ts +120 -0
  305. package/source/components/shared/core/agent/index.ts +46 -0
  306. package/source/components/shared/core/agent/numbers.ts +217 -0
  307. package/source/components/shared/core/agent/schema.ts +180 -0
  308. package/source/components/shared/core/agent/types.ts +169 -0
  309. package/source/components/shared/core/agent/webmcp.ts +328 -0
  310. package/source/components/shared/core/cx.ts +9 -0
  311. package/source/components/shared/core/field.ts +35 -0
  312. package/source/components/shared/core/position.ts +124 -0
  313. package/source/components/shared/core/text.ts +14 -0
  314. package/source/components/shared/index.ts +17 -0
  315. package/source/components/shared/react/GramproAIProvider.tsx +50 -0
  316. package/source/components/shared/react/Popover.tsx +189 -0
  317. package/source/components/shared/react/icons.tsx +74 -0
  318. package/source/components/shared/react/useAskAgent.ts +217 -0
  319. package/source/components/shared/react/useControllableState.ts +42 -0
  320. package/source/components/shared/styles.css +79 -0
  321. package/source/components/shared/version.json +4 -0
  322. package/source/components/shared/version.ts +6 -0
  323. package/source/components/skeleton/README.md +58 -0
  324. package/source/components/skeleton/core/index.ts +3 -0
  325. package/source/components/skeleton/core/lines.ts +25 -0
  326. package/source/components/skeleton/core/types.ts +5 -0
  327. package/source/components/skeleton/index.ts +5 -0
  328. package/source/components/skeleton/passport.json +251 -0
  329. package/source/components/skeleton/react/Empty.tsx +51 -0
  330. package/source/components/skeleton/react/Skeleton.tsx +92 -0
  331. package/source/components/skeleton/react/props.ts +4 -0
  332. package/source/components/skeleton/styles.css +185 -0
  333. package/source/components/spinner/README.md +29 -0
  334. package/source/components/spinner/core/index.ts +3 -0
  335. package/source/components/spinner/core/types.ts +28 -0
  336. package/source/components/spinner/core/visibility.ts +34 -0
  337. package/source/components/spinner/index.ts +6 -0
  338. package/source/components/spinner/passport.json +245 -0
  339. package/source/components/spinner/react/Spinner.tsx +96 -0
  340. package/source/components/spinner/react/locale.ts +5 -0
  341. package/source/components/spinner/react/props.ts +4 -0
  342. package/source/components/spinner/react/useDelayedLoading.ts +39 -0
  343. package/source/components/spinner/styles.css +173 -0
  344. package/source/components/switch/README.md +46 -0
  345. package/source/components/switch/core/index.ts +2 -0
  346. package/source/components/switch/core/toggle.ts +54 -0
  347. package/source/components/switch/core/types.ts +9 -0
  348. package/source/components/switch/index.ts +5 -0
  349. package/source/components/switch/passport.json +421 -0
  350. package/source/components/switch/react/Switch.tsx +219 -0
  351. package/source/components/switch/react/locale.ts +5 -0
  352. package/source/components/switch/react/props.ts +12 -0
  353. package/source/components/switch/styles.css +227 -0
  354. package/source/components/tabs/README.md +32 -0
  355. package/source/components/tabs/core/index.ts +3 -0
  356. package/source/components/tabs/core/navigation.ts +54 -0
  357. package/source/components/tabs/core/types.ts +16 -0
  358. package/source/components/tabs/index.ts +5 -0
  359. package/source/components/tabs/passport.json +315 -0
  360. package/source/components/tabs/react/Tabs.tsx +306 -0
  361. package/source/components/tabs/react/context.ts +21 -0
  362. package/source/components/tabs/styles.css +263 -0
  363. package/source/components/textarea/README.md +39 -0
  364. package/source/components/textarea/core/count.ts +5 -0
  365. package/source/components/textarea/core/index.ts +4 -0
  366. package/source/components/textarea/core/size.ts +23 -0
  367. package/source/components/textarea/core/types.ts +17 -0
  368. package/source/components/textarea/index.ts +5 -0
  369. package/source/components/textarea/passport.json +382 -0
  370. package/source/components/textarea/react/Textarea.tsx +208 -0
  371. package/source/components/textarea/react/locale.ts +5 -0
  372. package/source/components/textarea/react/props.ts +4 -0
  373. package/source/components/textarea/styles.css +158 -0
  374. package/source/components/toaster/README.md +128 -0
  375. package/source/components/toaster/core/api.ts +87 -0
  376. package/source/components/toaster/core/index.ts +14 -0
  377. package/source/components/toaster/core/store.ts +211 -0
  378. package/source/components/toaster/core/toast.ts +12 -0
  379. package/source/components/toaster/core/types.ts +78 -0
  380. package/source/components/toaster/index.ts +6 -0
  381. package/source/components/toaster/passport.json +221 -0
  382. package/source/components/toaster/react/ToastItem.tsx +164 -0
  383. package/source/components/toaster/react/Toaster.tsx +187 -0
  384. package/source/components/toaster/react/icons.tsx +23 -0
  385. package/source/components/toaster/react/locale.ts +6 -0
  386. package/source/components/toaster/react/props.ts +15 -0
  387. package/source/components/toaster/react/useToasts.ts +11 -0
  388. package/source/components/toaster/styles.css +282 -0
  389. package/source/components/tooltip/README.md +43 -0
  390. package/source/components/tooltip/core/index.ts +4 -0
  391. package/source/components/tooltip/core/types.ts +4 -0
  392. package/source/components/tooltip/core/visibility.ts +34 -0
  393. package/source/components/tooltip/index.ts +3 -0
  394. package/source/components/tooltip/passport.json +170 -0
  395. package/source/components/tooltip/react/Tooltip.tsx +196 -0
  396. package/source/components/tooltip/react/props.ts +4 -0
  397. package/source/components/tooltip/styles.css +71 -0
  398. package/source/fallback/index.tsx +11 -0
  399. package/source/globalStyle.ts +74 -0
  400. package/source/hooks/SelectionHooks/type.ts +4 -0
  401. package/source/hooks/SelectionHooks/useClickOutside.ts +22 -0
  402. package/source/hooks/SelectionHooks/useMultiSelectState.ts +64 -0
  403. package/source/hooks/SelectionHooks/useSelectData.ts +58 -0
  404. package/source/hooks/SelectionHooks/useSelectState.ts +36 -0
  405. package/source/icon/Icon.tsx +102 -0
  406. package/source/icon/iconPaths.ts +206 -0
  407. package/source/legacy-components/bargraph/index.tsx +95 -0
  408. package/source/legacy-components/bargraph/type.ts +12 -0
  409. package/source/legacy-components/breadcrumb/index.tsx +66 -0
  410. package/source/legacy-components/breadcrumb/types.ts +10 -0
  411. package/source/legacy-components/button/index.tsx +42 -0
  412. package/source/legacy-components/card/index.tsx +31 -0
  413. package/source/legacy-components/checkbox/index.tsx +25 -0
  414. package/source/legacy-components/contextmenu/ContextMenu.tsx +87 -0
  415. package/source/legacy-components/contextmenu/ContextMenuItem.tsx +30 -0
  416. package/source/legacy-components/contextmenu/index.ts +2 -0
  417. package/source/legacy-components/contextmenu/types.ts +19 -0
  418. package/source/legacy-components/darkmode/index.tsx +55 -0
  419. package/source/legacy-components/datagrid/context/GridContext.tsx +215 -0
  420. package/source/legacy-components/datagrid/createTemplate.tsx +82 -0
  421. package/source/legacy-components/datagrid/hooks/index.ts +6 -0
  422. package/source/legacy-components/datagrid/hooks/useColumns.ts +33 -0
  423. package/source/legacy-components/datagrid/hooks/useDataSource.ts +54 -0
  424. package/source/legacy-components/datagrid/hooks/useFiltering.ts +169 -0
  425. package/source/legacy-components/datagrid/hooks/usePagination.ts +112 -0
  426. package/source/legacy-components/datagrid/hooks/useRowSelection.ts +48 -0
  427. package/source/legacy-components/datagrid/hooks/useSearch.ts +90 -0
  428. package/source/legacy-components/datagrid/index.tsx +28 -0
  429. package/source/legacy-components/datagrid/layout/FilterPopup.tsx +92 -0
  430. package/source/legacy-components/datagrid/layout/GridBody.tsx +184 -0
  431. package/source/legacy-components/datagrid/layout/GridPagination.tsx +119 -0
  432. package/source/legacy-components/datagrid/layout/GridToolbar.tsx +109 -0
  433. package/source/legacy-components/datagrid/layout/index.tsx +68 -0
  434. package/source/legacy-components/datagrid/type.ts +198 -0
  435. package/source/legacy-components/datepicker/index.tsx +365 -0
  436. package/source/legacy-components/datepicker/types.ts +12 -0
  437. package/source/legacy-components/dialog/index.tsx +44 -0
  438. package/source/legacy-components/dialog/types.ts +12 -0
  439. package/source/legacy-components/formrenderer/componentHandles/CheckBoxHandles.tsx +80 -0
  440. package/source/legacy-components/formrenderer/componentHandles/DatePickerHandles.tsx +93 -0
  441. package/source/legacy-components/formrenderer/componentHandles/InputHandles.tsx +106 -0
  442. package/source/legacy-components/formrenderer/componentHandles/MultiHandles.tsx +93 -0
  443. package/source/legacy-components/formrenderer/componentHandles/SelectHandles.tsx +95 -0
  444. package/source/legacy-components/formrenderer/helperFunctions.ts +72 -0
  445. package/source/legacy-components/formrenderer/index.tsx +93 -0
  446. package/source/legacy-components/formrenderer/types.ts +127 -0
  447. package/source/legacy-components/input/index.tsx +142 -0
  448. package/source/legacy-components/input/types.ts +10 -0
  449. package/source/legacy-components/materialInput/index.tsx +138 -0
  450. package/source/legacy-components/materialInput/types.ts +16 -0
  451. package/source/legacy-components/modal/index.tsx +152 -0
  452. package/source/legacy-components/modal/types.ts +19 -0
  453. package/source/legacy-components/multiselect/PortalDropDown.tsx +44 -0
  454. package/source/legacy-components/multiselect/index.tsx +269 -0
  455. package/source/legacy-components/multiselect/types.ts +26 -0
  456. package/source/legacy-components/navbar/AuthSection.tsx +98 -0
  457. package/source/legacy-components/navbar/MobileToggle.tsx +31 -0
  458. package/source/legacy-components/navbar/NavItemComponent.tsx +119 -0
  459. package/source/legacy-components/navbar/SearchBar.tsx +55 -0
  460. package/source/legacy-components/navbar/helperFunctions.ts +27 -0
  461. package/source/legacy-components/navbar/index.tsx +156 -0
  462. package/source/legacy-components/navbar/types.ts +69 -0
  463. package/source/legacy-components/select/PortalDropDown.tsx +59 -0
  464. package/source/legacy-components/select/index.tsx +249 -0
  465. package/source/legacy-components/select/types.ts +29 -0
  466. package/source/legacy-components/sidebar/components/MenuItem.tsx +101 -0
  467. package/source/legacy-components/sidebar/components/MenuSection.tsx +34 -0
  468. package/source/legacy-components/sidebar/components/SidebarFooter.tsx +50 -0
  469. package/source/legacy-components/sidebar/components/SidebarLogo.tsx +24 -0
  470. package/source/legacy-components/sidebar/components/SidebarMenu.tsx +29 -0
  471. package/source/legacy-components/sidebar/components/UserProfile.tsx +31 -0
  472. package/source/legacy-components/sidebar/hooks/useSidebarState.ts +41 -0
  473. package/source/legacy-components/sidebar/index.tsx +77 -0
  474. package/source/legacy-components/sidebar/type.ts +42 -0
  475. package/source/legacy-components/spinner/Stroke.tsx +89 -0
  476. package/source/legacy-components/spinner/index.tsx +54 -0
  477. package/source/legacy-components/spinner/types.ts +9 -0
  478. package/source/legacy-components/tabs/index.tsx +71 -0
  479. package/source/legacy-components/tabs/types.ts +16 -0
  480. package/source/legacy-components/textarea/index.tsx +123 -0
  481. package/source/legacy-components/textarea/types.ts +15 -0
  482. package/source/legacy-components/toast/ToastComponent.tsx +101 -0
  483. package/source/legacy-components/toast/ToastIcon.tsx +61 -0
  484. package/source/legacy-components/toast/index.tsx +42 -0
  485. package/source/legacy-components/toast/toastStore.ts +42 -0
  486. package/source/legacy-components/toast/types.ts +18 -0
  487. package/source/legacy-components/toast/useToast.ts +12 -0
  488. package/source/legacy-components/uploader/ProgressAnimation.tsx +50 -0
  489. package/source/legacy-components/uploader/UploadedFilePreview.tsx +130 -0
  490. package/source/legacy-components/uploader/index.tsx +311 -0
  491. package/source/legacy-components/uploader/types.ts +30 -0
  492. package/source/legacy-components/uploader/uploaderIcon.tsx +72 -0
  493. package/source/legacy-components/uploader/uploaderService.ts +134 -0
  494. package/source/legacy-components/useUploader/useUploader.tsx +310 -0
  495. package/source/legacy-components/usepaginateddata/usePaginatedData.ts +174 -0
  496. package/source/theme.ts +40 -0
  497. package/source/utils.ts +10 -0
  498. package/tools/env.cjs +61 -0
  499. package/tools/passport/cli.cjs +79 -0
  500. package/tools/passport/extract.cjs +493 -0
  501. package/tools/passport/index.cjs +185 -0
  502. package/tools/passport/merge.cjs +131 -0
  503. package/tools/passport/policy.cjs +65 -0
  504. package/tools/passport/validate.cjs +277 -0
  505. package/tools/ts-require.cjs +79 -0
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import { createContext, useContext, useMemo, type ReactNode } from "react";
4
+ import type { AgentAdapter } from "../core/agent/adapter";
5
+
6
+ /*
7
+ * Where an application plugs its own language model in.
8
+ *
9
+ * Nothing below this provider knows which one it is. A component asks the
10
+ * context for an adapter; if there is none, the component renders exactly as
11
+ * it does today and its natural-language affordance is simply absent. That is
12
+ * the whole opt-in: no provider, no AI, no bytes, no network.
13
+ */
14
+
15
+ interface AIContextValue {
16
+ adapter: AgentAdapter | null;
17
+ /** Shown above the input, e.g. "Ask about these customers". */
18
+ placeholder?: string;
19
+ /** Example utterances offered as one-click suggestions. */
20
+ suggestions?: readonly string[];
21
+ }
22
+
23
+ const AIContext = createContext<AIContextValue>({ adapter: null });
24
+
25
+ export interface GramproAIProviderProps extends AIContextValue {
26
+ children: ReactNode;
27
+ }
28
+
29
+ export function GramproAIProvider({
30
+ adapter,
31
+ placeholder,
32
+ suggestions,
33
+ children,
34
+ }: GramproAIProviderProps) {
35
+ const value = useMemo(
36
+ () => ({ adapter, placeholder, suggestions }),
37
+ [adapter, placeholder, suggestions],
38
+ );
39
+ return <AIContext.Provider value={value}>{children}</AIContext.Provider>;
40
+ }
41
+
42
+ /**
43
+ * The adapter in scope, or null.
44
+ *
45
+ * Null is an ordinary case, not an error: a component asks, gets nothing, and
46
+ * renders without the affordance.
47
+ */
48
+ export function useAgentAdapter(): AIContextValue {
49
+ return useContext(AIContext);
50
+ }
@@ -0,0 +1,189 @@
1
+ "use client";
2
+
3
+ import { useLayoutEffect, useRef, type ReactNode, type ToggleEvent } from "react";
4
+ import { cx } from "../core/cx";
5
+ import { placePopover, type Align, type Side } from "../core/position";
6
+
7
+ /** Space kept between the popover and the edge of the viewport. */
8
+ const EDGE = 8;
9
+
10
+ export interface AnchoredPopoverProps {
11
+ /** The element the popover is positioned against. */
12
+ anchor: HTMLElement;
13
+ /** Called when the browser light-dismisses it, or Escape closes it. */
14
+ onClose(): void;
15
+ children: ReactNode;
16
+ id?: string;
17
+ className?: string;
18
+ /**
19
+ * Gives the popover `role="dialog"` and this accessible name. Leave it and
20
+ * `labelledBy` out for content that carries its own role, such as a listbox.
21
+ */
22
+ label?: string;
23
+ /** Names the popover from an element inside it, such as its heading. */
24
+ labelledBy?: string;
25
+ /** Points at a description inside the popover. */
26
+ describedBy?: string;
27
+ /** `menu` for a list of commands, `tooltip` for a label; otherwise a dialog. */
28
+ role?: "dialog" | "menu" | "tooltip";
29
+ /** The side of the anchor to open on, before flipping. Default `bottom`. */
30
+ side?: Side;
31
+ /** Which edge of the anchor to align to, in reading order. Default `start`. */
32
+ align?: Align;
33
+ /** Distance between the anchor and the popover. Default 4. */
34
+ gap?: number;
35
+ /** Make the popover at least as wide as its anchor. */
36
+ matchAnchorWidth?: boolean;
37
+ /**
38
+ * Cap the height to the free space on the chosen side, and prefer the side
39
+ * with more room. For scrolling content such as a long list; panels that
40
+ * cannot scroll should leave it off so they only flip when they fully fit.
41
+ */
42
+ fitHeight?: boolean;
43
+ /** Floor for `fitHeight`, so a cramped viewport still shows something. Default 140. */
44
+ minHeight?: number;
45
+ /**
46
+ * Where focus goes when it opens: a selector, `true` for the first
47
+ * `[data-autofocus]` and otherwise the popover itself, or `false` to leave
48
+ * focus where it is. A popover focused this way needs `tabIndex={-1}`.
49
+ */
50
+ autoFocus?: string | boolean;
51
+ /** Reposition when the popover resizes (`self`) or the anchor does too (`both`). */
52
+ observeResize?: "self" | "both" | false;
53
+ /** Put focus back on the anchor when the popover closes. */
54
+ returnFocus?: boolean;
55
+ /**
56
+ * `auto` (the default) gets the browser's light dismiss and Escape, and is
57
+ * right for anything opened deliberately. `manual` opts out of both, for
58
+ * content that appears beside something else and must not close it: opening
59
+ * an `auto` popover closes every other one, so a tooltip or a submenu over an
60
+ * open menu would take the menu down with it. Manual popovers handle their
61
+ * own dismissal.
62
+ */
63
+ mode?: "auto" | "manual";
64
+ }
65
+
66
+ /**
67
+ * Anchored popover on the native Popover API: rendered in the top layer, so it
68
+ * is never clipped by a scrolling parent or an `overflow: hidden` ancestor, and
69
+ * the browser provides light dismiss and Escape. Mount it to open, unmount it
70
+ * to close.
71
+ *
72
+ * Positioning is deliberately plain — align, clamp to the viewport, flip when
73
+ * there is no room below — because that is all any of the components need, and
74
+ * it keeps the library free of a positioning dependency.
75
+ */
76
+ export function AnchoredPopover({
77
+ anchor,
78
+ onClose,
79
+ children,
80
+ id,
81
+ className,
82
+ label,
83
+ labelledBy,
84
+ describedBy,
85
+ role,
86
+ side = "bottom",
87
+ align = "start",
88
+ gap = 4,
89
+ matchAnchorWidth = false,
90
+ fitHeight = false,
91
+ minHeight = 140,
92
+ autoFocus = "[data-autofocus]",
93
+ observeResize = false,
94
+ returnFocus = false,
95
+ mode = "auto",
96
+ }: AnchoredPopoverProps) {
97
+ const ref = useRef<HTMLDivElement>(null);
98
+
99
+ useLayoutEffect(() => {
100
+ const el = ref.current;
101
+ if (!el) return;
102
+
103
+ const position = () => {
104
+ const rect = anchor.getBoundingClientRect();
105
+ if (matchAnchorWidth) el.style.minWidth = `${rect.width}px`;
106
+
107
+ const placement = placePopover(
108
+ rect,
109
+ { width: el.offsetWidth, height: el.offsetHeight },
110
+ { width: window.innerWidth, height: window.innerHeight },
111
+ {
112
+ side,
113
+ align,
114
+ gap,
115
+ edge: EDGE,
116
+ rtl: getComputedStyle(anchor).direction === "rtl",
117
+ fitHeight,
118
+ minHeight,
119
+ },
120
+ );
121
+
122
+ el.style.left = `${placement.left}px`;
123
+ el.style.top = `${placement.top}px`;
124
+ if (placement.maxHeight !== undefined) el.style.maxHeight = `${placement.maxHeight}px`;
125
+ // Lets a stylesheet point an arrow, or slide the panel in from the right
126
+ // direction, without measuring anything itself.
127
+ el.dataset.side = placement.side;
128
+ };
129
+
130
+ el.showPopover();
131
+ position();
132
+ // A popover is display:none until it is shown, so focus only lands after
133
+ // showPopover().
134
+ if (autoFocus) {
135
+ const selector = typeof autoFocus === "string" ? autoFocus : "[data-autofocus]";
136
+ const target = el.querySelector<HTMLElement>(selector) ?? (autoFocus === true ? el : null);
137
+ target?.focus({ preventScroll: true });
138
+ }
139
+
140
+ const observer = observeResize ? new ResizeObserver(position) : null;
141
+ observer?.observe(el);
142
+ if (observeResize === "both") observer?.observe(anchor);
143
+ window.addEventListener("resize", position);
144
+ // Capture: a scroll in any ancestor moves the anchor, not just the page.
145
+ window.addEventListener("scroll", position, true);
146
+
147
+ return () => {
148
+ observer?.disconnect();
149
+ window.removeEventListener("resize", position);
150
+ window.removeEventListener("scroll", position, true);
151
+ const hadFocus = el.contains(document.activeElement);
152
+ if (el.matches(":popover-open")) el.hidePopover();
153
+ if (returnFocus && (hadFocus || document.activeElement === document.body) && anchor.isConnected) {
154
+ anchor.focus({ preventScroll: true });
155
+ }
156
+ };
157
+ }, [
158
+ anchor,
159
+ side,
160
+ align,
161
+ gap,
162
+ matchAnchorWidth,
163
+ fitHeight,
164
+ minHeight,
165
+ autoFocus,
166
+ observeResize,
167
+ returnFocus,
168
+ ]);
169
+
170
+ return (
171
+ <div
172
+ ref={ref}
173
+ id={id}
174
+ popover={mode}
175
+ // Focusable only from script, so `autoFocus` can land on the panel itself.
176
+ tabIndex={-1}
177
+ role={role ?? (label || labelledBy ? "dialog" : undefined)}
178
+ aria-label={label}
179
+ aria-labelledby={labelledBy}
180
+ aria-describedby={describedBy}
181
+ className={cx(className)}
182
+ onToggle={(event: ToggleEvent<HTMLDivElement>) => {
183
+ if (event.newState === "closed") onClose();
184
+ }}
185
+ >
186
+ {children}
187
+ </div>
188
+ );
189
+ }
@@ -0,0 +1,74 @@
1
+ import type { SVGProps } from "react";
2
+
3
+ export type IconProps = SVGProps<SVGSVGElement>;
4
+
5
+ /**
6
+ * The base every icon draws on: a 24-unit grid, stroked in `currentColor`, and
7
+ * hidden from assistive technology because the control around it carries the
8
+ * name. Size it by passing `width` and `height`.
9
+ */
10
+ export function Svg(props: IconProps) {
11
+ return (
12
+ <svg
13
+ width="16"
14
+ height="16"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ stroke="currentColor"
18
+ strokeWidth="2"
19
+ strokeLinecap="round"
20
+ strokeLinejoin="round"
21
+ aria-hidden="true"
22
+ focusable="false"
23
+ {...props}
24
+ />
25
+ );
26
+ }
27
+
28
+ /*
29
+ * Glyphs more than one component draws. A component keeps its own icons file
30
+ * for anything only it uses, and re-exports from here for the rest, so a fix to
31
+ * a shape lands everywhere at once.
32
+ */
33
+
34
+ export const XIcon = (p: IconProps) => <Svg {...p}><path d="M18 6 6 18M6 6l12 12" /></Svg>;
35
+ export const CheckIcon = (p: IconProps) => <Svg {...p}><path d="M20 6 9 17l-5-5" /></Svg>;
36
+ export const ChevronDownIcon = (p: IconProps) => <Svg {...p}><path d="m6 9 6 6 6-6" /></Svg>;
37
+ export const ChevronLeftIcon = (p: IconProps) => <Svg {...p}><path d="m15 18-6-6 6-6" /></Svg>;
38
+ export const ChevronRightIcon = (p: IconProps) => <Svg {...p}><path d="m9 18 6-6-6-6" /></Svg>;
39
+
40
+ export const SearchIcon = (p: IconProps) => (
41
+ <Svg {...p}><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /></Svg>
42
+ );
43
+
44
+ export const SuccessIcon = (p: IconProps) => (
45
+ <Svg {...p}>
46
+ <circle cx="12" cy="12" r="9" />
47
+ <path d="m8 12.5 2.5 2.5L16 9.5" />
48
+ </Svg>
49
+ );
50
+
51
+ /** The circled exclamation used for errors, danger and alerts alike. */
52
+ export const AlertCircleIcon = (p: IconProps) => (
53
+ <Svg {...p}>
54
+ <circle cx="12" cy="12" r="9" />
55
+ <path d="M12 7.5v5.5M12 16.5h.01" />
56
+ </Svg>
57
+ );
58
+
59
+ export const WarningIcon = (p: IconProps) => (
60
+ <Svg {...p}>
61
+ <path d="M10.3 3.9 2.4 18a2 2 0 0 0 1.7 3h15.8a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" />
62
+ <path d="M12 9v4M12 17h.01" />
63
+ </Svg>
64
+ );
65
+
66
+ export const InfoIcon = (p: IconProps) => (
67
+ <Svg {...p}>
68
+ <circle cx="12" cy="12" r="9" />
69
+ <path d="M12 11v5M12 7.5h.01" />
70
+ </Svg>
71
+ );
72
+
73
+ /** The arc only; the spin comes from each component's own stylesheet. */
74
+ export const SpinnerIcon = (p: IconProps) => <Svg {...p}><path d="M12 3a9 9 0 1 0 9 9" /></Svg>;
@@ -0,0 +1,217 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import type { AgentAdapter, AskOutcome } from "../core/agent/adapter";
5
+ import type { JsonSchema } from "../core/agent/types";
6
+
7
+ /*
8
+ * One request, end to end: what a person typed goes to the adapter, the
9
+ * adapter's answer goes to the validator, and only a validated command runs.
10
+ *
11
+ * The order is the point. This hook never looks at the answer's contents to
12
+ * decide anything — it hands the envelope to `respond()` and reports what came
13
+ * back. A producer that returns nonsense, a stale schema, or an operation the
14
+ * component does not have is refused by the same five layers a form faces, and
15
+ * the person sees the validator's own words rather than a guess.
16
+ */
17
+
18
+ /** The part of a component's agent this hook uses. */
19
+ export interface AskableAgent {
20
+ contract(): unknown;
21
+ responseSchema(): JsonSchema;
22
+ /** Validates a whole envelope. Does not change anything. */
23
+ respond(response: unknown): AskExecution;
24
+ execute(intent: unknown, options?: { confirm?: boolean }): Promise<AskExecution>;
25
+ }
26
+
27
+ /** The statuses a component's validator and executor answer with. */
28
+ export type AskExecution =
29
+ | {
30
+ status: "done";
31
+ commands: readonly { explain: { summary: string } }[];
32
+ warnings: readonly { code: string; message: string }[];
33
+ }
34
+ | {
35
+ status: "needs-confirmation";
36
+ commands: readonly { explain: { summary: string } }[];
37
+ confirm: { code: string; message: string };
38
+ }
39
+ | { status: "rejected"; reason: string; code: string; layer: string; suggestion?: string }
40
+ | { status: "clarify"; question: string; options?: readonly string[] }
41
+ | { status: "declined"; reason: string };
42
+
43
+ const IDLE: AskOutcome = { phase: "idle", message: "" };
44
+
45
+ export interface UseAskAgent {
46
+ ask(utterance: string): Promise<void>;
47
+ /** Run a `needs-confirmation` request the person has now agreed to. */
48
+ confirm(): Promise<void>;
49
+ reset(): void;
50
+ outcome: AskOutcome;
51
+ busy: boolean;
52
+ /** Set when the last answer stopped to ask; `confirm()` applies it. */
53
+ pending: unknown;
54
+ }
55
+
56
+ export function useAskAgent(
57
+ agent: AskableAgent | null,
58
+ adapter: AgentAdapter | null,
59
+ ): UseAskAgent {
60
+ const [outcome, setOutcome] = useState<AskOutcome>(IDLE);
61
+ const [busy, setBusy] = useState(false);
62
+ const [pending, setPending] = useState<unknown>(null);
63
+
64
+ // One request at a time: typing again abandons the one in flight rather
65
+ // than racing it to the grid.
66
+ const inFlight = useRef<AbortController | null>(null);
67
+ const alive = useRef(true);
68
+ useEffect(() => {
69
+ alive.current = true;
70
+ return () => {
71
+ alive.current = false;
72
+ inFlight.current?.abort();
73
+ };
74
+ }, []);
75
+
76
+ const report = useCallback((next: AskOutcome) => {
77
+ if (alive.current) setOutcome(next);
78
+ }, []);
79
+
80
+ /** Turn a validator answer into something to show, and run it when allowed. */
81
+ const settle = useCallback(
82
+ async (verdict: AskExecution, intents: unknown, raw: unknown) => {
83
+ if (verdict.status === "rejected") {
84
+ report({
85
+ phase: "refused",
86
+ message: verdict.reason,
87
+ code: verdict.code,
88
+ layer: verdict.layer,
89
+ suggestion: verdict.suggestion,
90
+ raw,
91
+ });
92
+ return;
93
+ }
94
+ if (verdict.status === "clarify") {
95
+ report({ phase: "clarify", message: verdict.question, raw });
96
+ return;
97
+ }
98
+ if (verdict.status === "declined") {
99
+ report({ phase: "refused", message: verdict.reason, raw });
100
+ return;
101
+ }
102
+ if (verdict.status === "needs-confirmation") {
103
+ setPending(intents);
104
+ report({
105
+ phase: "clarify",
106
+ message: verdict.confirm.message,
107
+ code: verdict.confirm.code,
108
+ raw,
109
+ });
110
+ return;
111
+ }
112
+
113
+ const run = await agent!.execute(intents);
114
+ if (run.status !== "done") {
115
+ report({
116
+ phase: "refused",
117
+ message: "reason" in run ? run.reason : run.status,
118
+ raw,
119
+ });
120
+ return;
121
+ }
122
+ report({
123
+ phase: "done",
124
+ message: run.commands.map((command) => command.explain.summary).join("; "),
125
+ warnings: run.warnings.map((warning) => `${warning.code}: ${warning.message}`),
126
+ raw,
127
+ });
128
+ },
129
+ [agent, report],
130
+ );
131
+
132
+ const ask = useCallback(
133
+ async (utterance: string) => {
134
+ const text = utterance.trim();
135
+ if (!agent || !adapter || text === "") return;
136
+
137
+ inFlight.current?.abort();
138
+ const controller = new AbortController();
139
+ inFlight.current = controller;
140
+
141
+ setPending(null);
142
+ setBusy(true);
143
+ report({ phase: "thinking", message: "" });
144
+
145
+ let raw: unknown;
146
+ try {
147
+ raw = await adapter({
148
+ utterance: text,
149
+ contract: agent.contract(),
150
+ responseSchema: agent.responseSchema(),
151
+ signal: controller.signal,
152
+ });
153
+ } catch (error) {
154
+ if (!controller.signal.aborted) {
155
+ // Reaching the producer failed. That is not the producer refusing,
156
+ // and saying so avoids blaming the person's wording.
157
+ report({
158
+ phase: "error",
159
+ message: error instanceof Error ? error.message : String(error),
160
+ });
161
+ }
162
+ if (alive.current && inFlight.current === controller) setBusy(false);
163
+ return;
164
+ }
165
+
166
+ if (controller.signal.aborted) return;
167
+
168
+ try {
169
+ const intents =
170
+ raw && typeof raw === "object" && "intents" in raw
171
+ ? (raw as { intents: unknown }).intents
172
+ : raw;
173
+ await settle(agent.respond(raw), intents, raw);
174
+ } catch (error) {
175
+ report({
176
+ phase: "error",
177
+ message: error instanceof Error ? error.message : String(error),
178
+ raw,
179
+ });
180
+ } finally {
181
+ if (alive.current && inFlight.current === controller) setBusy(false);
182
+ }
183
+ },
184
+ [adapter, agent, report, settle],
185
+ );
186
+
187
+ const confirm = useCallback(async () => {
188
+ if (!agent || pending === null) return;
189
+ setBusy(true);
190
+ try {
191
+ // Without the flag the executor stops and asks again, forever.
192
+ const run = await agent.execute(pending, { confirm: true });
193
+ report(
194
+ run.status === "done"
195
+ ? {
196
+ phase: "done",
197
+ message: run.commands.map((command) => command.explain.summary).join("; "),
198
+ }
199
+ : {
200
+ phase: "refused",
201
+ message: "reason" in run ? run.reason : run.status,
202
+ },
203
+ );
204
+ setPending(null);
205
+ } finally {
206
+ if (alive.current) setBusy(false);
207
+ }
208
+ }, [agent, pending, report]);
209
+
210
+ const reset = useCallback(() => {
211
+ inFlight.current?.abort();
212
+ setPending(null);
213
+ report(IDLE);
214
+ }, [report]);
215
+
216
+ return { ask, confirm, reset, outcome, busy, pending };
217
+ }
@@ -0,0 +1,42 @@
1
+ "use client";
2
+
3
+ import { useCallback, useState } from "react";
4
+
5
+ /**
6
+ * One value that may be controlled by the caller or owned by the component.
7
+ *
8
+ * Pass the `value` prop (or `undefined`) and the `defaultValue`. The returned
9
+ * setter writes internal state only while the component is uncontrolled, so a
10
+ * controlled caller stays the single source of truth and the component never
11
+ * renders a value its parent did not hand it.
12
+ *
13
+ * Change callbacks stay with the component: they differ too much between
14
+ * controls — some pass a DOM event, some skip a no-op change — and hiding them
15
+ * here would only move the difference somewhere less obvious.
16
+ *
17
+ * ```ts
18
+ * const [value, setValue] = useControllableState(valueProp, defaultValue ?? "");
19
+ *
20
+ * const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
21
+ * setValue(event.target.value);
22
+ * onChange?.(event);
23
+ * };
24
+ * ```
25
+ */
26
+ export function useControllableState<T>(
27
+ controlled: T | undefined,
28
+ defaultValue: T | (() => T),
29
+ ): readonly [T, (next: T) => void, boolean] {
30
+ const [internal, setInternal] = useState(defaultValue);
31
+ const isControlled = controlled !== undefined;
32
+ const value = isControlled ? controlled : internal;
33
+
34
+ const setValue = useCallback(
35
+ (next: T) => {
36
+ if (!isControlled) setInternal(next);
37
+ },
38
+ [isControlled],
39
+ );
40
+
41
+ return [value, setValue, isControlled] as const;
42
+ }
@@ -0,0 +1,79 @@
1
+ /*
2
+ * Shared defaults every component can rely on.
3
+ *
4
+ * Rules are unlayered: they beat a framework reset on specificity, and lose to
5
+ * anything you pass through `className`. With Tailwind v4, import this file
6
+ * after the framework and inside its components layer - see the README.
7
+ *
8
+ * Right now this file is scrollbars. Each component carries its own fallback
9
+ * values, so a component installed on its own still looks right; what lives
10
+ * here is the single place to theme them, and the `gbs-scroll` class for your
11
+ * own scrolling areas.
12
+ */
13
+
14
+ /*
15
+ * Thin scrollbars, themed with the rest of the kit.
16
+ *
17
+ * `scrollbar-width` and `scrollbar-color` are the standard properties -
18
+ * Baseline since December 2024 - rather than the `::-webkit-scrollbar`
19
+ * pseudo-elements. Two reasons: the standard ones are what the other browsers
20
+ * implement, and mixing the two is a known way to get a scrollbar that is thin
21
+ * in one engine and default in another. `scrollbar-width` takes no length,
22
+ * only `auto | thin | none`, so `thin` is the whole control surface.
23
+ *
24
+ * Override any of these on `:root` to restyle every scrollbar at once, or on
25
+ * one element to restyle that one:
26
+ *
27
+ * :root {
28
+ * --gbs-scrollbar-width: auto; bring the chunky ones back
29
+ * --gbs-scrollbar-thumb: var(--gbs-accent); tint them with the brand
30
+ * }
31
+ */
32
+ :root {
33
+ /* `auto | thin | none`. `thin` is the default across the kit. */
34
+ --gbs-scrollbar-width: thin;
35
+
36
+ /*
37
+ * Derived from the accent so a themed kit themes its scrollbars too, and
38
+ * muted hard, because a scrollbar is furniture rather than content. The
39
+ * fallbacks are the same neutral the components use when untouched.
40
+ */
41
+ --gbs-scrollbar-thumb: color-mix(
42
+ in oklab,
43
+ var(--gbs-accent, light-dark(#2563eb, #60a5fa)) 28%,
44
+ light-dark(#a1a1aa, #52525b)
45
+ );
46
+ --gbs-scrollbar-thumb-hover: color-mix(
47
+ in oklab,
48
+ var(--gbs-accent, light-dark(#2563eb, #60a5fa)) 55%,
49
+ light-dark(#71717a, #71717a)
50
+ );
51
+ /* Transparent by default: a track that is a visible stripe reads as heavier
52
+ than the scrollbar it holds. */
53
+ --gbs-scrollbar-track: transparent;
54
+ }
55
+
56
+ /*
57
+ * Apply to your own scrolling areas to match the components:
58
+ *
59
+ * <div class="gbs-scroll">…</div>
60
+ *
61
+ * `:where()` keeps the specificity at zero, so a single utility class of your
62
+ * own still wins without `!important`.
63
+ */
64
+ :where(.gbs-scroll) {
65
+ scrollbar-width: var(--gbs-scrollbar-width, thin);
66
+ scrollbar-color: var(--gbs-scrollbar-thumb, light-dark(#c4c4ca, #3f3f46))
67
+ var(--gbs-scrollbar-track, transparent);
68
+ }
69
+
70
+ /*
71
+ * The hover brightening is a progressive enhancement: `scrollbar-color` does
72
+ * not transition, and a pointer-coarse device has no hover to speak of.
73
+ */
74
+ @media (hover: hover) {
75
+ :where(.gbs-scroll):hover {
76
+ scrollbar-color: var(--gbs-scrollbar-thumb-hover, light-dark(#a1a1aa, #52525b))
77
+ var(--gbs-scrollbar-track, transparent);
78
+ }
79
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "shared",
3
+ "version": "1.3.0"
4
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Bumped whenever anything in `shared/` changes. The installer copies
3
+ * `version.json` next to it and compares the two, so a project is never left
4
+ * with components built against a newer `shared/` than the one on disk.
5
+ */
6
+ export const version = "1.3.0";