@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,65 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatDate, formatNumber, formatBoolean, formatSelectLabel } from './formatValue';
3
+
4
+ describe('formatDate', () => {
5
+ it('returns "-" for empty values', () => {
6
+ expect(formatDate(null)).toBe('-');
7
+ expect(formatDate('')).toBe('-');
8
+ });
9
+
10
+ it('returns the raw value for invalid dates', () => {
11
+ expect(formatDate('not-a-date')).toBe('not-a-date');
12
+ });
13
+
14
+ it('applies YYYY-MM-DD style format tokens', () => {
15
+ expect(formatDate('2026-01-15T10:30:45', 'YYYY-MM-DD')).toBe('2026-01-15');
16
+ expect(formatDate('2026-01-15T10:30:45', 'DD/MM/YYYY HH:mm')).toBe('15/01/2026 10:30');
17
+ });
18
+ });
19
+
20
+ describe('formatNumber', () => {
21
+ it('returns "-" for null/undefined', () => {
22
+ expect(formatNumber(null)).toBe('-');
23
+ expect(formatNumber(undefined)).toBe('-');
24
+ });
25
+
26
+ it('returns the raw value as string for non-numbers', () => {
27
+ expect(formatNumber('abc')).toBe('abc');
28
+ });
29
+
30
+ it('formats currency', () => {
31
+ expect(formatNumber(1234.5, { currency: 'USD' })).toBe('$1,234.50');
32
+ });
33
+
34
+ it('applies fixed decimals', () => {
35
+ expect(formatNumber(3.14159, { decimals: 2 })).toBe('3.14');
36
+ });
37
+
38
+ it('falls back to locale formatting', () => {
39
+ expect(formatNumber(1000000)).toBe((1000000).toLocaleString());
40
+ });
41
+ });
42
+
43
+ describe('formatBoolean', () => {
44
+ it('maps booleans to Yes/No and empty to "-"', () => {
45
+ expect(formatBoolean(true)).toBe('Yes');
46
+ expect(formatBoolean(false)).toBe('No');
47
+ expect(formatBoolean(null)).toBe('-');
48
+ });
49
+ });
50
+
51
+ describe('formatSelectLabel', () => {
52
+ it('returns "-" for empty values', () => {
53
+ expect(formatSelectLabel(null)).toBe('-');
54
+ });
55
+
56
+ it('maps a single value through options', () => {
57
+ expect(formatSelectLabel('a', { a: 'Alpha' })).toBe('Alpha');
58
+ expect(formatSelectLabel('missing', { a: 'Alpha' })).toBe('missing');
59
+ });
60
+
61
+ it('joins multiple values with labels', () => {
62
+ expect(formatSelectLabel(['a', 'b'], { a: 'Alpha', b: 'Beta' }, true)).toBe('Alpha, Beta');
63
+ expect(formatSelectLabel([], { a: 'Alpha' }, true)).toBe('-');
64
+ });
65
+ });
@@ -0,0 +1,117 @@
1
+ import React from 'react';
2
+ import { getActiveLocale, translate } from '../i18n/activeLocale';
3
+
4
+ /**
5
+ * Utility functions for formatting field values in view mode
6
+ */
7
+
8
+ /**
9
+ * Format a date value according to the specified format
10
+ */
11
+ export function formatDate(value: any, format?: string): string {
12
+ if (!value) return '-';
13
+
14
+ try {
15
+ const date = new Date(value);
16
+ if (isNaN(date.getTime())) return String(value);
17
+
18
+ if (format) {
19
+ // Simple format support - can be extended
20
+ const year = date.getFullYear();
21
+ const month = String(date.getMonth() + 1).padStart(2, '0');
22
+ const day = String(date.getDate()).padStart(2, '0');
23
+ const hours = String(date.getHours()).padStart(2, '0');
24
+ const minutes = String(date.getMinutes()).padStart(2, '0');
25
+ const seconds = String(date.getSeconds()).padStart(2, '0');
26
+
27
+ return format
28
+ .replace('YYYY', String(year))
29
+ .replace('MM', month)
30
+ .replace('DD', day)
31
+ .replace('HH', hours)
32
+ .replace('mm', minutes)
33
+ .replace('ss', seconds);
34
+ }
35
+
36
+ return date.toLocaleString(getActiveLocale());
37
+ } catch {
38
+ return String(value);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Format a number value with optional options
44
+ */
45
+ export function formatNumber(value: any, options?: { decimals?: number; currency?: string }): string {
46
+ if (value === null || value === undefined) return '-';
47
+
48
+ const num = Number(value);
49
+ if (isNaN(num)) return String(value);
50
+
51
+ if (options?.currency) {
52
+ return new Intl.NumberFormat(getActiveLocale(), {
53
+ style: 'currency',
54
+ currency: options.currency,
55
+ minimumFractionDigits: options.decimals ?? 2,
56
+ maximumFractionDigits: options.decimals ?? 2,
57
+ }).format(num);
58
+ }
59
+
60
+ if (options?.decimals !== undefined) {
61
+ return num.toFixed(options.decimals);
62
+ }
63
+
64
+ return num.toLocaleString(getActiveLocale());
65
+ }
66
+
67
+ /**
68
+ * Format a boolean value
69
+ */
70
+ export function formatBoolean(value: any): string {
71
+ if (value === null || value === undefined) return '-';
72
+ return value ? translate('core:common.yes') : translate('core:common.no');
73
+ }
74
+
75
+ /**
76
+ * Format a select value to display option labels
77
+ */
78
+ export function formatSelectLabel(value: any, options?: Record<string | number, string>, isMultiple?: boolean): string {
79
+ if (!value) return '-';
80
+
81
+ if (isMultiple && Array.isArray(value)) {
82
+ if (value.length === 0) return '-';
83
+ if (!options) return value.join(', ');
84
+ return value
85
+ .map(v => {
86
+ const key = String(v);
87
+ return options[key] || key;
88
+ })
89
+ .join(', ');
90
+ }
91
+
92
+ if (!options) return String(value);
93
+ const key = String(value);
94
+ return options[key] || key;
95
+ }
96
+
97
+ /**
98
+ * Format a textarea value preserving line breaks
99
+ * Returns an array of React elements for rendering
100
+ */
101
+ export function formatTextarea(value: any): React.ReactNode {
102
+ if (value === null || value === undefined) return '-';
103
+ // If is js object, return json string
104
+ let text = value;
105
+ if (typeof value === 'object') {
106
+ text = JSON.stringify(value, null, 2);
107
+ } else {
108
+ text = String(value);
109
+ }
110
+ const lines = text.split('\n');
111
+ return lines.map((line, i) => (
112
+ <React.Fragment key={i}>
113
+ {line}
114
+ {i < lines.length - 1 && <br />}
115
+ </React.Fragment>
116
+ ));
117
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Layout storage utilities for managing table/grid layout preferences in localStorage
3
+ */
4
+ export const layoutStorage = {
5
+ /**
6
+ * Get layout preference for a resource
7
+ * @param resourceKey Unique identifier for the resource (e.g., 'users', 'posts')
8
+ * @param defaultLayout Default layout to return if no preference is stored
9
+ * @returns 'table' or 'grid'
10
+ */
11
+ getLayout(resourceKey: string, defaultLayout: 'table' | 'grid' = 'table'): 'table' | 'grid' {
12
+ try {
13
+ const key = `kratosjs_layout_${resourceKey}`;
14
+ const stored = localStorage.getItem(key);
15
+ if (stored === 'table' || stored === 'grid') {
16
+ return stored;
17
+ }
18
+ return defaultLayout;
19
+ } catch (error) {
20
+ console.warn('Failed to read layout preference from localStorage:', error);
21
+ return defaultLayout;
22
+ }
23
+ },
24
+
25
+ /**
26
+ * Set layout preference for a resource
27
+ * @param resourceKey Unique identifier for the resource
28
+ * @param layout Layout mode - 'table' or 'grid'
29
+ */
30
+ setLayout(resourceKey: string, layout: 'table' | 'grid'): void {
31
+ try {
32
+ const key = `kratosjs_layout_${resourceKey}`;
33
+ localStorage.setItem(key, layout);
34
+ } catch (error) {
35
+ // Handle quota exceeded or other localStorage errors
36
+ if (error instanceof Error && error.name === 'QuotaExceededError') {
37
+ console.warn('localStorage quota exceeded, layout preference not saved');
38
+ } else {
39
+ console.warn('Failed to save layout preference to localStorage:', error);
40
+ }
41
+ }
42
+ },
43
+
44
+ /**
45
+ * Clear stored layout preference for a resource
46
+ * @param resourceKey Unique identifier for the resource
47
+ */
48
+ clearLayout(resourceKey: string): void {
49
+ const key = `kratosjs_layout_${resourceKey}`;
50
+ localStorage.removeItem(key);
51
+ },
52
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Handle redirect from API response
3
+ * @param responseData - Response data from API
4
+ * @param navigate - React Router navigate function
5
+ * @returns true if redirect was handled, false otherwise
6
+ */
7
+ export function handleRedirect(responseData: any, navigate: (path: string) => void): boolean {
8
+ if (responseData?.redirect) {
9
+ const redirectPath = responseData.redirect;
10
+
11
+ // Handle relative paths (client-side navigation)
12
+ if (redirectPath.startsWith('/')) {
13
+ navigate(redirectPath);
14
+ return true;
15
+ }
16
+
17
+ // Handle absolute URLs (external redirects)
18
+ if (redirectPath.startsWith('http://') || redirectPath.startsWith('https://')) {
19
+ window.location.href = redirectPath;
20
+ return true;
21
+ }
22
+
23
+ // Invalid redirect path
24
+ console.warn('Invalid redirect path:', redirectPath);
25
+ return false;
26
+ }
27
+
28
+ return false;
29
+ }
@@ -0,0 +1,54 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatValue, stripHtml } from './tableFormatters';
3
+
4
+ const column = (overrides: Record<string, unknown> = {}) => overrides as any;
5
+
6
+ describe('formatValue', () => {
7
+ it('returns null for null/undefined values', () => {
8
+ expect(formatValue(null, column())).toBeNull();
9
+ expect(formatValue(undefined, column())).toBeNull();
10
+ });
11
+
12
+ it('formats dates with dateFormat', () => {
13
+ const value = '2026-01-15T10:30:00';
14
+ expect(formatValue(value, column({ dateFormat: 'date' }))).toBe(new Date(value).toLocaleDateString());
15
+ expect(formatValue(value, column({ dateFormat: 'dateTime' }))).toBe(new Date(value).toLocaleString());
16
+ });
17
+
18
+ it('returns the raw value for invalid dates', () => {
19
+ expect(formatValue('nope', column({ dateFormat: 'date' }))).toBe('nope');
20
+ });
21
+
22
+ it('formats relative time for past dates', () => {
23
+ const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
24
+ expect(formatValue(twoHoursAgo, column({ dateFormat: 'since' }))).toBe('2 hours ago');
25
+ });
26
+
27
+ it('formats money', () => {
28
+ expect(formatValue(12.5, column({ moneyFormat: 'USD' }))).toBe('$12.50');
29
+ expect(formatValue('12.5', column({ moneyFormat: 'EUR' }))).toBe('€12.50');
30
+ expect(formatValue('abc', column({ moneyFormat: 'USD' }))).toBe('abc');
31
+ });
32
+
33
+ it('strips HTML by default', () => {
34
+ expect(formatValue('<b>bold</b> text', column())).toBe('bold text');
35
+ });
36
+
37
+ it('keeps HTML when stripHtml is false', () => {
38
+ expect(formatValue('<b>bold</b>', column({ stripHtml: false }))).toBe('<b>bold</b>');
39
+ });
40
+
41
+ it('strips HTML from array items', () => {
42
+ expect(formatValue(['<i>a</i>', 2], column())).toEqual(['a', 2]);
43
+ });
44
+ });
45
+
46
+ describe('stripHtml', () => {
47
+ it('removes tags and keeps text', () => {
48
+ expect(stripHtml('<div><p>hello</p> <span>world</span></div>')).toBe('hello world');
49
+ });
50
+
51
+ it('passes through non-strings', () => {
52
+ expect(stripHtml(42 as unknown as string)).toBe(42);
53
+ });
54
+ });
@@ -0,0 +1,104 @@
1
+ import { SerializedColumn } from '@maxal_studio/kratosjs';
2
+ import { executeSerializedFunction } from '../runtime/serializedFunctions';
3
+ import { getActiveLocale } from '../i18n/activeLocale';
4
+
5
+ /**
6
+ * Format a value based on column configuration
7
+ * @param value - The cell value
8
+ * @param column - The column configuration
9
+ * @param row - The entire row data (optional, used by formatStateUsing function)
10
+ */
11
+ export function formatValue(value: any, column: SerializedColumn, row?: Record<string, any>): any {
12
+ // Only apply placeholder for null/undefined when there's no formatter
13
+ if (value === null || value === undefined) {
14
+ return null;
15
+ }
16
+
17
+ // Date formatting
18
+ if (column.dateFormat) {
19
+ const date = new Date(value);
20
+ if (isNaN(date.getTime())) return value;
21
+
22
+ const locale = getActiveLocale();
23
+ switch (column.dateFormat) {
24
+ case 'date':
25
+ return date.toLocaleDateString(locale);
26
+ case 'dateTime':
27
+ return date.toLocaleString(locale);
28
+ case 'time':
29
+ return date.toLocaleTimeString(locale);
30
+ case 'since':
31
+ case 'until':
32
+ return getRelativeTime(date);
33
+ default:
34
+ return date.toLocaleDateString(locale);
35
+ }
36
+ }
37
+
38
+ // Money formatting
39
+ if (column.moneyFormat) {
40
+ const numValue = typeof value === 'number' ? value : parseFloat(value);
41
+ if (isNaN(numValue)) return value;
42
+
43
+ return new Intl.NumberFormat(getActiveLocale(), {
44
+ style: 'currency',
45
+ currency: column.moneyFormat || 'USD',
46
+ }).format(numValue);
47
+ }
48
+
49
+ // Strip HTML by default; only skip when stripHtml is explicitly false.
50
+ // column.stripHtml is true (default), false (explicit), or undefined (treated as true).
51
+ const shouldStripHtml = column.stripHtml !== false;
52
+
53
+ if (shouldStripHtml) {
54
+ if (typeof value === 'string') {
55
+ return stripHtml(value);
56
+ }
57
+ // Handle arrays - strip HTML from each string item
58
+ if (Array.isArray(value)) {
59
+ return value.map(item => (typeof item === 'string' ? stripHtml(item) : item));
60
+ }
61
+ }
62
+
63
+ return value;
64
+ }
65
+
66
+ /**
67
+ * Strip HTML tags from a string
68
+ * @param html - The HTML string to strip
69
+ * @returns Plain text with HTML tags removed
70
+ */
71
+ export function stripHtml(html: string): string {
72
+ if (typeof html !== 'string') {
73
+ return html;
74
+ }
75
+
76
+ // Create a temporary DOM element to parse HTML
77
+ const tmp = document.createElement('div');
78
+ tmp.innerHTML = html;
79
+ return tmp.textContent || tmp.innerText || '';
80
+ }
81
+
82
+ /**
83
+ * Locale-aware relative time (e.g. "2 hours ago", "in 3 days"), using the active
84
+ * locale via `Intl.RelativeTimeFormat`. The true signed delta (date − now) drives
85
+ * direction, so past dates read "ago" and future dates read "in …".
86
+ */
87
+ function getRelativeTime(date: Date): string {
88
+ const deltaSec = Math.round((date.getTime() - Date.now()) / 1000);
89
+ const abs = Math.abs(deltaSec);
90
+ const rtf = new Intl.RelativeTimeFormat(getActiveLocale(), { numeric: 'auto' });
91
+
92
+ const units: [Intl.RelativeTimeFormatUnit, number][] = [
93
+ ['year', 31536000],
94
+ ['month', 2592000],
95
+ ['week', 604800],
96
+ ['day', 86400],
97
+ ['hour', 3600],
98
+ ['minute', 60],
99
+ ];
100
+ for (const [unit, secs] of units) {
101
+ if (abs >= secs) return rtf.format(Math.round(deltaSec / secs), unit);
102
+ }
103
+ return rtf.format(0, 'second');
104
+ }
@@ -0,0 +1,38 @@
1
+ const WIDGET_VISIBILITY_KEY = 'kratosjs_widgets_expanded';
2
+
3
+ /** Default when no preference stored: desktop expanded, mobile collapsed */
4
+ export function getDefaultWidgetsExpanded(): boolean {
5
+ if (typeof window === 'undefined') return true;
6
+ return window.matchMedia('(min-width: 768px)').matches;
7
+ }
8
+
9
+ /**
10
+ * Storage for widgets expanded/collapsed state.
11
+ * When no value is stored, mobile should be collapsed and desktop expanded (handled in component via media query).
12
+ */
13
+ export const widgetVisibilityStorage = {
14
+ get(): boolean | null {
15
+ try {
16
+ const stored = localStorage.getItem(WIDGET_VISIBILITY_KEY);
17
+ if (stored === 'true') return true;
18
+ if (stored === 'false') return false;
19
+ return null;
20
+ } catch {
21
+ return null;
22
+ }
23
+ },
24
+
25
+ set(expanded: boolean): void {
26
+ try {
27
+ localStorage.setItem(WIDGET_VISIBILITY_KEY, String(expanded));
28
+ } catch (error) {
29
+ if (error instanceof Error && error.name === 'QuotaExceededError') {
30
+ console.warn('localStorage quota exceeded, widgets visibility not saved');
31
+ }
32
+ }
33
+ },
34
+
35
+ clear(): void {
36
+ localStorage.removeItem(WIDGET_VISIBILITY_KEY);
37
+ },
38
+ };
@@ -0,0 +1,9 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ /**
3
+ * Tailwind v4 uses CSS-first configuration. Dynamic color and plugin spacing
4
+ * safelists live in src/styles.css via @source inline(). This file is kept
5
+ * for tooling compatibility only.
6
+ */
7
+ export default {
8
+ content: ['./src/**/*.{js,ts,jsx,tsx}'],
9
+ };
package/vite.config.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { defineConfig } from 'vite';
2
+ import tailwindcss from '@tailwindcss/vite';
3
+
4
+ // Vite config for building only the CSS with Tailwind
5
+ export default defineConfig({
6
+ plugins: [tailwindcss()],
7
+ build: {
8
+ outDir: 'dist',
9
+ emptyOutDir: false, // Don't clear dist folder (tsc already created .js/.d.ts files)
10
+ rollupOptions: {
11
+ input: './src/styles.css',
12
+ output: {
13
+ assetFileNames: 'styles.css',
14
+ },
15
+ },
16
+ },
17
+ });