@phis/ui 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/components/cms/phi-cms-layout-renderer.js +1 -1
  2. package/components/controls/phi-collection-header-control.js +1 -1
  3. package/components/controls/phi-collection-view-control.js +2 -1
  4. package/components/controls/phi-drawer-control-adapter.d.ts +1 -1
  5. package/components/controls/phi-drawer-control-adapter.js +2 -2
  6. package/components/controls/phi-image-control.d.ts +6 -1
  7. package/components/controls/phi-image-control.js +23 -4
  8. package/components/controls/phi-lightbox-image-control-adapter.d.ts +2 -0
  9. package/components/controls/phi-lightbox-image-control-adapter.js +11 -0
  10. package/components/controls/phi-lightbox-image-control.d.ts +3 -2
  11. package/components/controls/phi-lightbox-image-control.js +7 -3
  12. package/components/controls/phi-modal-control-adapter.d.ts +1 -1
  13. package/components/controls/phi-modal-control-adapter.js +5 -2
  14. package/components/controls/phi-overlay-control-contract.d.ts +5 -0
  15. package/components/controls/phi-pagination-control-adapter.d.ts +2 -0
  16. package/components/controls/phi-pagination-control-adapter.js +15 -0
  17. package/components/controls/phi-pagination-control.d.ts +2 -1
  18. package/components/controls/phi-pagination-control.js +11 -7
  19. package/components/controls/phi-table-control.d.ts +6 -1
  20. package/components/controls/phi-table-control.js +17 -5
  21. package/components/controls/phi-timeline-control-adapter.d.ts +2 -0
  22. package/components/controls/phi-timeline-control-adapter.js +28 -0
  23. package/components/controls/phi-timeline-control.d.ts +3 -1
  24. package/components/controls/phi-timeline-control.js +8 -22
  25. package/components/controls/phi-tour-control.js +25 -7
  26. package/components/controls/phi-tour-viewport.d.ts +36 -0
  27. package/components/controls/phi-tour-viewport.js +86 -0
  28. package/components/controls/phi-zoom-image-overlay.d.ts +17 -0
  29. package/components/controls/phi-zoom-image-overlay.js +58 -0
  30. package/components/layouts/layout-definitions.d.ts +2 -20
  31. package/components/layouts/layout-definitions.js +13 -2
  32. package/components/layouts/plugins/carousel-layout-plugin.js +2 -1
  33. package/components/media/aspect-ratios.d.ts +14 -0
  34. package/components/media/aspect-ratios.js +13 -0
  35. package/components/motion/phi-sequence-run.d.ts +27 -0
  36. package/components/motion/phi-sequence-run.js +87 -0
  37. package/components/motion/phi-sequence-viewport.d.ts +16 -0
  38. package/components/motion/phi-sequence-viewport.js +97 -34
  39. package/components/overlays/phi-overlay-container-client.js +5 -2
  40. package/components/runtime/runtime-visual-anchors.d.ts +13 -2
  41. package/components/runtime/runtime-visual-anchors.js +49 -3
  42. package/components/shell/use-phi-shell-sticky-top.d.ts +5 -0
  43. package/components/shell/use-phi-shell-sticky-top.js +78 -0
  44. package/components/widgets/config/image-variant-options.d.ts +3 -5
  45. package/components/widgets/config/image-variant-options.js +11 -11
  46. package/components/widgets/config/sequence-settings.d.ts +75 -0
  47. package/components/widgets/config/sequence-settings.js +173 -0
  48. package/components/widgets/helpers/semantic-html-translation.d.ts +3 -1
  49. package/components/widgets/helpers/semantic-html-translation.js +8 -3
  50. package/components/widgets/label-sets/content-entries.d.ts +9 -0
  51. package/components/widgets/label-sets/content-entries.js +17 -0
  52. package/components/widgets/label-types/gallery.d.ts +2 -10
  53. package/components/widgets/label-types/sequence.d.ts +18 -0
  54. package/components/widgets/label-types/sequence.js +1 -0
  55. package/components/widgets/navigation-descriptor-resolver.server.js +6 -1
  56. package/components/widgets/shared/markdown-render.js +15 -5
  57. package/helpers/cms-layout-defaults.js +9 -2
  58. package/helpers/cms-region-keys.d.ts +1 -1
  59. package/helpers/motion.d.ts +7 -0
  60. package/helpers/motion.js +7 -0
  61. package/helpers/text-source.d.ts +19 -0
  62. package/helpers/text-source.js +20 -0
  63. package/next/config.mjs +1 -1
  64. package/package.json +1 -1
  65. package/plugins/runtime-modules/asset/data-providers.d.ts +4 -0
  66. package/plugins/runtime-modules/asset/data-providers.js +1 -0
  67. package/plugins/runtime-modules/asset/definition.d.ts +4 -0
  68. package/plugins/runtime-modules/asset/presets.d.ts +53 -1
  69. package/plugins/runtime-modules/asset/presets.js +16 -12
  70. package/plugins/runtime-modules/asset/tour.d.ts +44 -0
  71. package/plugins/runtime-modules/asset/tour.js +53 -0
  72. package/plugins/runtime-modules/auth/trees/phi-default-pub-confirm-page-tree.js +3 -0
  73. package/plugins/runtime-modules/auth/trees/phi-default-pub-login-page-tree.js +2 -0
  74. package/plugins/runtime-modules/auth/trees/phi-default-pub-registration-page-tree.js +3 -0
  75. package/plugins/runtime-modules/auth/trees/phi-default-pub-reset-password-page-tree.js +3 -0
  76. package/plugins/runtime-modules/builder/clients/inspector-config-field.js +42 -18
  77. package/plugins/runtime-modules/builder/clients/inspector-image-field.js +2 -2
  78. package/plugins/runtime-modules/builder/clients/widget-inspector.js +9 -0
  79. package/plugins/runtime-modules/builder/clients/workspace-scope-boundary.js +10 -0
  80. package/plugins/runtime-modules/builder/controller/workspace-controller.js +18 -3
  81. package/plugins/runtime-modules/builder/plugin-meta-labels.js +8 -0
  82. package/plugins/runtime-modules/builder/presets.js +5 -3
  83. package/plugins/runtime-modules/builder/tour.d.ts +316 -0
  84. package/plugins/runtime-modules/builder/tour.js +337 -0
  85. package/plugins/runtime-modules/builder/trees/phi-builder-inspector-area-overlay-tree.server.js +8 -1
  86. package/plugins/runtime-modules/builder/trees/phi-default-builder-area-preset-tree.js +4 -0
  87. package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +3 -2
  88. package/plugins/runtime-modules/core/widgets/card/server.js +4 -2
  89. package/plugins/runtime-modules/core/widgets/collection-view/client.js +10 -0
  90. package/plugins/runtime-modules/core/widgets/description/config.d.ts +28 -1
  91. package/plugins/runtime-modules/core/widgets/description/config.js +2 -0
  92. package/plugins/runtime-modules/core/widgets/description/server.js +10 -12
  93. package/plugins/runtime-modules/core/widgets/entry-detail/config.d.ts +2 -0
  94. package/plugins/runtime-modules/core/widgets/entry-detail/config.js +8 -1
  95. package/plugins/runtime-modules/core/widgets/entry-header/config.d.ts +3 -0
  96. package/plugins/runtime-modules/core/widgets/entry-header/config.js +8 -1
  97. package/plugins/runtime-modules/core/widgets/entry-list/client.d.ts +4 -1
  98. package/plugins/runtime-modules/core/widgets/entry-list/client.js +3 -2
  99. package/plugins/runtime-modules/core/widgets/entry-list/config.d.ts +392 -93
  100. package/plugins/runtime-modules/core/widgets/entry-list/config.js +21 -3
  101. package/plugins/runtime-modules/core/widgets/entry-list/server.js +4 -2
  102. package/plugins/runtime-modules/core/widgets/gallery/authoring.js +62 -10
  103. package/plugins/runtime-modules/core/widgets/gallery/client.d.ts +6 -1
  104. package/plugins/runtime-modules/core/widgets/gallery/client.js +7 -79
  105. package/plugins/runtime-modules/core/widgets/gallery/config.d.ts +337 -144
  106. package/plugins/runtime-modules/core/widgets/gallery/config.js +52 -113
  107. package/plugins/runtime-modules/core/widgets/gallery/defaults.d.ts +15 -0
  108. package/plugins/runtime-modules/core/widgets/gallery/defaults.js +20 -0
  109. package/plugins/runtime-modules/core/widgets/html/server.js +1 -1
  110. package/plugins/runtime-modules/core/widgets/image/client.js +1 -1
  111. package/plugins/runtime-modules/core/widgets/image/config.d.ts +29 -4
  112. package/plugins/runtime-modules/core/widgets/image/config.js +19 -2
  113. package/plugins/runtime-modules/core/widgets/image/editor.js +1 -1
  114. package/plugins/runtime-modules/core/widgets/markdown-toc/server.js +7 -2
  115. package/plugins/runtime-modules/core/widgets/quick-links/config.d.ts +3 -0
  116. package/plugins/runtime-modules/core/widgets/quick-links/config.js +2 -0
  117. package/plugins/runtime-modules/core/widgets/quick-links/plugin.js +4 -2
  118. package/plugins/runtime-modules/core/widgets/quick-links/server.d.ts +5 -1
  119. package/plugins/runtime-modules/core/widgets/quick-links/server.js +4 -2
  120. package/plugins/runtime-modules/core/widgets/result/config.d.ts +25 -1
  121. package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +28 -1
  122. package/plugins/runtime-modules/core/widgets/simple-text/config.js +2 -0
  123. package/plugins/runtime-modules/core/widgets/simple-text/plugin.js +1 -1
  124. package/plugins/runtime-modules/core/widgets/simple-text/server.d.ts +4 -1
  125. package/plugins/runtime-modules/core/widgets/simple-text/server.js +3 -3
  126. package/plugins/runtime-modules/core/widgets/table/client.js +1 -1
  127. package/plugins/runtime-modules/core/widgets/table/config.d.ts +80 -3
  128. package/plugins/runtime-modules/core/widgets/table/config.js +3 -0
  129. package/plugins/runtime-modules/core/widgets/tour-button/client.js +1 -1
  130. package/plugins/runtime-modules/phi-default-site-area-preset-tree.js +12 -4
  131. package/plugins/runtime-modules/public/trees/phi-default-pub-contact-page-tree.js +2 -0
  132. package/plugins/runtime-modules/public/trees/phi-default-pub-unsubscribe-page-tree.js +3 -0
  133. package/plugins/runtime-modules/public/trees/phi-default-pub-welcome-page-tree.js +2 -1
  134. package/plugins/runtime-modules/revisions/presets.d.ts +53 -2
  135. package/plugins/runtime-modules/revisions/presets.js +16 -12
  136. package/plugins/runtime-modules/revisions/tour.d.ts +43 -0
  137. package/plugins/runtime-modules/revisions/tour.js +51 -0
  138. package/plugins/runtime-modules/revisions/trees/phi-default-builder-revisions-page-tree.js +4 -0
  139. package/plugins/runtime-modules/theme/presets.d.ts +36 -4
  140. package/plugins/runtime-modules/theme/tour.d.ts +45 -11
  141. package/plugins/runtime-modules/theme/tour.js +39 -8
  142. package/plugins/runtime-modules/tour/controller/address.js +2 -2
  143. package/plugins/runtime-modules/tour/controller/client.js +43 -2
  144. package/plugins/runtime-modules/tour/controller/definition.js +2 -1
  145. package/server-helpers/cms-request.js +1 -0
  146. package/server-helpers/page-tour.d.ts +10 -3
  147. package/server-helpers/page-tour.js +25 -12
  148. package/server-helpers/translate.d.ts +9 -0
  149. package/server-helpers/translate.js +14 -0
  150. package/styles/controls.css +15 -1
  151. package/styles/root.css +20 -19
  152. package/types/cms-config.d.ts +3 -1
  153. package/types/cms-config.js +3 -3
  154. package/types/cms-plugins.d.ts +31 -4
  155. package/types/core-widget-placements.d.ts +5 -0
  156. package/types/table-widget.d.ts +2 -0
  157. package/types/tour-controller.d.ts +10 -0
  158. package/types/tour-controller.js +13 -0
  159. package/types/tours.d.ts +27 -25
  160. package/types/tours.js +9 -23
  161. package/types/visual-anchors.d.ts +15 -0
  162. package/types/visual-anchors.js +12 -0
  163. package/types.d.ts +2 -0
  164. package/types.js +4 -1
@@ -1,4 +1,5 @@
1
1
  import { resolvePhiCmsWidgetPluginKey } from "../../../../../constants/cms-widget-types";
2
+ import { readPhiTextSource } from "../../../../../helpers/text-source";
2
3
  import { PHI_SIMPLE_TEXT_MARKS } from "../../../../../types/core-widget-placements";
3
4
  import { PhiCmsWidgetType } from "../../../../../constants/cms-widget-types";
4
5
  import { PHI_RENDERABLE_BLOCK_GEOMETRY_FIELDS } from "../../../../../helpers/renderable-block-plugin-fields";
@@ -27,6 +28,7 @@ function parsePhiCmsSimpleTextWidgetConfig(config) {
27
28
  tone: readPhiTextTone(config.tone),
28
29
  marks: readSimpleTextMarks(config.marks),
29
30
  disabled: readBoolean(config.disabled),
31
+ textSource: readPhiTextSource(config.textSource),
30
32
  };
31
33
  }
32
34
  export const PHI_SIMPLE_TEXT_WIDGET_DEFINITION = {
@@ -9,7 +9,7 @@ export const PHI_SIMPLE_TEXT_WIDGET_PLUGIN = {
9
9
  const noTranslate = hasPhiFlag(widget.flags, PhiCmsFlags.NoTranslate);
10
10
  // A record's text is already translated; only the Widget's own still has to be.
11
11
  const hasResolvedText = Boolean(widget.resolvedContent?.textFields.text);
12
- return (_jsx(PhiSimpleTextWidget, { blockId: widget.id, translate: !noTranslate && !hasResolvedText, labels: {
12
+ return (_jsx(PhiSimpleTextWidget, { blockId: widget.id, translate: !noTranslate && !hasResolvedText, textSource: config.textSource, labels: {
13
13
  text: resolvePhiSimpleTextWidgetText({
14
14
  ...config,
15
15
  label: widget.label ?? undefined,
@@ -1,3 +1,4 @@
1
+ import type { PhiTextSource } from "../../../../../helpers/text-source";
1
2
  import type { PhiCmsInstanceId, PhiRenderableBlockBase, PhiServerBlockBaseProps } from "../../../../../types";
2
3
  import type { PhiSimpleTextWidgetClientConfig } from "./client";
3
4
  export type PhiSimpleTextWidgetLabels = {
@@ -6,6 +7,8 @@ export type PhiSimpleTextWidgetLabels = {
6
7
  export type PhiSimpleTextWidgetConfig = PhiSimpleTextWidgetClientConfig & PhiRenderableBlockBase;
7
8
  export type PhiSimpleTextWidgetProps = PhiServerBlockBaseProps<PhiSimpleTextWidgetLabels, PhiSimpleTextWidgetConfig> & {
8
9
  blockId: PhiCmsInstanceId;
10
+ /** Whose words the text is, which decides the store that translates it (`helpers/text-source.ts`). */
11
+ textSource?: PhiTextSource;
9
12
  /**
10
13
  * Whether the text still has to be translated, which is true only where it is the Widget's own.
11
14
  *
@@ -16,4 +19,4 @@ export type PhiSimpleTextWidgetProps = PhiServerBlockBaseProps<PhiSimpleTextWidg
16
19
  */
17
20
  translate?: boolean;
18
21
  };
19
- export declare function PhiSimpleTextWidget({ blockId, labels, config, translate, runtime, }: PhiSimpleTextWidgetProps): Promise<import("react").JSX.Element>;
22
+ export declare function PhiSimpleTextWidget({ blockId, labels, config, translate, textSource, runtime, }: PhiSimpleTextWidgetProps): Promise<import("react").JSX.Element>;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { trGlobal, trGlobalForLocale, } from "../../../../../server-helpers/translate";
2
+ import { trWidgetText } from "../../../../../server-helpers/translate";
3
3
  import { maskPhiTextPlaceholders, resolvePhiTextPlaceholders } from "../../../../../helpers/text-placeholders";
4
4
  import { PhiCmsWidgetType } from "../../../../../constants/cms-widget-types";
5
5
  import { PhiRuntimeModuleRenderClientHost } from "../../../../../components/runtime/runtime-module-render-client-manifest";
6
- export async function PhiSimpleTextWidget({ blockId, labels, config, translate, runtime, }) {
6
+ export async function PhiSimpleTextWidget({ blockId, labels, config, translate, textSource, runtime, }) {
7
7
  const locale = runtime?.locale.current;
8
8
  /*
9
9
  * Masked before the translation and filled after it.
@@ -14,7 +14,7 @@ export async function PhiSimpleTextWidget({ blockId, labels, config, translate,
14
14
  */
15
15
  const masked = maskPhiTextPlaceholders(labels.text);
16
16
  const translated = translate && masked.text
17
- ? locale ? await trGlobalForLocale(locale, masked.text) : await trGlobal(masked.text)
17
+ ? await trWidgetText(locale, masked.text, textSource)
18
18
  : masked.text;
19
19
  const text = resolvePhiTextPlaceholders(translated, masked.names, runtime);
20
20
  return (_jsx(PhiRuntimeModuleRenderClientHost, { type: PhiCmsWidgetType.SimpleText, componentProps: {
@@ -913,7 +913,7 @@ export function PhiTableWidgetClient({ config: inputConfig, externalSearch, exte
913
913
  afterRowIdentity: null,
914
914
  }).catch(() => undefined).finally(clearPhiDataDragPayload);
915
915
  }
916
- : undefined, loading: effectiveLoading, bordered: presentation.borders, striped: presentation.row?.striped, showHeader: presentation.header, size: resolvedControlSize, emptyText: (_jsxs(PhiFlexControl, { vertical: true, gap: "small", children: [_jsx(PhiTypographyControl, { strong: true, children: presentation.emptyState?.title ?? labels.emptyTitle }), _jsx(PhiTypographyControl, { type: "secondary", children: presentation.emptyState?.description ?? labels.emptyDescription })] })), layout: presentation.layout, footer: footer, summary: tableSummary })] }));
916
+ : undefined, loading: effectiveLoading, bordered: presentation.borders, striped: presentation.row?.striped, showHeader: presentation.header, stickyHeader: presentation.stickyHeader !== false, size: resolvedControlSize, emptyText: (_jsxs(PhiFlexControl, { vertical: true, gap: "small", children: [_jsx(PhiTypographyControl, { strong: true, children: presentation.emptyState?.title ?? labels.emptyTitle }), _jsx(PhiTypographyControl, { type: "secondary", children: presentation.emptyState?.description ?? labels.emptyDescription })] })), layout: presentation.layout, footer: footer, summary: tableSummary })] }));
917
917
  }
918
918
  function TableAction({ action, disabled = false, disabledReason, templateValue, size, onActivate }) {
919
919
  const icon = action.icon ? resolvePhiButtonIcon(action.icon) : null;
@@ -105,6 +105,7 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
105
105
  } & {
106
106
  type: "data-provider";
107
107
  providerKind?: import("../../../../../types").PhiRuntimeDataProviderKind;
108
+ providerKey?: import("@phis/contracts/controls").PhiRuntimeDataProviderKey;
108
109
  }) | ({
109
110
  key: string;
110
111
  label: string;
@@ -278,10 +279,33 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
278
279
  editorPlacement?: "inspector" | "geometry" | "toolbar";
279
280
  visibleWhen?: import("../../../../../types").PhiCmsConfigFieldVisibilityRule | readonly import("../../../../../types").PhiCmsConfigFieldVisibilityRule[];
280
281
  heading?: string;
282
+ } & {
283
+ type: "choice";
284
+ valueType: "number";
285
+ options: import("@phis/contracts/controls").PhiControlOption<number>[];
286
+ emptyOption?: import("@phis/contracts/controls").PhiControlOption;
287
+ emptyValue?: null | undefined;
288
+ placeholder?: string;
289
+ mode?: never;
290
+ presentation?: never;
291
+ optionsProvider?: never;
292
+ allowCustom?: never;
293
+ createBehavior?: never;
294
+ filter?: never;
295
+ patchOnChange?: never;
296
+ optionPresets?: never;
297
+ }) | ({
298
+ key: string;
299
+ label: string;
300
+ description?: string;
301
+ required?: boolean;
302
+ editorPlacement?: "inspector" | "geometry" | "toolbar";
303
+ visibleWhen?: import("../../../../../types").PhiCmsConfigFieldVisibilityRule | readonly import("../../../../../types").PhiCmsConfigFieldVisibilityRule[];
304
+ heading?: string;
281
305
  } & {
282
306
  type: "choice";
283
307
  mode?: import("../../../../../types").PhiCmsConfigFieldChoiceMode;
284
- valueType?: import("../../../../../types").PhiCmsConfigFieldChoiceValueType;
308
+ valueType?: Exclude<import("../../../../../types").PhiCmsConfigFieldChoiceValueType, "number">;
285
309
  presentation?: import("../../../../../types").PhiCmsConfigFieldChoicePresentation;
286
310
  options?: import("@phis/contracts/controls").PhiControlOption[];
287
311
  optionsProvider?: import("@phis/contracts/controls").PhiControlOptionsProviderConfig;
@@ -411,6 +435,7 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
411
435
  heading?: string;
412
436
  type: "data-provider";
413
437
  providerKind?: import("../../../../../types").PhiRuntimeDataProviderKind;
438
+ providerKey?: import("@phis/contracts/controls").PhiRuntimeDataProviderKey;
414
439
  } | {
415
440
  visibleWhen: {
416
441
  field: string;
@@ -602,6 +627,31 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
602
627
  prefix?: string;
603
628
  presentation?: "slider";
604
629
  suffix?: string;
630
+ } | {
631
+ visibleWhen: {
632
+ field: string;
633
+ notEquals: string;
634
+ };
635
+ key: string;
636
+ label: string;
637
+ description?: string;
638
+ required?: boolean;
639
+ editorPlacement?: "inspector" | "geometry" | "toolbar";
640
+ heading?: string;
641
+ type: "choice";
642
+ valueType: "number";
643
+ options: import("@phis/contracts/controls").PhiControlOption<number>[];
644
+ emptyOption?: import("@phis/contracts/controls").PhiControlOption;
645
+ emptyValue?: null | undefined;
646
+ placeholder?: string;
647
+ mode?: never;
648
+ presentation?: never;
649
+ optionsProvider?: never;
650
+ allowCustom?: never;
651
+ createBehavior?: never;
652
+ filter?: never;
653
+ patchOnChange?: never;
654
+ optionPresets?: never;
605
655
  } | {
606
656
  visibleWhen: {
607
657
  field: string;
@@ -615,7 +665,7 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
615
665
  heading?: string;
616
666
  type: "choice";
617
667
  mode?: import("../../../../../types").PhiCmsConfigFieldChoiceMode;
618
- valueType?: import("../../../../../types").PhiCmsConfigFieldChoiceValueType;
668
+ valueType?: Exclude<import("../../../../../types").PhiCmsConfigFieldChoiceValueType, "number">;
619
669
  presentation?: import("../../../../../types").PhiCmsConfigFieldChoicePresentation;
620
670
  options?: import("@phis/contracts/controls").PhiControlOption[];
621
671
  optionsProvider?: import("@phis/contracts/controls").PhiControlOptionsProviderConfig;
@@ -778,6 +828,7 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
778
828
  heading?: string;
779
829
  type: "data-provider";
780
830
  providerKind?: import("../../../../../types").PhiRuntimeDataProviderKind;
831
+ providerKey?: import("@phis/contracts/controls").PhiRuntimeDataProviderKey;
781
832
  } | {
782
833
  visibleWhen: {
783
834
  field: string;
@@ -969,6 +1020,31 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
969
1020
  prefix?: string;
970
1021
  presentation?: "slider";
971
1022
  suffix?: string;
1023
+ } | {
1024
+ visibleWhen: {
1025
+ field: string;
1026
+ equals: boolean;
1027
+ };
1028
+ key: string;
1029
+ label: string;
1030
+ description?: string;
1031
+ required?: boolean;
1032
+ editorPlacement?: "inspector" | "geometry" | "toolbar";
1033
+ heading?: string;
1034
+ type: "choice";
1035
+ valueType: "number";
1036
+ options: import("@phis/contracts/controls").PhiControlOption<number>[];
1037
+ emptyOption?: import("@phis/contracts/controls").PhiControlOption;
1038
+ emptyValue?: null | undefined;
1039
+ placeholder?: string;
1040
+ mode?: never;
1041
+ presentation?: never;
1042
+ optionsProvider?: never;
1043
+ allowCustom?: never;
1044
+ createBehavior?: never;
1045
+ filter?: never;
1046
+ patchOnChange?: never;
1047
+ optionPresets?: never;
972
1048
  } | {
973
1049
  visibleWhen: {
974
1050
  field: string;
@@ -982,7 +1058,7 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
982
1058
  heading?: string;
983
1059
  type: "choice";
984
1060
  mode?: import("../../../../../types").PhiCmsConfigFieldChoiceMode;
985
- valueType?: import("../../../../../types").PhiCmsConfigFieldChoiceValueType;
1061
+ valueType?: Exclude<import("../../../../../types").PhiCmsConfigFieldChoiceValueType, "number">;
986
1062
  presentation?: import("../../../../../types").PhiCmsConfigFieldChoicePresentation;
987
1063
  options?: import("@phis/contracts/controls").PhiControlOption[];
988
1064
  optionsProvider?: import("@phis/contracts/controls").PhiControlOptionsProviderConfig;
@@ -1141,6 +1217,7 @@ export declare const PHI_TABLE_WIDGET_DEFINITION: {
1141
1217
  };
1142
1218
  borders: false;
1143
1219
  header: true;
1220
+ stickyHeader: true;
1144
1221
  row: {
1145
1222
  striped: false;
1146
1223
  };
@@ -537,6 +537,7 @@ export function parsePhiTableWidgetConfig(config) {
537
537
  },
538
538
  borders: readBoolean(presentation.borders),
539
539
  header: readBoolean(presentation.header),
540
+ stickyHeader: readBoolean(presentation.stickyHeader),
540
541
  footer: readTableFooter(presentation.footer),
541
542
  summary: readTableSummary(presentation.summary),
542
543
  row: {
@@ -1153,6 +1154,7 @@ export const PHI_TABLE_WIDGET_DEFINITION = {
1153
1154
  { ...PHI_CONTROL_SIZE_FIELD, key: "presentation.controlSize" },
1154
1155
  { key: "presentation.borders", type: "boolean", label: "Borders" },
1155
1156
  { key: "presentation.header", type: "boolean", label: "Header" },
1157
+ { key: "presentation.stickyHeader", type: "boolean", label: "Sticky Header" },
1156
1158
  { key: "presentation.row.striped", type: "boolean", label: "Striped Rows" },
1157
1159
  ...buildPhiTableConditionExpressionConfigFields("presentation.row.mutedWhen", "Muted Row Conditions", "any", "No muted rows"),
1158
1160
  ],
@@ -1162,6 +1164,7 @@ export const PHI_TABLE_WIDGET_DEFINITION = {
1162
1164
  layout: { mode: "auto", overflowX: "auto" },
1163
1165
  borders: false,
1164
1166
  header: true,
1167
+ stickyHeader: true,
1165
1168
  row: { striped: false },
1166
1169
  },
1167
1170
  features: {
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
4
4
  import { usePhiSignalDispatcher, usePhiSignalListener } from "../../../../../components/runtime/runtime-signal-bus";
5
5
  import { PhiButtonControl } from "../../../../../components/controls/phi-button-control";
6
6
  import { PhiIcon } from "../../../../../components/shell/phi-icon";
7
- import { PHI_TOUR_CONTROLLER_ADDRESS } from "../../../../../types/tours";
7
+ import { PHI_TOUR_CONTROLLER_ADDRESS } from "../../../../../types/tour-controller";
8
8
  function readAvailable(value) {
9
9
  return typeof value === "object" && value !== null && value.available === true;
10
10
  }
@@ -4,8 +4,7 @@ import { PhiCmsFlags, PhiCmsRegionType } from "../../constants/phi-cms";
4
4
  import { resolvePhiCmsWidgetPluginKey } from "../../constants/cms-widget-types";
5
5
  import { buildPhiCmsLayoutNamespacedTypeKey } from "../../constants/cms-layout-types";
6
6
  import { resolvePhiCmsLayoutPluginKey } from "../../constants/cms-layout-type-keys";
7
- import { trGlobal } from "../../server-helpers/translate";
8
- import { PHI_TR_CTX_WEB_UI_LABEL } from "../../gateway/tr";
7
+ import { PHI_TEXT_SOURCE_PRESET } from "../../helpers/text-source";
9
8
  import { PHI_SPACE } from "../../theme/antd-css-var-contract";
10
9
  import { buildPhiCmsWidgetNamespacedTypeKey } from "../../constants/cms-widget-types";
11
10
  import { createPhiCmsPresetNodes } from "../../helpers/cms-preset-nodes";
@@ -44,7 +43,12 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
44
43
  const footerTopRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "footer_top");
45
44
  const footerBottomRegion = PHI_DEFAULT_PUB_AREA_PRESET.regions.find((region) => region.key === "footer_bottom");
46
45
  const { label: contactLabel, href: contactHref, icon: contactIcon, } = resolvePhiBrandContact(runtime);
47
- const defaultQuickLinksTitle = await trGlobal("Quick Links", 0, PHI_TR_CTX_WEB_UI_LABEL);
46
+ /*
47
+ * The Preset's words stay in the source language and say they are the Preset's; the Widgets translate
48
+ * them through the global store (`helpers/text-source.ts`). The contact label is the Preset's only
49
+ * while the Site's theme names none.
50
+ */
51
+ const contactLabelIsPreset = !runtime.site.theme?.contact?.label?.trim();
48
52
  /*
49
53
  * A template rather than a finished sentence, and left untranslated here.
50
54
  *
@@ -477,6 +481,7 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
477
481
  label: "pub header top right",
478
482
  config: {
479
483
  text: contactLabel,
484
+ ...(contactLabelIsPreset ? { textSource: PHI_TEXT_SOURCE_PRESET } : {}),
480
485
  href: contactHref,
481
486
  icon: contactIcon,
482
487
  },
@@ -581,7 +586,8 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
581
586
  visibilityMask: page.visibilityMask,
582
587
  label: "pub footer main quick links",
583
588
  config: {
584
- title: defaultQuickLinksTitle,
589
+ title: "Quick Links",
590
+ textSource: PHI_TEXT_SOURCE_PRESET,
585
591
  navKey: `${navigationArea}:footer`,
586
592
  columns: 2,
587
593
  separator: true,
@@ -601,6 +607,7 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
601
607
  label: "pub footer main right",
602
608
  config: {
603
609
  text: contactLabel,
610
+ ...(contactLabelIsPreset ? { textSource: PHI_TEXT_SOURCE_PRESET } : {}),
604
611
  href: contactHref,
605
612
  icon: contactIcon,
606
613
  },
@@ -623,6 +630,7 @@ export async function buildPhiDefaultSiteAreaPresetTree({ page, runtime, presetK
623
630
  label: "pub footer bottom text",
624
631
  config: {
625
632
  text: footerBottomText,
633
+ textSource: PHI_TEXT_SOURCE_PRESET,
626
634
  tone: "secondary",
627
635
  },
628
636
  contentVersionId: null,
@@ -1,3 +1,4 @@
1
+ import { PHI_TEXT_SOURCE_PRESET } from "../../../../helpers/text-source";
1
2
  import { createPhiPresetCmsInstanceIdMap } from "../../../../types/cms-instance-id";
2
3
  import { PHI_SPACE } from "../../../../theme/antd-css-var-contract";
3
4
  import { PHI_PUBLIC_RUNTIME_MODULE_ID } from "../ids";
@@ -73,6 +74,7 @@ export async function buildPhiDefaultPubContactPageTree({ page, }) {
73
74
  sortOrder: 0,
74
75
  label: "pub contact description widget",
75
76
  config: {
77
+ textSource: PHI_TEXT_SOURCE_PRESET,
76
78
  eyebrow: "Contact",
77
79
  title: "Get in touch",
78
80
  description: "Send us your question, project request, or product inquiry and we will get back to you.",
@@ -1,3 +1,4 @@
1
+ import { PHI_TEXT_SOURCE_PRESET } from "../../../../helpers/text-source";
1
2
  import { createPhiPresetCmsInstanceIdMap } from "../../../../types/cms-instance-id";
2
3
  import { PHI_PUBLIC_RUNTIME_MODULE_ID } from "../ids";
3
4
  import { PhiCmsPageType } from "../../../../constants/phi-cms";
@@ -58,6 +59,7 @@ export async function buildPhiDefaultPubUnsubscribePageTree({ page, presetKey, }
58
59
  sortOrder: 0,
59
60
  label: "pub unsubscribe intro widget",
60
61
  config: {
62
+ textSource: PHI_TEXT_SOURCE_PRESET,
61
63
  title: "Stop receiving updates",
62
64
  description: "Press the button below and this site will send you no further updates.",
63
65
  visibleWhen: withToken,
@@ -75,6 +77,7 @@ export async function buildPhiDefaultPubUnsubscribePageTree({ page, presetKey, }
75
77
  sortOrder: 0,
76
78
  label: "pub unsubscribe incomplete widget",
77
79
  config: {
80
+ textSource: PHI_TEXT_SOURCE_PRESET,
78
81
  title: "This link is incomplete",
79
82
  description: "Open the unsubscribe link from the message itself, or use the most recent one you received.",
80
83
  tone: "secondary",
@@ -1,3 +1,4 @@
1
+ import { PHI_TEXT_SOURCE_PRESET } from "../../../../helpers/text-source";
1
2
  import { createPhiPresetCmsInstanceIdMap } from "../../../../types/cms-instance-id";
2
3
  import { PHI_PUBLIC_RUNTIME_MODULE_ID } from "../ids";
3
4
  import { PHI_PUBLIC_BASE_PAGE_REFERENCES } from "../../public-base-page-references";
@@ -125,7 +126,7 @@ export async function buildPhiDefaultPubWelcomePageTree({ page, runtime, }) {
125
126
  sortOrder: 0,
126
127
  label: "pub welcome greeting",
127
128
  // English source, like every Preset sentence: the Site translator makes it "Herzlich willkommen".
128
- config: { text: "A warm welcome" },
129
+ config: { textSource: PHI_TEXT_SOURCE_PRESET, text: "A warm welcome" },
129
130
  }),
130
131
  nodes.widget({
131
132
  typeKey: "markdown",
@@ -1,2 +1,53 @@
1
- import type { PhiCmsRoutePresetDescriptor } from "../../../types/cms-module-descriptors";
2
- export declare const PHI_REVISIONS_RUNTIME_MODULE_ROUTES: PhiCmsRoutePresetDescriptor[];
1
+ export declare const PHI_REVISIONS_RUNTIME_MODULE_ROUTES: {
2
+ tour: {
3
+ readonly id: "@phis/ui/modules/revisions/revisions";
4
+ readonly version: 1;
5
+ readonly steps: readonly [{
6
+ readonly key: "history";
7
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:filters`;
8
+ readonly title: "Whose history";
9
+ readonly description: "Every save is kept as a revision. Kind chooses what the list shows: an Area's Shell, a Page, a Navigation or the Theme. Scope chooses which Page or which Navigation.";
10
+ readonly placement: "bottom";
11
+ readonly ifMissing: "skip";
12
+ }, {
13
+ readonly key: "list";
14
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:header`;
15
+ readonly title: "One row per revision";
16
+ readonly description: "Newest first, with when it was saved, by whom and what changed. The tags say which revision is live and which is the draft being worked on; those two cannot be deleted.";
17
+ readonly placement: "bottom";
18
+ }, {
19
+ readonly key: "answer";
20
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:row-actions`;
21
+ readonly title: "Looking back and going back";
22
+ readonly description: "Review opens the revision as it was, in a new tab. Restore makes a new draft from it: nothing live changes until that draft is published. Delete removes a revision for good; selected rows can be deleted together.";
23
+ readonly placement: "left";
24
+ readonly ifMissing: "skip";
25
+ }, {
26
+ readonly key: "reset";
27
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:toolbar`;
28
+ readonly title: "Back to the preset";
29
+ readonly description: "A Page a Module brings can go back to that Module's version. Every revision the Site stored for it goes with it, so this is offered only while a Page's history is shown.";
30
+ readonly placement: "bottom";
31
+ readonly ifMissing: "skip";
32
+ }, {
33
+ readonly key: "delete-area";
34
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
35
+ readonly title: "Deleting an Area";
36
+ readonly description: "Clears everything the Site stored for an Area's Shell and Module selection, live included, and leaves no revision to restore. The Area keeps its Pages, its Navigation and its Theme. It asks for the Area's key before it does anything.";
37
+ readonly placement: "bottom";
38
+ }];
39
+ };
40
+ ownerModuleId: import("../contracts").PhiRuntimeModuleId;
41
+ presetKey: string;
42
+ presetVersion: number;
43
+ area: import("@phis/contracts/cms").PhiCmsAreaKey;
44
+ path: string;
45
+ landingPage?: true;
46
+ title: string;
47
+ defaultPageFlags?: number;
48
+ loadTree: (context: import("../../../types").PhiCmsDescriptorBuildContext & {
49
+ activeModuleIds: ReadonlySet<import("../contracts").PhiRuntimeModuleId>;
50
+ params: Readonly<Record<string, string>>;
51
+ }) => import("../../../types").PhiResolvedCmsPageTree | Promise<import("../../../types").PhiResolvedCmsPageTree>;
52
+ navigation?: readonly import("../../../types").PhiCmsNavigationInjectionDescriptor[];
53
+ }[];
@@ -1,16 +1,20 @@
1
1
  import { buildPhiSidebarRoutePresetDescriptor } from "../sidebar-route";
2
2
  import { PHI_REVISIONS_RUNTIME_MODULE_ID } from "./ids";
3
+ import { PHI_REVISIONS_TOUR } from "./tour";
3
4
  export const PHI_REVISIONS_RUNTIME_MODULE_ROUTES = [
4
- buildPhiSidebarRoutePresetDescriptor({
5
- area: "builder",
6
- anchor: "main",
7
- ownerModuleId: PHI_REVISIONS_RUNTIME_MODULE_ID,
8
- presetKey: "builder-revisions-page",
9
- title: "Revisions",
10
- path: "/revisions",
11
- itemKey: "@phis/ui/modules/revisions/nav/builder/revisions",
12
- icon: "antd:history",
13
- loadTree: ({ page, runtime }) => import("./trees/phi-default-builder-revisions-page-tree")
14
- .then((module) => module.buildPhiDefaultBuilderRevisionsPageTree({ page, runtime })),
15
- }),
5
+ {
6
+ ...buildPhiSidebarRoutePresetDescriptor({
7
+ area: "builder",
8
+ anchor: "main",
9
+ ownerModuleId: PHI_REVISIONS_RUNTIME_MODULE_ID,
10
+ presetKey: "builder-revisions-page",
11
+ title: "Revisions",
12
+ path: "/revisions",
13
+ itemKey: "@phis/ui/modules/revisions/nav/builder/revisions",
14
+ icon: "antd:history",
15
+ loadTree: ({ page, runtime }) => import("./trees/phi-default-builder-revisions-page-tree")
16
+ .then((module) => module.buildPhiDefaultBuilderRevisionsPageTree({ page, runtime })),
17
+ }),
18
+ tour: PHI_REVISIONS_TOUR,
19
+ },
16
20
  ];
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The Revisions Tour. What the Page does not say is that every save is kept, that going back never
3
+ * touches what is live -- a restored revision is a new draft -- and that the one act here that cannot be
4
+ * taken back stands apart from the rest.
5
+ */
6
+ export declare const PHI_REVISIONS_TOUR: {
7
+ readonly id: "@phis/ui/modules/revisions/revisions";
8
+ readonly version: 1;
9
+ readonly steps: readonly [{
10
+ readonly key: "history";
11
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:filters`;
12
+ readonly title: "Whose history";
13
+ readonly description: "Every save is kept as a revision. Kind chooses what the list shows: an Area's Shell, a Page, a Navigation or the Theme. Scope chooses which Page or which Navigation.";
14
+ readonly placement: "bottom";
15
+ readonly ifMissing: "skip";
16
+ }, {
17
+ readonly key: "list";
18
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:header`;
19
+ readonly title: "One row per revision";
20
+ readonly description: "Newest first, with when it was saved, by whom and what changed. The tags say which revision is live and which is the draft being worked on; those two cannot be deleted.";
21
+ readonly placement: "bottom";
22
+ }, {
23
+ readonly key: "answer";
24
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:row-actions`;
25
+ readonly title: "Looking back and going back";
26
+ readonly description: "Review opens the revision as it was, in a new tab. Restore makes a new draft from it: nothing live changes until that draft is published. Delete removes a revision for good; selected rows can be deleted together.";
27
+ readonly placement: "left";
28
+ readonly ifMissing: "skip";
29
+ }, {
30
+ readonly key: "reset";
31
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:toolbar`;
32
+ readonly title: "Back to the preset";
33
+ readonly description: "A Page a Module brings can go back to that Module's version. Every revision the Site stored for it goes with it, so this is offered only while a Page's history is shown.";
34
+ readonly placement: "bottom";
35
+ readonly ifMissing: "skip";
36
+ }, {
37
+ readonly key: "delete-area";
38
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
39
+ readonly title: "Deleting an Area";
40
+ readonly description: "Clears everything the Site stored for an Area's Shell and Module selection, live included, and leaves no revision to restore. The Area keeps its Pages, its Navigation and its Theme. It asks for the Area's key before it does anything.";
41
+ readonly placement: "bottom";
42
+ }];
43
+ };
@@ -0,0 +1,51 @@
1
+ import { PHI_REVISIONS_RUNTIME_MODULE_ID } from "./ids";
2
+ import { PHI_REVISIONS_PAGE_WIDGET_IDS, PHI_REVISIONS_TABLE_WIDGET_ID } from "./page-ids";
3
+ /**
4
+ * The Revisions Tour. What the Page does not say is that every save is kept, that going back never
5
+ * touches what is live -- a restored revision is a new draft -- and that the one act here that cannot be
6
+ * taken back stands apart from the rest.
7
+ */
8
+ export const PHI_REVISIONS_TOUR = {
9
+ id: `${PHI_REVISIONS_RUNTIME_MODULE_ID}/revisions`,
10
+ version: 1,
11
+ steps: [
12
+ {
13
+ key: "history",
14
+ target: `cms:${PHI_REVISIONS_TABLE_WIDGET_ID}:filters`,
15
+ title: "Whose history",
16
+ description: "Every save is kept as a revision. Kind chooses what the list shows: an Area's Shell, a Page, a Navigation or the Theme. Scope chooses which Page or which Navigation.",
17
+ placement: "bottom",
18
+ ifMissing: "skip",
19
+ },
20
+ {
21
+ key: "list",
22
+ target: `cms:${PHI_REVISIONS_TABLE_WIDGET_ID}:header`,
23
+ title: "One row per revision",
24
+ description: "Newest first, with when it was saved, by whom and what changed. The tags say which revision is live and which is the draft being worked on; those two cannot be deleted.",
25
+ placement: "bottom",
26
+ },
27
+ {
28
+ key: "answer",
29
+ target: `cms:${PHI_REVISIONS_TABLE_WIDGET_ID}:row-actions`,
30
+ title: "Looking back and going back",
31
+ description: "Review opens the revision as it was, in a new tab. Restore makes a new draft from it: nothing live changes until that draft is published. Delete removes a revision for good; selected rows can be deleted together.",
32
+ placement: "left",
33
+ ifMissing: "skip",
34
+ },
35
+ {
36
+ key: "reset",
37
+ target: `cms:${PHI_REVISIONS_TABLE_WIDGET_ID}:toolbar`,
38
+ title: "Back to the preset",
39
+ description: "A Page a Module brings can go back to that Module's version. Every revision the Site stored for it goes with it, so this is offered only while a Page's history is shown.",
40
+ placement: "bottom",
41
+ ifMissing: "skip",
42
+ },
43
+ {
44
+ key: "delete-area",
45
+ target: `cms:${PHI_REVISIONS_PAGE_WIDGET_IDS.widgetRevisionsAreaShellDelete}`,
46
+ title: "Deleting an Area",
47
+ description: "Clears everything the Site stored for an Area's Shell and Module selection, live included, and leaves no revision to restore. The Area keeps its Pages, its Navigation and its Theme. It asks for the Area's key before it does anything.",
48
+ placement: "bottom",
49
+ },
50
+ ],
51
+ };
@@ -265,6 +265,8 @@ export async function buildPhiDefaultBuilderRevisionsPageTree({ page, runtime, }
265
265
  */
266
266
  nodes.widget({
267
267
  typeKey: "simple-text",
268
+ /* Label set text, translated already; a second pass would hand the translator a non-source text. */
269
+ flags: PhiCmsFlags.NoTranslate,
268
270
  id: PHI_REVISIONS_DELETE_AREA_WIDGET_IDS.deleteAreaWarning,
269
271
  parentLayoutNodeId: PHI_REVISIONS_DELETE_AREA_LAYOUT_IDS.deleteAreaBody,
270
272
  slotIndex: PHI_CMS_DEFAULT_SLOT_INDEX,
@@ -279,6 +281,8 @@ export async function buildPhiDefaultBuilderRevisionsPageTree({ page, runtime, }
279
281
  }),
280
282
  nodes.widget({
281
283
  typeKey: "simple-text",
284
+ /* Label set text, translated already; a second pass would hand the translator a non-source text. */
285
+ flags: PhiCmsFlags.NoTranslate,
282
286
  id: PHI_REVISIONS_DELETE_AREA_WIDGET_IDS.deleteAreaSurvives,
283
287
  parentLayoutNodeId: PHI_REVISIONS_DELETE_AREA_LAYOUT_IDS.deleteAreaBody,
284
288
  slotIndex: PHI_CMS_SEQUENTIAL_LAYOUT_SLOTS[1].slotIndex,
@@ -5,15 +5,47 @@ export declare const PHI_THEME_RUNTIME_MODULE_ROUTES: {
5
5
  readonly steps: readonly [{
6
6
  readonly key: "theme-choice";
7
7
  readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
8
- readonly title: "Which theme you are working on";
9
- readonly description: "The Site's published theme, its draft, or a theme a Module brings. A Module's theme changes nothing until it is picked here.";
8
+ readonly title: "What your draft starts from";
9
+ readonly description: "The Site's published theme, its draft, or a theme a Module brings. Picking one makes it the base of your theme draft; the Module's theme itself stays as it is.";
10
10
  readonly placement: "bottom";
11
11
  }, {
12
12
  readonly key: "theme-parts";
13
13
  readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
14
- readonly title: "Colour and style";
15
- readonly description: "Switch between the palette and the shapes and type of the theme.";
14
+ readonly title: "Four parts of the theme";
15
+ readonly description: "Colour, style, background and brand: each opens its own controls on the left, with the preview beside them.";
16
16
  readonly placement: "bottom";
17
+ }, {
18
+ readonly key: string;
19
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
20
+ readonly title: string;
21
+ readonly description: string;
22
+ readonly placement: "right";
23
+ readonly prepare: readonly [import("../../../types").PhiTourStepSignal];
24
+ readonly release: readonly [import("../../../types").PhiTourStepSignal];
25
+ }, {
26
+ readonly key: string;
27
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
28
+ readonly title: string;
29
+ readonly description: string;
30
+ readonly placement: "right";
31
+ readonly prepare: readonly [import("../../../types").PhiTourStepSignal];
32
+ readonly release: readonly [import("../../../types").PhiTourStepSignal];
33
+ }, {
34
+ readonly key: string;
35
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
36
+ readonly title: string;
37
+ readonly description: string;
38
+ readonly placement: "right";
39
+ readonly prepare: readonly [import("../../../types").PhiTourStepSignal];
40
+ readonly release: readonly [import("../../../types").PhiTourStepSignal];
41
+ }, {
42
+ readonly key: string;
43
+ readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;
44
+ readonly title: string;
45
+ readonly description: string;
46
+ readonly placement: "right";
47
+ readonly prepare: readonly [import("../../../types").PhiTourStepSignal];
48
+ readonly release: readonly [import("../../../types").PhiTourStepSignal];
17
49
  }, {
18
50
  readonly key: "preview-mode";
19
51
  readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}`;