@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,158 @@
1
+ /*
2
+ * Textarea styles.
3
+ *
4
+ * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
+ * (set them on :root to theme every component at once) and fall back to the
6
+ * same default palette otherwise. Rules are unlayered: they beat a framework
7
+ * reset on specificity, and lose to anything you pass through `className`.
8
+ * With Tailwind v4, import this file after the framework and inside its
9
+ * components layer - see the README.
10
+ */
11
+
12
+ .ta-root {
13
+ --ta-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
14
+ --ta-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
15
+ --ta-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
16
+ --ta-input-bg: var(--gbs-input-bg, var(--dg-input-bg, light-dark(#ffffff, #121216)));
17
+ --ta-readonly-bg: var(--gbs-readonly-bg, light-dark(#fafafa, #0e0e12));
18
+ --ta-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
19
+ --ta-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
20
+ --ta-radius: var(--gbs-radius, var(--dg-radius, 8px));
21
+ --ta-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
22
+ --ta-px: 10px;
23
+ --ta-py: 8px;
24
+
25
+ color-scheme: inherit;
26
+ display: flex;
27
+ flex-direction: column;
28
+ gap: 4px;
29
+ width: 100%;
30
+ min-width: 0;
31
+ font-size: var(--ta-font-size);
32
+ line-height: 1.4;
33
+ color: var(--ta-fg);
34
+ }
35
+
36
+ :where(.dark, [data-theme="dark"]) .ta-root {
37
+ color-scheme: dark;
38
+ }
39
+ :where(.light, [data-theme="light"]) .ta-root {
40
+ color-scheme: light;
41
+ }
42
+
43
+ :where(.ta-root) *,
44
+ :where(.ta-root) *::before,
45
+ :where(.ta-root) *::after {
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ .ta-root[data-size="sm"] {
50
+ --ta-font-size: 12px;
51
+ --ta-px: 8px;
52
+ --ta-py: 6px;
53
+ }
54
+ .ta-root[data-size="lg"] {
55
+ --ta-font-size: 14px;
56
+ --ta-px: 12px;
57
+ --ta-py: 10px;
58
+ }
59
+
60
+ .ta-label {
61
+ font-weight: 500;
62
+ }
63
+ .ta-label[data-required]::after {
64
+ content: " *";
65
+ color: var(--ta-danger);
66
+ }
67
+
68
+ .ta-input {
69
+ display: block;
70
+ width: 100%;
71
+ min-height: calc(1lh + 2 * var(--ta-py) + 2px);
72
+ margin: 0;
73
+ padding: var(--ta-py) var(--ta-px);
74
+ border: 1px solid var(--ta-border);
75
+ border-radius: var(--ta-radius);
76
+ background: var(--ta-input-bg);
77
+ color: inherit;
78
+ font: inherit;
79
+ line-height: 1.5;
80
+ }
81
+ .ta-input::placeholder {
82
+ color: var(--ta-muted);
83
+ }
84
+ .ta-input:hover:not(:disabled) {
85
+ border-color: color-mix(in oklab, var(--ta-border), var(--ta-fg) 25%);
86
+ }
87
+ .ta-input:focus-visible {
88
+ outline: 2px solid var(--ta-focus);
89
+ outline-offset: -1px;
90
+ }
91
+ .ta-input[data-invalid] {
92
+ border-color: var(--ta-danger);
93
+ outline-color: var(--ta-danger);
94
+ }
95
+ .ta-input:read-only {
96
+ background: var(--ta-readonly-bg);
97
+ }
98
+ .ta-input:disabled {
99
+ opacity: 0.55;
100
+ cursor: not-allowed;
101
+ }
102
+
103
+ .ta-input[data-resize="none"] {
104
+ resize: none;
105
+ }
106
+ .ta-input[data-resize="vertical"] {
107
+ resize: vertical;
108
+ }
109
+ .ta-input[data-resize="horizontal"] {
110
+ resize: horizontal;
111
+ }
112
+ .ta-input[data-resize="both"] {
113
+ resize: both;
114
+ }
115
+
116
+ /*
117
+ * Auto-resize in CSS where supported. The row limits come from the
118
+ * component; `--ta-max-rows: none` makes max-height invalid, which means no limit.
119
+ */
120
+ @supports (field-sizing: content) {
121
+ .ta-input[data-autoresize] {
122
+ field-sizing: content;
123
+ min-height: calc(var(--ta-min-rows, 3) * 1lh + 2 * var(--ta-py) + 2px);
124
+ max-height: calc(var(--ta-max-rows) * 1lh + 2 * var(--ta-py) + 2px);
125
+ }
126
+ }
127
+
128
+ .ta-footer {
129
+ display: flex;
130
+ align-items: baseline;
131
+ gap: 8px;
132
+ }
133
+ .ta-description {
134
+ flex: 1 1 auto;
135
+ min-width: 0;
136
+ color: var(--ta-muted);
137
+ font-size: 0.92em;
138
+ }
139
+ .ta-count {
140
+ flex: none;
141
+ margin-inline-start: auto;
142
+ color: var(--ta-muted);
143
+ font-size: 0.92em;
144
+ font-variant-numeric: tabular-nums;
145
+ }
146
+ .ta-count[data-over] {
147
+ color: var(--ta-danger);
148
+ }
149
+ .ta-error {
150
+ color: var(--ta-danger);
151
+ font-size: 0.92em;
152
+ }
153
+
154
+ @media (forced-colors: active) {
155
+ .ta-input:focus-visible {
156
+ outline-color: Highlight;
157
+ }
158
+ }
@@ -0,0 +1,128 @@
1
+ # Toaster
2
+
3
+ Notifications for any React 19 app — Vite, Next.js, Remix or plain React — styled
4
+ to match the DataGrid, Combobox and DatePicker. No runtime dependencies besides
5
+ React.
6
+
7
+ - **`<Toaster />`** — mount once; renders the toasts.
8
+ - **`toast()`** — call from anywhere: components, event handlers, data layers,
9
+ even code outside React. No hook, context or provider.
10
+
11
+ ## Setup
12
+
13
+ ```ts
14
+ import { toast, Toaster } from "@/components/toaster";
15
+ import "@/components/toaster/styles.css";
16
+ ```
17
+
18
+ ```tsx
19
+ // Once, near the root of the app (e.g. app/layout.tsx or App.tsx)
20
+ <Toaster />
21
+
22
+ // Anywhere
23
+ toast.success("Settings saved");
24
+ ```
25
+
26
+ Import from one path everywhere. `toast()` and `<Toaster />` meet through a
27
+ shared store, and a bundler that sees two import paths may create two stores.
28
+
29
+ ## Showing toasts
30
+
31
+ ```tsx
32
+ toast("Event created", { description: "Monday, 10:00" });
33
+ toast.success("Saved");
34
+ toast.error("Upload failed", { action: { label: "Retry", onClick: retry } });
35
+ toast.warning("Storage almost full");
36
+ toast.info("New version available");
37
+ const id = toast.loading("Uploading…"); // stays until updated
38
+
39
+ toast.update(id, { type: "success", title: "Uploaded" });
40
+ toast.dismiss(id); // or toast.dismiss() for all
41
+
42
+ toast.promise(saveUser(data), {
43
+ loading: "Saving…",
44
+ success: (user) => `${user.name} saved`,
45
+ error: (error) => `Could not save: ${(error as Error).message}`,
46
+ });
47
+
48
+ toast.custom(({ dismiss }) => <MyCard onClose={dismiss} />);
49
+ ```
50
+
51
+ Every call returns the toast's id. Passing an `id` that is already on screen
52
+ updates that toast instead of adding another.
53
+
54
+ ## Toast options
55
+
56
+ | Option | Type | Default | Description |
57
+ | --- | --- | --- | --- |
58
+ | `id` | `string` | generated | Reuse to update a toast in place. |
59
+ | `type` | `"default"` \| `"success"` \| `"error"` \| `"warning"` \| `"info"` \| `"loading"` | `"default"` | Icon, color bar and announcement. |
60
+ | `description` | `ReactNode` | — | Second line. |
61
+ | `duration` | `number` | `5000` (loading: stays) | Milliseconds. `0` or `Infinity` stays until dismissed. |
62
+ | `dismissible` | `boolean` | `true` | Close button, Escape and swipe. |
63
+ | `action` / `cancel` | `{ label, onClick(event) }` | — | Buttons. The toast closes after a click unless `event.preventDefault()` is called. |
64
+ | `icon` | `ReactNode` | the type's icon | `null` hides it. |
65
+ | `className` | `string` | — | Class for this toast. |
66
+ | `render` | `({ id, dismiss }) => ReactNode` | — | Custom body (`toast.custom` sets it). |
67
+ | `onDismiss` / `onAutoClose` | `(toast) => void` | — | Closed by someone, or because time ran out. |
68
+
69
+ ## Toaster props
70
+
71
+ | Prop | Type | Default | Description |
72
+ | --- | --- | --- | --- |
73
+ | `position` | `"top-left"` \| `"top-center"` \| `"top-right"` \| `"bottom-left"` \| `"bottom-center"` \| `"bottom-right"` | `"top-right"` | Where the stack sits. Full width on narrow screens. |
74
+ | `limit` | `number` | `3` | Toasts on screen at once. The rest wait, with their timers held. |
75
+ | `duration` | `number` | `5000` | Default auto-close delay. |
76
+ | `closeButton` | `boolean` | `true` | Close button on dismissible toasts. |
77
+ | `hotkey` | `string[]` | `["altKey", "KeyT"]` | Moves focus to the notifications. `[]` turns it off. |
78
+ | `icons` | `Partial<Record<ToastType, ReactNode>>` | — | Replace icons per type; `null` hides one. |
79
+ | `store` | `ToastStore` | the `toast()` store | For a separate notification area. |
80
+ | `dir` | `"ltr"` \| `"rtl"` \| `"auto"` | inherited | Text direction. |
81
+ | `className`, `classNames`, `style` | — | — | Slots: `region`, `list`, `toast`, `icon`, `content`, `title`, `description`, `actions`, `action`, `cancel`, `close`. |
82
+ | `localeText` | `Partial<ToasterLocaleText>` | English | `regionLabel(hotkey)`, `close`. |
83
+
84
+ ## Behavior
85
+
86
+ - Timers pause while the pointer is over the toasts, while focus is inside them,
87
+ and while the browser tab is hidden.
88
+ - Toasts beyond `limit` wait with their full time and appear as others close.
89
+ - Toasts render in a portal on `<body>`, so no parent's overflow, transform or
90
+ z-index can hide them.
91
+
92
+ ## Keyboard and accessibility
93
+
94
+ | Keys | Action |
95
+ | --- | --- |
96
+ | **Alt + T** | Move focus to the notifications (configurable with `hotkey`). |
97
+ | **Tab** | Move between toasts and their buttons. |
98
+ | **Escape** | Dismiss the focused toast. |
99
+ | swipe sideways | Dismiss (touch, pen or mouse). |
100
+
101
+ The list is a polite live region, always in the page, so new toasts are read out
102
+ without interrupting. Error toasts use `role="alert"` and interrupt. The region is
103
+ a labelled landmark ("Notifications (Alt+T)").
104
+
105
+ ## Theming
106
+
107
+ Override `--ts-*` variables (they default to the grid's `--dg-*`). Toasts render
108
+ on `<body>`, so set shared `--dg-*` values on `:root`:
109
+
110
+ ```css
111
+ .ts-region { --ts-width: 420px; --ts-success: #059669; --ts-radius: 12px; }
112
+ ```
113
+
114
+ State attributes: `data-position` on the region; `data-type`, `data-state`
115
+ (`open` / `closing`), `data-custom`, `data-swiping` on toasts.
116
+
117
+ ## Headless use
118
+
119
+ `useToasts(store?)` returns the live snapshot (`toasts`, `paused`, `limit`) for a
120
+ custom UI, and `visibleToasts(snapshot)` picks the ones to show.
121
+ `createToastStore()` and `createToastApi(store)` build separate instances. All of
122
+ `core` runs without React.
123
+
124
+ ## Known limits
125
+
126
+ - One stack per `<Toaster />`; toasts don't collapse into an expandable pile.
127
+ - `toast()` does nothing during a server render or in server code. Call it in
128
+ the browser, e.g. after a Server Action resolves.
@@ -0,0 +1,87 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ToastPatch, ToastStore } from "./store";
3
+ import type { ToastOptions, ToastRenderProps, ToastType } from "./types";
4
+
5
+ type TypedOptions = Omit<ToastOptions, "type">;
6
+ type Message<T> = ReactNode | ((value: T) => ReactNode);
7
+
8
+ export interface PromiseMessages<T> {
9
+ loading: ReactNode;
10
+ /** Omit to close the toast quietly on success. */
11
+ success?: Message<T>;
12
+ /** Omit to close the toast quietly on failure. */
13
+ error?: Message<unknown>;
14
+ }
15
+
16
+ export interface ToastApi {
17
+ (title: ReactNode, options?: ToastOptions): string;
18
+ success(title: ReactNode, options?: TypedOptions): string;
19
+ error(title: ReactNode, options?: TypedOptions): string;
20
+ warning(title: ReactNode, options?: TypedOptions): string;
21
+ info(title: ReactNode, options?: TypedOptions): string;
22
+ /** Stays until updated or dismissed. */
23
+ loading(title: ReactNode, options?: TypedOptions): string;
24
+ custom(
25
+ render: (props: ToastRenderProps) => ReactNode,
26
+ options?: Omit<TypedOptions, "render">,
27
+ ): string;
28
+ /** Shows a loading toast, then turns it into a success or error. Returns the same promise. */
29
+ promise<T>(
30
+ input: Promise<T> | (() => Promise<T>),
31
+ messages: PromiseMessages<T>,
32
+ options?: TypedOptions,
33
+ ): Promise<T>;
34
+ update(id: string, patch: ToastPatch): void;
35
+ dismiss(id?: string): void;
36
+ }
37
+
38
+ /**
39
+ * The `toast()` function for a store. `canShow` lets the default instance ignore
40
+ * calls made where nobody can see them, such as during a server render.
41
+ */
42
+ export function createToastApi(store: ToastStore, canShow: () => boolean = () => true): ToastApi {
43
+ const show = (title: ReactNode, options?: ToastOptions) =>
44
+ canShow() ? store.show(title, options) : (options?.id ?? "");
45
+
46
+ const typed = (type: ToastType) => (title: ReactNode, options?: TypedOptions) =>
47
+ show(title, { ...options, type });
48
+
49
+ function promise<T>(
50
+ input: Promise<T> | (() => Promise<T>),
51
+ messages: PromiseMessages<T>,
52
+ options?: TypedOptions,
53
+ ): Promise<T> {
54
+ const pending = typeof input === "function" ? input() : input;
55
+ if (!canShow()) return pending;
56
+
57
+ const id = store.show(messages.loading, { ...options, type: "loading" });
58
+
59
+ function settle<V>(type: "success" | "error", message: Message<V> | undefined, value: V) {
60
+ if (message === undefined) store.dismiss(id);
61
+ else store.update(id, { type, title: typeof message === "function" ? message(value) : message });
62
+ }
63
+
64
+ // Handling the rejection here also stops it being reported as unhandled when
65
+ // the caller doesn't await the returned promise.
66
+ pending.then(
67
+ (value) => settle("success", messages.success, value),
68
+ (error: unknown) => settle("error", messages.error, error),
69
+ );
70
+ return pending;
71
+ }
72
+
73
+ return Object.assign(show, {
74
+ success: typed("success"),
75
+ error: typed("error"),
76
+ warning: typed("warning"),
77
+ info: typed("info"),
78
+ loading: typed("loading"),
79
+ custom: (
80
+ render: (props: ToastRenderProps) => ReactNode,
81
+ options?: Omit<TypedOptions, "render">,
82
+ ) => show(null, { ...options, render }),
83
+ promise,
84
+ update: (id: string, patch: ToastPatch) => store.update(id, patch),
85
+ dismiss: (id?: string) => store.dismiss(id),
86
+ });
87
+ }
@@ -0,0 +1,14 @@
1
+ // Framework-free: the store, the timers and the `toast()` API run without
2
+ // React, so they can be called from a data layer and tested on their own.
3
+ export { createToastApi } from "./api";
4
+ export type { PromiseMessages, ToastApi } from "./api";
5
+ export {
6
+ createToastStore,
7
+ DEFAULT_DURATION,
8
+ DEFAULT_LIMIT,
9
+ EXIT_DURATION,
10
+ visibleToasts,
11
+ } from "./store";
12
+ export type { ToastPatch, ToastStore, ToastStoreConfig } from "./store";
13
+ export { toast, toastStore } from "./toast";
14
+ export type * from "./types";
@@ -0,0 +1,211 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ToastOptions, ToastRecord, ToastSnapshot } from "./types";
3
+
4
+ export const DEFAULT_DURATION = 5000;
5
+ export const DEFAULT_LIMIT = 3;
6
+ /** Matches the CSS exit transition, so a toast fades out before it leaves the DOM. */
7
+ export const EXIT_DURATION = 200;
8
+
9
+ export interface ToastStoreConfig {
10
+ /** Default auto-close delay in milliseconds. */
11
+ duration?: number;
12
+ /** Open toasts on screen at once; the rest wait with their timers held. */
13
+ limit?: number;
14
+ /** How long a closed toast stays for its exit animation. */
15
+ exitDuration?: number;
16
+ }
17
+
18
+ export type ToastPatch = Omit<ToastOptions, "id"> & { title?: ReactNode };
19
+
20
+ export interface ToastStore {
21
+ subscribe(listener: () => void): () => void;
22
+ getSnapshot(): ToastSnapshot;
23
+ getServerSnapshot(): ToastSnapshot;
24
+ /** Adds a toast, or updates the one with the same `id`. Returns the id. */
25
+ show(title: ReactNode, options?: ToastOptions): string;
26
+ /** Changes an open toast. A new `type` without a `duration` gets that type's default. */
27
+ update(id: string, patch: ToastPatch): void;
28
+ /** Closes one toast, or every toast when no id is given. */
29
+ dismiss(id?: string): void;
30
+ pause(): void;
31
+ resume(): void;
32
+ configure(config: ToastStoreConfig): void;
33
+ }
34
+
35
+ interface Countdown {
36
+ remaining: number;
37
+ startedAt: number;
38
+ handle: ReturnType<typeof setTimeout> | null;
39
+ }
40
+
41
+ const EMPTY: ToastSnapshot = { toasts: [], paused: false, limit: DEFAULT_LIMIT };
42
+
43
+ /** What a Toaster renders: every closing toast, plus the newest `limit` open ones. */
44
+ export function visibleToasts(snapshot: ToastSnapshot): ToastRecord[] {
45
+ let open = 0;
46
+ return snapshot.toasts.filter((toast) => toast.state !== "open" || open++ < snapshot.limit);
47
+ }
48
+
49
+ function definedOnly<T extends object>(value: T): Partial<T> {
50
+ return Object.fromEntries(
51
+ Object.entries(value).filter(([, entry]) => entry !== undefined),
52
+ ) as Partial<T>;
53
+ }
54
+
55
+ /**
56
+ * Toast state and timers, with no React. Snapshots are immutable, so the store
57
+ * plugs straight into `useSyncExternalStore`. Only toasts on screen count down:
58
+ * one waiting beyond `limit` keeps its full time until it gets a slot.
59
+ */
60
+ export function createToastStore(config: ToastStoreConfig = {}): ToastStore {
61
+ let settings: Required<ToastStoreConfig> = {
62
+ duration: DEFAULT_DURATION,
63
+ limit: DEFAULT_LIMIT,
64
+ exitDuration: EXIT_DURATION,
65
+ ...definedOnly(config),
66
+ };
67
+ let snapshot: ToastSnapshot = { ...EMPTY, limit: settings.limit };
68
+ let counter = 0;
69
+ const listeners = new Set<() => void>();
70
+ const countdowns = new Map<string, Countdown>();
71
+ const removals = new Map<string, ReturnType<typeof setTimeout>>();
72
+
73
+ function stop(id: string) {
74
+ const countdown = countdowns.get(id);
75
+ if (!countdown?.handle) return;
76
+ clearTimeout(countdown.handle);
77
+ countdown.handle = null;
78
+ countdown.remaining = Math.max(0, countdown.remaining - (Date.now() - countdown.startedAt));
79
+ }
80
+
81
+ function syncTimers() {
82
+ const visible = new Set(visibleToasts(snapshot));
83
+ for (const toast of snapshot.toasts) {
84
+ const countdown = countdowns.get(toast.id);
85
+ if (!countdown || toast.state !== "open") continue;
86
+ const run =
87
+ visible.has(toast) && !snapshot.paused && Number.isFinite(countdown.remaining);
88
+ if (run && !countdown.handle) {
89
+ countdown.startedAt = Date.now();
90
+ countdown.handle = setTimeout(() => close(toast.id, true), countdown.remaining);
91
+ } else if (!run && countdown.handle) {
92
+ stop(toast.id);
93
+ }
94
+ }
95
+ }
96
+
97
+ function commit(
98
+ toasts: readonly ToastRecord[],
99
+ changes: Partial<Omit<ToastSnapshot, "toasts">> = {},
100
+ ) {
101
+ snapshot = { ...snapshot, ...changes, toasts };
102
+ syncTimers();
103
+ for (const listener of listeners) listener();
104
+ }
105
+
106
+ function close(id: string, auto: boolean) {
107
+ const toast = snapshot.toasts.find((item) => item.id === id && item.state === "open");
108
+ if (!toast) return;
109
+ stop(id);
110
+ countdowns.delete(id);
111
+
112
+ const closing: ToastRecord = { ...toast, state: "closing" };
113
+ commit(snapshot.toasts.map((item) => (item === toast ? closing : item)));
114
+ if (auto) closing.onAutoClose?.(closing);
115
+ else closing.onDismiss?.(closing);
116
+
117
+ removals.set(
118
+ id,
119
+ setTimeout(() => {
120
+ removals.delete(id);
121
+ commit(snapshot.toasts.filter((item) => item !== closing));
122
+ }, settings.exitDuration),
123
+ );
124
+ }
125
+
126
+ function show(title: ReactNode, options: ToastOptions = {}): string {
127
+ const id = options.id ?? `toast-${++counter}`;
128
+ const type = options.type ?? "default";
129
+ const existing = snapshot.toasts.find((item) => item.id === id);
130
+ const reused = existing?.state === "open" ? existing : undefined;
131
+ const requested = options.duration ?? (type === "loading" ? Infinity : settings.duration);
132
+
133
+ const record: ToastRecord = {
134
+ ...options,
135
+ id,
136
+ type,
137
+ title,
138
+ // 0, negative and NaN all mean "stay until dismissed".
139
+ duration: requested > 0 ? requested : Infinity,
140
+ dismissible: options.dismissible ?? true,
141
+ state: "open",
142
+ createdAt: reused?.createdAt ?? Date.now(),
143
+ version: (existing?.version ?? 0) + 1,
144
+ };
145
+
146
+ // Showing an id that is fading out brings it back instead of stacking a copy.
147
+ const removal = removals.get(id);
148
+ if (removal !== undefined) {
149
+ clearTimeout(removal);
150
+ removals.delete(id);
151
+ }
152
+ stop(id);
153
+ countdowns.set(id, { remaining: record.duration, startedAt: 0, handle: null });
154
+
155
+ commit(
156
+ reused
157
+ ? snapshot.toasts.map((item) => (item === reused ? record : item))
158
+ : [record, ...snapshot.toasts.filter((item) => item.id !== id)],
159
+ );
160
+ return id;
161
+ }
162
+
163
+ function update(id: string, patch: ToastPatch) {
164
+ const existing = snapshot.toasts.find((item) => item.id === id && item.state === "open");
165
+ if (!existing) return;
166
+ const { title = existing.title, ...changes } = patch;
167
+ const typeChanged = changes.type !== undefined && changes.type !== existing.type;
168
+ show(title, {
169
+ ...existing,
170
+ ...changes,
171
+ id,
172
+ duration: changes.duration ?? (typeChanged ? undefined : existing.duration),
173
+ });
174
+ }
175
+
176
+ function dismiss(id?: string) {
177
+ if (id !== undefined) {
178
+ close(id, false);
179
+ return;
180
+ }
181
+ for (const toast of snapshot.toasts) {
182
+ if (toast.state === "open") close(toast.id, false);
183
+ }
184
+ }
185
+
186
+ function setPaused(paused: boolean) {
187
+ if (snapshot.paused !== paused) commit(snapshot.toasts, { paused });
188
+ }
189
+
190
+ function configure(next: ToastStoreConfig) {
191
+ settings = { ...settings, ...definedOnly(next) };
192
+ if (settings.limit !== snapshot.limit) commit(snapshot.toasts, { limit: settings.limit });
193
+ }
194
+
195
+ return {
196
+ subscribe(listener) {
197
+ listeners.add(listener);
198
+ return () => {
199
+ listeners.delete(listener);
200
+ };
201
+ },
202
+ getSnapshot: () => snapshot,
203
+ getServerSnapshot: () => EMPTY,
204
+ show,
205
+ update,
206
+ dismiss,
207
+ pause: () => setPaused(true),
208
+ resume: () => setPaused(false),
209
+ configure,
210
+ };
211
+ }
@@ -0,0 +1,12 @@
1
+ import { createToastApi } from "./api";
2
+ import { createToastStore } from "./store";
3
+
4
+ /** The store behind `toast()`, and behind any `<Toaster />` without a `store` prop. */
5
+ export const toastStore = createToastStore();
6
+
7
+ /**
8
+ * Shows a notification from anywhere: components, event handlers, data layers,
9
+ * code outside React. On a server nobody can see a toast, so calls do nothing
10
+ * there — which also keeps one request's toasts from leaking into another's.
11
+ */
12
+ export const toast = createToastApi(toastStore, () => typeof document !== "undefined");
@@ -0,0 +1,78 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ export type ToastType = "default" | "success" | "error" | "warning" | "info" | "loading";
4
+
5
+ export type ToastPosition =
6
+ | "top-left"
7
+ | "top-center"
8
+ | "top-right"
9
+ | "bottom-left"
10
+ | "bottom-center"
11
+ | "bottom-right";
12
+
13
+ /** The click event handed to an action. Call `preventDefault()` to keep the toast open. */
14
+ export interface ToastActionEvent {
15
+ preventDefault(): void;
16
+ readonly defaultPrevented: boolean;
17
+ }
18
+
19
+ export interface ToastAction {
20
+ label: ReactNode;
21
+ onClick(event: ToastActionEvent): void;
22
+ }
23
+
24
+ export interface ToastRenderProps {
25
+ id: string;
26
+ dismiss(): void;
27
+ }
28
+
29
+ export interface ToastOptions {
30
+ /** Showing a toast with an id that is already on screen updates it in place. */
31
+ id?: string;
32
+ type?: ToastType;
33
+ description?: ReactNode;
34
+ /** Milliseconds before it closes. `0` or `Infinity` keeps it until dismissed. */
35
+ duration?: number;
36
+ /** Close button, Escape and swipe. Default true. */
37
+ dismissible?: boolean;
38
+ action?: ToastAction;
39
+ cancel?: ToastAction;
40
+ /** Replaces the type's icon; `null` hides it. */
41
+ icon?: ReactNode;
42
+ className?: string;
43
+ /** Renders the whole toast body yourself. */
44
+ render?(props: ToastRenderProps): ReactNode;
45
+ /** Closed by the user or by code. */
46
+ onDismiss?(toast: ToastRecord): void;
47
+ /** Closed because its time ran out. */
48
+ onAutoClose?(toast: ToastRecord): void;
49
+ }
50
+
51
+ export interface ToastRecord
52
+ extends Omit<ToastOptions, "id" | "type" | "duration" | "dismissible"> {
53
+ id: string;
54
+ type: ToastType;
55
+ title: ReactNode;
56
+ /** Always a positive number; `Infinity` when it stays until dismissed. */
57
+ duration: number;
58
+ dismissible: boolean;
59
+ /** `closing` while the exit animation plays, just before removal. */
60
+ state: "open" | "closing";
61
+ createdAt: number;
62
+ /** Goes up each time the same id is shown or updated. */
63
+ version: number;
64
+ }
65
+
66
+ export interface ToastSnapshot {
67
+ /** Newest first, including toasts waiting beyond `limit`. */
68
+ toasts: readonly ToastRecord[];
69
+ /** Timers are held, e.g. while the pointer is over the toasts. */
70
+ paused: boolean;
71
+ /** How many open toasts are on screen at once. */
72
+ limit: number;
73
+ }
74
+
75
+ export interface ToasterLocaleText {
76
+ regionLabel(hotkey: string): string;
77
+ close: string;
78
+ }
@@ -0,0 +1,6 @@
1
+ export { Toaster } from "./react/Toaster";
2
+ export type { ToasterProps } from "./react/Toaster";
3
+ export { useToasts } from "./react/useToasts";
4
+ export { defaultToasterText } from "./react/locale";
5
+ export type { ToasterSlot } from "./react/props";
6
+ export * from "./core";