@maxal_studio/kratosjs-react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. package/README.md +44 -0
  2. package/dist/FieldRenderer.d.ts +13 -0
  3. package/dist/FieldRenderer.js +62 -0
  4. package/dist/FormRenderer.d.ts +7 -0
  5. package/dist/FormRenderer.js +78 -0
  6. package/dist/TableRenderer.d.ts +2 -0
  7. package/dist/TableRenderer.js +1 -0
  8. package/dist/api/actionsApi.d.ts +23 -0
  9. package/dist/api/actionsApi.js +46 -0
  10. package/dist/api/authenticatedFetch.d.ts +8 -0
  11. package/dist/api/authenticatedFetch.js +31 -0
  12. package/dist/api/exportApi.d.ts +18 -0
  13. package/dist/api/exportApi.js +50 -0
  14. package/dist/api/http.d.ts +24 -0
  15. package/dist/api/http.js +52 -0
  16. package/dist/api/resourceApi.d.ts +37 -0
  17. package/dist/api/resourceApi.js +52 -0
  18. package/dist/api/tableApi.d.ts +83 -0
  19. package/dist/api/tableApi.js +51 -0
  20. package/dist/api/urls.d.ts +19 -0
  21. package/dist/api/urls.js +46 -0
  22. package/dist/app.d.ts +101 -0
  23. package/dist/app.js +89 -0
  24. package/dist/auth/AuthContext.d.ts +22 -0
  25. package/dist/auth/AuthContext.js +147 -0
  26. package/dist/auth/LoginPage.d.ts +10 -0
  27. package/dist/auth/LoginPage.js +179 -0
  28. package/dist/auth/ProtectedRoute.d.ts +12 -0
  29. package/dist/auth/ProtectedRoute.js +22 -0
  30. package/dist/auth/authApiClient.d.ts +24 -0
  31. package/dist/auth/authApiClient.js +95 -0
  32. package/dist/auth/types.d.ts +103 -0
  33. package/dist/auth/types.js +1 -0
  34. package/dist/components/ActionFormModal.d.ts +22 -0
  35. package/dist/components/ActionFormModal.js +8 -0
  36. package/dist/components/AdminPanel.d.ts +11 -0
  37. package/dist/components/AdminPanel.js +194 -0
  38. package/dist/components/Checkbox.d.ts +10 -0
  39. package/dist/components/Checkbox.js +8 -0
  40. package/dist/components/CheckboxField.d.ts +7 -0
  41. package/dist/components/CheckboxField.js +26 -0
  42. package/dist/components/ColorPickerField.d.ts +7 -0
  43. package/dist/components/ColorPickerField.js +26 -0
  44. package/dist/components/DateTimePickerField.d.ts +7 -0
  45. package/dist/components/DateTimePickerField.js +64 -0
  46. package/dist/components/FileUploadField.d.ts +9 -0
  47. package/dist/components/FileUploadField.js +478 -0
  48. package/dist/components/GlobalSearch.d.ts +22 -0
  49. package/dist/components/GlobalSearch.js +181 -0
  50. package/dist/components/GroupField.d.ts +7 -0
  51. package/dist/components/GroupField.js +23 -0
  52. package/dist/components/HiddenField.d.ts +3 -0
  53. package/dist/components/HiddenField.js +10 -0
  54. package/dist/components/ModalBreadcrumb.d.ts +5 -0
  55. package/dist/components/ModalBreadcrumb.js +33 -0
  56. package/dist/components/ModalDrawer.d.ts +15 -0
  57. package/dist/components/ModalDrawer.js +40 -0
  58. package/dist/components/RadioField.d.ts +7 -0
  59. package/dist/components/RadioField.js +26 -0
  60. package/dist/components/RepeaterField.d.ts +3 -0
  61. package/dist/components/RepeaterField.js +191 -0
  62. package/dist/components/ResourceModalRenderer.d.ts +10 -0
  63. package/dist/components/ResourceModalRenderer.js +80 -0
  64. package/dist/components/RichEditorField.d.ts +3 -0
  65. package/dist/components/RichEditorField.js +655 -0
  66. package/dist/components/SectionField.d.ts +9 -0
  67. package/dist/components/SectionField.js +111 -0
  68. package/dist/components/SelectField.d.ts +8 -0
  69. package/dist/components/SelectField.js +523 -0
  70. package/dist/components/TabsField.d.ts +10 -0
  71. package/dist/components/TabsField.js +214 -0
  72. package/dist/components/TagsInputField.d.ts +7 -0
  73. package/dist/components/TagsInputField.js +172 -0
  74. package/dist/components/TextInputField.d.ts +7 -0
  75. package/dist/components/TextInputField.js +44 -0
  76. package/dist/components/TextareaField.d.ts +7 -0
  77. package/dist/components/TextareaField.js +31 -0
  78. package/dist/components/ToggleField.d.ts +7 -0
  79. package/dist/components/ToggleField.js +57 -0
  80. package/dist/components/ViewModal.d.ts +25 -0
  81. package/dist/components/ViewModal.js +159 -0
  82. package/dist/components/blocks/BlockRenderer.d.ts +7 -0
  83. package/dist/components/blocks/BlockRenderer.js +36 -0
  84. package/dist/components/blocks/FormBlockRenderer.d.ts +6 -0
  85. package/dist/components/blocks/FormBlockRenderer.js +110 -0
  86. package/dist/components/blocks/TableBlockRenderer.d.ts +6 -0
  87. package/dist/components/blocks/TableBlockRenderer.js +12 -0
  88. package/dist/components/blocks/TabsBlockRenderer.d.ts +7 -0
  89. package/dist/components/blocks/TabsBlockRenderer.js +11 -0
  90. package/dist/components/blocks/WidgetBlockRenderer.d.ts +6 -0
  91. package/dist/components/blocks/WidgetBlockRenderer.js +11 -0
  92. package/dist/components/columns/CheckboxColumnComponent.d.ts +6 -0
  93. package/dist/components/columns/CheckboxColumnComponent.js +21 -0
  94. package/dist/components/columns/ColorColumnComponent.d.ts +3 -0
  95. package/dist/components/columns/ColorColumnComponent.js +11 -0
  96. package/dist/components/columns/DeeplinkWrapper.d.ts +15 -0
  97. package/dist/components/columns/DeeplinkWrapper.js +85 -0
  98. package/dist/components/columns/IconColumnComponent.d.ts +3 -0
  99. package/dist/components/columns/IconColumnComponent.js +52 -0
  100. package/dist/components/columns/ImageColumnComponent.d.ts +3 -0
  101. package/dist/components/columns/ImageColumnComponent.js +98 -0
  102. package/dist/components/columns/MediaColumnComponent.d.ts +3 -0
  103. package/dist/components/columns/MediaColumnComponent.js +160 -0
  104. package/dist/components/columns/SelectColumnComponent.d.ts +6 -0
  105. package/dist/components/columns/SelectColumnComponent.js +26 -0
  106. package/dist/components/columns/TagsColumnComponent.d.ts +3 -0
  107. package/dist/components/columns/TagsColumnComponent.js +18 -0
  108. package/dist/components/columns/TextColumnComponent.d.ts +11 -0
  109. package/dist/components/columns/TextColumnComponent.js +107 -0
  110. package/dist/components/columns/TextInputColumnComponent.d.ts +6 -0
  111. package/dist/components/columns/TextInputColumnComponent.js +18 -0
  112. package/dist/components/columns/ToggleColumnComponent.d.ts +6 -0
  113. package/dist/components/columns/ToggleColumnComponent.js +25 -0
  114. package/dist/components/columns/VideoColumnComponent.d.ts +3 -0
  115. package/dist/components/columns/VideoColumnComponent.js +125 -0
  116. package/dist/components/columns/ViewColumnComponent.d.ts +3 -0
  117. package/dist/components/columns/ViewColumnComponent.js +7 -0
  118. package/dist/components/errors/ErrorBoundary.d.ts +23 -0
  119. package/dist/components/errors/ErrorBoundary.js +33 -0
  120. package/dist/components/filters/CustomFilterComponent.d.ts +10 -0
  121. package/dist/components/filters/CustomFilterComponent.js +33 -0
  122. package/dist/components/filters/DateFilterComponent.d.ts +15 -0
  123. package/dist/components/filters/DateFilterComponent.js +132 -0
  124. package/dist/components/filters/QueryBuilderFilterComponent.d.ts +11 -0
  125. package/dist/components/filters/QueryBuilderFilterComponent.js +200 -0
  126. package/dist/components/layout/Header.d.ts +10 -0
  127. package/dist/components/layout/Header.js +70 -0
  128. package/dist/components/layout/PanelBrandMark.d.ts +8 -0
  129. package/dist/components/layout/PanelBrandMark.js +28 -0
  130. package/dist/components/layout/Sidebar.d.ts +35 -0
  131. package/dist/components/layout/Sidebar.js +125 -0
  132. package/dist/components/modals/RelationCreateModal.d.ts +19 -0
  133. package/dist/components/modals/RelationCreateModal.js +57 -0
  134. package/dist/components/modals/ResourceFormModal.d.ts +37 -0
  135. package/dist/components/modals/ResourceFormModal.js +44 -0
  136. package/dist/components/modals/useResourceForm.d.ts +40 -0
  137. package/dist/components/modals/useResourceForm.js +138 -0
  138. package/dist/components/modals/view/RecordActions.d.ts +17 -0
  139. package/dist/components/modals/view/RecordActions.js +16 -0
  140. package/dist/components/modals/view/RecordDetails.d.ts +13 -0
  141. package/dist/components/modals/view/RecordDetails.js +29 -0
  142. package/dist/components/modals/view/RelationPanel.d.ts +18 -0
  143. package/dist/components/modals/view/RelationPanel.js +16 -0
  144. package/dist/components/modals/view/RelationTabs.d.ts +32 -0
  145. package/dist/components/modals/view/RelationTabs.js +42 -0
  146. package/dist/components/modals/view/useRecordView.d.ts +18 -0
  147. package/dist/components/modals/view/useRecordView.js +114 -0
  148. package/dist/components/pages/PageRenderer.d.ts +6 -0
  149. package/dist/components/pages/PageRenderer.js +107 -0
  150. package/dist/components/table/ColumnTogglePopup.d.ts +11 -0
  151. package/dist/components/table/ColumnTogglePopup.js +16 -0
  152. package/dist/components/table/GridCard.d.ts +21 -0
  153. package/dist/components/table/GridCard.js +30 -0
  154. package/dist/components/table/GridView.d.ts +23 -0
  155. package/dist/components/table/GridView.js +49 -0
  156. package/dist/components/table/LayoutToggle.d.ts +7 -0
  157. package/dist/components/table/LayoutToggle.js +9 -0
  158. package/dist/components/table/TableActionsDropdown.d.ts +13 -0
  159. package/dist/components/table/TableActionsDropdown.js +46 -0
  160. package/dist/components/table/TableBulkActions.d.ts +11 -0
  161. package/dist/components/table/TableBulkActions.js +21 -0
  162. package/dist/components/table/TableHeader.d.ts +14 -0
  163. package/dist/components/table/TableHeader.js +23 -0
  164. package/dist/components/table/TablePagination.d.ts +13 -0
  165. package/dist/components/table/TablePagination.js +55 -0
  166. package/dist/components/table/TableRow.d.ts +21 -0
  167. package/dist/components/table/TableRow.js +32 -0
  168. package/dist/components/table/TableSearchBar.d.ts +11 -0
  169. package/dist/components/table/TableSearchBar.js +12 -0
  170. package/dist/components/table/TableTabs.d.ts +14 -0
  171. package/dist/components/table/TableTabs.js +8 -0
  172. package/dist/components/ui/Badge.d.ts +6 -0
  173. package/dist/components/ui/Badge.js +12 -0
  174. package/dist/components/ui/Button.d.ts +22 -0
  175. package/dist/components/ui/Button.js +22 -0
  176. package/dist/components/ui/Card.d.ts +7 -0
  177. package/dist/components/ui/Card.js +5 -0
  178. package/dist/components/ui/ConfirmDialog.d.ts +19 -0
  179. package/dist/components/ui/ConfirmDialog.js +45 -0
  180. package/dist/components/ui/EmptyState.d.ts +9 -0
  181. package/dist/components/ui/EmptyState.js +6 -0
  182. package/dist/components/ui/ErrorAlert.d.ts +7 -0
  183. package/dist/components/ui/ErrorAlert.js +9 -0
  184. package/dist/components/ui/Input.d.ts +11 -0
  185. package/dist/components/ui/Input.js +10 -0
  186. package/dist/components/ui/Label.d.ts +5 -0
  187. package/dist/components/ui/Label.js +5 -0
  188. package/dist/components/ui/PillButton.d.ts +14 -0
  189. package/dist/components/ui/PillButton.js +19 -0
  190. package/dist/components/ui/Select.d.ts +7 -0
  191. package/dist/components/ui/Select.js +7 -0
  192. package/dist/components/ui/Spinner.d.ts +8 -0
  193. package/dist/components/ui/Spinner.js +14 -0
  194. package/dist/components/ui/Toast.d.ts +21 -0
  195. package/dist/components/ui/Toast.js +47 -0
  196. package/dist/components/ui/index.d.ts +24 -0
  197. package/dist/components/ui/index.js +12 -0
  198. package/dist/components/utils/HintDisplay.d.ts +11 -0
  199. package/dist/components/utils/HintDisplay.js +12 -0
  200. package/dist/components/utils/Icon.d.ts +22 -0
  201. package/dist/components/utils/Icon.js +22 -0
  202. package/dist/components/utils/MediaPreviewModal.d.ts +14 -0
  203. package/dist/components/utils/MediaPreviewModal.js +32 -0
  204. package/dist/components/utils/ViewFieldWrapper.d.ts +11 -0
  205. package/dist/components/utils/ViewFieldWrapper.js +9 -0
  206. package/dist/components/utils/layoutHelpers.d.ts +19 -0
  207. package/dist/components/utils/layoutHelpers.js +257 -0
  208. package/dist/components/widgets/ChartWidget.d.ts +16 -0
  209. package/dist/components/widgets/ChartWidget.js +192 -0
  210. package/dist/components/widgets/StatsWidget.d.ts +16 -0
  211. package/dist/components/widgets/StatsWidget.js +39 -0
  212. package/dist/components/widgets/WidgetRenderer.d.ts +10 -0
  213. package/dist/components/widgets/WidgetRenderer.js +50 -0
  214. package/dist/components/widgets/WidgetShell.d.ts +9 -0
  215. package/dist/components/widgets/WidgetShell.js +7 -0
  216. package/dist/contexts/AuthChallengeRegistryContext.d.ts +15 -0
  217. package/dist/contexts/AuthChallengeRegistryContext.js +15 -0
  218. package/dist/contexts/BlockRegistryContext.d.ts +18 -0
  219. package/dist/contexts/BlockRegistryContext.js +8 -0
  220. package/dist/contexts/ColumnRegistryContext.d.ts +8 -0
  221. package/dist/contexts/ColumnRegistryContext.js +30 -0
  222. package/dist/contexts/FieldRegistryContext.d.ts +13 -0
  223. package/dist/contexts/FieldRegistryContext.js +46 -0
  224. package/dist/contexts/PanelMetadataContext.d.ts +26 -0
  225. package/dist/contexts/PanelMetadataContext.js +26 -0
  226. package/dist/contexts/PanelProviders.d.ts +27 -0
  227. package/dist/contexts/PanelProviders.js +24 -0
  228. package/dist/contexts/ResourceModalContext.d.ts +26 -0
  229. package/dist/contexts/ResourceModalContext.js +76 -0
  230. package/dist/contexts/SlotRegistryContext.d.ts +19 -0
  231. package/dist/contexts/SlotRegistryContext.js +24 -0
  232. package/dist/contexts/TableRefreshContext.d.ts +10 -0
  233. package/dist/contexts/TableRefreshContext.js +30 -0
  234. package/dist/contexts/WidgetRegistryContext.d.ts +17 -0
  235. package/dist/contexts/WidgetRegistryContext.js +14 -0
  236. package/dist/contexts/createRegistryContext.d.ts +19 -0
  237. package/dist/contexts/createRegistryContext.js +20 -0
  238. package/dist/hooks/useAfterStateUpdated.d.ts +6 -0
  239. package/dist/hooks/useAfterStateUpdated.js +62 -0
  240. package/dist/hooks/useValidation.d.ts +26 -0
  241. package/dist/hooks/useValidation.js +76 -0
  242. package/dist/i18n/I18nProvider.d.ts +27 -0
  243. package/dist/i18n/I18nProvider.js +101 -0
  244. package/dist/i18n/LocaleSwitcher.d.ts +10 -0
  245. package/dist/i18n/LocaleSwitcher.js +30 -0
  246. package/dist/i18n/activeLocale.d.ts +11 -0
  247. package/dist/i18n/activeLocale.js +34 -0
  248. package/dist/i18n/buildClientI18n.d.ts +28 -0
  249. package/dist/i18n/buildClientI18n.js +67 -0
  250. package/dist/i18n/index.d.ts +11 -0
  251. package/dist/i18n/index.js +9 -0
  252. package/dist/i18n/locales/core/en.d.ts +225 -0
  253. package/dist/i18n/locales/core/en.js +252 -0
  254. package/dist/i18n/locales/core/index.d.ts +2 -0
  255. package/dist/i18n/locales/core/index.js +4 -0
  256. package/dist/i18n/locales/core/sq.d.ts +253 -0
  257. package/dist/i18n/locales/core/sq.js +255 -0
  258. package/dist/i18n/useFormatter.d.ts +18 -0
  259. package/dist/i18n/useFormatter.js +37 -0
  260. package/dist/i18n/useLocale.d.ts +11 -0
  261. package/dist/i18n/useLocale.js +11 -0
  262. package/dist/i18n/useTranslation.d.ts +12 -0
  263. package/dist/i18n/useTranslation.js +12 -0
  264. package/dist/index.d.ts +106 -0
  265. package/dist/index.js +101 -0
  266. package/dist/pages/ResourceListPage.d.ts +8 -0
  267. package/dist/pages/ResourceListPage.js +139 -0
  268. package/dist/plugin.d.ts +79 -0
  269. package/dist/plugin.js +34 -0
  270. package/dist/runtime/conditions.d.ts +35 -0
  271. package/dist/runtime/conditions.js +97 -0
  272. package/dist/runtime/formTraversal.d.ts +25 -0
  273. package/dist/runtime/formTraversal.js +37 -0
  274. package/dist/runtime/serializedFunctions.d.ts +41 -0
  275. package/dist/runtime/serializedFunctions.js +264 -0
  276. package/dist/slots/Slot.d.ts +24 -0
  277. package/dist/slots/Slot.js +29 -0
  278. package/dist/slots/SlotCluster.d.ts +22 -0
  279. package/dist/slots/SlotCluster.js +49 -0
  280. package/dist/slots/index.d.ts +7 -0
  281. package/dist/slots/index.js +4 -0
  282. package/dist/slots/mergeSlots.d.ts +18 -0
  283. package/dist/slots/mergeSlots.js +35 -0
  284. package/dist/slots/types.d.ts +87 -0
  285. package/dist/slots/types.js +30 -0
  286. package/dist/styles.css +1 -0
  287. package/dist/table/TableContext.d.ts +36 -0
  288. package/dist/table/TableContext.js +13 -0
  289. package/dist/table/TableRenderer.d.ts +29 -0
  290. package/dist/table/TableRenderer.js +159 -0
  291. package/dist/table/components/FiltersPanel.d.ts +11 -0
  292. package/dist/table/components/FiltersPanel.js +52 -0
  293. package/dist/table/components/TableToolbar.d.ts +28 -0
  294. package/dist/table/components/TableToolbar.js +27 -0
  295. package/dist/table/components/TableToolbarButton.d.ts +6 -0
  296. package/dist/table/components/TableToolbarButton.js +9 -0
  297. package/dist/table/components/TableView.d.ts +12 -0
  298. package/dist/table/components/TableView.js +21 -0
  299. package/dist/table/defaultRowActions.d.ts +21 -0
  300. package/dist/table/defaultRowActions.js +37 -0
  301. package/dist/table/hooks/useColumnVisibility.d.ts +13 -0
  302. package/dist/table/hooks/useColumnVisibility.js +59 -0
  303. package/dist/table/hooks/useEditableRows.d.ts +22 -0
  304. package/dist/table/hooks/useEditableRows.js +63 -0
  305. package/dist/table/hooks/useTableActions.d.ts +54 -0
  306. package/dist/table/hooks/useTableActions.js +313 -0
  307. package/dist/table/hooks/useTableData.d.ts +28 -0
  308. package/dist/table/hooks/useTableData.js +63 -0
  309. package/dist/table/hooks/useTableLayout.d.ts +12 -0
  310. package/dist/table/hooks/useTableLayout.js +31 -0
  311. package/dist/table/hooks/useTableQuery.d.ts +29 -0
  312. package/dist/table/hooks/useTableQuery.js +135 -0
  313. package/dist/types/index.d.ts +224 -0
  314. package/dist/types/index.js +6 -0
  315. package/dist/utils/classNames.d.ts +7 -0
  316. package/dist/utils/classNames.js +9 -0
  317. package/dist/utils/columnMediaDimensions.d.ts +13 -0
  318. package/dist/utils/columnMediaDimensions.js +29 -0
  319. package/dist/utils/columnVisibilityStorage.d.ts +22 -0
  320. package/dist/utils/columnVisibilityStorage.js +56 -0
  321. package/dist/utils/fieldErrors.d.ts +13 -0
  322. package/dist/utils/fieldErrors.js +25 -0
  323. package/dist/utils/formatValue.d.ts +28 -0
  324. package/dist/utils/formatValue.js +109 -0
  325. package/dist/utils/layoutStorage.d.ts +23 -0
  326. package/dist/utils/layoutStorage.js +53 -0
  327. package/dist/utils/redirectHandler.d.ts +7 -0
  328. package/dist/utils/redirectHandler.js +25 -0
  329. package/dist/utils/tableFormatters.d.ts +14 -0
  330. package/dist/utils/tableFormatters.js +93 -0
  331. package/dist/utils/widgetVisibilityStorage.d.ts +11 -0
  332. package/dist/utils/widgetVisibilityStorage.js +39 -0
  333. package/package.json +101 -0
  334. package/src/FieldRenderer.test.tsx +44 -0
  335. package/src/FieldRenderer.tsx +104 -0
  336. package/src/FormRenderer.containers.test.tsx +121 -0
  337. package/src/FormRenderer.test.tsx +174 -0
  338. package/src/FormRenderer.tsx +140 -0
  339. package/src/TableRenderer.tsx +2 -0
  340. package/src/api/actionsApi.ts +76 -0
  341. package/src/api/authenticatedFetch.ts +40 -0
  342. package/src/api/exportApi.ts +66 -0
  343. package/src/api/http.test.ts +58 -0
  344. package/src/api/http.ts +68 -0
  345. package/src/api/resourceApi.ts +88 -0
  346. package/src/api/tableApi.test.ts +108 -0
  347. package/src/api/tableApi.ts +107 -0
  348. package/src/api/urls.ts +50 -0
  349. package/src/app.test.tsx +67 -0
  350. package/src/app.tsx +181 -0
  351. package/src/auth/AuthContext.tsx +188 -0
  352. package/src/auth/LoginPage.tsx +380 -0
  353. package/src/auth/ProtectedRoute.tsx +39 -0
  354. package/src/auth/authApiClient.ts +109 -0
  355. package/src/auth/authFlow.test.tsx +168 -0
  356. package/src/auth/types.ts +104 -0
  357. package/src/components/ActionFormModal.tsx +45 -0
  358. package/src/components/AdminPanel.tsx +368 -0
  359. package/src/components/Checkbox.tsx +59 -0
  360. package/src/components/CheckboxField.tsx +88 -0
  361. package/src/components/ColorPickerField.tsx +93 -0
  362. package/src/components/DateTimePickerField.tsx +112 -0
  363. package/src/components/FileUploadField.tsx +841 -0
  364. package/src/components/GlobalSearch.tsx +436 -0
  365. package/src/components/GroupField.tsx +85 -0
  366. package/src/components/HiddenField.tsx +14 -0
  367. package/src/components/ModalBreadcrumb.tsx +74 -0
  368. package/src/components/ModalDrawer.tsx +137 -0
  369. package/src/components/RadioField.tsx +80 -0
  370. package/src/components/RepeaterField.tsx +546 -0
  371. package/src/components/ResourceModalRenderer.tsx +144 -0
  372. package/src/components/RichEditorField.tsx +942 -0
  373. package/src/components/SectionField.tsx +242 -0
  374. package/src/components/SelectField.tsx +843 -0
  375. package/src/components/TabsField.test.tsx +151 -0
  376. package/src/components/TabsField.tsx +386 -0
  377. package/src/components/TagsInputField.tsx +411 -0
  378. package/src/components/TextInputField.tsx +91 -0
  379. package/src/components/TextareaField.tsx +110 -0
  380. package/src/components/ToggleField.tsx +126 -0
  381. package/src/components/ViewModal.tsx +353 -0
  382. package/src/components/blocks/BlockRenderer.tsx +56 -0
  383. package/src/components/blocks/FormBlockRenderer.tsx +160 -0
  384. package/src/components/blocks/TableBlockRenderer.tsx +33 -0
  385. package/src/components/blocks/TabsBlockRenderer.tsx +49 -0
  386. package/src/components/blocks/WidgetBlockRenderer.tsx +19 -0
  387. package/src/components/columns/CheckboxColumnComponent.tsx +38 -0
  388. package/src/components/columns/ColorColumnComponent.tsx +23 -0
  389. package/src/components/columns/CustomColumn.test.tsx +55 -0
  390. package/src/components/columns/DeeplinkWrapper.tsx +103 -0
  391. package/src/components/columns/IconColumnComponent.tsx +55 -0
  392. package/src/components/columns/ImageColumnComponent.tsx +220 -0
  393. package/src/components/columns/MediaColumnComponent.tsx +294 -0
  394. package/src/components/columns/SelectColumnComponent.tsx +49 -0
  395. package/src/components/columns/TagsColumnComponent.tsx +46 -0
  396. package/src/components/columns/TextColumnComponent.tsx +191 -0
  397. package/src/components/columns/TextInputColumnComponent.tsx +35 -0
  398. package/src/components/columns/ToggleColumnComponent.tsx +56 -0
  399. package/src/components/columns/VideoColumnComponent.tsx +236 -0
  400. package/src/components/columns/ViewColumnComponent.tsx +9 -0
  401. package/src/components/errors/ErrorBoundary.tsx +58 -0
  402. package/src/components/filters/CustomFilterComponent.tsx +130 -0
  403. package/src/components/filters/DateFilterComponent.tsx +272 -0
  404. package/src/components/filters/QueryBuilderFilterComponent.tsx +502 -0
  405. package/src/components/layout/Header.tsx +212 -0
  406. package/src/components/layout/PanelBrandMark.tsx +61 -0
  407. package/src/components/layout/Sidebar.tsx +283 -0
  408. package/src/components/modals/RelationCreateModal.tsx +107 -0
  409. package/src/components/modals/ResourceFormModal.test.tsx +119 -0
  410. package/src/components/modals/ResourceFormModal.tsx +128 -0
  411. package/src/components/modals/useResourceForm.ts +207 -0
  412. package/src/components/modals/view/RecordActions.tsx +69 -0
  413. package/src/components/modals/view/RecordDetails.tsx +60 -0
  414. package/src/components/modals/view/RelationPanel.tsx +76 -0
  415. package/src/components/modals/view/RelationTabs.tsx +145 -0
  416. package/src/components/modals/view/useRecordView.ts +134 -0
  417. package/src/components/pages/PageRenderer.tsx +173 -0
  418. package/src/components/table/ColumnTogglePopup.tsx +85 -0
  419. package/src/components/table/GridCard.tsx +155 -0
  420. package/src/components/table/GridView.tsx +138 -0
  421. package/src/components/table/LayoutToggle.tsx +24 -0
  422. package/src/components/table/TableActionsDropdown.tsx +114 -0
  423. package/src/components/table/TableBulkActions.tsx +65 -0
  424. package/src/components/table/TableHeader.tsx +96 -0
  425. package/src/components/table/TablePagination.tsx +169 -0
  426. package/src/components/table/TableRow.tsx +155 -0
  427. package/src/components/table/TableSearchBar.tsx +66 -0
  428. package/src/components/table/TableTabs.tsx +49 -0
  429. package/src/components/ui/Badge.tsx +30 -0
  430. package/src/components/ui/Button.test.tsx +78 -0
  431. package/src/components/ui/Button.tsx +102 -0
  432. package/src/components/ui/Card.tsx +23 -0
  433. package/src/components/ui/ConfirmDialog.tsx +112 -0
  434. package/src/components/ui/EmptyState.tsx +24 -0
  435. package/src/components/ui/ErrorAlert.tsx +37 -0
  436. package/src/components/ui/Input.tsx +48 -0
  437. package/src/components/ui/Label.tsx +15 -0
  438. package/src/components/ui/PillButton.tsx +72 -0
  439. package/src/components/ui/Select.tsx +33 -0
  440. package/src/components/ui/Spinner.tsx +39 -0
  441. package/src/components/ui/Toast.tsx +105 -0
  442. package/src/components/ui/index.ts +24 -0
  443. package/src/components/utils/HintDisplay.tsx +26 -0
  444. package/src/components/utils/Icon.tsx +36 -0
  445. package/src/components/utils/MediaPreviewModal.tsx +114 -0
  446. package/src/components/utils/ViewFieldWrapper.tsx +23 -0
  447. package/src/components/utils/layoutHelpers.ts +267 -0
  448. package/src/components/widgets/ChartWidget.tsx +247 -0
  449. package/src/components/widgets/StatsWidget.tsx +72 -0
  450. package/src/components/widgets/WidgetRenderer.tsx +108 -0
  451. package/src/components/widgets/WidgetShell.tsx +37 -0
  452. package/src/contexts/AuthChallengeRegistryContext.tsx +29 -0
  453. package/src/contexts/BlockRegistryContext.tsx +28 -0
  454. package/src/contexts/ColumnRegistryContext.tsx +38 -0
  455. package/src/contexts/FieldRegistryContext.tsx +56 -0
  456. package/src/contexts/PanelMetadataContext.tsx +60 -0
  457. package/src/contexts/PanelProviders.tsx +85 -0
  458. package/src/contexts/ResourceModalContext.tsx +137 -0
  459. package/src/contexts/SlotRegistryContext.tsx +35 -0
  460. package/src/contexts/TableRefreshContext.tsx +44 -0
  461. package/src/contexts/WidgetRegistryContext.tsx +34 -0
  462. package/src/contexts/createRegistryContext.tsx +29 -0
  463. package/src/hooks/useAfterStateUpdated.ts +70 -0
  464. package/src/hooks/useValidation.test.ts +59 -0
  465. package/src/hooks/useValidation.ts +95 -0
  466. package/src/i18n/I18nProvider.tsx +128 -0
  467. package/src/i18n/LocaleSwitcher.tsx +50 -0
  468. package/src/i18n/activeLocale.ts +39 -0
  469. package/src/i18n/buildClientI18n.ts +101 -0
  470. package/src/i18n/i18n.test.tsx +140 -0
  471. package/src/i18n/index.ts +12 -0
  472. package/src/i18n/locales/core/en.ts +274 -0
  473. package/src/i18n/locales/core/index.ts +5 -0
  474. package/src/i18n/locales/core/sq.ts +275 -0
  475. package/src/i18n/useFormatter.ts +42 -0
  476. package/src/i18n/useLocale.ts +16 -0
  477. package/src/i18n/useTranslation.ts +17 -0
  478. package/src/index.ts +244 -0
  479. package/src/pages/ResourceListPage.tsx +205 -0
  480. package/src/plugin.ts +110 -0
  481. package/src/runtime/conditions.test.ts +99 -0
  482. package/src/runtime/conditions.ts +148 -0
  483. package/src/runtime/formTraversal.ts +41 -0
  484. package/src/runtime/serializedFunctions.test.ts +59 -0
  485. package/src/runtime/serializedFunctions.ts +284 -0
  486. package/src/slots/Slot.test.tsx +89 -0
  487. package/src/slots/Slot.tsx +47 -0
  488. package/src/slots/SlotCluster.test.tsx +95 -0
  489. package/src/slots/SlotCluster.tsx +107 -0
  490. package/src/slots/index.ts +15 -0
  491. package/src/slots/mergeSlots.test.ts +71 -0
  492. package/src/slots/mergeSlots.ts +40 -0
  493. package/src/slots/slotNames.test.ts +21 -0
  494. package/src/slots/types.ts +119 -0
  495. package/src/styles.css +437 -0
  496. package/src/table/TableContext.tsx +41 -0
  497. package/src/table/TableRenderer.test.tsx +197 -0
  498. package/src/table/TableRenderer.tsx +390 -0
  499. package/src/table/components/FiltersPanel.tsx +193 -0
  500. package/src/table/components/TableToolbar.tsx +153 -0
  501. package/src/table/components/TableToolbarButton.tsx +14 -0
  502. package/src/table/components/TableView.tsx +106 -0
  503. package/src/table/defaultRowActions.ts +43 -0
  504. package/src/table/hooks/useColumnVisibility.test.ts +51 -0
  505. package/src/table/hooks/useColumnVisibility.ts +71 -0
  506. package/src/table/hooks/useEditableRows.test.ts +69 -0
  507. package/src/table/hooks/useEditableRows.ts +89 -0
  508. package/src/table/hooks/useTableActions.ts +393 -0
  509. package/src/table/hooks/useTableData.ts +89 -0
  510. package/src/table/hooks/useTableLayout.ts +45 -0
  511. package/src/table/hooks/useTableQuery.test.ts +116 -0
  512. package/src/table/hooks/useTableQuery.ts +172 -0
  513. package/src/test/mockFetch.ts +67 -0
  514. package/src/test/setup.ts +25 -0
  515. package/src/types/index.ts +228 -0
  516. package/src/utils/classNames.ts +10 -0
  517. package/src/utils/columnMediaDimensions.ts +45 -0
  518. package/src/utils/columnVisibilityStorage.ts +55 -0
  519. package/src/utils/fieldErrors.test.ts +35 -0
  520. package/src/utils/fieldErrors.ts +27 -0
  521. package/src/utils/formatValue.test.tsx +65 -0
  522. package/src/utils/formatValue.tsx +117 -0
  523. package/src/utils/layoutStorage.ts +52 -0
  524. package/src/utils/redirectHandler.ts +29 -0
  525. package/src/utils/tableFormatters.test.ts +54 -0
  526. package/src/utils/tableFormatters.ts +104 -0
  527. package/src/utils/widgetVisibilityStorage.ts +38 -0
  528. package/tailwind.config.js +9 -0
  529. package/vite.config.ts +17 -0
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ChevronDown } from 'lucide-react';
3
+ import { Icon } from '../utils/Icon';
4
+ import { cn } from '../../utils/classNames';
5
+ import { translate } from '../../i18n/activeLocale';
6
+ export function TablePagination({ schema, currentPage, perPage, totalRecords, onPageChange, onPageSizeChange, className, }) {
7
+ if (!schema.paginate || totalRecords === 0) {
8
+ return null;
9
+ }
10
+ const lastPage = Math.ceil(totalRecords / perPage);
11
+ const pages = [];
12
+ const totalPages = lastPage;
13
+ const current = currentPage;
14
+ const delta = 2;
15
+ if (totalPages <= 9) {
16
+ for (let i = 1; i <= totalPages; i++) {
17
+ pages.push(i);
18
+ }
19
+ }
20
+ else {
21
+ pages.push(1);
22
+ const rangeStart = Math.max(2, current - delta);
23
+ const rangeEnd = Math.min(totalPages - 1, current + delta);
24
+ if (rangeStart > 2) {
25
+ pages.push('ellipsis-start');
26
+ }
27
+ for (let i = rangeStart; i <= rangeEnd; i++) {
28
+ pages.push(i);
29
+ }
30
+ if (rangeEnd < totalPages - 1) {
31
+ pages.push('ellipsis-end');
32
+ }
33
+ pages.push(totalPages);
34
+ }
35
+ const rangeStart = (currentPage - 1) * perPage + 1;
36
+ const rangeEnd = Math.min(currentPage * perPage, totalRecords);
37
+ const navButtonClass = 'inline-flex h-8 w-8 items-center justify-center rounded-full text-sm text-fg-secondary transition-colors hover:bg-hover/70 hover:text-fg disabled:cursor-not-allowed disabled:opacity-40 touch-manipulation';
38
+ const pageButtonClass = (active) => cn('inline-flex h-8 min-w-8 items-center justify-center rounded-full px-2.5 text-sm transition-colors', active
39
+ ? 'bg-raised font-medium text-fg shadow-soft-sm'
40
+ : 'text-fg-secondary hover:bg-hover/70 hover:text-fg');
41
+ return (_jsxs("div", { className: cn('flex flex-col gap-3 px-4 py-3 sm:flex-row sm:items-center sm:justify-between', className), children: [_jsx("div", { className: "flex min-w-0 items-center gap-2", children: _jsxs("span", { className: "whitespace-nowrap text-sm text-fg-secondary", children: [_jsx("span", { className: "sm:hidden", children: translate('core:pagination.range_compact', {
42
+ start: rangeStart,
43
+ end: rangeEnd,
44
+ total: totalRecords,
45
+ }) }), _jsx("span", { className: "hidden sm:inline", children: translate('core:pagination.showing', {
46
+ start: rangeStart,
47
+ end: rangeEnd,
48
+ total: totalRecords,
49
+ }) })] }) }), _jsxs("div", { className: "flex flex-wrap items-center gap-3 sm:gap-4", children: [schema.recordsPerPageOptions && schema.recordsPerPageOptions.length > 0 && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "whitespace-nowrap text-sm text-fg-secondary", children: translate('core:pagination.per_page_short') }), _jsxs("div", { className: "relative", children: [_jsx("select", { value: perPage, onChange: e => onPageSizeChange(Number(e.target.value)), className: "h-8 min-w-[4.5rem] appearance-none rounded-full border border-border bg-input/60 pl-3 pr-9 text-sm text-fg focus:outline-none focus:ring-2 focus:ring-ring", "aria-label": translate('core:pagination.per_page'), children: schema.recordsPerPageOptions.map(option => (_jsx("option", { value: option, children: option }, option))) }), _jsx(ChevronDown, { className: "pointer-events-none absolute right-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-fg-muted" })] })] })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: () => onPageChange(currentPage - 1), disabled: currentPage === 1, className: navButtonClass, title: translate('core:pagination.previous'), "aria-label": translate('core:pagination.previous'), children: _jsx(Icon, { name: "ChevronLeft", size: 16 }) }), _jsxs("span", { className: "min-w-16 px-2 py-1.5 text-center text-sm text-fg-secondary sm:hidden", children: [currentPage, " / ", lastPage] }), _jsx("div", { className: "hidden items-center gap-1 sm:flex", children: pages.map((page, index) => {
50
+ if (page === 'ellipsis-start' || page === 'ellipsis-end') {
51
+ return (_jsx("span", { className: "px-2 text-sm text-fg-muted", children: "\u2026" }, `ellipsis-${index}`));
52
+ }
53
+ return (_jsx("button", { onClick: () => onPageChange(page), className: pageButtonClass(currentPage === page), "aria-current": currentPage === page ? 'page' : undefined, children: page }, page));
54
+ }) }), _jsx("button", { onClick: () => onPageChange(currentPage + 1), disabled: currentPage === lastPage, className: navButtonClass, title: translate('core:pagination.next'), "aria-label": translate('core:pagination.next'), children: _jsx(Icon, { name: "ChevronRight", size: 16 }) })] })] })] }));
55
+ }
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { SerializedTable } from '@maxal_studio/kratosjs';
3
+ interface TableRowProps {
4
+ schema: SerializedTable;
5
+ row: any;
6
+ rowIndex: number;
7
+ totalRows: number;
8
+ rowId: any;
9
+ visibleColumns: any[];
10
+ isSelected: boolean;
11
+ hasChanges: boolean;
12
+ openActionsRowId: any;
13
+ onRowSelect: (rowId: any) => void;
14
+ onCellChange: (rowId: any, columnName: string, value: any) => void;
15
+ onRowAction: (actionName: string, rowId: any) => void;
16
+ onSaveRow: (rowId: any) => void;
17
+ onResetRow: (rowId: any) => void;
18
+ onToggleActions: (rowId: any) => void;
19
+ }
20
+ export declare function TableRow({ schema, row, rowIndex, totalRows, rowId, visibleColumns, isSelected, hasChanges, openActionsRowId, onRowSelect, onCellChange, onRowAction, onSaveRow, onResetRow, onToggleActions, }: TableRowProps): React.JSX.Element;
21
+ export {};
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useColumnRegistry } from '../../contexts/ColumnRegistryContext';
3
+ import { cn } from '../../utils/classNames';
4
+ import { TableActionsDropdown } from './TableActionsDropdown';
5
+ import { Checkbox } from '../Checkbox';
6
+ import { PillButton } from '../ui/PillButton';
7
+ import { translate } from '../../i18n/activeLocale';
8
+ import { Slot } from '../../slots/Slot';
9
+ export function TableRow({ schema, row, rowIndex, totalRows, rowId, visibleColumns, isSelected, hasChanges, openActionsRowId, onRowSelect, onCellChange, onRowAction, onSaveRow, onResetRow, onToggleActions, }) {
10
+ const columnRegistry = useColumnRegistry();
11
+ const rowBg = cn(schema.striped && !hasChanges && (rowIndex % 2 === 1 ? 'bg-muted/25' : 'bg-surface'), hasChanges && 'bg-accent-soft/20');
12
+ const stickyActionsBg = cn('border-l border-border shadow-[-6px_0_10px_-6px] shadow-black/10', hasChanges ? 'bg-accent-soft' : schema.striped && rowIndex % 2 === 1 ? 'bg-muted' : 'bg-surface', 'group-hover:bg-hover');
13
+ return (_jsxs("tr", { className: cn('group border-b border-border/60 transition-colors last:border-b-0 hover:bg-hover/70', hasChanges && 'ring-1 ring-inset ring-accent/20', rowBg), children: [schema.bulkActions && schema.bulkActions.length > 0 && (_jsx("td", { className: "w-12 px-4 py-3", children: _jsx(Checkbox, { id: `checkbox-${rowId}`, checked: isSelected, onChange: () => onRowSelect(rowId) }) })), visibleColumns.map(column => {
14
+ const ColumnComponent = columnRegistry[column.type];
15
+ const isMediaColumn = ['image', 'video', 'media'].includes(column.type);
16
+ const width = !isMediaColumn && column.width
17
+ ? typeof column.width === 'number'
18
+ ? `${column.width}px`
19
+ : /^\d+$/.test(column.width)
20
+ ? `${column.width}px`
21
+ : column.width
22
+ : undefined;
23
+ const widthStyle = width ? { width, minWidth: width, maxWidth: width } : undefined;
24
+ if (!ColumnComponent) {
25
+ return (_jsxs("td", { className: "px-4 py-3 text-sm text-fg-secondary", style: widthStyle, children: ["Unknown column type: ", column.type] }, column.name));
26
+ }
27
+ const isEditable = ['textinput', 'select', 'checkbox', 'toggle'].includes(column.type);
28
+ return (_jsx("td", { className: "px-4 py-3 text-sm text-fg whitespace-nowrap", style: widthStyle, children: _jsx(ColumnComponent, { column: column, record: row, rowIndex: rowIndex, onCellChange: isEditable ? (value) => onCellChange(rowId, column.name, value) : undefined }) }, column.name));
29
+ }), _jsx("td", { className: cn('sticky right-0 px-4 py-3 text-right transition-colors', stickyActionsBg), style: {
30
+ zIndex: openActionsRowId === rowId ? 50 : 10,
31
+ }, children: _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx(Slot, { name: "table.rowActions", context: { schema, record: row, data: { rowId, rowIndex } }, as: "div", className: "flex items-center gap-2 empty:hidden" }), hasChanges && (_jsxs(_Fragment, { children: [_jsx(PillButton, { variant: "primary", onClick: () => onSaveRow(rowId), title: translate('core:table.save_changes'), children: translate('core:common.save') }), _jsx(PillButton, { variant: "default", onClick: () => onResetRow(rowId), title: translate('core:table.reset_changes'), children: translate('core:common.reset') }), _jsx("div", { className: "hidden h-5 w-px bg-border sm:block", "aria-hidden": true })] })), schema.actions && schema.actions.length > 0 && (_jsx(TableActionsDropdown, { schema: schema, rowId: rowId, rowIndex: rowIndex, totalRows: totalRows, isOpen: openActionsRowId === rowId, onToggle: () => onToggleActions(rowId), onAction: onRowAction }))] }) })] }));
32
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ interface TableSearchBarProps {
3
+ searchable: boolean;
4
+ searchQuery: string;
5
+ onSearchChange: (query: string) => void;
6
+ onCreateClick?: () => void;
7
+ onCreateModalOpen?: () => void;
8
+ showCreateButton?: boolean;
9
+ }
10
+ export declare function TableSearchBar({ searchable, searchQuery, onSearchChange, onCreateClick, onCreateModalOpen, showCreateButton, }: TableSearchBarProps): React.JSX.Element;
11
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Search } from 'lucide-react';
3
+ import { Icon } from '../utils/Icon';
4
+ import { cn } from '../../utils/classNames';
5
+ import { useTranslation } from '../../i18n/useTranslation';
6
+ export function TableSearchBar({ searchable, searchQuery, onSearchChange, onCreateClick, onCreateModalOpen, showCreateButton = true, }) {
7
+ const { t } = useTranslation();
8
+ if (!searchable && !showCreateButton) {
9
+ return null;
10
+ }
11
+ return (_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 sm:gap-3", children: [searchable && (_jsxs("div", { className: "relative min-w-0 flex-1", children: [_jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-fg-muted" }), _jsx("input", { type: "text", placeholder: t('core:common.search'), value: searchQuery, onChange: e => onSearchChange(e.target.value), className: cn('h-9 w-full rounded-full border border-border bg-input/60 pl-9 pr-4 text-sm text-fg', 'placeholder:text-fg-muted', 'focus:border-accent focus:outline-none focus:ring-2 focus:ring-ring'), "aria-label": t('core:search.records') })] })), showCreateButton && (_jsxs("button", { onClick: onCreateClick || onCreateModalOpen, className: cn('inline-flex h-9 shrink-0 touch-manipulation items-center justify-center gap-2 rounded-full bg-accent px-3 text-sm font-medium text-accent-fg transition-colors', 'sm:px-4 hover:bg-accent-hover', !searchable && 'w-auto', searchable && 'w-9 sm:w-auto'), title: t('core:table.create_record'), "aria-label": t('core:table.create_record'), children: [_jsx(Icon, { name: "Plus", className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "hidden sm:inline", children: t('core:common.create') })] }))] }));
12
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ export interface TableTab {
3
+ key: string;
4
+ label: string;
5
+ icon?: string;
6
+ default?: boolean;
7
+ }
8
+ interface TableTabsProps {
9
+ tabs: TableTab[];
10
+ activeTab: string | null;
11
+ onTabChange: (tabKey: string | null) => void;
12
+ }
13
+ export declare function TableTabs({ tabs, activeTab, onTabChange }: TableTabsProps): React.JSX.Element;
14
+ export {};
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Icon } from '../utils/Icon';
3
+ import { cn } from '../../utils/classNames';
4
+ import { pillTabClass } from '../ui/PillButton';
5
+ import { translate } from '../../i18n/activeLocale';
6
+ export function TableTabs({ tabs, activeTab, onTabChange }) {
7
+ return (_jsxs("div", { className: cn('flex w-full max-w-full touch-pan-x snap-x snap-mandatory gap-1 overflow-x-auto overscroll-x-contain sm:snap-none'), style: { WebkitOverflowScrolling: 'touch' }, role: "tablist", "aria-label": translate('core:table.view_tabs'), children: [_jsx("button", { role: "tab", "aria-selected": activeTab === null, onClick: () => onTabChange(null), className: pillTabClass(activeTab === null), children: translate('core:common.all') }), tabs.map(tab => (_jsxs("button", { role: "tab", "aria-selected": activeTab === tab.key, onClick: () => onTabChange(tab.key), className: pillTabClass(activeTab === tab.key), children: [tab.icon && _jsx(Icon, { name: tab.icon, className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "whitespace-nowrap", children: tab.label })] }, tab.key)))] }));
8
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export type BadgeVariant = 'neutral' | 'accent' | 'success' | 'danger' | 'warning';
3
+ export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
4
+ variant?: BadgeVariant;
5
+ }
6
+ export declare function Badge({ variant, className, children, ...rest }: BadgeProps): React.JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../../utils/classNames';
3
+ const VARIANT_CLASSES = {
4
+ neutral: 'bg-muted text-fg-secondary',
5
+ accent: 'bg-accent-soft text-accent',
6
+ success: 'bg-success-soft text-success',
7
+ danger: 'bg-danger-soft text-danger',
8
+ warning: 'bg-warning-soft text-warning',
9
+ };
10
+ export function Badge({ variant = 'neutral', className, children, ...rest }) {
11
+ return (_jsx("span", { className: cn('inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap', VARIANT_CLASSES[variant], className), ...rest, children: children }));
12
+ }
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'outline';
3
+ export type ButtonSize = 'sm' | 'md';
4
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
+ variant?: ButtonVariant;
6
+ size?: ButtonSize;
7
+ loading?: boolean;
8
+ /** Use squared corners instead of the default pill shape. */
9
+ square?: boolean;
10
+ /** Icon element rendered before the label */
11
+ icon?: React.ReactNode;
12
+ }
13
+ export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
14
+ export interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
15
+ variant?: ButtonVariant;
16
+ size?: ButtonSize;
17
+ /** Use squared corners instead of the default pill shape. */
18
+ square?: boolean;
19
+ /** Accessible label (required — icon-only buttons have no text) */
20
+ 'aria-label': string;
21
+ }
22
+ export declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { cn } from '../../utils/classNames';
4
+ import { Spinner } from './Spinner';
5
+ /* Static class maps — never build Tailwind classes dynamically. */
6
+ const VARIANT_CLASSES = {
7
+ primary: 'bg-accent text-accent-fg hover:bg-accent-hover shadow-soft-sm',
8
+ secondary: 'bg-input text-fg border border-input-border hover:bg-hover shadow-soft-sm',
9
+ ghost: 'bg-transparent text-fg-secondary hover:bg-hover hover:text-fg',
10
+ danger: 'bg-danger text-white hover:bg-danger-hover shadow-soft-sm',
11
+ outline: 'bg-transparent text-fg border border-border-strong hover:bg-hover',
12
+ };
13
+ const SIZE_CLASSES = {
14
+ sm: 'h-8 px-3 text-xs gap-1.5',
15
+ md: 'h-10 px-4 text-sm gap-2',
16
+ };
17
+ export const Button = React.forwardRef(function Button({ variant = 'primary', size = 'md', loading = false, square = false, icon, className, children, disabled, type, ...rest }, ref) {
18
+ return (_jsxs("button", { ref: ref, type: type ?? 'button', disabled: disabled || loading, className: cn('inline-flex items-center justify-center font-medium transition-colors touch-manipulation', square ? 'rounded-lg' : 'rounded-full', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', 'disabled:opacity-60 disabled:cursor-not-allowed', VARIANT_CLASSES[variant], SIZE_CLASSES[size], className), ...rest, children: [loading ? (_jsx(Spinner, { size: "sm", className: "shrink-0" })) : icon ? (_jsx("span", { className: "shrink-0", children: icon })) : null, children] }));
19
+ });
20
+ export const IconButton = React.forwardRef(function IconButton({ variant = 'ghost', size = 'md', square = false, className, children, type, ...rest }, ref) {
21
+ return (_jsx("button", { ref: ref, type: type ?? 'button', className: cn('inline-flex items-center justify-center transition-colors touch-manipulation', square ? 'rounded-lg' : 'rounded-full', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', 'disabled:opacity-60 disabled:cursor-not-allowed', VARIANT_CLASSES[variant], size === 'sm' ? 'h-8 w-8' : 'h-10 w-10', className), ...rest, children: children }));
22
+ });
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /** Raised cards get a soft shadow (modals, popovers); flat cards only a border */
4
+ raised?: boolean;
5
+ padding?: boolean;
6
+ }
7
+ export declare function Card({ raised, padding, className, children, ...rest }: CardProps): React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../../utils/classNames';
3
+ export function Card({ raised = false, padding = true, className, children, ...rest }) {
4
+ return (_jsx("div", { className: cn('rounded-lg border border-border', raised ? 'bg-raised shadow-soft' : 'bg-surface shadow-soft-sm', padding && 'p-4 sm:p-6', className), ...rest, children: children }));
5
+ }
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ export interface ConfirmOptions {
3
+ title?: string;
4
+ message: React.ReactNode;
5
+ confirmLabel?: string;
6
+ cancelLabel?: string;
7
+ /** Style the confirm button as destructive */
8
+ danger?: boolean;
9
+ }
10
+ type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;
11
+ export declare function ConfirmProvider({ children }: {
12
+ children: React.ReactNode;
13
+ }): React.JSX.Element;
14
+ /**
15
+ * Promise-based confirmation dialog. Outside a ConfirmProvider it falls
16
+ * back to the native window.confirm so callers always get an answer.
17
+ */
18
+ export declare function useConfirm(): ConfirmFn;
19
+ export {};
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
3
+ import { AlertTriangle } from 'lucide-react';
4
+ import { Button } from './Button';
5
+ import { translate } from '../../i18n/activeLocale';
6
+ const ConfirmContext = createContext(null);
7
+ export function ConfirmProvider({ children }) {
8
+ const [pending, setPending] = useState(null);
9
+ const confirmButtonRef = useRef(null);
10
+ const confirm = useCallback(options => {
11
+ return new Promise(resolve => {
12
+ setPending({ ...options, resolve });
13
+ });
14
+ }, []);
15
+ const settle = useCallback((confirmed) => {
16
+ pending?.resolve(confirmed);
17
+ setPending(null);
18
+ }, [pending]);
19
+ // Focus the confirm button and support Escape to cancel
20
+ useEffect(() => {
21
+ if (!pending)
22
+ return;
23
+ confirmButtonRef.current?.focus();
24
+ const onKeyDown = (e) => {
25
+ if (e.key === 'Escape')
26
+ settle(false);
27
+ };
28
+ window.addEventListener('keydown', onKeyDown);
29
+ return () => window.removeEventListener('keydown', onKeyDown);
30
+ }, [pending, settle]);
31
+ return (_jsxs(ConfirmContext.Provider, { value: confirm, children: [children, pending && (_jsxs("div", { className: "fixed inset-0 z-[90] flex items-center justify-center p-4", children: [_jsx("div", { className: "absolute inset-0 bg-black/50", onClick: () => settle(false), "aria-hidden": "true" }), _jsxs("div", { role: "alertdialog", "aria-modal": "true", "aria-label": pending.title || translate('core:common.confirm'), className: "relative w-full max-w-md rounded-lg border border-border bg-raised p-6 shadow-soft-lg", children: [_jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: pending.danger
32
+ ? 'flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-danger-soft text-danger'
33
+ : 'flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-accent-soft text-accent', children: _jsx(AlertTriangle, { className: "h-5 w-5" }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h3", { className: "text-base font-semibold text-fg", children: pending.title || translate('core:confirm.are_you_sure') }), _jsx("div", { className: "mt-1.5 text-sm text-fg-secondary", children: pending.message })] })] }), _jsxs("div", { className: "mt-6 flex justify-end gap-2", children: [_jsx(Button, { variant: "secondary", onClick: () => settle(false), children: pending.cancelLabel || translate('core:common.cancel') }), _jsx(Button, { ref: confirmButtonRef, variant: pending.danger ? 'danger' : 'primary', onClick: () => settle(true), children: pending.confirmLabel || translate('core:common.confirm') })] })] })] }))] }));
34
+ }
35
+ /**
36
+ * Promise-based confirmation dialog. Outside a ConfirmProvider it falls
37
+ * back to the native window.confirm so callers always get an answer.
38
+ */
39
+ export function useConfirm() {
40
+ const context = useContext(ConfirmContext);
41
+ return (context ??
42
+ (async (options) => window.confirm(typeof options.message === 'string'
43
+ ? options.message
44
+ : options.title || translate('core:confirm.are_you_sure'))));
45
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export interface EmptyStateProps {
3
+ icon?: React.ReactNode;
4
+ title: string;
5
+ description?: string;
6
+ action?: React.ReactNode;
7
+ className?: string;
8
+ }
9
+ export declare function EmptyState({ icon, title, description, action, className }: EmptyStateProps): React.JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Inbox } from 'lucide-react';
3
+ import { cn } from '../../utils/classNames';
4
+ export function EmptyState({ icon, title, description, action, className }) {
5
+ return (_jsxs("div", { className: cn('flex flex-col items-center justify-center px-6 py-12 text-center', className), children: [_jsx("div", { className: "mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-muted text-fg-muted", children: icon ?? _jsx(Inbox, { className: "h-6 w-6" }) }), _jsx("p", { className: "text-sm font-semibold text-fg", children: title }), description && _jsx("p", { className: "mt-1 max-w-sm text-sm text-fg-secondary", children: description }), action && _jsx("div", { className: "mt-4", children: action })] }));
6
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface ErrorAlertProps {
3
+ message: React.ReactNode;
4
+ onDismiss?: () => void;
5
+ className?: string;
6
+ }
7
+ export declare function ErrorAlert({ message, onDismiss, className }: ErrorAlertProps): React.JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { X, AlertCircle } from 'lucide-react';
3
+ import { cn } from '../../utils/classNames';
4
+ import { translate } from '../../i18n/activeLocale';
5
+ export function ErrorAlert({ message, onDismiss, className }) {
6
+ if (!message)
7
+ return null;
8
+ return (_jsxs("div", { role: "alert", className: cn('flex items-start justify-between gap-3 rounded-lg border border-danger/30 bg-danger-soft px-4 py-3', className), children: [_jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [_jsx(AlertCircle, { className: "mt-0.5 h-4 w-4 shrink-0 text-danger" }), _jsx("p", { className: "min-w-0 flex-1 break-words text-sm font-medium text-danger", children: message })] }), onDismiss && (_jsx("button", { type: "button", onClick: onDismiss, "aria-label": translate('core:common.dismiss'), className: "shrink-0 rounded-md p-1 text-danger transition-colors hover:bg-danger/10", children: _jsx(X, { className: "h-4 w-4" }) }))] }));
9
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
3
+ /** Render the error state (red border/ring) */
4
+ invalid?: boolean;
5
+ }
6
+ export declare const inputClasses: (invalid?: boolean, className?: string) => string;
7
+ export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
8
+ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
9
+ invalid?: boolean;
10
+ }
11
+ export declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { cn } from '../../utils/classNames';
4
+ export const inputClasses = (invalid, className) => cn('w-full h-10 px-3 text-sm rounded-lg border transition-colors', 'bg-input text-fg border-input-border placeholder:text-fg-muted', 'focus:outline-none focus:ring-2 focus:ring-ring focus:border-accent', 'disabled:opacity-60 disabled:cursor-not-allowed', invalid && 'border-danger focus:border-danger focus:ring-danger-soft', className);
5
+ export const Input = React.forwardRef(function Input({ invalid, className, ...rest }, ref) {
6
+ return _jsx("input", { ref: ref, className: inputClasses(invalid, className), ...rest });
7
+ });
8
+ export const Textarea = React.forwardRef(function Textarea({ invalid, className, ...rest }, ref) {
9
+ return (_jsx("textarea", { ref: ref, className: cn('w-full px-3 py-2 text-sm rounded-lg border transition-colors', 'bg-input text-fg border-input-border placeholder:text-fg-muted', 'focus:outline-none focus:ring-2 focus:ring-ring focus:border-accent', 'disabled:opacity-60 disabled:cursor-not-allowed', invalid && 'border-danger focus:border-danger focus:ring-danger-soft', className), ...rest }));
10
+ });
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
3
+ required?: boolean;
4
+ }
5
+ export declare function Label({ required, className, children, ...rest }: LabelProps): React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../utils/classNames';
3
+ export function Label({ required, className, children, ...rest }) {
4
+ return (_jsxs("label", { className: cn('block text-sm font-medium text-fg', className), ...rest, children: [children, required && _jsx("span", { className: "ml-0.5 text-danger", children: "*" })] }));
5
+ }
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ export type PillButtonVariant = 'default' | 'primary' | 'danger' | 'ghost';
3
+ export interface PillButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
4
+ variant?: PillButtonVariant;
5
+ icon?: React.ReactNode;
6
+ }
7
+ export declare function PillButton({ variant, icon, className, children, type, ...rest }: PillButtonProps): React.JSX.Element;
8
+ export interface PillIconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
9
+ variant?: PillButtonVariant;
10
+ active?: boolean;
11
+ }
12
+ export declare function PillIconButton({ variant, active, className, children, type, ...rest }: PillIconButtonProps): React.JSX.Element;
13
+ /** Pill tab styling shared by table tabs, modal relation tabs, and breadcrumbs. */
14
+ export declare function pillTabClass(active: boolean): string;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../utils/classNames';
3
+ const focusClass = 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';
4
+ const VARIANT_CLASSES = {
5
+ default: 'border border-border bg-input/60 text-fg hover:bg-hover/70 disabled:cursor-not-allowed disabled:opacity-60',
6
+ primary: 'border border-transparent bg-accent text-accent-fg hover:bg-accent-hover shadow-soft-sm',
7
+ danger: 'border border-transparent bg-danger text-white hover:bg-danger-hover shadow-soft-sm',
8
+ ghost: 'border border-transparent bg-transparent text-fg-secondary hover:bg-hover/70 hover:text-fg',
9
+ };
10
+ export function PillButton({ variant = 'default', icon, className, children, type, ...rest }) {
11
+ return (_jsxs("button", { type: type ?? 'button', className: cn('inline-flex h-9 touch-manipulation items-center justify-center gap-1.5 rounded-full px-3 text-sm font-medium transition-colors', focusClass, VARIANT_CLASSES[variant], className), ...rest, children: [icon ? _jsx("span", { className: "shrink-0", children: icon }) : null, children] }));
12
+ }
13
+ export function PillIconButton({ variant = 'default', active = false, className, children, type, ...rest }) {
14
+ return (_jsx("button", { type: type ?? 'button', className: cn('inline-flex h-9 w-9 shrink-0 touch-manipulation items-center justify-center rounded-full text-sm transition-colors', focusClass, active ? 'border border-border bg-raised text-fg shadow-soft-sm' : VARIANT_CLASSES[variant], className), ...rest, children: children }));
15
+ }
16
+ /** Pill tab styling shared by table tabs, modal relation tabs, and breadcrumbs. */
17
+ export function pillTabClass(active) {
18
+ return cn('inline-flex shrink-0 touch-manipulation items-center gap-2 rounded-full px-3 py-1.5 text-sm transition-colors whitespace-nowrap', active ? 'bg-raised font-medium text-fg shadow-soft-sm' : 'text-fg-secondary hover:bg-hover/70 hover:text-fg');
19
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
3
+ invalid?: boolean;
4
+ /** Highlight the control (e.g. an active filter) */
5
+ active?: boolean;
6
+ }
7
+ export declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLSelectElement>>;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { ChevronDown } from 'lucide-react';
4
+ import { cn } from '../../utils/classNames';
5
+ export const Select = React.forwardRef(function Select({ invalid, active, className, children, ...rest }, ref) {
6
+ return (_jsxs("div", { className: cn('relative', className), children: [_jsx("select", { ref: ref, className: cn('w-full h-10 px-3 pr-10 text-sm rounded-lg border appearance-none cursor-pointer transition-colors', 'bg-input text-fg border-input-border', 'focus:outline-none focus:ring-2 focus:ring-ring focus:border-accent', 'disabled:opacity-60 disabled:cursor-not-allowed', invalid && 'border-danger focus:border-danger focus:ring-danger-soft', active && 'ring-2 ring-ring border-accent'), ...rest, children: children }), _jsx(ChevronDown, { className: "absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 text-fg-muted pointer-events-none" })] }));
7
+ });
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export interface SpinnerProps {
3
+ size?: 'sm' | 'md' | 'lg';
4
+ className?: string;
5
+ /** Optional label rendered next to the spinner */
6
+ label?: string;
7
+ }
8
+ export declare function Spinner({ size, className, label }: SpinnerProps): React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../utils/classNames';
3
+ import { translate } from '../../i18n/activeLocale';
4
+ const SIZE_CLASSES = {
5
+ sm: 'h-4 w-4 border-2',
6
+ md: 'h-6 w-6 border-2',
7
+ lg: 'h-8 w-8 border-[3px]',
8
+ };
9
+ export function Spinner({ size = 'md', className, label }) {
10
+ const circle = (_jsx("span", { role: "status", "aria-label": label || translate('core:common.loading'), className: cn('inline-block animate-spin rounded-full border-current border-t-transparent', SIZE_CLASSES[size], className) }));
11
+ if (!label)
12
+ return circle;
13
+ return (_jsxs("span", { className: "inline-flex items-center gap-2 text-fg-secondary", children: [circle, _jsx("span", { className: "text-sm", children: label })] }));
14
+ }
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ export type ToastVariant = 'success' | 'error' | 'info';
3
+ export interface ToastOptions {
4
+ variant?: ToastVariant;
5
+ /** Auto-dismiss delay in ms (default 4000; 0 disables) */
6
+ duration?: number;
7
+ }
8
+ export interface ToastApi {
9
+ toast: (message: React.ReactNode, options?: ToastOptions) => void;
10
+ success: (message: React.ReactNode) => void;
11
+ error: (message: React.ReactNode) => void;
12
+ info: (message: React.ReactNode) => void;
13
+ }
14
+ export declare function ToastProvider({ children }: {
15
+ children: React.ReactNode;
16
+ }): React.JSX.Element;
17
+ /**
18
+ * Toast API. Outside a ToastProvider (e.g. standalone FormRenderer usage)
19
+ * it degrades to console logging instead of crashing.
20
+ */
21
+ export declare function useToast(): ToastApi;
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';
3
+ import { CheckCircle2, AlertCircle, Info, X } from 'lucide-react';
4
+ import { cn } from '../../utils/classNames';
5
+ import { translate } from '../../i18n/activeLocale';
6
+ const ToastContext = createContext(null);
7
+ const VARIANT_STYLES = {
8
+ success: { icon: _jsx(CheckCircle2, { className: "h-5 w-5 text-success" }), bar: 'bg-success' },
9
+ error: { icon: _jsx(AlertCircle, { className: "h-5 w-5 text-danger" }), bar: 'bg-danger' },
10
+ info: { icon: _jsx(Info, { className: "h-5 w-5 text-accent" }), bar: 'bg-accent' },
11
+ };
12
+ export function ToastProvider({ children }) {
13
+ const [toasts, setToasts] = useState([]);
14
+ const idRef = useRef(0);
15
+ const dismiss = useCallback((id) => {
16
+ setToasts(prev => prev.filter(t => t.id !== id));
17
+ }, []);
18
+ const toast = useCallback((message, options) => {
19
+ const id = ++idRef.current;
20
+ const variant = options?.variant ?? 'info';
21
+ setToasts(prev => [...prev, { id, message, variant }]);
22
+ const duration = options?.duration ?? 4000;
23
+ if (duration > 0) {
24
+ setTimeout(() => dismiss(id), duration);
25
+ }
26
+ }, [dismiss]);
27
+ const api = useMemo(() => ({
28
+ toast,
29
+ success: message => toast(message, { variant: 'success' }),
30
+ error: message => toast(message, { variant: 'error', duration: 6000 }),
31
+ info: message => toast(message, { variant: 'info' }),
32
+ }), [toast]);
33
+ return (_jsxs(ToastContext.Provider, { value: api, children: [children, toasts.length > 0 && (_jsx("div", { className: "fixed bottom-4 right-4 z-[100] flex w-[calc(100vw-2rem)] max-w-sm flex-col gap-2", children: toasts.map(t => (_jsxs("div", { role: "status", className: "relative flex items-start gap-3 overflow-hidden rounded-lg border border-border bg-raised p-4 pr-10 shadow-soft-lg", children: [_jsx("span", { className: cn('absolute inset-y-0 left-0 w-1', VARIANT_STYLES[t.variant].bar) }), _jsx("span", { className: "shrink-0", children: VARIANT_STYLES[t.variant].icon }), _jsx("div", { className: "min-w-0 flex-1 break-words text-sm text-fg", children: t.message }), _jsx("button", { type: "button", onClick: () => dismiss(t.id), "aria-label": translate('core:common.dismiss'), className: "absolute right-2 top-2 rounded-md p-1 text-fg-muted transition-colors hover:bg-hover hover:text-fg", children: _jsx(X, { className: "h-4 w-4" }) })] }, t.id))) }))] }));
34
+ }
35
+ /**
36
+ * Toast API. Outside a ToastProvider (e.g. standalone FormRenderer usage)
37
+ * it degrades to console logging instead of crashing.
38
+ */
39
+ export function useToast() {
40
+ const context = useContext(ToastContext);
41
+ return useMemo(() => {
42
+ if (context)
43
+ return context;
44
+ const fallback = (message) => console.info('[kratosjs toast]', message);
45
+ return { toast: fallback, success: fallback, error: fallback, info: fallback };
46
+ }, [context]);
47
+ }
@@ -0,0 +1,24 @@
1
+ export { PillButton, PillIconButton, pillTabClass } from './PillButton';
2
+ export type { PillButtonProps, PillIconButtonProps, PillButtonVariant } from './PillButton';
3
+ export { Button, IconButton } from './Button';
4
+ export type { ButtonProps, IconButtonProps, ButtonVariant, ButtonSize } from './Button';
5
+ export { Input, Textarea, inputClasses } from './Input';
6
+ export type { InputProps, TextareaProps } from './Input';
7
+ export { Select } from './Select';
8
+ export type { SelectProps } from './Select';
9
+ export { Label } from './Label';
10
+ export type { LabelProps } from './Label';
11
+ export { Badge } from './Badge';
12
+ export type { BadgeProps, BadgeVariant } from './Badge';
13
+ export { Card } from './Card';
14
+ export type { CardProps } from './Card';
15
+ export { Spinner } from './Spinner';
16
+ export type { SpinnerProps } from './Spinner';
17
+ export { EmptyState } from './EmptyState';
18
+ export type { EmptyStateProps } from './EmptyState';
19
+ export { ErrorAlert } from './ErrorAlert';
20
+ export type { ErrorAlertProps } from './ErrorAlert';
21
+ export { ToastProvider, useToast } from './Toast';
22
+ export type { ToastApi, ToastOptions, ToastVariant } from './Toast';
23
+ export { ConfirmProvider, useConfirm } from './ConfirmDialog';
24
+ export type { ConfirmOptions } from './ConfirmDialog';
@@ -0,0 +1,12 @@
1
+ export { PillButton, PillIconButton, pillTabClass } from './PillButton';
2
+ export { Button, IconButton } from './Button';
3
+ export { Input, Textarea, inputClasses } from './Input';
4
+ export { Select } from './Select';
5
+ export { Label } from './Label';
6
+ export { Badge } from './Badge';
7
+ export { Card } from './Card';
8
+ export { Spinner } from './Spinner';
9
+ export { EmptyState } from './EmptyState';
10
+ export { ErrorAlert } from './ErrorAlert';
11
+ export { ToastProvider, useToast } from './Toast';
12
+ export { ConfirmProvider, useConfirm } from './ConfirmDialog';
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export interface HintDisplayProps {
3
+ hint?: string;
4
+ hintIcon?: string;
5
+ hintColor?: string;
6
+ }
7
+ /**
8
+ * Reusable hint display component
9
+ * Shows hint text with optional icon and color
10
+ */
11
+ export declare function HintDisplay({ hint, hintIcon, hintColor }: HintDisplayProps): React.JSX.Element;