@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
@@ -1,10 +1,12 @@
1
1
  "use client";
2
- import { isPhiRecord } from "../../helpers/is-record";
3
2
  import { useEffect, useMemo, useState } from "react";
4
3
  import { PhiMediaKind } from "../../constants/media";
5
4
  import { createPhiAssetUri } from "../../types/references";
6
5
  import { usePhiCollectionProvider } from "../widgets/client/shared/phi-collection-provider";
7
6
  import { PHI_ASSET_COLLECTION_DATA_SOURCE } from "./asset-collection-runtime";
7
+ import { readPhiFontMetricsFields } from "./media-font-metrics";
8
+ import { readPhiMediaAssetTiles } from "./phi-image-preview-data";
9
+ import { createPhiResponseReader } from "../widgets/config/strict-config-reader";
8
10
  /**
9
11
  * The typefaces a Site owns, as something a font slot can be set to.
10
12
  *
@@ -19,12 +21,9 @@ import { PHI_ASSET_COLLECTION_DATA_SOURCE } from "./asset-collection-runtime";
19
21
  /** Enough for any Site's own lettering; a ceiling rather than a page size. */
20
22
  const PHI_SITE_FONT_ASSET_LIMIT = 100;
21
23
  function readFontAssetMetrics(asset) {
22
- const meta = asset.meta?.font;
23
- if (!isPhiRecord(meta))
24
- return null;
25
- const record = meta;
26
- // The management tile carries `meta` as stored; only a shape with its unit grid is worth drawing from.
27
- return typeof record.unitsPerEm === "number" && record.unitsPerEm > 0 ? record : null;
24
+ // The management tile carries `meta` as stored, and the server stored every field of the metrics.
25
+ return createPhiResponseReader(asset.meta ?? {}, `The stored metrics of Asset ${asset.id}`, "meta")
26
+ .object("font", readPhiFontMetricsFields) ?? null;
28
27
  }
29
28
  function readFontAssetLabel(asset) {
30
29
  const family = readFontAssetMetrics(asset)?.familyName;
@@ -68,7 +67,7 @@ export function usePhiSiteFontAssets(enabled = true) {
68
67
  setError(data.error);
69
68
  return;
70
69
  }
71
- setAssets(data.items.filter((item) => Boolean(item)));
70
+ setAssets(readPhiMediaAssetTiles(data.items));
72
71
  }).catch((cause) => {
73
72
  if (abortController.signal.aborted)
74
73
  return;
@@ -10,10 +10,15 @@ export function PhiLink({ href, children, external, newTab, prefetch, className,
10
10
  const [active, setActive] = useState(false);
11
11
  const useAnchor = external ?? isPhiExternalHref(href);
12
12
  const linkStyle = useMemo(() => ({
13
- color: active ? token.colorLinkActive : hovered ? token.colorLinkHover : token.colorLink,
14
13
  textDecoration: "none",
15
14
  cursor: "pointer",
16
15
  ...style,
16
+ /*
17
+ * A colour the caller states is the link at rest -- a Header's text colour, a list's inherited one --
18
+ * and never more: pointed at and pressed, a link answers in the Theme's link colours whatever it
19
+ * rests in. Spread after `style`, a stated colour had silenced the hover of every link that set one.
20
+ */
21
+ color: active ? token.colorLinkActive : hovered ? token.colorLinkHover : style?.color ?? token.colorLink,
17
22
  }), [active, hovered, style, token.colorLink, token.colorLinkActive, token.colorLinkHover]);
18
23
  const interactionProps = {
19
24
  onMouseEnter: () => setHovered(true),
@@ -60,6 +60,13 @@ export function PhiOverlayContainerClient({ overlayId, overlayType, config: rawC
60
60
  const [runtimeControlSizeOverride, setRuntimeControlSizeOverride] = useState(null);
61
61
  const [runtimeSizeOverride, setRuntimeSizeOverride] = useState(null);
62
62
  const [runtimeTitleOverride, setRuntimeTitleOverride] = useState(null);
63
+ /*
64
+ * Whether work the Overlay holds is under way -- a Form in the Body saving. While it is, a reader's
65
+ * dismissal (close button, mask, Escape) is not taken: closing would abandon the save's answer. A
66
+ * `close` sent on purpose still closes, which is how a Form that went through ends its dialog. Told
67
+ * through the `busy` input by whoever knows, so a dialog needs no Controller to refuse a close.
68
+ */
69
+ const [busy, setBusy] = useState(false);
63
70
  const runtimeControlSize = runtimeControlSizeOverride?.config === config
64
71
  ? runtimeControlSizeOverride.value
65
72
  : null;
@@ -106,6 +113,9 @@ export function PhiOverlayContainerClient({ overlayId, overlayType, config: rawC
106
113
  // A failed load is forgotten on close, so the next open asks the server again.
107
114
  if (!nextOpen)
108
115
  setLoadedZones((current) => current && "failure" in current ? null : current);
116
+ // A closed Overlay holds no work; a busy state left behind would refuse the next dismissal.
117
+ if (!nextOpen)
118
+ setBusy(false);
109
119
  setOpen(nextOpen);
110
120
  }, []);
111
121
  /*
@@ -200,6 +210,9 @@ export function PhiOverlayContainerClient({ overlayId, overlayType, config: rawC
200
210
  else if (route.capabilityId === "close") {
201
211
  updateOpen(false);
202
212
  }
213
+ else if (route.capabilityId === "busy" && signal.valueType === "boolean") {
214
+ setBusy(signal.value === true);
215
+ }
203
216
  else if (route.capabilityId === "toggle") {
204
217
  updateOpen(typeof signal.value === "boolean" ? signal.value : !open);
205
218
  }
@@ -229,12 +242,14 @@ export function PhiOverlayContainerClient({ overlayId, overlayType, config: rawC
229
242
  receiver,
230
243
  }), [receiver, signalScope]), receiver);
231
244
  const requestClose = useCallback((source) => {
245
+ if (busy)
246
+ return;
232
247
  if (config.closeMode === "request") {
233
248
  emitCapability("closeRequest", { source });
234
249
  return;
235
250
  }
236
251
  updateOpen(false);
237
- }, [config.closeMode, emitCapability, updateOpen]);
252
+ }, [busy, config.closeMode, emitCapability, updateOpen]);
238
253
  // An Overlay's window is simply "open", which is why it can share the rule with a Carousel whose
239
254
  // window is several slots wide.
240
255
  const shouldRenderContent = shouldPhiCmsContentStayMounted({
@@ -17,7 +17,8 @@ import { PhiEffectsReadyTrigger } from "../../../plugins/runtime/phi-effects-rea
17
17
  import { PhiSlotChildEffectsVisibilityObserver } from "../../../plugins/runtime/phi-slot-child-effects-visibility-observer";
18
18
  import { PhiSlotChildViewportEffectsObserver } from "../../../plugins/runtime/phi-slot-child-viewport-effects-observer";
19
19
  import { PhiFlexControl } from "../../controls/phi-flex-control";
20
- import { resolvePhiCmsRegionShell } from "../phi-cms-region-shell";
20
+ import { phiCmsRegionSiderSticks, resolvePhiCmsRegionShell, } from "../phi-cms-region-shell";
21
+ import { usePhiShellStickyTop } from "../../shell/use-phi-shell-sticky-top";
21
22
  import { usePhiVisualAnchor } from "../../runtime/runtime-visual-anchors";
22
23
  import { usePhiPathname } from "../../runtime/use-phi-pathname";
23
24
  import { stripLocaleAndAreaFromPathname } from "../../../helpers/locale";
@@ -100,6 +101,10 @@ export function PhiCmsRegionContainerClient({ children, className, regionKey, co
100
101
  elementRef,
101
102
  placeholderRef,
102
103
  });
104
+ usePhiShellStickyTop({
105
+ active: !previewMode && inScope && phiCmsRegionSiderSticks(regionKey, initialConfig),
106
+ elementRef,
107
+ });
103
108
  /*
104
109
  * Off this Page, the Region leaves a hidden marker rather than nothing: `header_top` still has to tell
105
110
  * the Shell it holds no room, and it finds the Shell from here.
@@ -3,6 +3,7 @@ import { isPhiCmsPageOwnedRegion } from "../../helpers/cms-region-keys";
3
3
  import { hasPhiFlag } from "../../helpers/flags";
4
4
  import { PhiCmsFlags } from "../../constants/phi-cms";
5
5
  import { PhiCmsRegionStatic } from "./phi-cms-region-static";
6
+ import { phiCmsRegionSiderSticks } from "./phi-cms-region-shell";
6
7
  import { resolveRenderableBlockEffectsAttributes, resolveRenderableBlockViewportEffects, } from "../../helpers/renderable-block-effects";
7
8
  import { PhiRuntimeModuleRenderClientHost } from "../runtime/runtime-module-render-client-manifest";
8
9
  import { PhiRuntimeRenderClientType } from "../../constants/runtime-render-client-types";
@@ -21,6 +22,8 @@ export function PhiCmsRegionContainer({ children, className, regionKey, config,
21
22
  const requiresClientEnhancement = signalParticipant ||
22
23
  pageScoped ||
23
24
  (!previewMode && readPhiCmsRegionReveal(regionKey, config) !== "always") ||
25
+ // A stuck Sider stands under the Header as measured, and only the browser can measure it.
26
+ (!previewMode && phiCmsRegionSiderSticks(regionKey, config)) ||
24
27
  hasPhiFlag(config?.flags, PhiCmsFlags.Collapsible) ||
25
28
  requiresEffectsObserver ||
26
29
  resolvePhiBackgroundMotion(config?.surface?.background) != null;
@@ -3,7 +3,7 @@ import type { CSSProperties } from "react";
3
3
  import { type PhiRenderableBlockEffectsAttributes } from "../../helpers/renderable-block-effects";
4
4
  import { resolvePhiShellRegionChrome } from "../../helpers/shell-region-style";
5
5
  import type { PhiBlockRuntime, PhiCmsRegionConfig, PhiCmsRegionKey, PhiRenderableBlock } from "../../types";
6
- import type { PhiSurfaceGround } from "../../helpers/surface-style";
6
+ import { type PhiSurfaceGround } from "../../helpers/surface-style";
7
7
  import type { PhiCmsRegionReveal } from "../../types/cms-presets";
8
8
  import { type PhiCmsBackgroundWidgetConfig } from "../widgets/config/background";
9
9
  /**
@@ -92,6 +92,17 @@ export type PhiCmsRegionShell = {
92
92
  /** The content wrapper's style, which is where Region padding lives (LAYOUTING.md "Regions"). */
93
93
  contentStyle: CSSProperties;
94
94
  };
95
+ /**
96
+ * Whether a Region is a Sider that sticks under the Header, and so needs the Header's measured bottom.
97
+ *
98
+ * Two kinds of Sider stick, and only one of them under the Header. A `FullHeight` Sider is a column of the
99
+ * Shell from the viewport's top to its bottom -- an Admin or Builder navigation beside the Header, not
100
+ * below it -- and stands at its configured `offsetTop`. A `Sticky` Sider without it stands in the page
101
+ * below the Header -- a contents beside a text -- and sticks under the line the Shell publishes as
102
+ * `--phi-shell-sticky-top` (`usePhiShellStickyTop`), with its offset added. The Region renderer runs that
103
+ * measurement for such a Sider, which is why this is asked before the Region renders.
104
+ */
105
+ export declare function phiCmsRegionSiderSticks(regionKey: PhiCmsRegionKey, config: Pick<PhiCmsRegionConfig, "flags"> | null | undefined): boolean;
95
106
  /**
96
107
  * The Region's shell, or null where the Region renders nothing: hidden, or collapsed in a preview.
97
108
  * `header_bottom` is exempt from the preview collapse because the Page, not the Area, owns its content.
@@ -6,11 +6,12 @@ import { resolveRenderableBlockEffectsAttributes, resolveRenderableBlockEffectsS
6
6
  import { resolvePhiShellRegionChrome, resolvePhiShellRegionGroundStyle, resolvePhiShellRegionTypography, resolvePhiShellRegionZIndex, resolvePhiShellSiderCollapsedWidth, resolvePhiShellSiderWidth, } from "../../helpers/shell-region-style";
7
7
  import { PhiCmsFlags } from "../../constants/phi-cms";
8
8
  import { resolvePhiCmsBorderSource } from "../../types/cms-border-source";
9
+ import { PHI_SURFACE_TONE_GROUND, phiSurfaceTakesToneGround, } from "../../helpers/surface-style";
9
10
  import { resolvePhiRenderableBlockGeometry } from "../../types/renderable-block-geometry";
10
11
  import { createPhiSignalAddress } from "../../types/signals";
11
12
  import { readPhiCmsRegionReveal } from "../../helpers/region-page-scope";
12
13
  import { resolvePhiPaddingStyle } from "../layouts/phi-layout-contract";
13
- import { phiRegionUsesShellChromeOverlay } from "../root/phi-shell-chrome-overlay";
14
+ import { PHI_SHELL_STICKY_TOP_PROPERTY, phiRegionUsesShellChromeOverlay } from "../root/phi-shell-chrome-overlay";
14
15
  import { normalizePhiBackgroundWidgetConfig, phiBackgroundWidgetConfigPaintsGround, resolvePhiBackgroundGroundFilter, resolvePhiBackgroundMotion, resolvePhiBackgroundMotionHostStyle, resolvePhiBackgroundPane, resolvePhiBackgroundWidgetStyle, } from "../widgets/config/background";
15
16
  /*
16
17
  * The longhands every Region that paints the Shell Chrome Overlay (SHELL.md) carries, read from the
@@ -45,6 +46,25 @@ function resolvePhiCmsRegionShellFamily(regionKey) {
45
46
  }
46
47
  return "other";
47
48
  }
49
+ /**
50
+ * Whether a Region is a Sider that sticks under the Header, and so needs the Header's measured bottom.
51
+ *
52
+ * Two kinds of Sider stick, and only one of them under the Header. A `FullHeight` Sider is a column of the
53
+ * Shell from the viewport's top to its bottom -- an Admin or Builder navigation beside the Header, not
54
+ * below it -- and stands at its configured `offsetTop`. A `Sticky` Sider without it stands in the page
55
+ * below the Header -- a contents beside a text -- and sticks under the line the Shell publishes as
56
+ * `--phi-shell-sticky-top` (`usePhiShellStickyTop`), with its offset added. The Region renderer runs that
57
+ * measurement for such a Sider, which is why this is asked before the Region renders.
58
+ */
59
+ export function phiCmsRegionSiderSticks(regionKey, config) {
60
+ return resolvePhiCmsRegionShellFamily(regionKey) === "sider"
61
+ && hasPhiFlag(config?.flags, PhiCmsFlags.Sticky)
62
+ && !hasPhiFlag(config?.flags, PhiCmsFlags.FullHeight);
63
+ }
64
+ /** The line a stuck Sider stands at: under the Header as measured, plus its own offset. */
65
+ function resolvePhiCmsRegionSiderStuckTop(topCss) {
66
+ return `calc(var(${PHI_SHELL_STICKY_TOP_PROPERTY}, 0px) + ${topCss})`;
67
+ }
48
68
  /*
49
69
  * A Region's edge, from its Surface.
50
70
  *
@@ -123,15 +143,24 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
123
143
  * `scroll-up` band ever publishes it (SHELL.md "Region visibility per Page"), so for every other Shell
124
144
  * it is unset and the offset is the one configured.
125
145
  */
146
+ /*
147
+ * A full-height Sider is a Shell column from the viewport's top and stands at its own offset; a sticky
148
+ * one stands under the Header as it is measured right now (`phiCmsRegionSiderSticks`) and is at most as
149
+ * tall as what is left of the viewport below that line.
150
+ */
151
+ const siderUnderHeader = isSider && sticky && !fullHeight;
126
152
  const stuckTop = !stuck
127
153
  ? undefined
128
154
  : isHeader && regionKey !== "header_top"
129
155
  ? `calc(${topCss} + var(--phi-shell-header-top-stack, 0px))`
130
- : top;
156
+ : siderUnderHeader
157
+ ? resolvePhiCmsRegionSiderStuckTop(topCss)
158
+ : top;
131
159
  const blockSize = geometry.block.size?.css;
132
160
  const fullHeightSize = fullHeight && !blockSize
133
161
  ? `calc(100dvh - ${topCss})`
134
162
  : blockSize;
163
+ const underHeaderMaxSize = siderUnderHeader ? `calc(100dvh - ${resolvePhiCmsRegionSiderStuckTop(topCss)})` : undefined;
135
164
  const zIndex = config.zIndex ?? resolvePhiShellRegionZIndex(regionKey, hasPhiFlag(config.flags, PhiCmsFlags.FullHeight));
136
165
  /*
137
166
  * A Background config that paints nothing is not an authored ground. The Builder writes one onto every
@@ -143,12 +172,31 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
143
172
  ? normalizePhiBackgroundWidgetConfig(surface.background)
144
173
  : null;
145
174
  const backgroundConfig = phiBackgroundWidgetConfigPaintsGround(surfaceBackground) ? surfaceBackground : null;
175
+ /*
176
+ * A tone turns the ground as well, by the rule every Surface follows (LAYOUTING.md "Surface tone"):
177
+ * where the Background paints nothing, the Region takes its tone's container ground, which resolves
178
+ * under the tone class the root element carries. That is a ground of the Region's own, so the Shell's
179
+ * -- the Theme's record, the Chrome Overlay, a pane frosting either -- does not show beneath it.
180
+ */
181
+ const toneGround = phiSurfaceTakesToneGround(surface?.tone, backgroundConfig != null);
182
+ /*
183
+ * The Theme's Overlay as the ground (`base.kind: "theme"`). Without a tone a Chrome Region takes it the
184
+ * way a Region without a Background does -- the `data-phi-shell-chrome` marker, so that where the Shell
185
+ * draws its panes the pane behind shows through instead of a second frosting -- but over any ground the
186
+ * Shell record sets. Every other Region, and a toned one, paints it itself, which under a tone's class
187
+ * is the Overlay of the tone's mode.
188
+ */
189
+ const themeGround = backgroundConfig?.base.kind === "theme";
190
+ const themeGroundIsShellChrome = themeGround
191
+ && resolvePhiSurfaceToneClassName(surface?.tone) == null
192
+ && phiRegionUsesShellChromeOverlay({ regionKey, backgroundConfig, grounds: [] });
146
193
  /*
147
194
  * A pane on a Region without a ground of its own frosts the Shell's ground for this Region -- the
148
195
  * Theme's record, or the family's fallback -- which is what glass on a bare Header has always meant.
149
- * A Region that paints its own ground carries its pane inside that Background, as every Surface does.
196
+ * A Region that paints its own ground carries its pane inside that Background, as every Surface does;
197
+ * the tone's ground is one, so its pane stays on the box under that ground, as on a toned Layout.
150
198
  */
151
- const shellPane = backgroundConfig == null ? resolvePhiBackgroundPane(surfaceBackground) : null;
199
+ const shellPane = backgroundConfig == null && !toneGround ? resolvePhiBackgroundPane(surfaceBackground) : null;
152
200
  const backgroundMoves = animatesBackground &&
153
201
  backgroundConfig != null &&
154
202
  resolvePhiBackgroundMotion(backgroundConfig) != null;
@@ -160,11 +208,18 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
160
208
  motion: null,
161
209
  }
162
210
  : null;
163
- const backgroundStyle = backgroundConfig == null || ground != null
211
+ const backgroundStyle = themeGroundIsShellChrome
164
212
  ? null
165
- : backgroundMoves
166
- ? resolvePhiBackgroundMotionHostStyle(backgroundConfig)
167
- : resolvePhiBackgroundWidgetStyle(backgroundConfig);
213
+ : toneGround
214
+ ? {
215
+ ...(surfaceBackground ? resolvePhiBackgroundWidgetStyle(surfaceBackground) : {}),
216
+ backgroundColor: PHI_SURFACE_TONE_GROUND,
217
+ }
218
+ : backgroundConfig == null || ground != null
219
+ ? null
220
+ : backgroundMoves
221
+ ? resolvePhiBackgroundMotionHostStyle(backgroundConfig)
222
+ : resolvePhiBackgroundWidgetStyle(backgroundConfig);
168
223
  const chromeInput = {
169
224
  shadow: surface?.shadow ?? undefined,
170
225
  effect: shellPane ?? undefined,
@@ -184,12 +239,14 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
184
239
  * the stored one: the Builder persists an empty Background record for every Region an author has ever
185
240
  * opened, and the raw value is never null for those.
186
241
  */
187
- const usesShellChromeOverlay = phiRegionUsesShellChromeOverlay({
188
- regionKey,
189
- backgroundConfig,
190
- pane: shellPane,
191
- grounds: [chrome.light.background, chrome.dark.background],
192
- });
242
+ const usesShellChromeOverlay = themeGround
243
+ ? themeGroundIsShellChrome
244
+ : !toneGround && phiRegionUsesShellChromeOverlay({
245
+ regionKey,
246
+ backgroundConfig,
247
+ pane: shellPane,
248
+ grounds: [chrome.light.background, chrome.dark.background],
249
+ });
193
250
  /*
194
251
  * The ground. Published, it is the pair of custom properties `shell.css` paints from, because it may
195
252
  * be a colour or a gradient and only CSS can tell which without guessing; nothing inline may name a
@@ -203,13 +260,18 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
203
260
  * drop one of those from an element whose `background` shorthand is still set.
204
261
  */
205
262
  const liveChrome = paint.kind === "live" ? chrome[paint.mode] : null;
263
+ /*
264
+ * A toned Region publishes no Shell ground: `shell.css` would paint a gradient one beneath its own. Nor
265
+ * does one whose ground is the Theme's: the Overlay stands where the Shell record's ground would.
266
+ */
267
+ const withoutShellGround = toneGround || themeGround;
206
268
  const modeStyle = liveChrome
207
269
  ? {}
208
270
  : {
209
- ...(chrome.light.background == null
271
+ ...(chrome.light.background == null || withoutShellGround
210
272
  ? {}
211
273
  : { "--phi-region-background-light": String(chrome.light.background) }),
212
- ...(chrome.dark.background == null
274
+ ...(chrome.dark.background == null || withoutShellGround
213
275
  ? {}
214
276
  : { "--phi-region-background-dark": String(chrome.dark.background) }),
215
277
  "--phi-region-color-light": String(chrome.light.color),
@@ -219,7 +281,7 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
219
281
  const effectStyle = liveChrome || paintedChrome.effectStyle?.backgroundColor == null
220
282
  ? paintedChrome.effectStyle
221
283
  : { ...paintedChrome.effectStyle, backgroundColor: "var(--phi-region-background)" };
222
- const groundStyle = liveChrome && backgroundStyle == null
284
+ const groundStyle = liveChrome && backgroundStyle == null && !themeGround
223
285
  ? resolvePhiShellRegionGroundStyle(liveChrome.background)
224
286
  : {};
225
287
  const typography = resolvePhiShellRegionTypography(regionKey, shellTheme, {
@@ -258,11 +320,11 @@ export function resolvePhiCmsRegionShell({ regionKey, config, shellTheme, paint,
258
320
  maxWidth: geometry.inline.max?.css ?? siderWidth,
259
321
  height: fullHeightSize,
260
322
  minHeight: geometry.block.min?.css ?? (fullHeight ? fullHeightSize : undefined),
261
- maxHeight: geometry.block.max?.css,
323
+ maxHeight: geometry.block.max?.css ?? underHeaderMaxSize,
262
324
  alignSelf: fullHeight ? "stretch" : "start",
263
325
  flex: fullHeight ? "1 1 auto" : undefined,
264
326
  overflowX: "visible",
265
- overflowY: fullHeight ? "auto" : "visible",
327
+ overflowY: fullHeight || siderUnderHeader ? "auto" : "visible",
266
328
  }
267
329
  : {
268
330
  width: geometry.inline.size?.css ?? "100%",
@@ -4,7 +4,7 @@ import { createPhiCmsPresetNodes } from "../../../helpers/cms-preset-nodes";
4
4
  import { PHI_SPACE } from "../../../theme/antd-css-var-contract";
5
5
  import { PHI_LAYOUT } from "../../../theme/phi-tokens";
6
6
  import { createPhiPresetCmsInstanceIdMap } from "../../../types/cms-instance-id";
7
- import { PHI_SIGNAL_VALUE_SCHEMAS, createPhiSignalAddress } from "../../../types/signals";
7
+ import { PHI_SIGNAL_VALUE_SCHEMAS, createPhiSignalAddress, createPhiSignalSubcontrolAddress, } from "../../../types/signals";
8
8
  import { buildPhiBasePageContentScaffold, PHI_BASE_PAGE_LAYOUT_NODE_ID } from "./phi-base-page-layout";
9
9
  import { PHI_DIALOG_BODY_CONFIG, PHI_DIALOG_COMMANDS_CONFIG } from "../../../helpers/cms-dialog";
10
10
  /**
@@ -252,6 +252,29 @@ export function buildPhiSettingsPageShellTree({ page, ownerModuleId, presetKey,
252
252
  valueType: "none",
253
253
  receiver: overlayAddress,
254
254
  },
255
+ /*
256
+ * While the save is under way the dialog refuses a reader's dismissal, and the Save
257
+ * button shows that it is working -- the two things a Controller would otherwise be
258
+ * mounted for (OVERLAYS.md, "Runtime and signaling").
259
+ */
260
+ {
261
+ routeKey: `${overlay.nodeKey}-busy`,
262
+ capabilityId: "submitting",
263
+ scope: "page",
264
+ channel: "busy",
265
+ action: "change",
266
+ valueType: "boolean",
267
+ receiver: overlayAddress,
268
+ },
269
+ {
270
+ routeKey: `${overlay.nodeKey}-submit-loading`,
271
+ capabilityId: "submitting",
272
+ scope: "page",
273
+ channel: "loading",
274
+ action: "change",
275
+ valueType: "boolean",
276
+ receiver: createPhiSignalSubcontrolAddress("cms", widgets[`${overlay.nodeKey}Commands`], "submit"),
277
+ },
255
278
  ...(extraSignalRoutes?.emits ?? []),
256
279
  ],
257
280
  listens: [
@@ -315,6 +338,17 @@ export function buildPhiSettingsPageShellTree({ page, ownerModuleId, presetKey,
315
338
  receiver: formAddress,
316
339
  },
317
340
  ],
341
+ listens: [
342
+ {
343
+ routeKey: `${overlay.nodeKey}-commands-submit-loading`,
344
+ capabilityId: "loading",
345
+ scope: "page",
346
+ channel: "loading",
347
+ action: "change",
348
+ valueType: "boolean",
349
+ receiver: createPhiSignalSubcontrolAddress("cms", widgets[`${overlay.nodeKey}Commands`], "submit"),
350
+ },
351
+ ],
318
352
  },
319
353
  },
320
354
  }),
@@ -344,6 +378,10 @@ export function buildPhiSettingsPageShellTree({ page, ownerModuleId, presetKey,
344
378
  * the provider somebody looked at before.
345
379
  */
346
380
  mountPolicy: "remount",
381
+ /*
382
+ * `immediate`, because nothing is mounted to answer a close request; while the Form saves, its
383
+ * `submitting` route sets this Overlay `busy`, and a busy Overlay does not take a dismissal.
384
+ */
347
385
  closeMode: "immediate",
348
386
  openActionKey: overlay.openActionKey,
349
387
  signalRoutes: {
@@ -371,6 +409,15 @@ export function buildPhiSettingsPageShellTree({ page, ownerModuleId, presetKey,
371
409
  valueType: "none",
372
410
  receiver: createPhiSignalAddress("cms", overlayIds[overlay.nodeKey]),
373
411
  },
412
+ {
413
+ routeKey: `${overlay.nodeKey}-busy`,
414
+ capabilityId: "busy",
415
+ scope: "page",
416
+ channel: "busy",
417
+ action: "change",
418
+ valueType: "boolean",
419
+ receiver: createPhiSignalAddress("cms", overlayIds[overlay.nodeKey]),
420
+ },
374
421
  ],
375
422
  },
376
423
  },
@@ -30,6 +30,11 @@ export type PhiConfig = {
30
30
  * the reader rather than quietly working until the day the Theme is computed by something else.
31
31
  */
32
32
  token: PhiThemeTokens;
33
+ /**
34
+ * The page's Theme where `token` is a Surface tone's (`PhiNestedModeConfigProvider`): set only inside
35
+ * a tone scope, so outside one the page's Theme is `token` itself. Read through `usePhiPageModeToken`.
36
+ */
37
+ pageToken?: PhiThemeTokens;
33
38
  };
34
39
  export type PhiFontCatalogueFamily = {
35
40
  family: string;
@@ -49,6 +54,14 @@ export declare function PhiConfigProvider({ children, locale, fonts, fontFamilie
49
54
  controlShape: PhiControlShape;
50
55
  }): import("react").JSX.Element;
51
56
  export declare function usePhiConfig(): PhiConfig;
57
+ /**
58
+ * The Theme of the page's own mode, wherever this is asked -- inside a Surface tone too.
59
+ *
60
+ * What draws the page's tools rather than its content takes its colours from here: the Builder's scaffolds
61
+ * mark Layouts and Widgets in the editor's mode, and a Region turned inverse leaves them as they were
62
+ * instead of turning them with the content they stand around.
63
+ */
64
+ export declare function usePhiPageModeToken(): PhiThemeTokens;
52
65
  /** The locale the root adapter configures Ant Design with, for whoever hands it on. */
53
66
  export type PhiConfigLocale = ConfigProviderProps["locale"];
54
67
  /**
@@ -70,6 +70,17 @@ export function usePhiConfig() {
70
70
  }
71
71
  return config;
72
72
  }
73
+ /**
74
+ * The Theme of the page's own mode, wherever this is asked -- inside a Surface tone too.
75
+ *
76
+ * What draws the page's tools rather than its content takes its colours from here: the Builder's scaffolds
77
+ * mark Layouts and Widgets in the editor's mode, and a Region turned inverse leaves them as they were
78
+ * instead of turning them with the content they stand around.
79
+ */
80
+ export function usePhiPageModeToken() {
81
+ const config = usePhiConfig();
82
+ return config.pageToken ?? config.token;
83
+ }
73
84
  /**
74
85
  * The page's config in another mode: Ant Design's Theme for `mode` and the house config with that mode's
75
86
  * colours and tokens.
@@ -89,6 +100,6 @@ export function PhiNestedModeConfigProvider({ mode, theme, cssVarKey, locale, cu
89
100
  function PhiNestedModeConfigValue({ mode, customColors, children, }) {
90
101
  const outer = usePhiConfig();
91
102
  const { token } = antdTheme.useToken();
92
- const value = useMemo(() => ({ ...outer, mode, customColors, token }), [customColors, mode, outer, token]);
103
+ const value = useMemo(() => ({ ...outer, mode, customColors, token, pageToken: outer.pageToken ?? outer.token }), [customColors, mode, outer, token]);
93
104
  return _jsx(PhiConfigContext.Provider, { value: value, children: children });
94
105
  }
@@ -53,6 +53,13 @@ export declare const PHI_ROOT_BACKGROUND_IMAGE_SOURCE_KINDS: readonly PhiBackgro
53
53
  * simply resolves away.
54
54
  */
55
55
  export declare const PHI_ROOT_BACKGROUND_FILTERS: readonly PhiBackgroundFilter[];
56
+ /**
57
+ * The Base kinds the Theme Root Background offers and honours: every one but `theme`.
58
+ *
59
+ * `theme` is the Chrome Overlay standing in for a box's ground, and the Root Background is no box on the
60
+ * page but the ground beneath all of them. A stored value outside the offer resolves to `none`.
61
+ */
62
+ export declare const PHI_ROOT_BACKGROUND_BASE_KINDS: readonly PhiCmsBackgroundWidgetConfig["base"]["kind"][];
56
63
  /**
57
64
  * What the ground paints, without the geometry of the layer that paints it.
58
65
  *
@@ -59,8 +59,27 @@ export const PHI_ROOT_BACKGROUND_FILTERS = [];
59
59
  function withoutPhiRootBackgroundFilter(config) {
60
60
  return config ? { ...normalizePhiBackgroundWidgetConfig(config), filter: null } : null;
61
61
  }
62
+ /**
63
+ * The Base kinds the Theme Root Background offers and honours: every one but `theme`.
64
+ *
65
+ * `theme` is the Chrome Overlay standing in for a box's ground, and the Root Background is no box on the
66
+ * page but the ground beneath all of them. A stored value outside the offer resolves to `none`.
67
+ */
68
+ export const PHI_ROOT_BACKGROUND_BASE_KINDS = [
69
+ "none",
70
+ "color",
71
+ "gradient",
72
+ "image",
73
+ ];
62
74
  function readPhiRootBackgroundConfig(root, mode) {
63
- return (mode === "dark" ? root?.background?.dark : root?.background?.light) ?? null;
75
+ const configured = (mode === "dark" ? root?.background?.dark : root?.background?.light) ?? null;
76
+ if (configured == null) {
77
+ return null;
78
+ }
79
+ const normalized = normalizePhiBackgroundWidgetConfig(configured);
80
+ return PHI_ROOT_BACKGROUND_BASE_KINDS.includes(normalized.base.kind)
81
+ ? configured
82
+ : { ...normalized, base: { kind: "none" } };
64
83
  }
65
84
  /**
66
85
  * What the ground paints, without the geometry of the layer that paints it.
@@ -53,6 +53,9 @@ export function resolvePhiRootTheme({ siteTheme, mode, fonts, presets, }) {
53
53
  const resolvedShellHeaderMainBackground = resolvePhiShellRegionBackground(siteTheme?.shell, mode, { family: "header", region: "main" }) ??
54
54
  (mode === "dark" ? PHI_DEFAULT_DARK_NAV_BACKGROUND : undefined);
55
55
  const sharedComponentDefaults = buildPhiComponentTokens({
56
+ ...(typeof effectiveThemeTokens.fontSizeSM === "number" ? { fontSizeSM: effectiveThemeTokens.fontSizeSM } : {}),
57
+ ...(typeof effectiveThemeTokens.fontSize === "number" ? { fontSize: effectiveThemeTokens.fontSize } : {}),
58
+ ...(typeof effectiveThemeTokens.lineHeight === "number" ? { lineHeight: effectiveThemeTokens.lineHeight } : {}),
56
59
  layout: {
57
60
  ...(resolvedShellSiderBackground ? { siderBg: resolvedShellSiderBackground } : {}),
58
61
  ...(resolvedShellHeaderMainBackground ? { headerBg: resolvedShellHeaderMainBackground } : {}),
@@ -58,13 +58,18 @@ export declare const PHI_SHELL_CHROME_OVERLAY_IMAGE_SOURCE_KINDS: readonly PhiBa
58
58
  export declare const PHI_SHELL_CHROME_OVERLAY_MOTION_MODES: readonly PhiBackgroundMotionMode[];
59
59
  export type PhiShellChromeOverlayVariables = Record<`--phi-shell-chrome-${string}`, string>;
60
60
  /**
61
- * Whether this Region paints the shared overlay, which it does only while it authored nothing itself.
61
+ * Whether this Region paints the shared overlay, which it does while it authored nothing itself -- or
62
+ * while what it authored is the overlay.
62
63
  *
63
64
  * A Region that authored its own chrome paints over the Theme, and that is how an Area keeps a look of
64
65
  * its own. Authored means every carrier, not just one: the Region Surface's Background, the ground the
65
66
  * Shell record sets, and a glass pane the Region asks for over that ground. Reading only the
66
67
  * first let the Builder's Sider take the Site's overlay on top of the container ground it paints on
67
68
  * purpose, which is what this exists to prevent.
69
+ *
70
+ * A Background whose Base is `theme` states the overlay, so a Chrome Region takes it whatever the Shell
71
+ * record says. The caller asks this only for a Region without a tone: a toned one wants the overlay of
72
+ * its tone's mode, which it paints itself (`PHI_BACKGROUND_THEME_STYLE`).
68
73
  */
69
74
  export declare function phiRegionUsesShellChromeOverlay({ regionKey, backgroundConfig, pane, grounds, }: {
70
75
  regionKey: string;
@@ -125,6 +130,12 @@ export declare function resolvePhiShellChromePaneStickyTop(bands: readonly PhiSh
125
130
  */
126
131
  export declare const PHI_SHELL_HEADER_TOP_EXTENT_PROPERTY = "--phi-shell-header-top-extent";
127
132
  export declare const PHI_SHELL_HEADER_TOP_STACK_PROPERTY = "--phi-shell-header-top-stack";
133
+ /**
134
+ * The Header's measured bottom: the lowest bottom of every Header band stuck right now, written on the
135
+ * Shell by `usePhiShellStickyTop` (components/shell/use-phi-shell-sticky-top.ts). A sticky Table header
136
+ * and a stuck Sider stand under it; unset, it reads `0px`.
137
+ */
138
+ export declare const PHI_SHELL_STICKY_TOP_PROPERTY = "--phi-shell-sticky-top";
128
139
  /**
129
140
  * How `header_top` behaves where the browser decides it, as far as the Header pane is concerned.
130
141
  */
@@ -76,17 +76,27 @@ const PHI_SHELL_CHROME_OVERLAY_REGION_KEYS = [
76
76
  "footer_bottom",
77
77
  ];
78
78
  /**
79
- * Whether this Region paints the shared overlay, which it does only while it authored nothing itself.
79
+ * Whether this Region paints the shared overlay, which it does while it authored nothing itself -- or
80
+ * while what it authored is the overlay.
80
81
  *
81
82
  * A Region that authored its own chrome paints over the Theme, and that is how an Area keeps a look of
82
83
  * its own. Authored means every carrier, not just one: the Region Surface's Background, the ground the
83
84
  * Shell record sets, and a glass pane the Region asks for over that ground. Reading only the
84
85
  * first let the Builder's Sider take the Site's overlay on top of the container ground it paints on
85
86
  * purpose, which is what this exists to prevent.
87
+ *
88
+ * A Background whose Base is `theme` states the overlay, so a Chrome Region takes it whatever the Shell
89
+ * record says. The caller asks this only for a Region without a tone: a toned one wants the overlay of
90
+ * its tone's mode, which it paints itself (`PHI_BACKGROUND_THEME_STYLE`).
86
91
  */
87
92
  export function phiRegionUsesShellChromeOverlay({ regionKey, backgroundConfig, pane, grounds, }) {
88
- return (PHI_SHELL_CHROME_OVERLAY_REGION_KEYS.includes(regionKey) &&
89
- backgroundConfig == null &&
93
+ if (!PHI_SHELL_CHROME_OVERLAY_REGION_KEYS.includes(regionKey)) {
94
+ return false;
95
+ }
96
+ if (backgroundConfig != null && normalizePhiBackgroundWidgetConfig(backgroundConfig).base.kind === "theme") {
97
+ return true;
98
+ }
99
+ return (backgroundConfig == null &&
90
100
  pane == null &&
91
101
  grounds.every((ground) => ground == null));
92
102
  }
@@ -223,6 +233,12 @@ export function resolvePhiShellChromePaneStickyTop(bands) {
223
233
  */
224
234
  export const PHI_SHELL_HEADER_TOP_EXTENT_PROPERTY = "--phi-shell-header-top-extent";
225
235
  export const PHI_SHELL_HEADER_TOP_STACK_PROPERTY = "--phi-shell-header-top-stack";
236
+ /**
237
+ * The Header's measured bottom: the lowest bottom of every Header band stuck right now, written on the
238
+ * Shell by `usePhiShellStickyTop` (components/shell/use-phi-shell-sticky-top.ts). A sticky Table header
239
+ * and a stuck Sider stand under it; unset, it reads `0px`.
240
+ */
241
+ export const PHI_SHELL_STICKY_TOP_PROPERTY = "--phi-shell-sticky-top";
226
242
  /**
227
243
  * Where the Header pane sticks when `header_top` may come and go.
228
244
  *