@phis/ui 0.3.0 → 0.4.0
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 +1 -1
- package/components/controls/phi-collection-header-control.js +1 -1
- package/components/controls/phi-collection-view-control.js +2 -1
- package/components/controls/phi-drawer-control-adapter.d.ts +1 -1
- package/components/controls/phi-drawer-control-adapter.js +2 -2
- package/components/controls/phi-image-control.d.ts +6 -1
- package/components/controls/phi-image-control.js +23 -4
- package/components/controls/phi-lightbox-image-control-adapter.d.ts +2 -0
- package/components/controls/phi-lightbox-image-control-adapter.js +11 -0
- package/components/controls/phi-lightbox-image-control.d.ts +3 -2
- package/components/controls/phi-lightbox-image-control.js +7 -3
- package/components/controls/phi-modal-control-adapter.d.ts +1 -1
- package/components/controls/phi-modal-control-adapter.js +5 -2
- package/components/controls/phi-overlay-control-contract.d.ts +5 -0
- package/components/controls/phi-pagination-control-adapter.d.ts +2 -0
- package/components/controls/phi-pagination-control-adapter.js +15 -0
- package/components/controls/phi-pagination-control.d.ts +2 -1
- package/components/controls/phi-pagination-control.js +11 -7
- package/components/controls/phi-table-control.js +1 -1
- package/components/controls/phi-timeline-control-adapter.d.ts +2 -0
- package/components/controls/phi-timeline-control-adapter.js +28 -0
- package/components/controls/phi-timeline-control.d.ts +3 -1
- package/components/controls/phi-timeline-control.js +8 -22
- package/components/controls/phi-tour-control.js +25 -7
- package/components/controls/phi-tour-viewport.d.ts +36 -0
- package/components/controls/phi-tour-viewport.js +86 -0
- package/components/controls/phi-zoom-image-overlay.d.ts +17 -0
- package/components/controls/phi-zoom-image-overlay.js +58 -0
- package/components/layouts/layout-definitions.d.ts +0 -18
- package/components/layouts/layout-definitions.js +7 -1
- package/components/layouts/plugins/carousel-layout-plugin.js +2 -1
- package/components/media/aspect-ratios.d.ts +14 -0
- package/components/media/aspect-ratios.js +13 -0
- package/components/motion/phi-sequence-run.d.ts +27 -0
- package/components/motion/phi-sequence-run.js +87 -0
- package/components/motion/phi-sequence-viewport.d.ts +16 -0
- package/components/motion/phi-sequence-viewport.js +97 -34
- package/components/overlays/phi-overlay-container-client.js +5 -2
- package/components/runtime/runtime-visual-anchors.d.ts +13 -2
- package/components/runtime/runtime-visual-anchors.js +49 -3
- package/components/widgets/config/image-variant-options.d.ts +3 -5
- package/components/widgets/config/image-variant-options.js +11 -11
- package/components/widgets/config/sequence-settings.d.ts +75 -0
- package/components/widgets/config/sequence-settings.js +173 -0
- package/components/widgets/label-sets/content-entries.d.ts +9 -0
- package/components/widgets/label-sets/content-entries.js +17 -0
- package/components/widgets/label-types/gallery.d.ts +2 -10
- package/components/widgets/label-types/sequence.d.ts +18 -0
- package/components/widgets/label-types/sequence.js +1 -0
- package/helpers/cms-layout-defaults.js +9 -2
- package/helpers/cms-region-keys.d.ts +1 -1
- package/helpers/motion.d.ts +7 -0
- package/helpers/motion.js +7 -0
- package/package.json +1 -1
- package/plugins/runtime-modules/asset/data-providers.d.ts +4 -0
- package/plugins/runtime-modules/asset/data-providers.js +1 -0
- package/plugins/runtime-modules/asset/definition.d.ts +4 -0
- package/plugins/runtime-modules/asset/presets.d.ts +53 -1
- package/plugins/runtime-modules/asset/presets.js +16 -12
- package/plugins/runtime-modules/asset/tour.d.ts +44 -0
- package/plugins/runtime-modules/asset/tour.js +53 -0
- package/plugins/runtime-modules/builder/clients/inspector-config-field.js +42 -18
- package/plugins/runtime-modules/builder/clients/inspector-image-field.js +2 -2
- package/plugins/runtime-modules/builder/clients/workspace-scope-boundary.js +10 -0
- package/plugins/runtime-modules/builder/controller/workspace-controller.js +18 -3
- package/plugins/runtime-modules/builder/plugin-meta-labels.js +8 -0
- package/plugins/runtime-modules/builder/presets.js +5 -3
- package/plugins/runtime-modules/builder/tour.d.ts +316 -0
- package/plugins/runtime-modules/builder/tour.js +337 -0
- package/plugins/runtime-modules/builder/trees/phi-builder-inspector-area-overlay-tree.server.js +8 -1
- package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +3 -2
- package/plugins/runtime-modules/core/widgets/collection-view/client.js +10 -0
- package/plugins/runtime-modules/core/widgets/description/config.d.ts +25 -1
- package/plugins/runtime-modules/core/widgets/entry-detail/config.d.ts +2 -0
- package/plugins/runtime-modules/core/widgets/entry-detail/config.js +8 -1
- package/plugins/runtime-modules/core/widgets/entry-header/config.d.ts +3 -0
- package/plugins/runtime-modules/core/widgets/entry-header/config.js +8 -1
- package/plugins/runtime-modules/core/widgets/entry-list/client.d.ts +4 -1
- package/plugins/runtime-modules/core/widgets/entry-list/client.js +3 -2
- package/plugins/runtime-modules/core/widgets/entry-list/config.d.ts +392 -93
- package/plugins/runtime-modules/core/widgets/entry-list/config.js +21 -3
- package/plugins/runtime-modules/core/widgets/entry-list/server.js +2 -0
- package/plugins/runtime-modules/core/widgets/gallery/authoring.js +62 -10
- package/plugins/runtime-modules/core/widgets/gallery/client.d.ts +6 -1
- package/plugins/runtime-modules/core/widgets/gallery/client.js +7 -79
- package/plugins/runtime-modules/core/widgets/gallery/config.d.ts +337 -144
- package/plugins/runtime-modules/core/widgets/gallery/config.js +52 -113
- package/plugins/runtime-modules/core/widgets/gallery/defaults.d.ts +15 -0
- package/plugins/runtime-modules/core/widgets/gallery/defaults.js +20 -0
- package/plugins/runtime-modules/core/widgets/image/client.js +1 -1
- package/plugins/runtime-modules/core/widgets/image/config.d.ts +29 -4
- package/plugins/runtime-modules/core/widgets/image/config.js +19 -2
- package/plugins/runtime-modules/core/widgets/image/editor.js +1 -1
- package/plugins/runtime-modules/core/widgets/result/config.d.ts +25 -1
- package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +25 -1
- package/plugins/runtime-modules/core/widgets/table/config.d.ts +79 -3
- package/plugins/runtime-modules/core/widgets/tour-button/client.js +1 -1
- package/plugins/runtime-modules/revisions/presets.d.ts +53 -2
- package/plugins/runtime-modules/revisions/presets.js +16 -12
- package/plugins/runtime-modules/revisions/tour.d.ts +43 -0
- package/plugins/runtime-modules/revisions/tour.js +51 -0
- package/plugins/runtime-modules/theme/presets.d.ts +36 -4
- package/plugins/runtime-modules/theme/tour.d.ts +45 -11
- package/plugins/runtime-modules/theme/tour.js +39 -8
- package/plugins/runtime-modules/tour/controller/address.js +2 -2
- package/plugins/runtime-modules/tour/controller/client.js +43 -2
- package/plugins/runtime-modules/tour/controller/definition.js +2 -1
- package/server-helpers/cms-request.js +1 -0
- package/server-helpers/page-tour.d.ts +10 -3
- package/server-helpers/page-tour.js +25 -12
- package/types/cms-config.d.ts +3 -1
- package/types/cms-config.js +3 -3
- package/types/cms-plugins.d.ts +31 -4
- package/types/tour-controller.d.ts +10 -0
- package/types/tour-controller.js +13 -0
- package/types/tours.d.ts +27 -25
- package/types/tours.js +9 -23
- package/types/visual-anchors.d.ts +15 -0
- package/types/visual-anchors.js +12 -0
- package/types.d.ts +2 -0
- package/types.js +4 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Media Tour. What the Page does not say is that it is the one library every picker of the Site
|
|
3
|
+
* draws from, and that what is set on an asset here -- its words, its folder, its focal rectangle -- goes
|
|
4
|
+
* wherever the asset is used. The Inspector is described rather than opened: it opens on an asset, and a
|
|
5
|
+
* Tour cannot know which assets a Site has.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PHI_ASSET_MEDIA_TOUR: {
|
|
8
|
+
readonly id: "@phis/ui/modules/asset/media";
|
|
9
|
+
readonly version: 1;
|
|
10
|
+
readonly steps: readonly [{
|
|
11
|
+
readonly key: "find";
|
|
12
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:filters`;
|
|
13
|
+
readonly title: "Finding an asset";
|
|
14
|
+
readonly description: "Kind narrows the library to images or other files, Flags to assets marked Featured, Locked, Mask or Background, Folder to one folder. The plus beside Folder creates a new folder. The search looks through file names, titles and alternative texts.";
|
|
15
|
+
readonly placement: "bottom";
|
|
16
|
+
readonly ifMissing: "skip";
|
|
17
|
+
}, {
|
|
18
|
+
readonly key: "upload";
|
|
19
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:toolbar`;
|
|
20
|
+
readonly title: "Adding files";
|
|
21
|
+
readonly description: "Upload opens a field to drop files into. They arrive in the folder and with the flags chosen in the filters, so choosing the folder first saves sorting later. Reset clears the filters, Reload fetches the library again.";
|
|
22
|
+
readonly placement: "bottom";
|
|
23
|
+
readonly ifMissing: "skip";
|
|
24
|
+
}, {
|
|
25
|
+
readonly key: "library";
|
|
26
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:items`;
|
|
27
|
+
readonly title: "The Site's library";
|
|
28
|
+
readonly description: "Every image and file the Site has, newest first. It is the same library every image picker of the Site opens, so what is uploaded here can be placed anywhere.";
|
|
29
|
+
readonly placement: "top";
|
|
30
|
+
}, {
|
|
31
|
+
readonly key: "inspector";
|
|
32
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:items`;
|
|
33
|
+
readonly title: "What an asset says about itself";
|
|
34
|
+
readonly description: "A click on an asset opens its Inspector: its folder, its title, the alternative text read out to those who cannot see it, its flags, and the focal rectangle -- the part of a picture that stays in view when a variant cuts it to another shape. Saved there, it applies wherever the asset is used.";
|
|
35
|
+
readonly placement: "top";
|
|
36
|
+
}, {
|
|
37
|
+
readonly key: "pages";
|
|
38
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:pagination`;
|
|
39
|
+
readonly title: "Page by page";
|
|
40
|
+
readonly description: "The library is shown a page at a time; how many fit on one is chosen here.";
|
|
41
|
+
readonly placement: "top";
|
|
42
|
+
readonly ifMissing: "skip";
|
|
43
|
+
}];
|
|
44
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { PHI_ASSET_RUNTIME_MODULE_ID } from "./ids";
|
|
2
|
+
import { PHI_ASSET_MEDIA_PAGE_WIDGET_IDS } from "./media-page-ids";
|
|
3
|
+
const LIBRARY_ID = PHI_ASSET_MEDIA_PAGE_WIDGET_IDS.widgetMediaPreview;
|
|
4
|
+
/**
|
|
5
|
+
* The Media Tour. What the Page does not say is that it is the one library every picker of the Site
|
|
6
|
+
* draws from, and that what is set on an asset here -- its words, its folder, its focal rectangle -- goes
|
|
7
|
+
* wherever the asset is used. The Inspector is described rather than opened: it opens on an asset, and a
|
|
8
|
+
* Tour cannot know which assets a Site has.
|
|
9
|
+
*/
|
|
10
|
+
export const PHI_ASSET_MEDIA_TOUR = {
|
|
11
|
+
id: `${PHI_ASSET_RUNTIME_MODULE_ID}/media`,
|
|
12
|
+
version: 1,
|
|
13
|
+
steps: [
|
|
14
|
+
{
|
|
15
|
+
key: "find",
|
|
16
|
+
target: `cms:${LIBRARY_ID}:filters`,
|
|
17
|
+
title: "Finding an asset",
|
|
18
|
+
description: "Kind narrows the library to images or other files, Flags to assets marked Featured, Locked, Mask or Background, Folder to one folder. The plus beside Folder creates a new folder. The search looks through file names, titles and alternative texts.",
|
|
19
|
+
placement: "bottom",
|
|
20
|
+
ifMissing: "skip",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
key: "upload",
|
|
24
|
+
target: `cms:${LIBRARY_ID}:toolbar`,
|
|
25
|
+
title: "Adding files",
|
|
26
|
+
description: "Upload opens a field to drop files into. They arrive in the folder and with the flags chosen in the filters, so choosing the folder first saves sorting later. Reset clears the filters, Reload fetches the library again.",
|
|
27
|
+
placement: "bottom",
|
|
28
|
+
ifMissing: "skip",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: "library",
|
|
32
|
+
target: `cms:${LIBRARY_ID}:items`,
|
|
33
|
+
title: "The Site's library",
|
|
34
|
+
description: "Every image and file the Site has, newest first. It is the same library every image picker of the Site opens, so what is uploaded here can be placed anywhere.",
|
|
35
|
+
placement: "top",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: "inspector",
|
|
39
|
+
target: `cms:${LIBRARY_ID}:items`,
|
|
40
|
+
title: "What an asset says about itself",
|
|
41
|
+
description: "A click on an asset opens its Inspector: its folder, its title, the alternative text read out to those who cannot see it, its flags, and the focal rectangle -- the part of a picture that stays in view when a variant cuts it to another shape. Saved there, it applies wherever the asset is used.",
|
|
42
|
+
placement: "top",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: "pages",
|
|
46
|
+
target: `cms:${LIBRARY_ID}:pagination`,
|
|
47
|
+
title: "Page by page",
|
|
48
|
+
description: "The library is shown a page at a time; how many fit on one is chosen here.",
|
|
49
|
+
placement: "top",
|
|
50
|
+
ifMissing: "skip",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
@@ -314,6 +314,21 @@ function resolveInspectorChoiceOptions(field, widgetReferenceOptions, resolvedOp
|
|
|
314
314
|
}
|
|
315
315
|
return resolvedOptions;
|
|
316
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* A closed list of numbers. The select holds the numbers themselves, so what is picked is what is
|
|
319
|
+
* stored; only the empty line is a word, and it stands for `emptyValue`.
|
|
320
|
+
*/
|
|
321
|
+
function renderPhiInspectorNumberChoiceField({ field, value, defaultValue, disabled, onChange, }) {
|
|
322
|
+
const stored = value ?? defaultValue;
|
|
323
|
+
const emptyOptionValue = field.emptyOption?.value;
|
|
324
|
+
const selectedValue = typeof stored === "number" ? stored : emptyOptionValue;
|
|
325
|
+
const options = field.emptyOption
|
|
326
|
+
? [field.emptyOption, ...field.options]
|
|
327
|
+
: field.options;
|
|
328
|
+
return renderPhiInspectorConfigFieldControl(field, _jsx(PhiSelectControl, { options: options, placeholder: field.placeholder, value: selectedValue, disabled: disabled, style: { width: "100%" }, onChange: (next) => onChange?.({
|
|
329
|
+
[field.key]: emptyOptionValue != null && next === emptyOptionValue ? field.emptyValue : next,
|
|
330
|
+
}) }));
|
|
331
|
+
}
|
|
317
332
|
function PhiInspectorChoiceFieldControl({ field, config, value, defaultValue, disabled, widgetReferenceOptions, labels, onChange, }) {
|
|
318
333
|
const staticOptions = useMemo(() => field.filter?.widgetType
|
|
319
334
|
? widgetReferenceOptions
|
|
@@ -524,7 +539,7 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
|
|
|
524
539
|
* other kinds are a Provider or nothing.
|
|
525
540
|
*/
|
|
526
541
|
const supportsStaticOptions = !field.providerKind || field.providerKind === "options" || field.providerKind === "timeline";
|
|
527
|
-
const selectedProvider = dataProviderDescriptors.find((descriptor) => descriptor.key === providerConfig?.providerKey) ?? null;
|
|
542
|
+
const selectedProvider = dataProviderDescriptors.find((descriptor) => descriptor.key === (field.providerKey ?? providerConfig?.providerKey)) ?? null;
|
|
528
543
|
const options = [
|
|
529
544
|
...(supportsStaticOptions
|
|
530
545
|
? [{
|
|
@@ -540,7 +555,7 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
|
|
|
540
555
|
description: descriptor.description,
|
|
541
556
|
})),
|
|
542
557
|
];
|
|
543
|
-
|
|
558
|
+
const bindingRow = renderPhiInspectorConfigFieldControl(field, _jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%" }, children: [_jsx(PhiSelectControl, { options: options, placeholder: fieldLabels.selectDataProvider, value: providerConfig?.providerKey ?? (supportsStaticOptions ? PHI_STATIC_OPTIONS_PROVIDER_VALUE : undefined), disabled: disabled || !onChange, style: { width: "100%" }, onChange: (providerKey) => onChange?.({
|
|
544
559
|
[field.key]: providerKey === PHI_STATIC_OPTIONS_PROVIDER_VALUE
|
|
545
560
|
? null
|
|
546
561
|
: field.providerKind === "table" || field.providerKind === "tree" || field.providerKind === "collection"
|
|
@@ -575,22 +590,28 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
|
|
|
575
590
|
resourceKey,
|
|
576
591
|
params: isPhiRecord(rawProviderConfig.params) ? rawProviderConfig.params : undefined,
|
|
577
592
|
},
|
|
578
|
-
}) })) : null
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
593
|
+
}) })) : null] }));
|
|
594
|
+
if (field.providerKind !== "record" || !selectedProvider)
|
|
595
|
+
return bindingRow;
|
|
596
|
+
/*
|
|
597
|
+
* A record is one thing, named by its parameters -- an entry by kind and address -- and the
|
|
598
|
+
* Provider says which it takes in its `settingsFields`. They are rows of their own under the
|
|
599
|
+
* binding, words on the left like every other field; inside the binding's control column they
|
|
600
|
+
* would draw a second pair of columns squeezed into the first one's right half. A binding fixed
|
|
601
|
+
* to one Provider shows only them.
|
|
602
|
+
*/
|
|
603
|
+
const params = isPhiRecord(rawProviderConfig.params) ? rawProviderConfig.params : {};
|
|
604
|
+
return (_jsxs(Fragment, { children: [field.providerKey ? null : bindingRow, (selectedProvider.settingsFields ?? []).map((paramField) => (_jsx(Fragment, { children: renderPhiInspectorConfigField({
|
|
605
|
+
field: paramField,
|
|
606
|
+
value: params[paramField.key],
|
|
607
|
+
defaultValue: undefined,
|
|
608
|
+
config: params,
|
|
609
|
+
disabled,
|
|
610
|
+
fieldLabels,
|
|
611
|
+
onChange: (patch) => onChange?.({
|
|
612
|
+
[field.key]: { providerKey: selectedProvider.key, params: { ...params, ...patch } },
|
|
613
|
+
}),
|
|
614
|
+
}) }, paramField.key)))] }, field.key));
|
|
594
615
|
}
|
|
595
616
|
if (field.type === "calendar-adapter") {
|
|
596
617
|
return renderPhiInspectorConfigFieldControl(field, _jsx(PhiSelectControl, { options: calendarAdapterDescriptors.map((descriptor) => ({
|
|
@@ -692,6 +713,9 @@ function renderPhiInspectorConfigFieldBody({ field, value, defaultValue, config,
|
|
|
692
713
|
...(onChange ? { onChange: (checked) => onChange({ [field.key]: checked }) } : {}),
|
|
693
714
|
});
|
|
694
715
|
}
|
|
716
|
+
if (field.type === "choice" && field.valueType === "number") {
|
|
717
|
+
return renderPhiInspectorNumberChoiceField({ field, value, defaultValue, disabled: disabled || !onChange, onChange });
|
|
718
|
+
}
|
|
695
719
|
if (field.type === "choice") {
|
|
696
720
|
return (_jsx(PhiInspectorChoiceFieldControl, { field: field, config: config, value: value, defaultValue: defaultValue, disabled: disabled || !onChange, widgetReferenceOptions: widgetReferenceOptions ?? [], labels: fieldLabels, onChange: onChange }, field.key));
|
|
697
721
|
}
|
|
@@ -26,7 +26,7 @@ export function PhiInspectorImageFieldControl({ config, blockId, disabled, onCha
|
|
|
26
26
|
const assetId = config.sourceKind === "asset" && typeof config.assetId === "number" ? config.assetId : null;
|
|
27
27
|
const asset = usePhiAuthoringAssetDetails(assetId);
|
|
28
28
|
const sourceUrl = typeof config.sourceUrl === "string" ? config.sourceUrl : "";
|
|
29
|
-
const variantKey = typeof config.variantKey === "number" ?
|
|
29
|
+
const variantKey = typeof config.variantKey === "number" ? config.variantKey : PHI_IMAGE_FIELD_ORIGINAL_VARIANT;
|
|
30
30
|
const editable = !disabled && onChange != null;
|
|
31
31
|
return (_jsxs(PhiFlexControl, { vertical: true, gap: 8, style: { width: "100%", minWidth: 0 }, children: [_jsx(PhiMediaPickerBinding, { config: {
|
|
32
32
|
mediaType: PhiMediaKind.Image,
|
|
@@ -52,7 +52,7 @@ export function PhiInspectorImageFieldControl({ config, blockId, disabled, onCha
|
|
|
52
52
|
sourceUrl: undefined,
|
|
53
53
|
})
|
|
54
54
|
: undefined }), assetId != null ? (_jsx(PhiInspectorFieldRow, { label: "Variant", children: _jsx(PhiSelectControl, { value: variantKey, options: [{ value: PHI_IMAGE_FIELD_ORIGINAL_VARIANT, label: "Original", separator: "after" }, ...PHI_IMAGE_VARIANT_OPTIONS], disabled: !editable, style: { width: "100%" }, onChange: (next) => onChange?.({
|
|
55
|
-
variantKey: next === PHI_IMAGE_FIELD_ORIGINAL_VARIANT ? null :
|
|
55
|
+
variantKey: next === PHI_IMAGE_FIELD_ORIGINAL_VARIANT ? null : next,
|
|
56
56
|
}) }) })) : (_jsx(PhiInspectorFieldRow, { label: "URL", children: _jsx(PhiTextControl, { value: sourceUrl, inputType: "url", placeholder: "https://", disabled: !editable, style: { width: "100%" }, onChange: (next) => onChange?.({ sourceKind: "url", sourceUrl: next?.trim() || undefined }) }) })), _jsx(PhiInspectorFieldRow, { label: "Alt text", children: _jsx(PhiTextControl, { value: typeof config.alt === "string" ? config.alt : "",
|
|
57
57
|
/* An Asset brings its own; this replaces it for this placement only. */
|
|
58
58
|
placeholder: asset?.altText ?? undefined, disabled: !editable, style: { width: "100%" }, onChange: (next) => onChange?.({ alt: next || undefined }) }) })] }));
|
|
@@ -4,10 +4,20 @@ import { PhiBuilderWorkspacePreviewSkeleton } from "../../../../components/widge
|
|
|
4
4
|
import { usePhiDeveloperBuilderStateValue, } from "../developer-workspace-store";
|
|
5
5
|
import { PhiSignalRuntimePartitionProvider } from "../../../../components/runtime/runtime-signal-partition";
|
|
6
6
|
import { PhiBuilderCanvasRegionOverrides } from "./builder-region-overrides";
|
|
7
|
+
import { usePhiSignalIdentity } from "../../../../components/runtime/runtime-signal-identity";
|
|
8
|
+
import { usePhiVisualAnchorParts } from "../../../../components/runtime/runtime-visual-anchors";
|
|
9
|
+
import { PHI_BUILDER_PAGE_REGION_KEYS, PHI_BUILDER_SHELL_REGION_KEYS } from "../region-keys";
|
|
7
10
|
export function PhiBuilderWorkspaceScopeBoundary({ kind, targetArea, targetPageKey, children, }) {
|
|
8
11
|
const activeArea = usePhiDeveloperBuilderStateValue("public", (state) => state.area);
|
|
9
12
|
const activePageKey = usePhiDeveloperBuilderStateValue("public", (state) => state.pageKey);
|
|
10
13
|
const scopeMatches = activeArea === targetArea &&
|
|
11
14
|
(targetPageKey == null || activePageKey === targetPageKey);
|
|
15
|
+
/*
|
|
16
|
+
* Each Region on the canvas, offered to a Tour as `cms:<workspace>:<regionKey>`. Registered here, on
|
|
17
|
+
* this side of the canvas partition: the Tour looks in the Page's partition, and the canvas below runs
|
|
18
|
+
* in an isolated one of its own.
|
|
19
|
+
*/
|
|
20
|
+
const signalIdentity = usePhiSignalIdentity();
|
|
21
|
+
usePhiVisualAnchorParts(signalIdentity.receiver?.startsWith("cms:") ? signalIdentity.receiver : null, kind === "shells" ? PHI_BUILDER_SHELL_REGION_KEYS : PHI_BUILDER_PAGE_REGION_KEYS);
|
|
12
22
|
return scopeMatches ? (_jsx(PhiSignalRuntimePartitionProvider, { id: `canvas:${kind}:${targetArea}:${targetPageKey ?? "area"}`, kind: "canvas", context: { area: targetArea, pageKey: targetPageKey ?? null }, isolated: true, children: _jsx(PhiBuilderCanvasRegionOverrides, { children: children }) })) : _jsx(PhiBuilderWorkspacePreviewSkeleton, { kind: kind });
|
|
13
23
|
}
|
|
@@ -22,7 +22,7 @@ import { isPhiBuilderAreaKey, resolvePhiBuilderAreaAsCmsArea, } from "../../../.
|
|
|
22
22
|
import { resolvePhiRuntimeAreaDefinition } from "../../../../plugins/runtime-modules/area-definitions";
|
|
23
23
|
import { resolvePhiBuilderNavigationWidgetNavKey } from "../navigation-widget-runtime";
|
|
24
24
|
import { parsePhiBuilderNavigationScopeKey } from "../../../../helpers/cms-navigation-catalog";
|
|
25
|
-
import { builderWorkspaceStore, usePhiDeveloperBuilderWorkspaceState, completePhiDeveloperBuilderEffectsEditor, normalizePhiDeveloperBuilderArea as normalizeBuilderArea, previewPhiDeveloperBuilderEffects, resetPhiBuilderSelectionToPage, selectPhiDeveloperBuilderNode, usePhiDeveloperRegionDraft, getPhiDeveloperBuilderStateSnapshot, readPhiBuilderEffectiveAreaRootRoute, setPhiDeveloperBuilderAreaRootRoutes, setPhiDeveloperBuilderAreaMetaBaseline, setPhiDeveloperBuilderAreaControllerSettings, readPhiBuilderEffectiveAreaMeta, closePhiBuilderModuleDeactivationRequest, closePhiBuilderPublicRouteCollisionRequest, } from "../developer-workspace-store";
|
|
25
|
+
import { builderWorkspaceStore, usePhiDeveloperBuilderWorkspaceState, completePhiDeveloperBuilderEffectsEditor, normalizePhiDeveloperBuilderArea as normalizeBuilderArea, previewPhiDeveloperBuilderEffects, resetPhiBuilderSelectionToPage, selectPhiDeveloperBuilderNode, usePhiDeveloperRegionDraft, getPhiDeveloperBuilderStateSnapshot, getPhiDeveloperRegionDraftsSnapshot, readPhiBuilderEffectiveAreaRootRoute, setPhiDeveloperBuilderAreaRootRoutes, setPhiDeveloperBuilderAreaMetaBaseline, setPhiDeveloperBuilderAreaControllerSettings, readPhiBuilderEffectiveAreaMeta, closePhiBuilderModuleDeactivationRequest, closePhiBuilderPublicRouteCollisionRequest, } from "../developer-workspace-store";
|
|
26
26
|
import {} from "../options-providers";
|
|
27
27
|
import { PHI_AREA_META_PUBLIC_DEFAULTS } from "../../../../helpers/cms-area-config";
|
|
28
28
|
import { getPhiBuilderRegionDraftKey } from "../region-keys";
|
|
@@ -1072,13 +1072,28 @@ function usePhiDeveloperBuilderWorkspaceController(defaultArea, options) {
|
|
|
1072
1072
|
if (!next || typeof next.nodeKey !== "string" || typeof next.nodeKind !== "string") {
|
|
1073
1073
|
return;
|
|
1074
1074
|
}
|
|
1075
|
-
|
|
1075
|
+
let nextNodeKey = next.nodeKey;
|
|
1076
|
+
let nextNodeId = readPhiCmsInstanceId(next.nodeId);
|
|
1076
1077
|
const nextPageKey = typeof next.pageKey === "string" ? next.pageKey : undefined;
|
|
1078
|
+
/*
|
|
1079
|
+
* A Layout named only by its Region is that Region's root Layout, read from its draft. A sender that
|
|
1080
|
+
* cannot know a Site's node ids -- a Tour step showing the Layout Inspector -- names it this way. A
|
|
1081
|
+
* Region without a root Layout selects nothing.
|
|
1082
|
+
*/
|
|
1083
|
+
if (next.nodeKind === "layout" && nextNodeId == null && typeof next.regionKey === "string") {
|
|
1084
|
+
const current = getPhiDeveloperBuilderStateSnapshot(defaultArea);
|
|
1085
|
+
const rootNode = getPhiDeveloperRegionDraftsSnapshot()[getPhiBuilderRegionDraftKey(typeof next.area === "string" ? next.area : current.area, next.regionKey, nextPageKey ?? current.pageKey)]?.rootNode;
|
|
1086
|
+
if (!rootNode) {
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
nextNodeId = rootNode.id;
|
|
1090
|
+
nextNodeKey = rootNode.widgetType;
|
|
1091
|
+
}
|
|
1077
1092
|
selectPhiDeveloperBuilderNode(defaultArea, {
|
|
1078
1093
|
...(typeof next.area === "string" ? { area: next.area } : {}),
|
|
1079
1094
|
...(nextPageKey ? { pageKey: nextPageKey } : {}),
|
|
1080
1095
|
nodeKey: nextNodeKey,
|
|
1081
|
-
nodeId:
|
|
1096
|
+
nodeId: nextNodeId,
|
|
1082
1097
|
nodeKind: next.nodeKind,
|
|
1083
1098
|
regionType: typeof next.regionType === "number" ? next.regionType : null,
|
|
1084
1099
|
regionKey: typeof next.regionKey === "string" ? next.regionKey : null,
|
|
@@ -38,6 +38,14 @@ function mapPhiConfigFieldText(field, mapText) {
|
|
|
38
38
|
...(field.description == null ? {} : { description: mapOptionalText(field.description, mapText) }),
|
|
39
39
|
...(field.heading == null ? {} : { heading: mapOptionalText(field.heading, mapText) }),
|
|
40
40
|
};
|
|
41
|
+
if (mapped.type === "choice" && mapped.valueType === "number") {
|
|
42
|
+
return {
|
|
43
|
+
...mapped,
|
|
44
|
+
options: mapped.options.map((option) => mapPhiControlOptionText(option, mapText)),
|
|
45
|
+
...(mapped.emptyOption == null ? {} : { emptyOption: mapPhiControlOptionText(mapped.emptyOption, mapText) }),
|
|
46
|
+
...(mapped.placeholder == null ? {} : { placeholder: mapOptionalText(mapped.placeholder, mapText) }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
41
49
|
if (mapped.type === "choice") {
|
|
42
50
|
return {
|
|
43
51
|
...mapped,
|
|
@@ -2,6 +2,7 @@ import { PHI_BASE_PAGE_LAYOUT_VERSION } from "../../../components/regions/preset
|
|
|
2
2
|
import { buildPhiAreaRootRoutePresetDescriptor } from "../area-root-route";
|
|
3
3
|
import { PHI_BUILDER_RUNTIME_MODULE_ID } from "./ids";
|
|
4
4
|
import { PHI_BUILDER_PAGE_PRESET_VERSION } from "../../../components/regions/presets/phi-builder-page-preset-version";
|
|
5
|
+
import { PHI_BUILDER_NAVIGATION_TOUR, PHI_BUILDER_PAGES_TOUR, PHI_BUILDER_SHELLS_TOUR } from "./tour";
|
|
5
6
|
export const PHI_BUILDER_RUNTIME_MODULE_AREA_SHELLS = [{
|
|
6
7
|
ownerModuleId: PHI_BUILDER_RUNTIME_MODULE_ID,
|
|
7
8
|
presetKey: "builder-area-preset",
|
|
@@ -11,9 +12,9 @@ export const PHI_BUILDER_RUNTIME_MODULE_AREA_SHELLS = [{
|
|
|
11
12
|
.then((module) => module.buildPhiDefaultBuilderAreaPresetTree({ page, runtime })),
|
|
12
13
|
}];
|
|
13
14
|
const BUILDER_ROUTE_PRESETS = [
|
|
14
|
-
{ presetKey: "builder-shells-page", title: "Shells", path: "/shells" },
|
|
15
|
-
{ presetKey: "builder-pages-page", title: "Pages", path: "/pages" },
|
|
16
|
-
{ presetKey: "builder-navigation-page", title: "Navigation", path: "/navigation" },
|
|
15
|
+
{ presetKey: "builder-shells-page", title: "Shells", path: "/shells", tour: PHI_BUILDER_SHELLS_TOUR },
|
|
16
|
+
{ presetKey: "builder-pages-page", title: "Pages", path: "/pages", tour: PHI_BUILDER_PAGES_TOUR },
|
|
17
|
+
{ presetKey: "builder-navigation-page", title: "Navigation", path: "/navigation", tour: PHI_BUILDER_NAVIGATION_TOUR },
|
|
17
18
|
{ presetKey: "builder-modules-page", title: "Modules", path: "/modules" },
|
|
18
19
|
];
|
|
19
20
|
const BUILDER_WORKSPACE_ROUTES = BUILDER_ROUTE_PRESETS.map((route) => ({
|
|
@@ -23,6 +24,7 @@ const BUILDER_WORKSPACE_ROUTES = BUILDER_ROUTE_PRESETS.map((route) => ({
|
|
|
23
24
|
area: "builder",
|
|
24
25
|
title: route.title,
|
|
25
26
|
path: route.path,
|
|
27
|
+
...("tour" in route ? { tour: route.tour } : {}),
|
|
26
28
|
loadTree: ({ page, runtime }) => import("./trees/phi-default-builder-area-preset-tree")
|
|
27
29
|
.then((module) => module.buildPhiDefaultBuilderPagePresetTree({
|
|
28
30
|
page,
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { type PhiCmsInstanceId } from "../../../types/cms-instance-id";
|
|
2
|
+
/**
|
|
3
|
+
* The Shells workspace's Tour. What the workspace does not say is what a Shell is: the frame every Page
|
|
4
|
+
* of the Area stands in, so a change here reaches all of them at once. The rest is the order a person
|
|
5
|
+
* meets the workspace in, ending where the work goes live. The canvas steps point at single Regions
|
|
6
|
+
* (`cms:<canvas>:<regionKey>`): the canvas is taller than the window, and pointing at all of it scrolled
|
|
7
|
+
* it under the Builder's header and lit the header up with it.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PHI_BUILDER_SHELLS_TOUR: {
|
|
10
|
+
readonly id: "@phis/ui/modules/builder/shells";
|
|
11
|
+
readonly version: 1;
|
|
12
|
+
readonly steps: readonly [{
|
|
13
|
+
readonly key: "area";
|
|
14
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
15
|
+
readonly title: "Which Area you are building";
|
|
16
|
+
readonly description: "Every Area has its own Shell, and everything in this workspace applies to the Area chosen here. Usually only Public and App are worked on; the other Areas come as their Modules build them.";
|
|
17
|
+
readonly placement: "bottom";
|
|
18
|
+
readonly ifMissing: "skip";
|
|
19
|
+
}, {
|
|
20
|
+
readonly key: "shell";
|
|
21
|
+
readonly target: `cms:${PhiCmsInstanceId}:header_main`;
|
|
22
|
+
readonly title: "The frame of every Page";
|
|
23
|
+
readonly description: "The Shell is what every Page of the Area shares: the rows of the header, the left sider and the footer. What you change here appears on all of them.";
|
|
24
|
+
readonly placement: "bottom";
|
|
25
|
+
}, {
|
|
26
|
+
readonly key: "regions";
|
|
27
|
+
readonly target: `cms:${PhiCmsInstanceId}:sider_left`;
|
|
28
|
+
readonly title: "Regions and what stands in them";
|
|
29
|
+
readonly description: "A region holds only Layouts, and a Layout holds further Layouts or Widgets, so the first thing placed in an empty region is always a Layout.";
|
|
30
|
+
readonly placement: "right";
|
|
31
|
+
}, {
|
|
32
|
+
readonly key: "select";
|
|
33
|
+
readonly target: `cms:${PhiCmsInstanceId}:header_top` | `cms:${PhiCmsInstanceId}:header_bottom`;
|
|
34
|
+
readonly title: "Setting something up";
|
|
35
|
+
readonly description: "A click on a region, a Layout or a Widget opens its Inspector, where everything about it is set up.";
|
|
36
|
+
readonly placement: "bottom";
|
|
37
|
+
}, {
|
|
38
|
+
readonly key: "inspector";
|
|
39
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
40
|
+
readonly title: "The Inspector";
|
|
41
|
+
readonly description: "For a region: its size and whether it stays put while the Page scrolls, the screens and the Pages it shows on, its spacing and its surface. A Layout and a Widget open an Inspector of their own, with their settings and the signals they send and hear. A change shows on the canvas at once and is part of the draft.";
|
|
42
|
+
readonly placement: "left";
|
|
43
|
+
readonly prepare: readonly [{
|
|
44
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
45
|
+
readonly channel: "selection";
|
|
46
|
+
readonly action: "change";
|
|
47
|
+
readonly valueType: "json";
|
|
48
|
+
readonly valueSchema: `${string}/signals/${string}`;
|
|
49
|
+
readonly value: {
|
|
50
|
+
readonly nodeKind: "region";
|
|
51
|
+
readonly nodeKey: "region:header_top" | "region:header_bottom";
|
|
52
|
+
readonly regionKey: "header_top" | "header_bottom";
|
|
53
|
+
readonly regionType: number;
|
|
54
|
+
};
|
|
55
|
+
}];
|
|
56
|
+
readonly release: readonly [{
|
|
57
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
58
|
+
readonly channel: "inspectorVisibility";
|
|
59
|
+
readonly action: "change";
|
|
60
|
+
readonly valueType: "boolean";
|
|
61
|
+
readonly value: false;
|
|
62
|
+
}];
|
|
63
|
+
}, ...{
|
|
64
|
+
readonly key: string;
|
|
65
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
66
|
+
readonly title: string;
|
|
67
|
+
readonly description: string;
|
|
68
|
+
readonly placement: "left";
|
|
69
|
+
readonly ifMissing: "skip";
|
|
70
|
+
readonly prepare: readonly [{
|
|
71
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
72
|
+
readonly channel: "selection";
|
|
73
|
+
readonly action: "change";
|
|
74
|
+
readonly valueType: "json";
|
|
75
|
+
readonly valueSchema: `${string}/signals/${string}`;
|
|
76
|
+
readonly value: {
|
|
77
|
+
readonly nodeKind: "layout";
|
|
78
|
+
readonly nodeKey: "layout";
|
|
79
|
+
readonly regionKey: "content" | "header_top";
|
|
80
|
+
};
|
|
81
|
+
}, {
|
|
82
|
+
readonly receiver: `cms:${PhiCmsInstanceId}`;
|
|
83
|
+
readonly channel: "slot";
|
|
84
|
+
readonly action: "open";
|
|
85
|
+
readonly valueType: "string";
|
|
86
|
+
readonly value: string;
|
|
87
|
+
}];
|
|
88
|
+
readonly release: readonly [{
|
|
89
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
90
|
+
readonly channel: "inspectorVisibility";
|
|
91
|
+
readonly action: "change";
|
|
92
|
+
readonly valueType: "boolean";
|
|
93
|
+
readonly value: false;
|
|
94
|
+
}, {
|
|
95
|
+
readonly receiver: `cms:${PhiCmsInstanceId}`;
|
|
96
|
+
readonly channel: "slot";
|
|
97
|
+
readonly action: "open";
|
|
98
|
+
readonly valueType: "string";
|
|
99
|
+
readonly value: string;
|
|
100
|
+
}];
|
|
101
|
+
}[], {
|
|
102
|
+
readonly key: "mode";
|
|
103
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
104
|
+
readonly title: "Editor and Preview";
|
|
105
|
+
readonly description: "Editor shows the regions to work in. Preview gives a first impression of your changes without saving them -- a sketch, not exactly what a visitor will see.";
|
|
106
|
+
readonly placement: "bottom";
|
|
107
|
+
}, {
|
|
108
|
+
readonly key: "sider";
|
|
109
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
110
|
+
readonly title: "How tall the sider is";
|
|
111
|
+
readonly description: "Whether the left sider runs the full height of the Shell, or stands beside the content between header and footer.";
|
|
112
|
+
readonly placement: "bottom";
|
|
113
|
+
readonly ifMissing: "skip";
|
|
114
|
+
}, {
|
|
115
|
+
readonly key: "area-settings";
|
|
116
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
117
|
+
readonly title: "What the Area says about itself";
|
|
118
|
+
readonly description: "What the Area's own address shows, how Page titles are built, and for the public Area whether search engines may find it.";
|
|
119
|
+
readonly placement: "bottom";
|
|
120
|
+
}, {
|
|
121
|
+
readonly key: "commands";
|
|
122
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
123
|
+
readonly title: "Saving and publishing";
|
|
124
|
+
readonly description: "Save keeps your changes as a draft, and Live preview opens the Area with it. Publish puts the Shell live on every Page; publishing takes the Publisher role. Undo and Redo step through your changes, and Reset discards the draft without touching what is live.";
|
|
125
|
+
readonly placement: "bottom";
|
|
126
|
+
}, {
|
|
127
|
+
readonly key: "draft-status";
|
|
128
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
129
|
+
readonly title: "Where your changes stand";
|
|
130
|
+
readonly description: "What you change here is a draft. Visitors see the published Shell until the draft is published.";
|
|
131
|
+
readonly placement: "bottom";
|
|
132
|
+
}];
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* The Pages workspace's Tour. Its first point is the split with Shells: a Page owns its own regions, and
|
|
136
|
+
* the frame around them is not edited here. A new or deleted Page is a draft like any other change.
|
|
137
|
+
*/
|
|
138
|
+
export declare const PHI_BUILDER_PAGES_TOUR: {
|
|
139
|
+
readonly id: "@phis/ui/modules/builder/pages";
|
|
140
|
+
readonly version: 1;
|
|
141
|
+
readonly steps: readonly [{
|
|
142
|
+
readonly key: "area";
|
|
143
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
144
|
+
readonly title: "Which Area you are building";
|
|
145
|
+
readonly description: "Every Area has its own Pages, and the Page list below holds those of the Area chosen here. Usually only Public and App are worked on; the other Areas come as their Modules build them.";
|
|
146
|
+
readonly placement: "bottom";
|
|
147
|
+
readonly ifMissing: "skip";
|
|
148
|
+
}, {
|
|
149
|
+
readonly key: "page-choice";
|
|
150
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
151
|
+
readonly title: "Which Page you are building";
|
|
152
|
+
readonly description: "Every Page of the Area, the ones created here and the ones a Module brings.";
|
|
153
|
+
readonly placement: "bottom";
|
|
154
|
+
}, {
|
|
155
|
+
readonly key: "page";
|
|
156
|
+
readonly target: `cms:${PhiCmsInstanceId}:content`;
|
|
157
|
+
readonly title: "What belongs to this Page";
|
|
158
|
+
readonly description: "The content, the hero, the row under the header, the right sider, the row above the footer and the drawer are this Page's alone. The frame around them is the Shell, edited under Shells.";
|
|
159
|
+
readonly placement: "top";
|
|
160
|
+
}, {
|
|
161
|
+
readonly key: "regions";
|
|
162
|
+
readonly target: `cms:${PhiCmsInstanceId}:hero`;
|
|
163
|
+
readonly title: "Regions and what stands in them";
|
|
164
|
+
readonly description: "A region holds only Layouts, and a Layout holds further Layouts or Widgets, so the first thing placed in an empty region is always a Layout.";
|
|
165
|
+
readonly placement: "bottom";
|
|
166
|
+
}, {
|
|
167
|
+
readonly key: "select";
|
|
168
|
+
readonly target: `cms:${PhiCmsInstanceId}:header_top` | `cms:${PhiCmsInstanceId}:header_bottom`;
|
|
169
|
+
readonly title: "Setting something up";
|
|
170
|
+
readonly description: "A click on a region, a Layout or a Widget opens its Inspector, where everything about it is set up.";
|
|
171
|
+
readonly placement: "bottom";
|
|
172
|
+
}, {
|
|
173
|
+
readonly key: "inspector";
|
|
174
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
175
|
+
readonly title: "The Inspector";
|
|
176
|
+
readonly description: "For a region: its size and whether it stays put while the Page scrolls, the screens and the Pages it shows on, its spacing and its surface. A Layout and a Widget open an Inspector of their own, with their settings and the signals they send and hear. A change shows on the canvas at once and is part of the draft.";
|
|
177
|
+
readonly placement: "left";
|
|
178
|
+
readonly prepare: readonly [{
|
|
179
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
180
|
+
readonly channel: "selection";
|
|
181
|
+
readonly action: "change";
|
|
182
|
+
readonly valueType: "json";
|
|
183
|
+
readonly valueSchema: `${string}/signals/${string}`;
|
|
184
|
+
readonly value: {
|
|
185
|
+
readonly nodeKind: "region";
|
|
186
|
+
readonly nodeKey: "region:header_top" | "region:header_bottom";
|
|
187
|
+
readonly regionKey: "header_top" | "header_bottom";
|
|
188
|
+
readonly regionType: number;
|
|
189
|
+
};
|
|
190
|
+
}];
|
|
191
|
+
readonly release: readonly [{
|
|
192
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
193
|
+
readonly channel: "inspectorVisibility";
|
|
194
|
+
readonly action: "change";
|
|
195
|
+
readonly valueType: "boolean";
|
|
196
|
+
readonly value: false;
|
|
197
|
+
}];
|
|
198
|
+
}, ...{
|
|
199
|
+
readonly key: string;
|
|
200
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
201
|
+
readonly title: string;
|
|
202
|
+
readonly description: string;
|
|
203
|
+
readonly placement: "left";
|
|
204
|
+
readonly ifMissing: "skip";
|
|
205
|
+
readonly prepare: readonly [{
|
|
206
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
207
|
+
readonly channel: "selection";
|
|
208
|
+
readonly action: "change";
|
|
209
|
+
readonly valueType: "json";
|
|
210
|
+
readonly valueSchema: `${string}/signals/${string}`;
|
|
211
|
+
readonly value: {
|
|
212
|
+
readonly nodeKind: "layout";
|
|
213
|
+
readonly nodeKey: "layout";
|
|
214
|
+
readonly regionKey: "content" | "header_top";
|
|
215
|
+
};
|
|
216
|
+
}, {
|
|
217
|
+
readonly receiver: `cms:${PhiCmsInstanceId}`;
|
|
218
|
+
readonly channel: "slot";
|
|
219
|
+
readonly action: "open";
|
|
220
|
+
readonly valueType: "string";
|
|
221
|
+
readonly value: string;
|
|
222
|
+
}];
|
|
223
|
+
readonly release: readonly [{
|
|
224
|
+
readonly receiver: `controller:${string}/${string}:${string}`;
|
|
225
|
+
readonly channel: "inspectorVisibility";
|
|
226
|
+
readonly action: "change";
|
|
227
|
+
readonly valueType: "boolean";
|
|
228
|
+
readonly value: false;
|
|
229
|
+
}, {
|
|
230
|
+
readonly receiver: `cms:${PhiCmsInstanceId}`;
|
|
231
|
+
readonly channel: "slot";
|
|
232
|
+
readonly action: "open";
|
|
233
|
+
readonly valueType: "string";
|
|
234
|
+
readonly value: string;
|
|
235
|
+
}];
|
|
236
|
+
}[], {
|
|
237
|
+
readonly key: "page-commands";
|
|
238
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
239
|
+
readonly title: "New Pages and what a Page says";
|
|
240
|
+
readonly description: "New page creates one in this Area. Page meta sets its title, its description and whether search engines may find it. Delete takes the Page away once the change is published.";
|
|
241
|
+
readonly placement: "bottom";
|
|
242
|
+
}, {
|
|
243
|
+
readonly key: "mode";
|
|
244
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
245
|
+
readonly title: "Editor and Preview";
|
|
246
|
+
readonly description: "Editor shows the regions to work in. Preview gives a first impression of your changes without saving them -- a sketch, not exactly what a visitor will see.";
|
|
247
|
+
readonly placement: "bottom";
|
|
248
|
+
}, {
|
|
249
|
+
readonly key: "commands";
|
|
250
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
251
|
+
readonly title: "Saving and publishing";
|
|
252
|
+
readonly description: "Save keeps your changes as a draft, and Live preview opens the Page with it. Publish puts it live, and a new Page exists for visitors only from then on; publishing takes the Publisher role. Undo and Redo step through your changes, and Reset discards the draft without touching what is live.";
|
|
253
|
+
readonly placement: "bottom";
|
|
254
|
+
}, {
|
|
255
|
+
readonly key: "draft-status";
|
|
256
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
257
|
+
readonly title: "Where your changes stand";
|
|
258
|
+
readonly description: "What you change here is a draft. Visitors see the published Page until the draft is published.";
|
|
259
|
+
readonly placement: "bottom";
|
|
260
|
+
}];
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* The Navigation workspace's Tour. What the workspace does not say is that a Site has several
|
|
264
|
+
* navigations, that a Page is linked by dragging it across rather than by typing its path, and that the
|
|
265
|
+
* items a Module brings stand in the same list as the Site's own.
|
|
266
|
+
*/
|
|
267
|
+
export declare const PHI_BUILDER_NAVIGATION_TOUR: {
|
|
268
|
+
readonly id: "@phis/ui/modules/builder/navigation";
|
|
269
|
+
readonly version: 1;
|
|
270
|
+
readonly steps: readonly [{
|
|
271
|
+
readonly key: "choice";
|
|
272
|
+
readonly target: `cms:${PhiCmsInstanceId}:filters`;
|
|
273
|
+
readonly title: "Which navigation";
|
|
274
|
+
readonly description: "A Site has more than one navigation -- the main menu, the one in the footer, a sider's. Everything below belongs to the one chosen here, and the plus beside it adds a new one under a key of its own.";
|
|
275
|
+
readonly placement: "bottom";
|
|
276
|
+
readonly ifMissing: "skip";
|
|
277
|
+
}, {
|
|
278
|
+
readonly key: "source";
|
|
279
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
280
|
+
readonly title: "The Pages to link";
|
|
281
|
+
readonly description: "Every Page of the Area chosen above the list. Drag one into the navigation to link it, onto a container to put it inside; the link follows the Page wherever its path goes.";
|
|
282
|
+
readonly placement: "right";
|
|
283
|
+
}, {
|
|
284
|
+
readonly key: "items";
|
|
285
|
+
readonly target: `cms:${PhiCmsInstanceId}:header`;
|
|
286
|
+
readonly title: "What the navigation holds";
|
|
287
|
+
readonly description: "A row per item, in the order it is shown. Drag a row to move it, into a container to nest it. A click on a label or an icon changes it in place. Origin says whether the item is the Site's own or came with a Module.";
|
|
288
|
+
readonly placement: "bottom";
|
|
289
|
+
}, {
|
|
290
|
+
readonly key: "add";
|
|
291
|
+
readonly target: `cms:${PhiCmsInstanceId}:toolbar`;
|
|
292
|
+
readonly title: "Links, containers, separators";
|
|
293
|
+
readonly description: "Add link adds a link to an address outside the Site, written in its Path; a Page of the Site is linked by dragging it in. A container holds further items and opens as a group; a separator draws a line between them.";
|
|
294
|
+
readonly placement: "bottom";
|
|
295
|
+
readonly ifMissing: "skip";
|
|
296
|
+
}, {
|
|
297
|
+
readonly key: "row-actions";
|
|
298
|
+
readonly target: `cms:${PhiCmsInstanceId}:row-actions`;
|
|
299
|
+
readonly title: "Hiding and deleting";
|
|
300
|
+
readonly description: "A hidden item stays in the list and keeps its place, but visitors do not see it. Delete takes it out; Undo brings it back.";
|
|
301
|
+
readonly placement: "left";
|
|
302
|
+
readonly ifMissing: "skip";
|
|
303
|
+
}, {
|
|
304
|
+
readonly key: "commands";
|
|
305
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
306
|
+
readonly title: "Saving and publishing";
|
|
307
|
+
readonly description: "Save keeps your changes as a draft, and Live preview shows the Site with it. Publish puts the navigation live; publishing takes the Publisher role. Undo and Redo step through your changes, and Reset discards the draft without touching what is live.";
|
|
308
|
+
readonly placement: "bottom";
|
|
309
|
+
}, {
|
|
310
|
+
readonly key: "draft-status";
|
|
311
|
+
readonly target: `cms:${PhiCmsInstanceId}`;
|
|
312
|
+
readonly title: "Where your changes stand";
|
|
313
|
+
readonly description: "What you change here is a draft. Visitors see the published navigation until the draft is published.";
|
|
314
|
+
readonly placement: "bottom";
|
|
315
|
+
}];
|
|
316
|
+
};
|