@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,9 +1,10 @@
1
1
  import { resolvePhiCmsWidgetPluginKey } from "../../../../../constants/cms-widget-types";
2
2
  import { PHI_MEDIA_LIBRARY_DATA_PROVIDER_KEYS } from "../../../../../constants/media-library-provider-keys";
3
+ import { PHI_MEDIA_ASPECT_RATIOS, PHI_MEDIA_ASPECT_RATIO_OPTIONS, } from "../../../../../components/media/aspect-ratios";
3
4
  import { PHI_IMAGE_VARIANT_OPTIONS } from "../../../../../components/widgets/config/image-variant-options";
5
+ import { buildPhiSequenceSettingsFields, PHI_SEQUENCE_SETTINGS_DEFAULTS, readPhiSequenceSettings, } from "../../../../../components/widgets/config/sequence-settings";
6
+ import { PHI_GALLERY_DEFAULT_ASPECT_RATIO } from "./defaults";
4
7
  import { readPhiRuntimeDataProviderBinding, } from "../../../../../types/runtime-data-provider";
5
- import { PHI_MOTION_EASING_FIELD_OPTIONS, PHI_SEQUENCE_TRANSITION_MAX_MS, PHI_SEQUENCE_TRANSITION_MIN_MS, PHI_SEQUENCE_TRANSITION_STEP_MS, clampPhiSequenceTransitionMs, PHI_SEQUENCE_ANCHORS, PHI_SEQUENCE_TRANSITIONS, readPhiMotionEasing, } from "../../../../../helpers/motion";
6
- import { PHI_CMS_MOUNT_POLICY_FIELD_OPTIONS, readPhiCmsMountPolicy, } from "../../../../../types/cms-mount-policy";
7
8
  import { readRenderableBlockConfig, } from "../../../../../components/widgets/config/parser-primitives";
8
9
  /*
9
10
  * Read strictly, and say so when a document is wrong.
@@ -24,14 +25,6 @@ function readMember(value, members, key) {
24
25
  }
25
26
  return value;
26
27
  }
27
- function readCount(value, key, min) {
28
- if (value === undefined || value === null)
29
- return undefined;
30
- if (typeof value !== "number" || !Number.isInteger(value) || value < min) {
31
- fail(key, value, `a whole number of at least ${min}`);
32
- }
33
- return value;
34
- }
35
28
  function readFlag(value, key) {
36
29
  if (value === undefined || value === null)
37
30
  return undefined;
@@ -39,55 +32,38 @@ function readFlag(value, key) {
39
32
  fail(key, value, "true or false");
40
33
  return value;
41
34
  }
42
- function readText(value, key) {
35
+ /** The Folder the pictures come from; a binding to any other Provider is a mistake in the document. */
36
+ function readFolderSource(value) {
37
+ const binding = readPhiRuntimeDataProviderBinding(value);
38
+ if (binding && binding.providerKey !== PHI_MEDIA_LIBRARY_DATA_PROVIDER_KEYS.folderImages) {
39
+ fail("source", binding.providerKey, PHI_MEDIA_LIBRARY_DATA_PROVIDER_KEYS.folderImages);
40
+ }
41
+ return binding;
42
+ }
43
+ function readVariantKey(value) {
43
44
  if (value === undefined || value === null)
44
45
  return undefined;
45
- if (typeof value !== "string" || value.trim() === "")
46
- fail(key, value, "a non-empty string");
46
+ if (!PHI_IMAGE_VARIANT_OPTIONS.some((option) => option.value === value)) {
47
+ fail("variantKey", value, `one of ${PHI_IMAGE_VARIANT_OPTIONS.map((option) => option.value).join(", ")}`);
48
+ }
47
49
  return value;
48
50
  }
49
51
  export function parsePhiCmsGalleryWidgetConfig(raw) {
50
- const visibleCount = readCount(raw.visibleCount, "visibleCount", 1);
51
- const windowAnchor = readMember(raw.windowAnchor, PHI_SEQUENCE_ANCHORS, "windowAnchor");
52
- const transition = readMember(raw.transition, PHI_SEQUENCE_TRANSITIONS, "transition");
53
- const easing = readPhiMotionEasing(raw.easing, undefined);
54
- const gap = readText(raw.gap, "gap");
55
- const lookahead = readCount(raw.lookahead, "lookahead", 0);
56
- const aspectRatio = readText(raw.aspectRatio, "aspectRatio");
52
+ const aspectRatio = readMember(raw.aspectRatio, PHI_MEDIA_ASPECT_RATIOS, "aspectRatio");
57
53
  const fit = readMember(raw.fit, ["cover", "contain"], "fit");
58
- const controls = readMember(raw.controls, ["none", "arrows", "dots", "both"], "controls");
59
- const loop = readFlag(raw.loop, "loop");
60
- const autoplayMs = readCount(raw.autoplayMs, "autoplayMs", 0);
61
- const variantKey = readMember(raw.variantKey, PHI_IMAGE_VARIANT_OPTIONS.map((option) => option.value), "variantKey");
54
+ const variantKey = readVariantKey(raw.variantKey);
62
55
  const preview = readFlag(raw.preview, "preview");
63
56
  return {
64
57
  ...readRenderableBlockConfig(raw),
65
- source: readPhiRuntimeDataProviderBinding(raw.source),
58
+ ...readPhiSequenceSettings(raw, fail),
59
+ source: readFolderSource(raw.source),
66
60
  ...(variantKey === undefined ? {} : { variantKey }),
67
61
  ...(preview === undefined ? {} : { preview }),
68
- ...(visibleCount === undefined ? {} : { visibleCount }),
69
- ...(windowAnchor === undefined ? {} : { windowAnchor }),
70
- ...(transition === undefined ? {} : { transition }),
71
- // Absent stays absent: the viewport then moves at the pace the theme sets rather than one this
72
- // Widget invented.
73
- ...(raw.durationMs === undefined || raw.durationMs === null
74
- ? {}
75
- : { durationMs: clampPhiSequenceTransitionMs(raw.durationMs) }),
76
- ...(easing === undefined ? {} : { easing }),
77
- ...(gap === undefined ? {} : { gap }),
78
- ...(lookahead === undefined ? {} : { lookahead }),
79
- mountPolicy: readPhiCmsMountPolicy(raw.mountPolicy, "lazy-keep"),
80
62
  ...(aspectRatio === undefined ? {} : { aspectRatio }),
81
63
  ...(fit === undefined ? {} : { fit }),
82
- ...(controls === undefined ? {} : { controls }),
83
- ...(loop === undefined ? {} : { loop }),
84
- // Zero is how "does not move on its own" is written, so it is the one number below the floor
85
- // that means something.
86
- ...(autoplayMs === undefined || autoplayMs === 0
87
- ? {}
88
- : { autoplayMs: clampPhiSequenceTransitionMs(autoplayMs) }),
89
64
  };
90
65
  }
66
+ const PHI_GALLERY_SEQUENCE_FIELDS = buildPhiSequenceSettingsFields({ countLabel: "Visible Pictures" });
91
67
  export const PHI_GALLERY_WIDGET_DEFINITION = {
92
68
  kind: "widget",
93
69
  pluginKey: resolvePhiCmsWidgetPluginKey("gallery"),
@@ -104,63 +80,33 @@ export const PHI_GALLERY_WIDGET_DEFINITION = {
104
80
  key: "source",
105
81
  type: "data-provider",
106
82
  providerKind: "record",
107
- label: "Pictures",
108
- description: "Where the pictures come from. The folder and its order are set inside the binding.",
83
+ // Always a Folder: the Inspector asks for the folder and its order, never for a Provider.
84
+ providerKey: PHI_MEDIA_LIBRARY_DATA_PROVIDER_KEYS.folderImages,
85
+ label: "Source",
109
86
  },
110
87
  {
111
88
  key: "variantKey",
112
89
  type: "choice",
90
+ valueType: "number",
91
+ heading: "Picture",
113
92
  label: "Variant",
114
93
  options: PHI_IMAGE_VARIANT_OPTIONS,
115
94
  emptyOption: { value: "__original__", label: "Original" },
116
95
  emptyValue: null,
117
96
  },
118
- { key: "preview", type: "boolean", label: "Lightbox", description: "Open a picture larger over the page when it is clicked." },
119
- { key: "visibleCount", type: "number", label: "Visible Pictures", min: 1 },
120
- {
121
- key: "windowAnchor",
122
- type: "choice",
123
- label: "Window Anchor",
124
- options: [
125
- { value: "start", label: "Leading edge" },
126
- { value: "center", label: "Centre" },
127
- ],
128
- },
129
- {
130
- key: "transition",
131
- type: "choice",
132
- label: "Transition",
133
- options: [
134
- { value: "none", label: "None" },
135
- { value: "fade", label: "Fade" },
136
- { value: "slide", label: "Slide" },
137
- { value: "diagonal", label: "Diagonal" },
138
- ],
139
- },
140
- {
141
- key: "durationMs",
142
- type: "number",
143
- label: "Duration",
144
- min: PHI_SEQUENCE_TRANSITION_MIN_MS,
145
- max: PHI_SEQUENCE_TRANSITION_MAX_MS,
146
- step: PHI_SEQUENCE_TRANSITION_STEP_MS,
147
- prefix: "ms",
148
- },
149
- {
150
- key: "easing",
151
- type: "choice",
152
- label: "Easing",
153
- options: [...PHI_MOTION_EASING_FIELD_OPTIONS],
154
- },
155
- { key: "gap", type: "string", label: "Gap" },
156
- { key: "lookahead", type: "number", label: "Preload Ahead", min: 0 },
97
+ /*
98
+ * Proportion and fit are questions only the original asks. A variant is cut to its own width and
99
+ * height, so the frame takes that proportion and the picture fills it exactly; a second ratio on
100
+ * top would crop a crop. Originals come in every shape, and a run of them needs one frame to
101
+ * stand in, or the Gallery changes height with every step.
102
+ */
157
103
  {
158
- key: "mountPolicy",
104
+ key: "aspectRatio",
159
105
  type: "choice",
160
- label: "Mounting",
161
- options: [...PHI_CMS_MOUNT_POLICY_FIELD_OPTIONS],
106
+ label: "Aspect Ratio",
107
+ options: PHI_MEDIA_ASPECT_RATIO_OPTIONS,
108
+ visibleWhen: { field: "variantKey", equals: null },
162
109
  },
163
- { key: "aspectRatio", type: "string", label: "Aspect Ratio" },
164
110
  {
165
111
  key: "fit",
166
112
  type: "choice",
@@ -169,31 +115,24 @@ export const PHI_GALLERY_WIDGET_DEFINITION = {
169
115
  { value: "cover", label: "Cover" },
170
116
  { value: "contain", label: "Contain" },
171
117
  ],
118
+ visibleWhen: { field: "variantKey", equals: null },
172
119
  },
173
- {
174
- key: "controls",
175
- type: "choice",
176
- label: "Controls",
177
- options: [
178
- { value: "both", label: "Arrows and dots" },
179
- { value: "arrows", label: "Arrows" },
180
- { value: "dots", label: "Dots" },
181
- { value: "none", label: "None" },
182
- ],
183
- },
184
- { key: "loop", type: "boolean", label: "Wrap Around" },
185
- {
186
- // Zero is the one value below the floor that means something: it does not move on its own.
187
- key: "autoplayMs",
188
- type: "number",
189
- label: "Autoplay",
190
- min: 0,
191
- max: PHI_SEQUENCE_TRANSITION_MAX_MS,
192
- step: PHI_SEQUENCE_TRANSITION_STEP_MS,
193
- prefix: "ms",
194
- },
120
+ { key: "preview", type: "boolean", label: "Lightbox", description: "Open a picture larger over the page when it is clicked." },
121
+ ...PHI_GALLERY_SEQUENCE_FIELDS.window,
122
+ ...PHI_GALLERY_SEQUENCE_FIELDS.movement,
123
+ ...PHI_GALLERY_SEQUENCE_FIELDS.controls,
195
124
  ],
196
- // Bound to the Folder Provider from the start, so the inspector asks for a folder and nothing else.
197
- defaultConfig: { source: { providerKey: PHI_MEDIA_LIBRARY_DATA_PROVIDER_KEYS.folderImages, params: {} } },
125
+ /*
126
+ * Bound to the Folder Provider from the start, so the inspector asks for a folder and nothing else.
127
+ * The rest is what the Gallery does when nobody said otherwise, stated here so the Inspector shows
128
+ * it as the standing answer rather than an empty box over a setting that was never in doubt.
129
+ */
130
+ defaultConfig: {
131
+ source: { providerKey: PHI_MEDIA_LIBRARY_DATA_PROVIDER_KEYS.folderImages, params: {} },
132
+ preview: false,
133
+ aspectRatio: PHI_GALLERY_DEFAULT_ASPECT_RATIO,
134
+ fit: "cover",
135
+ ...PHI_SEQUENCE_SETTINGS_DEFAULTS,
136
+ },
198
137
  parseConfig: parsePhiCmsGalleryWidgetConfig,
199
138
  };
@@ -0,0 +1,15 @@
1
+ import { type PhiMediaAspectRatio } from "../../../../../components/media/aspect-ratios";
2
+ import type { PhiCmsGalleryWidgetConfig } from "./config";
3
+ /** What a Gallery is drawn at where nobody said otherwise, on the page and on the canvas alike. */
4
+ export declare const PHI_GALLERY_DEFAULT_ASPECT_RATIO: PhiMediaAspectRatio;
5
+ /**
6
+ * The frame every picture of the run stands in.
7
+ *
8
+ * A variant is cut to a width and a height of its own, so its proportion is the frame's and the
9
+ * picture fills it exactly -- the author's ratio and fit are not asked for and not read. Only the
10
+ * original, which comes in every shape, takes them.
11
+ */
12
+ export declare function resolvePhiGalleryFrame(config: Pick<PhiCmsGalleryWidgetConfig, "variantKey" | "aspectRatio" | "fit"> | undefined): {
13
+ aspectRatio: string;
14
+ fit: "cover" | "contain";
15
+ };
@@ -0,0 +1,20 @@
1
+ import { resolvePhiImageAssetVariantSpec } from "../../../../../constants/media";
2
+ import { resolvePhiMediaAspectRatioCss } from "../../../../../components/media/aspect-ratios";
3
+ /** What a Gallery is drawn at where nobody said otherwise, on the page and on the canvas alike. */
4
+ export const PHI_GALLERY_DEFAULT_ASPECT_RATIO = "16:9";
5
+ /**
6
+ * The frame every picture of the run stands in.
7
+ *
8
+ * A variant is cut to a width and a height of its own, so its proportion is the frame's and the
9
+ * picture fills it exactly -- the author's ratio and fit are not asked for and not read. Only the
10
+ * original, which comes in every shape, takes them.
11
+ */
12
+ export function resolvePhiGalleryFrame(config) {
13
+ const spec = config?.variantKey == null ? null : resolvePhiImageAssetVariantSpec(config.variantKey);
14
+ return spec
15
+ ? { aspectRatio: `${spec.width} / ${spec.height}`, fit: "cover" }
16
+ : {
17
+ aspectRatio: resolvePhiMediaAspectRatioCss(config?.aspectRatio ?? PHI_GALLERY_DEFAULT_ASPECT_RATIO),
18
+ fit: config?.fit ?? "cover",
19
+ };
20
+ }
@@ -52,7 +52,7 @@ export async function PhiHtmlWidget({ blockId, config, runtime, }) {
52
52
  }
53
53
  const translatedHtml = (sourceMode !== "url" && config?.resolvedContent != null) || config?.preferSource === true
54
54
  ? sourceHtml
55
- : await translateSemanticHtml(sourceHtml, sourceMode === "url" ? config?.sourceLocale?.trim() : undefined);
55
+ : await translateSemanticHtml(sourceHtml, sourceMode === "url" ? config?.sourceLocale?.trim() : undefined, runtime.locale.current);
56
56
  if (!translatedHtml) {
57
57
  return null;
58
58
  }
@@ -87,7 +87,7 @@ export function PhiImageWidget({ labels, config, resolvedAsset, focalRect, autho
87
87
  textAlign: "center",
88
88
  }, children: [_jsx(PhiEmptyControl, {}), _jsx(PhiTypographyControl, { type: "secondary", strong: false, children: labels.emptyTitle }), _jsx(PhiTypographyControl, { type: "secondary", children: labels.emptyDescription })] }));
89
89
  }
90
- return (_jsx(PhiImageControl, { presentation: presentation, source: sourceKind === "asset" ? "asset" : config?.trusted === true ? "trusted-url" : "url", alt: alt, title: title || undefined, width: width, height: height, blurDataUrl: resolvedAsset?.blurDataUrl, optimizable: optimizable, sizes: config?.sizes, preload: config?.preload === true && isPublicAsset, preview: (config?.previewMode ?? "none") === "lightbox", style: {
90
+ return (_jsx(PhiImageControl, { presentation: presentation, source: sourceKind === "asset" ? "asset" : config?.trusted === true ? "trusted-url" : "url", alt: alt, title: title || undefined, width: width, height: height, blurDataUrl: resolvedAsset?.blurDataUrl, optimizable: optimizable, sizes: config?.sizes, preload: config?.preload === true && isPublicAsset, preview: (config?.previewMode ?? "none") === "lightbox", zoom: config?.previewMode === "native", style: {
91
91
  ...radiusStyle,
92
92
  ...maskStyle,
93
93
  overflow: presentation.simulatedCropStyle || Object.values(radiusStyle).some((value) => value != null)
@@ -42,6 +42,7 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
42
42
  label: string;
43
43
  }[];
44
44
  visibleWhen?: undefined;
45
+ valueType?: undefined;
45
46
  emptyOption?: undefined;
46
47
  emptyValue?: undefined;
47
48
  widthPlaceholder?: undefined;
@@ -59,6 +60,7 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
59
60
  equals: string;
60
61
  };
61
62
  options?: undefined;
63
+ valueType?: undefined;
62
64
  emptyOption?: undefined;
63
65
  emptyValue?: undefined;
64
66
  widthPlaceholder?: undefined;
@@ -70,11 +72,9 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
70
72
  } | {
71
73
  key: string;
72
74
  type: "choice";
75
+ valueType: "number";
73
76
  label: string;
74
- options: {
75
- value: string;
76
- label: string;
77
- }[];
77
+ options: import("@phis/contracts/controls").PhiControlOption<number>[];
78
78
  emptyOption: {
79
79
  value: string;
80
80
  label: string;
@@ -99,6 +99,28 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
99
99
  equals: string;
100
100
  };
101
101
  options?: undefined;
102
+ valueType?: undefined;
103
+ emptyOption?: undefined;
104
+ emptyValue?: undefined;
105
+ widthPlaceholder?: undefined;
106
+ heightPlaceholder?: undefined;
107
+ topLeftKey?: undefined;
108
+ topRightKey?: undefined;
109
+ bottomLeftKey?: undefined;
110
+ bottomRightKey?: undefined;
111
+ } | {
112
+ key: string;
113
+ type: "choice";
114
+ label: string;
115
+ visibleWhen: {
116
+ field: string;
117
+ equals: null;
118
+ };
119
+ options: {
120
+ value: string;
121
+ label: string;
122
+ }[];
123
+ valueType?: undefined;
102
124
  emptyOption?: undefined;
103
125
  emptyValue?: undefined;
104
126
  widthPlaceholder?: undefined;
@@ -113,6 +135,7 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
113
135
  label: string;
114
136
  options?: undefined;
115
137
  visibleWhen?: undefined;
138
+ valueType?: undefined;
116
139
  emptyOption?: undefined;
117
140
  emptyValue?: undefined;
118
141
  widthPlaceholder?: undefined;
@@ -129,6 +152,7 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
129
152
  heightPlaceholder: string;
130
153
  options?: undefined;
131
154
  visibleWhen?: undefined;
155
+ valueType?: undefined;
132
156
  emptyOption?: undefined;
133
157
  emptyValue?: undefined;
134
158
  topLeftKey?: undefined;
@@ -145,6 +169,7 @@ export declare const PHI_IMAGE_WIDGET_DEFINITION: {
145
169
  bottomRightKey: string;
146
170
  options?: undefined;
147
171
  visibleWhen?: undefined;
172
+ valueType?: undefined;
148
173
  emptyOption?: undefined;
149
174
  emptyValue?: undefined;
150
175
  widthPlaceholder?: undefined;
@@ -66,8 +66,12 @@ export function normalizePhiImageWidgetConfig(config) {
66
66
  borderBottomRightRadius: readCssSize(raw.borderBottomRightRadius),
67
67
  mask: normalizePhiMaskConfig(raw.mask),
68
68
  };
69
+ /*
70
+ * An Asset without a word about its variant gets the Card variant; `null` is a word -- the Inspector's
71
+ * Original -- and stays. Read from the raw config, because the source parser answers `null` for both.
72
+ */
69
73
  return source.sourceKind === "asset"
70
- ? { ...normalized, ...source, variantKey: source.variantKey ?? PhiImageAssetVariantKey.Card }
74
+ ? { ...normalized, ...source, variantKey: raw.variantKey === null ? null : source.variantKey ?? PhiImageAssetVariantKey.Card }
71
75
  : { ...normalized, ...source };
72
76
  }
73
77
  function parsePhiCmsImageWidgetConfig(config) {
@@ -108,6 +112,7 @@ export const PHI_IMAGE_WIDGET_DEFINITION = {
108
112
  {
109
113
  key: "variantKey",
110
114
  type: "choice",
115
+ valueType: "number",
111
116
  label: "Variant",
112
117
  options: PHI_IMAGE_VARIANT_OPTIONS,
113
118
  emptyOption: { value: "__original__", label: "Original" },
@@ -116,17 +121,29 @@ export const PHI_IMAGE_WIDGET_DEFINITION = {
116
121
  },
117
122
  { key: "alt", type: "string", label: "Alt Text", visibleWhen: { field: "sourceKind", equals: "url" } },
118
123
  { key: "title", type: "string", label: "Title", visibleWhen: { field: "sourceKind", equals: "url" } },
124
+ /*
125
+ * Fit and position steer only the original picture, an Asset's or a URL's. A variant is cut to its
126
+ * own fit, and its position comes from the Asset's focal rectangle, so with a variant chosen both
127
+ * would be settings that change nothing. A URL clears the variant, so one rule covers both cases.
128
+ */
119
129
  {
120
130
  key: "fit",
121
131
  type: "choice",
122
132
  label: "Fit",
133
+ visibleWhen: { field: "variantKey", equals: null },
123
134
  options: [
124
135
  { value: "cover", label: "Cover" },
125
136
  { value: "contain", label: "Contain" },
126
137
  { value: "fill", label: "Fill" },
127
138
  ],
128
139
  },
129
- { key: "objectPosition", type: "choice", label: "Object Position", options: IMAGE_OBJECT_POSITION_OPTIONS },
140
+ {
141
+ key: "objectPosition",
142
+ type: "choice",
143
+ label: "Object Position",
144
+ options: IMAGE_OBJECT_POSITION_OPTIONS,
145
+ visibleWhen: { field: "variantKey", equals: null },
146
+ },
130
147
  {
131
148
  key: "previewMode",
132
149
  type: "choice",
@@ -76,7 +76,7 @@ export function PhiImageWidgetEditor({ config, onChange }) {
76
76
  }, children: overlaySize })) : null] }));
77
77
  }
78
78
  export function PhiImageWidgetEditorTools({ blockId, config, onChange, }) {
79
- return (_jsxs("span", { style: { display: "inline-flex" }, children: [_jsx(PhiWidgetImageToolButton, { blockId: blockId, onChange: (patch) => onChange?.(patch) }), _jsx(PhiMaskPickerButton, { value: config?.mask, onChange: (mask) => {
79
+ return (_jsxs("span", { style: { display: "inline-flex" }, children: [_jsx(PhiWidgetImageToolButton, { blockId: blockId, onChange: (patch) => onChange?.(patch) }), _jsx(PhiMaskPickerButton, { placement: "topRight", value: config?.mask, onChange: (mask) => {
80
80
  onChange?.({ mask });
81
81
  } })] }));
82
82
  }
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { PhiCmsFlags } from "../../../../../constants/phi-cms";
3
3
  import { hasPhiFlag } from "../../../../../helpers/flags";
4
- import { tr } from "../../../../../server-helpers/translate";
4
+ import { trForLocale } from "../../../../../server-helpers/translate";
5
5
  import { PhiCmsWidgetType } from "../../../../../constants/cms-widget-types";
6
6
  import { parsePhiCmsMarkdownWidgetConfig } from "../markdown/config";
7
7
  import { PhiRuntimeModuleRenderClientHost } from "../../../../../components/runtime/runtime-module-render-client-manifest";
@@ -25,7 +25,12 @@ function filterHeadings(headings, config) {
25
25
  return headings.filter((heading) => heading.level >= minLevel && heading.level <= maxLevel);
26
26
  }
27
27
  export async function PhiMarkdownTocWidget({ config, defaultLabels, tree, runtime, }) {
28
- const title = await tr(config?.title?.trim() || defaultLabels.title);
28
+ /*
29
+ * The author's title in the render's locale; the default is a label set's and arrives translated, so
30
+ * asking for it again would hand a translator text that is no longer in the source language.
31
+ */
32
+ const ownTitle = config?.title?.trim();
33
+ const title = ownTitle ? await trForLocale(runtime.locale.current, ownTitle) : defaultLabels.title;
29
34
  const targetWidget = resolveTargetMarkdownWidget(tree, config);
30
35
  if (!targetWidget) {
31
36
  return (_jsx(PhiRuntimeModuleRenderClientHost, { type: PhiCmsWidgetType.MarkdownToc, componentProps: { config: { ...config, title, headings: [] } } }));
@@ -1,9 +1,12 @@
1
+ import { type PhiTextSource } from "../../../../../helpers/text-source";
1
2
  import { type PhiCmsWidgetConfigBase } from "../../../../../components/widgets/config/parser-primitives";
2
3
  export type PhiCmsQuickLinksWidgetConfig = PhiCmsWidgetConfigBase & {
3
4
  navKey?: string;
4
5
  title?: string;
5
6
  columns?: 1 | 2 | 3;
6
7
  separator?: boolean;
8
+ /** `"preset"` while the words are a Preset's and translated globally (`helpers/text-source.ts`). */
9
+ textSource?: PhiTextSource;
7
10
  };
8
11
  declare function parsePhiCmsQuickLinksWidgetConfig(config: Record<string, unknown>): PhiCmsQuickLinksWidgetConfig;
9
12
  export declare const PHI_QUICK_LINKS_WIDGET_DEFINITION: {
@@ -1,4 +1,5 @@
1
1
  import { resolvePhiCmsWidgetPluginKey } from "../../../../../constants/cms-widget-types";
2
+ import { readPhiTextSource } from "../../../../../helpers/text-source";
2
3
  import { PhiCmsWidgetType } from "../../../../../constants/cms-widget-types";
3
4
  import { PHI_AUTHORING_OPTION_PROVIDER_KEYS } from "../../../../../constants/authoring-option-provider-keys";
4
5
  import { readBoolean, readNumber, readRenderableBlockConfig, readString, } from "../../../../../components/widgets/config/parser-primitives";
@@ -11,6 +12,7 @@ function parsePhiCmsQuickLinksWidgetConfig(config) {
11
12
  title: readString(config.title),
12
13
  columns: columns === 1 || columns === 3 ? columns : 2,
13
14
  separator: readBoolean(config.separator) ?? true,
15
+ textSource: readPhiTextSource(config.textSource),
14
16
  };
15
17
  }
16
18
  export const PHI_QUICK_LINKS_WIDGET_DEFINITION = {
@@ -1,9 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { PhiCmsFlags } from "../../../../../constants/phi-cms";
3
+ import { hasPhiFlag } from "../../../../../helpers/flags";
2
4
  import { PhiQuickLinksWidget } from "./server";
3
5
  import { PHI_QUICK_LINKS_WIDGET_DEFINITION, PHI_QUICK_LINKS_WIDGET_PLUGIN_TYPE, } from "./config";
4
6
  export const PHI_QUICK_LINKS_WIDGET_PLUGIN = {
5
7
  ...PHI_QUICK_LINKS_WIDGET_DEFINITION,
6
- render: ({ widget, runtime, config }) => (_jsx(PhiQuickLinksWidget, { runtime: runtime, navKey: config.navKey, title: config.title, columns: config.columns, separator: config.separator }, `widget-${widget.id}`)),
7
- renderPreview: ({ widget, runtime, config }) => (_jsx(PhiQuickLinksWidget, { runtime: runtime, navKey: config.navKey, title: config.title, columns: config.columns, separator: config.separator, interactive: false }, `widget-${widget.id}`)),
8
+ render: ({ widget, runtime, config }) => (_jsx(PhiQuickLinksWidget, { runtime: runtime, navKey: config.navKey, title: config.title, textSource: config.textSource, translate: !hasPhiFlag(widget.flags, PhiCmsFlags.NoTranslate), columns: config.columns, separator: config.separator }, `widget-${widget.id}`)),
9
+ renderPreview: ({ widget, runtime, config }) => (_jsx(PhiQuickLinksWidget, { runtime: runtime, navKey: config.navKey, title: config.title, textSource: config.textSource, translate: !hasPhiFlag(widget.flags, PhiCmsFlags.NoTranslate), columns: config.columns, separator: config.separator, interactive: false }, `widget-${widget.id}`)),
8
10
  };
9
11
  export { PHI_QUICK_LINKS_WIDGET_PLUGIN_TYPE };
@@ -1,10 +1,14 @@
1
1
  import type { PhiBlockRuntime } from "../../../../../types";
2
+ import type { PhiTextSource } from "../../../../../helpers/text-source";
2
3
  export type PhiQuickLinksWidgetProps = {
3
4
  runtime: Pick<PhiBlockRuntime, "site" | "locale" | "area" | "viewer" | "request">;
4
5
  navKey?: string;
5
6
  title?: string;
7
+ /** Whose words the title is, which decides the store that translates it. */
8
+ textSource?: PhiTextSource;
9
+ translate?: boolean;
6
10
  columns?: 1 | 2 | 3;
7
11
  separator?: boolean;
8
12
  interactive?: boolean;
9
13
  };
10
- export declare function PhiQuickLinksWidget({ runtime, navKey, title, columns, separator, interactive, }: PhiQuickLinksWidgetProps): Promise<import("react").JSX.Element | null>;
14
+ export declare function PhiQuickLinksWidget({ runtime, navKey, title, textSource, translate, columns, separator, interactive, }: PhiQuickLinksWidgetProps): Promise<import("react").JSX.Element | null>;
@@ -3,15 +3,17 @@ import { PhiCmsWidgetType } from "../../../../../constants/cms-widget-types";
3
3
  import { PhiRuntimeModuleRenderClientHost } from "../../../../../components/runtime/runtime-module-render-client-manifest";
4
4
  import { resolvePhiNavigationItems } from "../../../../../components/widgets/server/navigation-request";
5
5
  import { mapPhiNavItemsToQuickLinksItems } from "./items";
6
- export async function PhiQuickLinksWidget({ runtime, navKey, title, columns = 2, separator = true, interactive = true, }) {
6
+ import { trWidgetText } from "../../../../../server-helpers/translate";
7
+ export async function PhiQuickLinksWidget({ runtime, navKey, title, textSource, translate = true, columns = 2, separator = true, interactive = true, }) {
7
8
  const resolvedNavKey = navKey?.trim() ||
8
9
  `${runtime.area}:footer`;
9
10
  const resolvedNavigationItems = (await resolvePhiNavigationItems(runtime, resolvedNavKey)) ?? [];
10
11
  if (resolvedNavigationItems.length === 0) {
11
12
  return null;
12
13
  }
14
+ const ownTitle = title?.trim();
13
15
  const labels = {
14
- title,
16
+ title: ownTitle && translate ? await trWidgetText(runtime.locale.current, ownTitle, textSource) : title,
15
17
  };
16
18
  const config = {
17
19
  columns,
@@ -74,6 +74,7 @@ export declare const PHI_RESULT_WIDGET_DEFINITION: {
74
74
  } & {
75
75
  type: "data-provider";
76
76
  providerKind?: import("../../../../../types").PhiRuntimeDataProviderKind;
77
+ providerKey?: import("@phis/contracts/controls").PhiRuntimeDataProviderKey;
77
78
  }) | ({
78
79
  key: string;
79
80
  label: string;
@@ -247,10 +248,33 @@ export declare const PHI_RESULT_WIDGET_DEFINITION: {
247
248
  editorPlacement?: "inspector" | "geometry" | "toolbar";
248
249
  visibleWhen?: import("../../../../../types").PhiCmsConfigFieldVisibilityRule | readonly import("../../../../../types").PhiCmsConfigFieldVisibilityRule[];
249
250
  heading?: string;
251
+ } & {
252
+ type: "choice";
253
+ valueType: "number";
254
+ options: import("@phis/contracts/controls").PhiControlOption<number>[];
255
+ emptyOption?: import("@phis/contracts/controls").PhiControlOption;
256
+ emptyValue?: null | undefined;
257
+ placeholder?: string;
258
+ mode?: never;
259
+ presentation?: never;
260
+ optionsProvider?: never;
261
+ allowCustom?: never;
262
+ createBehavior?: never;
263
+ filter?: never;
264
+ patchOnChange?: never;
265
+ optionPresets?: never;
266
+ }) | ({
267
+ key: string;
268
+ label: string;
269
+ description?: string;
270
+ required?: boolean;
271
+ editorPlacement?: "inspector" | "geometry" | "toolbar";
272
+ visibleWhen?: import("../../../../../types").PhiCmsConfigFieldVisibilityRule | readonly import("../../../../../types").PhiCmsConfigFieldVisibilityRule[];
273
+ heading?: string;
250
274
  } & {
251
275
  type: "choice";
252
276
  mode?: import("../../../../../types").PhiCmsConfigFieldChoiceMode;
253
- valueType?: import("../../../../../types").PhiCmsConfigFieldChoiceValueType;
277
+ valueType?: Exclude<import("../../../../../types").PhiCmsConfigFieldChoiceValueType, "number">;
254
278
  presentation?: import("../../../../../types").PhiCmsConfigFieldChoicePresentation;
255
279
  options?: import("@phis/contracts/controls").PhiControlOption[];
256
280
  optionsProvider?: import("@phis/contracts/controls").PhiControlOptionsProviderConfig;
@@ -1,3 +1,4 @@
1
+ import { type PhiTextSource } from "../../../../../helpers/text-source";
1
2
  import { type PhiSimpleTextMark } from "../../../../../types/core-widget-placements";
2
3
  import type { PhiCmsResolvedContent } from "../../../../../types";
3
4
  import type { PhiWidgetFontFamilyKey, PhiWidgetFontSizeKey } from "../../../../../types/site-theme";
@@ -15,6 +16,8 @@ export type PhiCmsSimpleTextWidgetConfig = PhiCmsWidgetConfigBase & {
15
16
  tone?: PhiTextTone;
16
17
  marks?: PhiSimpleTextMark[];
17
18
  disabled?: boolean;
19
+ /** `"preset"` while the words are a Preset's and translated globally (`helpers/text-source.ts`). */
20
+ textSource?: PhiTextSource;
18
21
  };
19
22
  declare function parsePhiCmsSimpleTextWidgetConfig(config: Record<string, unknown>): PhiCmsSimpleTextWidgetConfig;
20
23
  export type PhiSimpleTextWidgetRenderableConfig = PhiCmsSimpleTextWidgetConfig & {
@@ -79,6 +82,7 @@ export declare const PHI_SIMPLE_TEXT_WIDGET_DEFINITION: {
79
82
  } & {
80
83
  type: "data-provider";
81
84
  providerKind?: import("../../../../../types").PhiRuntimeDataProviderKind;
85
+ providerKey?: import("@phis/contracts/controls").PhiRuntimeDataProviderKey;
82
86
  }) | ({
83
87
  key: string;
84
88
  label: string;
@@ -252,10 +256,33 @@ export declare const PHI_SIMPLE_TEXT_WIDGET_DEFINITION: {
252
256
  editorPlacement?: "inspector" | "geometry" | "toolbar";
253
257
  visibleWhen?: import("../../../../../types").PhiCmsConfigFieldVisibilityRule | readonly import("../../../../../types").PhiCmsConfigFieldVisibilityRule[];
254
258
  heading?: string;
259
+ } & {
260
+ type: "choice";
261
+ valueType: "number";
262
+ options: import("@phis/contracts/controls").PhiControlOption<number>[];
263
+ emptyOption?: import("@phis/contracts/controls").PhiControlOption;
264
+ emptyValue?: null | undefined;
265
+ placeholder?: string;
266
+ mode?: never;
267
+ presentation?: never;
268
+ optionsProvider?: never;
269
+ allowCustom?: never;
270
+ createBehavior?: never;
271
+ filter?: never;
272
+ patchOnChange?: never;
273
+ optionPresets?: never;
274
+ }) | ({
275
+ key: string;
276
+ label: string;
277
+ description?: string;
278
+ required?: boolean;
279
+ editorPlacement?: "inspector" | "geometry" | "toolbar";
280
+ visibleWhen?: import("../../../../../types").PhiCmsConfigFieldVisibilityRule | readonly import("../../../../../types").PhiCmsConfigFieldVisibilityRule[];
281
+ heading?: string;
255
282
  } & {
256
283
  type: "choice";
257
284
  mode?: import("../../../../../types").PhiCmsConfigFieldChoiceMode;
258
- valueType?: import("../../../../../types").PhiCmsConfigFieldChoiceValueType;
285
+ valueType?: Exclude<import("../../../../../types").PhiCmsConfigFieldChoiceValueType, "number">;
259
286
  presentation?: import("../../../../../types").PhiCmsConfigFieldChoicePresentation;
260
287
  options?: import("@phis/contracts/controls").PhiControlOption[];
261
288
  optionsProvider?: import("@phis/contracts/controls").PhiControlOptionsProviderConfig;