@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.
- 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.d.ts +6 -1
- package/components/controls/phi-table-control.js +17 -5
- 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 +2 -20
- package/components/layouts/layout-definitions.js +13 -2
- 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/shell/use-phi-shell-sticky-top.d.ts +5 -0
- package/components/shell/use-phi-shell-sticky-top.js +78 -0
- 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/helpers/semantic-html-translation.d.ts +3 -1
- package/components/widgets/helpers/semantic-html-translation.js +8 -3
- 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/components/widgets/navigation-descriptor-resolver.server.js +6 -1
- package/components/widgets/shared/markdown-render.js +15 -5
- 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/helpers/text-source.d.ts +19 -0
- package/helpers/text-source.js +20 -0
- package/next/config.mjs +1 -1
- 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/auth/trees/phi-default-pub-confirm-page-tree.js +3 -0
- package/plugins/runtime-modules/auth/trees/phi-default-pub-login-page-tree.js +2 -0
- package/plugins/runtime-modules/auth/trees/phi-default-pub-registration-page-tree.js +3 -0
- package/plugins/runtime-modules/auth/trees/phi-default-pub-reset-password-page-tree.js +3 -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/widget-inspector.js +9 -0
- 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/trees/phi-default-builder-area-preset-tree.js +4 -0
- package/plugins/runtime-modules/builder/widgets/structure-region/built-in.js +3 -2
- package/plugins/runtime-modules/core/widgets/card/server.js +4 -2
- package/plugins/runtime-modules/core/widgets/collection-view/client.js +10 -0
- package/plugins/runtime-modules/core/widgets/description/config.d.ts +28 -1
- package/plugins/runtime-modules/core/widgets/description/config.js +2 -0
- package/plugins/runtime-modules/core/widgets/description/server.js +10 -12
- 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 +4 -2
- 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/html/server.js +1 -1
- 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/markdown-toc/server.js +7 -2
- package/plugins/runtime-modules/core/widgets/quick-links/config.d.ts +3 -0
- package/plugins/runtime-modules/core/widgets/quick-links/config.js +2 -0
- package/plugins/runtime-modules/core/widgets/quick-links/plugin.js +4 -2
- package/plugins/runtime-modules/core/widgets/quick-links/server.d.ts +5 -1
- package/plugins/runtime-modules/core/widgets/quick-links/server.js +4 -2
- package/plugins/runtime-modules/core/widgets/result/config.d.ts +25 -1
- package/plugins/runtime-modules/core/widgets/simple-text/config.d.ts +28 -1
- package/plugins/runtime-modules/core/widgets/simple-text/config.js +2 -0
- package/plugins/runtime-modules/core/widgets/simple-text/plugin.js +1 -1
- package/plugins/runtime-modules/core/widgets/simple-text/server.d.ts +4 -1
- package/plugins/runtime-modules/core/widgets/simple-text/server.js +3 -3
- package/plugins/runtime-modules/core/widgets/table/client.js +1 -1
- package/plugins/runtime-modules/core/widgets/table/config.d.ts +80 -3
- package/plugins/runtime-modules/core/widgets/table/config.js +3 -0
- package/plugins/runtime-modules/core/widgets/tour-button/client.js +1 -1
- package/plugins/runtime-modules/phi-default-site-area-preset-tree.js +12 -4
- package/plugins/runtime-modules/public/trees/phi-default-pub-contact-page-tree.js +2 -0
- package/plugins/runtime-modules/public/trees/phi-default-pub-unsubscribe-page-tree.js +3 -0
- package/plugins/runtime-modules/public/trees/phi-default-pub-welcome-page-tree.js +2 -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/revisions/trees/phi-default-builder-revisions-page-tree.js +4 -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/server-helpers/translate.d.ts +9 -0
- package/server-helpers/translate.js +14 -0
- package/styles/controls.css +15 -1
- package/styles/root.css +20 -19
- 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/core-widget-placements.d.ts +5 -0
- package/types/table-widget.d.ts +2 -0
- 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
|
@@ -5,10 +5,11 @@ import { getPhiContentEntryReaderLabels } from "../../../../../components/widget
|
|
|
5
5
|
import { PhiCmsWidgetType } from "../../../../../constants/cms-widget-types";
|
|
6
6
|
import { fetchPhiSiteContentEntries } from "../../../../../gateway/content-entries";
|
|
7
7
|
import { phiRuntime } from "../../../../../server-helpers/phi-runtime";
|
|
8
|
-
import {
|
|
8
|
+
import { trBulkForLocale } from "../../../../../server-helpers/translate";
|
|
9
9
|
import { readPhiBoundContentEntry } from "../../content-entries/record-source.server";
|
|
10
10
|
import { buildPhiEntryViews } from "./view.server";
|
|
11
11
|
import { normalizePhiEntryListWidgetConfig } from "./config";
|
|
12
|
+
import { pickPhiSequenceSettings } from "../../../../../components/widgets/config/sequence-settings";
|
|
12
13
|
/**
|
|
13
14
|
* One kind's published entries, read while the page is drawn (`CONTENT_ENTRIES.md`).
|
|
14
15
|
*
|
|
@@ -73,11 +74,12 @@ export async function PhiEntryListWidget({ config, runtime, registry, links, tra
|
|
|
73
74
|
// A stacked entry's title is an `h2`; its text's headings start under it.
|
|
74
75
|
headingOffset: 2,
|
|
75
76
|
});
|
|
76
|
-
const [title] = settings.title && translate ? await
|
|
77
|
+
const [title] = settings.title && translate ? await trBulkForLocale(locale, [settings.title]) : [settings.title];
|
|
77
78
|
return (_jsx(PhiRuntimeModuleRenderClientHost, { type: PhiCmsWidgetType.EntryList, componentProps: {
|
|
78
79
|
entries: views,
|
|
79
80
|
labels,
|
|
80
81
|
presentation: settings.presentation,
|
|
82
|
+
...(settings.presentation === "slideshow" ? { sequence: pickPhiSequenceSettings(settings) } : {}),
|
|
81
83
|
parts: settings.show,
|
|
82
84
|
...(title ? { title } : {}),
|
|
83
85
|
emptyBehavior: related ? "hide" : "say",
|
|
@@ -1,18 +1,70 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { usePhiConfig } from "../../../../../components/root/phi-config-provider";
|
|
4
|
+
import { PhiTypographyControl } from "../../../../../components/controls/phi-typography-control";
|
|
5
|
+
import { PhiIcon } from "../../../../../components/shell/phi-icon";
|
|
3
6
|
import { createPhiCmsBuilderWidgetPlugin } from "../../../../../plugins/factories/widget-builder-plugin";
|
|
4
|
-
import { PhiWidgetEditorPlaceholder } from "../../../../../components/widgets/builder/widget-editor-placeholder";
|
|
5
7
|
import { PHI_GALLERY_WIDGET_DEFINITION, } from "./config";
|
|
8
|
+
import { resolvePhiSpacingScaleValue } from "../../../../../components/widgets/config/spacing-options";
|
|
9
|
+
import { PHI_SEQUENCE_SETTINGS_DEFAULTS } from "../../../../../components/widgets/config/sequence-settings";
|
|
10
|
+
import { resolvePhiGalleryFrame } from "./defaults";
|
|
11
|
+
/** How many dots stand for "more than one page" on the canvas, which does not know how many pictures there are. */
|
|
12
|
+
const EDITOR_DOT_COUNT = 3;
|
|
6
13
|
/**
|
|
7
|
-
*
|
|
14
|
+
* The Gallery's window, drawn empty.
|
|
8
15
|
*
|
|
9
|
-
* The Folder is read when the page is drawn, and what is in it then is what a visitor sees
|
|
10
|
-
*
|
|
16
|
+
* The Folder is read when the page is drawn, and what is in it then is what a visitor sees, so the
|
|
17
|
+
* canvas fetches nothing. What it can show is everything the author set: as many frames as pictures
|
|
18
|
+
* stand side by side, in the variant's proportion or the one set for originals, at their distance,
|
|
19
|
+
* with the arrows and dots the controls ask for. A change in the Inspector is a change on the canvas,
|
|
20
|
+
* which a sentence never was.
|
|
11
21
|
*/
|
|
12
|
-
function
|
|
22
|
+
function PhiGalleryWidgetEditor({ config }) {
|
|
23
|
+
const { token } = usePhiConfig();
|
|
24
|
+
const visibleCount = config?.visibleCount ?? PHI_SEQUENCE_SETTINGS_DEFAULTS.visibleCount;
|
|
25
|
+
const controls = config?.controls ?? PHI_SEQUENCE_SETTINGS_DEFAULTS.controls;
|
|
26
|
+
const showArrows = controls === "arrows" || controls === "both";
|
|
27
|
+
const showDots = controls === "dots" || controls === "both";
|
|
13
28
|
const folderId = config?.source?.params?.folderId;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
const hasFolder = folderId != null && folderId !== "";
|
|
30
|
+
const { aspectRatio } = resolvePhiGalleryFrame(config);
|
|
31
|
+
const arrowStyle = {
|
|
32
|
+
position: "absolute",
|
|
33
|
+
insetBlockStart: "50%",
|
|
34
|
+
transform: "translateY(-50%)",
|
|
35
|
+
display: "inline-flex",
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
justifyContent: "center",
|
|
38
|
+
width: token.controlHeight,
|
|
39
|
+
height: token.controlHeight,
|
|
40
|
+
borderRadius: "50%",
|
|
41
|
+
background: token.colorBgElevated,
|
|
42
|
+
boxShadow: token.boxShadowTertiary,
|
|
43
|
+
color: token.colorTextSecondary,
|
|
44
|
+
pointerEvents: "none",
|
|
45
|
+
};
|
|
46
|
+
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: token.marginXS, width: "100%", minWidth: 0 }, children: [_jsxs("div", { style: { position: "relative", minWidth: 0 }, children: [_jsx("div", { style: { display: "flex", gap: resolvePhiSpacingScaleValue(config?.gap ?? PHI_SEQUENCE_SETTINGS_DEFAULTS.gap), minWidth: 0 }, children: Array.from({ length: visibleCount }, (_, index) => (_jsxs("div", { style: {
|
|
47
|
+
flex: "1 1 0",
|
|
48
|
+
minWidth: 0,
|
|
49
|
+
aspectRatio,
|
|
50
|
+
display: "flex",
|
|
51
|
+
flexDirection: "column",
|
|
52
|
+
alignItems: "center",
|
|
53
|
+
justifyContent: "center",
|
|
54
|
+
gap: token.marginXXS,
|
|
55
|
+
borderRadius: token.borderRadius,
|
|
56
|
+
border: `1px dashed ${token.colorBorder}`,
|
|
57
|
+
background: token.colorFillQuaternary,
|
|
58
|
+
color: token.colorTextTertiary,
|
|
59
|
+
fontSize: token.fontSizeLG,
|
|
60
|
+
overflow: "hidden",
|
|
61
|
+
}, children: [_jsx(PhiIcon, { name: "picture", size: "inherit" }), _jsx("span", { style: { fontSize: token.fontSizeSM }, children: index + 1 })] }, index))) }), showArrows ? (_jsxs(_Fragment, { children: [_jsx("span", { style: { ...arrowStyle, insetInlineStart: token.marginXS }, children: _jsx(PhiIcon, { name: "left", size: "inherit" }) }), _jsx("span", { style: { ...arrowStyle, insetInlineEnd: token.marginXS }, children: _jsx(PhiIcon, { name: "right", size: "inherit" }) })] })) : null] }), showDots ? (_jsx("div", { style: { display: "flex", justifyContent: "center", gap: token.marginXXS }, children: Array.from({ length: EDITOR_DOT_COUNT }, (_, page) => (_jsx("span", { style: {
|
|
62
|
+
width: page === 0 ? token.controlHeightXS : token.marginXS,
|
|
63
|
+
height: token.marginXS,
|
|
64
|
+
borderRadius: token.borderRadiusSM,
|
|
65
|
+
background: page === 0 ? token.colorPrimary : token.colorFill,
|
|
66
|
+
} }, page))) })) : null, _jsx(PhiTypographyControl, { type: "secondary", style: { fontSize: token.fontSizeSM }, children: hasFolder
|
|
67
|
+
? "The public pictures of the chosen media folder, read when the page is drawn."
|
|
68
|
+
: "No folder chosen yet. Pick one in the inspector; its public pictures are read when the page is drawn." })] }));
|
|
17
69
|
}
|
|
18
|
-
export const PHI_GALLERY_WIDGET_BUILDER_PLUGIN = createPhiCmsBuilderWidgetPlugin(PHI_GALLERY_WIDGET_DEFINITION, ({
|
|
70
|
+
export const PHI_GALLERY_WIDGET_BUILDER_PLUGIN = createPhiCmsBuilderWidgetPlugin(PHI_GALLERY_WIDGET_DEFINITION, ({ config }) => _jsx(PhiGalleryWidgetEditor, { config: config ?? undefined }));
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type PhiGalleryWidgetLabels } from "../../../../../components/widgets/label-types/gallery";
|
|
2
2
|
import type { PhiPublicMediaAssetReference } from "../../../../../types/media";
|
|
3
3
|
import type { PhiCmsGalleryWidgetConfig } from "./config";
|
|
4
|
+
/**
|
|
5
|
+
* A run of pictures. How it moves and stops is `PhiSequenceRun`'s; what is here is the picture: its
|
|
6
|
+
* rendition, its frame, and that it loads eagerly -- the run mounts only what its window wants, so
|
|
7
|
+
* reaching a picture already means it is wanted.
|
|
8
|
+
*/
|
|
4
9
|
export type PhiGalleryWidgetProps = {
|
|
5
10
|
config?: PhiCmsGalleryWidgetConfig;
|
|
6
11
|
/** The server's answer to the binding: public Assets, in the order the Folder was asked for. */
|
|
7
12
|
images?: PhiPublicMediaAssetReference[];
|
|
8
13
|
labels?: PhiGalleryWidgetLabels;
|
|
9
14
|
};
|
|
10
|
-
export declare function PhiGalleryWidget({ config, images: imagesInput, labels: labelsInput }: PhiGalleryWidgetProps): import("react").JSX.Element
|
|
15
|
+
export declare function PhiGalleryWidget({ config, images: imagesInput, labels: labelsInput }: PhiGalleryWidgetProps): import("react").JSX.Element;
|
|
@@ -1,37 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { usePhiConfig } from "../../../../../components/root/phi-config-provider";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { usePhiSequenceAutoplay } from "../../../../../components/motion/use-phi-sequence-autoplay";
|
|
7
|
-
import { usePhiSequenceGestures } from "../../../../../components/motion/use-phi-sequence-gestures";
|
|
8
|
-
import { resolvePhiCarouselCurrentPage, resolvePhiCarouselPageStarts, resolvePhiCarouselStep, } from "../../../../../components/layouts/phi-carousel-pages";
|
|
9
|
-
import { PhiButtonControl } from "../../../../../components/controls/phi-button-control";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { PhiSequenceRun, resolvePhiSequenceRunSpan } from "../../../../../components/motion/phi-sequence-run";
|
|
10
6
|
import { PhiImageControl } from "../../../../../components/controls/phi-image-control";
|
|
11
7
|
import { readPhiAspectRatio, resolvePhiImagePresentation } from "../../../../../components/media/image-presentation";
|
|
12
|
-
import { PhiIcon } from "../../../../../components/shell/phi-icon";
|
|
13
8
|
import { PHI_GALLERY_WIDGET_DEFAULT_LABELS, } from "../../../../../components/widgets/label-types/gallery";
|
|
14
9
|
import { isPhiMediaSvgContentType } from "../../../../../constants/media";
|
|
15
|
-
|
|
16
|
-
* A run of pictures, and the two things the browser will not do for us.
|
|
17
|
-
*
|
|
18
|
-
* The first is knowing which picture is next. Native lazy loading decides from an element's distance
|
|
19
|
-
* to the viewport, so on a fade -- where every picture sits in the same place -- it loads all of them
|
|
20
|
-
* at once, and on a slide it loads the next one as it arrives, during the transition. Next's escape
|
|
21
|
-
* hatch for a scrolling container, `lazyRoot`, is a deprecated no-op in Next 16. So the window says
|
|
22
|
-
* what loads: what is mounted is wanted, and what is wanted is fetched eagerly.
|
|
23
|
-
*
|
|
24
|
-
* The second is stopping: `usePhiSequenceAutoplay` holds every way to decline movement nobody asked
|
|
25
|
-
* for, and the Pause button is the one a finger has, since a finger neither hovers nor tabs. Where
|
|
26
|
-
* the window stops -- the last window rather than the last multiple of the window -- is the Carousel
|
|
27
|
-
* Layout's list of stops (`phi-carousel-pages.ts`), read by the arrows, the dots and the timer alike.
|
|
28
|
-
*/
|
|
29
|
-
const DEFAULT_ASPECT_RATIO = "16 / 9";
|
|
30
|
-
/** The dots' label, `%1` the first and `%2` the last picture a page shows. */
|
|
31
|
-
function formatPageLabel(template, from, to) {
|
|
32
|
-
return template.replace("%1", String(from)).replace("%2", String(to));
|
|
33
|
-
}
|
|
34
|
-
const DEFAULT_GAP = "8px";
|
|
10
|
+
import { resolvePhiGalleryFrame } from "./defaults";
|
|
35
11
|
function GalleryPicture({ image, variantKey, fit, preview, sizes, aspectRatio, }) {
|
|
36
12
|
const presentation = resolvePhiImagePresentation({
|
|
37
13
|
sourceKind: "asset",
|
|
@@ -66,62 +42,14 @@ export function PhiGalleryWidget({ config, images: imagesInput, labels: labelsIn
|
|
|
66
42
|
const { token } = usePhiConfig();
|
|
67
43
|
const labels = labelsInput ?? PHI_GALLERY_WIDGET_DEFAULT_LABELS;
|
|
68
44
|
const images = useMemo(() => imagesInput ?? [], [imagesInput]);
|
|
69
|
-
const
|
|
70
|
-
const windowAnchor = config?.windowAnchor ?? "start";
|
|
71
|
-
const loop = config?.loop ?? false;
|
|
72
|
-
const controls = config?.controls ?? "both";
|
|
73
|
-
const autoplayMs = config?.autoplayMs ?? 0;
|
|
74
|
-
const [activeIndex, setActiveIndex] = useState(0);
|
|
75
|
-
const span = Math.min(visibleCount, Math.max(images.length, 1));
|
|
76
|
-
const pageStarts = useMemo(() => resolvePhiCarouselPageStarts(images.length, span), [images.length, span]);
|
|
77
|
-
const lastStart = pageStarts[pageStarts.length - 1] ?? 0;
|
|
78
|
-
const step = useCallback((direction) => {
|
|
79
|
-
setActiveIndex((current) => resolvePhiCarouselStep(pageStarts, current, direction, loop));
|
|
80
|
-
}, [loop, pageStarts]);
|
|
81
|
-
const advance = useCallback(() => step(1), [step]);
|
|
82
|
-
const autoplay = usePhiSequenceAutoplay({ intervalMs: autoplayMs, active: images.length > span, advance });
|
|
83
|
-
// A step somebody took: the next automatic one is a whole interval away again.
|
|
84
|
-
const stepByHand = useCallback((direction) => {
|
|
85
|
-
step(direction);
|
|
86
|
-
autoplay.restart();
|
|
87
|
-
}, [autoplay, step]);
|
|
88
|
-
const gestures = usePhiSequenceGestures({ step: stepByHand });
|
|
89
|
-
if (images.length === 0) {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
const windowStart = resolvePhiSequenceWindowStart({
|
|
93
|
-
activeIndex: activeIndex,
|
|
94
|
-
visibleCount: span,
|
|
95
|
-
itemCount: images.length,
|
|
96
|
-
anchor: windowAnchor,
|
|
97
|
-
});
|
|
98
|
-
const lookahead = config?.lookahead ?? 1;
|
|
99
|
-
const pageCount = pageStarts.length;
|
|
100
|
-
const currentPage = resolvePhiCarouselCurrentPage(pageStarts, windowStart);
|
|
45
|
+
const span = resolvePhiSequenceRunSpan(config?.visibleCount, images.length);
|
|
101
46
|
// What a picture of this window is worth of the viewport, for the optimiser's choice of rendition.
|
|
102
47
|
const sizes = span === 1 ? "100vw" : `(max-width: 768px) 100vw, ${Math.ceil(100 / span)}vw`;
|
|
103
|
-
const aspectRatio = config
|
|
48
|
+
const { aspectRatio, fit } = resolvePhiGalleryFrame(config);
|
|
104
49
|
const frameStyle = {
|
|
105
50
|
minWidth: 0,
|
|
106
51
|
borderRadius: token.borderRadius,
|
|
107
52
|
overflow: "hidden",
|
|
108
53
|
};
|
|
109
|
-
|
|
110
|
-
const atEnd = windowStart >= lastStart;
|
|
111
|
-
// Two disabled arrows over a single picture say nothing; the dots already know to stay away.
|
|
112
|
-
const showArrows = (controls === "arrows" || controls === "both") && images.length > span;
|
|
113
|
-
const showDots = (controls === "dots" || controls === "both") && pageCount > 1;
|
|
114
|
-
return (_jsxs("div", { role: "region", "aria-roledescription": "carousel", "aria-label": labels.region, style: { display: "flex", flexDirection: "column", gap: token.marginXS, width: "100%", minWidth: 0, ...gestures.style }, ...autoplay.holdHandlers, ...gestures.handlers, children: [_jsxs("div", { style: { position: "relative", minWidth: 0 }, "aria-live": autoplay.running ? "off" : "polite", children: [_jsx(PhiSequenceViewport, { items: images.map((image) => (_jsx(GalleryPicture, { image: image, variantKey: config?.variantKey, fit: config?.fit ?? "cover", preview: config?.preview === true, sizes: sizes, aspectRatio: aspectRatio }, image.id))), activeIndex: activeIndex, visibleCount: span, anchor: windowAnchor, transition: config?.transition ?? "slide", ...(config?.durationMs === undefined ? {} : { durationMs: config.durationMs }), ...(config?.easing === undefined ? {} : { easing: config.easing }), lookahead: lookahead, mountPolicy: config?.mountPolicy ?? "lazy-keep", gap: config?.gap ?? DEFAULT_GAP, itemStyle: frameStyle }), showArrows ? (_jsxs(_Fragment, { children: [_jsx("div", { style: { position: "absolute", insetBlockStart: "50%", insetInlineStart: token.marginXS, transform: "translateY(-50%)" }, children: _jsx(PhiButtonControl, { icon: _jsx(PhiIcon, { name: "left", size: "inherit" }), ariaLabel: labels.previous, shape: "circle", disabled: atStart && !loop, onClick: () => stepByHand(-1) }) }), _jsx("div", { style: { position: "absolute", insetBlockStart: "50%", insetInlineEnd: token.marginXS, transform: "translateY(-50%)" }, children: _jsx(PhiButtonControl, { icon: _jsx(PhiIcon, { name: "right", size: "inherit" }), ariaLabel: labels.next, shape: "circle", disabled: atEnd && !loop, onClick: () => stepByHand(1) }) })] })) : null, autoplay.offered ? (_jsx("div", { style: { position: "absolute", insetBlockEnd: token.marginXS, insetInlineEnd: token.marginXS }, children: _jsx(PhiButtonControl, { icon: _jsx(PhiIcon, { name: autoplay.stopped ? "play-circle" : "pause-circle", size: "inherit" }), ariaLabel: autoplay.stopped ? labels.play : labels.pause, ariaPressed: autoplay.stopped, shape: "circle", onClick: autoplay.toggleStopped }) })) : null] }), showDots ? (_jsx("div", { role: "group", "aria-label": labels.pages, style: { display: "flex", justifyContent: "center", gap: token.marginXXS }, children: Array.from({ length: pageCount }, (_, page) => (_jsx("button", { type: "button", "aria-label": formatPageLabel(labels.page, (pageStarts[page] ?? 0) + 1, Math.min((pageStarts[page] ?? 0) + span, images.length)), "aria-current": page === currentPage || undefined, onClick: () => {
|
|
115
|
-
setActiveIndex(pageStarts[page] ?? 0);
|
|
116
|
-
autoplay.restart();
|
|
117
|
-
}, style: {
|
|
118
|
-
width: page === currentPage ? token.controlHeightXS : token.marginXS,
|
|
119
|
-
height: token.marginXS,
|
|
120
|
-
padding: 0,
|
|
121
|
-
border: "none",
|
|
122
|
-
cursor: "pointer",
|
|
123
|
-
borderRadius: token.borderRadiusSM,
|
|
124
|
-
background: page === currentPage ? token.colorPrimary : token.colorFill,
|
|
125
|
-
transition: `width ${token.motionDurationMid}, background ${token.motionDurationMid}`,
|
|
126
|
-
} }, page))) })) : null] }));
|
|
54
|
+
return (_jsx(PhiSequenceRun, { items: images.map((image) => (_jsx(GalleryPicture, { image: image, variantKey: config?.variantKey, fit: fit, preview: config?.preview === true, sizes: sizes, aspectRatio: aspectRatio }, image.id))), settings: config, labels: labels, itemStyle: frameStyle }));
|
|
127
55
|
}
|