@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.
- package/components/cms/phi-cms-layout-renderer.js +4 -3
- package/components/cms/phi-cms-page-render-scope.d.ts +4 -5
- package/components/cms/phi-cms-page-render-scope.js +43 -22
- package/components/cms/phi-cms-render-diagnostic-client.js +7 -3
- package/components/cms/phi-cms-render-error-boundary.js +2 -1
- package/components/controls/phi-anchor-nav-control.js +4 -1
- package/components/controls/phi-background-control.js +21 -6
- package/components/controls/phi-bullet-list-control.d.ts +7 -2
- package/components/controls/phi-bullet-list-control.js +35 -5
- package/components/controls/phi-color-control.js +4 -2
- package/components/controls/phi-drawer-control-adapter.js +3 -2
- package/components/controls/phi-inline-text-editor.js +7 -1
- package/components/controls/phi-length-control.js +1 -1
- package/components/controls/phi-ribbon-control.d.ts +38 -0
- package/components/controls/phi-ribbon-control.js +57 -0
- package/components/controls/phi-ribbon-wrap-control.d.ts +26 -0
- package/components/controls/phi-ribbon-wrap-control.js +25 -0
- package/components/controls/phi-select-control.js +5 -2
- package/components/controls/phi-series-chart-control.d.ts +48 -0
- package/components/controls/phi-series-chart-control.js +82 -0
- package/components/controls/phi-table-control.d.ts +3 -0
- package/components/controls/phi-table-control.js +13 -1
- package/components/controls/phi-text-control.js +57 -3
- package/components/controls/phi-tree-control.js +4 -4
- package/components/controls/phi-truncated-hover-text.d.ts +15 -0
- package/components/controls/phi-truncated-hover-text.js +25 -0
- package/components/forms/link-target-form-control.d.ts +1 -1
- package/components/forms/link-target-form-control.js +2 -45
- package/components/forms/phi-form-widget-frame.js +4 -2
- package/components/forms/shared-form-provider-registry.js +1 -4
- package/components/layouts/clients/phi-three-column-layout-client.js +10 -1
- package/components/media/asset-collection-runtime.js +6 -16
- package/components/media/media-font-metrics.d.ts +3 -0
- package/components/media/media-font-metrics.js +43 -0
- package/components/media/phi-area-upload-widget.js +53 -97
- package/components/media/phi-image-preview-data.d.ts +13 -0
- package/components/media/phi-image-preview-data.js +184 -9
- package/components/media/phi-media-picker-binding.js +16 -13
- package/components/media/phi-media-upload.d.ts +15 -8
- package/components/media/phi-media-upload.js +18 -9
- package/components/media/phi-site-font-assets.js +7 -8
- package/components/navigation/phi-link.js +6 -1
- package/components/overlays/phi-overlay-container-client.js +16 -1
- package/components/regions/clients/cms-region-container-client.js +6 -1
- package/components/regions/phi-cms-region-container.js +3 -0
- package/components/regions/phi-cms-region-shell.d.ts +12 -1
- package/components/regions/phi-cms-region-shell.js +81 -19
- package/components/regions/presets/phi-settings-page-shell-tree.js +48 -1
- package/components/root/phi-config-provider.d.ts +13 -0
- package/components/root/phi-config-provider.js +12 -1
- package/components/root/phi-root-background.d.ts +7 -0
- package/components/root/phi-root-background.js +20 -1
- package/components/root/phi-root-theme-resolver.js +3 -0
- package/components/root/phi-shell-chrome-overlay.d.ts +12 -1
- package/components/root/phi-shell-chrome-overlay.js +19 -3
- package/components/runtime/runtime-controller-materialization.js +12 -1
- package/components/shell/phi-antd-icon.d.ts +1 -0
- package/components/shell/phi-antd-icon.js +3 -0
- package/components/shell/use-phi-shell-sticky-top.js +61 -16
- package/components/state/scoped-state-store.js +20 -3
- package/components/surface/phi-surface-tone.d.ts +13 -0
- package/components/surface/phi-surface-tone.js +21 -0
- package/components/tables/client/phi-table-binding.d.ts +2 -1
- package/components/tables/client/phi-table-binding.js +45 -21
- package/components/trees/client/phi-tree-binding.js +19 -11
- package/components/widgets/client/bullet-list-entries-editor.d.ts +26 -0
- package/components/widgets/client/bullet-list-entries-editor.js +109 -0
- package/components/widgets/client/html-editor.js +1 -1
- package/components/widgets/client/shared/use-page-reference-options.d.ts +17 -0
- package/components/widgets/client/shared/use-page-reference-options.js +57 -0
- package/components/widgets/config/background.d.ts +32 -1
- package/components/widgets/config/background.js +41 -2
- package/components/widgets/config/choice-shared.js +12 -13
- package/components/widgets/config/command-buttons.d.ts +5 -1
- package/components/widgets/config/command-buttons.js +38 -81
- package/components/widgets/config/control-signal-config.d.ts +3 -1
- package/components/widgets/config/control-signal-config.js +19 -17
- package/components/widgets/config/image-source-parser.d.ts +1 -0
- package/components/widgets/config/image-source-parser.js +7 -8
- package/components/widgets/config/mask.d.ts +6 -1
- package/components/widgets/config/mask.js +24 -1
- package/components/widgets/config/parser-primitives.js +72 -0
- package/components/widgets/config/stack-tabs.d.ts +1 -1
- package/components/widgets/config/stack-tabs.js +2 -3
- package/components/widgets/config/strict-config-reader.d.ts +40 -0
- package/components/widgets/config/strict-config-reader.js +174 -0
- package/components/widgets/label-sets/background.js +2 -0
- package/components/widgets/label-sets/effects.js +2 -0
- package/components/widgets/label-types/background.d.ts +1 -0
- package/components/widgets/label-types/background.js +1 -0
- package/components/widgets/label-types/effects.d.ts +1 -0
- package/components/widgets/label-types/effects.js +1 -0
- package/components/widgets/navigation-descriptor-resolver.server.js +20 -8
- package/components/widgets/shared/bullet-list-vocabulary.d.ts +27 -1
- package/components/widgets/shared/bullet-list-vocabulary.js +24 -4
- package/components/widgets/shared/card-body-client.d.ts +18 -4
- package/components/widgets/shared/card-body-client.js +126 -26
- package/components/widgets/shared/card-vocabulary.d.ts +31 -4
- package/components/widgets/shared/card-vocabulary.js +35 -2
- package/components/widgets/shared/markdown-body-client.js +39 -10
- package/components/widgets/signals/control-signal-capabilities.d.ts +0 -18
- package/components/widgets/signals/control-signal-capabilities.js +10 -22
- package/components/workspace/catalog-store.d.ts +4 -3
- package/components/workspace/catalog-store.js +6 -5
- package/gateway/dashboard-cards-route.js +1 -0
- package/gateway/internal-references.d.ts +6 -1
- package/gateway/internal-references.js +48 -23
- package/gateway/site-cms-write-validation.d.ts +9 -0
- package/gateway/site-cms-write-validation.js +78 -0
- package/gateway/site-proxy.js +19 -3
- package/helpers/cms-container-chrome.js +6 -1
- package/helpers/locale.d.ts +8 -0
- package/helpers/locale.js +18 -0
- package/helpers/renderable-block-serialization.js +1 -1
- package/helpers/shell-region-style.js +2 -1
- package/helpers/surface-style.d.ts +12 -1
- package/helpers/surface-style.js +28 -2
- package/module-dashboard-cards.d.ts +1 -1
- package/module-dashboard-cards.js +1 -1
- package/next/config.d.mts +3 -0
- package/next/config.mjs +28 -1
- package/package.json +2 -2
- package/plugins/runtime/phi-slot-child-viewport-effects-observer.js +5 -1
- package/plugins/runtime-modules/accounting/presets.d.ts +9 -0
- package/plugins/runtime-modules/accounting/presets.js +37 -0
- package/plugins/runtime-modules/accounting/server.d.ts +1 -4
- package/plugins/runtime-modules/accounting/server.js +4 -7
- package/plugins/runtime-modules/app/presets.d.ts +18 -0
- package/plugins/runtime-modules/app/presets.js +67 -0
- package/plugins/runtime-modules/app/server.d.ts +1 -4
- package/plugins/runtime-modules/app/server.js +4 -7
- package/plugins/runtime-modules/area-definitions.d.ts +0 -42
- package/plugins/runtime-modules/area-definitions.js +3 -8
- package/plugins/runtime-modules/asset/controller/runtime.js +2 -2
- package/plugins/runtime-modules/asset/services/collection.js +9 -1
- package/plugins/runtime-modules/asset/services/options.js +2 -2
- package/plugins/runtime-modules/builder/area-settings-answer.js +2 -1
- package/plugins/runtime-modules/builder/authoring-canvas.js +6 -6
- package/plugins/runtime-modules/builder/cards.js +3 -5
- package/plugins/runtime-modules/builder/clients/builder-region-overrides.js +3 -3
- package/plugins/runtime-modules/builder/clients/canvas-widget.js +15 -54
- package/plugins/runtime-modules/builder/clients/inspector-config-field.d.ts +4 -1
- package/plugins/runtime-modules/builder/clients/inspector-config-field.js +25 -35
- package/plugins/runtime-modules/builder/clients/inspector-link-target-field.js +1 -1
- package/plugins/runtime-modules/builder/clients/inspector-section-widget.js +8 -8
- package/plugins/runtime-modules/builder/clients/inspector-title.js +6 -6
- package/plugins/runtime-modules/builder/clients/layout-inspector.d.ts +1 -1
- package/plugins/runtime-modules/builder/clients/layout-inspector.js +11 -25
- package/plugins/runtime-modules/builder/clients/layout-scaffold-overlays.js +10 -5
- package/plugins/runtime-modules/builder/clients/mode-switch.js +1 -1
- package/plugins/runtime-modules/builder/clients/pages-header.js +11 -11
- package/plugins/runtime-modules/builder/clients/pages-workspace.js +1 -1
- package/plugins/runtime-modules/builder/clients/region-visibility-fields.js +1 -1
- package/plugins/runtime-modules/builder/clients/runtime-module-authoring-boundary.js +1 -1
- package/plugins/runtime-modules/builder/clients/shells-workspace.js +15 -31
- package/plugins/runtime-modules/builder/clients/structure-canvas.js +1 -1
- package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.d.ts +26 -0
- package/plugins/runtime-modules/builder/clients/use-region-draft-hydration.js +36 -0
- package/plugins/runtime-modules/builder/clients/widget-effects-editor.js +1 -1
- package/plugins/runtime-modules/builder/clients/widget-inspector.js +1 -0
- package/plugins/runtime-modules/builder/clients/workspace-scope-boundary.js +2 -2
- package/plugins/runtime-modules/builder/cms-instance-allocator.js +8 -28
- package/plugins/runtime-modules/builder/controller/client.d.ts +0 -15
- package/plugins/runtime-modules/builder/controller/definition.d.ts +0 -15
- package/plugins/runtime-modules/builder/controller/definition.js +0 -8
- package/plugins/runtime-modules/builder/controller/draft-command-controller.d.ts +1 -2
- package/plugins/runtime-modules/builder/controller/draft-command-controller.js +11 -30
- package/plugins/runtime-modules/builder/controller/draft-status-controller.js +15 -2
- package/plugins/runtime-modules/builder/controller/inspector-controller.d.ts +1 -2
- package/plugins/runtime-modules/builder/controller/inspector-controller.js +4 -7
- package/plugins/runtime-modules/builder/controller/page-controller.d.ts +1 -2
- package/plugins/runtime-modules/builder/controller/page-controller.js +16 -68
- package/plugins/runtime-modules/builder/controller/server-definition.d.ts +0 -15
- package/plugins/runtime-modules/builder/controller/signal-wiring-controller.d.ts +2 -5
- package/plugins/runtime-modules/builder/controller/signal-wiring-controller.js +6 -50
- package/plugins/runtime-modules/builder/controller/workspace-controller.d.ts +2 -3
- package/plugins/runtime-modules/builder/controller/workspace-controller.js +89 -153
- package/plugins/runtime-modules/builder/data-providers.d.ts +1 -0
- package/plugins/runtime-modules/builder/data-providers.js +1 -0
- package/plugins/runtime-modules/builder/definition.d.ts +1 -0
- package/plugins/runtime-modules/builder/developer-workspace-store.d.ts +64 -30
- package/plugins/runtime-modules/builder/developer-workspace-store.js +255 -61
- package/plugins/runtime-modules/builder/edit-scaffold-drawer.js +4 -3
- package/plugins/runtime-modules/builder/history.d.ts +3 -1
- package/plugins/runtime-modules/builder/options-providers.js +3 -2
- package/plugins/runtime-modules/builder/page-catalog-client.js +19 -7
- package/plugins/runtime-modules/builder/page-meta-form.js +1 -0
- package/plugins/runtime-modules/builder/page-references-provider.js +1 -1
- package/plugins/runtime-modules/builder/persistence.js +33 -69
- package/plugins/runtime-modules/builder/public-route-collisions.d.ts +2 -2
- package/plugins/runtime-modules/builder/public-route-collisions.js +6 -19
- package/plugins/runtime-modules/builder/render-root-node-preview.server.js +20 -3
- package/plugins/runtime-modules/builder/render-root-node-scaffold.js +28 -18
- package/plugins/runtime-modules/builder/runtime-module-selection.d.ts +2 -12
- package/plugins/runtime-modules/builder/runtime-module-selection.js +16 -42
- package/plugins/runtime-modules/builder/services/navigation-table.js +9 -15
- package/plugins/runtime-modules/builder/services/page-source-tree.js +8 -8
- package/plugins/runtime-modules/builder/services/runtime-modules-table.js +10 -10
- package/plugins/runtime-modules/builder/services/signal-routes-table.js +3 -3
- package/plugins/runtime-modules/builder/signal-route-selection.d.ts +1 -2
- package/plugins/runtime-modules/builder/signal-route-selection.js +2 -2
- package/plugins/runtime-modules/builder/signal-wiring-options.js +3 -2
- package/plugins/runtime-modules/builder/structure-dnd.js +8 -61
- package/plugins/runtime-modules/builder/trees/phi-default-builder-area-preset-tree.js +17 -10
- package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +27 -22
- package/plugins/runtime-modules/builder/workspace-catalog-actions.d.ts +55 -0
- package/plugins/runtime-modules/builder/workspace-catalog-actions.js +142 -0
- package/plugins/runtime-modules/client-authoring-module.d.ts +8 -1
- package/plugins/runtime-modules/client-authoring-module.js +13 -3
- package/plugins/runtime-modules/client-manifests/common.js +1 -1
- package/plugins/runtime-modules/{runtime-calendar-adapters.js → core/calendar-adapters.js} +2 -2
- package/plugins/runtime-modules/{client-calendar-adapters/core.js → core/client-calendar-adapters.js} +1 -1
- package/plugins/runtime-modules/core/content-entries/table.js +1 -1
- package/plugins/runtime-modules/core/data-providers.d.ts +3 -0
- package/plugins/runtime-modules/core/data-providers.js +2 -1
- package/plugins/runtime-modules/core/definition.d.ts +3 -0
- package/plugins/runtime-modules/core/definition.js +1 -1
- package/plugins/runtime-modules/core/messaging/data-providers.d.ts +1 -0
- package/plugins/runtime-modules/core/messaging/data-providers.js +1 -0
- package/plugins/runtime-modules/core/messaging/thread-inbox-table.js +1 -1
- package/plugins/runtime-modules/core/server.js +1 -1
- package/plugins/runtime-modules/core/themes.d.ts +44 -0
- package/plugins/runtime-modules/core/themes.js +12 -0
- package/plugins/runtime-modules/core/widgets/brand/client.d.ts +12 -3
- package/plugins/runtime-modules/core/widgets/brand/client.js +3 -11
- package/plugins/runtime-modules/core/widgets/brand/home.d.ts +15 -0
- package/plugins/runtime-modules/core/widgets/brand/home.js +18 -0
- package/plugins/runtime-modules/core/widgets/brand/plugin.js +3 -2
- package/plugins/runtime-modules/core/widgets/brand/server.d.ts +2 -2
- package/plugins/runtime-modules/core/widgets/brand/server.js +2 -2
- package/plugins/runtime-modules/core/widgets/card/collection-view-binding.js +25 -9
- package/plugins/runtime-modules/core/widgets/card/config.d.ts +301 -254
- package/plugins/runtime-modules/core/widgets/card/config.js +68 -3
- package/plugins/runtime-modules/core/widgets/card/editor.js +41 -4
- package/plugins/runtime-modules/core/widgets/card/server.d.ts +3 -0
- package/plugins/runtime-modules/core/widgets/card/server.js +32 -3
- package/plugins/runtime-modules/core/widgets/collection-view/asset-binding.js +7 -6
- package/plugins/runtime-modules/core/widgets/collection-view/config.js +9 -2
- package/plugins/runtime-modules/core/widgets/description/client.js +3 -3
- package/plugins/runtime-modules/core/widgets/description/config.d.ts +2 -25
- package/plugins/runtime-modules/core/widgets/description/editor.js +7 -63
- package/plugins/runtime-modules/core/widgets/description/server.js +3 -2
- package/plugins/runtime-modules/core/widgets/entry-list/config.d.ts +2 -25
- package/plugins/runtime-modules/core/widgets/gallery/config.d.ts +2 -25
- package/plugins/runtime-modules/core/widgets/header-navigation/client.js +2 -2
- package/plugins/runtime-modules/core/widgets/html/client.js +1 -1
- package/plugins/runtime-modules/core/widgets/image/config.js +2 -2
- package/plugins/runtime-modules/core/widgets/markdown/config.d.ts +320 -2
- package/plugins/runtime-modules/core/widgets/markdown/config.js +18 -4
- package/plugins/runtime-modules/core/widgets/markdown/editor.js +11 -4
- package/plugins/runtime-modules/core/widgets/markdown-toc/client.js +6 -1
- package/plugins/runtime-modules/core/widgets/markdown-toc/config.d.ts +14 -0
- package/plugins/runtime-modules/core/widgets/markdown-toc/config.js +14 -2
- package/plugins/runtime-modules/core/widgets/quick-links/authoring.js +7 -2
- package/plugins/runtime-modules/core/widgets/quick-links/client.js +2 -2
- package/plugins/runtime-modules/core/widgets/quick-links/items.d.ts +0 -2
- package/plugins/runtime-modules/core/widgets/quick-links/items.js +0 -15
- package/plugins/runtime-modules/core/widgets/result/config.d.ts +5 -25
- package/plugins/runtime-modules/core/widgets/result/config.js +2 -0
- package/plugins/runtime-modules/core/widgets/result/server.js +25 -19
- package/plugins/runtime-modules/core/widgets/sidebar-navigation/authoring.js +1 -1
- package/plugins/runtime-modules/core/widgets/sidebar-navigation/client.js +1 -1
- package/plugins/runtime-modules/core/widgets/simple-text/client.js +8 -3
- package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +2 -25
- package/plugins/runtime-modules/core/widgets/simple-text/editor.js +2 -2
- package/plugins/runtime-modules/core/widgets/slot-upload/client.js +11 -2
- package/plugins/runtime-modules/core/widgets/table/client.js +8 -4
- package/plugins/runtime-modules/core/widgets/table/config.d.ts +6 -83
- package/plugins/runtime-modules/core/widgets/table/config.js +302 -452
- package/plugins/runtime-modules/core/widgets/tree/config.js +5 -2
- package/plugins/runtime-modules/dashboard/card-rows.d.ts +7 -0
- package/plugins/runtime-modules/dashboard/card-rows.js +87 -0
- package/plugins/runtime-modules/dashboard/clients/dashboard-card-view.js +32 -12
- package/plugins/runtime-modules/dashboard/services/collection.js +17 -7
- package/plugins/runtime-modules/dashboard/trees/phi-default-builder-dashboard-page-tree.js +5 -40
- package/plugins/runtime-modules/groups/data-providers.d.ts +2 -0
- package/plugins/runtime-modules/groups/data-providers.js +3 -3
- package/plugins/runtime-modules/groups/definition.d.ts +2 -0
- package/plugins/runtime-modules/localization/data-providers.d.ts +3 -0
- package/plugins/runtime-modules/localization/data-providers.js +2 -0
- package/plugins/runtime-modules/localization/definition.d.ts +3 -0
- package/plugins/runtime-modules/localization/services/table.js +3 -7
- package/plugins/runtime-modules/observability/data-providers.d.ts +1 -0
- package/plugins/runtime-modules/observability/data-providers.js +1 -0
- package/plugins/runtime-modules/observability/definition.d.ts +1 -0
- package/plugins/runtime-modules/observability/module.d.ts +1 -0
- package/plugins/runtime-modules/observability/services/table.js +1 -1
- package/plugins/runtime-modules/phi-default-site-area-preset-tree.js +2 -105
- package/plugins/runtime-modules/public/presets.d.ts +115 -0
- package/plugins/runtime-modules/{area-base-presets.js → public/presets.js} +19 -119
- package/plugins/runtime-modules/public/server.d.ts +1 -4
- package/plugins/runtime-modules/public/server.js +4 -7
- package/plugins/runtime-modules/public/trees/phi-default-pub-error-page-tree.js +7 -8
- package/plugins/runtime-modules/public-base-page-references.d.ts +1 -1
- package/plugins/runtime-modules/public-base-page-references.js +1 -1
- package/plugins/runtime-modules/revisions/controller/client.js +11 -11
- package/plugins/runtime-modules/revisions/services/table.js +3 -3
- package/plugins/runtime-modules/theme/trees/phi-default-builder-theme-page-tree.js +22 -0
- package/plugins/runtime-modules/theme/widgets/brand-controls/client.d.ts +2 -1
- package/plugins/runtime-modules/theme/widgets/brand-controls/client.js +111 -72
- package/plugins/runtime-modules/theme/widgets/brand-controls/config.d.ts +2 -1
- package/plugins/runtime-modules/theme/widgets/brand-controls/config.js +28 -31
- package/plugins/runtime-modules/theme/widgets/brand-controls/plugin.js +1 -1
- package/plugins/runtime-modules/theme-descriptors.js +1 -1
- package/plugins/runtime-modules/user-management/data-providers.d.ts +2 -0
- package/plugins/runtime-modules/user-management/data-providers.js +1 -0
- package/plugins/runtime-modules/user-management/definition.d.ts +2 -0
- package/server-helpers/cms-link-targets.js +6 -0
- package/styles/control-shape.css +11 -11
- package/styles/controls.css +67 -5
- package/styles/layout.css +61 -9
- package/styles/shell.css +73 -0
- package/theme/phi-antd-token-resolver.js +20 -1
- package/theme/phi-theme-tokens.d.ts +1 -1
- package/theme/phi-theme-tokens.js +1 -0
- package/theme/phi-theme.d.ts +5 -0
- package/theme/phi-theme.js +21 -0
- package/theme/phi-tokens.d.ts +16 -15
- package/theme/phi-tokens.js +16 -15
- package/types/cms-config.js +142 -185
- package/types/cms-plugins.d.ts +6 -11
- package/types/core-widget-placements.d.ts +14 -3
- package/types/dashboard-cards.d.ts +48 -4
- package/types/dashboard-cards.js +6 -0
- package/types/media.d.ts +0 -3
- package/types/renderable-block.d.ts +6 -1
- package/types/site-theme.d.ts +10 -2
- package/types/table-widget.d.ts +9 -0
- package/types/table-widget.js +20 -0
- package/types.d.ts +1 -1
- package/widget-config.d.ts +2 -0
- package/widget-config.js +6 -0
- package/plugins/runtime-modules/area-base-presets.d.ts +0 -139
- /package/plugins/runtime-modules/{runtime-calendar-adapters.d.ts → core/calendar-adapters.d.ts} +0 -0
- /package/plugins/runtime-modules/{client-calendar-adapters/core.d.ts → core/client-calendar-adapters.d.ts} +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
/*
|
|
4
|
+
* One request per Area for as long as the page lives: the create and the edit dialog offer the same
|
|
5
|
+
* Pages, and a list that changed meanwhile is a Page somebody published while this one was being written.
|
|
6
|
+
* A failed request is forgotten, so the next dialog asks again.
|
|
7
|
+
*/
|
|
8
|
+
const pageOptionsByArea = new Map();
|
|
9
|
+
function loadPageOptions(area) {
|
|
10
|
+
const cached = pageOptionsByArea.get(area);
|
|
11
|
+
if (cached)
|
|
12
|
+
return cached;
|
|
13
|
+
const request = (async () => {
|
|
14
|
+
const response = await fetch(`/api/site/page-references?area=${encodeURIComponent(area)}`, {
|
|
15
|
+
cache: "no-store",
|
|
16
|
+
credentials: "same-origin",
|
|
17
|
+
headers: { accept: "application/json" },
|
|
18
|
+
});
|
|
19
|
+
const payload = (await response.json().catch(() => null));
|
|
20
|
+
if (!response.ok || !Array.isArray(payload?.options)) {
|
|
21
|
+
throw new Error(`Page references for "${area}" answered ${response.status}.`);
|
|
22
|
+
}
|
|
23
|
+
return payload.options;
|
|
24
|
+
})();
|
|
25
|
+
pageOptionsByArea.set(area, request);
|
|
26
|
+
request.catch(() => pageOptionsByArea.delete(area));
|
|
27
|
+
return request;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The Pages of one Area a link may point at, as the tree `PhiLinkTargetControl` offers, for a surface
|
|
31
|
+
* that stands outside the Builder's own catalog: a Form's `link-target` field, the Theme's Brand.
|
|
32
|
+
*
|
|
33
|
+
* Answered by `/api/site/page-references` (`gateway/page-references-route.ts`), which merges the Area's
|
|
34
|
+
* Module Pages and Core's the way the Builder's picker does. `failed` is set when the list could not be
|
|
35
|
+
* read, so the surface can say so instead of showing an empty list that looks like a Site without Pages.
|
|
36
|
+
*/
|
|
37
|
+
export function usePhiPageReferenceOptions(area, logScope) {
|
|
38
|
+
const [options, setOptions] = useState([]);
|
|
39
|
+
const [failed, setFailed] = useState(false);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
let current = true;
|
|
42
|
+
loadPageOptions(area).then((next) => {
|
|
43
|
+
if (current) {
|
|
44
|
+
setOptions(next);
|
|
45
|
+
setFailed(false);
|
|
46
|
+
}
|
|
47
|
+
}, (error) => {
|
|
48
|
+
console.warn(`[${logScope}] Page references could not be loaded.`, { area, error });
|
|
49
|
+
if (current)
|
|
50
|
+
setFailed(true);
|
|
51
|
+
});
|
|
52
|
+
return () => {
|
|
53
|
+
current = false;
|
|
54
|
+
};
|
|
55
|
+
}, [area, logScope]);
|
|
56
|
+
return { options, failed };
|
|
57
|
+
}
|
|
@@ -18,6 +18,19 @@ export type PhiBackgroundBaseColor = {
|
|
|
18
18
|
export type PhiBackgroundBaseNone = {
|
|
19
19
|
kind: "none";
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* The Theme's Chrome Overlay as the ground (LAYOUTING.md "Surface tone", SHELL.md "Root Background and
|
|
23
|
+
* Shell Backdrop Layers").
|
|
24
|
+
*
|
|
25
|
+
* The box paints what the Theme workspace calls the Chrome Overlay -- its colour or picture and its glass
|
|
26
|
+
* pane -- instead of a ground of its own. It carries nothing else: the Overlay is the Theme's, per mode
|
|
27
|
+
* (`root.chrome[mode]`), and the box reads the mode it stands in. A Surface `tone` is that mode, so an
|
|
28
|
+
* `inverse` Footer is the dark Overlay on a light page and the light one on a dark page. It is a stated
|
|
29
|
+
* ground: a tone does not paint its own container ground beneath it.
|
|
30
|
+
*/
|
|
31
|
+
export type PhiBackgroundBaseTheme = {
|
|
32
|
+
kind: "theme";
|
|
33
|
+
};
|
|
21
34
|
export type PhiBackgroundBaseGradient = {
|
|
22
35
|
kind: "gradient";
|
|
23
36
|
direction: PhiBackgroundDirection;
|
|
@@ -50,6 +63,24 @@ export type PhiBackgroundImageSourceKind = "asset" | "url";
|
|
|
50
63
|
*/
|
|
51
64
|
export declare const PHI_BACKGROUND_IMAGE_SOURCE_KINDS: readonly PhiBackgroundImageSourceKind[];
|
|
52
65
|
export declare const PHI_BACKGROUND_BASE_KINDS: readonly PhiCmsBackgroundWidgetConfig["base"]["kind"][];
|
|
66
|
+
/**
|
|
67
|
+
* The container ground of the mode a box stands in. What a toned Surface paints where it states no
|
|
68
|
+
* ground (`PHI_SURFACE_TONE_GROUND`), and what a `theme` ground falls back to where the Theme's Overlay
|
|
69
|
+
* is not published.
|
|
70
|
+
*/
|
|
71
|
+
export declare const PHI_BACKGROUND_CONTAINER_GROUND = "var(--ant-color-bg-container)";
|
|
72
|
+
/**
|
|
73
|
+
* What a `theme` Base paints: the Shell Chrome Overlay's custom properties, the same ones the Shell's
|
|
74
|
+
* chrome panes paint from (components/shell/phi-cms-shell.tsx).
|
|
75
|
+
*
|
|
76
|
+
* The Root Layout publishes them for the page's mode, and `styles/shell.css` publishes them again under a
|
|
77
|
+
* tone's class for the tone's mode, so the box needs no colour of its own and turns with the mode switch.
|
|
78
|
+
* Outside the Root Layout -- a Modal or Drawer portalled to `<body>` -- nothing publishes them, and the box
|
|
79
|
+
* takes the container ground of its mode instead: the tone's ground, or the Overlay's own where it has no
|
|
80
|
+
* tone. Fixed attachment for the reason the Chrome Regions have it: every box is a window onto one
|
|
81
|
+
* viewport-sized painting.
|
|
82
|
+
*/
|
|
83
|
+
export declare const PHI_BACKGROUND_THEME_STYLE: Readonly<CSSProperties>;
|
|
53
84
|
export declare const PHI_BACKGROUND_MOTION_MODES: readonly PhiBackgroundMotionMode[];
|
|
54
85
|
export type PhiBackgroundMotionDirection = "natural" | "reverse";
|
|
55
86
|
/**
|
|
@@ -103,7 +134,7 @@ export type PhiBackgroundOverlay = PhiBackgroundColorOverlay | PhiBackgroundPatt
|
|
|
103
134
|
/** What an Overlay that states no opacity is painted at, shared by every kind. */
|
|
104
135
|
export declare const PHI_BACKGROUND_OVERLAY_DEFAULT_OPACITY = 0.14;
|
|
105
136
|
export type PhiCmsBackgroundWidgetConfig = {
|
|
106
|
-
base: PhiBackgroundBaseColor | PhiBackgroundBaseGradient | PhiBackgroundBaseImage | PhiBackgroundBaseNone;
|
|
137
|
+
base: PhiBackgroundBaseColor | PhiBackgroundBaseGradient | PhiBackgroundBaseImage | PhiBackgroundBaseNone | PhiBackgroundBaseTheme;
|
|
107
138
|
overlay?: PhiBackgroundOverlay | null;
|
|
108
139
|
filter?: PhiBackgroundFilter | null;
|
|
109
140
|
motion?: PhiBackgroundMotion | null;
|
|
@@ -30,7 +30,35 @@ export const PHI_BACKGROUND_BASE_KINDS = [
|
|
|
30
30
|
"color",
|
|
31
31
|
"gradient",
|
|
32
32
|
"image",
|
|
33
|
+
"theme",
|
|
33
34
|
];
|
|
35
|
+
/**
|
|
36
|
+
* The container ground of the mode a box stands in. What a toned Surface paints where it states no
|
|
37
|
+
* ground (`PHI_SURFACE_TONE_GROUND`), and what a `theme` ground falls back to where the Theme's Overlay
|
|
38
|
+
* is not published.
|
|
39
|
+
*/
|
|
40
|
+
export const PHI_BACKGROUND_CONTAINER_GROUND = "var(--ant-color-bg-container)";
|
|
41
|
+
/**
|
|
42
|
+
* What a `theme` Base paints: the Shell Chrome Overlay's custom properties, the same ones the Shell's
|
|
43
|
+
* chrome panes paint from (components/shell/phi-cms-shell.tsx).
|
|
44
|
+
*
|
|
45
|
+
* The Root Layout publishes them for the page's mode, and `styles/shell.css` publishes them again under a
|
|
46
|
+
* tone's class for the tone's mode, so the box needs no colour of its own and turns with the mode switch.
|
|
47
|
+
* Outside the Root Layout -- a Modal or Drawer portalled to `<body>` -- nothing publishes them, and the box
|
|
48
|
+
* takes the container ground of its mode instead: the tone's ground, or the Overlay's own where it has no
|
|
49
|
+
* tone. Fixed attachment for the reason the Chrome Regions have it: every box is a window onto one
|
|
50
|
+
* viewport-sized painting.
|
|
51
|
+
*/
|
|
52
|
+
export const PHI_BACKGROUND_THEME_STYLE = {
|
|
53
|
+
backgroundColor: `var(--phi-shell-chrome-color, ${PHI_BACKGROUND_CONTAINER_GROUND})`,
|
|
54
|
+
backgroundImage: "var(--phi-shell-chrome-image, none)",
|
|
55
|
+
backgroundSize: "var(--phi-shell-chrome-size, auto)",
|
|
56
|
+
backgroundPosition: "var(--phi-shell-chrome-position, 0 0)",
|
|
57
|
+
backgroundRepeat: "var(--phi-shell-chrome-repeat, repeat)",
|
|
58
|
+
backgroundAttachment: "fixed",
|
|
59
|
+
backdropFilter: "var(--phi-shell-chrome-filter, none)",
|
|
60
|
+
WebkitBackdropFilter: "var(--phi-shell-chrome-filter, none)",
|
|
61
|
+
};
|
|
34
62
|
export const PHI_BACKGROUND_MOTION_MODES = [
|
|
35
63
|
"static",
|
|
36
64
|
"fixed",
|
|
@@ -145,7 +173,7 @@ function normalizePhiBackgroundBase(value) {
|
|
|
145
173
|
? { ...normalized, ...source }
|
|
146
174
|
: { ...normalized, ...source };
|
|
147
175
|
}
|
|
148
|
-
if (kind === "none")
|
|
176
|
+
if (kind === "none" || kind === "theme")
|
|
149
177
|
return { kind };
|
|
150
178
|
if (kind === "color") {
|
|
151
179
|
const color = readString(raw.color);
|
|
@@ -253,6 +281,10 @@ export function normalizePhiBackgroundWidgetConfig(config) {
|
|
|
253
281
|
}
|
|
254
282
|
const raw = config;
|
|
255
283
|
const base = normalizePhiBackgroundBase(raw.base) ?? normalizePhiBackgroundBase(raw) ?? { kind: "none" };
|
|
284
|
+
// The Theme's Overlay is the whole ground: it carries its own Overlay and pane, and takes none of the box's.
|
|
285
|
+
if (base.kind === "theme") {
|
|
286
|
+
return { base, overlay: null, filter: null, motion: null };
|
|
287
|
+
}
|
|
256
288
|
return {
|
|
257
289
|
base,
|
|
258
290
|
overlay: readBackgroundOverlay(raw.overlay),
|
|
@@ -278,6 +310,9 @@ export function readPhiBackgroundPatternInkFromCss(css) {
|
|
|
278
310
|
export function serializePhiBackgroundBaseCss(base) {
|
|
279
311
|
if (base.kind === "none")
|
|
280
312
|
return "none";
|
|
313
|
+
// Not a value a Base can be read back from: the Overlay's colour, as far as one CSS value can say it.
|
|
314
|
+
if (base.kind === "theme")
|
|
315
|
+
return String(PHI_BACKGROUND_THEME_STYLE.backgroundColor);
|
|
281
316
|
if (base.kind === "color")
|
|
282
317
|
return base.color;
|
|
283
318
|
if (base.kind === "gradient") {
|
|
@@ -320,6 +355,9 @@ function resolvePhiBackgroundOverlayLayer(overlay) {
|
|
|
320
355
|
export function resolvePhiBackgroundWidgetStyle(config) {
|
|
321
356
|
const normalized = normalizePhiBackgroundWidgetConfig(config);
|
|
322
357
|
const base = normalized.base;
|
|
358
|
+
if (base.kind === "theme") {
|
|
359
|
+
return { ...PHI_BACKGROUND_THEME_STYLE };
|
|
360
|
+
}
|
|
323
361
|
const style = {};
|
|
324
362
|
if (base.kind === "color")
|
|
325
363
|
style.backgroundColor = base.color;
|
|
@@ -397,7 +435,8 @@ export function phiBackgroundWidgetConfigPaintsGround(config) {
|
|
|
397
435
|
* nor honoured there.
|
|
398
436
|
*/
|
|
399
437
|
export function phiBackgroundBaseSupportsGlassEffect(base) {
|
|
400
|
-
|
|
438
|
+
// The Theme's Overlay brings its own pane, and a second one over it is nothing anybody asked for.
|
|
439
|
+
return base.kind !== "image" && base.kind !== "gradient" && base.kind !== "theme";
|
|
401
440
|
}
|
|
402
441
|
/**
|
|
403
442
|
* Whether `blur` has anything to soften: a picture, a gradient, or a patterned Overlay.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parsePhiControlOptionsProviderConfig, readPhiControlOptions, } from "../../controls/phi-control-options";
|
|
2
|
-
import {
|
|
2
|
+
import { createPhiConfigReader } from "./strict-config-reader";
|
|
3
3
|
import { PHI_CONTROL_PRESENTATION_FIELDS, PHI_CONTROL_STATE_FIELDS, parsePhiControlConfig, } from "./control-signal-config";
|
|
4
4
|
export function buildPhiChoiceControlOptionFields(editorPlacement = "inspector") {
|
|
5
5
|
return [{
|
|
@@ -28,9 +28,10 @@ export function buildPhiChoiceControlOptionFields(editorPlacement = "inspector")
|
|
|
28
28
|
}
|
|
29
29
|
export const PHI_CHOICE_CONTROL_OPTION_FIELDS = buildPhiChoiceControlOptionFields();
|
|
30
30
|
export function parsePhiChoiceOptionsConfig(config) {
|
|
31
|
+
const reader = createPhiConfigReader(config);
|
|
31
32
|
return {
|
|
32
|
-
optionsProvider:
|
|
33
|
-
options:
|
|
33
|
+
optionsProvider: reader.value("optionsProvider", "an options provider", (value) => parsePhiControlOptionsProviderConfig(value) ?? undefined) ?? null,
|
|
34
|
+
options: reader.value("options", "a list of options", (value) => (Array.isArray(value) ? readPhiControlOptions(value) : undefined)) ?? readPhiControlOptions(undefined),
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
export const PHI_CHOICE_CONTROL_CONFIG_FIELDS = [
|
|
@@ -46,27 +47,25 @@ export const PHI_CHOICE_CONTROL_VALUE_MODE_FIELD = {
|
|
|
46
47
|
{ value: "stack-slot-index", label: "Stack Slot Index" },
|
|
47
48
|
],
|
|
48
49
|
};
|
|
49
|
-
function readPhiChoiceValueMode(value) {
|
|
50
|
-
return readString(value) === "stack-slot-index" ? "stack-slot-index" : "raw";
|
|
51
|
-
}
|
|
52
50
|
export function parsePhiChoiceControlConfig(config) {
|
|
53
51
|
const controlState = parsePhiControlConfig(config, {
|
|
54
52
|
key: "choice",
|
|
55
53
|
});
|
|
54
|
+
const reader = createPhiConfigReader(config);
|
|
56
55
|
return {
|
|
57
56
|
...controlState,
|
|
58
|
-
label:
|
|
59
|
-
description:
|
|
60
|
-
value:
|
|
61
|
-
placeholder:
|
|
62
|
-
presentation:
|
|
63
|
-
allowCustom:
|
|
57
|
+
label: reader.string("label"),
|
|
58
|
+
description: reader.string("description"),
|
|
59
|
+
value: reader.string("value"),
|
|
60
|
+
placeholder: reader.string("placeholder"),
|
|
61
|
+
presentation: reader.oneOf("presentation", ["select", "autocomplete"]) ?? "select",
|
|
62
|
+
allowCustom: reader.boolean("allowCustom"),
|
|
64
63
|
...parsePhiChoiceOptionsConfig(config),
|
|
65
64
|
};
|
|
66
65
|
}
|
|
67
66
|
export function parsePhiStackChoiceControlConfig(config) {
|
|
68
67
|
return {
|
|
69
68
|
...parsePhiChoiceControlConfig(config),
|
|
70
|
-
valueMode:
|
|
69
|
+
valueMode: createPhiConfigReader(config).oneOf("valueMode", ["raw", "stack-slot-index"]) ?? "raw",
|
|
71
70
|
};
|
|
72
71
|
}
|
|
@@ -2,7 +2,11 @@ import type { PhiCommandButtonConfig } from "../../../types/core-widget-placemen
|
|
|
2
2
|
import type { PhiCmsConfigField } from "../../../types";
|
|
3
3
|
import type { PhiCmsConfigFieldVisibilityRule } from "../../../types/cms-plugins";
|
|
4
4
|
import { type PhiAccessViewer, type PhiRoleProviderId } from "../../../types/access";
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* A Widget's buttons. Strict (`strict-config-reader.ts`): a button without a key or without an emit is
|
|
7
|
+
* an error naming it, not a button left out.
|
|
8
|
+
*/
|
|
9
|
+
export declare function readPhiCommandButtons(value: unknown, path?: string): PhiCommandButtonConfig[];
|
|
6
10
|
export declare function filterPhiCommandButtonsForViewer(buttons: readonly PhiCommandButtonConfig[], viewer: PhiAccessViewer, ownerProviderId?: PhiRoleProviderId | null): PhiCommandButtonConfig[];
|
|
7
11
|
/**
|
|
8
12
|
* A new button: the first free `buttonN` key, labelled after it, sending its key as the command. The
|
|
@@ -4,7 +4,7 @@ import { PHI_COMMON_CONTROL_DEFAULT_LABELS, readPhiCommonControlActionKey, } fro
|
|
|
4
4
|
import { PHI_BUTTON_VARIANT_FIELD_OPTIONS, readPhiButtonVariant } from "./button-variant";
|
|
5
5
|
import { createPhiCommonActionField, readPhiControlLabel } from "./common-action-field";
|
|
6
6
|
import { PHI_CONTROL_BADGE_FIELDS, parsePhiControlBadgeConfig } from "./control-signal-config";
|
|
7
|
-
import {
|
|
7
|
+
import { createPhiConfigReader } from "./strict-config-reader";
|
|
8
8
|
/*
|
|
9
9
|
* The buttons of a Widget that holds several: the Command Toolbar's row, and the Float Button's corner.
|
|
10
10
|
*
|
|
@@ -12,102 +12,59 @@ import { readBoolean, readNumber, readString } from "./parser-primitives";
|
|
|
12
12
|
* emit, and the Signals panel wires both. The two Widgets differ in how the buttons stand, never in what
|
|
13
13
|
* a button is, so the parser, the Inspector fields, the viewer filter and the scaffold's count are one.
|
|
14
14
|
*/
|
|
15
|
+
/** What a button sends: a text, a number, true/false, a list of texts or of numbers, or an object. */
|
|
15
16
|
function readButtonEmitValue(value) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const numberValue = readNumber(value);
|
|
21
|
-
if (numberValue !== undefined) {
|
|
22
|
-
return numberValue;
|
|
23
|
-
}
|
|
24
|
-
const booleanValue = readBoolean(value);
|
|
25
|
-
if (booleanValue !== undefined) {
|
|
26
|
-
return booleanValue;
|
|
27
|
-
}
|
|
28
|
-
if (value == null) {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
17
|
+
if (typeof value === "string" || typeof value === "boolean")
|
|
18
|
+
return value;
|
|
19
|
+
if (typeof value === "number")
|
|
20
|
+
return Number.isFinite(value) ? value : undefined;
|
|
31
21
|
if (Array.isArray(value)) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const numberItems = value.filter((item) => typeof item === "number" && Number.isFinite(item));
|
|
37
|
-
if (numberItems.length === value.length) {
|
|
38
|
-
return numberItems;
|
|
39
|
-
}
|
|
22
|
+
if (value.every((item) => typeof item === "string"))
|
|
23
|
+
return value;
|
|
24
|
+
if (value.every((item) => typeof item === "number" && Number.isFinite(item)))
|
|
25
|
+
return value;
|
|
40
26
|
return undefined;
|
|
41
27
|
}
|
|
42
|
-
|
|
43
|
-
return value;
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
28
|
+
return isPhiRecord(value) ? value : undefined;
|
|
46
29
|
}
|
|
47
|
-
function readCommandButtonEmitConfig(
|
|
48
|
-
if (!isPhiRecord(value)) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
const record = value;
|
|
52
|
-
const capabilityId = readString(record.capabilityId);
|
|
53
|
-
if (!capabilityId) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
30
|
+
function readCommandButtonEmitConfig(reader) {
|
|
56
31
|
return {
|
|
57
|
-
capabilityId,
|
|
58
|
-
value:
|
|
32
|
+
capabilityId: reader.string("capabilityId") ?? reader.fail("capabilityId", "a capability id"),
|
|
33
|
+
value: reader.value("value", "a text, number, true/false, list or object", readButtonEmitValue),
|
|
59
34
|
};
|
|
60
35
|
}
|
|
61
|
-
function
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
.
|
|
68
|
-
}
|
|
69
|
-
function readCommandButtonConfig(value) {
|
|
70
|
-
if (!isPhiRecord(value)) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
const record = value;
|
|
74
|
-
const key = readString(record.key);
|
|
75
|
-
const emits = readCommandButtonEmits(record.emits);
|
|
76
|
-
if (!key || emits.length === 0) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
const hasAccessPolicy = Object.prototype.hasOwnProperty.call(record, "accessPolicy");
|
|
80
|
-
const accessPolicy = hasAccessPolicy
|
|
81
|
-
? readPhiViewerAccessPolicy(record.accessPolicy)
|
|
36
|
+
function readCommandButtonConfig(reader) {
|
|
37
|
+
const key = reader.string("key") ?? reader.fail("key", "a text");
|
|
38
|
+
const emits = reader.list("emits", readCommandButtonEmitConfig) ?? [];
|
|
39
|
+
if (emits.length === 0)
|
|
40
|
+
reader.fail("emits", "at least one emit");
|
|
41
|
+
const accessPolicy = Object.prototype.hasOwnProperty.call(reader.record, "accessPolicy")
|
|
42
|
+
? readPhiViewerAccessPolicy(reader.record.accessPolicy) ?? reader.fail("accessPolicy", "an access policy")
|
|
82
43
|
: null;
|
|
83
|
-
if (hasAccessPolicy && !accessPolicy) {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
44
|
return {
|
|
87
45
|
key,
|
|
88
46
|
emits,
|
|
89
47
|
...(accessPolicy ? { accessPolicy } : {}),
|
|
90
|
-
...parsePhiControlBadgeConfig(record),
|
|
91
|
-
action:
|
|
92
|
-
label: readPhiControlLabel(record.label),
|
|
93
|
-
tooltip:
|
|
94
|
-
icon:
|
|
95
|
-
display:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
readOnly: readBoolean(record.readOnly),
|
|
101
|
-
variant: readPhiButtonVariant(record.variant),
|
|
48
|
+
...parsePhiControlBadgeConfig(reader.record, reader.path),
|
|
49
|
+
action: reader.value("action", "a common action", (value) => typeof value === "string" ? readPhiCommonControlActionKey(value) ?? undefined : undefined),
|
|
50
|
+
label: readPhiControlLabel(reader.record.label),
|
|
51
|
+
tooltip: reader.string("tooltip"),
|
|
52
|
+
icon: reader.string("icon"),
|
|
53
|
+
display: reader.oneOf("display", ["icon", "label", "icon-label"]),
|
|
54
|
+
danger: reader.boolean("danger"),
|
|
55
|
+
disabled: reader.boolean("disabled"),
|
|
56
|
+
readOnly: reader.boolean("readOnly"),
|
|
57
|
+
variant: reader.value("variant", "a button variant", readPhiButtonVariant),
|
|
102
58
|
};
|
|
103
59
|
}
|
|
104
|
-
|
|
105
|
-
|
|
60
|
+
/**
|
|
61
|
+
* A Widget's buttons. Strict (`strict-config-reader.ts`): a button without a key or without an emit is
|
|
62
|
+
* an error naming it, not a button left out.
|
|
63
|
+
*/
|
|
64
|
+
export function readPhiCommandButtons(value, path = "buttons") {
|
|
65
|
+
if (value === undefined || value === null)
|
|
106
66
|
return [];
|
|
107
|
-
}
|
|
108
|
-
return value
|
|
109
|
-
.map(readCommandButtonConfig)
|
|
110
|
-
.filter((item) => item != null);
|
|
67
|
+
return createPhiConfigReader({ [path]: value }).list(path, readCommandButtonConfig) ?? [];
|
|
111
68
|
}
|
|
112
69
|
export function filterPhiCommandButtonsForViewer(buttons, viewer, ownerProviderId) {
|
|
113
70
|
return buttons.filter((button) => canPhiViewerAccessOwnedPolicy(viewer, button.accessPolicy, ownerProviderId));
|
|
@@ -143,4 +143,6 @@ export declare function parsePhiControlSignalConfig(config: Record<string, unkno
|
|
|
143
143
|
export declare function parsePhiControlStateConfig(config: Record<string, unknown>, defaults: PhiControlSignalConfigDefaults): Required<Pick<PhiControlStateConfig, "key">> & Pick<PhiControlStateConfig, "signalRoutes" | "readOnly" | "disabled">;
|
|
144
144
|
export declare function parsePhiControlPresentationConfig<TSize extends PhiControlSize = PhiControlSize>(config: Record<string, unknown>, allowedSizes?: readonly TSize[]): PhiControlPresentationConfig<TSize>;
|
|
145
145
|
export declare function parsePhiControlConfig<TSize extends PhiControlSize = PhiControlSize>(config: Record<string, unknown>, defaults: PhiControlSignalConfigDefaults, allowedSizes?: readonly TSize[]): Required<Pick<PhiControlConfig<TSize>, "key">> & Pick<PhiControlConfig<TSize>, "signalRoutes" | "readOnly" | "disabled" | "controlSize">;
|
|
146
|
-
export declare function parsePhiControlBadgeConfig(config: Record<string, unknown
|
|
146
|
+
export declare function parsePhiControlBadgeConfig(config: Record<string, unknown>,
|
|
147
|
+
/** Where the config stands, when it is an entry of a list -- a button of a toolbar. */
|
|
148
|
+
path?: string): PhiControlBadgeConfig;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readPhiSignalRouteSet, } from "../../../types/signals";
|
|
2
|
-
import { PHI_CONTROL_SIZES,
|
|
3
|
-
import {
|
|
2
|
+
import { PHI_CONTROL_SIZES, } from "../../../types/control";
|
|
3
|
+
import { createPhiConfigReader } from "./strict-config-reader";
|
|
4
4
|
export const PHI_CONTROL_READ_ONLY_FIELD = {
|
|
5
5
|
key: "readOnly",
|
|
6
6
|
type: "boolean",
|
|
@@ -83,23 +83,22 @@ export const PHI_CONTROL_BADGE_FIELDS = [
|
|
|
83
83
|
export function parsePhiControlSignalConfig(config, defaults) {
|
|
84
84
|
return {
|
|
85
85
|
signalRoutes: readPhiSignalRouteSet(config.signalRoutes),
|
|
86
|
-
key:
|
|
86
|
+
key: createPhiConfigReader(config).string("key") ?? defaults.key,
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
export function parsePhiControlStateConfig(config, defaults) {
|
|
90
|
+
const reader = createPhiConfigReader(config);
|
|
90
91
|
return {
|
|
91
92
|
...parsePhiControlSignalConfig(config, defaults),
|
|
92
|
-
readOnly:
|
|
93
|
-
disabled:
|
|
93
|
+
readOnly: reader.boolean("readOnly"),
|
|
94
|
+
disabled: reader.boolean("disabled"),
|
|
94
95
|
};
|
|
95
96
|
}
|
|
96
97
|
export function parsePhiControlPresentationConfig(config, allowedSizes) {
|
|
97
|
-
|
|
98
|
-
const resolvedAllowedSizes = allowedSizes ?? PHI_CONTROL_SIZES;
|
|
98
|
+
// A size this Control does not offer is an error, not the default in its place.
|
|
99
|
+
const resolvedAllowedSizes = (allowedSizes ?? PHI_CONTROL_SIZES);
|
|
99
100
|
return {
|
|
100
|
-
controlSize: controlSize
|
|
101
|
-
? controlSize
|
|
102
|
-
: undefined,
|
|
101
|
+
controlSize: createPhiConfigReader(config).oneOf("controlSize", resolvedAllowedSizes),
|
|
103
102
|
};
|
|
104
103
|
}
|
|
105
104
|
export function parsePhiControlConfig(config, defaults, allowedSizes) {
|
|
@@ -113,13 +112,16 @@ export function parsePhiControlConfig(config, defaults, allowedSizes) {
|
|
|
113
112
|
controlSize: controlSize ?? ((allowedSizes ?? PHI_CONTROL_SIZES).includes("medium") ? "medium" : undefined),
|
|
114
113
|
};
|
|
115
114
|
}
|
|
116
|
-
export function parsePhiControlBadgeConfig(config
|
|
115
|
+
export function parsePhiControlBadgeConfig(config,
|
|
116
|
+
/** Where the config stands, when it is an entry of a list -- a button of a toolbar. */
|
|
117
|
+
path = "") {
|
|
118
|
+
const reader = createPhiConfigReader(config, path);
|
|
117
119
|
return {
|
|
118
|
-
badgeEnabled:
|
|
119
|
-
badgeText:
|
|
120
|
-
badgeCount:
|
|
121
|
-
badgeShowZero:
|
|
122
|
-
badgeOverflowCount:
|
|
123
|
-
badgeColor:
|
|
120
|
+
badgeEnabled: reader.boolean("badgeEnabled"),
|
|
121
|
+
badgeText: reader.string("badgeText"),
|
|
122
|
+
badgeCount: reader.number("badgeCount"),
|
|
123
|
+
badgeShowZero: reader.boolean("badgeShowZero"),
|
|
124
|
+
badgeOverflowCount: reader.number("badgeOverflowCount"),
|
|
125
|
+
badgeColor: reader.string("badgeColor"),
|
|
124
126
|
};
|
|
125
127
|
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { PhiMediaImageSourceConfig } from "../../../types/media";
|
|
2
|
+
/** Where an image comes from: an Asset of the Media library, or a URL. Strict: an unknown kind is an error. */
|
|
2
3
|
export declare function readPhiMediaImageSourceConfig(value: Record<string, unknown>): PhiMediaImageSourceConfig;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { normalizePhiImageAssetVariantKey } from "../../../constants/media";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
return readString(value) === "asset" ? "asset" : "url";
|
|
5
|
-
}
|
|
2
|
+
import { createPhiConfigReader } from "./strict-config-reader";
|
|
3
|
+
/** Where an image comes from: an Asset of the Media library, or a URL. Strict: an unknown kind is an error. */
|
|
6
4
|
export function readPhiMediaImageSourceConfig(value) {
|
|
7
|
-
|
|
5
|
+
const reader = createPhiConfigReader(value);
|
|
6
|
+
if ((reader.oneOf("sourceKind", ["url", "asset"]) ?? "url") === "asset") {
|
|
8
7
|
return {
|
|
9
8
|
sourceKind: "asset",
|
|
10
|
-
assetId:
|
|
9
|
+
assetId: reader.number("assetId"),
|
|
11
10
|
variantKey: normalizePhiImageAssetVariantKey(value.variantKey),
|
|
12
|
-
variantVersion:
|
|
11
|
+
variantVersion: reader.number("variantVersion"),
|
|
13
12
|
};
|
|
14
13
|
}
|
|
15
14
|
return {
|
|
16
15
|
sourceKind: "url",
|
|
17
|
-
sourceUrl:
|
|
16
|
+
sourceUrl: reader.string("sourceUrl"),
|
|
18
17
|
};
|
|
19
18
|
}
|
|
@@ -24,7 +24,12 @@ export declare const PHI_MASK_PRESET_OPTIONS: ReadonlyArray<{
|
|
|
24
24
|
label: string;
|
|
25
25
|
}>;
|
|
26
26
|
export declare function resolvePhiMaskStyle(mask: PhiMaskConfig | null | undefined): CSSProperties | undefined;
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* A stored mask, read strictly (`strict-config-reader.ts`) before it is normalized: a field that is
|
|
29
|
+
* there and of the wrong kind is an error naming it. The normalization below stays lenient for the
|
|
30
|
+
* editor, which normalizes drafts while an author is still choosing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function readPhiMaskConfig(value: unknown, path?: string): PhiMaskConfig | undefined;
|
|
28
33
|
export declare function mergePhiMaskConfigDefaults(mask: PhiMaskConfig | null | undefined): PhiMaskConfig;
|
|
29
34
|
/** A picker's change on top of the current mask: the defaults filled, the patch applied, the mask enabled. */
|
|
30
35
|
export declare function mergePhiMaskConfigPatch(mask: PhiMaskConfig | null | undefined, patch: PhiMaskConfig): PhiMaskConfig;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isPhiRecord } from "../../../helpers/is-record";
|
|
2
2
|
import { readBoolean, readCssSize, readNumber, readString } from "./parser-primitives";
|
|
3
|
+
import { createPhiConfigReader } from "./strict-config-reader";
|
|
3
4
|
/** The preset shapes and their names, in the order a picker lists them. */
|
|
4
5
|
const PHI_MASK_PRESET_ENTRIES = [
|
|
5
6
|
["circle", "Circle"],
|
|
@@ -129,7 +130,29 @@ function readMaskRotation(value) {
|
|
|
129
130
|
}
|
|
130
131
|
return Math.min(180, Math.max(-180, rotation));
|
|
131
132
|
}
|
|
132
|
-
|
|
133
|
+
/**
|
|
134
|
+
* A stored mask, read strictly (`strict-config-reader.ts`) before it is normalized: a field that is
|
|
135
|
+
* there and of the wrong kind is an error naming it. The normalization below stays lenient for the
|
|
136
|
+
* editor, which normalizes drafts while an author is still choosing.
|
|
137
|
+
*/
|
|
138
|
+
export function readPhiMaskConfig(value, path = "mask") {
|
|
139
|
+
createPhiConfigReader({ [path]: value }).object(path, (reader) => {
|
|
140
|
+
reader.boolean("enabled");
|
|
141
|
+
reader.oneOf("source", ["asset", "preset"]);
|
|
142
|
+
reader.oneOf("preset", [...PHI_MASK_PRESETS]);
|
|
143
|
+
reader.number("assetId");
|
|
144
|
+
reader.string("assetUrl");
|
|
145
|
+
reader.number("scale");
|
|
146
|
+
reader.number("offsetX");
|
|
147
|
+
reader.number("offsetY");
|
|
148
|
+
reader.number("rotationDeg");
|
|
149
|
+
reader.value("position", "a CSS position", (position) => typeof position === "string" || (typeof position === "number" && Number.isFinite(position)) ? position : undefined);
|
|
150
|
+
reader.oneOf("repeat", ["repeat", "no-repeat"]);
|
|
151
|
+
reader.oneOf("mode", ["luminance", "alpha"]);
|
|
152
|
+
});
|
|
153
|
+
return normalizePhiMaskConfig(value);
|
|
154
|
+
}
|
|
155
|
+
function normalizePhiMaskConfig(value) {
|
|
133
156
|
if (!isPhiRecord(value)) {
|
|
134
157
|
return undefined;
|
|
135
158
|
}
|