@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,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cloneElement, isValidElement } from "react";
3
+ import { resolvePhiRenderFailureCode } from "../widgets/config/strict-config-reader";
3
4
  import { readPhiCmsRegionPageScope, resolvePhiCmsRegionPageScope } from "../../helpers/region-page-scope";
4
5
  import { isPhiCmsWidgetContentUnpublished } from "../../helpers/cms-content-binding";
5
6
  import { comparePhiCmsInstanceIds } from "../../types/cms-instance-id";
@@ -435,7 +436,7 @@ function renderContentWidget(widget, context) {
435
436
  }
436
437
  catch (error) {
437
438
  return renderCmsDiagnostic({
438
- code: "render-failed",
439
+ code: resolvePhiRenderFailureCode(error),
439
440
  kind: "widget",
440
441
  type: widget.widgetType,
441
442
  blockId: widget.id,
@@ -507,7 +508,7 @@ function withLayoutRenderKey(node, key) {
507
508
  /** What a Widget that threw while rendering on the server reports in its place. */
508
509
  export function buildPhiRenderFailureIssue(error, options) {
509
510
  return {
510
- code: "render-failed",
511
+ code: resolvePhiRenderFailureCode(error),
511
512
  kind: options.kind,
512
513
  type: options.typeKey ?? "unknown",
513
514
  blockId: options.blockId,
@@ -703,7 +704,7 @@ function renderLayoutNode(node, context) {
703
704
  }
704
705
  catch (error) {
705
706
  return renderCmsDiagnostic({
706
- code: "render-failed",
707
+ code: resolvePhiRenderFailureCode(error),
707
708
  kind: "layout",
708
709
  type: node.widgetType,
709
710
  blockId: node.id,
@@ -1,12 +1,11 @@
1
- import type { ReactNode } from "react";
1
+ import { type ReactNode } from "react";
2
2
  import type { PhiBlockRuntime } from "../../types";
3
3
  import type { PhiCmsSiteBridge } from "../../types/cms-plugins";
4
4
  import type { loadPhiCmsRootRequest } from "../../server-helpers/cms-root";
5
5
  type PhiCmsResolvedRootRequest = NonNullable<Awaited<ReturnType<typeof loadPhiCmsRootRequest>>["resolvedRequest"]>;
6
6
  /**
7
- * What a Page and each of its Region slots work out before they render: the Module scope of the Area,
8
- * the tree filtered to what this viewer may see, the registry of what the tree needs, and the Page's
9
- * Controllers for the Regions in question.
7
+ * What a Page and each of its Region slots work out before they render: the shared part above, and the
8
+ * Page's Controllers for the Regions in question.
10
9
  *
11
10
  * The Page and the slot used to carry this as two copies, four blocks apart, and the slot's trailed the
12
11
  * Page's. One resolution, parameterised by the Regions it is for.
@@ -36,7 +35,7 @@ export declare function resolvePhiCmsPageRenderScope({ cmsBridge, resolvedReques
36
35
  };
37
36
  runtimeRegistry: import("../../types/cms-plugins").PhiCmsRuntimeRenderRegistry;
38
37
  pageControllerSettings: import("../../types").PhiRuntimeControllerSetting[];
39
- controllerConfigOverlays: {
38
+ controllerConfigOverlays: readonly {
40
39
  address: `controller:${string}/${string}:${string}`;
41
40
  config: Record<string, unknown>;
42
41
  }[];
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cache } from "react";
2
3
  import { PhiRuntimeControllerServerHost } from "../runtime/runtime-controller-server-host";
3
4
  import { collectPhiRuntimeControllerConfigOverlays, materializePhiRuntimeControllerSettings, } from "../runtime/runtime-controller-materialization";
4
5
  import { PhiRuntimeControllerConfigOverlays } from "../runtime/runtime-controller-config-overlays";
@@ -9,15 +10,17 @@ import { buildPhiRuntimeModuleAccessRegistry, filterPhiCmsRenderableTreeForViewe
9
10
  import { resolvePhiCmsAreaRuntimeModuleScope, resolvePhiCmsTreeRuntimeRegistry, } from "./phi-cms-runtime-registry";
10
11
  import { resolvePhiPageTour } from "../../server-helpers/page-tour";
11
12
  import { PHI_PAGE_TOUR_CONFIG_KEY, PHI_PAGE_TOUR_CONTROLLER_FLAG, readPhiTourTargets, } from "../../types/tours";
12
- /**
13
- * What a Page and each of its Region slots work out before they render: the Module scope of the Area,
14
- * the tree filtered to what this viewer may see, the registry of what the tree needs, and the Page's
15
- * Controllers for the Regions in question.
13
+ /*
14
+ * What a Page and every one of its Region slots share: the Area's Module scope, the Page's Tour, the tree
15
+ * filtered for this viewer, the registry of what that tree needs, and the Controller config the tree
16
+ * carries. None of it depends on the Region.
16
17
  *
17
- * The Page and the slot used to carry this as two copies, four blocks apart, and the slot's trailed the
18
- * Page's. One resolution, parameterised by the Regions it is for.
18
+ * The Page and its six slots render in parallel and each worked all of it out again -- up to seven
19
+ * filters of the same tree and seven registries per request (audit R9). The root request is memoized per
20
+ * request (`loadPhiCmsRootRequest`), so every slot holds the same object, and React's `cache` keyed by it
21
+ * and the bridge keeps this for exactly that request.
19
22
  */
20
- export async function resolvePhiCmsPageRenderScope({ cmsBridge, resolvedRequest, regionTypes, includeOverlays = false, }) {
23
+ const resolvePhiCmsPageRenderBase = cache(async (cmsBridge, resolvedRequest) => {
21
24
  const runtimeModuleScope = await resolvePhiCmsAreaRuntimeModuleScope({
22
25
  cmsBridge,
23
26
  area: resolvedRequest.runtime.area,
@@ -47,20 +50,6 @@ export async function resolvePhiCmsPageRenderScope({ cmsBridge, resolvedRequest,
47
50
  });
48
51
  // What the Area runs for every Page: a Page setting for one of these configures it, it is not a second.
49
52
  const enclosingSettings = runtimeModuleScope.moduleSet.areaControllerSettings;
50
- const pageControllerSettings = materializePhiRuntimeControllerSettings({
51
- tree: filteredPageTree,
52
- ownerMountScope: "page",
53
- widgetPluginsByType: runtimeModuleScope.widgetDefinitionsByType,
54
- enclosingSettings,
55
- activeControllerTypes: [...runtimeModuleScope.moduleSet.controllerDescriptorsByType.keys()],
56
- regionTypes,
57
- ...(includeOverlays ? { includeOverlays: true } : {}),
58
- });
59
- const controllerDefinitionsByType = await resolvePhiRuntimeControllerDefinitions({
60
- catalog: cmsBridge.runtimeModuleCatalog,
61
- moduleSet: runtimeModuleScope.moduleSet,
62
- settings: pageControllerSettings,
63
- });
64
53
  const controllerConfigOverlays = collectPhiRuntimeControllerConfigOverlays({
65
54
  tree: filteredPageTree,
66
55
  ownerMountScope: "page",
@@ -83,8 +72,40 @@ export async function resolvePhiCmsPageRenderScope({ cmsBridge, resolvedRequest,
83
72
  runtimeModuleScope,
84
73
  filteredPageTree,
85
74
  runtimeRegistry,
75
+ enclosingSettings,
76
+ controllerConfigOverlays: controllerConfigOverlays,
77
+ };
78
+ });
79
+ /**
80
+ * What a Page and each of its Region slots work out before they render: the shared part above, and the
81
+ * Page's Controllers for the Regions in question.
82
+ *
83
+ * The Page and the slot used to carry this as two copies, four blocks apart, and the slot's trailed the
84
+ * Page's. One resolution, parameterised by the Regions it is for.
85
+ */
86
+ export async function resolvePhiCmsPageRenderScope({ cmsBridge, resolvedRequest, regionTypes, includeOverlays = false, }) {
87
+ const base = await resolvePhiCmsPageRenderBase(cmsBridge, resolvedRequest);
88
+ const { runtimeModuleScope, filteredPageTree } = base;
89
+ const pageControllerSettings = materializePhiRuntimeControllerSettings({
90
+ tree: filteredPageTree,
91
+ ownerMountScope: "page",
92
+ widgetPluginsByType: runtimeModuleScope.widgetDefinitionsByType,
93
+ enclosingSettings: base.enclosingSettings,
94
+ activeControllerTypes: [...runtimeModuleScope.moduleSet.controllerDescriptorsByType.keys()],
95
+ regionTypes,
96
+ ...(includeOverlays ? { includeOverlays: true } : {}),
97
+ });
98
+ const controllerDefinitionsByType = await resolvePhiRuntimeControllerDefinitions({
99
+ catalog: cmsBridge.runtimeModuleCatalog,
100
+ moduleSet: runtimeModuleScope.moduleSet,
101
+ settings: pageControllerSettings,
102
+ });
103
+ return {
104
+ runtimeModuleScope,
105
+ filteredPageTree,
106
+ runtimeRegistry: base.runtimeRegistry,
86
107
  pageControllerSettings,
87
- controllerConfigOverlays,
108
+ controllerConfigOverlays: base.controllerConfigOverlays,
88
109
  controllerDefinitionsByType,
89
110
  };
90
111
  }
@@ -13,6 +13,8 @@ function buildIssueTitle(issue) {
13
13
  return `${formatKind(issue.kind)} visibility unresolved`;
14
14
  if (issue.code === "missing-node")
15
15
  return `${formatKind(issue.kind)} root missing`;
16
+ if (issue.code === "invalid-config")
17
+ return `${formatKind(issue.kind)} settings invalid`;
16
18
  return `${formatKind(issue.kind)} not renderable`;
17
19
  }
18
20
  function buildIssueDescription(issue) {
@@ -24,9 +26,11 @@ function buildIssueDescription(issue) {
24
26
  ? "A Module its condition reads could not be asked this render."
25
27
  : issue.code === "missing-node"
26
28
  ? "The stored tree names a node it does not contain."
27
- : issue.moduleId
28
- ? `Module: ${issue.moduleId}.`
29
- : "The required renderer is unavailable.";
29
+ : issue.code === "invalid-config"
30
+ ? "Correct the field in the Inspector; on the live page this block is left out until then."
31
+ : issue.moduleId
32
+ ? `Module: ${issue.moduleId}.`
33
+ : "The required renderer is unavailable.";
30
34
  return `${issue.type}. ${moduleDescription}${issue.detail ? ` ${issue.detail}` : ""}`;
31
35
  }
32
36
  function buildIssueKey(issue) {
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Component } from "react";
4
4
  import { PhiCmsRenderDiagnostic } from "./phi-cms-render-diagnostic";
5
+ import { resolvePhiRenderFailureCode } from "../widgets/config/strict-config-reader";
5
6
  export class PhiCmsRenderErrorBoundary extends Component {
6
7
  state = {
7
8
  error: null,
@@ -20,7 +21,7 @@ export class PhiCmsRenderErrorBoundary extends Component {
20
21
  render() {
21
22
  if (this.state.error) {
22
23
  return _jsx(PhiCmsRenderDiagnostic, { issue: {
23
- code: "render-failed",
24
+ code: resolvePhiRenderFailureCode(this.state.error),
24
25
  kind: this.props.kind,
25
26
  type: this.props.typeKey ?? "unknown",
26
27
  blockId: this.props.blockId,
@@ -8,5 +8,8 @@ import { Anchor } from "antd";
8
8
  * page, the shape a table of contents takes. It stays where it is drawn and never pins itself.
9
9
  */
10
10
  export function PhiAnchorNavControl({ items, offsetTop = 0, style }) {
11
- return _jsx(Anchor, { affix: false, offsetTop: offsetTop, items: [...items], style: style });
11
+ return (_jsx(Anchor, { affix: false, offsetTop: offsetTop, items: [...items], className: "phi-anchor-nav-control",
12
+ // As wide as its slot and no wider: Ant Design sizes the list to its longest title, which in a
13
+ // narrow sider ran past the edge. Within the slot a long title ends in an ellipsis, Ant Design's own.
14
+ style: { maxWidth: "100%", minWidth: 0, ...style } }));
12
15
  }
@@ -50,7 +50,7 @@ const BACKGROUND_IMAGE_VARIANT_OPTIONS = [
50
50
  ];
51
51
  function toPickerValue(background) {
52
52
  const normalized = normalizePhiBackgroundWidgetConfig(background ?? null);
53
- if (normalized.base.kind === "none") {
53
+ if (normalized.base.kind === "none" || normalized.base.kind === "theme") {
54
54
  return "rgba(255, 255, 255, 0)";
55
55
  }
56
56
  if (normalized.base.kind === "image") {
@@ -126,6 +126,7 @@ export function PhiBackgroundControl({ value, config, disabled = false, mode = "
126
126
  { value: "color", label: labels.base.color },
127
127
  { value: "gradient", label: labels.base.gradient },
128
128
  { value: "image", label: labels.base.image },
129
+ { value: "theme", label: labels.base.theme },
129
130
  ];
130
131
  const baseKindOptions = baseKindCatalog.filter((option) => baseKinds.includes(option.value));
131
132
  const backgroundPositionOptions = [
@@ -223,7 +224,13 @@ export function PhiBackgroundControl({ value, config, disabled = false, mode = "
223
224
  const isOfferedFilter = (filter) => filters.includes(filter) && phiBackgroundSupportsFilter(currentValue, filter);
224
225
  const filterKindOptions = filterKindCatalog.filter((option) => option.value === "none" || isOfferedFilter(option.value));
225
226
  const activeFilterKind = currentValue.filter && isOfferedFilter(currentValue.filter) ? currentValue.filter : "none";
226
- const canOpenPreview = currentValue.base.kind !== "none";
227
+ // The Theme's Overlay is edited in the Theme workspace; here it has nothing to open.
228
+ const canOpenPreview = currentValue.base.kind !== "none" && currentValue.base.kind !== "theme";
229
+ /*
230
+ * A `theme` Base is the Theme's Overlay whole -- its own Overlay and pane included -- so the Background
231
+ * offers nothing to lay over it, and the Filter segment has nothing to offer either.
232
+ */
233
+ const offersOverlay = currentValue.base.kind !== "theme";
227
234
  useEffect(() => {
228
235
  if (currentValue.base.kind === "color") {
229
236
  lastColorBaseRef.current = currentValue.base;
@@ -298,6 +305,11 @@ export function PhiBackgroundControl({ value, config, disabled = false, mode = "
298
305
  if (kind === currentValue.base.kind) {
299
306
  return;
300
307
  }
308
+ // The last colour, gradient and picture stay remembered (the effect above), so switching back finds them.
309
+ if (kind === "theme") {
310
+ emit({ base: { kind: "theme" }, overlay: null, filter: null, motion: null });
311
+ return;
312
+ }
301
313
  if (kind === "none") {
302
314
  emit({
303
315
  ...currentValue,
@@ -650,7 +662,10 @@ export function PhiBackgroundControl({ value, config, disabled = false, mode = "
650
662
  return (_jsx(ConfigPreviewShell, { expanded: canOpenPreview, children: renderPreviewPicker() }));
651
663
  }
652
664
  const showPreview = mode !== "config";
653
- return (_jsxs(PhiFlexControl, { vertical: true, gap: 12, style: { width: "100%" }, children: [showPreview ? (_jsx(ConfigPreviewShell, { expanded: canOpenPreview, children: renderPreviewPicker() })) : null, _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingXS, width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.base }), _jsx(PhiSegmentedControl, { block: true, disabled: isDisabled, value: currentValue.base.kind, options: baseKindOptions, onChange: (next) => updateBaseKind(next) })] }), currentValue.base.kind === "image" ? (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingSM, width: "100%" }, children: [_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingXS, wrap: false, style: { width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.image }), currentValue.base.sourceKind === "asset" && currentValue.base.assetId != null ? (_jsx(Typography.Text, { type: "secondary", style: { fontSize: token.fontSizeSM, textAlign: "right" }, children: currentValue.base.assetId })) : null] }), _jsxs("div", { style: {
665
+ return (_jsxs(PhiFlexControl, { vertical: true, gap: 12, style: { width: "100%" }, children: [showPreview ? (_jsx(ConfigPreviewShell, { expanded: canOpenPreview, children: renderPreviewPicker() })) : null, _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingXS, width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.base }), _jsx(PhiSelectControl, { ariaLabel: labels.sections.base, disabled: isDisabled, value: currentValue.base.kind, options: baseKindOptions, style: { width: "100%" }, onChange: (next) => {
666
+ if (next != null)
667
+ updateBaseKind(next);
668
+ } })] }), currentValue.base.kind === "image" ? (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingSM, width: "100%" }, children: [_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingXS, wrap: false, style: { width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.image }), currentValue.base.sourceKind === "asset" && currentValue.base.assetId != null ? (_jsx(Typography.Text, { type: "secondary", style: { fontSize: token.fontSizeSM, textAlign: "right" }, children: currentValue.base.assetId })) : null] }), _jsxs("div", { style: {
654
669
  display: "grid",
655
670
  gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
656
671
  gap: token.paddingSM,
@@ -676,13 +691,13 @@ export function PhiBackgroundControl({ value, config, disabled = false, mode = "
676
691
  }, children: [_jsx(Select, { value: currentValue.base.position ?? "center", disabled: isDisabled, style: { width: "100%" }, options: backgroundPositionOptions, onChange: (next) => updateImageField("position", next) }), _jsx(Select, { value: currentValue.base.size ?? "cover", disabled: isDisabled, style: { width: "100%" }, options: backgroundSizeOptions, onChange: (next) => updateImageField("size", next) }), _jsx(Select, { value: currentValue.base.repeat ?? "no-repeat", disabled: isDisabled, style: { width: "100%" }, options: backgroundRepeatOptions, onChange: (next) => updateImageField("repeat", next) })] }), backgroundMotionOptions.length > 1 ? (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingXS, width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.motion }), _jsx(PhiSegmentedControl, { block: true, value: activeMotionMode, options: backgroundMotionOptions, disabled: isDisabled, onChange: updateMotionMode }), activeParallaxMotion ? (_jsxs(_Fragment, { children: [_jsx(Typography.Text, { children: labels.motion.strength }), _jsx(PhiSliderControl, { min: 0, max: 1, step: 0.05, ariaLabel: labels.motion.strength, value: activeParallaxMotion.strength ?? resolvePhiBackgroundParallaxDefaultStrength(activeParallaxMotion.travel), disabled: isDisabled, tooltipSuffix: "\u00D7", style: { width: "100%" }, onChange: (strength) => {
677
692
  beginSliderEdit();
678
693
  updateParallaxMotion({ strength });
679
- }, onChangeComplete: commitSliderEdit }), _jsx(Typography.Text, { children: labels.motion.direction }), _jsx(PhiSegmentedControl, { block: true, value: activeParallaxMotion.direction ?? "natural", options: backgroundMotionDirectionOptions, disabled: isDisabled, onChange: (direction) => updateParallaxMotion({ direction }) }), _jsx(Typography.Text, { children: labels.motion.travel }), _jsx(PhiSegmentedControl, { block: true, value: activeParallaxMotion.travel ?? "rate", options: backgroundMotionTravelOptions, disabled: isDisabled, onChange: (travel) => updateParallaxMotion({ travel }) })] })) : null] })) : null] })) : currentValue.base.kind !== "none" ? (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingSM, width: "100%" }, children: [currentValue.base.kind === "color" ? (_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingSM, wrap: "wrap", children: [_jsx(Typography.Text, { children: labels.base.color }), _jsx(PhiColorControl, { ...colorPickerTransaction, value: currentValue.base.color, disabled: isDisabled, presets: colorPickerPresets, placement: colorPickerPlacement, onChange: (value) => {
694
+ }, onChangeComplete: commitSliderEdit }), _jsx(Typography.Text, { children: labels.motion.direction }), _jsx(PhiSegmentedControl, { block: true, value: activeParallaxMotion.direction ?? "natural", options: backgroundMotionDirectionOptions, disabled: isDisabled, onChange: (direction) => updateParallaxMotion({ direction }) }), _jsx(Typography.Text, { children: labels.motion.travel }), _jsx(PhiSegmentedControl, { block: true, value: activeParallaxMotion.travel ?? "rate", options: backgroundMotionTravelOptions, disabled: isDisabled, onChange: (travel) => updateParallaxMotion({ travel }) })] })) : null] })) : null] })) : currentValue.base.kind === "color" || currentValue.base.kind === "gradient" ? (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.paddingSM, width: "100%" }, children: [currentValue.base.kind === "color" ? (_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingSM, wrap: "wrap", children: [_jsx(Typography.Text, { children: labels.base.color }), _jsx(PhiColorControl, { ...colorPickerTransaction, value: currentValue.base.color, disabled: isDisabled, presets: colorPickerPresets, placement: colorPickerPlacement, onChange: (value) => {
680
695
  if (value != null)
681
696
  updateBaseFromCss(value);
682
697
  } })] })) : (_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingSM, wrap: "wrap", children: [_jsx(Typography.Text, { children: labels.base.gradient }), _jsx(PhiColorControl, { ...colorPickerTransaction, mode: "gradient", value: derivedPickerValue, disabled: isDisabled, presets: colorPickerPresets, placement: colorPickerPlacement, onChange: (value) => {
683
698
  if (value != null)
684
699
  updateBaseFromCss(value);
685
- } })] })), currentValue.base.kind === "gradient" ? (renderDirectionEditor(labels.gradient.direction, currentValue.base.direction, updateGradientDirection)) : null] })) : null, _jsx(Divider, { dashed: true, size: "small" }), _jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.overlay }), _jsx(PhiSegmentedControl, { block: true, disabled: isDisabled, value: currentValue.overlay?.kind ?? "none", options: overlayKindOptions, onChange: (next) => updateOverlayKind(next) }), currentValue.overlay ? (_jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [currentValue.overlay.kind === "pattern" ? (_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingSM, wrap: "wrap", children: [_jsx(Typography.Text, { children: labels.overlay.pattern }), _jsx(PhiSelectControl, { value: currentValue.overlay.patternKey, options: resolvedPatternOptions, disabled: isDisabled, style: { width: fieldControlWidth }, onChange: (patternKey) => {
700
+ } })] })), currentValue.base.kind === "gradient" ? (renderDirectionEditor(labels.gradient.direction, currentValue.base.direction, updateGradientDirection)) : null] })) : null, offersOverlay ? _jsx(Divider, { dashed: true, size: "small" }) : null, offersOverlay ? _jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.overlay }), _jsx(PhiSegmentedControl, { block: true, disabled: isDisabled, value: currentValue.overlay?.kind ?? "none", options: overlayKindOptions, onChange: (next) => updateOverlayKind(next) }), currentValue.overlay ? (_jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [currentValue.overlay.kind === "pattern" ? (_jsxs(Flex, { align: "center", justify: "space-between", gap: token.paddingSM, wrap: "wrap", children: [_jsx(Typography.Text, { children: labels.overlay.pattern }), _jsx(PhiSelectControl, { value: currentValue.overlay.patternKey, options: resolvedPatternOptions, disabled: isDisabled, style: { width: fieldControlWidth }, onChange: (patternKey) => {
686
701
  const provider = resolvePhiBackgroundPatternProvider(patternKey);
687
702
  if (!provider)
688
703
  return;
@@ -762,5 +777,5 @@ export function PhiBackgroundControl({ value, config, disabled = false, mode = "
762
777
  });
763
778
  }, style: { width: fieldControlWidth } })] }, field.key));
764
779
  })
765
- : null] })) : null] }), filterKindOptions.length > 1 ? (_jsxs(_Fragment, { children: [_jsx(Divider, { dashed: true, size: "small" }), _jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.filter }), _jsx(PhiSegmentedControl, { block: true, disabled: isDisabled, value: activeFilterKind, options: filterKindOptions, onChange: (next) => updateFilterKind(next) })] })] })) : null] }));
780
+ : null] })) : null] }) : null, filterKindOptions.length > 1 ? (_jsxs(_Fragment, { children: [_jsx(Divider, { dashed: true, size: "small" }), _jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [_jsx(Typography.Text, { children: labels.sections.filter }), _jsx(PhiSegmentedControl, { block: true, disabled: isDisabled, value: activeFilterKind, options: filterKindOptions, onChange: (next) => updateFilterKind(next) })] })] })) : null] }));
766
781
  }
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import type { CSSProperties, ReactNode } from "react";
2
2
  import { type PhiBulletListNode, type PhiResolvedBulletListStyle } from "../widgets/shared/bullet-list-vocabulary";
3
3
  export type PhiBulletListControlProps = {
4
4
  items: readonly PhiBulletListNode<ReactNode>[];
@@ -15,6 +15,11 @@ export type PhiBulletListControlProps = {
15
15
  * an entry that is a text field has the field's height instead.
16
16
  */
17
17
  markerLineHeight?: string;
18
+ /**
19
+ * The space the list keeps around it as a block among blocks -- a Markdown text's list takes its
20
+ * paragraphs' spacing, so the block after the last entry stands as far off as after a paragraph.
21
+ */
22
+ blockSpacing?: Pick<CSSProperties, "marginBlockStart" | "marginBlockEnd">;
18
23
  };
19
24
  /**
20
25
  * A list, as the house draws one: a marker per level, entries with a box of their own or none, lines
@@ -29,4 +34,4 @@ export type PhiBulletListControlProps = {
29
34
  * blocks. An entry's children are the list one level below it, drawn inside the entry under its content,
30
35
  * so they are indented by the marker and keep to the entry's box.
31
36
  */
32
- export declare function PhiBulletListControl({ items, listStyle, depth, ordered, start, markerLineHeight, }: PhiBulletListControlProps): import("react").JSX.Element;
37
+ export declare function PhiBulletListControl({ items, listStyle, depth, ordered, start, markerLineHeight, blockSpacing, }: PhiBulletListControlProps): import("react").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { PhiIcon } from "../shell/phi-icon";
3
3
  import { phiSurfaceDrawsChrome, resolvePhiSurfaceStyle } from "../../helpers/surface-style";
4
4
  import { PHI_COLOR, PHI_RADIUS, PHI_SPACE } from "../../theme/antd-css-var-contract";
@@ -7,6 +7,21 @@ import { PhiBulletListFlag, resolvePhiBulletListLevel, resolvePhiBulletListStyle
7
7
  import { hasPhiFlag } from "../../helpers/flags";
8
8
  const PHI_BULLET_LIST_MARKER_SIZE = PHI_SPACE.xs;
9
9
  const PHI_BULLET_LIST_ICON_SIZE = 14;
10
+ /*
11
+ * An entry's state stands in place of the level's marker: a tick for what is included, a dash for what is
12
+ * not. Neither is the list's colour: included is the Theme's success, excluded the tertiary text, so a
13
+ * plan's list reads the same whatever marker its neutral entries take.
14
+ */
15
+ function renderStateMarker(state) {
16
+ switch (state) {
17
+ case "included":
18
+ return _jsx(PhiIcon, { name: "antd:check-outlined", size: PHI_BULLET_LIST_ICON_SIZE, style: { color: PHI_COLOR.success } });
19
+ case "excluded":
20
+ return _jsx(PhiIcon, { name: "antd:minus-outlined", size: PHI_BULLET_LIST_ICON_SIZE, style: { color: PHI_COLOR.textTertiary } });
21
+ default:
22
+ return null;
23
+ }
24
+ }
10
25
  function renderMarker(marker, icon, number) {
11
26
  switch (marker) {
12
27
  case "none":
@@ -51,7 +66,7 @@ function renderMarker(marker, icon, number) {
51
66
  * blocks. An entry's children are the list one level below it, drawn inside the entry under its content,
52
67
  * so they are indented by the marker and keep to the entry's box.
53
68
  */
54
- export function PhiBulletListControl({ items, listStyle = resolvePhiBulletListStyle(null), depth = 1, ordered = false, start = 1, markerLineHeight = "1lh", }) {
69
+ export function PhiBulletListControl({ items, listStyle = resolvePhiBulletListStyle(null), depth = 1, ordered = false, start = 1, markerLineHeight = "1lh", blockSpacing, }) {
55
70
  const level = resolvePhiBulletListLevel(depth);
56
71
  const marker = ordered ? "number" : listStyle.markers[level];
57
72
  const gap = resolvePhiSpacingScaleValue(listStyle.gap);
@@ -60,14 +75,29 @@ export function PhiBulletListControl({ items, listStyle = resolvePhiBulletListSt
60
75
  // A line between entries that have edges of their own would only double them.
61
76
  const divided = !boxed && hasPhiFlag(listStyle.flags, PhiBulletListFlag.Dividers);
62
77
  const ListTag = marker === "number" ? "ol" : "ul";
63
- const listCss = { display: "grid", gap, margin: 0, padding: 0, listStyle: "none", width: "100%", minWidth: 0 };
78
+ const listCss = { display: "grid", gap, margin: 0, padding: 0, listStyle: "none", width: "100%", minWidth: 0, ...blockSpacing };
64
79
  return (_jsx(ListTag, { style: listCss, ...(ListTag === "ol" && start !== 1 ? { start } : {}), children: items.map((item, index) => (_jsxs("li", { className: surface.className, style: {
65
80
  display: "flex",
66
81
  alignItems: "flex-start",
67
- gap: PHI_SPACE.sm,
82
+ // A marker belongs to its words: one small step between them, not the space between blocks.
83
+ gap: PHI_SPACE.xs,
68
84
  minWidth: 0,
69
85
  ...surface.style,
70
86
  ...(boxed ? { padding: `${PHI_SPACE.sm} ${PHI_SPACE.md}` } : {}),
71
87
  ...(divided && index > 0 ? { borderTop: `1px solid ${PHI_COLOR.borderSecondary}`, paddingTop: gap } : {}),
72
- }, children: [marker === "none" ? null : (_jsx("span", { "aria-hidden": "true", style: { display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0, height: markerLineHeight }, children: renderMarker(marker, listStyle.icon, start + index) })), _jsxs("div", { style: { display: "grid", gap, flex: 1, minWidth: 0 }, children: [item.content, item.children?.length ? (_jsx(PhiBulletListControl, { items: item.children, listStyle: listStyle, depth: depth + 1, markerLineHeight: markerLineHeight })) : null] })] }, index))) }));
88
+ }, children: [(() => {
89
+ const stated = renderStateMarker(item.state);
90
+ /* An editor's marker is a button, so a list whose marker is `none` still offers one. */
91
+ const drawn = stated ?? renderMarker(marker === "none" && item.onMarkerClick ? "dot" : marker, listStyle.icon, start + index);
92
+ if (drawn == null)
93
+ return null;
94
+ const markerStyle = {
95
+ display: "inline-flex",
96
+ alignItems: "center",
97
+ justifyContent: "center",
98
+ flexShrink: 0,
99
+ height: markerLineHeight,
100
+ };
101
+ return item.onMarkerClick ? (_jsx("button", { type: "button", className: "phi-bullet-list__marker-button", "aria-label": `State: ${item.state ?? "neutral"}`, onClick: item.onMarkerClick, style: { ...markerStyle, padding: 0, border: 0, background: "none", cursor: "pointer", color: "inherit" }, children: drawn })) : (_jsx("span", { "aria-hidden": "true", style: markerStyle, children: drawn }));
102
+ })(), _jsxs("div", { style: { display: "grid", gap, flex: 1, minWidth: 0, ...(item.state === "excluded" ? { color: PHI_COLOR.textTertiary } : {}) }, children: [item.content, item.children?.length ? (_jsx(PhiBulletListControl, { items: item.children, listStyle: listStyle, depth: depth + 1, markerLineHeight: markerLineHeight })) : null] })] }, index))) }));
73
103
  }
@@ -82,8 +82,10 @@ export function PhiColorControl({ value = null, defaultValue = "#f0f0f0", disabl
82
82
  */
83
83
  ...(children == null ? { width: "fit-content" } : {}),
84
84
  },
85
- popupOverlayInner: {
86
- padding: 12,
85
+ popup: {
86
+ container: {
87
+ padding: 12,
88
+ },
87
89
  },
88
90
  }, panelRender: (_, extra) => {
89
91
  const { Picker } = extra.components;
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  */
7
7
  import { useSyncExternalStore } from "react";
8
8
  import { Drawer } from "antd";
9
- import { PHI_SPACE } from "../../theme/antd-css-var-contract";
9
+ import { PHI_FONT_SIZE, PHI_SPACE } from "../../theme/antd-css-var-contract";
10
10
  import { PHI_OVERLAY_DEFAULT_MASK, resolvePhiOverlayDismissSource, resolvePhiOverlayMaskPresentation, } from "./phi-overlay-control-contract";
11
11
  const subscribeHydration = () => () => undefined;
12
12
  const PHI_DRAWER_HEADER_MIN_BLOCK_SIZE = `calc(var(--ant-control-height) + ${PHI_SPACE.xs} + ${PHI_SPACE.xs})`;
@@ -51,7 +51,8 @@ export function PhiDrawerControlAdapter({ open, title, header, body, footer, clo
51
51
  padding: 0,
52
52
  background: "transparent",
53
53
  },
54
- title: { width: "100%", minWidth: 0 },
54
+ // The title in the body's size, as a Modal's is (theme/phi-theme.ts); Ant Design sets a Drawer's at `lg`.
55
+ title: { width: "100%", minWidth: 0, fontSize: PHI_FONT_SIZE.base, lineHeight: "var(--ant-line-height)" },
55
56
  close: {
56
57
  position: "absolute",
57
58
  top: "50%",
@@ -46,7 +46,13 @@ export function PhiInlineTextEditor({ value, onChange, onCommit, onCancel, onFoc
46
46
  * At one column it is the smallest thing in the box and the text is the widest, which is the
47
47
  * order this field is built on; it is also the width an empty field keeps.
48
48
  */
49
- cols: fitContent ? 1 : undefined, style: fitContent ? { width: "100%", overflow: "hidden" } : { width: "100%" }, inputStyle: inputStyle, onChange: (nextValue) => onChange(nextValue ?? ""), onFocus: onFocus, onBlur: (event) => {
49
+ cols: fitContent ? 1 : undefined,
50
+ /*
51
+ * `overflowX` and `overflowY`, not the `overflow` shorthand: while it measures, the text area's
52
+ * `autoSize` sets both longhands and takes them away again, and React warns when a longhand
53
+ * leaves beside its shorthand -- the shorthand would not be written back.
54
+ */
55
+ style: fitContent ? { width: "100%", overflowX: "hidden", overflowY: "hidden" } : { width: "100%" }, inputStyle: inputStyle, onChange: (nextValue) => onChange(nextValue ?? ""), onFocus: onFocus, onBlur: (event) => {
50
56
  const shouldCommit = !cancelPendingRef.current;
51
57
  cancelPendingRef.current = false;
52
58
  if (shouldCommit) {
@@ -20,7 +20,7 @@ export function PhiLengthControl({ value, label, placeholder, min, max, step, pr
20
20
  * is kept shut and its change ignored instead.
21
21
  */
22
22
  const controlDisabled = disabled || (!onChange && !readOnly);
23
- const control = (_jsxs(PhiCompactGroupControl, { block: true, size: size, style: { width: "100%", minWidth: 0, ...style }, children: [_jsx(InputNumber, { "aria-label": placeholder ?? label ?? "Length", controls: false, disabled: controlDisabled, readOnly: readOnly, min: min, max: max, step: step, precision: precision, placeholder: placeholder, value: part?.value ?? null, style: { flex: "1 1 0", minWidth: 0 }, onChange: (nextValue) => onChange?.(typeof nextValue === "number" ? serializePhiCssLength(nextValue, unit) : null) }), _jsx(Select, { "aria-label": `${placeholder ?? label ?? "Length"} unit`, disabled: controlDisabled, open: readOnly ? false : undefined, options: PHI_CSS_LENGTH_UNITS.map((option) => ({ value: option, label: option })), popupMatchSelectWidth: false, getPopupContainer: getPopupContainer, showSearch: false, suffixIcon: null, variant: "filled", value: unit, style: { flex: "0 0 38px", width: 38 }, styles: {
23
+ const control = (_jsxs(PhiCompactGroupControl, { block: true, size: size, style: { width: "100%", minWidth: 0, ...style }, children: [_jsx(InputNumber, { "aria-label": placeholder ?? label ?? "Length", controls: false, disabled: controlDisabled, readOnly: readOnly, min: min, max: max, step: step, precision: precision, placeholder: placeholder, value: part?.value ?? null, style: { flex: "1 1 0", minWidth: 0 }, onChange: (nextValue) => onChange?.(typeof nextValue === "number" ? serializePhiCssLength(nextValue, unit) : null) }), _jsx(Select, { "aria-label": `${placeholder ?? label ?? "Length"} unit`, disabled: controlDisabled, open: readOnly ? false : undefined, options: PHI_CSS_LENGTH_UNITS.map((option) => ({ value: option, label: option })), popupMatchSelectWidth: false, getPopupContainer: getPopupContainer, showSearch: false, suffix: null, variant: "filled", value: unit, style: { flex: "0 0 38px", width: 38 }, styles: {
24
24
  root: { paddingInline: 4 },
25
25
  content: { justifyContent: "center", textAlign: "center" },
26
26
  }, onChange: (nextUnit) => {
@@ -0,0 +1,38 @@
1
+ import type { CSSProperties, MouseEventHandler, ReactNode } from "react";
2
+ export type PhiRibbonControlProps = {
3
+ children: ReactNode;
4
+ /** The band's ground; absent, the Theme's primary. Its words are the light text on any ground. */
5
+ color?: string;
6
+ /**
7
+ * Where the band stands: `corner` flush with the box's top and end edge, its top end corner the box's
8
+ * own; `edge` a small padding down the end edge. Either way it floats: nothing in the box moves for it.
9
+ */
10
+ placement?: "corner" | "edge";
11
+ style?: CSSProperties;
12
+ /**
13
+ * The band's whole words, shown on hover when its ellipsis cut them short (`PhiTruncatedHoverText`).
14
+ * A band with a hover text takes the pointer, so it needs `onClick` to hand a click on to what lies
15
+ * under it.
16
+ */
17
+ fullText?: string;
18
+ /** What a click on the band does, for a band that takes the pointer: the box's own click, passed on. */
19
+ onClick?: MouseEventHandler<HTMLSpanElement>;
20
+ };
21
+ /**
22
+ * A band of words at the end edge of a box: "Popular", "New", "-20 %".
23
+ *
24
+ * Ant Design draws this as `Badge.Ribbon`, with a fold that hangs past the box's edge. Not that one: it
25
+ * wraps the box in an element of its own, and its fold needs the box not to clip -- a card clips, so its
26
+ * picture keeps its corners. This band stands inside the box and needs nothing from it but a position
27
+ * to stand against. It is drawn on the server as well, without hooks.
28
+ *
29
+ * It floats and takes no room, so boxes side by side in a row start their content on one line whether
30
+ * they carry a band or not. A band on a line of its own pushed its box's words down; squeezed into the
31
+ * box's top inset it was too thin to read. In the corner it stands over the inset and a little into the
32
+ * first line's end, which a long eyebrow in a narrow box can reach.
33
+ *
34
+ * It sits above what the box draws, the highlight's ring included. Without a hover text it takes no
35
+ * clicks, so a card that is a link stays one under its band; with one it has to take the pointer to be
36
+ * pointed at, and hands a click on through `onClick`.
37
+ */
38
+ export declare function PhiRibbonControl({ children, color, placement, style, fullText, onClick }: PhiRibbonControlProps): import("react").JSX.Element;
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { PHI_COLOR, PHI_FONT_SIZE, PHI_SPACE } from "../../theme/antd-css-var-contract";
3
+ import { PhiTruncatedHoverText } from "./phi-truncated-hover-text";
4
+ /**
5
+ * A band of words at the end edge of a box: "Popular", "New", "-20 %".
6
+ *
7
+ * Ant Design draws this as `Badge.Ribbon`, with a fold that hangs past the box's edge. Not that one: it
8
+ * wraps the box in an element of its own, and its fold needs the box not to clip -- a card clips, so its
9
+ * picture keeps its corners. This band stands inside the box and needs nothing from it but a position
10
+ * to stand against. It is drawn on the server as well, without hooks.
11
+ *
12
+ * It floats and takes no room, so boxes side by side in a row start their content on one line whether
13
+ * they carry a band or not. A band on a line of its own pushed its box's words down; squeezed into the
14
+ * box's top inset it was too thin to read. In the corner it stands over the inset and a little into the
15
+ * first line's end, which a long eyebrow in a narrow box can reach.
16
+ *
17
+ * It sits above what the box draws, the highlight's ring included. Without a hover text it takes no
18
+ * clicks, so a card that is a link stays one under its band; with one it has to take the pointer to be
19
+ * pointed at, and hands a click on through `onClick`.
20
+ */
21
+ export function PhiRibbonControl({ children, color, placement = "edge", style, fullText, onClick }) {
22
+ const radius = "var(--phi-control-radius-sm)";
23
+ const position = placement === "corner"
24
+ ? {
25
+ top: 0,
26
+ paddingBlock: PHI_SPACE.xxs,
27
+ // The top end corner is the box's own, which clips it; only the corner inside the box is rounded.
28
+ borderEndStartRadius: radius,
29
+ }
30
+ : {
31
+ top: PHI_SPACE.sm,
32
+ paddingBlock: PHI_SPACE.xxs,
33
+ borderStartStartRadius: radius,
34
+ borderEndStartRadius: radius,
35
+ };
36
+ const band = (_jsx("span", { className: "phi-ribbon-control", style: {
37
+ position: "absolute",
38
+ insetInlineEnd: 0,
39
+ zIndex: 4,
40
+ maxWidth: "70%",
41
+ boxSizing: "border-box",
42
+ paddingInline: PHI_SPACE.sm,
43
+ background: color ?? PHI_COLOR.primary,
44
+ color: PHI_COLOR.textLightSolid,
45
+ fontSize: PHI_FONT_SIZE.sm,
46
+ fontWeight: 600,
47
+ lineHeight: 2,
48
+ whiteSpace: "nowrap",
49
+ overflow: "hidden",
50
+ textOverflow: "ellipsis",
51
+ pointerEvents: fullText ? "auto" : "none",
52
+ ...(fullText && onClick ? { cursor: "pointer" } : {}),
53
+ ...position,
54
+ ...style,
55
+ }, ...(onClick ? { onClick } : {}), children: children }));
56
+ return fullText ? _jsx(PhiTruncatedHoverText, { title: fullText, children: band }) : band;
57
+ }
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from "react";
2
+ export type PhiRibbonWrapControlProps = {
3
+ /** The box the ribbon hangs on. */
4
+ children: ReactNode;
5
+ /** The ribbon's words. */
6
+ text: ReactNode;
7
+ /** The ribbon's ground; absent, the Theme's primary. The fold under it is a darker shade of it. */
8
+ color?: string;
9
+ /** Takes the pointer, for an editor that writes in the ribbon; otherwise clicks pass to the box. */
10
+ interactive?: boolean;
11
+ className?: string;
12
+ };
13
+ /**
14
+ * A ribbon that hangs over a box's end edge, with a fold behind it: Ant Design's `Badge.Ribbon`.
15
+ *
16
+ * The other band, `PhiRibbonControl`, stands inside the box and needs nothing from it. This one reaches
17
+ * past the box's edge, which a box that clips -- a card does, for its picture's corners and its zoom --
18
+ * cannot give a child of its own. So it wraps the box: the wrapper does not clip, the box keeps clipping
19
+ * what is its own, and the ribbon is the box's sibling. The wrapper is a column that passes the slot's
20
+ * width and height on to the box. Whatever stands around the wrapper must leave the overhang room: a
21
+ * Layout that clips at the box's edge cuts the ribbon off as it would any overhang.
22
+ *
23
+ * Imported from its own module, not from `antd`'s Badge: the Badge brings its scroll-number motion along,
24
+ * which a ribbon never uses.
25
+ */
26
+ export declare function PhiRibbonWrapControl({ children, text, color, interactive, className }: PhiRibbonWrapControlProps): import("react").JSX.Element;
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import Ribbon from "antd/es/badge/Ribbon";
4
+ /**
5
+ * A ribbon that hangs over a box's end edge, with a fold behind it: Ant Design's `Badge.Ribbon`.
6
+ *
7
+ * The other band, `PhiRibbonControl`, stands inside the box and needs nothing from it. This one reaches
8
+ * past the box's edge, which a box that clips -- a card does, for its picture's corners and its zoom --
9
+ * cannot give a child of its own. So it wraps the box: the wrapper does not clip, the box keeps clipping
10
+ * what is its own, and the ribbon is the box's sibling. The wrapper is a column that passes the slot's
11
+ * width and height on to the box. Whatever stands around the wrapper must leave the overhang room: a
12
+ * Layout that clips at the box's edge cuts the ribbon off as it would any overhang.
13
+ *
14
+ * Imported from its own module, not from `antd`'s Badge: the Badge brings its scroll-number motion along,
15
+ * which a ribbon never uses.
16
+ */
17
+ export function PhiRibbonWrapControl({ children, text, color, interactive = false, className }) {
18
+ const indicator = interactive ? { zIndex: 4 } : { zIndex: 4, pointerEvents: "none" };
19
+ /*
20
+ * An editor's field in the ribbon measures itself against the ribbon, which is as wide as its words:
21
+ * empty, both were nothing, and only the fold showed. Room for a word, as the inner band keeps it.
22
+ */
23
+ const content = interactive ? { display: "inline-block", minWidth: "6em" } : undefined;
24
+ return (_jsx(Ribbon, { text: text, ...(color ? { color } : {}), rootClassName: ["phi-ribbon-wrap-control", className].filter(Boolean).join(" "), styles: { indicator, ...(content ? { content } : {}) }, children: children }));
25
+ }