@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
@@ -138,6 +138,7 @@ export const PHI_THEME_TOKEN_KEYS = [
138
138
  "fontSizeHeading5",
139
139
  "fontWeightStrong",
140
140
  "lineHeight",
141
+ "lineHeightSM",
141
142
  "lineHeightLG",
142
143
  "lineHeightHeading1",
143
144
  "lineHeightHeading2",
@@ -16,6 +16,11 @@ export type PhiComponentTokenOptions = {
16
16
  overrides?: Record<string, unknown>;
17
17
  };
18
18
  menu?: Record<string, unknown>;
19
+ /** The Theme's small size (`fontSizeSM`), for the parts that take it; absent, the scale's `sm`. */
20
+ fontSizeSM?: number;
21
+ /** The Theme's body size and line height (`fontSize`, `lineHeight`); absent, the scale's `base`. */
22
+ fontSize?: number;
23
+ lineHeight?: number;
19
24
  overrides?: Record<string, Record<string, unknown>>;
20
25
  };
21
26
  export type PhiThemeTokens = {
@@ -65,6 +65,9 @@ export function buildPhiThemeStructuralTokens(options = {}) {
65
65
  return Object.fromEntries(Object.entries(buildPhiThemeTokens(options)).filter(([key]) => !key.startsWith("color")));
66
66
  }
67
67
  export function buildPhiComponentTokens(options = {}) {
68
+ const fontSizeSM = options.fontSizeSM ?? PHI_FONT_SIZES.sm;
69
+ const fontSize = options.fontSize ?? PHI_FONT_SIZES.base;
70
+ const lineHeight = options.lineHeight ?? lineHeightFor(PHI_FONT_SIZES.base);
68
71
  return {
69
72
  Layout: {
70
73
  headerHeight: PHI_LAYOUT.headerHeight,
@@ -81,6 +84,24 @@ export function buildPhiComponentTokens(options = {}) {
81
84
  itemMarginInline: PHI_SPACE.sm,
82
85
  ...options.menu,
83
86
  },
87
+ /*
88
+ * The parts that take the scale's small size rather than the body's. A table is read across, not down:
89
+ * its cells are small, as a plain table's are (controls.css). A compact control -- `size="small"` --
90
+ * is small in its words as well as its height; Ant Design gives it the body size unless told.
91
+ */
92
+ Table: { cellFontSize: fontSizeSM, cellFontSizeMD: fontSizeSM, cellFontSizeSM: fontSizeSM },
93
+ // A Tree lists rows like a Table and writes like one: its titles, and the switcher's icon with them.
94
+ Tree: { fontSize: fontSizeSM },
95
+ // A contents list beside a text is a list like a Tree's, and writes as small.
96
+ Anchor: { fontSize: fontSizeSM },
97
+ // A Divider's words label a section; Ant Design sets them at `lg`, which the scale made a heading's size.
98
+ Divider: { fontSizeLG: fontSize },
99
+ Input: { inputFontSizeSM: fontSizeSM },
100
+ InputNumber: { inputFontSizeSM: fontSizeSM },
101
+ DatePicker: { inputFontSizeSM: fontSizeSM },
102
+ Button: { contentFontSizeSM: fontSizeSM },
103
+ // An Overlay's title is a label over its body, in the body's size; Ant Design gives a Modal the h5's.
104
+ Modal: { titleFontSize: fontSize, titleLineHeight: lineHeight },
84
105
  ...options.overrides,
85
106
  };
86
107
  }
@@ -19,28 +19,29 @@ export declare const PHI_PADDING: {
19
19
  /**
20
20
  * The type scale: one list for every size a Phi surface states.
21
21
  *
22
- * Two halves. Up to `lg` it climbs in steps of 2 px, because an interface needs its small sizes close
23
- * together -- a caption, a tag, a label, the text beside them. From `xl` it is the spacing sequence, where
24
- * the steps are meant to be far apart. Every size is set rather than left to Ant Design's curve, which
25
- * lands between the steps.
22
+ * A ladder of phi from the body size 16 -- the browser's own, and what reading text on the web is set in.
23
+ * `sm`, `lg`, `xxl` and `display` are the Fibonacci sizes around it (13, 21, 34, 55), `xl` is 16 x phi (26),
24
+ * between 21 and 34 where their geometric mean falls, and `xs` keeps the 9 a counter or a superscript needs.
25
+ * Every size is set rather than left to Ant Design's curve, which lands between the steps.
26
26
  *
27
27
  * `sm` to `xl` are handed to Ant Design as its tokens; `xs`, `xxl` and `display` have none and are read
28
- * from here, fixed until v1. The headings take their sizes from the same list: `h4` and `h5` are both the
29
- * body size and differ by weight and colour alone. `display` is no heading level but a size, for a hero's
30
- * or a landing's title, and is not offered beside the others.
28
+ * from here, fixed until v1. The headings take their sizes from the same list: `h1` the page's title at
29
+ * `xxl`, about twice the body, then `xl`, `lg`, and `h4` and `h5` at the body and `sm` sizes, set apart by
30
+ * weight and colour. `display` is no heading level but a size, for a hero's or a landing's title, and is
31
+ * not offered beside the others.
31
32
  */
32
33
  export declare const PHI_FONT_SIZES: {
33
34
  readonly xs: 9;
34
- readonly sm: 11;
35
- readonly base: 13;
36
- readonly lg: 15;
37
- readonly xl: 21;
35
+ readonly sm: 13;
36
+ readonly base: 16;
37
+ readonly lg: 21;
38
+ readonly xl: 26;
38
39
  readonly xxl: 34;
39
40
  readonly display: 55;
40
41
  readonly heading1: 34;
41
- readonly heading2: 21;
42
- readonly heading3: 15;
43
- readonly heading4: 13;
42
+ readonly heading2: 26;
43
+ readonly heading3: 21;
44
+ readonly heading4: 16;
44
45
  readonly heading5: 13;
45
46
  };
46
47
  export declare const PHI_RADII: {
@@ -54,7 +55,7 @@ export declare const PHI_RADII: {
54
55
  readonly xxl: 89;
55
56
  };
56
57
  export declare const PHI_CONTROL_HEIGHTS: {
57
- readonly sm: 21;
58
+ readonly sm: 26;
58
59
  readonly md: 34;
59
60
  readonly lg: 55;
60
61
  };
@@ -19,28 +19,29 @@ export const PHI_PADDING = {
19
19
  /**
20
20
  * The type scale: one list for every size a Phi surface states.
21
21
  *
22
- * Two halves. Up to `lg` it climbs in steps of 2 px, because an interface needs its small sizes close
23
- * together -- a caption, a tag, a label, the text beside them. From `xl` it is the spacing sequence, where
24
- * the steps are meant to be far apart. Every size is set rather than left to Ant Design's curve, which
25
- * lands between the steps.
22
+ * A ladder of phi from the body size 16 -- the browser's own, and what reading text on the web is set in.
23
+ * `sm`, `lg`, `xxl` and `display` are the Fibonacci sizes around it (13, 21, 34, 55), `xl` is 16 x phi (26),
24
+ * between 21 and 34 where their geometric mean falls, and `xs` keeps the 9 a counter or a superscript needs.
25
+ * Every size is set rather than left to Ant Design's curve, which lands between the steps.
26
26
  *
27
27
  * `sm` to `xl` are handed to Ant Design as its tokens; `xs`, `xxl` and `display` have none and are read
28
- * from here, fixed until v1. The headings take their sizes from the same list: `h4` and `h5` are both the
29
- * body size and differ by weight and colour alone. `display` is no heading level but a size, for a hero's
30
- * or a landing's title, and is not offered beside the others.
28
+ * from here, fixed until v1. The headings take their sizes from the same list: `h1` the page's title at
29
+ * `xxl`, about twice the body, then `xl`, `lg`, and `h4` and `h5` at the body and `sm` sizes, set apart by
30
+ * weight and colour. `display` is no heading level but a size, for a hero's or a landing's title, and is
31
+ * not offered beside the others.
31
32
  */
32
33
  export const PHI_FONT_SIZES = {
33
34
  xs: 9,
34
- sm: 11,
35
- base: 13,
36
- lg: 15,
37
- xl: 21,
35
+ sm: 13,
36
+ base: 16,
37
+ lg: 21,
38
+ xl: 26,
38
39
  xxl: 34,
39
40
  display: 55,
40
41
  heading1: 34,
41
- heading2: 21,
42
- heading3: 15,
43
- heading4: 13,
42
+ heading2: 26,
43
+ heading3: 21,
44
+ heading4: 16,
44
45
  heading5: 13,
45
46
  };
46
47
  export const PHI_RADII = {
@@ -54,7 +55,7 @@ export const PHI_RADII = {
54
55
  xxl: 89,
55
56
  };
56
57
  export const PHI_CONTROL_HEIGHTS = {
57
- sm: 21,
58
+ sm: 26,
58
59
  md: 34,
59
60
  lg: 55,
60
61
  };
@@ -4,42 +4,28 @@ import { readPhiCmsMountPolicy } from "./cms-mount-policy";
4
4
  import { clampPhiSequenceTransitionMs, readPhiMotionEasing, PHI_SEQUENCE_ANCHORS, PHI_SEQUENCE_TRANSITIONS, } from "../helpers/motion";
5
5
  import { readPhiLengthValue } from "./length";
6
6
  import { isPhiAnchorWidgetPlacement, resolvePhiRenderableBlockAnchor, } from "../components/controls/phi-anchor-control-contract";
7
- import { readBoolean, readCssSize, readNumber, readRenderableBlockConfig, readString, } from "../components/widgets/config/parser-primitives";
7
+ import { readCssSize, readRenderableBlockConfig, } from "../components/widgets/config/parser-primitives";
8
8
  import { applyPhiLayoutDefaults } from "../helpers/cms-layout-defaults";
9
9
  import { resolvePhiLayoutDefaults } from "../helpers/cms-layout-defaults";
10
10
  import { normalizeRenderableBlockAnchor } from "../helpers/renderable-block-anchor";
11
11
  import { isPhiRecord } from "../helpers/is-record";
12
+ import { createPhiConfigReader } from "../components/widgets/config/strict-config-reader";
12
13
  import { PHI_SPACING_SCALE_KEYS } from "../components/widgets/config/spacing-options";
13
14
  import { PHI_GRID_COLUMN_COUNTS, isPhiGridColumnCount } from "../constants/grid-columns";
14
- function readInitialSlotStates(value) {
15
- if (Array.isArray(value)) {
16
- const normalized = value.map((candidate) => candidate === "expanded" || candidate === "collapsed" || candidate === "hidden" ? candidate : undefined);
17
- return normalized.some((candidate) => candidate !== undefined) ? normalized : undefined;
18
- }
19
- if (!value || typeof value !== "object") {
20
- return undefined;
21
- }
22
- const raw = value;
23
- const next = {};
24
- for (const [key, candidate] of Object.entries(raw)) {
25
- const slotIndex = Number(key);
26
- if (!Number.isInteger(slotIndex) || slotIndex < 0) {
27
- continue;
28
- }
29
- if (candidate === "expanded" || candidate === "collapsed" || candidate === "hidden") {
30
- next[slotIndex] = candidate;
15
+ const PHI_LAYOUT_SLOT_STATES = ["expanded", "collapsed", "hidden"];
16
+ /** A Layout's starting slot states: a list by slot, gaps allowed, or a record keyed by slot index. */
17
+ function readInitialSlotStates(reader) {
18
+ return reader.value("initialSlotStates", "slot states by slot index", (value) => {
19
+ const isState = (candidate) => candidate == null || PHI_LAYOUT_SLOT_STATES.includes(candidate);
20
+ if (Array.isArray(value)) {
21
+ return value.every(isState) ? value : undefined;
31
22
  }
32
- }
33
- return Object.keys(next).length > 0 ? next : undefined;
34
- }
35
- function readStringArray(value) {
36
- if (!Array.isArray(value)) {
37
- return undefined;
38
- }
39
- const next = value
40
- .map((candidate) => (typeof candidate === "string" ? candidate.trim() : ""))
41
- .filter((candidate) => candidate.length > 0);
42
- return [...new Set(next)];
23
+ if (!isPhiRecord(value))
24
+ return undefined;
25
+ return Object.entries(value).every(([key, candidate]) => Number.isInteger(Number(key)) && Number(key) >= 0 && isState(candidate))
26
+ ? value
27
+ : undefined;
28
+ });
43
29
  }
44
30
  export function normalizePhiPaddingWidgetConfig(config) {
45
31
  if (!isPhiRecord(config)) {
@@ -153,18 +139,14 @@ function readRenderableBlockAnchorOrPlacement(value) {
153
139
  ? resolvePhiRenderableBlockAnchor(value)
154
140
  : undefined;
155
141
  }
156
- function readGridResponsiveCount(value, accepts) {
157
- if (!isPhiRecord(value))
158
- return undefined;
159
- const record = value;
160
- const read = (key) => {
161
- const candidate = readNumber(record[key]);
162
- return candidate != null && Number.isInteger(candidate) && accepts(candidate) ? candidate : undefined;
163
- };
164
- const responsive = { compact: read("compact"), medium: read("medium"), wide: read("wide") };
165
- return responsive.compact != null || responsive.medium != null || responsive.wide != null
166
- ? responsive
167
- : undefined;
142
+ function readLayoutAnchor(reader) {
143
+ return reader.value("anchor", "an anchor or a placement", readRenderableBlockAnchorOrPlacement);
144
+ }
145
+ function readGridResponsiveCount(reader, key, expected, accepts) {
146
+ return reader.object(key, (countReader) => {
147
+ const read = (width) => countReader.value(width, expected, (candidate) => typeof candidate === "number" && Number.isInteger(candidate) && accepts(candidate) ? candidate : undefined);
148
+ return { compact: read("compact"), medium: read("medium"), wide: read("wide") };
149
+ });
168
150
  }
169
151
  const PHI_GRID_MAX_COLUMNS = Math.max(...PHI_GRID_COLUMN_COUNTS);
170
152
  /*
@@ -172,32 +154,43 @@ const PHI_GRID_MAX_COLUMNS = Math.max(...PHI_GRID_COLUMN_COUNTS);
172
154
  * they fit the row at a given width is answered where the row is known, by clamping
173
155
  * (`resolvePhiGridSlotPlacement`): a Grid whose columns were reduced keeps its stated placements.
174
156
  */
175
- function readGridSlotPlacement(value, slotIndexFromArray) {
176
- if (!isPhiRecord(value)) {
177
- return null;
178
- }
179
- const slot = value;
180
- const slotIndex = readNumber(slot.slotIndex) ?? slotIndexFromArray;
181
- if (!Number.isInteger(slotIndex) || slotIndex == null || slotIndex < 0) {
182
- return null;
183
- }
184
- const span = readGridResponsiveCount(slot.span, (candidate) => candidate >= 1 && candidate <= PHI_GRID_MAX_COLUMNS);
185
- const offset = readGridResponsiveCount(slot.offset, (candidate) => candidate >= 0 && candidate < PHI_GRID_MAX_COLUMNS);
157
+ function readGridSlotPlacement(reader, slotIndexFromArray) {
158
+ const slotIndex = reader.value("slotIndex", "a slot index", (candidate) => typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 0 ? candidate : undefined) ?? slotIndexFromArray;
159
+ const span = readGridResponsiveCount(reader, "span", `a whole number from 1 to ${PHI_GRID_MAX_COLUMNS}`, (candidate) => candidate >= 1 && candidate <= PHI_GRID_MAX_COLUMNS);
160
+ const offset = readGridResponsiveCount(reader, "offset", `a whole number from 0 to ${PHI_GRID_MAX_COLUMNS - 1}`, (candidate) => candidate >= 0 && candidate < PHI_GRID_MAX_COLUMNS);
186
161
  if (!span && !offset)
187
- return null;
162
+ reader.fail("span", "a span or an offset", undefined);
188
163
  return { slotIndex, span, offset };
189
164
  }
190
165
  /**
191
- * A shared Layout field, read the same way wherever it appears: a line on the 24-track form grid, so
192
- * anything outside 2..24 is not a narrower column but a mistake, and is dropped rather than clamped.
166
+ * The fields many Layouts share, read the same way wherever they appear. A label end is a line on the
167
+ * 24-track form grid, so anything outside 2..24 is not a narrower column but a mistake.
193
168
  */
194
- function readPhiLayoutLabelEnd(value) {
195
- const labelEnd = readNumber(value);
196
- return labelEnd !== undefined && Number.isInteger(labelEnd) && labelEnd >= 2 && labelEnd <= 24
197
- ? labelEnd
198
- : undefined;
169
+ function readCssSizeField(reader, key) {
170
+ return reader.value(key, "a CSS size", (value) => (typeof value === "number" && Number.isFinite(value)) || typeof value === "string" ? value : undefined);
171
+ }
172
+ function readLengthField(reader, key) {
173
+ return reader.value(key, "a CSS length", (value) => readPhiLengthValue(value) ?? undefined);
174
+ }
175
+ function readLayoutLabelEnd(reader) {
176
+ return reader.value("labelEnd", "a whole number from 2 to 24", (value) => typeof value === "number" && Number.isInteger(value) && value >= 2 && value <= 24 ? value : undefined);
177
+ }
178
+ function readLayoutPadding(reader) {
179
+ return {
180
+ padding: readCssSizeField(reader, "padding"),
181
+ paddingLeft: readCssSizeField(reader, "paddingLeft"),
182
+ paddingRight: readCssSizeField(reader, "paddingRight"),
183
+ paddingTop: readCssSizeField(reader, "paddingTop"),
184
+ paddingBottom: readCssSizeField(reader, "paddingBottom"),
185
+ };
186
+ }
187
+ function readFlexWrap(reader) {
188
+ return reader.value("wrap", "true, false or a flex wrap", (value) => typeof value === "boolean" || value === "nowrap" || value === "wrap" || value === "wrap-reverse"
189
+ ? value
190
+ : undefined) ?? false;
199
191
  }
200
192
  export function parsePhiCmsContentLayoutConfig(config) {
193
+ const reader = createPhiConfigReader(config);
201
194
  return applyPhiLayoutDefaults({
202
195
  ...readRenderableBlockConfig(config),
203
196
  /*
@@ -207,82 +200,65 @@ export function parsePhiCmsContentLayoutConfig(config) {
207
200
  * constraints never had the second way at all -- nothing has ever read a flat `maxWidth`.
208
201
  */
209
202
  size: normalizePhiRenderableBlockResponsiveSize(config.size),
210
- margin: readCssSize(config.margin),
211
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
212
- padding: readCssSize(config.padding),
213
- paddingLeft: readCssSize(config.paddingLeft),
214
- paddingRight: readCssSize(config.paddingRight),
215
- paddingTop: readCssSize(config.paddingTop),
216
- paddingBottom: readCssSize(config.paddingBottom),
203
+ margin: readCssSizeField(reader, "margin"),
204
+ labelEnd: readLayoutLabelEnd(reader),
205
+ ...readLayoutPadding(reader),
217
206
  /*
218
207
  * Handed on as the block anchor, like every other Layout's. This one used to be folded into a
219
208
  * placement name here, and the renderer then asked the name for its `horizontal` -- a string has
220
209
  * none, so a Content Layout anchored left drew centred wherever the parsed config reached it, in
221
210
  * preview and live, while the Builder, which hands the object straight through, drew it left.
222
211
  */
223
- anchor: readRenderableBlockAnchorOrPlacement(config.anchor),
212
+ anchor: readLayoutAnchor(reader),
224
213
  }, resolvePhiLayoutDefaults("content"));
225
214
  }
226
215
  export function parsePhiCmsFlexLayoutConfig(config) {
227
- const distribution = readString(config.distribution);
216
+ const reader = createPhiConfigReader(config);
228
217
  return applyPhiLayoutDefaults({
229
218
  ...readRenderableBlockConfig(config),
230
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
231
- initialSlotStates: readInitialSlotStates(config.initialSlotStates),
232
- padding: readCssSize(config.padding),
233
- paddingLeft: readCssSize(config.paddingLeft),
234
- paddingRight: readCssSize(config.paddingRight),
235
- paddingTop: readCssSize(config.paddingTop),
236
- paddingBottom: readCssSize(config.paddingBottom),
237
- gap: readCssSize(config.gap),
238
- verticalSeparators: readBoolean(config.verticalSeparators) ?? false,
239
- separatorBeforeFirst: readBoolean(config.separatorBeforeFirst) ?? false,
240
- separatorSpan: readPhiLengthValue(config.separatorSpan) ?? undefined,
241
- anchor: readRenderableBlockAnchorOrPlacement(config.anchor),
242
- distribution: distribution === "between" || distribution === "around" || distribution === "evenly"
243
- ? distribution
244
- : "anchor",
245
- wrap: readBoolean(config.wrap) ??
246
- readString(config.wrap) ??
247
- false,
219
+ labelEnd: readLayoutLabelEnd(reader),
220
+ initialSlotStates: readInitialSlotStates(reader),
221
+ ...readLayoutPadding(reader),
222
+ gap: readCssSizeField(reader, "gap"),
223
+ verticalSeparators: reader.boolean("verticalSeparators") ?? false,
224
+ separatorBeforeFirst: reader.boolean("separatorBeforeFirst") ?? false,
225
+ separatorSpan: readLengthField(reader, "separatorSpan"),
226
+ anchor: readLayoutAnchor(reader),
227
+ distribution: reader.oneOf("distribution", ["anchor", "between", "around", "evenly"]) ?? "anchor",
228
+ wrap: readFlexWrap(reader),
248
229
  }, resolvePhiLayoutDefaults("flex"));
249
230
  }
250
231
  export function parsePhiCmsFlexVerticalLayoutConfig(config) {
232
+ const reader = createPhiConfigReader(config);
251
233
  return applyPhiLayoutDefaults({
252
234
  ...readRenderableBlockConfig(config),
253
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
254
- initialSlotStates: readInitialSlotStates(config.initialSlotStates),
255
- padding: readCssSize(config.padding),
256
- paddingLeft: readCssSize(config.paddingLeft),
257
- paddingRight: readCssSize(config.paddingRight),
258
- paddingTop: readCssSize(config.paddingTop),
259
- paddingBottom: readCssSize(config.paddingBottom),
260
- gap: readCssSize(config.gap),
261
- anchor: readRenderableBlockAnchorOrPlacement(config.anchor),
235
+ labelEnd: readLayoutLabelEnd(reader),
236
+ initialSlotStates: readInitialSlotStates(reader),
237
+ ...readLayoutPadding(reader),
238
+ gap: readCssSizeField(reader, "gap"),
239
+ anchor: readLayoutAnchor(reader),
262
240
  }, resolvePhiLayoutDefaults("verticalflex"));
263
241
  }
264
242
  export function parsePhiCmsMasonryLayoutConfig(config) {
243
+ const reader = createPhiConfigReader(config);
265
244
  return applyPhiLayoutDefaults({
266
245
  ...readRenderableBlockConfig(config),
267
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
268
- padding: readCssSize(config.padding),
269
- paddingLeft: readCssSize(config.paddingLeft),
270
- paddingRight: readCssSize(config.paddingRight),
271
- paddingTop: readCssSize(config.paddingTop),
272
- paddingBottom: readCssSize(config.paddingBottom),
273
- columns: readGridResponsiveCount(config.columns, isPhiGridColumnCount),
274
- gap: readCssSize(config.gap),
246
+ labelEnd: readLayoutLabelEnd(reader),
247
+ ...readLayoutPadding(reader),
248
+ columns: readGridResponsiveCount(reader, "columns", "a Grid column count", isPhiGridColumnCount),
249
+ gap: readCssSizeField(reader, "gap"),
275
250
  }, resolvePhiLayoutDefaults("masonry"));
276
251
  }
277
252
  export function parsePhiCmsStackLayoutConfig(config) {
253
+ const reader = createPhiConfigReader(config);
278
254
  return applyPhiLayoutDefaults({
279
255
  ...readRenderableBlockConfig(config),
280
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
281
- padding: readCssSize(config.padding),
282
- defaultActiveSlotKey: readString(config.defaultActiveSlotKey),
283
- slotDisplay: config.slotDisplay === "stacked" ? "stacked" : "single",
256
+ labelEnd: readLayoutLabelEnd(reader),
257
+ padding: readCssSizeField(reader, "padding"),
258
+ defaultActiveSlotKey: reader.string("defaultActiveSlotKey"),
259
+ slotDisplay: reader.oneOf("slotDisplay", ["single", "stacked"]) ?? "single",
284
260
  mountPolicy: readPhiCmsMountPolicy(config.mountPolicy, "remount"),
285
- slotTransition: config.slotTransition === "fade-over" ? "fade-over" : "none",
261
+ slotTransition: reader.oneOf("slotTransition", ["none", "fade-over"]) ?? "none",
286
262
  // Absent means "whatever the theme does", which is why the fallback is read from the token
287
263
  // rather than written here as a number.
288
264
  ...(config.slotTransitionDurationMs === undefined ? {} : {
@@ -338,9 +314,9 @@ export function parsePhiCmsCarouselLayoutConfig(config) {
338
314
  const slotGap = readCarouselMember(config.slotGap, PHI_SPACING_SCALE_KEYS, "slotGap");
339
315
  return applyPhiLayoutDefaults({
340
316
  ...readRenderableBlockConfig(config),
341
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
342
- padding: readCssSize(config.padding),
343
- defaultActiveSlotKey: readString(config.defaultActiveSlotKey),
317
+ labelEnd: readLayoutLabelEnd(createPhiConfigReader(config)),
318
+ padding: readCssSizeField(createPhiConfigReader(config), "padding"),
319
+ defaultActiveSlotKey: createPhiConfigReader(config).string("defaultActiveSlotKey"),
344
320
  ...(visibleSlots === undefined ? {} : { visibleSlots }),
345
321
  ...(windowAnchor === undefined ? {} : { windowAnchor }),
346
322
  ...(transition === undefined ? {} : { transition }),
@@ -361,100 +337,81 @@ export function parsePhiCmsCarouselLayoutConfig(config) {
361
337
  ...(lookahead === undefined ? {} : { lookahead }),
362
338
  }, resolvePhiLayoutDefaults("carousel"));
363
339
  }
364
- function readCollapsibleTrigger(value) {
365
- return value === "header" || value === "icon" || value === "disabled" ? value : undefined;
366
- }
367
- function readCollapsibleSize(value) {
368
- return readPhiControlSize(value);
369
- }
370
- function readExpandIconPlacement(value) {
371
- return value === "start" || value === "end" ? value : undefined;
372
- }
373
- function readSlotTexts(value) {
374
- if (!Array.isArray(value)) {
340
+ /** Panel titles or descriptions by slot: texts, an empty one for a slot that has none; trailing empties trimmed. */
341
+ function readSlotTexts(reader, key) {
342
+ const texts = reader.value(key, "a list of texts", (value) => Array.isArray(value) && value.every((candidate) => typeof candidate === "string")
343
+ ? value.map((candidate) => candidate.trim())
344
+ : undefined);
345
+ if (!texts)
375
346
  return undefined;
376
- }
377
- const texts = value.map((candidate) => (typeof candidate === "string" ? candidate.trim() : ""));
378
- while (texts.length > 0 && !texts[texts.length - 1]) {
347
+ while (texts.length > 0 && !texts[texts.length - 1])
379
348
  texts.pop();
380
- }
381
349
  return texts.length > 0 ? texts : undefined;
382
350
  }
383
351
  export function parsePhiCmsCollapsibleLayoutConfig(config) {
352
+ const reader = createPhiConfigReader(config);
353
+ const defaultOpenSlotKeys = reader.stringList("defaultOpenSlotKeys");
384
354
  return applyPhiLayoutDefaults({
385
355
  ...readRenderableBlockConfig(config),
386
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
387
- initialSlotStates: readInitialSlotStates(config.initialSlotStates),
388
- padding: readCssSize(config.padding),
389
- paddingLeft: readCssSize(config.paddingLeft),
390
- paddingRight: readCssSize(config.paddingRight),
391
- paddingTop: readCssSize(config.paddingTop),
392
- paddingBottom: readCssSize(config.paddingBottom),
393
- anchor: readRenderableBlockAnchorOrPlacement(config.anchor),
394
- panelMinHeight: readPhiLengthValue(config.panelMinHeight) ?? undefined,
395
- accordion: readBoolean(config.accordion),
396
- slotTitles: readSlotTexts(config.slotTitles),
397
- slotDescriptions: readSlotTexts(config.slotDescriptions),
398
- defaultOpenSlotKeys: readStringArray(config.defaultOpenSlotKeys),
399
- collapsible: readCollapsibleTrigger(config.collapsible),
400
- ghost: readBoolean(config.ghost),
401
- expandIconPlacement: readExpandIconPlacement(config.expandIconPlacement),
402
- collapseSize: readCollapsibleSize(config.collapseSize),
403
- titleStrong: readBoolean(config.titleStrong),
404
- headerPadding: readCssSize(config.headerPadding),
405
- innerPadding: readCssSize(config.innerPadding),
356
+ labelEnd: readLayoutLabelEnd(reader),
357
+ initialSlotStates: readInitialSlotStates(reader),
358
+ ...readLayoutPadding(reader),
359
+ anchor: readLayoutAnchor(reader),
360
+ panelMinHeight: readLengthField(reader, "panelMinHeight"),
361
+ accordion: reader.boolean("accordion"),
362
+ slotTitles: readSlotTexts(reader, "slotTitles"),
363
+ slotDescriptions: readSlotTexts(reader, "slotDescriptions"),
364
+ defaultOpenSlotKeys: defaultOpenSlotKeys
365
+ ? [...new Set(defaultOpenSlotKeys.map((key) => key.trim()).filter(Boolean))]
366
+ : undefined,
367
+ collapsible: reader.oneOf("collapsible", ["header", "icon", "disabled"]),
368
+ ghost: reader.boolean("ghost"),
369
+ expandIconPlacement: reader.oneOf("expandIconPlacement", ["start", "end"]),
370
+ collapseSize: reader.value("collapseSize", "a control size", readPhiControlSize),
371
+ titleStrong: reader.boolean("titleStrong"),
372
+ headerPadding: readCssSizeField(reader, "headerPadding"),
373
+ innerPadding: readCssSizeField(reader, "innerPadding"),
406
374
  }, resolvePhiLayoutDefaults("collapsible"));
407
375
  }
408
376
  export function parsePhiCmsGridLayoutConfig(config) {
377
+ const reader = createPhiConfigReader(config);
409
378
  return applyPhiLayoutDefaults({
410
379
  ...readRenderableBlockConfig(config),
411
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
412
- padding: readCssSize(config.padding),
413
- paddingLeft: readCssSize(config.paddingLeft),
414
- paddingRight: readCssSize(config.paddingRight),
415
- paddingTop: readCssSize(config.paddingTop),
416
- paddingBottom: readCssSize(config.paddingBottom),
417
- gap: readCssSize(config.gap),
418
- anchor: readRenderableBlockAnchorOrPlacement(config.anchor),
419
- columns: readGridResponsiveCount(config.columns, isPhiGridColumnCount),
420
- slotPlacements: Array.isArray(config.slotPlacements)
421
- ? config.slotPlacements
422
- .map((slot, slotIndex) => readGridSlotPlacement(slot, slotIndex))
423
- .filter((slot) => slot !== null)
424
- : undefined,
380
+ labelEnd: readLayoutLabelEnd(reader),
381
+ ...readLayoutPadding(reader),
382
+ gap: readCssSizeField(reader, "gap"),
383
+ anchor: readLayoutAnchor(reader),
384
+ columns: readGridResponsiveCount(reader, "columns", "a Grid column count", isPhiGridColumnCount),
385
+ slotPlacements: reader.list("slotPlacements", readGridSlotPlacement),
425
386
  }, resolvePhiLayoutDefaults("grid"));
426
387
  }
427
388
  export function parsePhiCmsThreeColumnLayoutConfig(config) {
389
+ const reader = createPhiConfigReader(config);
428
390
  return applyPhiLayoutDefaults({
429
391
  ...readRenderableBlockConfig(config),
430
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
431
- padding: readCssSize(config.padding),
432
- paddingLeft: readCssSize(config.paddingLeft),
433
- paddingRight: readCssSize(config.paddingRight),
434
- paddingTop: readCssSize(config.paddingTop),
435
- paddingBottom: readCssSize(config.paddingBottom),
436
- balancedSides: readBoolean(config.balancedSides) ?? true,
437
- gap: readCssSize(config.gap),
438
- anchor: readRenderableBlockAnchorOrPlacement(config.anchor),
439
- align: readString(config.align),
440
- justify: readString(config.justify),
441
- wrap: readBoolean(config.wrap) ??
442
- readString(config.wrap) ??
443
- false,
444
- leftWidth: readPhiLengthValue(config.leftWidth) ?? undefined,
445
- middleWidth: readPhiLengthValue(config.middleWidth) ?? undefined,
446
- rightWidth: readPhiLengthValue(config.rightWidth) ?? undefined,
447
- contentAlign: readString(config.contentAlign),
392
+ labelEnd: readLayoutLabelEnd(reader),
393
+ ...readLayoutPadding(reader),
394
+ balancedSides: reader.boolean("balancedSides") ?? true,
395
+ gap: readCssSizeField(reader, "gap"),
396
+ anchor: readLayoutAnchor(reader),
397
+ align: reader.string("align"),
398
+ justify: reader.string("justify"),
399
+ wrap: readFlexWrap(reader),
400
+ leftWidth: readLengthField(reader, "leftWidth"),
401
+ middleWidth: readLengthField(reader, "middleWidth"),
402
+ rightWidth: readLengthField(reader, "rightWidth"),
403
+ contentAlign: reader.string("contentAlign"),
448
404
  }, resolvePhiLayoutDefaults("threecol"));
449
405
  }
450
406
  export function parsePhiCmsSplitCardLayoutConfig(config) {
407
+ const reader = createPhiConfigReader(config);
451
408
  return applyPhiLayoutDefaults({
452
409
  ...readRenderableBlockConfig(config),
453
- labelEnd: readPhiLayoutLabelEnd(config.labelEnd),
454
- gap: readCssSize(config.gap),
455
- swapRatio: readBoolean(config.swapRatio),
456
- padding: readCssSize(config.padding),
457
- paddingTop: readCssSize(config.paddingTop),
458
- paddingBottom: readCssSize(config.paddingBottom),
410
+ labelEnd: readLayoutLabelEnd(reader),
411
+ gap: readCssSizeField(reader, "gap"),
412
+ swapRatio: reader.boolean("swapRatio"),
413
+ padding: readCssSizeField(reader, "padding"),
414
+ paddingTop: readCssSizeField(reader, "paddingTop"),
415
+ paddingBottom: readCssSizeField(reader, "paddingBottom"),
459
416
  }, resolvePhiLayoutDefaults("split"));
460
417
  }