@phis/ui 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 (335) hide show
  1. package/components/cms/phi-cms-layout-renderer.js +4 -3
  2. package/components/cms/phi-cms-page-render-scope.d.ts +4 -5
  3. package/components/cms/phi-cms-page-render-scope.js +43 -22
  4. package/components/cms/phi-cms-render-diagnostic-client.js +7 -3
  5. package/components/cms/phi-cms-render-error-boundary.js +2 -1
  6. package/components/controls/phi-anchor-nav-control.js +4 -1
  7. package/components/controls/phi-background-control.js +21 -6
  8. package/components/controls/phi-bullet-list-control.d.ts +7 -2
  9. package/components/controls/phi-bullet-list-control.js +35 -5
  10. package/components/controls/phi-color-control.js +4 -2
  11. package/components/controls/phi-drawer-control-adapter.js +3 -2
  12. package/components/controls/phi-inline-text-editor.js +7 -1
  13. package/components/controls/phi-length-control.js +1 -1
  14. package/components/controls/phi-ribbon-control.d.ts +38 -0
  15. package/components/controls/phi-ribbon-control.js +57 -0
  16. package/components/controls/phi-ribbon-wrap-control.d.ts +26 -0
  17. package/components/controls/phi-ribbon-wrap-control.js +25 -0
  18. package/components/controls/phi-select-control.js +5 -2
  19. package/components/controls/phi-series-chart-control.d.ts +48 -0
  20. package/components/controls/phi-series-chart-control.js +82 -0
  21. package/components/controls/phi-table-control.d.ts +3 -0
  22. package/components/controls/phi-table-control.js +13 -1
  23. package/components/controls/phi-text-control.js +57 -3
  24. package/components/controls/phi-tree-control.js +4 -4
  25. package/components/controls/phi-truncated-hover-text.d.ts +15 -0
  26. package/components/controls/phi-truncated-hover-text.js +25 -0
  27. package/components/forms/link-target-form-control.d.ts +1 -1
  28. package/components/forms/link-target-form-control.js +2 -45
  29. package/components/forms/phi-form-widget-frame.js +4 -2
  30. package/components/forms/shared-form-provider-registry.js +1 -4
  31. package/components/layouts/clients/phi-three-column-layout-client.js +10 -1
  32. package/components/media/asset-collection-runtime.js +6 -16
  33. package/components/media/media-font-metrics.d.ts +3 -0
  34. package/components/media/media-font-metrics.js +43 -0
  35. package/components/media/phi-area-upload-widget.js +53 -97
  36. package/components/media/phi-image-preview-data.d.ts +13 -0
  37. package/components/media/phi-image-preview-data.js +184 -9
  38. package/components/media/phi-media-picker-binding.js +16 -13
  39. package/components/media/phi-media-upload.d.ts +15 -8
  40. package/components/media/phi-media-upload.js +18 -9
  41. package/components/media/phi-site-font-assets.js +7 -8
  42. package/components/navigation/phi-link.js +6 -1
  43. package/components/overlays/phi-overlay-container-client.js +16 -1
  44. package/components/regions/clients/cms-region-container-client.js +6 -1
  45. package/components/regions/phi-cms-region-container.js +3 -0
  46. package/components/regions/phi-cms-region-shell.d.ts +12 -1
  47. package/components/regions/phi-cms-region-shell.js +81 -19
  48. package/components/regions/presets/phi-settings-page-shell-tree.js +48 -1
  49. package/components/root/phi-config-provider.d.ts +13 -0
  50. package/components/root/phi-config-provider.js +12 -1
  51. package/components/root/phi-root-background.d.ts +7 -0
  52. package/components/root/phi-root-background.js +20 -1
  53. package/components/root/phi-root-theme-resolver.js +3 -0
  54. package/components/root/phi-shell-chrome-overlay.d.ts +12 -1
  55. package/components/root/phi-shell-chrome-overlay.js +19 -3
  56. package/components/runtime/runtime-controller-materialization.js +12 -1
  57. package/components/shell/phi-antd-icon.d.ts +1 -0
  58. package/components/shell/phi-antd-icon.js +3 -0
  59. package/components/shell/use-phi-shell-sticky-top.js +61 -16
  60. package/components/state/scoped-state-store.js +20 -3
  61. package/components/surface/phi-surface-tone.d.ts +13 -0
  62. package/components/surface/phi-surface-tone.js +21 -0
  63. package/components/tables/client/phi-table-binding.d.ts +2 -1
  64. package/components/tables/client/phi-table-binding.js +45 -21
  65. package/components/trees/client/phi-tree-binding.js +19 -11
  66. package/components/widgets/client/bullet-list-entries-editor.d.ts +26 -0
  67. package/components/widgets/client/bullet-list-entries-editor.js +109 -0
  68. package/components/widgets/client/html-editor.js +1 -1
  69. package/components/widgets/client/shared/use-page-reference-options.d.ts +17 -0
  70. package/components/widgets/client/shared/use-page-reference-options.js +57 -0
  71. package/components/widgets/config/background.d.ts +32 -1
  72. package/components/widgets/config/background.js +41 -2
  73. package/components/widgets/config/choice-shared.js +12 -13
  74. package/components/widgets/config/command-buttons.d.ts +5 -1
  75. package/components/widgets/config/command-buttons.js +38 -81
  76. package/components/widgets/config/control-signal-config.d.ts +3 -1
  77. package/components/widgets/config/control-signal-config.js +19 -17
  78. package/components/widgets/config/image-source-parser.d.ts +1 -0
  79. package/components/widgets/config/image-source-parser.js +7 -8
  80. package/components/widgets/config/mask.d.ts +6 -1
  81. package/components/widgets/config/mask.js +24 -1
  82. package/components/widgets/config/parser-primitives.js +72 -0
  83. package/components/widgets/config/stack-tabs.d.ts +1 -1
  84. package/components/widgets/config/stack-tabs.js +2 -3
  85. package/components/widgets/config/strict-config-reader.d.ts +40 -0
  86. package/components/widgets/config/strict-config-reader.js +174 -0
  87. package/components/widgets/label-sets/background.js +2 -0
  88. package/components/widgets/label-sets/effects.js +2 -0
  89. package/components/widgets/label-types/background.d.ts +1 -0
  90. package/components/widgets/label-types/background.js +1 -0
  91. package/components/widgets/label-types/effects.d.ts +1 -0
  92. package/components/widgets/label-types/effects.js +1 -0
  93. package/components/widgets/navigation-descriptor-resolver.server.js +20 -8
  94. package/components/widgets/shared/bullet-list-vocabulary.d.ts +27 -1
  95. package/components/widgets/shared/bullet-list-vocabulary.js +24 -4
  96. package/components/widgets/shared/card-body-client.d.ts +18 -4
  97. package/components/widgets/shared/card-body-client.js +126 -26
  98. package/components/widgets/shared/card-vocabulary.d.ts +31 -4
  99. package/components/widgets/shared/card-vocabulary.js +35 -2
  100. package/components/widgets/shared/markdown-body-client.js +39 -10
  101. package/components/widgets/signals/control-signal-capabilities.d.ts +0 -18
  102. package/components/widgets/signals/control-signal-capabilities.js +10 -22
  103. package/components/workspace/catalog-store.d.ts +4 -3
  104. package/components/workspace/catalog-store.js +6 -5
  105. package/gateway/dashboard-cards-route.js +1 -0
  106. package/gateway/internal-references.d.ts +6 -1
  107. package/gateway/internal-references.js +48 -23
  108. package/gateway/site-cms-write-validation.d.ts +9 -0
  109. package/gateway/site-cms-write-validation.js +78 -0
  110. package/gateway/site-proxy.js +19 -3
  111. package/helpers/cms-container-chrome.js +6 -1
  112. package/helpers/locale.d.ts +8 -0
  113. package/helpers/locale.js +18 -0
  114. package/helpers/renderable-block-serialization.js +1 -1
  115. package/helpers/shell-region-style.js +2 -1
  116. package/helpers/surface-style.d.ts +12 -1
  117. package/helpers/surface-style.js +28 -2
  118. package/module-dashboard-cards.d.ts +1 -1
  119. package/module-dashboard-cards.js +1 -1
  120. package/next/config.d.mts +3 -0
  121. package/next/config.mjs +28 -1
  122. package/package.json +2 -2
  123. package/plugins/runtime/phi-slot-child-viewport-effects-observer.js +5 -1
  124. package/plugins/runtime-modules/accounting/presets.d.ts +9 -0
  125. package/plugins/runtime-modules/accounting/presets.js +37 -0
  126. package/plugins/runtime-modules/accounting/server.d.ts +1 -4
  127. package/plugins/runtime-modules/accounting/server.js +4 -7
  128. package/plugins/runtime-modules/app/presets.d.ts +18 -0
  129. package/plugins/runtime-modules/app/presets.js +67 -0
  130. package/plugins/runtime-modules/app/server.d.ts +1 -4
  131. package/plugins/runtime-modules/app/server.js +4 -7
  132. package/plugins/runtime-modules/area-definitions.d.ts +0 -42
  133. package/plugins/runtime-modules/area-definitions.js +3 -8
  134. package/plugins/runtime-modules/asset/controller/runtime.js +2 -2
  135. package/plugins/runtime-modules/asset/services/collection.js +9 -1
  136. package/plugins/runtime-modules/asset/services/options.js +2 -2
  137. package/plugins/runtime-modules/builder/area-settings-answer.js +2 -1
  138. package/plugins/runtime-modules/builder/authoring-canvas.js +6 -6
  139. package/plugins/runtime-modules/builder/cards.js +3 -5
  140. package/plugins/runtime-modules/builder/clients/builder-region-overrides.js +3 -3
  141. package/plugins/runtime-modules/builder/clients/canvas-widget.js +15 -54
  142. package/plugins/runtime-modules/builder/clients/inspector-config-field.d.ts +4 -1
  143. package/plugins/runtime-modules/builder/clients/inspector-config-field.js +25 -35
  144. package/plugins/runtime-modules/builder/clients/inspector-link-target-field.js +1 -1
  145. package/plugins/runtime-modules/builder/clients/inspector-section-widget.js +8 -8
  146. package/plugins/runtime-modules/builder/clients/inspector-title.js +6 -6
  147. package/plugins/runtime-modules/builder/clients/layout-inspector.d.ts +1 -1
  148. package/plugins/runtime-modules/builder/clients/layout-inspector.js +11 -25
  149. package/plugins/runtime-modules/builder/clients/layout-scaffold-overlays.js +10 -5
  150. package/plugins/runtime-modules/builder/clients/mode-switch.js +1 -1
  151. package/plugins/runtime-modules/builder/clients/pages-header.js +11 -11
  152. package/plugins/runtime-modules/builder/clients/pages-workspace.js +1 -1
  153. package/plugins/runtime-modules/builder/clients/region-visibility-fields.js +1 -1
  154. package/plugins/runtime-modules/builder/clients/runtime-module-authoring-boundary.js +1 -1
  155. package/plugins/runtime-modules/builder/clients/shells-workspace.js +15 -31
  156. package/plugins/runtime-modules/builder/clients/structure-canvas.js +1 -1
  157. package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.d.ts +26 -0
  158. package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.js +36 -0
  159. package/plugins/runtime-modules/builder/clients/widget-effects-editor.js +1 -1
  160. package/plugins/runtime-modules/builder/clients/widget-inspector.js +1 -0
  161. package/plugins/runtime-modules/builder/clients/workspace-scope-boundary.js +2 -2
  162. package/plugins/runtime-modules/builder/cms-instance-allocator.js +8 -28
  163. package/plugins/runtime-modules/builder/controller/client.d.ts +0 -15
  164. package/plugins/runtime-modules/builder/controller/definition.d.ts +0 -15
  165. package/plugins/runtime-modules/builder/controller/definition.js +0 -8
  166. package/plugins/runtime-modules/builder/controller/draft-command-controller.d.ts +1 -2
  167. package/plugins/runtime-modules/builder/controller/draft-command-controller.js +11 -30
  168. package/plugins/runtime-modules/builder/controller/draft-status-controller.js +15 -2
  169. package/plugins/runtime-modules/builder/controller/inspector-controller.d.ts +1 -2
  170. package/plugins/runtime-modules/builder/controller/inspector-controller.js +4 -7
  171. package/plugins/runtime-modules/builder/controller/page-controller.d.ts +1 -2
  172. package/plugins/runtime-modules/builder/controller/page-controller.js +16 -68
  173. package/plugins/runtime-modules/builder/controller/server-definition.d.ts +0 -15
  174. package/plugins/runtime-modules/builder/controller/signal-wiring-controller.d.ts +2 -5
  175. package/plugins/runtime-modules/builder/controller/signal-wiring-controller.js +6 -50
  176. package/plugins/runtime-modules/builder/controller/workspace-controller.d.ts +2 -3
  177. package/plugins/runtime-modules/builder/controller/workspace-controller.js +89 -153
  178. package/plugins/runtime-modules/builder/data-providers.d.ts +1 -0
  179. package/plugins/runtime-modules/builder/data-providers.js +1 -0
  180. package/plugins/runtime-modules/builder/definition.d.ts +1 -0
  181. package/plugins/runtime-modules/builder/developer-workspace-store.d.ts +64 -30
  182. package/plugins/runtime-modules/builder/developer-workspace-store.js +255 -61
  183. package/plugins/runtime-modules/builder/edit-scaffold-drawer.js +4 -3
  184. package/plugins/runtime-modules/builder/history.d.ts +3 -1
  185. package/plugins/runtime-modules/builder/options-providers.js +3 -2
  186. package/plugins/runtime-modules/builder/page-catalog-client.js +19 -7
  187. package/plugins/runtime-modules/builder/page-meta-form.js +1 -0
  188. package/plugins/runtime-modules/builder/page-references-provider.js +1 -1
  189. package/plugins/runtime-modules/builder/persistence.js +33 -69
  190. package/plugins/runtime-modules/builder/public-route-collisions.d.ts +2 -2
  191. package/plugins/runtime-modules/builder/public-route-collisions.js +6 -19
  192. package/plugins/runtime-modules/builder/render-root-node-preview.server.js +20 -3
  193. package/plugins/runtime-modules/builder/render-root-node-scaffold.js +28 -18
  194. package/plugins/runtime-modules/builder/runtime-module-selection.d.ts +2 -12
  195. package/plugins/runtime-modules/builder/runtime-module-selection.js +16 -42
  196. package/plugins/runtime-modules/builder/services/navigation-table.js +9 -15
  197. package/plugins/runtime-modules/builder/services/page-source-tree.js +8 -8
  198. package/plugins/runtime-modules/builder/services/runtime-modules-table.js +10 -10
  199. package/plugins/runtime-modules/builder/services/signal-routes-table.js +3 -3
  200. package/plugins/runtime-modules/builder/signal-route-selection.d.ts +1 -2
  201. package/plugins/runtime-modules/builder/signal-route-selection.js +2 -2
  202. package/plugins/runtime-modules/builder/signal-wiring-options.js +3 -2
  203. package/plugins/runtime-modules/builder/structure-dnd.js +8 -61
  204. package/plugins/runtime-modules/builder/trees/phi-default-builder-area-preset-tree.js +17 -10
  205. package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +27 -22
  206. package/plugins/runtime-modules/builder/workspace-catalog-actions.d.ts +55 -0
  207. package/plugins/runtime-modules/builder/workspace-catalog-actions.js +142 -0
  208. package/plugins/runtime-modules/client-authoring-module.d.ts +8 -1
  209. package/plugins/runtime-modules/client-authoring-module.js +13 -3
  210. package/plugins/runtime-modules/client-manifests/common.js +1 -1
  211. package/plugins/runtime-modules/{runtime-calendar-adapters.js → core/calendar-adapters.js} +2 -2
  212. package/plugins/runtime-modules/{client-calendar-adapters/core.js → core/client-calendar-adapters.js} +1 -1
  213. package/plugins/runtime-modules/core/content-entries/table.js +1 -1
  214. package/plugins/runtime-modules/core/data-providers.d.ts +3 -0
  215. package/plugins/runtime-modules/core/data-providers.js +2 -1
  216. package/plugins/runtime-modules/core/definition.d.ts +3 -0
  217. package/plugins/runtime-modules/core/definition.js +1 -1
  218. package/plugins/runtime-modules/core/messaging/data-providers.d.ts +1 -0
  219. package/plugins/runtime-modules/core/messaging/data-providers.js +1 -0
  220. package/plugins/runtime-modules/core/messaging/thread-inbox-table.js +1 -1
  221. package/plugins/runtime-modules/core/server.js +1 -1
  222. package/plugins/runtime-modules/core/themes.d.ts +44 -0
  223. package/plugins/runtime-modules/core/themes.js +12 -0
  224. package/plugins/runtime-modules/core/widgets/brand/client.d.ts +12 -3
  225. package/plugins/runtime-modules/core/widgets/brand/client.js +3 -11
  226. package/plugins/runtime-modules/core/widgets/brand/home.d.ts +15 -0
  227. package/plugins/runtime-modules/core/widgets/brand/home.js +18 -0
  228. package/plugins/runtime-modules/core/widgets/brand/plugin.js +3 -2
  229. package/plugins/runtime-modules/core/widgets/brand/server.d.ts +2 -2
  230. package/plugins/runtime-modules/core/widgets/brand/server.js +2 -2
  231. package/plugins/runtime-modules/core/widgets/card/collection-view-binding.js +25 -9
  232. package/plugins/runtime-modules/core/widgets/card/config.d.ts +301 -254
  233. package/plugins/runtime-modules/core/widgets/card/config.js +68 -3
  234. package/plugins/runtime-modules/core/widgets/card/editor.js +41 -4
  235. package/plugins/runtime-modules/core/widgets/card/server.d.ts +3 -0
  236. package/plugins/runtime-modules/core/widgets/card/server.js +32 -3
  237. package/plugins/runtime-modules/core/widgets/collection-view/asset-binding.js +7 -6
  238. package/plugins/runtime-modules/core/widgets/collection-view/config.js +9 -2
  239. package/plugins/runtime-modules/core/widgets/description/client.js +3 -3
  240. package/plugins/runtime-modules/core/widgets/description/config.d.ts +2 -25
  241. package/plugins/runtime-modules/core/widgets/description/editor.js +7 -63
  242. package/plugins/runtime-modules/core/widgets/description/server.js +3 -2
  243. package/plugins/runtime-modules/core/widgets/entry-list/config.d.ts +2 -25
  244. package/plugins/runtime-modules/core/widgets/gallery/config.d.ts +2 -25
  245. package/plugins/runtime-modules/core/widgets/header-navigation/client.js +2 -2
  246. package/plugins/runtime-modules/core/widgets/html/client.js +1 -1
  247. package/plugins/runtime-modules/core/widgets/image/config.js +2 -2
  248. package/plugins/runtime-modules/core/widgets/markdown/config.d.ts +320 -2
  249. package/plugins/runtime-modules/core/widgets/markdown/config.js +18 -4
  250. package/plugins/runtime-modules/core/widgets/markdown/editor.js +11 -4
  251. package/plugins/runtime-modules/core/widgets/markdown-toc/client.js +6 -1
  252. package/plugins/runtime-modules/core/widgets/markdown-toc/config.d.ts +14 -0
  253. package/plugins/runtime-modules/core/widgets/markdown-toc/config.js +14 -2
  254. package/plugins/runtime-modules/core/widgets/quick-links/authoring.js +7 -2
  255. package/plugins/runtime-modules/core/widgets/quick-links/client.js +2 -2
  256. package/plugins/runtime-modules/core/widgets/quick-links/items.d.ts +0 -2
  257. package/plugins/runtime-modules/core/widgets/quick-links/items.js +0 -15
  258. package/plugins/runtime-modules/core/widgets/result/config.d.ts +5 -25
  259. package/plugins/runtime-modules/core/widgets/result/config.js +2 -0
  260. package/plugins/runtime-modules/core/widgets/result/server.js +25 -19
  261. package/plugins/runtime-modules/core/widgets/sidebar-navigation/authoring.js +1 -1
  262. package/plugins/runtime-modules/core/widgets/sidebar-navigation/client.js +1 -1
  263. package/plugins/runtime-modules/core/widgets/simple-text/client.js +8 -3
  264. package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +2 -25
  265. package/plugins/runtime-modules/core/widgets/simple-text/editor.js +2 -2
  266. package/plugins/runtime-modules/core/widgets/slot-upload/client.js +11 -2
  267. package/plugins/runtime-modules/core/widgets/table/client.js +8 -4
  268. package/plugins/runtime-modules/core/widgets/table/config.d.ts +6 -83
  269. package/plugins/runtime-modules/core/widgets/table/config.js +302 -452
  270. package/plugins/runtime-modules/core/widgets/tree/config.js +5 -2
  271. package/plugins/runtime-modules/dashboard/card-rows.d.ts +7 -0
  272. package/plugins/runtime-modules/dashboard/card-rows.js +87 -0
  273. package/plugins/runtime-modules/dashboard/clients/dashboard-card-view.js +32 -12
  274. package/plugins/runtime-modules/dashboard/services/collection.js +17 -7
  275. package/plugins/runtime-modules/dashboard/trees/phi-default-builder-dashboard-page-tree.js +5 -40
  276. package/plugins/runtime-modules/groups/data-providers.d.ts +2 -0
  277. package/plugins/runtime-modules/groups/data-providers.js +3 -3
  278. package/plugins/runtime-modules/groups/definition.d.ts +2 -0
  279. package/plugins/runtime-modules/localization/data-providers.d.ts +3 -0
  280. package/plugins/runtime-modules/localization/data-providers.js +2 -0
  281. package/plugins/runtime-modules/localization/definition.d.ts +3 -0
  282. package/plugins/runtime-modules/localization/services/table.js +3 -7
  283. package/plugins/runtime-modules/observability/data-providers.d.ts +1 -0
  284. package/plugins/runtime-modules/observability/data-providers.js +1 -0
  285. package/plugins/runtime-modules/observability/definition.d.ts +1 -0
  286. package/plugins/runtime-modules/observability/module.d.ts +1 -0
  287. package/plugins/runtime-modules/observability/services/table.js +1 -1
  288. package/plugins/runtime-modules/phi-default-site-area-preset-tree.js +2 -105
  289. package/plugins/runtime-modules/public/presets.d.ts +115 -0
  290. package/plugins/runtime-modules/{area-base-presets.js → public/presets.js} +19 -119
  291. package/plugins/runtime-modules/public/server.d.ts +1 -4
  292. package/plugins/runtime-modules/public/server.js +4 -7
  293. package/plugins/runtime-modules/public/trees/phi-default-pub-error-page-tree.js +7 -8
  294. package/plugins/runtime-modules/public-base-page-references.d.ts +1 -1
  295. package/plugins/runtime-modules/public-base-page-references.js +1 -1
  296. package/plugins/runtime-modules/revisions/controller/client.js +11 -11
  297. package/plugins/runtime-modules/revisions/services/table.js +3 -3
  298. package/plugins/runtime-modules/theme/trees/phi-default-builder-theme-page-tree.js +22 -0
  299. package/plugins/runtime-modules/theme/widgets/brand-controls/client.d.ts +2 -1
  300. package/plugins/runtime-modules/theme/widgets/brand-controls/client.js +111 -72
  301. package/plugins/runtime-modules/theme/widgets/brand-controls/config.d.ts +2 -1
  302. package/plugins/runtime-modules/theme/widgets/brand-controls/config.js +28 -31
  303. package/plugins/runtime-modules/theme/widgets/brand-controls/plugin.js +1 -1
  304. package/plugins/runtime-modules/theme-descriptors.js +1 -1
  305. package/plugins/runtime-modules/user-management/data-providers.d.ts +2 -0
  306. package/plugins/runtime-modules/user-management/data-providers.js +1 -0
  307. package/plugins/runtime-modules/user-management/definition.d.ts +2 -0
  308. package/server-helpers/cms-link-targets.js +6 -0
  309. package/styles/control-shape.css +11 -11
  310. package/styles/controls.css +67 -5
  311. package/styles/layout.css +61 -9
  312. package/styles/shell.css +73 -0
  313. package/theme/phi-antd-token-resolver.js +20 -1
  314. package/theme/phi-theme-tokens.d.ts +1 -1
  315. package/theme/phi-theme-tokens.js +1 -0
  316. package/theme/phi-theme.d.ts +5 -0
  317. package/theme/phi-theme.js +21 -0
  318. package/theme/phi-tokens.d.ts +16 -15
  319. package/theme/phi-tokens.js +16 -15
  320. package/types/cms-config.js +142 -185
  321. package/types/cms-plugins.d.ts +6 -11
  322. package/types/core-widget-placements.d.ts +14 -3
  323. package/types/dashboard-cards.d.ts +48 -4
  324. package/types/dashboard-cards.js +6 -0
  325. package/types/media.d.ts +0 -3
  326. package/types/renderable-block.d.ts +6 -1
  327. package/types/site-theme.d.ts +10 -2
  328. package/types/table-widget.d.ts +9 -0
  329. package/types/table-widget.js +20 -0
  330. package/types.d.ts +1 -1
  331. package/widget-config.d.ts +2 -0
  332. package/widget-config.js +6 -0
  333. package/plugins/runtime-modules/area-base-presets.d.ts +0 -139
  334. /package/plugins/runtime-modules/{runtime-calendar-adapters.d.ts → core/calendar-adapters.d.ts} +0 -0
  335. /package/plugins/runtime-modules/{client-calendar-adapters/core.d.ts → core/client-calendar-adapters.d.ts} +0 -0
@@ -0,0 +1,67 @@
1
+ import { PHI_BASE_PAGE_LAYOUT_VERSION } from "../../../components/regions/presets/phi-base-page-layout";
2
+ import { buildPhiAreaRootRoutePresetDescriptor } from "../area-root-route";
3
+ import { PHI_APP_RUNTIME_MODULE_ID } from "./ids";
4
+ /* What the App base Module brings: its Area shell, the Area root and the profile Page. */
5
+ export const PHI_APP_RUNTIME_MODULE_AREA_SHELLS = [
6
+ {
7
+ ownerModuleId: PHI_APP_RUNTIME_MODULE_ID,
8
+ presetKey: "app-area-preset",
9
+ shellPresetVersion: 1,
10
+ area: "app",
11
+ /*
12
+ * The Site shell with a left sider added, rather than a shell of its own.
13
+ *
14
+ * App's header and footer are Public's -- one Brand, one account trigger, one description of both.
15
+ * What App has that Public does not is somewhere for the Modules a signed-in person works with,
16
+ * and that is the whole of the overlay. Nothing is omitted from the base, so the two trees cannot
17
+ * disagree about a Region: composition refuses a Region type stated twice.
18
+ */
19
+ loadTree: async ({ page, runtime }) => {
20
+ const [{ buildPhiDefaultSiteAreaPresetTree }, { buildPhiDefaultAppAreaPresetTree }, { mergePhiCmsShellTrees },] = await Promise.all([
21
+ import("../phi-default-site-area-preset-tree"),
22
+ import("./trees/phi-default-app-area-preset-tree"),
23
+ import("../shell-tree-composition"),
24
+ ]);
25
+ const [base, overlay] = await Promise.all([
26
+ buildPhiDefaultSiteAreaPresetTree({
27
+ page,
28
+ runtime,
29
+ presetKey: "app-area-preset",
30
+ ownerModuleId: PHI_APP_RUNTIME_MODULE_ID,
31
+ runtimeModuleArea: "app",
32
+ }),
33
+ buildPhiDefaultAppAreaPresetTree({ page, runtime }),
34
+ ]);
35
+ return mergePhiCmsShellTrees(base, overlay);
36
+ },
37
+ },
38
+ ];
39
+ export const PHI_APP_RUNTIME_MODULE_ROUTES = [
40
+ buildPhiAreaRootRoutePresetDescriptor({
41
+ ownerModuleId: PHI_APP_RUNTIME_MODULE_ID,
42
+ area: "app",
43
+ title: "App",
44
+ }),
45
+ /*
46
+ * What a person has settled about their own account: their name, the language they read in.
47
+ *
48
+ * It sat with the Auth Module, which owned the route while Core owned every Widget on it. Nothing
49
+ * about a name or a language depends on how somebody signs in -- a Site that switches to a
50
+ * directory, or switches Auth off while sessions keep working, would have lost the Page that says
51
+ * what they are called. AUTHENTICATION.md section 5 already said so: profile administration does
52
+ * not become Auth's merely by appearing in its menu.
53
+ *
54
+ * The Area's own Settings child, so it is declared here rather than injected -- SETTINGS.md section
55
+ * 5, the same standing Admin and Builder give their General page.
56
+ */
57
+ {
58
+ ownerModuleId: PHI_APP_RUNTIME_MODULE_ID,
59
+ presetKey: "app-profile-page",
60
+ presetVersion: 1 + PHI_BASE_PAGE_LAYOUT_VERSION,
61
+ area: "app",
62
+ title: "Profile",
63
+ path: "/settings/profile",
64
+ loadTree: ({ page, runtime }) => import("./trees/phi-default-app-profile-page-tree")
65
+ .then((module) => module.buildPhiDefaultAppProfilePageTree({ page, runtime })),
66
+ },
67
+ ];
@@ -1,5 +1,2 @@
1
- /**
2
- * The unselectable base module of its Area. Shells and routes come from the shared Area-base preset
3
- * list and are filtered by owner, so each base module states its own half of it.
4
- */
1
+ /** The unselectable base module of its Area. Its shell and Pages are its own (`./presets`). */
5
2
  export declare const PHI_APP_RUNTIME_MODULE_SERVER_AREA_CONTRIBUTION: import("../area-contributions").PhiRuntimeModuleServerAreaContribution;
@@ -1,11 +1,8 @@
1
- import { PHI_AREA_BASE_RUNTIME_MODULE_AREA_SHELLS, PHI_AREA_BASE_RUNTIME_MODULE_ROUTES, } from "../area-base-presets";
1
+ import { PHI_APP_RUNTIME_MODULE_AREA_SHELLS, PHI_APP_RUNTIME_MODULE_ROUTES, } from "./presets";
2
2
  import { definePhiRuntimeModuleServerAreaContribution } from "../area-contributions";
3
3
  import { PHI_APP_RUNTIME_MODULE_DEFINITION } from "../app/definition";
4
4
  import { PHI_APP_RUNTIME_MODULE_FORMS } from "./forms";
5
- /**
6
- * The unselectable base module of its Area. Shells and routes come from the shared Area-base preset
7
- * list and are filtered by owner, so each base module states its own half of it.
8
- */
5
+ /** The unselectable base module of its Area. Its shell and Pages are its own (`./presets`). */
9
6
  export const PHI_APP_RUNTIME_MODULE_SERVER_AREA_CONTRIBUTION = definePhiRuntimeModuleServerAreaContribution({
10
7
  moduleId: PHI_APP_RUNTIME_MODULE_DEFINITION.moduleId,
11
8
  catalogEntry: {
@@ -13,8 +10,8 @@ export const PHI_APP_RUNTIME_MODULE_SERVER_AREA_CONTRIBUTION = definePhiRuntimeM
13
10
  widgets: [],
14
11
  forms: PHI_APP_RUNTIME_MODULE_FORMS,
15
12
  layouts: [],
16
- areaShells: PHI_AREA_BASE_RUNTIME_MODULE_AREA_SHELLS.filter((descriptor) => descriptor.ownerModuleId === PHI_APP_RUNTIME_MODULE_DEFINITION.moduleId),
17
- routes: PHI_AREA_BASE_RUNTIME_MODULE_ROUTES.filter((descriptor) => descriptor.ownerModuleId === PHI_APP_RUNTIME_MODULE_DEFINITION.moduleId),
13
+ areaShells: PHI_APP_RUNTIME_MODULE_AREA_SHELLS,
14
+ routes: PHI_APP_RUNTIME_MODULE_ROUTES,
18
15
  load: () => import("./module").then((module) => module.PHI_APP_RUNTIME_MODULE),
19
16
  },
20
17
  });
@@ -34,20 +34,6 @@ export declare const PHI_PUBLIC_RUNTIME_AREA_DEFINITIONS: {
34
34
  readonly routePresetKey: "public-terms-page";
35
35
  }];
36
36
  readonly exportedItemKeys: readonly ["@phis/ui/modules/public/nav/terms"];
37
- }, {
38
- readonly navKey: "public:quicklinks";
39
- readonly label: {
40
- defaultMessage: string;
41
- };
42
- readonly items: readonly [{
43
- readonly itemKey: "@phis/ui/modules/public/nav/terms";
44
- readonly label: {
45
- defaultMessage: string;
46
- };
47
- readonly icon: "antd:file-text";
48
- readonly routePresetKey: "public-terms-page";
49
- }];
50
- readonly exportedItemKeys: readonly ["@phis/ui/modules/public/nav/terms"];
51
37
  }, PhiCmsNavigationSurfaceDescriptor];
52
38
  }[];
53
39
  export declare const PHI_APP_ACCOUNT_NAV_ITEM_KEY = "@phis/ui/modules/app/nav/account";
@@ -226,20 +212,6 @@ export declare const PHI_ALL_RUNTIME_AREA_DEFINITIONS: ({
226
212
  readonly routePresetKey: "public-terms-page";
227
213
  }];
228
214
  readonly exportedItemKeys: readonly ["@phis/ui/modules/public/nav/terms"];
229
- }, {
230
- readonly navKey: "public:quicklinks";
231
- readonly label: {
232
- defaultMessage: string;
233
- };
234
- readonly items: readonly [{
235
- readonly itemKey: "@phis/ui/modules/public/nav/terms";
236
- readonly label: {
237
- defaultMessage: string;
238
- };
239
- readonly icon: "antd:file-text";
240
- readonly routePresetKey: "public-terms-page";
241
- }];
242
- readonly exportedItemKeys: readonly ["@phis/ui/modules/public/nav/terms"];
243
215
  }, PhiCmsNavigationSurfaceDescriptor];
244
216
  } | {
245
217
  area: "app";
@@ -457,20 +429,6 @@ export declare function resolvePhiRuntimeAreaDefinition(area: PhiCmsAreaDefiniti
457
429
  readonly routePresetKey: "public-terms-page";
458
430
  }];
459
431
  readonly exportedItemKeys: readonly ["@phis/ui/modules/public/nav/terms"];
460
- }, {
461
- readonly navKey: "public:quicklinks";
462
- readonly label: {
463
- defaultMessage: string;
464
- };
465
- readonly items: readonly [{
466
- readonly itemKey: "@phis/ui/modules/public/nav/terms";
467
- readonly label: {
468
- defaultMessage: string;
469
- };
470
- readonly icon: "antd:file-text";
471
- readonly routePresetKey: "public-terms-page";
472
- }];
473
- readonly exportedItemKeys: readonly ["@phis/ui/modules/public/nav/terms"];
474
432
  }, PhiCmsNavigationSurfaceDescriptor];
475
433
  } | {
476
434
  area: "app";
@@ -116,8 +116,9 @@ function sidebarAnchors(settingsItemKey) {
116
116
  * The Public surfaces carry one intrinsic entry, the terms, and export it as the one anchor.
117
117
  *
118
118
  * The terms are Core's, so their entry is; the contact entry hangs after it, and a Site package's
119
- * landing places its Home entry before it. Public has no sidebar surface: the Public Shell draws a
120
- * header and a footer, and a surface nothing renders is a promise nobody can see kept.
119
+ * landing places its Home entry before it. Public has no sidebar and no quick-links surface: the Public
120
+ * Shell draws a header and a footer -- the footer's Quick Links Widget reads `public:footer` -- and a
121
+ * surface nothing renders is a promise nobody can see kept.
121
122
  */
122
123
  const publicTermsItem = {
123
124
  itemKey: "@phis/ui/modules/public/nav/terms",
@@ -138,12 +139,6 @@ const publicNavigationSurfaces = [
138
139
  items: [publicTermsItem],
139
140
  exportedItemKeys: [publicTermsItem.itemKey],
140
141
  },
141
- {
142
- navKey: "public:quicklinks",
143
- label: label("Public quick links"),
144
- items: [publicTermsItem],
145
- exportedItemKeys: [publicTermsItem.itemKey],
146
- },
147
142
  accountNavigationSurface(PHI_PUBLIC_ACCOUNT_NAV_ITEM_KEY, "public:account"),
148
143
  ];
149
144
  export const PHI_PUBLIC_RUNTIME_AREA_DEFINITIONS = [
@@ -271,11 +271,11 @@ export function usePhiAssetRuntimeController({ address, mountScope, config, }) {
271
271
  value: {
272
272
  page: state.page,
273
273
  pageSize: state.pageSize,
274
- total: state.pagination?.total ?? state.assets.length,
274
+ total: state.pagination?.total ?? 0,
275
275
  },
276
276
  receiver: "broadcast",
277
277
  timestamp: Date.now(),
278
278
  });
279
- }, [emitAssetSignal, mountScope, state.assets.length, state.page, state.pageSize, state.pagination?.total]);
279
+ }, [emitAssetSignal, mountScope, state.page, state.pageSize, state.pagination?.total]);
280
280
  return state;
281
281
  }
@@ -62,10 +62,18 @@ async function queryMediaCollection(request) {
62
62
  signal: request.signal,
63
63
  });
64
64
  const payload = await readPhiImagePreviewResponse(response);
65
+ /*
66
+ * The server counts the listing on every read (`pagination.total`), and the paging below is drawn
67
+ * from it. Without it the count is unknown, which the assets of one page would only pretend to answer.
68
+ */
69
+ const total = payload.pagination?.total;
70
+ if (typeof total !== "number" || !Number.isFinite(total) || total < 0) {
71
+ throw new Error("The media listing answered no total.");
72
+ }
65
73
  return {
66
74
  resourceKey: request.resourceKey,
67
75
  items: payload.assets.map((asset) => ({ ...asset })),
68
- total: payload.pagination?.total ?? payload.assets.length,
76
+ total,
69
77
  loading: false,
70
78
  error: null,
71
79
  meta: {
@@ -2,6 +2,7 @@
2
2
  import { isPhiRecord } from "../../../../helpers/is-record";
3
3
  import { createPhiControlOptionsProviderClient, } from "../../../../components/controls/phi-options-provider";
4
4
  import { PHI_ASSET_RUNTIME_DATA_PROVIDER_KEYS } from "../ids";
5
+ import { readPhiMediaFolders } from "../../../../components/media/phi-image-preview-data";
5
6
  import { PHI_ASSET_CONTROLLER_STORE_KEY } from "../../../../components/media/asset-controller-signals";
6
7
  import { phiImagePreviewStore } from "../../../../components/media/phi-image-preview-store";
7
8
  import { buildPhiMediaFolderCascaderOptions, buildPhiMediaFolderNamesById, buildPhiMediaFolderValueById, } from "../../../../components/media/media-folder-options";
@@ -59,8 +60,7 @@ async function loadFolders() {
59
60
  const payload = await response.json().catch(() => null);
60
61
  if (!response.ok)
61
62
  throw new Error("Failed to load the Site's media folders.");
62
- const folders = isPhiRecord(payload) && Array.isArray(payload.folders) ? payload.folders : [];
63
- return folders.filter(isPhiRecord);
63
+ return readPhiMediaFolders(isPhiRecord(payload) ? payload.folders : undefined, "The media folders route");
64
64
  }
65
65
  export const PhiMediaFolderChoicesOptionsProviderClient = createPhiControlOptionsProviderClient({
66
66
  key: PHI_ASSET_RUNTIME_DATA_PROVIDER_KEYS.mediaFolderChoices,
@@ -1,3 +1,4 @@
1
+ import { PHI_WORKSPACE_CATALOG_SCOPE } from "../../../components/workspace/catalog-store";
1
2
  import { PHI_AREA_META_PUBLIC_DEFAULTS, } from "../../../helpers/cms-area-config";
2
3
  import { isPhiRecord } from "../../../helpers/is-record";
3
4
  import { builderWorkspaceStore, readPhiBuilderEffectiveAreaMeta, readPhiBuilderEffectiveAreaRootRoute, restorePhiDeveloperBuilderAreaMeta, setPhiDeveloperBuilderAreaRootRoute, } from "./developer-workspace-store";
@@ -54,7 +55,7 @@ function isSamePhiBuilderAreaAnswer(left, right) {
54
55
  * unsaved. `rootRoute` is `undefined` when the dialog did not ask it.
55
56
  */
56
57
  export function applyPhiBuilderAreaSettingsAnswer({ area, historyContext, rootRoute, meta, }) {
57
- const current = builderWorkspaceStore.getSnapshot("public");
58
+ const current = builderWorkspaceStore.getSnapshot(PHI_WORKSPACE_CATALOG_SCOPE);
58
59
  const before = [];
59
60
  const after = [];
60
61
  if (rootRoute !== undefined && !isSamePhiBuilderAreaAnswer(readPhiBuilderEffectiveAreaRootRoute(current, area), rootRoute)) {
@@ -13,12 +13,12 @@ import { getPhiBuilderNavigationDraftSnapshot } from "./navigation-store";
13
13
  * learn which Area they are being edited in.
14
14
  */
15
15
  export function usePhiBuilderAuthoringCanvas() {
16
- const area = usePhiDeveloperBuilderStateValue("public", (state) => state.area);
17
- const catalogHydrated = usePhiDeveloperBuilderStateValue("public", (state) => state.catalogHydrated);
18
- const navigationSurfaces = usePhiDeveloperBuilderStateValue("public", (state) => state.navigationSurfacesByArea[state.area] ?? null);
19
- const modulePresetPagesByArea = usePhiDeveloperBuilderStateValue("public", (state) => state.modulePresetPagesByArea);
20
- const customPages = usePhiDeveloperBuilderStateValue("public", (state) => state.customPages);
21
- const persistedPageCatalogByArea = usePhiDeveloperBuilderStateValue("public", (state) => state.persistedPageCatalogByArea);
16
+ const area = usePhiDeveloperBuilderStateValue((state) => state.area);
17
+ const catalogHydrated = usePhiDeveloperBuilderStateValue((state) => state.catalogHydrated);
18
+ const navigationSurfaces = usePhiDeveloperBuilderStateValue((state) => state.navigationSurfacesByArea[state.area] ?? null);
19
+ const modulePresetPagesByArea = usePhiDeveloperBuilderStateValue((state) => state.modulePresetPagesByArea);
20
+ const customPages = usePhiDeveloperBuilderStateValue((state) => state.customPages);
21
+ const persistedPageCatalogByArea = usePhiDeveloperBuilderStateValue((state) => state.persistedPageCatalogByArea);
22
22
  return useMemo(() => ({
23
23
  area,
24
24
  catalogHydrated,
@@ -2,7 +2,6 @@ import "server-only";
2
2
  import { PHI_TR_CTX_WEB_UI_LABEL } from "../../../gateway/tr";
3
3
  import { definePhiRuntimeModuleLabelSet, getPhiLabelSet } from "../../../gateway/label-set";
4
4
  import { getPhiBuilderModulesPageLabels } from "../../../components/widgets/label-sets/builder-modules";
5
- import { PHI_FIRST_PARTY_RUNTIME_MODULE_CATALOG } from "../catalog";
6
5
  import { createPhiDashboardCardId, } from "../../../types/dashboard-cards";
7
6
  import { readPhiBuilderAreasWithOpenDraft } from "./area-shell-presets.server";
8
7
  import { PHI_BUILDER_RUNTIME_MODULE_ID, PHI_BUILDER_RUNTIME_MODULE_IDENTITY } from "./ids";
@@ -12,9 +11,8 @@ import { PHI_BUILDER_RUNTIME_MODULE_ID, PHI_BUILDER_RUNTIME_MODULE_IDENTITY } fr
12
11
  * The first `list` card. A structure author opening the Builder wants to know where they left off,
13
12
  * which is a set of names rather than a count -- "Public and App" says where to go, "2" does not.
14
13
  *
15
- * The Area shells are read from the first-party catalog. A provider is handed no catalog, and every
16
- * Area's shell is contributed by its first-party base Module, so the Builder's catalog and this one name
17
- * the same shell sources; a Site's own Modules add Pages, not Areas.
14
+ * The Area shells are read from the catalog of the Area the Dashboard stands in -- the Builder's, which
15
+ * carries every Area's base Module, because the Builder edits them all.
18
16
  */
19
17
  const PHI_BUILDER_DASHBOARD_CARD_LABEL_SET = definePhiRuntimeModuleLabelSet(PHI_BUILDER_RUNTIME_MODULE_IDENTITY, {
20
18
  key: "cards:builder-drafts",
@@ -59,7 +57,7 @@ export const PHI_BUILDER_RUNTIME_MODULE_DASHBOARD_CARDS = {
59
57
  const [labels, areaLabels, drafted] = await Promise.all([
60
58
  getPhiLabelSet(options, PHI_BUILDER_DASHBOARD_CARD_LABEL_SET),
61
59
  getPhiBuilderModulesPageLabels(options).then((page) => page.areas),
62
- readPhiBuilderAreasWithOpenDraft(PHI_FIRST_PARTY_RUNTIME_MODULE_CATALOG, {
60
+ readPhiBuilderAreasWithOpenDraft(context.runtimeModuleCatalog, {
63
61
  siteKey: context.siteKey,
64
62
  locale: context.locale,
65
63
  apiBaseUrl: context.apiBaseUrl,
@@ -8,9 +8,9 @@ import { PhiAuthoringRegionOverridesProvider } from "../../../../components/runt
8
8
  import { getDefaultRegionDraft, resolveRegionDraftKey } from "../developer-region-drafts";
9
9
  import { usePhiDeveloperBuilderStateValue, usePhiDeveloperRegionDrafts } from "../developer-workspace-store";
10
10
  export function PhiBuilderCanvasRegionOverrides({ children }) {
11
- const builderMode = usePhiDeveloperBuilderStateValue("public", (state) => state.builderMode);
12
- const area = usePhiDeveloperBuilderStateValue("public", (state) => state.area);
13
- const pageKey = usePhiDeveloperBuilderStateValue("public", (state) => state.pageKey);
11
+ const builderMode = usePhiDeveloperBuilderStateValue((state) => state.builderMode);
12
+ const area = usePhiDeveloperBuilderStateValue((state) => state.area);
13
+ const pageKey = usePhiDeveloperBuilderStateValue((state) => state.pageKey);
14
14
  const regionDrafts = usePhiDeveloperRegionDrafts();
15
15
  const value = useMemo(() => {
16
16
  const siderRight = resolveRegionDraftKey(regionDrafts, area, "sider_right", pageKey) ?? getDefaultRegionDraft("sider_right");
@@ -1,75 +1,36 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useMemo } from "react";
3
+ import { useMemo } from "react";
4
4
  import { PhiDeveloperBuilderStructureCanvas, } from "./structure-canvas";
5
- import { getPhiDeveloperRegionDraftsSnapshot, mergePhiDeveloperRegionDrafts, usePhiDeveloperBuilderStateValue, usePhiDeveloperRegionDraftsValue, } from "../developer-workspace-store";
5
+ import { usePhiDeveloperBuilderStateValue } from "../developer-workspace-store";
6
+ import { usePhiBuilderRegionDraftHydration } from "./use-region-draft-hydration";
6
7
  import { getPhiBuilderRegionDraftKey, PHI_BUILDER_PAGE_REGION_KEYS, PHI_BUILDER_SHELL_REGION_KEYS, } from "../region-keys";
7
8
  import { usePhiBuilderModuleMetas } from "../plugin-meta-store";
8
9
  import { buildPhiStructureRegionPickItems } from "../structure-region-pick-items";
9
10
  export function PhiDeveloperBuilderCanvasWidgetClient({ workspace, serverPreviewRegions, structureShellDraftsByArea, pageDraftsByScope, previewRegionDrafts = null, shellTheme, disabled: _disabled = false, targetArea, regionLabels, pickerLabels, }) {
10
11
  void _disabled;
11
- const area = usePhiDeveloperBuilderStateValue("public", (state) => state.area);
12
- const pageKey = usePhiDeveloperBuilderStateValue("public", (state) => state.pageKey);
13
- const builderMode = usePhiDeveloperBuilderStateValue("public", (state) => state.builderMode);
12
+ const area = usePhiDeveloperBuilderStateValue((state) => state.area);
13
+ const pageKey = usePhiDeveloperBuilderStateValue((state) => state.pageKey);
14
+ const builderMode = usePhiDeveloperBuilderStateValue((state) => state.builderMode);
14
15
  const builderModuleMetas = usePhiBuilderModuleMetas(targetArea);
15
16
  const pickItems = useMemo(() => buildPhiStructureRegionPickItems(builderModuleMetas.plugins), [builderModuleMetas.plugins]);
16
17
  const isStructureWorkspace = workspace === "structure";
17
18
  const isPagesWorkspace = workspace === "pages";
18
- /*
19
- * Which of this workspace's drafts are not in the store, as one string. The Canvas used to subscribe
20
- * to the whole draft map for this question, so every write to any draft re-rendered it and, below it,
21
- * every Region scaffold on the canvas with its whole tree. The Regions read their own draft now
22
- * (`structure-canvas.tsx`); this widget renders when the set of missing drafts changes and not before.
23
- */
24
19
  const hydrationDraftKeys = useMemo(() => (isStructureWorkspace
25
20
  ? PHI_BUILDER_SHELL_REGION_KEYS.map((regionKey) => getPhiBuilderRegionDraftKey(area, regionKey, pageKey))
26
21
  : isPagesWorkspace
27
22
  ? PHI_BUILDER_PAGE_REGION_KEYS.map((regionKey) => getPhiBuilderRegionDraftKey(area, regionKey, pageKey))
28
23
  : []), [area, isPagesWorkspace, isStructureWorkspace, pageKey]);
29
- const missingDraftKeys = usePhiDeveloperRegionDraftsValue(useCallback((drafts) => hydrationDraftKeys.filter((draftKey) => drafts[draftKey] == null).join("\u0000"), [hydrationDraftKeys]));
30
- useEffect(() => {
31
- if (!isStructureWorkspace && !isPagesWorkspace) {
32
- return;
33
- }
34
- if (builderMode === "preview" && previewRegionDrafts && Object.keys(previewRegionDrafts).length > 0) {
35
- mergePhiDeveloperRegionDrafts(previewRegionDrafts);
36
- }
37
- const regionDrafts = getPhiDeveloperRegionDraftsSnapshot();
38
- const shellDraftKeys = PHI_BUILDER_SHELL_REGION_KEYS
39
- .map((regionKey) => getPhiBuilderRegionDraftKey(area, regionKey, pageKey));
40
- const pageDraftKeys = PHI_BUILDER_PAGE_REGION_KEYS
41
- .map((regionKey) => getPhiBuilderRegionDraftKey(area, regionKey, pageKey));
42
- const needsShellHydration = isStructureWorkspace && shellDraftKeys.some((draftKey) => regionDrafts[draftKey] == null);
43
- const needsPageHydration = isPagesWorkspace &&
44
- pageDraftKeys.some((draftKey) => regionDrafts[draftKey] == null);
45
- if (needsShellHydration) {
46
- const nextShellDrafts = structureShellDraftsByArea?.[area] ?? {};
47
- const missingShellDrafts = Object.fromEntries(Object.entries(nextShellDrafts).filter(([draftKey]) => regionDrafts[draftKey] == null));
48
- if (Object.keys(missingShellDrafts).length > 0) {
49
- mergePhiDeveloperRegionDrafts(missingShellDrafts);
50
- }
51
- }
52
- if (!needsPageHydration) {
53
- return;
54
- }
55
- const nextPageDrafts = pageDraftsByScope?.[area]?.[pageKey] ?? {};
56
- const missingPageDrafts = Object.fromEntries(Object.entries(nextPageDrafts).filter(([draftKey]) => regionDrafts[draftKey] == null));
57
- if (Object.keys(missingPageDrafts).length > 0) {
58
- mergePhiDeveloperRegionDrafts(missingPageDrafts);
59
- return;
60
- }
61
- // `missingDraftKeys` is the reason to run again; the snapshot inside is what is read.
62
- }, [
63
- isPagesWorkspace,
64
- isStructureWorkspace,
65
- missingDraftKeys,
66
- pageDraftsByScope,
67
- previewRegionDrafts,
68
- area,
24
+ usePhiBuilderRegionDraftHydration({
25
+ draftKeys: hydrationDraftKeys,
26
+ serverDrafts: isStructureWorkspace
27
+ ? structureShellDraftsByArea?.[area]
28
+ : isPagesWorkspace
29
+ ? pageDraftsByScope?.[area]?.[pageKey] ?? undefined
30
+ : undefined,
69
31
  builderMode,
70
- pageKey,
71
- structureShellDraftsByArea,
72
- ]);
32
+ previewRegionDrafts: isStructureWorkspace || isPagesWorkspace ? previewRegionDrafts : null,
33
+ });
73
34
  if (isStructureWorkspace) {
74
35
  return (_jsx(PhiDeveloperBuilderStructureCanvas, { workspace: "structure", builderMode: builderMode, area: area, pageKey: pageKey, shellTheme: shellTheme, pageDraftsByScope: pageDraftsByScope, serverPreviewRegions: serverPreviewRegions, pickItems: pickItems, regionLabels: regionLabels, pickerLabels: pickerLabels }));
75
36
  }
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
+ import type { PhiBackgroundControlProps } from "../../../../components/controls/phi-background-control";
2
3
  import type { PhiCmsConfigField, PhiRuntimeModuleDataProviderDescriptor } from "../../../../types/cms-plugins";
3
4
  import type { PhiCalendarAdapterDescriptor } from "../../../../types/calendar";
4
5
  import type { PhiVideoProviderDescriptor } from "../../../../types/video";
@@ -69,7 +70,7 @@ export declare function renderPhiInspectorPaddingConfigControl({ field, config,
69
70
  onChange?: (nextPadding: PhiCmsPaddingWidgetConfig | null, patch: Record<string, unknown>) => void;
70
71
  }): import("react").JSX.Element;
71
72
  export declare function renderPhiInspectorConfigField(args: Parameters<typeof renderPhiInspectorConfigFieldBody>[0]): import("react").JSX.Element | null;
72
- declare function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config, defaultConfig, disabled, onChange, widgetReferenceOptions, paddingLabels, backgroundLabels, borderLabels, colorPickerLabels, iconPickerLabels, fieldLabels, dataProviderDescriptors, calendarAdapterDescriptors, videoProviderDescriptors, blockId, }: {
73
+ declare function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config, defaultConfig, disabled, onChange, widgetReferenceOptions, paddingLabels, backgroundLabels, borderLabels, renderMediaPicker, colorPickerLabels, iconPickerLabels, fieldLabels, dataProviderDescriptors, calendarAdapterDescriptors, videoProviderDescriptors, blockId, }: {
73
74
  field: PhiCmsConfigField;
74
75
  value: unknown;
75
76
  defaultValue: unknown;
@@ -82,6 +83,8 @@ declare function renderPhiInspectorConfigFieldBody({ field, value, defaultValue,
82
83
  paddingLabels?: PhiPaddingWidgetLabels;
83
84
  backgroundLabels?: PhiBackgroundWidgetLabels;
84
85
  borderLabels?: PhiBorderWidgetLabels;
86
+ /** The Media library's picker, so a Surface field can take a background image like a block's own. */
87
+ renderMediaPicker?: PhiBackgroundControlProps["renderMediaPicker"];
85
88
  colorPickerLabels?: PhiColorPickerLabels;
86
89
  iconPickerLabels?: PhiIconPickerControlLabels;
87
90
  /** The Inspector's own words in its field controls, from the `widget:inspector` label set. */
@@ -7,8 +7,6 @@ import { PhiDividerControl } from "../../../../components/controls/phi-divider-c
7
7
  import { usePhiConfig } from "../../../../components/root/phi-config-provider";
8
8
  import { readPhiLengthValue } from "../../../../types";
9
9
  import { normalizePhiPaddingWidgetConfig, } from "../../../../types/cms-config";
10
- import { PhiBackgroundControl } from "../../../../components/controls/phi-background-control";
11
- import { PhiBorderControl } from "../../../../components/controls/phi-border-control";
12
10
  import { PhiColorFieldControl } from "../../../../components/controls/phi-color-field-control";
13
11
  import { PhiInspectorLinkTargetFieldControl, } from "./inspector-link-target-field";
14
12
  import { PhiInspectorImageFieldControl } from "./inspector-image-field";
@@ -30,10 +28,8 @@ import { PhiDialogControl } from "../../../../components/controls/phi-dialog-con
30
28
  import { PhiIcon } from "../../../../components/shell/phi-icon";
31
29
  import { PhiPaddingControl } from "../../../../components/controls/phi-padding-control";
32
30
  import { PHI_INSPECTOR_FIELD_LABEL_WIDTH, PhiInspectorFieldRow } from "../../../../components/widgets/inspector-field-row";
33
- import { PhiShadowControl } from "../../../../components/controls/phi-shadow-control";
34
31
  import { PhiSurfaceControl } from "../../../../components/controls/phi-surface-control";
35
32
  import { readPhiSurface } from "../../../../types/surface";
36
- import { readPhiShadow } from "../../../../types/layout-style";
37
33
  import { readInspectorChoiceMultiValue, readInspectorChoiceSingleValue, } from "./inspector-choice-values";
38
34
  import { PhiFlexControl } from "../../../../components/controls/phi-flex-control";
39
35
  import { PhiTypographyControl } from "../../../../components/controls/phi-typography-control";
@@ -248,12 +244,6 @@ function resolveInspectorColorMode(mode) {
248
244
  }
249
245
  return "single";
250
246
  }
251
- function normalizeInspectorBorderValue(value) {
252
- if (!isPhiRecord(value)) {
253
- return null;
254
- }
255
- return value;
256
- }
257
247
  function readPhiInspectorCollectionItems(value) {
258
248
  return Array.isArray(value)
259
249
  ? value.filter(isPhiRecord)
@@ -377,7 +367,7 @@ function PhiInspectorChoiceFieldControl({ field, config, value, defaultValue, di
377
367
  });
378
368
  } }));
379
369
  }
380
- function PhiInspectorCollectionFieldControl({ field, config, labels, value, defaultValue, disabled, widgetReferenceOptions, paddingLabels, backgroundLabels, borderLabels, colorPickerLabels, iconPickerLabels, dataProviderDescriptors, calendarAdapterDescriptors, videoProviderDescriptors, onChange, }) {
370
+ function PhiInspectorCollectionFieldControl({ field, config, labels, value, defaultValue, disabled, widgetReferenceOptions, paddingLabels, backgroundLabels, borderLabels, renderMediaPicker, colorPickerLabels, iconPickerLabels, dataProviderDescriptors, calendarAdapterDescriptors, videoProviderDescriptors, onChange, }) {
381
371
  const { token } = usePhiConfig();
382
372
  const popup = usePhiWidgetScaffoldPopup();
383
373
  const [overlayOpen, setOverlayOpen] = useState(false);
@@ -440,6 +430,7 @@ function PhiInspectorCollectionFieldControl({ field, config, labels, value, defa
440
430
  paddingLabels,
441
431
  backgroundLabels,
442
432
  borderLabels,
433
+ renderMediaPicker,
443
434
  colorPickerLabels,
444
435
  iconPickerLabels,
445
436
  fieldLabels: labels,
@@ -521,7 +512,7 @@ export function renderPhiInspectorConfigField(args) {
521
512
  return body;
522
513
  return (_jsxs(Fragment, { children: [_jsx(PhiDividerControl, { titlePlacement: "start", style: { marginBlock: 0 }, children: args.field.heading }), body] }, args.field.key));
523
514
  }
524
- function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config, defaultConfig, disabled, onChange, widgetReferenceOptions, paddingLabels, backgroundLabels, borderLabels, colorPickerLabels, iconPickerLabels, fieldLabels = PHI_INSPECTOR_WIDGET_DEFAULT_LABELS.fields, dataProviderDescriptors = [], calendarAdapterDescriptors = [], videoProviderDescriptors = [], blockId, }) {
515
+ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config, defaultConfig, disabled, onChange, widgetReferenceOptions, paddingLabels, backgroundLabels, borderLabels, renderMediaPicker, colorPickerLabels, iconPickerLabels, fieldLabels = PHI_INSPECTOR_WIDGET_DEFAULT_LABELS.fields, dataProviderDescriptors = [], calendarAdapterDescriptors = [], videoProviderDescriptors = [], blockId, }) {
525
516
  if (field.type === "readonly") {
526
517
  const displayValue = value ?? defaultValue;
527
518
  return renderPhiInspectorConfigFieldControl(field, _jsx(PhiTextControl, { value: displayValue == null ? "" : String(displayValue), readOnly: true, allowClear: false, style: { width: "100%" } }));
@@ -720,35 +711,15 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
720
711
  return (_jsx(PhiInspectorChoiceFieldControl, { field: field, config: config, value: value, defaultValue: defaultValue, disabled: disabled || !onChange, widgetReferenceOptions: widgetReferenceOptions ?? [], labels: fieldLabels, onChange: onChange }, field.key));
721
712
  }
722
713
  if (field.type === "collection") {
723
- return (_jsx(PhiInspectorCollectionFieldControl, { field: field, config: config, labels: fieldLabels, value: value, defaultValue: defaultValue, disabled: disabled || !onChange, widgetReferenceOptions: widgetReferenceOptions ?? [], paddingLabels: paddingLabels, backgroundLabels: backgroundLabels, borderLabels: borderLabels, colorPickerLabels: colorPickerLabels, iconPickerLabels: iconPickerLabels, dataProviderDescriptors: dataProviderDescriptors, calendarAdapterDescriptors: calendarAdapterDescriptors, videoProviderDescriptors: videoProviderDescriptors, onChange: onChange }, field.key));
714
+ return (_jsx(PhiInspectorCollectionFieldControl, { field: field, config: config, labels: fieldLabels, value: value, defaultValue: defaultValue, disabled: disabled || !onChange, widgetReferenceOptions: widgetReferenceOptions ?? [], paddingLabels: paddingLabels, backgroundLabels: backgroundLabels, borderLabels: borderLabels, renderMediaPicker: renderMediaPicker, colorPickerLabels: colorPickerLabels, iconPickerLabels: iconPickerLabels, dataProviderDescriptors: dataProviderDescriptors, calendarAdapterDescriptors: calendarAdapterDescriptors, videoProviderDescriptors: videoProviderDescriptors, onChange: onChange }, field.key));
724
715
  }
725
716
  if (field.type === "color") {
726
717
  return renderPhiInspectorConfigFieldControl(field, _jsx(PhiColorFieldControl, { value: value, defaultValue: defaultValue, ...(field.defaultToken ? { defaultToken: field.defaultToken } : {}), disabled: disabled || !onChange, mode: resolveInspectorColorMode(field.mode), placement: "left", labels: colorPickerLabels, onChange: (nextValue) => onChange?.({ [field.key]: nextValue || undefined }) }));
727
718
  }
728
- if (field.type === "background") {
729
- const usesSelfStorage = field.storage === "self";
730
- const currentValue = (usesSelfStorage ? config : value);
731
- const currentDefaultValue = (usesSelfStorage ? defaultConfig : defaultValue);
732
- return renderPhiInspectorConfigFieldControl(field, _jsx(PhiBackgroundControl, { mode: "control", disabled: disabled || !onChange, value: currentValue ?? null, config: currentDefaultValue ?? null, labels: backgroundLabels, colorPickerLabels: colorPickerLabels, colorPickerPlacement: "left", onChange: (nextValue) => usesSelfStorage
733
- ? onChange?.(nextValue)
734
- : onChange?.({ [field.key]: nextValue }) }));
735
- }
736
- if (field.type === "border") {
737
- const usesSelfStorage = field.storage === "self";
738
- const currentValue = normalizeInspectorBorderValue(usesSelfStorage ? config : value);
739
- const currentDefaultValue = normalizeInspectorBorderValue(usesSelfStorage ? defaultConfig : defaultValue);
740
- return renderPhiInspectorConfigFieldControl(field, _jsx(PhiBorderControl, { mode: "control", disabled: disabled || !onChange, value: currentValue, config: currentDefaultValue, labels: borderLabels, colorPickerLabels: colorPickerLabels, colorPickerPlacement: "left", onChange: (nextValue) => usesSelfStorage
741
- ? onChange?.(nextValue)
742
- : onChange?.({ [field.key]: nextValue }) }));
743
- }
744
719
  if (field.type === "surface") {
745
720
  return renderPhiInspectorConfigFieldBlock(field, _jsx(PhiSurfaceControl, { disabled: disabled || !onChange, value: value === null ? null : readPhiSurface(value) ?? readPhiSurface(defaultValue), tone: field.tone !== false,
746
721
  // A box inside a Widget has no layer of its own to blur.
747
- backgroundFilters: ["glass", "haze"], backgroundLabels: backgroundLabels, borderLabels: borderLabels, colorPickerLabels: colorPickerLabels, onChange: (nextValue) => onChange?.({ [field.key]: nextValue }) }));
748
- }
749
- if (field.type === "shadow") {
750
- const currentValue = readPhiShadow(value) ?? readPhiShadow(defaultValue) ?? null;
751
- return renderPhiInspectorConfigFieldControl(field, _jsx(PhiShadowControl, { mode: "control", disabled: disabled || !onChange, value: currentValue, onChange: (nextValue) => onChange?.({ [field.key]: nextValue }) }));
722
+ backgroundFilters: ["glass", "haze"], backgroundLabels: backgroundLabels, borderLabels: borderLabels, colorPickerLabels: colorPickerLabels, renderMediaPicker: renderMediaPicker, onChange: (nextValue) => onChange?.({ [field.key]: nextValue }) }));
752
723
  }
753
724
  if (field.type === "icon") {
754
725
  const iconValue = typeof value === "string"
@@ -765,7 +736,7 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
765
736
  ? String(value)
766
737
  : typeof defaultValue === "string" || typeof defaultValue === "number"
767
738
  ? String(defaultValue)
768
- : "", disabled: disabled || !onChange, inputType: field.type === "url" ? "url" : "text", style: { width: "100%" }, onChange: (nextValue) => onChange?.({
739
+ : "", disabled: disabled || !onChange, inputType: field.type === "url" ? "url" : "text", ...("placeholder" in field && field.placeholder ? { placeholder: field.placeholder } : {}), style: { width: "100%" }, onChange: (nextValue) => onChange?.({
769
740
  [field.key]: nextValue || ("emptyValue" in field ? field.emptyValue : undefined),
770
741
  }) }));
771
742
  }
@@ -784,6 +755,25 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
784
755
  }
785
756
  if (field.type === "flags") {
786
757
  const mask = typeof value === "number" ? value : typeof defaultValue === "number" ? defaultValue : 0;
758
+ /*
759
+ * One flag is a yes or no, and reads as one: the field's name with a switch behind it on its row,
760
+ * like a boolean field, rather than a group of a single checkbox under a heading. The other bits of
761
+ * the mask stay as they are.
762
+ */
763
+ const [onlyOption] = field.options.length === 1 ? field.options : [];
764
+ if (onlyOption) {
765
+ return renderPhiInspectorSwitchRow({
766
+ key: field.key,
767
+ label: renderPhiInspectorConfigFieldLabel(field),
768
+ checked: (mask & onlyOption.value) !== 0,
769
+ disabled: disabled || !onChange,
770
+ ...(onChange
771
+ ? {
772
+ onChange: (checked) => onChange({ [field.key]: checked ? mask | onlyOption.value : mask & ~onlyOption.value }),
773
+ }
774
+ : {}),
775
+ });
776
+ }
787
777
  return renderPhiInspectorConfigFieldBlock(field, _jsx(PhiCheckboxGroupControl, { vertical: true, value: field.options.filter((option) => (mask & option.value) !== 0).map((option) => option.value), options: field.options.map((option) => ({ value: option.value, label: option.label })), disabled: disabled || !onChange, onChange: (ticked) => onChange?.({ [field.key]: ticked.reduce((next, flag) => next | flag, 0) }) }));
788
778
  }
789
779
  if (field.type === "number-list") {
@@ -13,7 +13,7 @@ import { PHI_INSPECTOR_WIDGET_DEFAULT_LABELS, } from "../../../../components/wid
13
13
  * of the Area the Builder is working on.
14
14
  */
15
15
  export function PhiInspectorLinkTargetFieldControl({ value, disabled, labels = PHI_INSPECTOR_WIDGET_DEFAULT_LABELS.fields.linkTarget, onChange, }) {
16
- const state = usePhiDeveloperBuilderStateValue("public", (current) => current);
16
+ const state = usePhiDeveloperBuilderStateValue((current) => current);
17
17
  const pages = usePhiBuilderOfferedPageCatalog(state, state.area);
18
18
  const options = useMemo(() => buildPhiBuilderPageReferenceTree(state.area, pages, pages, { landing: labels.landingPage }), [labels.landingPage, pages, state.area]);
19
19
  return (_jsx(PhiLinkTargetControl, { value: value, options: options, labels: labels, disabled: disabled, onChange: onChange,
@@ -76,14 +76,14 @@ function resolveDraftFromLayoutNode(node, meta) {
76
76
  }
77
77
  function usePhiBuilderInspectorSectionState(signalRoutes) {
78
78
  const dispatchSignal = usePhiSignalDispatcher();
79
- const area = usePhiDeveloperBuilderStateValue("public", (state) => state.area);
80
- const pageKey = usePhiDeveloperBuilderStateValue("public", (state) => state.pageKey);
81
- const builderMode = usePhiDeveloperBuilderStateValue("public", (state) => state.builderMode);
82
- const nodeId = usePhiDeveloperBuilderStateValue("public", (state) => state.nodeId);
83
- const nodeKey = usePhiDeveloperBuilderStateValue("public", (state) => state.nodeKey);
84
- const nodeKind = usePhiDeveloperBuilderStateValue("public", (state) => state.nodeKind);
85
- const selectedLayoutAnchor = usePhiDeveloperBuilderStateValue("public", (state) => state.selectedLayoutAnchor);
86
- const selectedRootRegionKey = usePhiDeveloperBuilderStateValue("public", (state) => state.selectedRootRegionKey);
79
+ const area = usePhiDeveloperBuilderStateValue((state) => state.area);
80
+ const pageKey = usePhiDeveloperBuilderStateValue((state) => state.pageKey);
81
+ const builderMode = usePhiDeveloperBuilderStateValue((state) => state.builderMode);
82
+ const nodeId = usePhiDeveloperBuilderStateValue((state) => state.nodeId);
83
+ const nodeKey = usePhiDeveloperBuilderStateValue((state) => state.nodeKey);
84
+ const nodeKind = usePhiDeveloperBuilderStateValue((state) => state.nodeKind);
85
+ const selectedLayoutAnchor = usePhiDeveloperBuilderStateValue((state) => state.selectedLayoutAnchor);
86
+ const selectedRootRegionKey = usePhiDeveloperBuilderStateValue((state) => state.selectedRootRegionKey);
87
87
  const activeModuleMetas = usePhiBuilderModuleMetas(area);
88
88
  const activeBuilderPlugins = activeModuleMetas.plugins;
89
89
  const activeDataProviderDescriptors = activeModuleMetas.dataProviders;