@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
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
label: string;
|
|
5
|
-
}[];
|
|
1
|
+
import type { PhiControlOption } from "../../controls/phi-control-options";
|
|
2
|
+
/** The renditions an Asset is offered in, for every field that picks one; stored as the number the key is. */
|
|
3
|
+
export declare const PHI_IMAGE_VARIANT_OPTIONS: PhiControlOption<number>[];
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { PhiImageAssetVariantKey } from "../../../constants/media";
|
|
2
|
-
/** The renditions an Asset is offered in, for every field that picks one. */
|
|
2
|
+
/** The renditions an Asset is offered in, for every field that picks one; stored as the number the key is. */
|
|
3
3
|
export const PHI_IMAGE_VARIANT_OPTIONS = [
|
|
4
|
-
{ value:
|
|
5
|
-
{ value:
|
|
6
|
-
{ value:
|
|
7
|
-
{ value:
|
|
8
|
-
{ value:
|
|
9
|
-
{ value:
|
|
10
|
-
{ value:
|
|
11
|
-
{ value:
|
|
12
|
-
{ value:
|
|
13
|
-
{ value:
|
|
4
|
+
{ value: PhiImageAssetVariantKey.Thumbnail, label: "Thumbnail" },
|
|
5
|
+
{ value: PhiImageAssetVariantKey.Preview, label: "Preview" },
|
|
6
|
+
{ value: PhiImageAssetVariantKey.Banner, label: "Banner" },
|
|
7
|
+
{ value: PhiImageAssetVariantKey.Header, label: "Header" },
|
|
8
|
+
{ value: PhiImageAssetVariantKey.Card, label: "Card" },
|
|
9
|
+
{ value: PhiImageAssetVariantKey.Hero, label: "Hero" },
|
|
10
|
+
{ value: PhiImageAssetVariantKey.Avatar, label: "Avatar" },
|
|
11
|
+
{ value: PhiImageAssetVariantKey.Logo, label: "Logo" },
|
|
12
|
+
{ value: PhiImageAssetVariantKey.Landscape, label: "Landscape" },
|
|
13
|
+
{ value: PhiImageAssetVariantKey.Portrait, label: "Portrait" },
|
|
14
14
|
];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type PhiMotionEasing, type PhiSequenceTransition } from "../../../helpers/motion";
|
|
2
|
+
import { type PhiCmsMountPolicy } from "../../../types/cms-mount-policy";
|
|
3
|
+
import type { PhiCmsConfigField, PhiCmsConfigFieldVisibilityRule } from "../../../types/cms-plugins";
|
|
4
|
+
import { type PhiSpacingScaleKey } from "./spacing-options";
|
|
5
|
+
/**
|
|
6
|
+
* How a Widget that shows a run of things a few at a time moves through them.
|
|
7
|
+
*
|
|
8
|
+
* The Gallery runs through the pictures of a Folder, the Entries list through cards of News or Blog;
|
|
9
|
+
* what moves differs, how it moves does not. So the settings are one vocabulary with one reader, one
|
|
10
|
+
* set of Inspector fields and one set of defaults, and `PhiSequenceRun` draws them. The Carousel Layout
|
|
11
|
+
* asks the same questions under its own older keys (`visibleSlots`, `transitionDurationMs`).
|
|
12
|
+
*
|
|
13
|
+
* No window anchor, unlike the Carousel. A run moves a page at a time -- one to three, then four to
|
|
14
|
+
* six -- and nothing outside it names an item to show; a centred anchor would only shift every page by
|
|
15
|
+
* one and leave the dots pointing between pages. The window starts at its active item.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PHI_SEQUENCE_CONTROLS: readonly ["none", "arrows", "dots", "both"];
|
|
18
|
+
export type PhiSequenceControls = (typeof PHI_SEQUENCE_CONTROLS)[number];
|
|
19
|
+
export type PhiSequenceSettings = {
|
|
20
|
+
visibleCount?: number;
|
|
21
|
+
transition?: PhiSequenceTransition;
|
|
22
|
+
durationMs?: number;
|
|
23
|
+
easing?: PhiMotionEasing;
|
|
24
|
+
/** A step of the spacing scale between the items of a window. */
|
|
25
|
+
gap?: PhiSpacingScaleKey;
|
|
26
|
+
/**
|
|
27
|
+
* How many items beyond the window are kept mounted, and therefore told to load early.
|
|
28
|
+
*
|
|
29
|
+
* The browser will not do this for us. `loading="lazy"` decides from an element's distance to the
|
|
30
|
+
* viewport and knows nothing about a track: on a fade every item sits in the same place and all of
|
|
31
|
+
* them load at once, while on a slide the next one is off to the side and loads as it arrives --
|
|
32
|
+
* during the transition, which is the worst moment. Next's escape hatch for that, `lazyRoot`, is a
|
|
33
|
+
* deprecated no-op. So the window decides, and the window is ours.
|
|
34
|
+
*/
|
|
35
|
+
lookahead?: number;
|
|
36
|
+
mountPolicy?: PhiCmsMountPolicy;
|
|
37
|
+
controls?: PhiSequenceControls;
|
|
38
|
+
loop?: boolean;
|
|
39
|
+
/** Absent or zero means it does not move on its own. */
|
|
40
|
+
autoplayMs?: number;
|
|
41
|
+
};
|
|
42
|
+
/** What a run does where nobody said otherwise, stated so the Inspector shows it as the standing answer. */
|
|
43
|
+
export declare const PHI_SEQUENCE_SETTINGS_DEFAULTS: {
|
|
44
|
+
readonly visibleCount: 1;
|
|
45
|
+
readonly transition: "slide";
|
|
46
|
+
readonly durationMs: 320;
|
|
47
|
+
readonly easing: "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out";
|
|
48
|
+
readonly gap: "xs";
|
|
49
|
+
readonly lookahead: 1;
|
|
50
|
+
readonly mountPolicy: "lazy-keep";
|
|
51
|
+
readonly controls: "both";
|
|
52
|
+
readonly loop: false;
|
|
53
|
+
readonly autoplayMs: 0;
|
|
54
|
+
};
|
|
55
|
+
type PhiSequenceSettingsFail = (key: string, value: unknown, expected: string) => never;
|
|
56
|
+
export declare function readPhiSequenceSettings(raw: Record<string, unknown>, fail: PhiSequenceSettingsFail): PhiSequenceSettings;
|
|
57
|
+
/** The run's settings out of a Widget's config, for a client half that needs these and nothing else. */
|
|
58
|
+
export declare function pickPhiSequenceSettings(config: PhiSequenceSettings): PhiSequenceSettings;
|
|
59
|
+
/**
|
|
60
|
+
* The Inspector's fields for a run, in three groups a Widget places among its own: the window (how many
|
|
61
|
+
* stand side by side and how far apart), the movement, and the controls.
|
|
62
|
+
*
|
|
63
|
+
* `visibleWhen` is added to every field, for a Widget where the run is one presentation among others.
|
|
64
|
+
* `heading` names the window group; the Gallery leaves it out, its window stands under "Picture".
|
|
65
|
+
*/
|
|
66
|
+
export declare function buildPhiSequenceSettingsFields({ countLabel, heading, visibleWhen, }: {
|
|
67
|
+
countLabel: string;
|
|
68
|
+
heading?: string;
|
|
69
|
+
visibleWhen?: PhiCmsConfigFieldVisibilityRule;
|
|
70
|
+
}): {
|
|
71
|
+
window: PhiCmsConfigField[];
|
|
72
|
+
movement: PhiCmsConfigField[];
|
|
73
|
+
controls: PhiCmsConfigField[];
|
|
74
|
+
};
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { PHI_MOTION_EASING_FIELD_OPTIONS, PHI_SEQUENCE_DEFAULT_DURATION_MS, PHI_SEQUENCE_DEFAULT_EASING, PHI_SEQUENCE_TRANSITION_MAX_MS, PHI_SEQUENCE_TRANSITION_MIN_MS, PHI_SEQUENCE_TRANSITION_STEP_MS, PHI_SEQUENCE_TRANSITIONS, clampPhiSequenceTransitionMs, readPhiMotionEasing, } from "../../../helpers/motion";
|
|
2
|
+
import { PHI_CMS_MOUNT_POLICY_FIELD_OPTIONS, readPhiCmsMountPolicy, } from "../../../types/cms-mount-policy";
|
|
3
|
+
import { PHI_SPACING_SCALE_KEYS } from "./spacing-options";
|
|
4
|
+
/**
|
|
5
|
+
* How a Widget that shows a run of things a few at a time moves through them.
|
|
6
|
+
*
|
|
7
|
+
* The Gallery runs through the pictures of a Folder, the Entries list through cards of News or Blog;
|
|
8
|
+
* what moves differs, how it moves does not. So the settings are one vocabulary with one reader, one
|
|
9
|
+
* set of Inspector fields and one set of defaults, and `PhiSequenceRun` draws them. The Carousel Layout
|
|
10
|
+
* asks the same questions under its own older keys (`visibleSlots`, `transitionDurationMs`).
|
|
11
|
+
*
|
|
12
|
+
* No window anchor, unlike the Carousel. A run moves a page at a time -- one to three, then four to
|
|
13
|
+
* six -- and nothing outside it names an item to show; a centred anchor would only shift every page by
|
|
14
|
+
* one and leave the dots pointing between pages. The window starts at its active item.
|
|
15
|
+
*/
|
|
16
|
+
export const PHI_SEQUENCE_CONTROLS = ["none", "arrows", "dots", "both"];
|
|
17
|
+
/** What a run does where nobody said otherwise, stated so the Inspector shows it as the standing answer. */
|
|
18
|
+
export const PHI_SEQUENCE_SETTINGS_DEFAULTS = {
|
|
19
|
+
visibleCount: 1,
|
|
20
|
+
transition: "slide",
|
|
21
|
+
durationMs: PHI_SEQUENCE_DEFAULT_DURATION_MS,
|
|
22
|
+
easing: PHI_SEQUENCE_DEFAULT_EASING,
|
|
23
|
+
gap: "xs",
|
|
24
|
+
lookahead: 1,
|
|
25
|
+
mountPolicy: "lazy-keep",
|
|
26
|
+
controls: "both",
|
|
27
|
+
loop: false,
|
|
28
|
+
autoplayMs: 0,
|
|
29
|
+
};
|
|
30
|
+
function readMember(value, members, key, fail) {
|
|
31
|
+
if (value === undefined || value === null)
|
|
32
|
+
return undefined;
|
|
33
|
+
if (typeof value !== "string" || !members.includes(value)) {
|
|
34
|
+
fail(key, value, `one of ${members.join(", ")}`);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
function readCount(value, key, min, fail) {
|
|
39
|
+
if (value === undefined || value === null)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < min) {
|
|
42
|
+
fail(key, value, `a whole number of at least ${min}`);
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
export function readPhiSequenceSettings(raw, fail) {
|
|
47
|
+
const visibleCount = readCount(raw.visibleCount, "visibleCount", 1, fail);
|
|
48
|
+
const transition = readMember(raw.transition, PHI_SEQUENCE_TRANSITIONS, "transition", fail);
|
|
49
|
+
const easing = readPhiMotionEasing(raw.easing, undefined);
|
|
50
|
+
const gap = readMember(raw.gap, PHI_SPACING_SCALE_KEYS, "gap", fail);
|
|
51
|
+
const lookahead = readCount(raw.lookahead, "lookahead", 0, fail);
|
|
52
|
+
const controls = readMember(raw.controls, PHI_SEQUENCE_CONTROLS, "controls", fail);
|
|
53
|
+
if (raw.loop !== undefined && raw.loop !== null && typeof raw.loop !== "boolean") {
|
|
54
|
+
fail("loop", raw.loop, "true or false");
|
|
55
|
+
}
|
|
56
|
+
const loop = typeof raw.loop === "boolean" ? raw.loop : undefined;
|
|
57
|
+
const autoplayMs = readCount(raw.autoplayMs, "autoplayMs", 0, fail);
|
|
58
|
+
return {
|
|
59
|
+
...(visibleCount === undefined ? {} : { visibleCount }),
|
|
60
|
+
...(transition === undefined ? {} : { transition }),
|
|
61
|
+
...(raw.durationMs === undefined || raw.durationMs === null
|
|
62
|
+
? {}
|
|
63
|
+
: { durationMs: clampPhiSequenceTransitionMs(raw.durationMs) }),
|
|
64
|
+
...(easing === undefined ? {} : { easing }),
|
|
65
|
+
...(gap === undefined ? {} : { gap }),
|
|
66
|
+
...(lookahead === undefined ? {} : { lookahead }),
|
|
67
|
+
mountPolicy: readPhiCmsMountPolicy(raw.mountPolicy, PHI_SEQUENCE_SETTINGS_DEFAULTS.mountPolicy),
|
|
68
|
+
...(controls === undefined ? {} : { controls }),
|
|
69
|
+
...(loop === undefined ? {} : { loop }),
|
|
70
|
+
// Zero is how "does not move on its own" is written, so it is the one number below the floor
|
|
71
|
+
// that means something.
|
|
72
|
+
...(autoplayMs === undefined || autoplayMs === 0
|
|
73
|
+
? {}
|
|
74
|
+
: { autoplayMs: clampPhiSequenceTransitionMs(autoplayMs) }),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const PHI_SEQUENCE_SETTINGS_KEYS = Object.keys(PHI_SEQUENCE_SETTINGS_DEFAULTS);
|
|
78
|
+
/** The run's settings out of a Widget's config, for a client half that needs these and nothing else. */
|
|
79
|
+
export function pickPhiSequenceSettings(config) {
|
|
80
|
+
return Object.fromEntries(PHI_SEQUENCE_SETTINGS_KEYS.filter((key) => config[key] !== undefined).map((key) => [key, config[key]]));
|
|
81
|
+
}
|
|
82
|
+
function withRule(field, rule) {
|
|
83
|
+
if (!rule)
|
|
84
|
+
return field;
|
|
85
|
+
const own = field.visibleWhen == null ? [] : Array.isArray(field.visibleWhen) ? field.visibleWhen : [field.visibleWhen];
|
|
86
|
+
return { ...field, visibleWhen: [...own, rule] };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The Inspector's fields for a run, in three groups a Widget places among its own: the window (how many
|
|
90
|
+
* stand side by side and how far apart), the movement, and the controls.
|
|
91
|
+
*
|
|
92
|
+
* `visibleWhen` is added to every field, for a Widget where the run is one presentation among others.
|
|
93
|
+
* `heading` names the window group; the Gallery leaves it out, its window stands under "Picture".
|
|
94
|
+
*/
|
|
95
|
+
export function buildPhiSequenceSettingsFields({ countLabel, heading, visibleWhen, }) {
|
|
96
|
+
const window = [
|
|
97
|
+
{ key: "visibleCount", type: "number", label: countLabel, min: 1, ...(heading ? { heading } : {}) },
|
|
98
|
+
{
|
|
99
|
+
key: "gap",
|
|
100
|
+
type: "choice",
|
|
101
|
+
label: "Gap",
|
|
102
|
+
options: PHI_SPACING_SCALE_KEYS.map((key) => ({ value: key, label: key })),
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
const movement = [
|
|
106
|
+
{
|
|
107
|
+
key: "transition",
|
|
108
|
+
type: "choice",
|
|
109
|
+
heading: "Transition",
|
|
110
|
+
label: "Transition",
|
|
111
|
+
options: [
|
|
112
|
+
{ value: "none", label: "None" },
|
|
113
|
+
{ value: "fade", label: "Fade" },
|
|
114
|
+
{ value: "slide", label: "Slide" },
|
|
115
|
+
{ value: "diagonal", label: "Diagonal" },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
key: "durationMs",
|
|
120
|
+
type: "number",
|
|
121
|
+
label: "Duration",
|
|
122
|
+
min: PHI_SEQUENCE_TRANSITION_MIN_MS,
|
|
123
|
+
max: PHI_SEQUENCE_TRANSITION_MAX_MS,
|
|
124
|
+
step: PHI_SEQUENCE_TRANSITION_STEP_MS,
|
|
125
|
+
prefix: "ms",
|
|
126
|
+
visibleWhen: { field: "transition", notEquals: "none" },
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
key: "easing",
|
|
130
|
+
type: "choice",
|
|
131
|
+
label: "Easing",
|
|
132
|
+
options: [...PHI_MOTION_EASING_FIELD_OPTIONS],
|
|
133
|
+
visibleWhen: { field: "transition", notEquals: "none" },
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
// Zero is the one value below the floor that means something: it does not move on its own.
|
|
137
|
+
key: "autoplayMs",
|
|
138
|
+
type: "number",
|
|
139
|
+
label: "Autoplay",
|
|
140
|
+
min: 0,
|
|
141
|
+
max: PHI_SEQUENCE_TRANSITION_MAX_MS,
|
|
142
|
+
step: PHI_SEQUENCE_TRANSITION_STEP_MS,
|
|
143
|
+
prefix: "ms",
|
|
144
|
+
},
|
|
145
|
+
{ key: "lookahead", type: "number", label: "Preload Ahead", min: 0 },
|
|
146
|
+
{
|
|
147
|
+
key: "mountPolicy",
|
|
148
|
+
type: "choice",
|
|
149
|
+
label: "Mounting",
|
|
150
|
+
options: [...PHI_CMS_MOUNT_POLICY_FIELD_OPTIONS],
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
const controls = [
|
|
154
|
+
{
|
|
155
|
+
key: "controls",
|
|
156
|
+
type: "choice",
|
|
157
|
+
heading: "Controls",
|
|
158
|
+
label: "Controls",
|
|
159
|
+
options: [
|
|
160
|
+
{ value: "both", label: "Arrows and dots" },
|
|
161
|
+
{ value: "arrows", label: "Arrows" },
|
|
162
|
+
{ value: "dots", label: "Dots" },
|
|
163
|
+
{ value: "none", label: "None" },
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
{ key: "loop", type: "boolean", label: "Wrap Around" },
|
|
167
|
+
];
|
|
168
|
+
return {
|
|
169
|
+
window: window.map((field) => withRule(field, visibleWhen)),
|
|
170
|
+
movement: movement.map((field) => withRule(field, visibleWhen)),
|
|
171
|
+
controls: controls.map((field) => withRule(field, visibleWhen)),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -124,5 +124,14 @@ export declare function getPhiContentEntryReaderLabels(options: PhiGlobalTransla
|
|
|
124
124
|
unavailable: string;
|
|
125
125
|
readMore: string;
|
|
126
126
|
readEntry: string;
|
|
127
|
+
sequence: {
|
|
128
|
+
previous: string;
|
|
129
|
+
next: string;
|
|
130
|
+
page: string;
|
|
131
|
+
pause: string;
|
|
132
|
+
play: string;
|
|
133
|
+
region: string;
|
|
134
|
+
pages: string;
|
|
135
|
+
};
|
|
127
136
|
}>;
|
|
128
137
|
export type PhiContentEntryReaderLabels = Awaited<ReturnType<typeof getPhiContentEntryReaderLabels>>;
|
|
@@ -183,6 +183,14 @@ const PHI_CONTENT_ENTRY_READER_LABEL_SET = definePhiLabelSet({
|
|
|
183
183
|
unavailable: definePhiMessageLabel("The entries could not be loaded just now."),
|
|
184
184
|
read_more: "Read more",
|
|
185
185
|
read_entry: "Read",
|
|
186
|
+
// A slideshow's buttons and dots, and its name for a screen reader.
|
|
187
|
+
previous: "Previous",
|
|
188
|
+
next: "Next",
|
|
189
|
+
page: definePhiMessageLabel("Show entries %1 to %2"),
|
|
190
|
+
pause: "Pause",
|
|
191
|
+
play: "Play",
|
|
192
|
+
region: "Entries",
|
|
193
|
+
pages: definePhiMessageLabel("Choose entries"),
|
|
186
194
|
},
|
|
187
195
|
});
|
|
188
196
|
export async function getPhiContentEntryReaderLabels(options) {
|
|
@@ -193,5 +201,14 @@ export async function getPhiContentEntryReaderLabels(options) {
|
|
|
193
201
|
unavailable: labels.unavailable,
|
|
194
202
|
readMore: labels.read_more,
|
|
195
203
|
readEntry: labels.read_entry,
|
|
204
|
+
sequence: {
|
|
205
|
+
previous: labels.previous,
|
|
206
|
+
next: labels.next,
|
|
207
|
+
page: labels.page,
|
|
208
|
+
pause: labels.pause,
|
|
209
|
+
play: labels.play,
|
|
210
|
+
region: labels.region,
|
|
211
|
+
pages: labels.pages,
|
|
212
|
+
},
|
|
196
213
|
};
|
|
197
214
|
}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
next: string;
|
|
4
|
-
/** `%1` and `%2` are the first and last picture the page shows. */
|
|
5
|
-
page: string;
|
|
6
|
-
pause: string;
|
|
7
|
-
play: string;
|
|
8
|
-
/** The box's name for a screen reader, which calls it a carousel. */
|
|
9
|
-
region: string;
|
|
10
|
-
pages: string;
|
|
1
|
+
import type { PhiSequenceControlLabels } from "./sequence";
|
|
2
|
+
export type PhiGalleryWidgetLabels = PhiSequenceControlLabels & {
|
|
11
3
|
unavailable: string;
|
|
12
4
|
};
|
|
13
5
|
export declare const PHI_GALLERY_WIDGET_DEFAULT_LABELS: PhiGalleryWidgetLabels;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words around a run that moves: its buttons, its dots, and its name for a screen reader.
|
|
3
|
+
*
|
|
4
|
+
* Every Widget that draws `PhiSequenceRun` brings them from its own Label Set, because what is being
|
|
5
|
+
* stepped through is its own -- pictures in a Gallery, entries in a list -- and "Show pictures 1 to 3"
|
|
6
|
+
* is not a sentence about News.
|
|
7
|
+
*/
|
|
8
|
+
export type PhiSequenceControlLabels = {
|
|
9
|
+
previous: string;
|
|
10
|
+
next: string;
|
|
11
|
+
/** `%1` and `%2` are the first and last item the page shows. */
|
|
12
|
+
page: string;
|
|
13
|
+
pause: string;
|
|
14
|
+
play: string;
|
|
15
|
+
/** The box's name for a screen reader, which calls it a carousel. */
|
|
16
|
+
region: string;
|
|
17
|
+
pages: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PHI_SPACE } from "../theme/antd-css-var-contract";
|
|
2
2
|
import { PHI_RENDERABLE_BLOCK_DEFAULT_ANCHOR } from "./renderable-block-defaults";
|
|
3
3
|
import { isPhiRecord } from "./is-record";
|
|
4
|
+
import { PHI_SEQUENCE_DEFAULT_DURATION_MS, PHI_SEQUENCE_DEFAULT_EASING } from "./motion";
|
|
4
5
|
import { PHI_SURFACE_CARD } from "./surface-presets";
|
|
5
6
|
import { PHI_GRID_LAYOUT_DEFAULT_COLUMNS } from "../components/layouts/phi-grid-contract";
|
|
6
7
|
import { PHI_MASONRY_LAYOUT_DEFAULT_COLUMNS } from "../components/layouts/phi-masonry-contract";
|
|
@@ -119,9 +120,13 @@ const PHI_STACK_LAYOUT_PANEL_PRESET = {
|
|
|
119
120
|
};
|
|
120
121
|
const PHI_CAROUSEL_LAYOUT_DEFAULTS = {
|
|
121
122
|
// A slide is what tells somebody the slots are a run rather than a set, so it is the opening
|
|
122
|
-
// impression rather than a preference to be discovered.
|
|
123
|
-
//
|
|
123
|
+
// impression rather than a preference to be discovered. The window shows one slot until
|
|
124
|
+
// somebody widens it. The pace is the sequence's own, stated so the Inspector shows the number
|
|
125
|
+
// in effect rather than an empty box.
|
|
124
126
|
transition: "slide",
|
|
127
|
+
transitionDurationMs: PHI_SEQUENCE_DEFAULT_DURATION_MS,
|
|
128
|
+
transitionEasing: PHI_SEQUENCE_DEFAULT_EASING,
|
|
129
|
+
slotGap: "none",
|
|
125
130
|
visibleSlots: 1,
|
|
126
131
|
windowAnchor: "start",
|
|
127
132
|
/*
|
|
@@ -134,6 +139,8 @@ const PHI_CAROUSEL_LAYOUT_DEFAULTS = {
|
|
|
134
139
|
*/
|
|
135
140
|
controls: "arrows",
|
|
136
141
|
loop: false,
|
|
142
|
+
autoplayMs: 0,
|
|
143
|
+
lookahead: 1,
|
|
137
144
|
};
|
|
138
145
|
const PHI_CAROUSEL_LAYOUT_PANEL_PRESET = {
|
|
139
146
|
padding: PHI_SPACE.base,
|
|
@@ -33,5 +33,5 @@ export declare function resolvePhiCmsRegionOwnership(regionKey: string | null |
|
|
|
33
33
|
* know is not a placement anybody chose -- refusing it would hide Widgets over a typo.
|
|
34
34
|
*/
|
|
35
35
|
export declare function phiCmsRegionAcceptsWidget(regionKey: string | null | undefined, required: PhiCmsRegionOwnership | null | undefined): boolean;
|
|
36
|
-
export declare function resolvePhiCmsRegionType(regionKey: string | null | undefined): 10 | 40 |
|
|
36
|
+
export declare function resolvePhiCmsRegionType(regionKey: string | null | undefined): 10 | 40 | 12 | 50 | 11 | 20 | 21 | 25 | 30 | 39 | 41;
|
|
37
37
|
export declare function resolvePhiCmsRegionKey(regionType: number | null | undefined): "content" | "header_top" | "header_main" | "header_bottom" | "sider_left" | "sider_right" | "hero" | "footer_top" | "footer_main" | "footer_bottom" | "drawer_right" | undefined;
|
package/helpers/motion.d.ts
CHANGED
|
@@ -43,6 +43,13 @@ export declare const PHI_SEQUENCE_TRANSITION_MAX_MS = 600000;
|
|
|
43
43
|
* exactly, so the grid the spinner walks holds every value it offers.
|
|
44
44
|
*/
|
|
45
45
|
export declare const PHI_SEQUENCE_TRANSITION_STEP_MS = 100;
|
|
46
|
+
/**
|
|
47
|
+
* What a sequence that says nothing moves at: long enough to read as movement, short enough to
|
|
48
|
+
* ignore. Exported so that a Widget can state it as its default and the Inspector shows the number
|
|
49
|
+
* that is actually in effect instead of an empty box.
|
|
50
|
+
*/
|
|
51
|
+
export declare const PHI_SEQUENCE_DEFAULT_DURATION_MS = 320;
|
|
52
|
+
export declare const PHI_SEQUENCE_DEFAULT_EASING: PhiMotionEasing;
|
|
46
53
|
/**
|
|
47
54
|
* The two ways of showing a sequence, and which end of a wider window an index means.
|
|
48
55
|
*
|
package/helpers/motion.js
CHANGED
|
@@ -58,6 +58,13 @@ export const PHI_SEQUENCE_TRANSITION_MAX_MS = 600_000;
|
|
|
58
58
|
* exactly, so the grid the spinner walks holds every value it offers.
|
|
59
59
|
*/
|
|
60
60
|
export const PHI_SEQUENCE_TRANSITION_STEP_MS = 100;
|
|
61
|
+
/**
|
|
62
|
+
* What a sequence that says nothing moves at: long enough to read as movement, short enough to
|
|
63
|
+
* ignore. Exported so that a Widget can state it as its default and the Inspector shows the number
|
|
64
|
+
* that is actually in effect instead of an empty box.
|
|
65
|
+
*/
|
|
66
|
+
export const PHI_SEQUENCE_DEFAULT_DURATION_MS = 320;
|
|
67
|
+
export const PHI_SEQUENCE_DEFAULT_EASING = "ease-in-out";
|
|
61
68
|
/**
|
|
62
69
|
* The two ways of showing a sequence, and which end of a wider window an index means.
|
|
63
70
|
*
|
package/package.json
CHANGED
|
@@ -25,6 +25,7 @@ export declare const PHI_ASSET_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
|
|
|
25
25
|
settingsFields: ({
|
|
26
26
|
key: string;
|
|
27
27
|
type: "choice";
|
|
28
|
+
heading: string;
|
|
28
29
|
label: string;
|
|
29
30
|
optionsProvider: {
|
|
30
31
|
providerKey: `${string}/${string}`;
|
|
@@ -38,6 +39,7 @@ export declare const PHI_ASSET_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
|
|
|
38
39
|
type: "boolean";
|
|
39
40
|
label: string;
|
|
40
41
|
description: string;
|
|
42
|
+
heading?: undefined;
|
|
41
43
|
optionsProvider?: undefined;
|
|
42
44
|
options?: undefined;
|
|
43
45
|
min?: undefined;
|
|
@@ -50,6 +52,7 @@ export declare const PHI_ASSET_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
|
|
|
50
52
|
value: string;
|
|
51
53
|
label: string;
|
|
52
54
|
}[];
|
|
55
|
+
heading?: undefined;
|
|
53
56
|
optionsProvider?: undefined;
|
|
54
57
|
description?: undefined;
|
|
55
58
|
min?: undefined;
|
|
@@ -60,6 +63,7 @@ export declare const PHI_ASSET_RUNTIME_DATA_PROVIDER_DESCRIPTORS: ({
|
|
|
60
63
|
label: string;
|
|
61
64
|
min: number;
|
|
62
65
|
max: number;
|
|
66
|
+
heading?: undefined;
|
|
63
67
|
optionsProvider?: undefined;
|
|
64
68
|
description?: undefined;
|
|
65
69
|
options?: undefined;
|
|
@@ -32,6 +32,7 @@ export declare const PHI_ASSET_RUNTIME_MODULE_DEFINITION: {
|
|
|
32
32
|
settingsFields: ({
|
|
33
33
|
key: string;
|
|
34
34
|
type: "choice";
|
|
35
|
+
heading: string;
|
|
35
36
|
label: string;
|
|
36
37
|
optionsProvider: {
|
|
37
38
|
providerKey: `${string}/${string}`;
|
|
@@ -45,6 +46,7 @@ export declare const PHI_ASSET_RUNTIME_MODULE_DEFINITION: {
|
|
|
45
46
|
type: "boolean";
|
|
46
47
|
label: string;
|
|
47
48
|
description: string;
|
|
49
|
+
heading?: undefined;
|
|
48
50
|
optionsProvider?: undefined;
|
|
49
51
|
options?: undefined;
|
|
50
52
|
min?: undefined;
|
|
@@ -57,6 +59,7 @@ export declare const PHI_ASSET_RUNTIME_MODULE_DEFINITION: {
|
|
|
57
59
|
value: string;
|
|
58
60
|
label: string;
|
|
59
61
|
}[];
|
|
62
|
+
heading?: undefined;
|
|
60
63
|
optionsProvider?: undefined;
|
|
61
64
|
description?: undefined;
|
|
62
65
|
min?: undefined;
|
|
@@ -67,6 +70,7 @@ export declare const PHI_ASSET_RUNTIME_MODULE_DEFINITION: {
|
|
|
67
70
|
label: string;
|
|
68
71
|
min: number;
|
|
69
72
|
max: number;
|
|
73
|
+
heading?: undefined;
|
|
70
74
|
optionsProvider?: undefined;
|
|
71
75
|
description?: undefined;
|
|
72
76
|
options?: undefined;
|
|
@@ -1,2 +1,54 @@
|
|
|
1
1
|
import type { PhiCmsRoutePresetDescriptor } from "../../../types/cms-module-descriptors";
|
|
2
|
-
export declare const PHI_ASSET_RUNTIME_MODULE_ROUTES: PhiCmsRoutePresetDescriptor
|
|
2
|
+
export declare const PHI_ASSET_RUNTIME_MODULE_ROUTES: (PhiCmsRoutePresetDescriptor | {
|
|
3
|
+
tour: {
|
|
4
|
+
readonly id: "@phis/ui/modules/asset/media";
|
|
5
|
+
readonly version: 1;
|
|
6
|
+
readonly steps: readonly [{
|
|
7
|
+
readonly key: "find";
|
|
8
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:filters`;
|
|
9
|
+
readonly title: "Finding an asset";
|
|
10
|
+
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.";
|
|
11
|
+
readonly placement: "bottom";
|
|
12
|
+
readonly ifMissing: "skip";
|
|
13
|
+
}, {
|
|
14
|
+
readonly key: "upload";
|
|
15
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:toolbar`;
|
|
16
|
+
readonly title: "Adding files";
|
|
17
|
+
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.";
|
|
18
|
+
readonly placement: "bottom";
|
|
19
|
+
readonly ifMissing: "skip";
|
|
20
|
+
}, {
|
|
21
|
+
readonly key: "library";
|
|
22
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:items`;
|
|
23
|
+
readonly title: "The Site's library";
|
|
24
|
+
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.";
|
|
25
|
+
readonly placement: "top";
|
|
26
|
+
}, {
|
|
27
|
+
readonly key: "inspector";
|
|
28
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:items`;
|
|
29
|
+
readonly title: "What an asset says about itself";
|
|
30
|
+
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.";
|
|
31
|
+
readonly placement: "top";
|
|
32
|
+
}, {
|
|
33
|
+
readonly key: "pages";
|
|
34
|
+
readonly target: `cms:${import("@phis/contracts/cms").PhiCmsInstanceId}:pagination`;
|
|
35
|
+
readonly title: "Page by page";
|
|
36
|
+
readonly description: "The library is shown a page at a time; how many fit on one is chosen here.";
|
|
37
|
+
readonly placement: "top";
|
|
38
|
+
readonly ifMissing: "skip";
|
|
39
|
+
}];
|
|
40
|
+
};
|
|
41
|
+
ownerModuleId: import("../contracts").PhiRuntimeModuleId;
|
|
42
|
+
presetKey: string;
|
|
43
|
+
presetVersion: number;
|
|
44
|
+
area: import("@phis/contracts/cms").PhiCmsAreaKey;
|
|
45
|
+
path: string;
|
|
46
|
+
landingPage?: true;
|
|
47
|
+
title: string;
|
|
48
|
+
defaultPageFlags?: number;
|
|
49
|
+
loadTree: (context: import("../../../types").PhiCmsDescriptorBuildContext & {
|
|
50
|
+
activeModuleIds: ReadonlySet<import("../contracts").PhiRuntimeModuleId>;
|
|
51
|
+
params: Readonly<Record<string, string>>;
|
|
52
|
+
}) => import("../../../types").PhiResolvedCmsPageTree | Promise<import("../../../types").PhiResolvedCmsPageTree>;
|
|
53
|
+
navigation?: readonly import("../../../types").PhiCmsNavigationInjectionDescriptor[];
|
|
54
|
+
})[];
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { PHI_ASSET_RUNTIME_MODULE_ID } from "./ids";
|
|
2
2
|
import { buildPhiSidebarRoutePresetDescriptor } from "../sidebar-route";
|
|
3
|
+
import { PHI_ASSET_MEDIA_TOUR } from "./tour";
|
|
3
4
|
export const PHI_ASSET_RUNTIME_MODULE_ROUTES = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
{
|
|
6
|
+
...buildPhiSidebarRoutePresetDescriptor({
|
|
7
|
+
area: "builder",
|
|
8
|
+
anchor: "main",
|
|
9
|
+
ownerModuleId: PHI_ASSET_RUNTIME_MODULE_ID,
|
|
10
|
+
presetKey: "builder-media-page",
|
|
11
|
+
title: "Media",
|
|
12
|
+
path: "/media",
|
|
13
|
+
itemKey: "@phis/ui/modules/asset/nav/builder/media",
|
|
14
|
+
icon: "antd:picture",
|
|
15
|
+
loadTree: ({ page, runtime }) => import("./trees/phi-default-builder-media-page-tree")
|
|
16
|
+
.then((module) => module.buildPhiDefaultBuilderMediaPageTree({ page, runtime })),
|
|
17
|
+
}),
|
|
18
|
+
tour: PHI_ASSET_MEDIA_TOUR,
|
|
19
|
+
},
|
|
16
20
|
buildPhiSidebarRoutePresetDescriptor({
|
|
17
21
|
area: "admin",
|
|
18
22
|
anchor: "settings",
|