@jini-ai/admin 0.4.2 → 0.4.4

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 (361) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +7 -0
  3. package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +1 -1
  4. package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +1 -1
  5. package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +1 -1
  6. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +1 -1
  7. package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +1 -1
  8. package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +1 -1
  9. package/dist/agent-plugins/react/index.js +1 -1
  10. package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +1 -1
  11. package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +1 -1
  12. package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +1 -1
  13. package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +1 -1
  14. package/dist/comments/adapters/http.d.ts +29 -0
  15. package/dist/comments/adapters/http.js +50 -0
  16. package/dist/comments/adapters/memory.d.ts +17 -0
  17. package/dist/comments/adapters/memory.js +61 -0
  18. package/dist/comments/comments.module.d.ts +73 -0
  19. package/dist/comments/comments.module.js +16 -0
  20. package/dist/comments/conformance/comments-api.conformance.d.ts +9 -0
  21. package/dist/comments/conformance/comments-api.conformance.js +63 -0
  22. package/dist/comments/controllers/comment-queue.controller.d.ts +48 -0
  23. package/dist/comments/controllers/comment-queue.controller.js +164 -0
  24. package/dist/comments/controllers/comment-settings.controller.d.ts +32 -0
  25. package/dist/comments/controllers/comment-settings.controller.js +77 -0
  26. package/dist/comments/controllers/comments.controller.d.ts +16 -0
  27. package/dist/comments/controllers/comments.controller.js +16 -0
  28. package/dist/comments/index.d.ts +13 -0
  29. package/dist/comments/index.js +8 -0
  30. package/dist/comments/messages.en.d.ts +54 -0
  31. package/dist/comments/messages.en.js +56 -0
  32. package/dist/comments/models.d.ts +22 -0
  33. package/dist/comments/models.js +2 -0
  34. package/dist/comments/ports.d.ts +14 -0
  35. package/dist/comments/ports.js +5 -0
  36. package/dist/comments/react/components/QueueSection.d.ts +30 -0
  37. package/dist/comments/react/components/QueueSection.js +57 -0
  38. package/dist/comments/react/components/SettingsSection.d.ts +14 -0
  39. package/dist/comments/react/components/SettingsSection.js +23 -0
  40. package/dist/comments/react/hooks/CommentsPage.hooks.d.ts +9 -0
  41. package/dist/comments/react/hooks/CommentsPage.hooks.js +10 -0
  42. package/dist/comments/react/hooks/CommentsPorts.hooks.d.ts +13 -0
  43. package/dist/comments/react/hooks/CommentsPorts.hooks.js +15 -0
  44. package/dist/comments/react/hooks/QueueSection.hooks.d.ts +62 -0
  45. package/dist/comments/react/hooks/QueueSection.hooks.js +57 -0
  46. package/dist/comments/react/hooks/SettingsSection.hooks.d.ts +12 -0
  47. package/dist/comments/react/hooks/SettingsSection.hooks.js +21 -0
  48. package/dist/comments/react/hooks/use-comment-queue.hooks.d.ts +34 -0
  49. package/dist/comments/react/hooks/use-comment-queue.hooks.js +47 -0
  50. package/dist/comments/react/hooks/use-comment-settings.hooks.d.ts +22 -0
  51. package/dist/comments/react/hooks/use-comment-settings.hooks.js +30 -0
  52. package/dist/comments/react/hooks/use-comments.hooks.d.ts +15 -0
  53. package/dist/comments/react/hooks/use-comments.hooks.js +20 -0
  54. package/dist/comments/react/index.d.ts +316 -0
  55. package/dist/comments/react/index.js +35 -0
  56. package/dist/comments/react/pages/CommentsPage.d.ts +12 -0
  57. package/dist/comments/react/pages/CommentsPage.js +15 -0
  58. package/dist/comments/rules.d.ts +140 -0
  59. package/dist/comments/rules.js +199 -0
  60. package/dist/core/index.d.ts +3 -1
  61. package/dist/core/index.js +1 -0
  62. package/dist/core/ledger-slice.d.ts +90 -0
  63. package/dist/core/ledger-slice.js +81 -0
  64. package/dist/core/ports/comments.d.ts +2 -0
  65. package/dist/core/ports/forms.d.ts +19 -7
  66. package/dist/core/ports/forms.js +4 -4
  67. package/dist/core/ports/index.d.ts +1 -1
  68. package/dist/core/ports/seo.d.ts +33 -6
  69. package/dist/core/react/bind-react.d.ts +46 -0
  70. package/dist/core/react/bind-react.js +28 -0
  71. package/dist/core/react/index.d.ts +3 -0
  72. package/dist/core/react/index.js +3 -0
  73. package/dist/core/react/use-controller.d.ts +16 -0
  74. package/dist/core/react/use-controller.js +18 -0
  75. package/dist/forms/adapters/http.d.ts +26 -0
  76. package/dist/forms/adapters/http.js +43 -0
  77. package/dist/forms/adapters/memory.d.ts +14 -0
  78. package/dist/forms/adapters/memory.js +77 -0
  79. package/dist/forms/conformance/forms-api.conformance.d.ts +17 -0
  80. package/dist/forms/conformance/forms-api.conformance.js +71 -0
  81. package/dist/forms/controllers/draft-store.d.ts +18 -0
  82. package/dist/forms/controllers/draft-store.js +17 -0
  83. package/dist/forms/controllers/field-attributes-dialog.controller.d.ts +37 -0
  84. package/dist/forms/controllers/field-attributes-dialog.controller.js +27 -0
  85. package/dist/forms/controllers/form-editor.controller.d.ts +36 -0
  86. package/dist/forms/controllers/form-editor.controller.js +22 -0
  87. package/dist/forms/controllers/form-fields-editor.controller.d.ts +20 -0
  88. package/dist/forms/controllers/form-fields-editor.controller.js +10 -0
  89. package/dist/forms/controllers/form-submission-detail.controller.d.ts +20 -0
  90. package/dist/forms/controllers/form-submission-detail.controller.js +10 -0
  91. package/dist/forms/controllers/form-submissions.controller.d.ts +25 -0
  92. package/dist/forms/controllers/form-submissions.controller.js +10 -0
  93. package/dist/forms/controllers/forms-list.controller.d.ts +22 -0
  94. package/dist/forms/controllers/forms-list.controller.js +10 -0
  95. package/dist/forms/forms.module.d.ts +138 -0
  96. package/dist/forms/forms.module.js +17 -0
  97. package/dist/forms/html-rules.d.ts +34 -0
  98. package/dist/forms/html-rules.js +34 -0
  99. package/dist/forms/index.d.ts +14 -0
  100. package/dist/forms/index.js +12 -0
  101. package/dist/forms/messages.en.d.ts +101 -0
  102. package/dist/forms/messages.en.js +105 -0
  103. package/dist/forms/models.d.ts +29 -0
  104. package/dist/forms/models.js +8 -0
  105. package/dist/forms/ports.d.ts +26 -0
  106. package/dist/forms/ports.js +6 -0
  107. package/dist/forms/react/components/FieldAttributesDialog.d.ts +14 -0
  108. package/dist/forms/react/components/FieldAttributesDialog.js +47 -0
  109. package/dist/forms/react/components/FormEditorFieldsBody.d.ts +28 -0
  110. package/dist/forms/react/components/FormEditorFieldsBody.js +24 -0
  111. package/dist/forms/react/components/FormEditorHeaderText.d.ts +7 -0
  112. package/dist/forms/react/components/FormEditorHeaderText.js +8 -0
  113. package/dist/forms/react/components/FormEditorMainPanel.d.ts +12 -0
  114. package/dist/forms/react/components/FormEditorMainPanel.js +13 -0
  115. package/dist/forms/react/components/FormEditorTabStrip.d.ts +13 -0
  116. package/dist/forms/react/components/FormEditorTabStrip.js +14 -0
  117. package/dist/forms/react/components/FormFieldsEditor.d.ts +13 -0
  118. package/dist/forms/react/components/FormFieldsEditor.js +39 -0
  119. package/dist/forms/react/components/FormSubmissionDate.d.ts +8 -0
  120. package/dist/forms/react/components/FormSubmissionDate.js +5 -0
  121. package/dist/forms/react/components/FormSubmissionDetail.d.ts +15 -0
  122. package/dist/forms/react/components/FormSubmissionDetail.js +30 -0
  123. package/dist/forms/react/components/FormSubmissions.d.ts +12 -0
  124. package/dist/forms/react/components/FormSubmissions.js +46 -0
  125. package/dist/forms/react/hooks/FormsPorts.hooks.d.ts +41 -0
  126. package/dist/forms/react/hooks/FormsPorts.hooks.js +16 -0
  127. package/dist/forms/react/hooks/forms-view.hooks.d.ts +117 -0
  128. package/dist/forms/react/hooks/forms-view.hooks.js +78 -0
  129. package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.d.ts +31 -0
  130. package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.js +22 -0
  131. package/dist/forms/react/hooks/use-form-editor.hooks.d.ts +118 -0
  132. package/dist/forms/react/hooks/use-form-editor.hooks.js +208 -0
  133. package/dist/forms/react/hooks/use-form-fields-editor.hooks.d.ts +34 -0
  134. package/dist/forms/react/hooks/use-form-fields-editor.hooks.js +36 -0
  135. package/dist/forms/react/hooks/use-form-submission-date.hooks.d.ts +12 -0
  136. package/dist/forms/react/hooks/use-form-submission-date.hooks.js +9 -0
  137. package/dist/forms/react/hooks/use-form-submission-detail.hooks.d.ts +68 -0
  138. package/dist/forms/react/hooks/use-form-submission-detail.hooks.js +81 -0
  139. package/dist/forms/react/hooks/use-form-submissions.hooks.d.ts +67 -0
  140. package/dist/forms/react/hooks/use-form-submissions.hooks.js +110 -0
  141. package/dist/forms/react/hooks/use-forms-list.hooks.d.ts +78 -0
  142. package/dist/forms/react/hooks/use-forms-list.hooks.js +103 -0
  143. package/dist/forms/react/index.d.ts +452 -0
  144. package/dist/forms/react/index.js +35 -0
  145. package/dist/forms/react/pages/FormEditor.d.ts +19 -0
  146. package/dist/forms/react/pages/FormEditor.js +40 -0
  147. package/dist/forms/react/pages/FormsList.d.ts +39 -0
  148. package/dist/forms/react/pages/FormsList.js +50 -0
  149. package/dist/forms/rules.d.ts +291 -0
  150. package/dist/forms/rules.js +338 -0
  151. package/dist/media/react/hooks/EditMediaPanel.hooks.js +1 -1
  152. package/dist/media/react/hooks/LibraryTab.hooks.d.ts +1 -1
  153. package/dist/media/react/hooks/LibraryTab.hooks.js +1 -1
  154. package/dist/media/react/hooks/MediaCard.hooks.js +6 -20
  155. package/dist/media/react/hooks/MediaGrid.hooks.d.ts +2 -2
  156. package/dist/media/react/hooks/MediaPage.hooks.d.ts +1 -1
  157. package/dist/media/react/hooks/MediaPage.hooks.js +1 -1
  158. package/dist/media/react/hooks/MediaPicker.hooks.js +1 -1
  159. package/dist/media/react/index.js +1 -1
  160. package/dist/media/react/tabs/LibraryTab.d.ts +1 -1
  161. package/dist/media/react/tabs/ProvidersTab.d.ts +1 -1
  162. package/dist/playground/react/components/Canvas.d.ts +1 -1
  163. package/dist/playground/react/hooks/Canvas.hooks.d.ts +1 -1
  164. package/dist/playground/react/hooks/Canvas.hooks.js +1 -1
  165. package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +1 -1
  166. package/dist/playground/react/index.js +1 -1
  167. package/dist/playground/react/pages/PlaygroundPage.d.ts +1 -1
  168. package/dist/playground/react/tabs/CanvasTab.d.ts +1 -1
  169. package/dist/react/bind-react.d.ts +1 -45
  170. package/dist/react/bind-react.js +2 -27
  171. package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +22 -5
  172. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +2 -2
  173. package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +17 -55
  174. package/dist/react/components/ConfirmDialog/ConfirmDialog.js +33 -70
  175. package/dist/react/components/RowMenu/RowMenu.hooks.js +14 -3
  176. package/dist/react/use-controller.d.ts +1 -15
  177. package/dist/react/use-controller.js +2 -17
  178. package/dist/redirects/adapters/http.d.ts +20 -0
  179. package/dist/redirects/adapters/http.js +31 -0
  180. package/dist/redirects/adapters/memory.d.ts +13 -0
  181. package/dist/redirects/adapters/memory.js +83 -0
  182. package/dist/redirects/conformance/redirects-api.conformance.d.ts +12 -0
  183. package/dist/redirects/conformance/redirects-api.conformance.js +66 -0
  184. package/dist/redirects/controllers/hit-count.controller.d.ts +14 -0
  185. package/dist/redirects/controllers/hit-count.controller.js +10 -0
  186. package/dist/redirects/controllers/import-redirects.controller.d.ts +28 -0
  187. package/dist/redirects/controllers/import-redirects.controller.js +29 -0
  188. package/dist/redirects/controllers/redirects.controller.d.ts +37 -0
  189. package/dist/redirects/controllers/redirects.controller.js +38 -0
  190. package/dist/redirects/index.d.ts +11 -0
  191. package/dist/redirects/index.js +10 -0
  192. package/dist/redirects/messages.en.d.ts +58 -0
  193. package/dist/redirects/messages.en.js +60 -0
  194. package/dist/redirects/models.d.ts +14 -0
  195. package/dist/redirects/models.js +2 -0
  196. package/dist/redirects/ports.d.ts +9 -0
  197. package/dist/redirects/ports.js +4 -0
  198. package/dist/redirects/react/components/HitCountCell.d.ts +19 -0
  199. package/dist/redirects/react/components/HitCountCell.js +19 -0
  200. package/dist/redirects/react/components/ImportRedirectsForm.d.ts +17 -0
  201. package/dist/redirects/react/components/ImportRedirectsForm.js +12 -0
  202. package/dist/redirects/react/hooks/RedirectsOptions.hooks.d.ts +27 -0
  203. package/dist/redirects/react/hooks/RedirectsOptions.hooks.js +15 -0
  204. package/dist/redirects/react/hooks/RedirectsPage.hooks.d.ts +50 -0
  205. package/dist/redirects/react/hooks/RedirectsPage.hooks.js +30 -0
  206. package/dist/redirects/react/hooks/RedirectsPorts.hooks.d.ts +10 -0
  207. package/dist/redirects/react/hooks/RedirectsPorts.hooks.js +11 -0
  208. package/dist/redirects/react/hooks/use-hit-count-cell.hooks.d.ts +19 -0
  209. package/dist/redirects/react/hooks/use-hit-count-cell.hooks.js +15 -0
  210. package/dist/redirects/react/hooks/use-import-redirects-form.hooks.d.ts +21 -0
  211. package/dist/redirects/react/hooks/use-import-redirects-form.hooks.js +25 -0
  212. package/dist/redirects/react/hooks/use-redirects.hooks.d.ts +34 -0
  213. package/dist/redirects/react/hooks/use-redirects.hooks.js +63 -0
  214. package/dist/redirects/react/hooks/wired.hooks.d.ts +55 -0
  215. package/dist/redirects/react/hooks/wired.hooks.js +31 -0
  216. package/dist/redirects/react/index.d.ts +324 -0
  217. package/dist/redirects/react/index.js +28 -0
  218. package/dist/redirects/react/pages/RedirectsPage.d.ts +15 -0
  219. package/dist/redirects/react/pages/RedirectsPage.js +20 -0
  220. package/dist/redirects/redirects.module.d.ts +77 -0
  221. package/dist/redirects/redirects.module.js +13 -0
  222. package/dist/redirects/rules.d.ts +131 -0
  223. package/dist/redirects/rules.js +134 -0
  224. package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +1 -1
  225. package/dist/security/react/hooks/AccessTokensTab.hooks.js +1 -1
  226. package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +1 -1
  227. package/dist/security/react/hooks/RootKeyTab.hooks.js +1 -1
  228. package/dist/security/react/hooks/SecurityPage.hooks.d.ts +1 -1
  229. package/dist/security/react/index.js +1 -1
  230. package/dist/security/react/pages/SecurityPage.d.ts +1 -1
  231. package/dist/security/react/tabs/AccessTokensTab.d.ts +1 -1
  232. package/dist/security/react/tabs/RootKeyTab.d.ts +1 -1
  233. package/dist/seo/adapters/http.d.ts +31 -0
  234. package/dist/seo/adapters/http.js +37 -0
  235. package/dist/seo/adapters/memory.d.ts +28 -0
  236. package/dist/seo/adapters/memory.js +129 -0
  237. package/dist/seo/conformance/seo-api.conformance.d.ts +8 -0
  238. package/dist/seo/conformance/seo-api.conformance.js +44 -0
  239. package/dist/seo/controllers/entry-picker.controller.d.ts +21 -0
  240. package/dist/seo/controllers/entry-picker.controller.js +17 -0
  241. package/dist/seo/controllers/entry-section.controller.d.ts +20 -0
  242. package/dist/seo/controllers/entry-section.controller.js +7 -0
  243. package/dist/seo/controllers/media-ref.controller.d.ts +26 -0
  244. package/dist/seo/controllers/media-ref.controller.js +14 -0
  245. package/dist/seo/controllers/seo-entry.controller.d.ts +31 -0
  246. package/dist/seo/controllers/seo-entry.controller.js +52 -0
  247. package/dist/seo/controllers/seo.controller.d.ts +29 -0
  248. package/dist/seo/controllers/seo.controller.js +50 -0
  249. package/dist/seo/controllers/sitemap.controller.d.ts +25 -0
  250. package/dist/seo/controllers/sitemap.controller.js +27 -0
  251. package/dist/seo/index.d.ts +14 -0
  252. package/dist/seo/index.js +12 -0
  253. package/dist/seo/messages.en.d.ts +79 -0
  254. package/dist/seo/messages.en.js +79 -0
  255. package/dist/seo/models.d.ts +179 -0
  256. package/dist/seo/models.js +8 -0
  257. package/dist/seo/ports.d.ts +11 -0
  258. package/dist/seo/ports.js +4 -0
  259. package/dist/seo/react/components/MediaPickerBridge.d.ts +4 -0
  260. package/dist/seo/react/components/MediaPickerBridge.js +8 -0
  261. package/dist/seo/react/components/MediaRefField.d.ts +40 -0
  262. package/dist/seo/react/components/MediaRefField.js +12 -0
  263. package/dist/seo/react/components/SeoIcons.d.ts +13 -0
  264. package/dist/seo/react/components/SeoIcons.js +32 -0
  265. package/dist/seo/react/components/SitemapModal.d.ts +48 -0
  266. package/dist/seo/react/components/SitemapModal.js +72 -0
  267. package/dist/seo/react/hooks/MediaPickerBridge.hooks.d.ts +6 -0
  268. package/dist/seo/react/hooks/MediaPickerBridge.hooks.js +27 -0
  269. package/dist/seo/react/hooks/MediaRefField.hooks.d.ts +25 -0
  270. package/dist/seo/react/hooks/MediaRefField.hooks.js +30 -0
  271. package/dist/seo/react/hooks/SeoModuleTabs.d.ts +14 -0
  272. package/dist/seo/react/hooks/SeoModuleTabs.js +18 -0
  273. package/dist/seo/react/hooks/SeoPage.hooks.d.ts +69 -0
  274. package/dist/seo/react/hooks/SeoPage.hooks.js +37 -0
  275. package/dist/seo/react/hooks/SeoPorts.hooks.d.ts +19 -0
  276. package/dist/seo/react/hooks/SeoPorts.hooks.js +22 -0
  277. package/dist/seo/react/hooks/SitemapModal.hooks.d.ts +26 -0
  278. package/dist/seo/react/hooks/SitemapModal.hooks.js +20 -0
  279. package/dist/seo/react/hooks/use-entry-picker.hooks.d.ts +11 -0
  280. package/dist/seo/react/hooks/use-entry-picker.hooks.js +20 -0
  281. package/dist/seo/react/hooks/use-seo-entry-panel.hooks.d.ts +14 -0
  282. package/dist/seo/react/hooks/use-seo-entry-panel.hooks.js +26 -0
  283. package/dist/seo/react/hooks/use-seo-entry-section.hooks.d.ts +4 -0
  284. package/dist/seo/react/hooks/use-seo-entry-section.hooks.js +7 -0
  285. package/dist/seo/react/hooks/use-seo.hooks.d.ts +11 -0
  286. package/dist/seo/react/hooks/use-seo.hooks.js +29 -0
  287. package/dist/seo/react/hooks/use-sitemap-modal.hooks.d.ts +10 -0
  288. package/dist/seo/react/hooks/use-sitemap-modal.hooks.js +18 -0
  289. package/dist/seo/react/index.d.ts +369 -0
  290. package/dist/seo/react/index.js +30 -0
  291. package/dist/seo/react/options.d.ts +26 -0
  292. package/dist/seo/react/options.js +2 -0
  293. package/dist/seo/react/pages/SeoPage.d.ts +161 -0
  294. package/dist/seo/react/pages/SeoPage.js +215 -0
  295. package/dist/seo/rules.d.ts +142 -0
  296. package/dist/seo/rules.js +220 -0
  297. package/dist/seo/seo.module.d.ts +115 -0
  298. package/dist/seo/seo.module.js +14 -0
  299. package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +1 -1
  300. package/dist/source-control/react/hooks/ProvidersTab.hooks.js +1 -1
  301. package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +1 -1
  302. package/dist/source-control/react/index.js +1 -1
  303. package/dist/source-control/react/pages/SourceControlPage.d.ts +1 -1
  304. package/dist/source-control/react/tabs/ProvidersTab.d.ts +1 -1
  305. package/dist/widgets/adapters/http.d.ts +19 -0
  306. package/dist/widgets/adapters/http.js +33 -0
  307. package/dist/widgets/adapters/memory.d.ts +22 -0
  308. package/dist/widgets/adapters/memory.js +93 -0
  309. package/dist/widgets/conformance/widgets-api.conformance.d.ts +6 -0
  310. package/dist/widgets/conformance/widgets-api.conformance.js +55 -0
  311. package/dist/widgets/controllers/instance-editor.controller.d.ts +49 -0
  312. package/dist/widgets/controllers/instance-editor.controller.js +87 -0
  313. package/dist/widgets/controllers/library.controller.d.ts +33 -0
  314. package/dist/widgets/controllers/library.controller.js +53 -0
  315. package/dist/widgets/controllers/region-editor.controller.d.ts +42 -0
  316. package/dist/widgets/controllers/region-editor.controller.js +69 -0
  317. package/dist/widgets/controllers/regions.controller.d.ts +27 -0
  318. package/dist/widgets/controllers/regions.controller.js +44 -0
  319. package/dist/widgets/index.d.ts +11 -0
  320. package/dist/widgets/index.js +9 -0
  321. package/dist/widgets/messages.en.d.ts +78 -0
  322. package/dist/widgets/messages.en.js +83 -0
  323. package/dist/widgets/models.d.ts +62 -0
  324. package/dist/widgets/models.js +2 -0
  325. package/dist/widgets/ports.d.ts +79 -0
  326. package/dist/widgets/ports.js +5 -0
  327. package/dist/widgets/react/components/WidgetInstanceNotices.d.ts +14 -0
  328. package/dist/widgets/react/components/WidgetInstanceNotices.js +25 -0
  329. package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.d.ts +22 -0
  330. package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.js +18 -0
  331. package/dist/widgets/react/components/WidgetsLibraryNotices.d.ts +13 -0
  332. package/dist/widgets/react/components/WidgetsLibraryNotices.js +10 -0
  333. package/dist/widgets/react/hooks/WidgetsPorts.hooks.d.ts +270 -0
  334. package/dist/widgets/react/hooks/WidgetsPorts.hooks.js +17 -0
  335. package/dist/widgets/react/hooks/navigation.hooks.d.ts +9 -0
  336. package/dist/widgets/react/hooks/navigation.hooks.js +6 -0
  337. package/dist/widgets/react/hooks/page-views.hooks.d.ts +87 -0
  338. package/dist/widgets/react/hooks/page-views.hooks.js +30 -0
  339. package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.d.ts +56 -0
  340. package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.js +38 -0
  341. package/dist/widgets/react/hooks/use-widget-region-editor.hooks.d.ts +32 -0
  342. package/dist/widgets/react/hooks/use-widget-region-editor.hooks.js +22 -0
  343. package/dist/widgets/react/hooks/use-widget-regions.hooks.d.ts +23 -0
  344. package/dist/widgets/react/hooks/use-widget-regions.hooks.js +22 -0
  345. package/dist/widgets/react/hooks/use-widgets-library.hooks.d.ts +37 -0
  346. package/dist/widgets/react/hooks/use-widgets-library.hooks.js +23 -0
  347. package/dist/widgets/react/index.d.ts +391 -0
  348. package/dist/widgets/react/index.js +31 -0
  349. package/dist/widgets/react/pages/WidgetInstanceEditor.d.ts +23 -0
  350. package/dist/widgets/react/pages/WidgetInstanceEditor.js +37 -0
  351. package/dist/widgets/react/pages/WidgetRegionEditor.d.ts +22 -0
  352. package/dist/widgets/react/pages/WidgetRegionEditor.js +25 -0
  353. package/dist/widgets/react/pages/WidgetRegions.d.ts +21 -0
  354. package/dist/widgets/react/pages/WidgetRegions.js +31 -0
  355. package/dist/widgets/react/pages/WidgetsLibrary.d.ts +24 -0
  356. package/dist/widgets/react/pages/WidgetsLibrary.js +61 -0
  357. package/dist/widgets/rules.d.ts +94 -0
  358. package/dist/widgets/rules.js +83 -0
  359. package/dist/widgets/widgets.module.d.ts +122 -0
  360. package/dist/widgets/widgets.module.js +21 -0
  361. package/package.json +206 -9
@@ -1,4 +1,4 @@
1
- import { type ReactNode } from 'react';
1
+ import type { ReactNode } from 'react';
2
2
  import { type ConfirmTone } from '../../types.js';
3
3
  import { type UseConfirmDialog } from './ConfirmDialog.hooks.js';
4
4
  /**
@@ -10,8 +10,8 @@ import { type UseConfirmDialog } from './ConfirmDialog.hooks.js';
10
10
  * overlay + backdrop idiom: that shape hand-rolls focus trapping, Escape handling, and a backdrop
11
11
  * element, all of which the browser's own top layer gives a real `<dialog>` for free, including
12
12
  * correct stacking above everything else on the page without a chosen `z-index`. The `showModal`/
13
- * `close` calls themselves, and the jsdom fallback they need, live in `ConfirmDialog.hooks.tsx` —
14
- * see that file's doc comment.
13
+ * `close` calls themselves, and the jsdom fallback they need, are delegated by
14
+ * `ConfirmDialog.hooks.tsx` to UI-kit's native hook — see that adapter's doc comment.
15
15
  *
16
16
  * Unstyled, like everything in this layer: the `.confirm-dialog` / `.btn-secondary` /
17
17
  * `.btn-danger` / `.btn-warning` class names are emitted for the host stylesheet to define.
@@ -51,7 +51,7 @@ import { type UseConfirmDialog } from './ConfirmDialog.hooks.js';
51
51
  * Labels state both the action and its consequence tier, derived from this component's own
52
52
  * three-tier `ConfirmTone` vocabulary rather than reparsed from `title`/`body`: `body` is arbitrary
53
53
  * `ReactNode` (a caller can pass JSX), not guaranteed to be a string at all, so it cannot be safely
54
- * folded into agent-facing text — see {@link confirmDialogConsequencePhrase}.
54
+ * folded into agent-facing text — the shared UI-kit confirmation planner owns those phrases.
55
55
  */
56
56
  export interface ConfirmDialogProps {
57
57
  open: boolean;
@@ -90,6 +90,23 @@ export interface ConfirmDialogProps {
90
90
  * effect without `agentHandle`. @default true */
91
91
  agentMayConfirm?: boolean;
92
92
  }
93
+ /**
94
+ * UI-kit's confirmation planner owns the sub-handle segments appended to the caller's base:
95
+ * literals chosen by the mechanism, never host data. Neither needs sanitizing, unlike
96
+ * `RowMenu`'s per-item keys (see this file's "Agent handles" contract).
97
+ *
98
+ * Its plain-language consequence phrase is keyed off the dialog's three-tier `ConfirmTone`
99
+ * vocabulary (`"default"` / `"warning"` / `"danger"`, documented in `../../types.js`), rather
100
+ * than reparsed from `title` or `body`, which cannot safely supply agent-facing consequence text.
101
+ * The confirm label names the action (`confirmLabel`), target (`title`) and declared consequence;
102
+ * the planner does not parse `body` to decide whether an action is safe.
103
+ *
104
+ * The cancel label's consequence is a guarantee of the contract (cancelling never calls
105
+ * `onConfirm`), rather than something read off `tone`, so it needs no tone input at all.
106
+ * Agent attributes retain the shape used by `RowMenu`'s local `rowMenuAgentProps`; injecting
107
+ * admin's attribute port into the shared owner preserves that shape and handle validation
108
+ * without keeping a second local implementation. No base handle means no agent attributes.
109
+ */
93
110
  /**
94
111
  * Controlled modal confirm — renders the `<dialog>` markup and delegates its open/close and focus
95
112
  * lifecycle to {@link useConfirmDialog} (injectable via the `useDialog` prop, defaulted to the real
@@ -99,5 +116,5 @@ export interface ConfirmDialogProps {
99
116
  * is no browser-assigned "default button" for Enter to reach for at all; confirm can only ever fire
100
117
  * from an explicit click or explicit Tab-then-Enter onto it.
101
118
  */
102
- export declare function ConfirmDialog({ useDialog, agentHandle: baseHandle, agentMayConfirm, ...props }: ConfirmDialogProps): import("react").JSX.Element;
119
+ export declare function ConfirmDialog({ useDialog, agentHandle: baseHandle, agentMayConfirm, ...props }: ConfirmDialogProps, _optional?: Record<string, never>): import("react").JSX.Element;
103
120
  //# sourceMappingURL=ConfirmDialog.d.ts.map
@@ -78,10 +78,10 @@ export declare function useConfirmDialogCancelLabel(_requiredArgs: Record<string
78
78
  readonly explicit?: string | undefined;
79
79
  }): string;
80
80
  /**
81
- * Owns the `<dialog>` element's open/close lifecycle and focus management for `ConfirmDialog`.
81
+ * Adapts UI-kit's `<dialog>` element open/close lifecycle and focus management for `ConfirmDialog`.
82
82
  *
83
83
  * The caller keeps `ConfirmDialog` mounted and toggles `open` — it is never conditionally rendered
84
- * by its parent — so the effect below has a stable `<dialog>` element to call `showModal()`/
84
+ * by its parent — so the shared native hook has a stable `<dialog>` element to call `showModal()`/
85
85
  * `close()` on and to restore focus through when it closes.
86
86
  *
87
87
  * Focus moves to the *cancel* action on open, not confirm — an operator whose first keystroke after
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useEffect, useId, useMemo, useRef, } from 'react';
2
+ import { createContext, useContext, useMemo, useRef, } from 'react';
3
+ import { useNativeDialog } from '@jini-ai/ui-kit/react/native';
3
4
  /** Empty object, not `undefined` — {@link useConfirmDialogCancelLabel} can always read `cancelLabel`
4
5
  * off it without an extra null check, whether or not a provider is mounted. */
5
6
  const ConfirmDialogDefaultsContext = createContext({});
@@ -41,10 +42,10 @@ export function useConfirmDialogCancelLabel(_requiredArgs, { explicit } = {}) {
41
42
  return explicit ?? cancelLabel ?? DEFAULT_CANCEL_LABEL;
42
43
  }
43
44
  /**
44
- * Owns the `<dialog>` element's open/close lifecycle and focus management for `ConfirmDialog`.
45
+ * Adapts UI-kit's `<dialog>` element open/close lifecycle and focus management for `ConfirmDialog`.
45
46
  *
46
47
  * The caller keeps `ConfirmDialog` mounted and toggles `open` — it is never conditionally rendered
47
- * by its parent — so the effect below has a stable `<dialog>` element to call `showModal()`/
48
+ * by its parent — so the shared native hook has a stable `<dialog>` element to call `showModal()`/
48
49
  * `close()` on and to restore focus through when it closes.
49
50
  *
50
51
  * Focus moves to the *cancel* action on open, not confirm — an operator whose first keystroke after
@@ -60,63 +61,24 @@ export function useConfirmDialog({ open, onCancel, document }, { pending } = {})
60
61
  // in document order regardless of which dialog is actually open — a screen reader announcing
61
62
  // "Delete role?" while the operator is about to confirm "Delete policy?", on a destructive
62
63
  // action. `useId()` gives every mounted instance its own id for free.
63
- const titleId = useId();
64
- const dialogRef = useRef(null);
65
- const cancelRef = useRef(null);
66
64
  // Captured at the moment `open` flips true, before focus moves into the dialog — the element that
67
65
  // had focus then is, by construction, whatever triggered this dialog (a `RowMenu` item's
68
66
  // "Delete", a plain trigger button, …). Restored on close rather than left wherever the browser's
69
67
  // own modal-focus algorithm happened to land (its default without this is `<body>`, which drops a
70
68
  // keyboard user back to the top of the page).
71
- const triggerRef = useRef(null);
72
- useEffect(() => {
73
- const dialog = dialogRef.current;
74
- if (!dialog)
75
- return;
76
- if (open) {
77
- triggerRef.current = document.activeElement;
78
- if (typeof dialog.showModal === 'function') {
79
- if (!dialog.open)
80
- dialog.showModal();
81
- }
82
- else {
83
- dialog.setAttribute('open', '');
84
- }
85
- cancelRef.current?.focus();
86
- }
87
- else {
88
- if (typeof dialog.close === 'function') {
89
- if (dialog.open)
90
- dialog.close();
91
- }
92
- else {
93
- dialog.removeAttribute('open');
94
- }
95
- if (triggerRef.current instanceof HTMLElement)
96
- triggerRef.current.focus();
97
- }
98
- }, [open, document]);
99
- function handleNativeCancel(e) {
100
- // Fires on Escape while a real `showModal()`-opened dialog has focus. Always prevented: the
101
- // effect above is the single source of truth for open/closed (driven by `open`), so
102
- // letting the browser close the element on its own would desync DOM state from React state.
103
- // Escape still closes the dialog — it just does so by routing through `onCancel`, same as a
104
- // Cancel-button click, so the caller's `open` state (and therefore this same effect) is what
105
- // actually calls `dialog.close()`.
106
- e.preventDefault();
107
- if (pending)
108
- return;
109
- onCancel();
110
- }
111
- function handleBackdropClick(e) {
112
- // A `<dialog>` element's own box is sized to its content, not the viewport — a click that lands
113
- // on the `<dialog>` element itself (as opposed to one of its children) is therefore a click on
114
- // the backdrop area outside that content box.
115
- if (pending)
116
- return;
117
- if (e.target === dialogRef.current)
118
- onCancel();
119
- }
69
+ // Fires on Escape while a real `showModal()`-opened dialog has focus. Always prevented: the
70
+ // shared native hook is the single source of truth for open/closed (driven by `open`), so
71
+ // letting the browser close the element on its own would desync DOM state from React state.
72
+ // Escape still closes the dialog — it just does so by routing through `onCancel`, same as a
73
+ // Cancel-button click, so the caller's `open` state (and therefore this same effect) is what
74
+ // actually calls `dialog.close()`.
75
+ // A `<dialog>` element's own box is sized to its content, not the viewport — a click that lands
76
+ // on the `<dialog>` element itself (as opposed to one of its children) is therefore a click on
77
+ // the backdrop area outside that content box.
78
+ const cancelRef = useRef(null);
79
+ const vm = useNativeDialog({ open, title: '', onClose: () => onCancel(), ...(pending === undefined ? {} : { pending }) }, { document, initialFocus: () => cancelRef.current?.focus() });
80
+ const titleId = vm.titleId, dialogRef = vm.props.ref;
81
+ const handleNativeCancel = vm.props.onCancel, handleBackdropClick = vm.props.onClick;
120
82
  return { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick };
121
83
  }
122
84
  //# sourceMappingURL=ConfirmDialog.hooks.js.map
@@ -1,72 +1,25 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import {} from 'react';
3
2
  import { agentHandle } from '@jini-ai/agentic';
3
+ import { useConfirmController } from '@jini-ai/ui-kit/react';
4
4
  import { resolveTone, toneClassName } from '../../types.js';
5
5
  import { useConfirmDialog, useConfirmDialogCancelLabel } from './ConfirmDialog.hooks.js';
6
- /** Sub-handle segments appended to the caller's base — literals this component chooses itself,
7
- * never host data (see this file's "Agent handles" doc comment for why that means neither needs
8
- * sanitizing, unlike `RowMenu`'s per-item keys). */
9
- const CONFIRM_HANDLE_ACTION = 'confirm';
10
- const CANCEL_HANDLE_ACTION = 'cancel';
11
6
  /**
12
- * Plain-language phrase for what confirming actually changes, keyed off the dialog's own
13
- * three-tier `ConfirmTone` vocabulary (`"default"` / `"warning"` / `"danger"`, documented in
14
- * `../../types.js`) rather than reparsed from `title` or `body` — see this file's doc comment for
15
- * why those cannot be safely folded into agent-facing text.
7
+ * UI-kit's confirmation planner owns the sub-handle segments appended to the caller's base:
8
+ * literals chosen by the mechanism, never host data. Neither needs sanitizing, unlike
9
+ * `RowMenu`'s per-item keys (see this file's "Agent handles" contract).
16
10
  *
17
- * @param tone - The dialog's resolved tone (see `resolveTone`).
18
- * @returns The tier's consequence phrase, or `undefined` for `"default"`, which declares no tier.
19
- * @complexity O(1).
20
- */
21
- function confirmDialogConsequencePhrase(tone) {
22
- if (tone === 'danger')
23
- return 'cannot be undone';
24
- if (tone === 'warning')
25
- return 'changes access, but is reversible';
26
- return undefined;
27
- }
28
- /**
29
- * The confirm action's agent-facing label: what it does (`confirmLabel`), what it applies to
30
- * (`title`), and — when the tone declares one — its consequence tier.
31
- *
32
- * @param confirmLabel - The button's own visible text, e.g. `"Delete"`.
33
- * @param title - The dialog's title, e.g. `"Delete role?"`.
34
- * @param tone - The dialog's resolved tone.
35
- * @returns A label an agent can use to judge whether confirming is safe, without having read
36
- * `body` (which this function never receives — see this file's doc comment for why).
37
- * @complexity O(1).
38
- */
39
- function confirmDialogConfirmLabel(confirmLabel, title, tone) {
40
- const consequence = confirmDialogConsequencePhrase(tone);
41
- return consequence === undefined ? `${confirmLabel} — ${title}` : `${confirmLabel} — ${title}; ${consequence}`;
42
- }
43
- /**
44
- * The cancel action's agent-facing label. Unlike {@link confirmDialogConfirmLabel}, its consequence
45
- * is a guarantee of this component's own contract (cancelling never calls `onConfirm`) rather than
46
- * something read off `tone`, so it needs no tone input at all.
47
- *
48
- * @param cancelLabel - The button's own visible text, already defaulted by the caller.
49
- * @param title - The dialog's title, e.g. `"Delete role?"`.
50
- * @returns A label stating that this action leaves the titled action unconfirmed.
51
- * @complexity O(1).
52
- */
53
- function confirmDialogCancelLabel(cancelLabel, title) {
54
- return `${cancelLabel} — leaves "${title}" unconfirmed; no action taken`;
55
- }
56
- /**
57
- * Builds the `data-agent-*` attribute props for one of this dialog's two actions, or nothing at
58
- * all when the dialog published no base handle — same shape as `RowMenu.tsx`'s local
59
- * `rowMenuAgentProps`, kept local and unexported here since only this one component needs it.
11
+ * Its plain-language consequence phrase is keyed off the dialog's three-tier `ConfirmTone`
12
+ * vocabulary (`"default"` / `"warning"` / `"danger"`, documented in `../../types.js`), rather
13
+ * than reparsed from `title` or `body`, which cannot safely supply agent-facing consequence text.
14
+ * The confirm label names the action (`confirmLabel`), target (`title`) and declared consequence;
15
+ * the planner does not parse `body` to decide whether an action is safe.
60
16
  *
61
- * @param base - The dialog's own handle from the caller, or `undefined` when it published none.
62
- * @param action - Which action this is — see {@link CONFIRM_HANDLE_ACTION}/{@link CANCEL_HANDLE_ACTION}.
63
- * @param options - Role and this action's already-composed label.
64
- * @returns Spreadable attribute props, or `{}` when `base` is `undefined`.
65
- * @complexity O(1).
17
+ * The cancel label's consequence is a guarantee of the contract (cancelling never calls
18
+ * `onConfirm`), rather than something read off `tone`, so it needs no tone input at all.
19
+ * Agent attributes retain the shape used by `RowMenu`'s local `rowMenuAgentProps`; injecting
20
+ * admin's attribute port into the shared owner preserves that shape and handle validation
21
+ * without keeping a second local implementation. No base handle means no agent attributes.
66
22
  */
67
- function confirmDialogAgentProps(base, action, options) {
68
- return base === undefined ? {} : agentHandle({ handle: `${base}-${action}` }, options);
69
- }
70
23
  /**
71
24
  * Controlled modal confirm — renders the `<dialog>` markup and delegates its open/close and focus
72
25
  * lifecycle to {@link useConfirmDialog} (injectable via the `useDialog` prop, defaulted to the real
@@ -76,16 +29,26 @@ function confirmDialogAgentProps(base, action, options) {
76
29
  * is no browser-assigned "default button" for Enter to reach for at all; confirm can only ever fire
77
30
  * from an explicit click or explicit Tab-then-Enter onto it.
78
31
  */
79
- export function ConfirmDialog({ useDialog = useConfirmDialog, agentHandle: baseHandle, agentMayConfirm = true, ...props }) {
80
- const { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick } = useDialog({ open: props.open, onCancel: props.onCancel, document }, { pending: props.pending });
32
+ export function ConfirmDialog({ useDialog = useConfirmDialog, agentHandle: baseHandle, agentMayConfirm = true, ...props }, _optional = {}) {
81
33
  const tone = resolveTone({}, props);
82
34
  const cancelLabel = useConfirmDialogCancelLabel({}, { explicit: props.cancelLabel });
83
- return (_jsxs("dialog", { ref: dialogRef, className: "confirm-dialog", "aria-labelledby": titleId, onCancel: handleNativeCancel, onClick: handleBackdropClick, children: [_jsx("h2", { id: titleId, children: props.title }), _jsx("div", { className: "confirm-dialog-body", children: props.body }), _jsxs("div", { className: "confirm-dialog-actions", children: [_jsx("button", { ref: cancelRef, type: "button", className: "btn-secondary", disabled: props.pending, onClick: props.onCancel, ...confirmDialogAgentProps(baseHandle, CANCEL_HANDLE_ACTION, {
84
- role: 'button',
85
- label: confirmDialogCancelLabel(cancelLabel, props.title),
86
- }), children: cancelLabel }), _jsx("button", { type: "button", className: toneClassName({ tone }), disabled: props.pending, onClick: () => props.onConfirm(), ...confirmDialogAgentProps(agentMayConfirm ? baseHandle : undefined, CONFIRM_HANDLE_ACTION, {
87
- role: 'button',
88
- label: confirmDialogConfirmLabel(props.confirmLabel, props.title, tone),
89
- }), children: props.confirmLabel })] })] }));
35
+ const controller = useConfirmController({
36
+ open: props.open, title: props.title, body: props.body, confirmLabel: props.confirmLabel,
37
+ cancelLabel, tone, agentMayConfirm,
38
+ ...(baseHandle === undefined ? {} : { agentHandle: baseHandle }),
39
+ ...(props.pending === undefined ? {} : { pending: props.pending }),
40
+ onConfirm: () => props.onConfirm(), onCancel: () => props.onCancel(),
41
+ }, {
42
+ // UI-kit names selects separately; agentic publishes them as fields and still owns handle validation.
43
+ agent: ((required, optional = {}) => agentHandle(required, {
44
+ ...(optional.role === undefined ? {} : { role: optional.role === 'select' ? 'field' : optional.role }),
45
+ ...(optional.label === undefined ? {} : { label: optional.label }),
46
+ })),
47
+ });
48
+ const { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick } = useDialog({ open: props.open, onCancel: () => { controller.requestDismiss({ reason: 'close' }); }, document }, { pending: controller.pending });
49
+ // Keep admin's concise accessible names; the shared planner still supplies consequence-aware agent labels.
50
+ const { 'aria-label': _cancelName, ...cancelAttrs } = controller.cancel.attrs ?? {};
51
+ const { 'aria-label': _confirmName, ...confirmAttrs } = controller.confirm.attrs ?? {};
52
+ return (_jsxs("dialog", { ref: dialogRef, className: "confirm-dialog", "aria-labelledby": titleId, onCancel: handleNativeCancel, onClick: handleBackdropClick, children: [_jsx("h2", { id: titleId, children: props.title }), _jsxs("div", { className: "confirm-dialog-body", children: [props.body, controller.error] }), _jsxs("div", { className: "confirm-dialog-actions", children: [_jsx("button", { ref: cancelRef, type: "button", className: "btn-secondary", disabled: controller.pending, onClick: () => controller.cancel.onPress?.({}), ...cancelAttrs, children: cancelLabel }), _jsx("button", { type: "button", className: toneClassName({ tone }), disabled: controller.pending, onClick: () => controller.confirm.onPress?.({}), ...confirmAttrs, children: props.confirmLabel })] })] }));
90
53
  }
91
54
  //# sourceMappingURL=ConfirmDialog.js.map
@@ -12,13 +12,14 @@ const VIEWPORT_MARGIN = 8;
12
12
  * visible jump. Recomputed on scroll and resize too: a portaled menu is a DOM sibling of its anchor,
13
13
  * not a child, so it does not track the anchor's position on its own the way an in-flow popup would.
14
14
  *
15
- * Click-outside closes. Scoped to the open window only, same lifecycle discipline as
15
+ * Click-outside and Escape close. Escape is document-scoped so it also works after focus
16
+ * moves away from the popup. Scoped to the open window only, same lifecycle discipline as
16
17
  * `ConfirmButton`'s armed-only document listeners — a closed, idle `RowMenu` costs nothing beyond
17
18
  * its trigger button even with many mounted per table.
18
19
  *
19
20
  * @complexity O(1) per call and per scroll/resize/mousedown event.
20
21
  */
21
- function trackOpenMenu({ trigger, menu }, { window, document, onPosition, onDismiss }) {
22
+ function trackOpenMenu({ trigger, menu }, { window, document, onPosition, onDismiss, onEscape }) {
22
23
  function reposition() {
23
24
  const rect = trigger.getBoundingClientRect();
24
25
  const menuHeight = menu.offsetHeight;
@@ -41,14 +42,23 @@ function trackOpenMenu({ trigger, menu }, { window, document, onPosition, onDism
41
42
  return;
42
43
  onDismiss();
43
44
  }
45
+ function onDocKeyDown(e) {
46
+ if (e.key !== 'Escape' || e.defaultPrevented)
47
+ return;
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+ onEscape();
51
+ }
44
52
  reposition();
45
53
  window.addEventListener('scroll', reposition, true);
46
54
  window.addEventListener('resize', reposition);
47
55
  document.addEventListener('mousedown', onDocMouseDown);
56
+ document.addEventListener('keydown', onDocKeyDown);
48
57
  return () => {
49
58
  window.removeEventListener('scroll', reposition, true);
50
59
  window.removeEventListener('resize', reposition);
51
60
  document.removeEventListener('mousedown', onDocMouseDown);
61
+ document.removeEventListener('keydown', onDocKeyDown);
52
62
  };
53
63
  }
54
64
  /**
@@ -89,7 +99,7 @@ export function useRowMenu({ itemCount, window, document }) {
89
99
  let stop;
90
100
  return (menu) => {
91
101
  if (menu)
92
- stop = trackOpenMenu({ trigger: anchor, menu }, { window, document, onPosition: setPosition, onDismiss: () => close(false) });
102
+ stop = trackOpenMenu({ trigger: anchor, menu }, { window, document, onPosition: setPosition, onDismiss: () => close(false), onEscape: () => close(true) });
93
103
  else
94
104
  stop();
95
105
  };
@@ -140,6 +150,7 @@ export function useRowMenu({ itemCount, window, document }) {
140
150
  break;
141
151
  case 'Escape':
142
152
  e.preventDefault();
153
+ e.stopPropagation();
143
154
  close(true);
144
155
  break;
145
156
  case 'Tab':
@@ -1,16 +1,2 @@
1
- import type { DependencyList } from 'react';
2
- import type { ControllerStore } from '../core/module/controller-store.js';
3
- /** Factory runs after commit, never during render. Each effect attachment owns a fresh
4
- * controller, so StrictMode's cleanup/replay cannot revive a disposed controller. */
5
- export declare function useController<C extends ControllerStore<unknown>>({ create, dependencies }: {
6
- create: () => C;
7
- dependencies: DependencyList;
8
- }, { start, }?: {
9
- start?: (required: {
10
- controller: C;
11
- }, optional?: Record<string, never>) => void;
12
- }): {
13
- controller: C | null;
14
- snapshot: ReturnType<C["getSnapshot"]> | null;
15
- };
1
+ export * from '../core/react/use-controller.js';
16
2
  //# sourceMappingURL=use-controller.d.ts.map
@@ -1,18 +1,3 @@
1
- import { useEffect, useState, useSyncExternalStore, useCallback } from 'react';
2
- /** Factory runs after commit, never during render. Each effect attachment owns a fresh
3
- * controller, so StrictMode's cleanup/replay cannot revive a disposed controller. */
4
- export function useController({ create, dependencies }, { start, } = {}) {
5
- const [controller, setController] = useState(null);
6
- useEffect(() => {
7
- const current = create();
8
- setController(current);
9
- start?.({ controller: current });
10
- return () => current.dispose();
11
- // Dependencies are explicitly supplied by the owning hook, like useMemo's contract.
12
- // eslint-disable-next-line react-hooks/exhaustive-deps
13
- }, dependencies);
14
- const subscribe = useCallback((listener) => controller?.subscribe({ listener }) ?? (() => { }), [controller]);
15
- const snapshot = useSyncExternalStore(subscribe, () => (controller?.getSnapshot() ?? null), () => null);
16
- return { controller, snapshot };
17
- }
1
+ // Compatibility path; the shared implementation lives in core.
2
+ export * from '../core/react/use-controller.js';
18
3
  //# sourceMappingURL=use-controller.js.map
@@ -0,0 +1,20 @@
1
+ import type { AdminRedirectsPort } from '../../core/ports/redirects.js';
2
+ /** Host owns authentication, addressing, retries and error decoding, as in media's adapter. */
3
+ export interface RedirectsTransportPort {
4
+ request<T>(required: {
5
+ path: string;
6
+ method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
7
+ body?: unknown;
8
+ }, optional?: Record<string, never>): Promise<T>;
9
+ url(required: {
10
+ path: string;
11
+ }, optional?: Record<string, never>): string;
12
+ }
13
+ /** Map existing HTTP envelopes to the core API without validating or rewriting operator inputs.
14
+ * @example createHttpRedirectsApi({ transport, basePath: workspacePath + '/redirects' }, {});
15
+ */
16
+ export declare function createHttpRedirectsApi({ transport, basePath }: {
17
+ transport: RedirectsTransportPort;
18
+ basePath: string;
19
+ }, _optional?: Record<string, never>): AdminRedirectsPort;
20
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1,31 @@
1
+ /** Map existing HTTP envelopes to the core API without validating or rewriting operator inputs.
2
+ * @example createHttpRedirectsApi({ transport, basePath: workspacePath + '/redirects' }, {});
3
+ */
4
+ export function createHttpRedirectsApi({ transport, basePath }, _optional = {}) {
5
+ const base = basePath.replace(/\/$/, '');
6
+ const path = (id) => `${base}/${encodeURIComponent(id)}`;
7
+ async function record(method, target, body) {
8
+ const response = await transport.request({ path: target, method, ...(body === undefined ? {} : { body }) });
9
+ return response.data;
10
+ }
11
+ return {
12
+ async listRedirects(_required, filter = {}) {
13
+ const query = new URLSearchParams();
14
+ for (const key of ['status', 'source', 'matchType']) {
15
+ if (filter[key] !== undefined)
16
+ query.set(key, filter[key]);
17
+ }
18
+ const suffix = query.size ? `?${query.toString()}` : '';
19
+ return (await transport.request({ path: `${base}${suffix}`, method: 'GET' })).data;
20
+ },
21
+ getRedirect: ({ id }) => record('GET', path(id)),
22
+ createRedirect: (input, options = {}) => record('POST', base, { ...input, ...options }),
23
+ updateRedirect: ({ id }, patch = {}) => record('PATCH', path(id), patch),
24
+ tombstoneRedirect: ({ id }) => record('DELETE', path(id)),
25
+ async getRedirectHitStats({ id }) {
26
+ return (await transport.request({ path: `${path(id)}/hits`, method: 'GET' })).data;
27
+ },
28
+ importRedirects: ({ rules }) => transport.request({ path: `${base}/import`, method: 'POST', body: { rules } }),
29
+ };
30
+ }
31
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1,13 @@
1
+ import type { AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportResult, AdminRedirectsPort } from '../../core/ports/redirects.js';
2
+ /** Presentation backend, not a routing engine: host validators/origin policy remain server owned.
3
+ * Optional validation lets a host model its own open match vocabulary without a second schema.
4
+ * @example createMemoryRedirectsApi({ redirects: [] }, {});
5
+ */
6
+ export declare function createMemoryRedirectsApi({ redirects, hits }: {
7
+ redirects?: readonly AdminRedirect[];
8
+ hits?: Readonly<Record<string, AdminRedirectHitStats>>;
9
+ }, { validate, onImport }?: {
10
+ validate?: (input: AdminRedirectCreateInput) => void;
11
+ onImport?: (rules: readonly AdminRedirectCreateInput[]) => AdminRedirectImportResult | undefined;
12
+ }): AdminRedirectsPort;
13
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1,83 @@
1
+ import { AdminApiError } from '../../core/transport/errors.js';
2
+ /** Presentation backend, not a routing engine: host validators/origin policy remain server owned.
3
+ * Optional validation lets a host model its own open match vocabulary without a second schema.
4
+ * @example createMemoryRedirectsApi({ redirects: [] }, {});
5
+ */
6
+ export function createMemoryRedirectsApi({ redirects = [], hits = {} }, { validate, onImport } = {}) {
7
+ const rows = new Map(redirects.map(row => [row.id, Object.freeze({ ...row })]));
8
+ const stats = new Map(Object.entries(hits).map(([id, value]) => [id, Object.freeze({ ...value })]));
9
+ let nextId = 1;
10
+ function get(id) {
11
+ const row = rows.get(id);
12
+ if (!row)
13
+ throw new AdminApiError({ message: `redirect '${id}' was not found`, status: 404 }, { code: 'REDIRECT_NOT_FOUND' });
14
+ return row;
15
+ }
16
+ function create(input, source) {
17
+ // The core port documents reference-host rejection. A supplied validator owns alternate hosts.
18
+ if (validate)
19
+ validate(input);
20
+ else if (input.matchType === 'regex')
21
+ throw new AdminApiError({ message: 'regex match type is not supported', status: 400 }, { code: 'REDIRECT_VALIDATION_ERROR' });
22
+ let id;
23
+ do {
24
+ id = `memory-redirect-${nextId++}`;
25
+ } while (rows.has(id));
26
+ const row = Object.freeze({ ...input, id, status: 'active', override: input.override ?? false,
27
+ priority: input.priority ?? 0, source, sourceEntryId: null, fromPathAtCapture: null, toPathAtCapture: null,
28
+ createdByPrincipal: 'memory-principal', createdByPluginId: null,
29
+ createdAt: new Date(0).toISOString(), updatedAt: new Date(0).toISOString(), version: 1 });
30
+ rows.set(id, row);
31
+ return row;
32
+ }
33
+ return {
34
+ async listRedirects(_required, filter = {}) {
35
+ return Object.freeze([...rows.values()].filter(row => (filter.status === undefined || row.status === filter.status) &&
36
+ (filter.source === undefined || row.source === filter.source) &&
37
+ (filter.matchType === undefined || row.matchType === filter.matchType)));
38
+ },
39
+ async getRedirect({ id }) { return get(id); },
40
+ async createRedirect(input, options = {}) { return create({ ...input, ...options }, 'manual'); },
41
+ async updateRedirect({ id }, patch = {}) {
42
+ const before = get(id);
43
+ const next = { ...before, ...patch };
44
+ if (validate)
45
+ validate(next);
46
+ else if (patch.matchType === 'regex')
47
+ throw new AdminApiError({ message: 'regex match type is not supported', status: 400 }, { code: 'REDIRECT_VALIDATION_ERROR' });
48
+ const row = Object.freeze({ ...next, version: before.version + 1 });
49
+ rows.set(id, row);
50
+ return row;
51
+ },
52
+ async tombstoneRedirect({ id }) {
53
+ const row = get(id);
54
+ if (row.status === 'disabled')
55
+ return row;
56
+ const disabled = Object.freeze({ ...row, status: 'disabled', version: row.version + 1 });
57
+ rows.set(id, disabled);
58
+ return disabled;
59
+ },
60
+ async getRedirectHitStats({ id }) {
61
+ get(id);
62
+ return stats.get(id) ?? Object.freeze({ redirectId: id, hitCount: 0, lastHitAt: null });
63
+ },
64
+ async importRedirects({ rules }) {
65
+ const overridden = onImport?.(rules);
66
+ if (overridden)
67
+ return overridden;
68
+ const created = [], failed = [];
69
+ // One failed item never discards successful siblings; no per-item network I/O.
70
+ for (const [index, input] of rules.entries()) {
71
+ try {
72
+ created.push(create(input, 'import'));
73
+ }
74
+ catch (error) {
75
+ failed.push({ index, code: error instanceof AdminApiError ? error.code ?? 'INTERNAL_ERROR' : 'INTERNAL_ERROR',
76
+ message: error instanceof AdminApiError ? error.message : 'an internal error occurred' });
77
+ }
78
+ }
79
+ return { created: Object.freeze(created), failed: Object.freeze(failed) };
80
+ },
81
+ };
82
+ }
83
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1,12 @@
1
+ import type { AdminRedirectsPort } from '../../core/ports/redirects.js';
2
+ /** Destructive framework-free checklist: use an isolated backend with no production data.
3
+ * Validates core soft-delete, snapshots, lazy-read data and per-item partial import contracts.
4
+ * Reference regex rejection probes can be disabled for a host implementing the port's open vocabulary.
5
+ * @example await runRedirectsApiConformance({ api: createMemoryRedirectsApi({}, {}) }, {});
6
+ */
7
+ export declare function runRedirectsApiConformance({ api }: {
8
+ api: AdminRedirectsPort;
9
+ }, { referenceRegexRejection }?: {
10
+ referenceRegexRejection?: boolean;
11
+ }): Promise<readonly string[]>;
12
+ //# sourceMappingURL=redirects-api.conformance.d.ts.map
@@ -0,0 +1,66 @@
1
+ import { AdminApiError } from '../../core/transport/errors.js';
2
+ /** Destructive framework-free checklist: use an isolated backend with no production data.
3
+ * Validates core soft-delete, snapshots, lazy-read data and per-item partial import contracts.
4
+ * Reference regex rejection probes can be disabled for a host implementing the port's open vocabulary.
5
+ * @example await runRedirectsApiConformance({ api: createMemoryRedirectsApi({}, {}) }, {});
6
+ */
7
+ export async function runRedirectsApiConformance({ api }, { referenceRegexRejection = true } = {}) {
8
+ const checks = [];
9
+ function assert(ok, name) {
10
+ if (!ok)
11
+ throw new AdminApiError({ message: `Redirects API conformance: ${name}`, status: 0 }, { code: 'CONFORMANCE_FAILED' });
12
+ checks.push(name);
13
+ }
14
+ async function rejects(run, name) {
15
+ let rejected = false;
16
+ try {
17
+ await run();
18
+ }
19
+ catch {
20
+ rejected = true;
21
+ }
22
+ assert(rejected, name);
23
+ }
24
+ const input = { matchType: 'exact', fromPattern: '/redirects-conformance-a', toTarget: '/redirects-conformance-b', statusCode: 301 };
25
+ const created = await api.createRedirect(input, { override: true, priority: 7 });
26
+ assert(created.status === 'active' && created.override && created.priority === 7, 'create preserves fields and options');
27
+ const before = await api.listRedirects({});
28
+ assert(before.some(row => row.id === created.id), 'list contains the created rule');
29
+ assert((await api.getRedirect({ id: created.id })).id === created.id, 'get reads by id');
30
+ const hits = await api.getRedirectHitStats({ id: created.id });
31
+ assert(hits.redirectId === created.id && hits.hitCount === 0 && hits.lastHitAt === null, 'new rule has zero hits');
32
+ const updated = await api.updateRedirect({ id: created.id }, { status: 'disabled' });
33
+ assert(updated.status === 'disabled' && updated.toTarget === created.toTarget, 'partial update preserves other fields');
34
+ assert(created.status === 'active' && before.find(row => row.id === created.id)?.status === 'active', 'prior snapshots stay unchanged');
35
+ assert((await api.listRedirects({}, { status: 'disabled' })).every(row => row.status === 'disabled'), 'status filter');
36
+ await api.updateRedirect({ id: created.id }, { status: 'active' });
37
+ const disabled = await api.tombstoneRedirect({ id: created.id });
38
+ assert(disabled.status === 'disabled', 'tombstone returns the disabled rule');
39
+ assert((await api.listRedirects({})).some(row => row.id === created.id), 'soft deletion retains the rule');
40
+ assert((await api.getRedirect({ id: created.id })).status === 'disabled', 'tombstoned rule remains readable');
41
+ await rejects(() => api.getRedirect({ id: 'missing-conformance-rule' }), 'missing rule rejects');
42
+ await rejects(() => api.getRedirectHitStats({ id: 'missing-conformance-rule' }), 'missing hits differs from zero hits');
43
+ await rejects(() => api.updateRedirect({ id: 'missing-conformance-rule' }, { status: 'disabled' }), 'missing update rejects');
44
+ await rejects(() => api.tombstoneRedirect({ id: 'missing-conformance-rule' }), 'missing tombstone rejects');
45
+ if (referenceRegexRejection) {
46
+ await rejects(() => api.createRedirect({ ...input, fromPattern: '/regex-conformance', matchType: 'regex' }), 'reference regex create is loudly rejected');
47
+ await rejects(() => api.updateRedirect({ id: created.id }, { matchType: 'regex' }), 'reference regex update is loudly rejected');
48
+ }
49
+ const batch = await api.importRedirects({ rules: [
50
+ { ...input, fromPattern: '/import-conformance-a' },
51
+ ...(referenceRegexRejection ? [{ ...input, fromPattern: '/import-conformance-regex', matchType: 'regex' }] : []),
52
+ { ...input, fromPattern: '/import-conformance-c' },
53
+ ] });
54
+ if (referenceRegexRejection) {
55
+ assert(batch.created.length === 2 && batch.failed.length === 1 && batch.failed[0]?.index === 1, 'middle failure preserves both successful siblings');
56
+ assert(batch.created.every(row => row.fromPattern !== '/import-conformance-regex'), 'invalid item is never reported created');
57
+ }
58
+ else {
59
+ assert(batch.created.length === 2 && batch.failed.length === 0, 'valid import batch succeeds');
60
+ }
61
+ assert(batch.created.every(row => row.source === 'import'), 'import provenance is stamped by the backend');
62
+ for (const row of batch.created)
63
+ await api.tombstoneRedirect({ id: row.id });
64
+ return Object.freeze(checks);
65
+ }
66
+ //# sourceMappingURL=redirects-api.conformance.js.map