@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
|
@@ -4,6 +4,8 @@ import { useState } from "react";
|
|
|
4
4
|
import { PhiButtonControl } from "../../controls/phi-button-control";
|
|
5
5
|
import { PhiFlexControl } from "../../controls/phi-flex-control";
|
|
6
6
|
import { PhiImageControl } from "../../controls/phi-image-control";
|
|
7
|
+
import { PhiRibbonControl } from "../../controls/phi-ribbon-control";
|
|
8
|
+
import { PhiRibbonWrapControl } from "../../controls/phi-ribbon-wrap-control";
|
|
7
9
|
import { PhiSkeletonControl } from "../../controls/phi-skeleton-control";
|
|
8
10
|
import { PhiStatisticControl } from "../../controls/phi-statistic-control";
|
|
9
11
|
import { PhiTypographyControl } from "../../controls/phi-typography-control";
|
|
@@ -14,8 +16,10 @@ import { PhiSurfaceGroundLayer } from "../../surface/phi-surface-ground";
|
|
|
14
16
|
import { PhiSurfaceTone } from "../../surface/phi-surface-tone";
|
|
15
17
|
import { resolvePhiSurfaceStyle } from "../../../helpers/surface-style";
|
|
16
18
|
import { usePhiControlSignalController } from "../client/shared/phi-control-signals";
|
|
17
|
-
import { PHI_SPACE } from "../../../theme/antd-css-var-contract";
|
|
18
|
-
|
|
19
|
+
import { PHI_COLOR, PHI_SPACE } from "../../../theme/antd-css-var-contract";
|
|
20
|
+
import { PHI_THEME_HEADING_FONT_VARIABLE } from "../../../theme/phi-theme-typography";
|
|
21
|
+
import { PHI_CARD_TEXT_SLOTS, readPhiCardBillingPeriod } from "./card-vocabulary";
|
|
22
|
+
const PHI_CARD_SIGNAL_TEXT_SLOTS = new Set(PHI_CARD_TEXT_SLOTS);
|
|
19
23
|
/*
|
|
20
24
|
* What each variant sets, in one row per variant. A further variant -- a featured card -- is a row here
|
|
21
25
|
* and an entry in `PHI_CARD_VARIANTS`.
|
|
@@ -71,13 +75,19 @@ const PHI_CARD_HIDDEN_TEXT = {
|
|
|
71
75
|
whiteSpace: "nowrap",
|
|
72
76
|
border: 0,
|
|
73
77
|
};
|
|
74
|
-
const PHI_CARD_THEME_CORNER = "var(--phi-surface-radius
|
|
78
|
+
const PHI_CARD_THEME_CORNER = "var(--phi-surface-radius)";
|
|
75
79
|
/** The box a picture is shown in takes the picture's own proportion; 3:2 where nothing is known. */
|
|
76
80
|
function resolveMediaAspectRatio(presentation) {
|
|
77
81
|
return presentation.width && presentation.height
|
|
78
82
|
? `${presentation.width} / ${presentation.height}`
|
|
79
83
|
: "3 / 2";
|
|
80
84
|
}
|
|
85
|
+
/*
|
|
86
|
+
* Every colour the card paints is the Theme's variable (`PHI_COLOR`), never a token's resolved value: a
|
|
87
|
+
* Surface with a `tone` writes the other mode's variables on the card's box, and only a variable reaches
|
|
88
|
+
* the words inside it. Resolved values were the page's mode written in by hand, and dark words stayed
|
|
89
|
+
* dark on a photograph darkened for light ones.
|
|
90
|
+
*/
|
|
81
91
|
export function PhiCardWidgetClient({ labels: placedLabels, config, binding, listContent, renderText, }) {
|
|
82
92
|
const { token } = usePhiConfig();
|
|
83
93
|
const [overrides, setOverrides] = useState({});
|
|
@@ -94,6 +104,11 @@ export function PhiCardWidgetClient({ labels: placedLabels, config, binding, lis
|
|
|
94
104
|
else if (capabilityId === "loading" || capabilityId === "highlight") {
|
|
95
105
|
setOverrides((current) => ({ ...current, [capabilityId]: signal.value === true }));
|
|
96
106
|
}
|
|
107
|
+
else if (capabilityId === "billingPeriod") {
|
|
108
|
+
const billingPeriod = readPhiCardBillingPeriod(signal.value);
|
|
109
|
+
if (billingPeriod)
|
|
110
|
+
setOverrides((current) => ({ ...current, billingPeriod }));
|
|
111
|
+
}
|
|
97
112
|
return true;
|
|
98
113
|
},
|
|
99
114
|
});
|
|
@@ -157,15 +172,30 @@ export function PhiCardWidgetClient({ labels: placedLabels, config, binding, lis
|
|
|
157
172
|
const title = textOf("title");
|
|
158
173
|
const description = textOf("description");
|
|
159
174
|
const meta = textOf("meta");
|
|
175
|
+
const badge = textOf("badge");
|
|
160
176
|
const eyebrowType = { fontSize: token.fontSizeSM, letterSpacing: "0.04em", textTransform: "uppercase" };
|
|
161
177
|
/* On the picture's corner where the variant puts it there and there is a picture to put it on. */
|
|
162
178
|
const eyebrowOnMedia = metrics.eyebrowOnMedia === true && image != null;
|
|
163
|
-
const heading = title != null ? (_jsx(PhiTypographyControl, { presentation: "title", level: Number(headingLevel.slice(1)), style: { margin: 0, ...headingType[headingLevel], color:
|
|
179
|
+
const heading = title != null ? (_jsx(PhiTypographyControl, { presentation: "title", level: Number(headingLevel.slice(1)), style: { margin: 0, ...headingType[headingLevel], color: PHI_COLOR.textHeading, ...slotWidth }, children: title })) : null;
|
|
164
180
|
/*
|
|
165
181
|
* The icon's colours as custom properties, which `.phi-card__icon` paints (`styles/layout.css`): the
|
|
166
182
|
* `icon` hover effect turns them round, and a colour stated inline could not be turned by a rule.
|
|
167
183
|
*/
|
|
168
|
-
const iconColours = (color, background) => ({
|
|
184
|
+
const iconColours = (color, background) => ({
|
|
185
|
+
"--phi-card-icon-color": color,
|
|
186
|
+
"--phi-card-icon-background": background,
|
|
187
|
+
/* The mark's colour once the `icon` effect turns them round: a ground it can be read on. */
|
|
188
|
+
"--phi-card-icon-hover-color": config?.iconBackground ?? PHI_COLOR.bgContainer,
|
|
189
|
+
});
|
|
190
|
+
/*
|
|
191
|
+
* The corner of the icon's ground: the Theme's Control shape at the large size, scaled from a large
|
|
192
|
+
* Control's height to the ground's side. So `square` draws a square, `pill` a circle -- half the large
|
|
193
|
+
* height scaled to the side is half the side -- and the steps between keep their proportion, as a
|
|
194
|
+
* Segmented's items follow their track. The Theme's plain corner did not: a pill Site drew square marks.
|
|
195
|
+
*/
|
|
196
|
+
const iconCorner = (side) => `calc(var(--phi-control-radius-lg, ${token.borderRadiusLG}px) * ${side / token.controlHeightLG})`;
|
|
197
|
+
/* The framed box an icon before the title stands in. */
|
|
198
|
+
const inlineIconFrame = iconSize + 16;
|
|
169
199
|
const iconMark = (size, framed) => iconName ? (_jsx("span", { "aria-hidden": "true", className: "phi-card__icon", style: {
|
|
170
200
|
display: "inline-flex",
|
|
171
201
|
flex: "none",
|
|
@@ -173,22 +203,62 @@ export function PhiCardWidgetClient({ labels: placedLabels, config, binding, lis
|
|
|
173
203
|
justifyContent: "center",
|
|
174
204
|
width: framed,
|
|
175
205
|
height: framed,
|
|
176
|
-
borderRadius:
|
|
177
|
-
...iconColours(config?.iconColor ?? (highlight ?
|
|
206
|
+
borderRadius: iconCorner(framed),
|
|
207
|
+
...iconColours(config?.iconColor ?? (highlight ? PHI_COLOR.primary : PHI_COLOR.textSecondary), config?.iconBackground ?? PHI_COLOR.fillQuaternary),
|
|
178
208
|
}, children: _jsx(PhiIcon, { name: iconName, size: size }) })) : null;
|
|
179
209
|
/*
|
|
180
210
|
* A failure stands where the figure would, at body size, because a sentence in figure type is
|
|
181
211
|
* unreadable. A card whose figure is the only thing it has makes the figure the link.
|
|
182
212
|
*/
|
|
183
213
|
const valueText = renderText ? renderText("value", labels.value) : null;
|
|
184
|
-
|
|
214
|
+
/*
|
|
215
|
+
* Beside an icon before the title, the figure starts where the title's words do, under them rather
|
|
216
|
+
* than under the icon: the number belongs to the heading, the icon only marks it. On a line set to its
|
|
217
|
+
* start only -- centred or at the end, the figure already stands with the words.
|
|
218
|
+
*/
|
|
219
|
+
const figureIndent = iconPlacement === "inline" && iconName && (textAlign === "start" || textAlign === "justify")
|
|
220
|
+
? { paddingInlineStart: inlineIconFrame + gap }
|
|
221
|
+
: {};
|
|
222
|
+
/*
|
|
223
|
+
* The figure is set like the title it belongs to: in the font the Theme gives headings, and with digits
|
|
224
|
+
* of one width, so a figure that changes does not shift as it counts. No fallback in the `var()`, as for
|
|
225
|
+
* the headings themselves (`styles/layout.css`): a Theme that keeps headings on the body font sets no
|
|
226
|
+
* variable, and the figure inherits the body font.
|
|
227
|
+
*/
|
|
228
|
+
const figureType = {
|
|
229
|
+
fontFamily: `var(${PHI_THEME_HEADING_FONT_VARIABLE})`,
|
|
230
|
+
fontVariantNumeric: "tabular-nums",
|
|
231
|
+
};
|
|
232
|
+
const figure = valueText != null ? (_jsx("div", { style: {
|
|
233
|
+
...figureType,
|
|
234
|
+
fontSize: token.fontSizeHeading3,
|
|
235
|
+
color: highlight ? PHI_COLOR.primary : PHI_COLOR.textHeading,
|
|
236
|
+
...slotWidth,
|
|
237
|
+
...figureIndent,
|
|
238
|
+
}, children: valueText })) : (_jsx(PhiStatisticControl, { value: binding?.error ?? labels.value ?? "", loading: binding?.loading === true || overrides.loading === true, style: figureIndent, styles: {
|
|
185
239
|
content: binding?.error
|
|
186
|
-
? { color:
|
|
187
|
-
: { color: highlight ?
|
|
240
|
+
? { color: PHI_COLOR.error, fontSize: token.fontSize }
|
|
241
|
+
: { ...figureType, color: highlight ? PHI_COLOR.primary : PHI_COLOR.textHeading },
|
|
188
242
|
} }));
|
|
189
243
|
/* A failure stands where the lines would, as it does for a figure; a list still coming is three lines. */
|
|
190
|
-
const list = binding?.error ? (_jsx(PhiTypographyControl, { style: { color:
|
|
191
|
-
|
|
244
|
+
const list = binding?.error ? (_jsx(PhiTypographyControl, { style: { color: PHI_COLOR.error, ...slotWidth }, children: binding.error })) : binding?.loading === true || overrides.loading === true ? (_jsx(PhiSkeletonControl, { lines: 3 })) : listContent ?? null;
|
|
245
|
+
/*
|
|
246
|
+
* A plan's price: the period's own where it states one, the monthly one where it does not, so a switch
|
|
247
|
+
* to yearly never leaves a card without a price. An editor is asked for the shown period's fields.
|
|
248
|
+
*/
|
|
249
|
+
const yearly = (overrides.billingPeriod ?? config?.billingPeriod) === "yearly";
|
|
250
|
+
const showsYearly = yearly && (renderText != null || Boolean(labels.priceYearly));
|
|
251
|
+
const priceText = body === "plan" ? textOf(showsYearly ? "priceYearly" : "price") : null;
|
|
252
|
+
const periodText = body === "plan" ? textOf(showsYearly ? "pricePeriodYearly" : "pricePeriod") : null;
|
|
253
|
+
const plan = body === "plan" ? (_jsxs("div", { style: { display: "grid", gap, justifySelf: "stretch", justifyItems, minWidth: 0 }, children: [priceText != null || periodText != null ? (_jsxs("div", { style: { display: "flex", flexWrap: "wrap", alignItems: "baseline", justifyContent: justify, columnGap: PHI_SPACE.xs, ...slotWidth }, children: [priceText != null ? (_jsx("span", { className: "phi-card__price", style: {
|
|
254
|
+
fontSize: token.fontSizeHeading2,
|
|
255
|
+
lineHeight: token.lineHeightHeading2,
|
|
256
|
+
fontWeight: 600,
|
|
257
|
+
fontVariantNumeric: "tabular-nums",
|
|
258
|
+
color: highlight ? PHI_COLOR.primary : PHI_COLOR.textHeading,
|
|
259
|
+
...slotWidth,
|
|
260
|
+
}, children: priceText })) : null, periodText != null ? (_jsx("span", { style: { color: PHI_COLOR.textSecondary, ...slotWidth }, children: periodText })) : null] })) : null, list != null ? _jsx("div", { style: { justifySelf: "stretch", minWidth: 0, textAlign: "start" }, children: list }) : null] })) : null;
|
|
261
|
+
const headingRow = iconPlacement === "inline" && iconName ? (_jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: justify, gap, ...slotWidth }, children: [iconMark(iconSize, inlineIconFrame), heading] })) : heading;
|
|
192
262
|
const media = image ? (_jsxs("div", { className: "phi-card__media", style: {
|
|
193
263
|
position: "relative",
|
|
194
264
|
aspectRatio: metrics.mediaAspectRatio ?? resolveMediaAspectRatio(image.presentation),
|
|
@@ -208,9 +278,9 @@ export function PhiCardWidgetClient({ labels: placedLabels, config, binding, lis
|
|
|
208
278
|
justifyContent: "center",
|
|
209
279
|
width: topIconSize + 24,
|
|
210
280
|
height: topIconSize + 24,
|
|
211
|
-
borderRadius:
|
|
281
|
+
borderRadius: iconCorner(topIconSize + 24),
|
|
212
282
|
// A ground of its own, so the mark reads on a bright picture and on a dark one alike.
|
|
213
|
-
...iconColours(config?.iconColor ?? (highlight ?
|
|
283
|
+
...iconColours(config?.iconColor ?? (highlight ? PHI_COLOR.primary : PHI_COLOR.text), config?.iconBackground ?? `color-mix(in srgb, ${PHI_COLOR.bgContainer} 88%, transparent)`),
|
|
214
284
|
boxShadow: token.boxShadowTertiary,
|
|
215
285
|
}, children: _jsx(PhiIcon, { name: iconName, size: topIconSize }) })) : null, eyebrowOnMedia && eyebrow != null ? (_jsx(PhiTypographyControl, { type: "secondary", style: {
|
|
216
286
|
...eyebrowType,
|
|
@@ -222,8 +292,8 @@ export function PhiCardWidgetClient({ labels: placedLabels, config, binding, lis
|
|
|
222
292
|
paddingInline: token.paddingXS,
|
|
223
293
|
borderRadius: token.borderRadiusSM,
|
|
224
294
|
// A ground of its own, as the icon has, so the words read on any picture.
|
|
225
|
-
background: `color-mix(in srgb, ${
|
|
226
|
-
color: highlight ?
|
|
295
|
+
background: `color-mix(in srgb, ${PHI_COLOR.bgContainer} 88%, transparent)`,
|
|
296
|
+
color: highlight ? PHI_COLOR.primary : PHI_COLOR.text,
|
|
227
297
|
}, children: eyebrow })) : null] })) : null;
|
|
228
298
|
const boxStyle = {
|
|
229
299
|
...(config?.surface ? {} : { borderRadius: PHI_CARD_THEME_CORNER }),
|
|
@@ -235,21 +305,51 @@ export function PhiCardWidgetClient({ labels: placedLabels, config, binding, lis
|
|
|
235
305
|
minWidth: 0,
|
|
236
306
|
overflow: "hidden",
|
|
237
307
|
textAlign,
|
|
238
|
-
color:
|
|
308
|
+
color: PHI_COLOR.text,
|
|
239
309
|
/* The ring's colour; `.phi-card--highlight` draws it (`styles/layout.css`). */
|
|
240
|
-
...(highlight ? { "--phi-card-highlight-color":
|
|
310
|
+
...(highlight ? { "--phi-card-highlight-color": PHI_COLOR.primary } : {}),
|
|
241
311
|
};
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
312
|
+
/*
|
|
313
|
+
* A plan's button stands at the card's foot: plans side by side in a row have lists of different
|
|
314
|
+
* lengths, and their buttons belong on one line. The words keep their grid; the grid and the button
|
|
315
|
+
* stand in a column that fills the card, and the button takes what is left above it.
|
|
316
|
+
*/
|
|
317
|
+
const footAction = body === "plan" && action != null;
|
|
318
|
+
const actionButton = action ? (_jsx("div", { className: "phi-card__action",
|
|
319
|
+
/* At the foot, it stands where the words' alignment puts it, as it does among them. */
|
|
320
|
+
style: footAction ? { marginTop: "auto", alignSelf: textAlign === "center" ? "center" : textAlign === "end" ? "flex-end" : "flex-start" } : undefined, children: _jsx(PhiButtonControl, { type: highlight ? "primary" : "default", size: buttonSize, ...(action.href ? { href: action.href, newTab: action.newTab, external: action.external } : {}), label: labels.actionLabel || undefined, ...(labels.actionLabel ? {} : { ariaLabel: action.ariaLabel }), ...(action.icon ? { icon: _jsx(PhiIcon, { name: action.icon, size: "1em" }) } : {}), ...(activates ? { onClick: () => controlSignals.emitCapability("activate", null) } : {}) }) })) : null;
|
|
321
|
+
/*
|
|
322
|
+
* The band in the card's top end corner, floating (`PhiRibbonControl`): the words below it start where
|
|
323
|
+
* they start in a card without one, so plans side by side keep their headings on one line.
|
|
324
|
+
*/
|
|
325
|
+
const badgeStyle = config?.badgeStyle ?? "none";
|
|
326
|
+
const ribbon = badge != null && (badgeStyle === "corner" || badgeStyle === "tag") ? (_jsx(PhiRibbonControl, { color: config?.badgeColor, placement: badgeStyle === "tag" ? "edge" : "corner", ...(!renderText && labels.badge
|
|
327
|
+
? {
|
|
328
|
+
fullText: labels.badge,
|
|
329
|
+
...(href
|
|
330
|
+
? {
|
|
331
|
+
onClick: (event) => event.currentTarget.closest(".phi-card")?.querySelector(".phi-card__link")?.click(),
|
|
332
|
+
}
|
|
333
|
+
: {}),
|
|
334
|
+
}
|
|
335
|
+
: {}), ...(renderText ? { style: { pointerEvents: "auto", minWidth: "6em" } } : {}), children: badge })) : null;
|
|
336
|
+
const words = (_jsxs("div", { style: { display: "grid", gap, padding: footAction ? 0 : inset, justifyItems }, children: [iconAtTop && iconName && !image ? (_jsx("div", { style: { justifySelf: markSide === "center" ? "center" : markSide === "end" ? "end" : "start" }, children: iconMark(topIconSize, topIconSize + 24) })) : null, eyebrow != null && !eyebrowOnMedia && !labels.eyebrowEnd ? (_jsx(PhiTypographyControl, { type: "secondary", style: { ...eyebrowType, color: highlight ? PHI_COLOR.primary : PHI_COLOR.textTertiary, ...slotWidth }, children: eyebrow })) : null, labels.eyebrowEnd && !eyebrowOnMedia ? (_jsxs(PhiFlexControl, { justify: "space-between", align: "baseline", wrap: true, gap: PHI_SPACE.xs, style: { justifySelf: "stretch", minWidth: 0 }, children: [_jsx(PhiTypographyControl, { type: "secondary", style: { ...eyebrowType, color: highlight ? PHI_COLOR.primary : PHI_COLOR.textTertiary }, children: eyebrow ?? "" }), _jsx(PhiTypographyControl, { type: "secondary", style: { ...eyebrowType, color: PHI_COLOR.textTertiary }, children: labels.eyebrowEnd })] })) : null, headingRow, body === "stat" ? figure : null, body === "series" ? (_jsxs(_Fragment, { children: [labels.value || binding?.error || binding?.loading === true || overrides.loading === true ? figure : null, list != null && !binding?.error && binding?.loading !== true && overrides.loading !== true ? (_jsx("div", { style: { justifySelf: "stretch", minWidth: 0 }, children: list })) : null] })) : null, body === "list" && list != null ? (_jsx("div", { style: { justifySelf: "stretch", minWidth: 0 }, children: list })) : null, description != null ? (_jsx(PhiTypographyControl, { presentation: "paragraph", style: {
|
|
337
|
+
marginBottom: 0,
|
|
338
|
+
color: PHI_COLOR.textSecondary,
|
|
339
|
+
fontSize: descriptionSize,
|
|
340
|
+
...slotWidth,
|
|
341
|
+
}, children: description })) : null, plan, meta != null ? (_jsx(PhiTypographyControl, { type: "secondary", style: { fontSize: token.fontSizeSM, color: PHI_COLOR.textTertiary, ...slotWidth }, children: meta })) : null, footAction ? null : actionButton] }));
|
|
342
|
+
const content = (_jsxs(_Fragment, { children: [media, footAction ? (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap, padding: inset, flex: "1 1 auto", minWidth: 0 }, children: [words, actionButton] })) : words, cardLink] }));
|
|
343
|
+
const card = (_jsxs("article", { className: [
|
|
249
344
|
"phi-card",
|
|
250
345
|
href ? "phi-card--link" : null,
|
|
251
346
|
highlight ? "phi-card--highlight" : null,
|
|
252
347
|
hoverEffect !== "none" ? `phi-card--hover-${hoverEffect}` : null,
|
|
253
348
|
surface.className,
|
|
254
|
-
].filter(Boolean).join(" "), "data-phi-card-variant": variant, style: boxStyle, children: [_jsx(PhiSurfaceGroundLayer, { ground: surface.ground, className: "phi-card__ground" }), surface.className ? _jsx(PhiSurfaceTone, { tone: config?.surface?.tone, children: content }) : content] }));
|
|
349
|
+
].filter(Boolean).join(" "), "data-phi-card-variant": variant, style: boxStyle, children: [_jsx(PhiSurfaceGroundLayer, { ground: surface.ground, className: "phi-card__ground" }), ribbon, surface.className ? _jsx(PhiSurfaceTone, { tone: config?.surface?.tone, children: content }) : content] }));
|
|
350
|
+
/*
|
|
351
|
+
* A ribbon hangs over the card's edge, which the card -- clipping for its picture and its zoom -- cannot
|
|
352
|
+
* give a child of its own; it wraps the card instead (`PhiRibbonWrapControl`). An editor writes in it.
|
|
353
|
+
*/
|
|
354
|
+
return badge != null && badgeStyle === "ribbon" ? (_jsx(PhiRibbonWrapControl, { text: badge, ...(config?.badgeColor ? { color: config.badgeColor } : {}), interactive: renderText != null, className: hoverEffect === "lift" ? "phi-card-ribbon phi-card-ribbon--lift" : "phi-card-ribbon", children: card })) : card;
|
|
255
355
|
}
|
|
@@ -4,12 +4,26 @@
|
|
|
4
4
|
* `text` is a heading. `stat` is a labelled figure: the label is the heading, so a card that counts
|
|
5
5
|
* something says what it counted in the same place and type a text card says what it is about, and the
|
|
6
6
|
* figure is drawn by the house's one statistic Control. `list` is a heading over a few lines the caller
|
|
7
|
-
* draws and hands in (`listContent`), which only a Dashboard does today.
|
|
7
|
+
* draws and hands in (`listContent`), which only a Dashboard does today. `series` is a figure over time:
|
|
8
|
+
* the headline as a `stat` draws it, over a chart the caller draws and hands in the same way -- a Dashboard
|
|
9
|
+
* again, so the chart Control never loads with a Card on a Public page. `plan` is an offer: a price
|
|
10
|
+
* and what it is paid per, a monthly and a yearly one of each, over a list of what the plan includes and
|
|
11
|
+
* what it does not (`PhiBulletListEntry.state`). Several plan cards side by side are a Layout's row, and
|
|
12
|
+
* the recommended one is the card that is `highlight`ed.
|
|
8
13
|
*
|
|
9
14
|
* The body is chosen, never inferred from whether a value happens to have arrived. A card that decided
|
|
10
15
|
* by presence would draw as text and reflow into a statistic the moment its figure landed.
|
|
11
16
|
*/
|
|
12
|
-
export type PhiCardWidgetBody = "text" | "stat" | "list";
|
|
17
|
+
export type PhiCardWidgetBody = "text" | "stat" | "list" | "series" | "plan";
|
|
18
|
+
/**
|
|
19
|
+
* Which of a plan card's two prices it shows. A plan states one, the other, or both; one that states
|
|
20
|
+
* only the monthly price shows it under `yearly` as well, so a period switch on the page never leaves a
|
|
21
|
+
* card without a price. The page switches every plan at once by sending `billingPeriod`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PHI_CARD_BILLING_PERIODS: readonly ["monthly", "yearly"];
|
|
24
|
+
export type PhiCardBillingPeriod = (typeof PHI_CARD_BILLING_PERIODS)[number];
|
|
25
|
+
/** A sent period as one of the two; anything else is not a period and changes nothing. */
|
|
26
|
+
export declare function readPhiCardBillingPeriod(value: unknown): PhiCardBillingPeriod | undefined;
|
|
13
27
|
/**
|
|
14
28
|
* The tag of the card's heading, and the step it is drawn at.
|
|
15
29
|
*
|
|
@@ -24,6 +38,14 @@ export type PhiCardHeadingLevel = (typeof PHI_CARD_HEADING_LEVELS)[number];
|
|
|
24
38
|
/** Logical, so `start` is the left in a left-to-right page and the right in a right-to-left one. */
|
|
25
39
|
export declare const PHI_CARD_TEXT_ALIGNS: readonly ["start", "center", "end", "justify"];
|
|
26
40
|
export type PhiCardTextAlign = (typeof PHI_CARD_TEXT_ALIGNS)[number];
|
|
41
|
+
/**
|
|
42
|
+
* How a card's badge is drawn. `corner` is a band flush in the top end corner, `tag` a rounded mark a
|
|
43
|
+
* little down the end edge -- both inside the card. `ribbon` hangs over the end edge with a fold behind
|
|
44
|
+
* it, and needs room beside the card. `none` draws nothing and keeps the words, to hide a badge for a
|
|
45
|
+
* while. Absent is `none`: a card has a badge once a style is chosen for it.
|
|
46
|
+
*/
|
|
47
|
+
export declare const PHI_CARD_BADGE_STYLES: readonly ["none", "corner", "tag", "ribbon"];
|
|
48
|
+
export type PhiCardBadgeStyle = (typeof PHI_CARD_BADGE_STYLES)[number];
|
|
27
49
|
/**
|
|
28
50
|
* Where the icon stands: before the heading, small, or at the top, large -- at the start, the middle or
|
|
29
51
|
* the end of the line, over the picture when the card has one, on a ground of its own so it reads on any
|
|
@@ -48,6 +70,11 @@ export type PhiCardHoverEffect = (typeof PHI_CARD_HOVER_EFFECTS)[number];
|
|
|
48
70
|
*/
|
|
49
71
|
export declare const PHI_CARD_VARIANTS: readonly ["default", "compact", "center"];
|
|
50
72
|
export type PhiCardVariant = (typeof PHI_CARD_VARIANTS)[number];
|
|
51
|
-
/**
|
|
52
|
-
|
|
73
|
+
/**
|
|
74
|
+
* The words a card shows, each in its own place; what an editor can put a field in, and what a signal can
|
|
75
|
+
* write. `badge` is the band at the card's end edge, any body may carry one. The prices are figures like
|
|
76
|
+
* `value` and are never translated: a price that differs by country is sent by a Controller or comes
|
|
77
|
+
* from a Provider's row, not from a translator. The periods (`/ month`) are words and are.
|
|
78
|
+
*/
|
|
79
|
+
export declare const PHI_CARD_TEXT_SLOTS: readonly ["eyebrow", "title", "description", "meta", "value", "badge", "price", "pricePeriod", "priceYearly", "pricePeriodYearly"];
|
|
53
80
|
export type PhiCardTextSlot = (typeof PHI_CARD_TEXT_SLOTS)[number];
|
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
* The Card Widget's words, apart from its Client half: the Widget's definition is read on the server, and
|
|
3
3
|
* a value imported from the Client file would make that file a client reference of every route.
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* Which of a plan card's two prices it shows. A plan states one, the other, or both; one that states
|
|
7
|
+
* only the monthly price shows it under `yearly` as well, so a period switch on the page never leaves a
|
|
8
|
+
* card without a price. The page switches every plan at once by sending `billingPeriod`.
|
|
9
|
+
*/
|
|
10
|
+
export const PHI_CARD_BILLING_PERIODS = ["monthly", "yearly"];
|
|
11
|
+
/** A sent period as one of the two; anything else is not a period and changes nothing. */
|
|
12
|
+
export function readPhiCardBillingPeriod(value) {
|
|
13
|
+
return PHI_CARD_BILLING_PERIODS.includes(value) ? value : undefined;
|
|
14
|
+
}
|
|
5
15
|
/**
|
|
6
16
|
* The tag of the card's heading, and the step it is drawn at.
|
|
7
17
|
*
|
|
@@ -14,6 +24,13 @@
|
|
|
14
24
|
export const PHI_CARD_HEADING_LEVELS = ["h2", "h3", "h4"];
|
|
15
25
|
/** Logical, so `start` is the left in a left-to-right page and the right in a right-to-left one. */
|
|
16
26
|
export const PHI_CARD_TEXT_ALIGNS = ["start", "center", "end", "justify"];
|
|
27
|
+
/**
|
|
28
|
+
* How a card's badge is drawn. `corner` is a band flush in the top end corner, `tag` a rounded mark a
|
|
29
|
+
* little down the end edge -- both inside the card. `ribbon` hangs over the end edge with a fold behind
|
|
30
|
+
* it, and needs room beside the card. `none` draws nothing and keeps the words, to hide a badge for a
|
|
31
|
+
* while. Absent is `none`: a card has a badge once a style is chosen for it.
|
|
32
|
+
*/
|
|
33
|
+
export const PHI_CARD_BADGE_STYLES = ["none", "corner", "tag", "ribbon"];
|
|
17
34
|
/**
|
|
18
35
|
* Where the icon stands: before the heading, small, or at the top, large -- at the start, the middle or
|
|
19
36
|
* the end of the line, over the picture when the card has one, on a ground of its own so it reads on any
|
|
@@ -35,5 +52,21 @@ export const PHI_CARD_HOVER_EFFECTS = ["none", "lift", "zoom", "icon"];
|
|
|
35
52
|
* not another branch in every size the card draws. `default` is what a card without one is.
|
|
36
53
|
*/
|
|
37
54
|
export const PHI_CARD_VARIANTS = ["default", "compact", "center"];
|
|
38
|
-
/**
|
|
39
|
-
|
|
55
|
+
/**
|
|
56
|
+
* The words a card shows, each in its own place; what an editor can put a field in, and what a signal can
|
|
57
|
+
* write. `badge` is the band at the card's end edge, any body may carry one. The prices are figures like
|
|
58
|
+
* `value` and are never translated: a price that differs by country is sent by a Controller or comes
|
|
59
|
+
* from a Provider's row, not from a translator. The periods (`/ month`) are words and are.
|
|
60
|
+
*/
|
|
61
|
+
export const PHI_CARD_TEXT_SLOTS = [
|
|
62
|
+
"eyebrow",
|
|
63
|
+
"title",
|
|
64
|
+
"description",
|
|
65
|
+
"meta",
|
|
66
|
+
"value",
|
|
67
|
+
"badge",
|
|
68
|
+
"price",
|
|
69
|
+
"pricePeriod",
|
|
70
|
+
"priceYearly",
|
|
71
|
+
"pricePeriodYearly",
|
|
72
|
+
];
|
|
@@ -68,9 +68,16 @@ function renderInlineNodes(inlines) {
|
|
|
68
68
|
}
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
|
-
function renderBlocks(blocks, token,
|
|
71
|
+
function renderBlocks(blocks, token, paragraphStyle, headingStyle, lists, atStart = false) {
|
|
72
72
|
return blocks.map((block, index) => {
|
|
73
73
|
const key = `${block.kind}-${index}`;
|
|
74
|
+
/*
|
|
75
|
+
* The first block of a text, or of a quote, keeps no space before it: the space before a block
|
|
76
|
+
* parts it from the block above, and there is none -- the Widget's own edge stands there.
|
|
77
|
+
*/
|
|
78
|
+
const leading = atStart && index === 0;
|
|
79
|
+
const paragraphBlockStyle = leading ? { ...paragraphStyle, marginBlockStart: 0 } : paragraphStyle;
|
|
80
|
+
const headingBlockStyle = leading ? { ...headingStyle, paddingBlockStart: 0 } : headingStyle;
|
|
74
81
|
switch (block.kind) {
|
|
75
82
|
case "heading":
|
|
76
83
|
return (_jsx(PhiTypographyControl, { presentation: "title", id: block.id, level: block.level, style: headingBlockStyle, children: renderInlineNodes(block.inlines) }, key));
|
|
@@ -81,19 +88,31 @@ function renderBlocks(blocks, token, paragraphBlockStyle, headingBlockStyle, lis
|
|
|
81
88
|
margin: 0,
|
|
82
89
|
paddingInlineStart: PHI_SPACE.md,
|
|
83
90
|
borderInlineStart: `3px solid ${token.colorBorderSecondary}`,
|
|
84
|
-
}, children: _jsx("div", { style: { display: "grid", gap: 0 }, children: renderBlocks(block.children, token,
|
|
91
|
+
}, children: _jsx("div", { style: { display: "grid", gap: 0 }, children: renderBlocks(block.children, token, paragraphStyle, headingStyle, lists, true) }) }, key));
|
|
85
92
|
case "list":
|
|
86
93
|
/*
|
|
87
94
|
* The house's list, set by the Widget's list settings. A `1.` list counts whatever its level's
|
|
88
95
|
* marker says: the numbers are the text's, not a look. A list inside an entry is one level down.
|
|
89
96
|
*/
|
|
90
|
-
return (_jsx(PhiBulletListControl, { listStyle: lists.style, depth: lists.depth, ordered: block.ordered, start: block.start,
|
|
91
|
-
|
|
97
|
+
return (_jsx(PhiBulletListControl, { listStyle: lists.style, depth: lists.depth, ordered: block.ordered, start: block.start,
|
|
98
|
+
/*
|
|
99
|
+
* The list stands among the text's blocks as a paragraph does: the entries draw close, but the
|
|
100
|
+
* block after the last one keeps the text's spacing. A list inside an entry gets the entry's
|
|
101
|
+
* zeroed spacing, so it sits in its entry's grid.
|
|
102
|
+
*/
|
|
103
|
+
blockSpacing: {
|
|
104
|
+
marginBlockStart: paragraphBlockStyle.marginBlockStart,
|
|
105
|
+
marginBlockEnd: paragraphBlockStyle.marginBlockEnd,
|
|
106
|
+
}, items: block.items.map((itemBlocks) => ({
|
|
107
|
+
content: (_jsx("div", { style: { display: "grid", gap: PHI_SPACE.xs, minWidth: 0 }, children: renderBlocks(itemBlocks, token, { ...paragraphStyle, marginBlockStart: 0, marginBlockEnd: 0 }, headingStyle, { ...lists, depth: lists.depth + 1 }) })),
|
|
92
108
|
})) }, key));
|
|
93
109
|
case "code":
|
|
94
110
|
return (_jsx("pre", { "data-phi-code-language": block.language ?? undefined, style: {
|
|
95
111
|
margin: 0,
|
|
96
|
-
|
|
112
|
+
// A code block stands among the text's blocks as a paragraph does, with the text's spacing.
|
|
113
|
+
marginBlockStart: paragraphBlockStyle.marginBlockStart,
|
|
114
|
+
marginBlockEnd: paragraphBlockStyle.marginBlockEnd,
|
|
115
|
+
padding: PHI_SPACE.base,
|
|
97
116
|
overflowX: "auto",
|
|
98
117
|
borderRadius: token.borderRadiusSM,
|
|
99
118
|
background: token.colorFillQuaternary,
|
|
@@ -157,15 +176,25 @@ export function PhiMarkdownWidgetClient({ config }) {
|
|
|
157
176
|
marginBlockStart: resolvePhiSpacingScaleValue(config?.textBlockSpacingBefore ?? "none"),
|
|
158
177
|
marginBlockEnd: resolvePhiSpacingScaleValue(config?.textBlockSpacingAfter ?? "sm"),
|
|
159
178
|
};
|
|
179
|
+
/*
|
|
180
|
+
* The space before a heading is padding, not margin, so it adds to the space after the block above
|
|
181
|
+
* however the text is laid out: in the grid margins never collapse, in the flow that pictures need
|
|
182
|
+
* they would, and the same setting would part a heading from its paragraph by less there.
|
|
183
|
+
*/
|
|
160
184
|
const headingBlockStyle = {
|
|
161
185
|
margin: 0,
|
|
162
|
-
|
|
186
|
+
paddingBlockStart: resolvePhiSpacingScaleValue(config?.headingBlockSpacingBefore ?? "sm"),
|
|
163
187
|
marginBlockEnd: resolvePhiSpacingScaleValue(config?.headingBlockSpacingAfter ?? "sm"),
|
|
164
188
|
};
|
|
165
|
-
return (_jsx("div", { className: config?.imageFloat
|
|
166
|
-
?
|
|
167
|
-
:
|
|
189
|
+
return (_jsx("div", { className: config?.imageFloat
|
|
190
|
+
? `phi-markdown-text phi-markdown-body phi-markdown-body--float-${config.imageFloat}`
|
|
191
|
+
: "phi-markdown-text",
|
|
192
|
+
// The text's line height for everything in it, lists included: a list entry otherwise takes the
|
|
193
|
+
// browser's `normal`, and its marker centres on a line shorter than the one its words stand on.
|
|
194
|
+
style: config?.imageFloat
|
|
195
|
+
? { display: "flow-root", width: "100%", textAlign: config.textAlign, containerType: "inline-size", lineHeight: token.lineHeight }
|
|
196
|
+
: { display: "grid", gap: 0, width: "100%", textAlign: config?.textAlign, lineHeight: token.lineHeight }, children: renderBlocks(blocks, token, paragraphBlockStyle, headingBlockStyle, {
|
|
168
197
|
style: resolvePhiBulletListStyle(config?.list),
|
|
169
198
|
depth: 1,
|
|
170
|
-
}) }));
|
|
199
|
+
}, true) }));
|
|
171
200
|
}
|
|
@@ -328,21 +328,3 @@ export declare const PHI_MULTI_SELECT_CONTROL_SIGNALS: {
|
|
|
328
328
|
valueType: "none";
|
|
329
329
|
})[];
|
|
330
330
|
};
|
|
331
|
-
export declare const PHI_DRAG_SOURCE_CONTROL_SIGNALS: {
|
|
332
|
-
emits: ({
|
|
333
|
-
id: string;
|
|
334
|
-
action: "start";
|
|
335
|
-
valueType: "json";
|
|
336
|
-
valueSchema: `${string}/signals/${string}`;
|
|
337
|
-
} | {
|
|
338
|
-
id: string;
|
|
339
|
-
action: "change";
|
|
340
|
-
valueType: "json";
|
|
341
|
-
valueSchema: `${string}/signals/${string}`;
|
|
342
|
-
} | {
|
|
343
|
-
id: string;
|
|
344
|
-
action: "stop";
|
|
345
|
-
valueType: "json";
|
|
346
|
-
valueSchema: `${string}/signals/${string}`;
|
|
347
|
-
})[];
|
|
348
|
-
};
|
|
@@ -89,6 +89,16 @@ export const PHI_CARD_SIGNALS = {
|
|
|
89
89
|
{ id: "description", channel: "description", action: "change", valueType: "string" },
|
|
90
90
|
{ id: "meta", channel: "meta", action: "change", valueType: "string" },
|
|
91
91
|
{ id: "highlight", channel: "highlight", action: "change", valueType: "boolean" },
|
|
92
|
+
{ id: "badge", channel: "badge", action: "change", valueType: "string" },
|
|
93
|
+
/*
|
|
94
|
+
* A plan's prices, for a Controller that knows them better than the page does -- by the reader's
|
|
95
|
+
* country, say -- and the period a switch on the page shows (`monthly` or `yearly`).
|
|
96
|
+
*/
|
|
97
|
+
{ id: "price", channel: "price", action: "change", valueType: "string" },
|
|
98
|
+
{ id: "pricePeriod", channel: "pricePeriod", action: "change", valueType: "string" },
|
|
99
|
+
{ id: "priceYearly", channel: "priceYearly", action: "change", valueType: "string" },
|
|
100
|
+
{ id: "pricePeriodYearly", channel: "pricePeriodYearly", action: "change", valueType: "string" },
|
|
101
|
+
{ id: "billingPeriod", channel: "billingPeriod", action: "change", valueType: "string" },
|
|
92
102
|
],
|
|
93
103
|
};
|
|
94
104
|
export const PHI_TEXT_CONTROL_SIGNALS = {
|
|
@@ -227,25 +237,3 @@ export const PHI_MULTI_SELECT_CONTROL_SIGNALS = {
|
|
|
227
237
|
{ ...PHI_CONTROL_CLEAR_SIGNAL, channel: "selection" },
|
|
228
238
|
],
|
|
229
239
|
};
|
|
230
|
-
export const PHI_DRAG_SOURCE_CONTROL_SIGNALS = {
|
|
231
|
-
emits: [
|
|
232
|
-
{
|
|
233
|
-
id: "dragStart",
|
|
234
|
-
action: "start",
|
|
235
|
-
valueType: "json",
|
|
236
|
-
valueSchema: PHI_SIGNAL_VALUE_SCHEMAS.dragDrop,
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
id: "dragChange",
|
|
240
|
-
action: "change",
|
|
241
|
-
valueType: "json",
|
|
242
|
-
valueSchema: PHI_SIGNAL_VALUE_SCHEMAS.dragDrop,
|
|
243
|
-
},
|
|
244
|
-
{
|
|
245
|
-
id: "dragEnd",
|
|
246
|
-
action: "stop",
|
|
247
|
-
valueType: "json",
|
|
248
|
-
valueSchema: PHI_SIGNAL_VALUE_SCHEMAS.dragDrop,
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { PhiWorkspaceCatalogState } from "./catalog-state";
|
|
2
2
|
export type { PhiWorkspaceCatalogArea, PhiWorkspaceCatalogState } from "./catalog-state";
|
|
3
3
|
/**
|
|
4
|
-
* One scope per workspace host. Both the Builder and, later, the Editor write into
|
|
4
|
+
* One scope per workspace host, not one per Area. Both the Builder and, later, the Editor write into it;
|
|
5
|
+
* which Area is open is `area` inside it, and what belongs to an Area is keyed by Area there.
|
|
5
6
|
*/
|
|
6
7
|
export declare const PHI_WORKSPACE_CATALOG_SCOPE = "public";
|
|
7
8
|
export declare const phiWorkspaceCatalogStore: import("../state/plugin-state-store").PhiPluginStateStore<PhiWorkspaceCatalogState>;
|
|
8
|
-
export declare function usePhiWorkspaceCatalogValue<TSelected>(
|
|
9
|
-
export declare function getPhiWorkspaceCatalogSnapshot(
|
|
9
|
+
export declare function usePhiWorkspaceCatalogValue<TSelected>(selector: (state: PhiWorkspaceCatalogState) => TSelected): TSelected;
|
|
10
|
+
export declare function getPhiWorkspaceCatalogSnapshot(): PhiWorkspaceCatalogState;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { createEmptyPhiBuilderModulePresetPagesByArea } from "../../helpers/cms-page-catalog";
|
|
3
3
|
import { createPhiPluginStateStore } from "../state/plugin-state-store";
|
|
4
4
|
/**
|
|
5
|
-
* One scope per workspace host. Both the Builder and, later, the Editor write into
|
|
5
|
+
* One scope per workspace host, not one per Area. Both the Builder and, later, the Editor write into it;
|
|
6
|
+
* which Area is open is `area` inside it, and what belongs to an Area is keyed by Area there.
|
|
6
7
|
*/
|
|
7
8
|
export const PHI_WORKSPACE_CATALOG_SCOPE = "public";
|
|
8
9
|
function createDefaultWorkspaceCatalogState(scopeKey) {
|
|
@@ -25,9 +26,9 @@ function createDefaultWorkspaceCatalogState(scopeKey) {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
export const phiWorkspaceCatalogStore = createPhiPluginStateStore("@phis/ui/workspace-catalog", createDefaultWorkspaceCatalogState);
|
|
28
|
-
export function usePhiWorkspaceCatalogValue(
|
|
29
|
-
return phiWorkspaceCatalogStore.useStoreSelector(
|
|
29
|
+
export function usePhiWorkspaceCatalogValue(selector) {
|
|
30
|
+
return phiWorkspaceCatalogStore.useStoreSelector(PHI_WORKSPACE_CATALOG_SCOPE, selector);
|
|
30
31
|
}
|
|
31
|
-
export function getPhiWorkspaceCatalogSnapshot(
|
|
32
|
-
return phiWorkspaceCatalogStore.getSnapshot(
|
|
32
|
+
export function getPhiWorkspaceCatalogSnapshot() {
|
|
33
|
+
return phiWorkspaceCatalogStore.getSnapshot(PHI_WORKSPACE_CATALOG_SCOPE);
|
|
33
34
|
}
|
|
@@ -79,6 +79,7 @@ async function resolveDashboardCardScope({ bridge, area, locale, path, cookieHea
|
|
|
79
79
|
locale,
|
|
80
80
|
area,
|
|
81
81
|
viewer: requestContext.viewer,
|
|
82
|
+
runtimeModuleCatalog: bridge.runtimeModuleCatalog,
|
|
82
83
|
};
|
|
83
84
|
/*
|
|
84
85
|
* A route handler has no request runtime bound, and the label sets a card reads for its own title
|
|
@@ -11,7 +11,12 @@ export type PhiResolvedInternalReferences = {
|
|
|
11
11
|
pages: readonly PhiResolvedPageReference[];
|
|
12
12
|
assets: ReadonlyMap<number, PhiPublicMediaAssetReference>;
|
|
13
13
|
};
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* One Asset of the public reference projection, as the server writes it; a shape it does not match throws.
|
|
16
|
+
*
|
|
17
|
+
* Every field, not five of them: what passed here went straight into a rendered page under a type that
|
|
18
|
+
* promised a focal rectangle and font metrics nobody had looked at.
|
|
19
|
+
*/
|
|
15
20
|
export declare function readPhiPublicMediaAssetReference(entry: unknown): PhiPublicMediaAssetReference;
|
|
16
21
|
/**
|
|
17
22
|
* Resolves both internal reference kinds, together with whatever else asks in the same turn.
|