@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,10 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+ import { SerializedComponent } from '@maxal_studio/kratosjs';
4
+ export declare function TabsField({ schema: tabNodes, defaultTab, columns, mode, disabled, value, _recordData, description, operation, ...props }: FieldProps & {
5
+ /** Tab child components (each a serialized `tab` node with label/icon/schema). */
6
+ schema?: SerializedComponent[];
7
+ defaultTab?: number;
8
+ _recordData?: any;
9
+ operation?: 'create' | 'edit' | 'view';
10
+ }): React.JSX.Element;
@@ -0,0 +1,214 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useMemo, useRef } from 'react';
3
+ import { useFormContext, useWatch } from 'react-hook-form';
4
+ import { getFieldError } from '../utils/fieldErrors';
5
+ import { FieldRenderer } from '../FieldRenderer';
6
+ import { Icon } from './utils/Icon';
7
+ import { getFieldLayoutClasses } from './utils/layoutHelpers';
8
+ import { cn } from '../utils/classNames';
9
+ import { evaluateCondition } from '../runtime/conditions';
10
+ import { getChildComponents, isArrayScope, someComponent } from '../runtime/formTraversal';
11
+ import { translate } from '../i18n/activeLocale';
12
+ const isEmptyValue = (value) => value === undefined || value === null || value === '';
13
+ /**
14
+ * Recursively check if a component or its nested components have validation errors.
15
+ * Generic over the children contract — works for any container, including plugins.
16
+ */
17
+ function hasComponentErrors(component, errors) {
18
+ return someComponent(component, node => {
19
+ if (!node.name)
20
+ return false;
21
+ const fieldError = getFieldError(errors, node.name);
22
+ if (!fieldError)
23
+ return false;
24
+ // Array-scope containers (repeaters): the array itself or any item may have errors.
25
+ if (isArrayScope(node)) {
26
+ if (Array.isArray(fieldError)) {
27
+ return fieldError.some(itemErrors => itemErrors && Object.keys(itemErrors).length > 0);
28
+ }
29
+ return Object.keys(fieldError).length > 0;
30
+ }
31
+ // Ignore pure "required" errors here; required-emptiness is handled separately
32
+ // (based on current values) so a filled field doesn't keep its tab marked.
33
+ return fieldError.type !== 'required';
34
+ });
35
+ }
36
+ /**
37
+ * Check if a tab has any validation errors in its schema
38
+ */
39
+ function hasTabErrors(tabSchema, errors) {
40
+ return tabSchema.some(component => hasComponentErrors(component, errors));
41
+ }
42
+ /**
43
+ * Check if a component is required
44
+ */
45
+ /**
46
+ * Check if a component is required, evaluating conditional required logic
47
+ */
48
+ function isComponentRequired(component, formValues, operation) {
49
+ // Check direct required property
50
+ const requiredProp = component.required;
51
+ // If required is a boolean
52
+ if (typeof requiredProp === 'boolean') {
53
+ return requiredProp;
54
+ }
55
+ // If required is a function (serialized), evaluate it
56
+ if (typeof requiredProp === 'string') {
57
+ return evaluateCondition(requiredProp, formValues, operation);
58
+ }
59
+ // Check validation rules for 'required' on the serialized validation object
60
+ const validation = component.validation;
61
+ if (validation && Array.isArray(validation.rules)) {
62
+ // Check for simple 'required' string rule
63
+ if (validation.rules.some(rule => rule === 'required')) {
64
+ return true;
65
+ }
66
+ // Check for conditional required rule objects
67
+ for (const rule of validation.rules) {
68
+ if (typeof rule === 'object' && rule.rule === 'required') {
69
+ // If there's a condition function, evaluate it
70
+ const condition = rule.condition;
71
+ if (typeof condition === 'string') {
72
+ return evaluateCondition(condition, formValues, operation);
73
+ }
74
+ return true;
75
+ }
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+ /**
81
+ * Recursively check if a component (or its descendants) is required and empty.
82
+ * Generic over the children contract.
83
+ */
84
+ function hasRequiredEmptyField(component, formValues, operation) {
85
+ return someComponent(component, node => {
86
+ if (!node.name)
87
+ return false;
88
+ // Array-scope containers (repeaters): check required-empty fields within each item.
89
+ if (isArrayScope(node)) {
90
+ const items = formValues[node.name];
91
+ if (!Array.isArray(items))
92
+ return false;
93
+ const template = getChildComponents(node);
94
+ return items.some(item => template.some(field => field.name &&
95
+ isComponentRequired(field, item, operation) &&
96
+ isEmptyValue(item[field.name])));
97
+ }
98
+ if (isComponentRequired(node, formValues, operation)) {
99
+ return isEmptyValue(formValues[node.name]);
100
+ }
101
+ return false;
102
+ });
103
+ }
104
+ /**
105
+ * Check if a tab has any required empty fields
106
+ */
107
+ function hasRequiredEmptyFieldsInTab(tabSchema, formValues, operation) {
108
+ return tabSchema.some(component => hasRequiredEmptyField(component, formValues, operation));
109
+ }
110
+ export function TabsField({ schema: tabNodes, defaultTab = 0, columns, mode, disabled, value, _recordData, description, operation, ...props }) {
111
+ const [activeTab, setActiveTab] = useState(defaultTab);
112
+ const isViewMode = mode === 'view';
113
+ // Inherit API configuration from parent so nested fields (e.g. FileUpload) work inside tabs
114
+ const apiBaseUrl = props.apiBaseUrl;
115
+ const resource = props.resource;
116
+ // Get form context for validation errors and values (only in edit mode)
117
+ const formContext = mode === 'edit' ? useFormContext() : null;
118
+ const errors = formContext?.formState?.errors || {};
119
+ const submitCount = formContext?.formState?.submitCount ?? 0;
120
+ // Validation indicators (red dots) only appear after a submit attempt, so they
121
+ // never nag while the user is still filling the form.
122
+ const hasSubmitted = submitCount > 0;
123
+ // Use useWatch to get reactive form values
124
+ const formValues = mode === 'edit' && formContext ? useWatch({ control: formContext.control }) || {} : {};
125
+ // Normalize the serialized `tab` child nodes into render-friendly tab descriptors.
126
+ const tabs = useMemo(() => (Array.isArray(tabNodes) ? tabNodes : []).map((node) => ({
127
+ label: node.label,
128
+ icon: node.icon,
129
+ schema: getChildComponents(node),
130
+ })), [tabNodes]);
131
+ // Find tabs with errors
132
+ const tabsWithErrors = useMemo(() => {
133
+ if (!tabs || isViewMode)
134
+ return new Set();
135
+ const errorTabs = new Set();
136
+ tabs.forEach((tab, index) => {
137
+ if (hasTabErrors(tab.schema || [], errors)) {
138
+ errorTabs.add(index);
139
+ }
140
+ });
141
+ return errorTabs;
142
+ }, [tabs, errors, isViewMode]);
143
+ // Find tabs with required empty fields
144
+ const tabsWithRequiredEmpty = useMemo(() => {
145
+ if (!tabs || isViewMode)
146
+ return new Set();
147
+ const requiredTabs = new Set();
148
+ tabs.forEach((tab, index) => {
149
+ if (hasRequiredEmptyFieldsInTab(tab.schema || [], formValues, operation)) {
150
+ requiredTabs.add(index);
151
+ }
152
+ });
153
+ return requiredTabs;
154
+ }, [tabs, formValues, isViewMode, operation]);
155
+ // Auto-open the first tab with validation errors — exactly ONCE per submit attempt.
156
+ // Keying on submitCount (not activeTab/errors) means the jump happens when the user
157
+ // submits and never again, so manual navigation afterwards is never hijacked.
158
+ const lastHandledSubmit = useRef(0);
159
+ useEffect(() => {
160
+ if (isViewMode || submitCount === 0 || submitCount === lastHandledSubmit.current)
161
+ return;
162
+ lastHandledSubmit.current = submitCount;
163
+ const firstErrorTab = tabs.findIndex((_tab, index) => tabsWithErrors.has(index));
164
+ if (firstErrorTab !== -1) {
165
+ setActiveTab(firstErrorTab);
166
+ }
167
+ }, [submitCount, tabs, tabsWithErrors, isViewMode]);
168
+ // In view mode, use _recordData if provided, otherwise use value
169
+ const recordData = mode === 'view' && _recordData ? _recordData : value || {};
170
+ // Layout classes for tab field stacks
171
+ const fieldLayoutClasses = getFieldLayoutClasses(columns);
172
+ if (!tabs || tabs.length === 0) {
173
+ return null;
174
+ }
175
+ // In view mode, show tabs (read-only but can switch tabs)
176
+ if (isViewMode) {
177
+ return (_jsxs("div", { className: "mb-6", children: [description && _jsx("p", { className: "mb-4 text-sm text-gray-600 dark:text-gray-400", children: description }), _jsx("div", { className: "flex border-b border-gray-200 dark:border-gray-700 mb-4 overflow-x-auto", children: tabs.map((tab, index) => (_jsx("button", { type: "button", onClick: () => setActiveTab(index), className: cn('px-4 py-2 font-medium text-sm whitespace-nowrap', 'border-b-2 -mb-px', 'focus:none', activeTab === index
178
+ ? 'border-accent text-accent'
179
+ : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200'), "aria-selected": activeTab === index, role: "tab", children: _jsxs("span", { className: "inline-flex items-center gap-2", children: [tab.icon && _jsx(Icon, { name: tab.icon, className: "w-4 h-4" }), tab.label] }) }, index))) }), _jsx("div", { children: tabs[activeTab] && (_jsx("div", { className: fieldLayoutClasses, children: tabs[activeTab].schema?.map((field, fieldIndex) => {
180
+ // Determine if this nested field/layout needs full record data context
181
+ const needsRecordData = Boolean(field.needsRecordData) ||
182
+ Boolean(field.schema && Array.isArray(field.schema));
183
+ const nestedField = {
184
+ ...field,
185
+ disabled: disabled || field.disabled,
186
+ mode: mode || field.mode,
187
+ ...(needsRecordData && recordData ? { _recordData: recordData } : {}),
188
+ };
189
+ // For simple leaf fields with a name, pass their direct value in view mode
190
+ const nestedValue = mode === 'view' && field.name && !needsRecordData
191
+ ? recordData[field.name]
192
+ : undefined;
193
+ return (_jsx(FieldRenderer, { field: nestedField, mode: mode, value: nestedValue, apiBaseUrl: apiBaseUrl, resource: resource, operation: operation }, fieldIndex));
194
+ }) })) })] }));
195
+ }
196
+ // Edit mode: render tabs with navigation
197
+ // Render all tabs but hide inactive ones so React Hook Form can validate them
198
+ return (_jsxs("div", { className: "my-6", children: [description && _jsx("p", { className: "mb-4 text-sm text-gray-600 dark:text-gray-400", children: description }), _jsx("div", { className: "flex border-b border-gray-200 dark:border-gray-700 mb-4 overflow-x-auto", children: tabs.map((tab, index) => {
199
+ // Only flag tabs after a submit attempt, so the indicator reflects a real
200
+ // failed validation rather than nagging while the user is still filling in.
201
+ const showIndicator = hasSubmitted && (tabsWithErrors.has(index) || tabsWithRequiredEmpty.has(index));
202
+ return (_jsx("button", { type: "button", onClick: () => setActiveTab(index), disabled: disabled, className: cn('px-4 py-2 font-medium text-sm transition-colors whitespace-nowrap relative', 'border-b-2 -mb-px', 'focus:none', disabled && 'opacity-60 cursor-not-allowed', activeTab === index
203
+ ? 'border-accent text-accent '
204
+ : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200', showIndicator && activeTab !== index && 'text-red-600 dark:text-red-400'), "aria-selected": activeTab === index, role: "tab", children: _jsxs("span", { className: "inline-flex items-center gap-2", children: [tab.icon && _jsx(Icon, { name: tab.icon, className: "w-4 h-4" }), tab.label, showIndicator && (_jsx("span", { className: "ml-1 w-2 h-2 rounded-full bg-red-500 dark:bg-red-400", "aria-label": translate('core:a11y.tab_errors') }))] }) }, index));
205
+ }) }), tabs.map((tab, tabIndex) => (_jsx("div", { role: "tabpanel", "aria-labelledby": `tab-${tabIndex}`, className: activeTab === tabIndex ? '' : 'hidden', children: _jsx("div", { className: fieldLayoutClasses, children: tab.schema?.map((field, fieldIndex) => {
206
+ // Propagate disabled state and mode to nested fields
207
+ const nestedField = {
208
+ ...field,
209
+ disabled: disabled || field.disabled,
210
+ mode: mode || field.mode,
211
+ };
212
+ return (_jsx(FieldRenderer, { field: nestedField, mode: mode, apiBaseUrl: apiBaseUrl, resource: resource, operation: operation }, fieldIndex));
213
+ }) }) }, tabIndex)))] }));
214
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+ /**
4
+ * TagsInput field component
5
+ * Renders a tags input for managing arrays of simple values
6
+ */
7
+ export declare function TagsInputField(props: FieldProps): React.JSX.Element;
@@ -0,0 +1,172 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useState } from 'react';
3
+ import { useFormContext, Controller } from 'react-hook-form';
4
+ import { useValidation } from '../hooks/useValidation';
5
+ import { HintDisplay } from './utils/HintDisplay';
6
+ import { ViewFieldWrapper } from './utils/ViewFieldWrapper';
7
+ import { cn } from '../utils/classNames';
8
+ import { X, GripVertical, List } from 'lucide-react';
9
+ import { translate } from '../i18n/activeLocale';
10
+ /** View mode: trigger + popup when showInPopup is true */
11
+ function TagsViewPopup({ tags, renderHtml }) {
12
+ const [open, setOpen] = useState(false);
13
+ const count = tags.length;
14
+ const label = count === 1 ? '1 tag' : `${count} tags`;
15
+ return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => setOpen(true), className: cn('inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium', 'bg-accent-soft text-fg', 'hover:opacity-90 transition-opacity'), children: [_jsx(List, { className: "w-4 h-4 shrink-0" }), label] }), open && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-base opacity-80", "aria-hidden": true, onClick: () => setOpen(false) }), _jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": translate('core:tags.label'), className: cn('fixed left-1/2 top-1/2 z-50 w-[min(90vw,28rem)] max-h-[70vh] -translate-x-1/2 -translate-y-1/2', 'bg-surface rounded-xl shadow-xl border border-border', 'flex flex-col overflow-hidden'), children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-border shrink-0", children: [_jsx("span", { className: "text-sm font-medium text-fg", children: label }), _jsx("button", { type: "button", onClick: () => setOpen(false), className: "p-1 rounded-lg text-fg-secondary hover:bg-hover transition-colors", "aria-label": translate('core:modal.close'), children: _jsx(X, { className: "w-5 h-5" }) })] }), _jsx("div", { className: "p-4 overflow-y-auto flex flex-wrap gap-2", children: tags.map((tag, index) => (_jsx("span", { className: "inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-accent-soft text-fg", children: renderHtml ? (_jsx("span", { className: "kratosjshtml-content", dangerouslySetInnerHTML: { __html: String(tag) } })) : (String(tag)) }, index))) })] })] }))] }));
16
+ }
17
+ /**
18
+ * TagsInput field component
19
+ * Renders a tags input for managing arrays of simple values
20
+ */
21
+ export function TagsInputField(props) {
22
+ const { name, label, helperText, hint, hintIcon, hintColor, placeholder, disabled = false, mode, value, separator = ',', suggestions = [], minItems, maxItems, addable = true, deletable = true, reorderable = true, showInPopup = false, } = props;
23
+ // Determine if field should be treated as required (for minItems fallback)
24
+ let isRequired = props.required === true;
25
+ const validationRules = props.validation?.rules;
26
+ if (validationRules && Array.isArray(validationRules)) {
27
+ if (validationRules.some(rule => rule === 'required' || (typeof rule === 'object' && rule.rule === 'required'))) {
28
+ isRequired = true;
29
+ }
30
+ }
31
+ // Effective minItems: honor explicit minItems, otherwise infer from required
32
+ const effectiveMinItems = minItems !== undefined ? minItems : isRequired ? 1 : undefined;
33
+ const [inputValue, setInputValue] = useState('');
34
+ const [showSuggestions, setShowSuggestions] = useState(false);
35
+ const [draggedIndex, setDraggedIndex] = useState(null);
36
+ const [dragOverIndex, setDragOverIndex] = useState(null);
37
+ // View mode: render as comma-separated list or badges (or popup when showInPopup)
38
+ if (mode === 'view') {
39
+ const tags = Array.isArray(value) ? value : [];
40
+ if (tags.length === 0) {
41
+ return _jsx(ViewFieldWrapper, { label: label, children: "-" });
42
+ }
43
+ const renderHtml = props.renderHtml === true;
44
+ if (showInPopup) {
45
+ return (_jsx(ViewFieldWrapper, { label: label, children: _jsx(TagsViewPopup, { tags: tags, renderHtml: renderHtml }) }));
46
+ }
47
+ return (_jsx(ViewFieldWrapper, { label: label, children: _jsx("div", { className: "flex flex-wrap gap-2", children: tags.map((tag, index) => (_jsx("span", { className: "inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-accent-soft text-accent", children: renderHtml ? (_jsx("span", { className: "kratosjshtml-content", dangerouslySetInnerHTML: { __html: String(tag) } })) : (String(tag)) }, index))) }) }));
48
+ }
49
+ const { control } = useFormContext();
50
+ const validation = useValidation(props.validation?.rules || [], props.operation, props.name);
51
+ // Additional validation for minItems/maxItems
52
+ const tagsValidation = React.useMemo(() => {
53
+ const rules = { ...validation };
54
+ if (effectiveMinItems && effectiveMinItems > 0) {
55
+ rules.validate = {
56
+ ...(rules.validate || {}),
57
+ minItems: (value) => {
58
+ const length = Array.isArray(value) ? value.length : 0;
59
+ return length >= effectiveMinItems || `At least ${effectiveMinItems} item(s) are required`;
60
+ },
61
+ };
62
+ }
63
+ if (maxItems && maxItems > 0) {
64
+ rules.validate = {
65
+ ...(rules.validate || {}),
66
+ maxItems: (value) => {
67
+ const length = Array.isArray(value) ? value.length : 0;
68
+ return length <= maxItems || `Maximum ${maxItems} item(s) allowed`;
69
+ },
70
+ };
71
+ }
72
+ return rules;
73
+ }, [validation, effectiveMinItems, maxItems]);
74
+ return (_jsx(Controller, { name: name, control: control, rules: tagsValidation, render: ({ field: { value: fieldValue, onChange }, fieldState: { error } }) => {
75
+ const tags = Array.isArray(fieldValue) ? fieldValue : [];
76
+ const hasError = !!error;
77
+ const addTag = (tag) => {
78
+ const trimmedTag = tag.trim();
79
+ if (!trimmedTag)
80
+ return;
81
+ if (tags.includes(trimmedTag))
82
+ return;
83
+ if (maxItems && tags.length >= maxItems)
84
+ return;
85
+ onChange([...tags, trimmedTag]);
86
+ setInputValue('');
87
+ };
88
+ const removeTag = (index) => {
89
+ if (!deletable || disabled)
90
+ return;
91
+ if (effectiveMinItems && tags.length <= effectiveMinItems)
92
+ return;
93
+ const newTags = tags.filter((_, i) => i !== index);
94
+ onChange(newTags);
95
+ };
96
+ const handleDragStart = (e, index) => {
97
+ if (!reorderable || disabled)
98
+ return;
99
+ setDraggedIndex(index);
100
+ e.dataTransfer.effectAllowed = 'move';
101
+ };
102
+ const handleDragOver = (e, index) => {
103
+ if (!reorderable || disabled || draggedIndex === null)
104
+ return;
105
+ e.preventDefault();
106
+ e.dataTransfer.dropEffect = 'move';
107
+ setDragOverIndex(index);
108
+ };
109
+ const handleDragLeave = () => {
110
+ setDragOverIndex(null);
111
+ };
112
+ const handleDrop = (e, dropIndex) => {
113
+ if (!reorderable || disabled || draggedIndex === null)
114
+ return;
115
+ e.preventDefault();
116
+ if (draggedIndex === dropIndex) {
117
+ setDraggedIndex(null);
118
+ setDragOverIndex(null);
119
+ return;
120
+ }
121
+ const newTags = [...tags];
122
+ const [movedTag] = newTags.splice(draggedIndex, 1);
123
+ newTags.splice(dropIndex, 0, movedTag);
124
+ onChange(newTags);
125
+ setDraggedIndex(null);
126
+ setDragOverIndex(null);
127
+ };
128
+ const handleDragEnd = () => {
129
+ setDraggedIndex(null);
130
+ setDragOverIndex(null);
131
+ };
132
+ const handleKeyDown = (e) => {
133
+ if (e.key === 'Enter' || e.key === separator) {
134
+ e.preventDefault();
135
+ addTag(inputValue);
136
+ }
137
+ else if (e.key === 'Backspace' && !inputValue && tags.length > 0) {
138
+ // Remove last tag when backspace on empty input
139
+ removeTag(tags.length - 1);
140
+ }
141
+ };
142
+ const handleBlur = () => {
143
+ // Add remaining input as tag on blur
144
+ if (inputValue.trim()) {
145
+ addTag(inputValue);
146
+ }
147
+ setShowSuggestions(false);
148
+ };
149
+ const filteredSuggestions = suggestions.filter(s => s.toLowerCase().includes(inputValue.toLowerCase()) && !tags.includes(s));
150
+ const canAdd = addable && !disabled && (maxItems === undefined || tags.length < maxItems);
151
+ return (_jsxs("div", { className: "mb-4", children: [label && (_jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: [label, validation.required && _jsx("span", { className: "text-red-500 dark:text-red-400 ml-1", children: "*" })] })), _jsxs("div", { className: cn('w-full min-h-[42px] px-3 py-2 border rounded-lg shadow-sm', 'k-input', 'focus-within:outline-none focus-within:ring-2 focus-within:ring-ring ', 'transition duration-150 ease-in-out', hasError &&
152
+ 'border-red-500 dark:border-red-400 focus-within:ring-red-500 dark:focus-within:ring-red-400', disabled && 'opacity-60 cursor-not-allowed'), children: [_jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [tags.map((tag, index) => (_jsxs("span", { draggable: reorderable && !disabled, onDragStart: e => handleDragStart(e, index), onDragOver: e => handleDragOver(e, index), onDragLeave: handleDragLeave, onDrop: e => handleDrop(e, index), onDragEnd: handleDragEnd, className: cn('inline-flex items-center gap-1 px-2 py-1 rounded-md text-sm font-medium bg-accent-soft text-accent', 'transition-all duration-150', reorderable && !disabled && 'cursor-move hover:bg-accent/20', draggedIndex === index && 'opacity-50', dragOverIndex === index &&
153
+ draggedIndex !== index &&
154
+ 'scale-105 ring-2 ring-ring'), children: [reorderable && !disabled && _jsx(GripVertical, { className: "w-3 h-3 opacity-40" }), String(tag), deletable &&
155
+ !disabled &&
156
+ (!effectiveMinItems || tags.length > effectiveMinItems) && (_jsx("button", { type: "button", onClick: () => removeTag(index), className: "ml-1 hover:bg-accent/20 rounded-full p-0.5 transition-colors", "aria-label": `Remove ${tag}`, children: _jsx(X, { className: "w-3 h-3" }) }))] }, index))), canAdd && (_jsx("input", { type: "text", value: inputValue, onChange: e => {
157
+ setInputValue(e.target.value);
158
+ if (suggestions.length > 0) {
159
+ setShowSuggestions(true);
160
+ }
161
+ }, onKeyDown: handleKeyDown, onBlur: handleBlur, onFocus: () => {
162
+ if (suggestions.length > 0) {
163
+ setShowSuggestions(true);
164
+ }
165
+ }, placeholder: tags.length === 0
166
+ ? placeholder || `Enter values separated by ${separator}`
167
+ : '', disabled: disabled, className: "flex-1 min-w-[120px] outline-none bg-transparent" }))] }), showSuggestions && filteredSuggestions.length > 0 && (_jsx("div", { className: "relative", children: _jsx("div", { className: "absolute z-10 mt-2 w-full bg-white dark:bg-gray-800 border border-border rounded-lg shadow-lg max-h-48 overflow-y-auto", children: filteredSuggestions.map((suggestion, index) => (_jsx("button", { type: "button", onMouseDown: e => e.preventDefault(), onClick: () => {
168
+ addTag(suggestion);
169
+ setShowSuggestions(false);
170
+ }, className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm transition-colors", children: suggestion }, index))) }) }))] }), hasError && (_jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error?.message })), helperText && _jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }), !hasError && _jsx(HintDisplay, { hint: hint, hintIcon: hintIcon, hintColor: hintColor }), (effectiveMinItems !== undefined || maxItems !== undefined) && (_jsxs("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: [effectiveMinItems !== undefined && `Minimum: ${effectiveMinItems}`, effectiveMinItems !== undefined && maxItems !== undefined && ' • ', maxItems !== undefined && `Maximum: ${maxItems}`] }))] }));
171
+ } }));
172
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+ /**
4
+ * TextInput field component
5
+ * Renders text, email, password, number, tel, and url inputs
6
+ */
7
+ export declare function TextInputField(props: FieldProps): React.JSX.Element;
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useFormContext } from 'react-hook-form';
3
+ import { getFieldError } from '../utils/fieldErrors';
4
+ import { useValidation } from '../hooks/useValidation';
5
+ import { cn } from '../utils/classNames';
6
+ import { HintDisplay } from './utils/HintDisplay';
7
+ import { ViewFieldWrapper } from './utils/ViewFieldWrapper';
8
+ import { formatNumber } from '../utils/formatValue';
9
+ /**
10
+ * TextInput field component
11
+ * Renders text, email, password, number, tel, and url inputs
12
+ */
13
+ export function TextInputField(props) {
14
+ // View mode: render formatted display
15
+ if (props.mode === 'view') {
16
+ const value = props.value;
17
+ let displayValue = value;
18
+ // Format numbers if inputType is numeric
19
+ if (props.inputType === 'number' && value !== null && value !== undefined) {
20
+ displayValue = formatNumber(value);
21
+ }
22
+ else if (value === null || value === undefined) {
23
+ displayValue = '-';
24
+ }
25
+ else if (props.renderHtml && (typeof value === 'string' || typeof value === 'number')) {
26
+ displayValue = _jsx("div", { className: "kratosjshtml-content", dangerouslySetInnerHTML: { __html: String(value) } });
27
+ }
28
+ else {
29
+ // If is object, convert it into a ul list
30
+ if (typeof value === 'object') {
31
+ displayValue = (_jsx("div", { className: "space-y-2", children: Object.entries(value).map(([key, value]) => (_jsxs("div", { children: [_jsx("b", { children: key }), " : ", typeof value === 'object' ? JSON.stringify(value) : String(value)] }, key))) }));
32
+ }
33
+ else {
34
+ displayValue = String(value);
35
+ }
36
+ }
37
+ return _jsx(ViewFieldWrapper, { label: props.label, children: displayValue });
38
+ }
39
+ const { register, formState: { errors }, } = useFormContext();
40
+ const validation = useValidation(props.validation?.rules || [], props.operation, props.name);
41
+ const error = getFieldError(errors, props.name);
42
+ const hasError = !!error;
43
+ return (_jsxs("div", { className: "mb-4", children: [props.label && (_jsxs("label", { htmlFor: props.name, className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: [props.label, validation.required && _jsx("span", { className: "text-red-500 dark:text-red-400 ml-1", children: "*" })] })), _jsx("input", { id: props.name, type: props.inputType || 'text', ...register(props.name, validation), placeholder: props.placeholder, disabled: props.disabled, readOnly: props.readOnly, className: cn('w-full px-3 py-2 border rounded-lg shadow-sm', 'k-input', 'focus:outline-none focus:ring-2 focus:ring-ring', 'transition duration-150 ease-in-out', hasError && 'border-red-500 dark:border-red-400 focus:ring-red-500 dark:focus:ring-red-400', props.disabled && 'opacity-60 cursor-not-allowed', props.readOnly && 'bg-muted') }), hasError && _jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error?.message }), props.helperText && _jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: props.helperText }), !hasError && _jsx(HintDisplay, { hint: props.hint, hintIcon: props.hintIcon, hintColor: props.hintColor })] }));
44
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+ /**
4
+ * Textarea field component
5
+ * Renders multi-line text input with character count
6
+ */
7
+ export declare function TextareaField(props: FieldProps): React.JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useFormContext, useWatch } from 'react-hook-form';
3
+ import { getFieldError } from '../utils/fieldErrors';
4
+ import { useValidation } from '../hooks/useValidation';
5
+ import { cn } from '../utils/classNames';
6
+ import { HintDisplay } from './utils/HintDisplay';
7
+ import { ViewFieldWrapper } from './utils/ViewFieldWrapper';
8
+ import { formatTextarea } from '../utils/formatValue';
9
+ /**
10
+ * Textarea field component
11
+ * Renders multi-line text input with character count
12
+ */
13
+ export function TextareaField(props) {
14
+ // View mode: render formatted display
15
+ if (props.mode === 'view') {
16
+ const value = props.value;
17
+ const displayValue = props.renderHtml && value != null && (typeof value === 'string' || typeof value === 'number') ? (_jsx("div", { className: "kratosjshtml-content", dangerouslySetInnerHTML: { __html: String(value) } })) : (formatTextarea(value));
18
+ return _jsx(ViewFieldWrapper, { label: props.label, children: displayValue });
19
+ }
20
+ const { register, control, formState: { errors }, } = useFormContext();
21
+ const validation = useValidation(props.validation?.rules || [], props.operation, props.name);
22
+ const error = getFieldError(errors, props.name);
23
+ const hasError = !!error;
24
+ // Watch the field value for character count
25
+ const value = useWatch({ control, name: props.name, defaultValue: '' });
26
+ const currentLength = value?.length || 0;
27
+ const maxLength = props.maxLength;
28
+ return (_jsxs("div", { className: "mb-4", children: [props.label && (_jsxs("label", { htmlFor: props.name, className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: [props.label, validation.required && _jsx("span", { className: "text-red-500 dark:text-red-400 ml-1", children: "*" })] })), _jsx("textarea", { id: props.name, ...register(props.name, validation), placeholder: props.placeholder, disabled: props.disabled, readOnly: props.readOnly, rows: props.rows || 4, cols: props.cols, className: cn('w-full px-3 py-2 border rounded-lg shadow-sm', 'k-input', 'focus:outline-none focus:ring-2 focus:ring-ring', 'transition duration-150 ease-in-out', 'resize-y', hasError && 'border-red-500 dark:border-red-400 focus:ring-red-500 dark:focus:ring-red-400', props.disabled && 'opacity-60 cursor-not-allowed', props.readOnly && 'bg-muted') }), maxLength && (_jsxs("div", { className: "mt-1 flex justify-between items-center", children: [_jsxs("div", { className: "flex-1", children: [hasError && (_jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error?.message })), props.helperText && !hasError && (_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: props.helperText })), !hasError && (_jsx(HintDisplay, { hint: props.hint, hintIcon: props.hintIcon, hintColor: props.hintColor }))] }), _jsxs("p", { className: cn('text-xs ml-2', currentLength > maxLength
29
+ ? 'text-red-600 dark:text-red-400 font-medium'
30
+ : 'text-gray-500 dark:text-gray-400'), children: [currentLength, " / ", maxLength] })] })), !maxLength && hasError && (_jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error?.message })), !maxLength && props.helperText && (_jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: props.helperText })), !maxLength && !hasError && (_jsx(HintDisplay, { hint: props.hint, hintIcon: props.hintIcon, hintColor: props.hintColor }))] }));
31
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { FieldProps } from '../types';
3
+ /**
4
+ * Toggle field component
5
+ * Renders a toggle switch with custom colors
6
+ */
7
+ export declare function ToggleField(props: FieldProps): React.JSX.Element;
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useFormContext, useWatch } from 'react-hook-form';
3
+ import { getFieldError } from '../utils/fieldErrors';
4
+ import { useValidation } from '../hooks/useValidation';
5
+ import { cn } from '../utils/classNames';
6
+ import { Icon } from './utils/Icon';
7
+ import { HintDisplay } from './utils/HintDisplay';
8
+ import { ViewFieldWrapper } from './utils/ViewFieldWrapper';
9
+ import { formatBoolean } from '../utils/formatValue';
10
+ /**
11
+ * Toggle field component
12
+ * Renders a toggle switch with custom colors
13
+ */
14
+ export function ToggleField(props) {
15
+ // View mode: render formatted display
16
+ if (props.mode === 'view') {
17
+ const value = props.value;
18
+ const displayValue = formatBoolean(value);
19
+ const isChecked = Boolean(value);
20
+ const onColor = 'text-green-600';
21
+ const offColor = 'text-red-600';
22
+ return (_jsx(ViewFieldWrapper, { label: props.label, children: _jsx("div", { className: "flex items-center gap-3", children: _jsx("span", { className: cn(isChecked ? onColor : offColor), children: displayValue }) }) }));
23
+ }
24
+ const { register, control, formState: { errors }, } = useFormContext();
25
+ const validation = useValidation(props.validation?.rules || [], props.operation, props.name);
26
+ const error = getFieldError(errors, props.name);
27
+ const hasError = !!error;
28
+ // Watch the toggle state
29
+ const isChecked = useWatch({ control, name: props.name, defaultValue: props.default || false });
30
+ // Map color names to Tailwind classes
31
+ const getColorClass = (color) => {
32
+ const colorMap = {
33
+ success: 'bg-green-600 dark:bg-green-500',
34
+ danger: 'bg-red-600 dark:bg-red-500',
35
+ warning: 'bg-yellow-600 dark:bg-yellow-500',
36
+ info: 'bg-accent',
37
+ primary: 'bg-accent',
38
+ };
39
+ return colorMap[color || ''] || 'bg-accent';
40
+ };
41
+ // Map semantic color names to Tailwind classes; pass through full class strings as-is
42
+ const resolveTrackColor = (color, fallback) => {
43
+ if (!color)
44
+ return fallback.split(/\s+/);
45
+ if (/\b(bg|text)-/.test(color))
46
+ return color.split(/\s+/);
47
+ return getColorClass(color).split(/\s+/);
48
+ };
49
+ const onColor = resolveTrackColor(props.onColor, 'bg-accent');
50
+ const offColor = resolveTrackColor(props.offColor, 'bg-gray-200 dark:bg-gray-700');
51
+ return (_jsxs("div", { className: "mb-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "flex-1", children: props.label && (_jsxs("label", { htmlFor: props.name, className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: [props.label, validation.required && _jsx("span", { className: "text-red-500 dark:text-red-400 ml-1", children: "*" })] })) }), _jsx("button", { type: "button", role: "switch", "aria-checked": isChecked, disabled: props.disabled, onClick: () => {
52
+ const checkbox = document.getElementById(props.name);
53
+ if (checkbox) {
54
+ checkbox.click();
55
+ }
56
+ }, className: cn('relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent', 'transition-colors duration-200 ease-in-out', 'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 dark:focus:ring-offset-gray-900', ...(isChecked ? onColor : offColor), props.disabled && 'opacity-60 cursor-not-allowed'), children: _jsxs("span", { className: cn('pointer-events-none inline-flex items-center justify-center h-5 w-5 transform rounded-full bg-white dark:bg-gray-200 shadow ring-0', 'transition duration-200 ease-in-out', isChecked ? 'translate-x-5' : 'translate-x-0'), children: [props.onIcon && isChecked && _jsx(Icon, { name: props.onIcon, size: 12, className: "text-green-600" }), props.offIcon && !isChecked && (_jsx(Icon, { name: props.offIcon, size: 12, className: "text-gray-400" }))] }) }), _jsx("input", { id: props.name, type: "checkbox", ...register(props.name, validation), className: "sr-only" })] }), hasError && _jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error?.message }), props.helperText && _jsx("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: props.helperText }), !hasError && _jsx(HintDisplay, { hint: props.hint, hintIcon: props.hintIcon, hintColor: props.hintColor })] }));
57
+ }
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { SerializedForm } from '@maxal_studio/kratosjs';
3
+ import { SerializedRelation } from '../types';
4
+ export type { SerializedRelation };
5
+ interface ViewModalProps {
6
+ /** Whether the modal is open */
7
+ isOpen: boolean;
8
+ /** Function to close the modal */
9
+ onClose: () => void;
10
+ /** Resource slug (e.g., 'users', 'posts') */
11
+ resourceSlug: string;
12
+ /** Display name for the resource */
13
+ resourceName: string;
14
+ /** ID of the record to view */
15
+ recordId: string;
16
+ /** API base URL */
17
+ apiBaseUrl?: string;
18
+ /** Form schema for displaying fields */
19
+ formSchema: SerializedForm;
20
+ /** Stacking depth */
21
+ depth?: number;
22
+ /** Close all modals */
23
+ onCloseAll?: () => void;
24
+ }
25
+ export declare function ViewModal({ isOpen, onClose, resourceSlug, resourceName, recordId, apiBaseUrl, formSchema, depth, onCloseAll, }: ViewModalProps): React.JSX.Element;