@drawnagency/primitives 0.1.118 → 0.1.119
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/dist/{chunk-O37AV27P.js → chunk-5JYHTHVR.js} +28 -0
- package/dist/{chunk-W72BPGR3.js → chunk-BZKHHUIN.js} +44 -8
- package/dist/{chunk-CEFFP3CH.js → chunk-G6O3TYPJ.js} +297 -83
- package/dist/{chunk-4NSOKEA7.js → chunk-HFHM4MNK.js} +12 -7
- package/dist/{chunk-RIITGTV3.js → chunk-LQHBC7C6.js} +37 -2
- package/dist/{chunk-VY3IFGE3.js → chunk-QAMAIDXZ.js} +1 -1
- package/dist/{chunk-HRX3XJBU.js → chunk-RIN2QCYJ.js} +9 -11
- package/dist/{chunk-ZOTRHHUB.js → chunk-UNFPATDE.js} +8 -10
- package/dist/{chunk-ERLIL4RU.js → chunk-YKKGVSJH.js} +35 -37
- package/dist/{chunk-67P34WNW.js → chunk-ZKVQMIMJ.js} +3 -20
- package/dist/collab/rebase.js +4 -5
- package/dist/components/chat/ChatComposer.d.ts +0 -4
- package/dist/components/chat/ChatComposer.d.ts.map +1 -1
- package/dist/components/chat/ChatPanel.d.ts +2 -3
- package/dist/components/chat/ChatPanel.d.ts.map +1 -1
- package/dist/components/chat/markdown.d.ts +2 -3
- package/dist/components/chat/markdown.d.ts.map +1 -1
- package/dist/components/editor/PagesModal.d.ts +0 -2
- package/dist/components/editor/PagesModal.d.ts.map +1 -1
- package/dist/components/editor/index.js +15 -19
- package/dist/components/primitives/index.js +11 -15
- package/dist/components/sections/brand-guide.js +10 -13
- package/dist/components/sections/register-schemas.js +16 -21
- package/dist/components/sections/register.js +16 -21
- package/dist/components/shell/AudienceChips.d.ts +1 -3
- package/dist/components/shell/AudienceChips.d.ts.map +1 -1
- package/dist/components/shell/EditorShell.d.ts +0 -34
- package/dist/components/shell/EditorShell.d.ts.map +1 -1
- package/dist/components/shell/SiteSettingsModal.d.ts.map +1 -1
- package/dist/hooks/useSortableNavRow.d.ts +1 -1
- package/dist/hooks/useSortableRow.d.ts +1 -1
- package/dist/index.js +83 -90
- package/dist/lib/index-ops.js +5 -6
- package/dist/lib/index.js +27 -32
- package/dist/lib/pages.d.ts +0 -2
- package/dist/lib/pages.d.ts.map +1 -1
- package/dist/lib/sidecars.js +2 -2
- package/dist/lib/site-validation.js +13 -14
- package/dist/lib/storage-tier.js +4 -4
- package/dist/schemas/index.js +42 -45
- package/dist/schemas/site-config.d.ts +1 -277
- package/dist/schemas/site-config.d.ts.map +1 -1
- package/package.json +2 -42
- package/src/components/chat/ChatComposer.tsx +0 -4
- package/src/components/chat/ChatPanel.tsx +2 -3
- package/src/components/chat/markdown.ts +2 -3
- package/src/components/editor/PagesModal.tsx +1 -15
- package/src/components/editor/StatusIndicator.tsx +4 -4
- package/src/components/shell/AudienceChips.tsx +1 -3
- package/src/components/shell/EditorShell.tsx +5 -113
- package/src/components/shell/SiteSettingsModal.tsx +0 -11
- package/src/lib/pages.ts +0 -22
- package/src/schemas/index.ts +0 -4
- package/src/schemas/site-config.ts +4 -32
- package/dist/chunk-4TZJZU2T.js +0 -92
- package/dist/chunk-DIMDRBFK.js +0 -11
- package/dist/chunk-FV7JQRCN.js +0 -94
- package/dist/chunk-IIDKW7AV.js +0 -41
- package/dist/chunk-JCDZAFX2.js +0 -224
- package/dist/chunk-MM7KZS5C.js +0 -30
- package/dist/chunk-QQ3S3P5P.js +0 -38
- package/dist/chunk-TEOAKGZA.js +0 -784
- package/dist/chunk-VAYZJKVR.js +0 -209
- package/dist/components/shell/DocInspector.d.ts +0 -18
- package/dist/components/shell/DocInspector.d.ts.map +0 -1
- package/dist/components/shell/DocumentEditorOverlay.d.ts +0 -29
- package/dist/components/shell/DocumentEditorOverlay.d.ts.map +0 -1
- package/dist/components/shell/DocumentPresentOverlay.d.ts +0 -30
- package/dist/components/shell/DocumentPresentOverlay.d.ts.map +0 -1
- package/dist/components/shell/SiteSettingsDecks.d.ts +0 -13
- package/dist/components/shell/SiteSettingsDecks.d.ts.map +0 -1
- package/dist/deck/DeckComponentView.d.ts +0 -13
- package/dist/deck/DeckComponentView.d.ts.map +0 -1
- package/dist/deck/DeckPlayer.d.ts +0 -26
- package/dist/deck/DeckPlayer.d.ts.map +0 -1
- package/dist/deck/DeckSlideView.d.ts +0 -17
- package/dist/deck/DeckSlideView.d.ts.map +0 -1
- package/dist/deck/DeckStage.d.ts +0 -16
- package/dist/deck/DeckStage.d.ts.map +0 -1
- package/dist/deck/components/DeckImage.d.ts +0 -14
- package/dist/deck/components/DeckImage.d.ts.map +0 -1
- package/dist/deck/components/DeckImageGrid.d.ts +0 -27
- package/dist/deck/components/DeckImageGrid.d.ts.map +0 -1
- package/dist/deck/components/DeckRichText.d.ts +0 -22
- package/dist/deck/components/DeckRichText.d.ts.map +0 -1
- package/dist/deck/components/DeckVideo.d.ts +0 -15
- package/dist/deck/components/DeckVideo.d.ts.map +0 -1
- package/dist/deck/editing.d.ts +0 -50
- package/dist/deck/editing.d.ts.map +0 -1
- package/dist/deck/flip.d.ts +0 -11
- package/dist/deck/flip.d.ts.map +0 -1
- package/dist/deck/index.d.ts +0 -24
- package/dist/deck/index.d.ts.map +0 -1
- package/dist/deck/index.js +0 -51
- package/dist/deck/layouts/CenteredTextLayout.d.ts +0 -12
- package/dist/deck/layouts/CenteredTextLayout.d.ts.map +0 -1
- package/dist/deck/layouts/ColumnSplitLayout.d.ts +0 -14
- package/dist/deck/layouts/ColumnSplitLayout.d.ts.map +0 -1
- package/dist/deck/layouts/FullBleedImageLayout.d.ts +0 -14
- package/dist/deck/layouts/FullBleedImageLayout.d.ts.map +0 -1
- package/dist/deck/media.d.ts +0 -33
- package/dist/deck/media.d.ts.map +0 -1
- package/dist/deck/tokens.d.ts +0 -22
- package/dist/deck/tokens.d.ts.map +0 -1
- package/dist/deck/useStageScale.d.ts +0 -10
- package/dist/deck/useStageScale.d.ts.map +0 -1
- package/dist/deck-builder/DeckBuilderApp.d.ts +0 -30
- package/dist/deck-builder/DeckBuilderApp.d.ts.map +0 -1
- package/dist/deck-builder/DeckBuilderTopBar.d.ts +0 -24
- package/dist/deck-builder/DeckBuilderTopBar.d.ts.map +0 -1
- package/dist/deck-builder/DeckChatPanel.d.ts +0 -45
- package/dist/deck-builder/DeckChatPanel.d.ts.map +0 -1
- package/dist/deck-builder/DeckEditor.d.ts +0 -37
- package/dist/deck-builder/DeckEditor.d.ts.map +0 -1
- package/dist/deck-builder/DeckLibrary.d.ts +0 -22
- package/dist/deck-builder/DeckLibrary.d.ts.map +0 -1
- package/dist/deck-builder/DeckSlideSurface.d.ts +0 -31
- package/dist/deck-builder/DeckSlideSurface.d.ts.map +0 -1
- package/dist/deck-builder/deck-api.d.ts +0 -76
- package/dist/deck-builder/deck-api.d.ts.map +0 -1
- package/dist/deck-builder/deck-chat-client.d.ts +0 -44
- package/dist/deck-builder/deck-chat-client.d.ts.map +0 -1
- package/dist/deck-builder/deck-chat-history.d.ts +0 -10
- package/dist/deck-builder/deck-chat-history.d.ts.map +0 -1
- package/dist/deck-builder/index.d.ts +0 -13
- package/dist/deck-builder/index.d.ts.map +0 -1
- package/dist/deck-builder/index.js +0 -1498
- package/dist/deck-builder/starter-deck.d.ts +0 -23
- package/dist/deck-builder/starter-deck.d.ts.map +0 -1
- package/dist/deck-builder/types.d.ts +0 -29
- package/dist/deck-builder/types.d.ts.map +0 -1
- package/dist/deck-builder/useSortableSlide.d.ts +0 -29
- package/dist/deck-builder/useSortableSlide.d.ts.map +0 -1
- package/dist/document/assets/fonts/albra-grotesk-bold.woff +0 -0
- package/dist/document/assets/fonts/albra-grotesk-regular.woff +0 -0
- package/dist/document/assets/fonts/kapra-neue-expanded-medium.woff +0 -0
- package/dist/document/assets/fonts/kapra-neue-expanded-regular.woff +0 -0
- package/dist/document/components/DocCoverPage.d.ts +0 -11
- package/dist/document/components/DocCoverPage.d.ts.map +0 -1
- package/dist/document/components/DocPage.d.ts +0 -10
- package/dist/document/components/DocPage.d.ts.map +0 -1
- package/dist/document/components/DocRail.d.ts +0 -28
- package/dist/document/components/DocRail.d.ts.map +0 -1
- package/dist/document/components/DocSectionPage.d.ts +0 -12
- package/dist/document/components/DocSectionPage.d.ts.map +0 -1
- package/dist/document/components/DocViewer.d.ts +0 -21
- package/dist/document/components/DocViewer.d.ts.map +0 -1
- package/dist/document/components/Wordmark.d.ts +0 -4
- package/dist/document/components/Wordmark.d.ts.map +0 -1
- package/dist/document/components/measure.d.ts +0 -7
- package/dist/document/components/measure.d.ts.map +0 -1
- package/dist/document/components/useDocPages.d.ts +0 -12
- package/dist/document/components/useDocPages.d.ts.map +0 -1
- package/dist/document/engine/blocks.d.ts +0 -2
- package/dist/document/engine/blocks.d.ts.map +0 -1
- package/dist/document/engine/harvest.d.ts +0 -3
- package/dist/document/engine/harvest.d.ts.map +0 -1
- package/dist/document/engine/masonry.d.ts +0 -26
- package/dist/document/engine/masonry.d.ts.map +0 -1
- package/dist/document/engine/paginate.d.ts +0 -43
- package/dist/document/engine/paginate.d.ts.map +0 -1
- package/dist/document/engine/settings.d.ts +0 -91
- package/dist/document/engine/settings.d.ts.map +0 -1
- package/dist/document/engine/types.d.ts +0 -44
- package/dist/document/engine/types.d.ts.map +0 -1
- package/dist/document/index.d.ts +0 -13
- package/dist/document/index.d.ts.map +0 -1
- package/dist/document/index.js +0 -1030
- package/dist/document/styles/document.css +0 -217
- package/dist/lib/deck-access.d.ts +0 -86
- package/dist/lib/deck-access.d.ts.map +0 -1
- package/dist/lib/deck-access.js +0 -58
- package/dist/lib/deck-dexie.d.ts +0 -88
- package/dist/lib/deck-dexie.d.ts.map +0 -1
- package/dist/lib/deck-dexie.js +0 -22
- package/dist/lib/deck-edit.d.ts +0 -67
- package/dist/lib/deck-edit.d.ts.map +0 -1
- package/dist/lib/deck-media-assets.d.ts +0 -27
- package/dist/lib/deck-media-assets.d.ts.map +0 -1
- package/dist/lib/deck-media-assets.js +0 -25
- package/dist/lib/deck-media-refs.d.ts +0 -35
- package/dist/lib/deck-media-refs.d.ts.map +0 -1
- package/dist/lib/deck-media-refs.js +0 -36
- package/dist/lib/deck-tool.d.ts +0 -25
- package/dist/lib/deck-tool.d.ts.map +0 -1
- package/dist/lib/deck-tool.js +0 -58
- package/dist/lib/document-input.d.ts +0 -25
- package/dist/lib/document-input.d.ts.map +0 -1
- package/dist/schemas/deck-meta.d.ts +0 -85
- package/dist/schemas/deck-meta.d.ts.map +0 -1
- package/dist/schemas/deck-meta.js +0 -64
- package/dist/schemas/deck.d.ts +0 -954
- package/dist/schemas/deck.d.ts.map +0 -1
- package/dist/schemas/deck.js +0 -65
- package/src/components/shell/DocInspector.tsx +0 -314
- package/src/components/shell/DocumentEditorOverlay.tsx +0 -179
- package/src/components/shell/DocumentPresentOverlay.tsx +0 -87
- package/src/components/shell/SiteSettingsDecks.tsx +0 -41
- package/src/deck/DeckComponentView.tsx +0 -28
- package/src/deck/DeckPlayer.tsx +0 -166
- package/src/deck/DeckSlideView.tsx +0 -38
- package/src/deck/DeckStage.tsx +0 -39
- package/src/deck/components/DeckImage.tsx +0 -38
- package/src/deck/components/DeckImageGrid.tsx +0 -254
- package/src/deck/components/DeckRichText.tsx +0 -111
- package/src/deck/components/DeckVideo.tsx +0 -81
- package/src/deck/editing.tsx +0 -201
- package/src/deck/flip.ts +0 -70
- package/src/deck/index.ts +0 -30
- package/src/deck/layouts/CenteredTextLayout.tsx +0 -29
- package/src/deck/layouts/ColumnSplitLayout.tsx +0 -69
- package/src/deck/layouts/FullBleedImageLayout.tsx +0 -58
- package/src/deck/media.tsx +0 -46
- package/src/deck/tokens.ts +0 -57
- package/src/deck/useStageScale.ts +0 -44
- package/src/deck-builder/DeckBuilderApp.tsx +0 -572
- package/src/deck-builder/DeckBuilderTopBar.tsx +0 -62
- package/src/deck-builder/DeckChatPanel.tsx +0 -334
- package/src/deck-builder/DeckEditor.tsx +0 -258
- package/src/deck-builder/DeckLibrary.tsx +0 -195
- package/src/deck-builder/DeckSlideSurface.tsx +0 -55
- package/src/deck-builder/deck-api.ts +0 -177
- package/src/deck-builder/deck-chat-client.ts +0 -129
- package/src/deck-builder/deck-chat-history.ts +0 -62
- package/src/deck-builder/index.ts +0 -12
- package/src/deck-builder/starter-deck.ts +0 -86
- package/src/deck-builder/types.ts +0 -24
- package/src/deck-builder/useSortableSlide.ts +0 -102
- package/src/document/assets/fonts/albra-grotesk-bold.woff +0 -0
- package/src/document/assets/fonts/albra-grotesk-regular.woff +0 -0
- package/src/document/assets/fonts/kapra-neue-expanded-medium.woff +0 -0
- package/src/document/assets/fonts/kapra-neue-expanded-regular.woff +0 -0
- package/src/document/components/DocCoverPage.tsx +0 -45
- package/src/document/components/DocPage.tsx +0 -40
- package/src/document/components/DocRail.tsx +0 -189
- package/src/document/components/DocSectionPage.tsx +0 -48
- package/src/document/components/DocViewer.tsx +0 -313
- package/src/document/components/Wordmark.tsx +0 -18
- package/src/document/components/measure.tsx +0 -133
- package/src/document/components/useDocPages.ts +0 -95
- package/src/document/engine/blocks.ts +0 -116
- package/src/document/engine/harvest.ts +0 -95
- package/src/document/engine/masonry.ts +0 -158
- package/src/document/engine/paginate.ts +0 -232
- package/src/document/engine/settings.ts +0 -125
- package/src/document/engine/types.ts +0 -64
- package/src/document/index.ts +0 -18
- package/src/document/styles/document.css +0 -217
- package/src/lib/deck-access.ts +0 -132
- package/src/lib/deck-dexie.ts +0 -190
- package/src/lib/deck-edit.ts +0 -196
- package/src/lib/deck-media-assets.ts +0 -57
- package/src/lib/deck-media-refs.ts +0 -67
- package/src/lib/deck-tool.ts +0 -95
- package/src/lib/document-input.ts +0 -57
- package/src/schemas/deck-meta.ts +0 -88
- package/src/schemas/deck.ts +0 -478
- package/dist/{chunk-DJABADOO.js → chunk-AJ2QOAZI.js} +3 -3
package/dist/chunk-TEOAKGZA.js
DELETED
|
@@ -1,784 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
cn
|
|
3
|
-
} from "./chunk-7EOSDFS3.js";
|
|
4
|
-
import {
|
|
5
|
-
DECK_STAGE_HEIGHT,
|
|
6
|
-
DECK_STAGE_WIDTH
|
|
7
|
-
} from "./chunk-VAYZJKVR.js";
|
|
8
|
-
|
|
9
|
-
// src/deck/DeckPlayer.tsx
|
|
10
|
-
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
11
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo2, useState as useState5 } from "react";
|
|
12
|
-
|
|
13
|
-
// src/deck/media.tsx
|
|
14
|
-
import { createContext, useContext } from "react";
|
|
15
|
-
import { jsx } from "react/jsx-runtime";
|
|
16
|
-
var NO_MEDIA = () => null;
|
|
17
|
-
var DeckMediaContext = createContext(NO_MEDIA);
|
|
18
|
-
function DeckMediaProvider({ resolve, children }) {
|
|
19
|
-
return /* @__PURE__ */ jsx(DeckMediaContext.Provider, { value: resolve, children });
|
|
20
|
-
}
|
|
21
|
-
function useDeckMedia(ref) {
|
|
22
|
-
return useContext(DeckMediaContext)(ref);
|
|
23
|
-
}
|
|
24
|
-
function useDeckMediaResolver() {
|
|
25
|
-
return useContext(DeckMediaContext);
|
|
26
|
-
}
|
|
27
|
-
function DeckMissingMedia({ className }) {
|
|
28
|
-
return /* @__PURE__ */ jsx("span", { "data-deck-media": "missing", "aria-hidden": "true", className: cn("block size-full bg-base-200", className) });
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// src/deck/DeckStage.tsx
|
|
32
|
-
import { useRef } from "react";
|
|
33
|
-
|
|
34
|
-
// src/deck/useStageScale.ts
|
|
35
|
-
import { useEffect, useLayoutEffect, useState } from "react";
|
|
36
|
-
var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
37
|
-
function useStageScale(fitRef) {
|
|
38
|
-
const [scale, setScale] = useState(null);
|
|
39
|
-
useIsomorphicLayoutEffect(() => {
|
|
40
|
-
const el = fitRef.current;
|
|
41
|
-
if (!el) return;
|
|
42
|
-
const measure = () => {
|
|
43
|
-
const { clientWidth, clientHeight } = el;
|
|
44
|
-
if (!clientWidth || !clientHeight) return;
|
|
45
|
-
setScale(Math.min(clientWidth / DECK_STAGE_WIDTH, clientHeight / DECK_STAGE_HEIGHT));
|
|
46
|
-
};
|
|
47
|
-
measure();
|
|
48
|
-
if (typeof ResizeObserver === "undefined") {
|
|
49
|
-
window.addEventListener("resize", measure);
|
|
50
|
-
return () => window.removeEventListener("resize", measure);
|
|
51
|
-
}
|
|
52
|
-
const observer = new ResizeObserver(measure);
|
|
53
|
-
observer.observe(el);
|
|
54
|
-
return () => observer.disconnect();
|
|
55
|
-
}, [fitRef]);
|
|
56
|
-
return scale;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// src/deck/DeckStage.tsx
|
|
60
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
61
|
-
function DeckStage({ children, className }) {
|
|
62
|
-
const fitRef = useRef(null);
|
|
63
|
-
const scale = useStageScale(fitRef);
|
|
64
|
-
return /* @__PURE__ */ jsx2("div", { ref: fitRef, className: cn("relative min-h-0 w-full overflow-hidden", className), "data-deck-fit": "", children: /* @__PURE__ */ jsx2(
|
|
65
|
-
"div",
|
|
66
|
-
{
|
|
67
|
-
"data-deck-stage": "",
|
|
68
|
-
"data-deck-scale": scale === null ? void 0 : scale.toFixed(4),
|
|
69
|
-
className: "absolute top-1/2 left-1/2 origin-center overflow-hidden rounded-[var(--radius-outer)] font-body",
|
|
70
|
-
style: {
|
|
71
|
-
width: DECK_STAGE_WIDTH,
|
|
72
|
-
height: DECK_STAGE_HEIGHT,
|
|
73
|
-
transform: scale === null ? "translate(-50%, -50%)" : `translate(-50%, -50%) scale(${scale})`
|
|
74
|
-
},
|
|
75
|
-
children
|
|
76
|
-
}
|
|
77
|
-
) });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// src/deck/tokens.ts
|
|
81
|
-
var SURFACE_INK = {
|
|
82
|
-
base: {
|
|
83
|
-
"--deck-ink": "var(--color-base-contrast)",
|
|
84
|
-
"--deck-ink-muted": "var(--color-base-contrast-light)",
|
|
85
|
-
"--deck-accent": "var(--color-primary)"
|
|
86
|
-
},
|
|
87
|
-
brand: {
|
|
88
|
-
"--deck-ink": "var(--color-on-primary)",
|
|
89
|
-
"--deck-ink-muted": "color-mix(in srgb, var(--color-on-primary) 72%, transparent)",
|
|
90
|
-
"--deck-accent": "var(--color-primary-contrast)"
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
function surfaceInk(surface) {
|
|
94
|
-
return SURFACE_INK[surface];
|
|
95
|
-
}
|
|
96
|
-
var SURFACE_BACKGROUND = {
|
|
97
|
-
base: "bg-base-accent",
|
|
98
|
-
brand: "bg-primary"
|
|
99
|
-
};
|
|
100
|
-
function deckAlign(align) {
|
|
101
|
-
return { "--deck-align": align };
|
|
102
|
-
}
|
|
103
|
-
var DECK_ELEVATION = {
|
|
104
|
-
"--deck-lift": "0 26px 46px -18px color-mix(in srgb, var(--color-base-contrast) 45%, transparent)",
|
|
105
|
-
"--deck-lift-strong": "0 30px 60px -22px color-mix(in srgb, var(--color-base-contrast) 58%, transparent)"
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
// src/deck/components/DeckImage.tsx
|
|
109
|
-
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
110
|
-
function DeckImage({ content }) {
|
|
111
|
-
const asset = useDeckMedia(content.media);
|
|
112
|
-
return /* @__PURE__ */ jsxs("figure", { "data-deck-component": "image", className: "relative size-full overflow-hidden bg-base-200", children: [
|
|
113
|
-
asset === null ? /* @__PURE__ */ jsx3(DeckMissingMedia, {}) : /* @__PURE__ */ jsx3("img", { src: asset.src, alt: asset.alt, className: "size-full object-cover" }),
|
|
114
|
-
content.caption !== void 0 && /* @__PURE__ */ jsx3(
|
|
115
|
-
"figcaption",
|
|
116
|
-
{
|
|
117
|
-
"data-deck-surface": "brand",
|
|
118
|
-
style: surfaceInk("brand"),
|
|
119
|
-
className: "absolute right-0 bottom-0 left-0 bg-primary px-[28px] py-[18px] text-[18px] tracking-[0.06em] text-[var(--deck-ink)] [text-transform:var(--nav-text-transform)]",
|
|
120
|
-
children: content.caption
|
|
121
|
-
}
|
|
122
|
-
)
|
|
123
|
-
] });
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// src/deck/components/DeckImageGrid.tsx
|
|
127
|
-
import { useCallback, useEffect as useEffect2, useLayoutEffect as useLayoutEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
128
|
-
|
|
129
|
-
// src/deck/flip.ts
|
|
130
|
-
var TILE_SELECTOR = "[data-deck-tile]";
|
|
131
|
-
function captureTileRects(grid) {
|
|
132
|
-
const rects = /* @__PURE__ */ new Map();
|
|
133
|
-
for (const tile of grid.querySelectorAll(TILE_SELECTOR)) rects.set(tile, tile.getBoundingClientRect());
|
|
134
|
-
return rects;
|
|
135
|
-
}
|
|
136
|
-
function stageScale(el) {
|
|
137
|
-
const raw = el.closest("[data-deck-stage]")?.getAttribute("data-deck-scale");
|
|
138
|
-
const value = raw === null || raw === void 0 ? Number.NaN : Number(raw);
|
|
139
|
-
return Number.isFinite(value) && value > 0 ? value : 1;
|
|
140
|
-
}
|
|
141
|
-
function playTileFlip(grid, before) {
|
|
142
|
-
const scale = stageScale(grid);
|
|
143
|
-
const moved = [];
|
|
144
|
-
for (const tile of grid.querySelectorAll(TILE_SELECTOR)) {
|
|
145
|
-
const first = before.get(tile);
|
|
146
|
-
if (!first) continue;
|
|
147
|
-
const last = tile.getBoundingClientRect();
|
|
148
|
-
if (!first.width || !last.width) continue;
|
|
149
|
-
const dx = (first.left + first.width / 2 - (last.left + last.width / 2)) / scale;
|
|
150
|
-
const dy = (first.top + first.height / 2 - (last.top + last.height / 2)) / scale;
|
|
151
|
-
const sx = first.width / last.width;
|
|
152
|
-
const sy = first.height / last.height;
|
|
153
|
-
if (Math.abs(dx) < 0.5 && Math.abs(dy) < 0.5 && Math.abs(sx - 1) < 2e-3) continue;
|
|
154
|
-
tile.style.transition = "none";
|
|
155
|
-
tile.style.transform = `translate(${dx}px, ${dy}px) scale(${sx}, ${sy})`;
|
|
156
|
-
moved.push(tile);
|
|
157
|
-
}
|
|
158
|
-
if (moved.length === 0) return;
|
|
159
|
-
void grid.offsetWidth;
|
|
160
|
-
for (const tile of moved) {
|
|
161
|
-
tile.style.transition = "";
|
|
162
|
-
tile.style.transform = "";
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// src/deck/components/DeckImageGrid.tsx
|
|
167
|
-
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
168
|
-
function columnsFor(count) {
|
|
169
|
-
return count <= 4 ? 2 : 3;
|
|
170
|
-
}
|
|
171
|
-
function tileRatio(asset) {
|
|
172
|
-
if (asset?.width === void 0 || asset.height === void 0 || asset.width <= 0) return 1;
|
|
173
|
-
return asset.height / asset.width;
|
|
174
|
-
}
|
|
175
|
-
function packMasonry(ratios, columns) {
|
|
176
|
-
const packed = Array.from({ length: columns }, () => []);
|
|
177
|
-
const filled = new Array(columns).fill(0);
|
|
178
|
-
ratios.forEach((ratio, index) => {
|
|
179
|
-
let target = 0;
|
|
180
|
-
for (let column = 1; column < columns; column++) {
|
|
181
|
-
if (filled[column] < filled[target]) target = column;
|
|
182
|
-
}
|
|
183
|
-
packed[target].push(index);
|
|
184
|
-
filled[target] += ratio;
|
|
185
|
-
});
|
|
186
|
-
return packed;
|
|
187
|
-
}
|
|
188
|
-
var TILE_BASE = "group relative block shrink-0 overflow-hidden bg-base-200 will-change-transform transition-[transform,box-shadow,opacity] duration-[380ms] ease-[cubic-bezier(0.2,0.75,0.2,1)] focus-visible:outline-2 focus-visible:outline-offset-[-6px] focus-visible:outline-[var(--color-primary)]";
|
|
189
|
-
function DeckImageGrid({ content }) {
|
|
190
|
-
const [active, setActive] = useState2(null);
|
|
191
|
-
const gridRef = useRef2(null);
|
|
192
|
-
const pendingRects = useRef2(null);
|
|
193
|
-
const expanded = active !== null;
|
|
194
|
-
const resolve = useDeckMediaResolver();
|
|
195
|
-
const count = content.items.length;
|
|
196
|
-
const assets = useMemo(() => content.items.map((item) => resolve(item.media)), [content.items, resolve]);
|
|
197
|
-
const columns = columnsFor(count);
|
|
198
|
-
const packed = useMemo(() => packMasonry(assets.map(tileRatio), columns), [assets, columns]);
|
|
199
|
-
const transitionTo = useCallback((next) => {
|
|
200
|
-
const grid = gridRef.current;
|
|
201
|
-
if (grid) pendingRects.current = captureTileRects(grid);
|
|
202
|
-
setActive(next);
|
|
203
|
-
}, []);
|
|
204
|
-
useLayoutEffect2(() => {
|
|
205
|
-
const grid = gridRef.current;
|
|
206
|
-
const before = pendingRects.current;
|
|
207
|
-
pendingRects.current = null;
|
|
208
|
-
if (grid && before) playTileFlip(grid, before);
|
|
209
|
-
}, [active]);
|
|
210
|
-
useEffect2(() => {
|
|
211
|
-
setActive((prev) => prev === null || prev < count ? prev : null);
|
|
212
|
-
}, [count]);
|
|
213
|
-
useEffect2(() => {
|
|
214
|
-
if (!expanded) return;
|
|
215
|
-
const onKeyDown = (event) => {
|
|
216
|
-
if (event.key !== "Escape") return;
|
|
217
|
-
event.stopPropagation();
|
|
218
|
-
transitionTo(null);
|
|
219
|
-
};
|
|
220
|
-
window.addEventListener("keydown", onKeyDown);
|
|
221
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
222
|
-
}, [expanded, transitionTo]);
|
|
223
|
-
const close = useCallback(() => {
|
|
224
|
-
gridRef.current?.querySelector(`[data-deck-tile="${active}"]`)?.focus({ preventScroll: true });
|
|
225
|
-
transitionTo(null);
|
|
226
|
-
}, [active, transitionTo]);
|
|
227
|
-
return /* @__PURE__ */ jsxs2(
|
|
228
|
-
"div",
|
|
229
|
-
{
|
|
230
|
-
ref: gridRef,
|
|
231
|
-
"data-deck-component": "imageGrid",
|
|
232
|
-
"data-deck-grid-expanded": expanded ? "true" : "false",
|
|
233
|
-
"data-deck-grid-columns": columns,
|
|
234
|
-
style: DECK_ELEVATION,
|
|
235
|
-
className: "relative flex size-full gap-[14px] overflow-hidden",
|
|
236
|
-
children: [
|
|
237
|
-
packed.map((indices, column) => (
|
|
238
|
-
// `flex-1` rather than a width fraction: the columns have to share the
|
|
239
|
-
// gap between them, and equal flex bases divide what is left over.
|
|
240
|
-
/* @__PURE__ */ jsx4("div", { "data-deck-grid-column": column, className: "flex min-w-0 flex-1 flex-col gap-[14px]", children: indices.map((index) => /* @__PURE__ */ jsx4(
|
|
241
|
-
Tile,
|
|
242
|
-
{
|
|
243
|
-
item: content.items[index],
|
|
244
|
-
asset: assets[index],
|
|
245
|
-
index,
|
|
246
|
-
expanded,
|
|
247
|
-
active: index === active,
|
|
248
|
-
onActivate: () => transitionTo(index === active ? null : index)
|
|
249
|
-
},
|
|
250
|
-
index
|
|
251
|
-
)) }, column)
|
|
252
|
-
)),
|
|
253
|
-
expanded && /* @__PURE__ */ jsx4(
|
|
254
|
-
"button",
|
|
255
|
-
{
|
|
256
|
-
type: "button",
|
|
257
|
-
"data-deck-grid-close": "",
|
|
258
|
-
onClick: close,
|
|
259
|
-
"data-deck-surface": "brand",
|
|
260
|
-
style: surfaceInk("brand"),
|
|
261
|
-
className: "absolute top-[14px] right-[14px] z-[4] bg-primary px-[18px] py-[10px] text-[15px] font-semibold tracking-[0.12em] text-[var(--deck-ink)] uppercase",
|
|
262
|
-
children: "Close"
|
|
263
|
-
}
|
|
264
|
-
)
|
|
265
|
-
]
|
|
266
|
-
}
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
function Tile({ item, asset, index, expanded, active, onActivate }) {
|
|
270
|
-
const label = item.caption ?? asset?.alt ?? `Image ${index + 1}`;
|
|
271
|
-
return /* @__PURE__ */ jsxs2(
|
|
272
|
-
"button",
|
|
273
|
-
{
|
|
274
|
-
type: "button",
|
|
275
|
-
"data-deck-tile": index,
|
|
276
|
-
"data-deck-tile-active": active ? "true" : "false",
|
|
277
|
-
"aria-expanded": active,
|
|
278
|
-
"aria-label": active ? `Close ${label}` : `Expand ${label}`,
|
|
279
|
-
tabIndex: expanded && !active ? -1 : 0,
|
|
280
|
-
onClick: onActivate,
|
|
281
|
-
className: cn(
|
|
282
|
-
TILE_BASE,
|
|
283
|
-
// Every tile leaves the column flow when one is expanded, not only the
|
|
284
|
-
// active one: leaving the siblings in place would let the columns
|
|
285
|
-
// re-pack around the gap, which both reflows the tiles the lightbox is
|
|
286
|
-
// covering and moves the ones the FLIP is animating.
|
|
287
|
-
expanded ? "absolute inset-0 flex items-center justify-center" : "w-full",
|
|
288
|
-
expanded && !active && "pointer-events-none opacity-0",
|
|
289
|
-
// Transparent, not the tile's loading plate: an expanded frame is
|
|
290
|
-
// letterboxed inside the slot, and the field around it should read as
|
|
291
|
-
// the slide showing through rather than as a grey box drawn on top.
|
|
292
|
-
expanded && active && "z-[3] bg-transparent opacity-100",
|
|
293
|
-
!expanded && "cursor-pointer hover:z-[2] hover:scale-[1.035] hover:shadow-[var(--deck-lift)]"
|
|
294
|
-
),
|
|
295
|
-
children: [
|
|
296
|
-
asset === null ? /* @__PURE__ */ jsx4(DeckMissingMedia, { className: active ? "size-full" : "aspect-square h-auto w-full" }) : /* @__PURE__ */ jsx4(
|
|
297
|
-
"img",
|
|
298
|
-
{
|
|
299
|
-
src: asset.src,
|
|
300
|
-
alt: "",
|
|
301
|
-
width: asset.width,
|
|
302
|
-
height: asset.height,
|
|
303
|
-
className: active ? "max-h-full max-w-full object-contain shadow-[var(--deck-lift-strong)]" : "block h-auto w-full"
|
|
304
|
-
}
|
|
305
|
-
),
|
|
306
|
-
/* @__PURE__ */ jsx4(
|
|
307
|
-
"span",
|
|
308
|
-
{
|
|
309
|
-
"aria-hidden": "true",
|
|
310
|
-
"data-deck-surface": "brand",
|
|
311
|
-
style: surfaceInk("brand"),
|
|
312
|
-
className: "absolute top-0 left-0 bg-primary px-[12px] py-[6px] text-[15px] font-bold tracking-[0.1em] text-[var(--deck-ink)] tabular-nums",
|
|
313
|
-
children: String(index + 1).padStart(2, "0")
|
|
314
|
-
}
|
|
315
|
-
),
|
|
316
|
-
item.caption !== void 0 && /* @__PURE__ */ jsx4(
|
|
317
|
-
"span",
|
|
318
|
-
{
|
|
319
|
-
"data-deck-surface": "brand",
|
|
320
|
-
style: surfaceInk("brand"),
|
|
321
|
-
className: cn(
|
|
322
|
-
"absolute right-0 bottom-0 left-0 bg-primary text-left tracking-[0.04em] text-[var(--deck-ink)] transition-opacity duration-200",
|
|
323
|
-
active ? "px-[30px] py-[22px] text-[24px] opacity-100" : "px-[18px] py-[14px] text-[18px] opacity-0 group-hover:opacity-100"
|
|
324
|
-
),
|
|
325
|
-
children: item.caption
|
|
326
|
-
}
|
|
327
|
-
)
|
|
328
|
-
]
|
|
329
|
-
}
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// src/deck/components/DeckRichText.tsx
|
|
334
|
-
import { Fragment as Fragment2 } from "react";
|
|
335
|
-
|
|
336
|
-
// src/deck/editing.tsx
|
|
337
|
-
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
338
|
-
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
|
|
339
|
-
var DeckTextEditContext = createContext2(null);
|
|
340
|
-
function DeckTextEditProvider({ editor, children }) {
|
|
341
|
-
return /* @__PURE__ */ jsx5(DeckTextEditContext.Provider, { value: editor, children });
|
|
342
|
-
}
|
|
343
|
-
function useDeckTextEditor() {
|
|
344
|
-
return useContext2(DeckTextEditContext);
|
|
345
|
-
}
|
|
346
|
-
function EditableText({ path, children }) {
|
|
347
|
-
const editor = useDeckTextEditor();
|
|
348
|
-
const [editing, setEditing] = useState3(false);
|
|
349
|
-
const enabled = editor !== null && path !== void 0 && editor.disabled !== true;
|
|
350
|
-
useEffect3(() => {
|
|
351
|
-
if (!enabled && editing) setEditing(false);
|
|
352
|
-
}, [enabled, editing]);
|
|
353
|
-
if (editor === null || path === void 0) return /* @__PURE__ */ jsx5(Fragment, { children });
|
|
354
|
-
if (editing && enabled) {
|
|
355
|
-
return /* @__PURE__ */ jsx5(
|
|
356
|
-
EditableField,
|
|
357
|
-
{
|
|
358
|
-
initial: children,
|
|
359
|
-
onCommit: (text) => {
|
|
360
|
-
setEditing(false);
|
|
361
|
-
const trimmed = text.trim();
|
|
362
|
-
if (trimmed !== "" && trimmed !== children) editor.onEditText(path, trimmed);
|
|
363
|
-
},
|
|
364
|
-
onCancel: () => setEditing(false)
|
|
365
|
-
}
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
return /* @__PURE__ */ jsx5(
|
|
369
|
-
"span",
|
|
370
|
-
{
|
|
371
|
-
role: "button",
|
|
372
|
-
tabIndex: enabled ? 0 : -1,
|
|
373
|
-
"aria-disabled": enabled ? void 0 : true,
|
|
374
|
-
"data-deck-editable": "",
|
|
375
|
-
onClick: enabled ? () => setEditing(true) : void 0,
|
|
376
|
-
onKeyDown: enabled ? (event) => {
|
|
377
|
-
if (event.key !== "Enter" && event.key !== " ") return;
|
|
378
|
-
event.preventDefault();
|
|
379
|
-
setEditing(true);
|
|
380
|
-
} : void 0,
|
|
381
|
-
className: enabled ? "cursor-text rounded-[var(--radius-inner)] decoration-dotted underline-offset-[6px] outline-none hover:underline focus-visible:underline" : "opacity-70",
|
|
382
|
-
children
|
|
383
|
-
}
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
function EditableField({
|
|
387
|
-
initial,
|
|
388
|
-
onCommit,
|
|
389
|
-
onCancel
|
|
390
|
-
}) {
|
|
391
|
-
const ref = useRef3(null);
|
|
392
|
-
const cancelled = useRef3(false);
|
|
393
|
-
useEffect3(() => {
|
|
394
|
-
const element = ref.current;
|
|
395
|
-
if (!element) return;
|
|
396
|
-
element.textContent = initial;
|
|
397
|
-
element.focus();
|
|
398
|
-
const selection = window.getSelection?.();
|
|
399
|
-
if (selection) {
|
|
400
|
-
const range = document.createRange();
|
|
401
|
-
range.selectNodeContents(element);
|
|
402
|
-
selection.removeAllRanges();
|
|
403
|
-
selection.addRange(range);
|
|
404
|
-
}
|
|
405
|
-
}, [initial]);
|
|
406
|
-
return /* @__PURE__ */ jsx5(
|
|
407
|
-
"span",
|
|
408
|
-
{
|
|
409
|
-
ref,
|
|
410
|
-
contentEditable: true,
|
|
411
|
-
suppressContentEditableWarning: true,
|
|
412
|
-
role: "textbox",
|
|
413
|
-
"aria-label": "Edit text",
|
|
414
|
-
spellCheck: true,
|
|
415
|
-
"data-deck-editing": "",
|
|
416
|
-
onKeyDown: (event) => {
|
|
417
|
-
if (event.nativeEvent.isComposing) return;
|
|
418
|
-
if (event.key === "Enter") {
|
|
419
|
-
event.preventDefault();
|
|
420
|
-
event.currentTarget.blur();
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
if (event.key === "Escape") {
|
|
424
|
-
event.preventDefault();
|
|
425
|
-
cancelled.current = true;
|
|
426
|
-
event.currentTarget.blur();
|
|
427
|
-
}
|
|
428
|
-
},
|
|
429
|
-
onPaste: (event) => {
|
|
430
|
-
event.preventDefault();
|
|
431
|
-
const text = event.clipboardData.getData("text/plain").replace(/\s+/g, " ").trim();
|
|
432
|
-
const doc = event.currentTarget.ownerDocument;
|
|
433
|
-
if (text !== "" && typeof doc.execCommand === "function") doc.execCommand("insertText", false, text);
|
|
434
|
-
},
|
|
435
|
-
onBlur: (event) => {
|
|
436
|
-
if (cancelled.current) {
|
|
437
|
-
cancelled.current = false;
|
|
438
|
-
onCancel();
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
onCommit(event.currentTarget.textContent ?? "");
|
|
442
|
-
},
|
|
443
|
-
className: "rounded-[var(--radius-inner)] outline-2 outline-offset-2 outline-[var(--deck-accent)]"
|
|
444
|
-
}
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// src/deck/components/DeckRichText.tsx
|
|
449
|
-
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
450
|
-
function InlineText({ value, path }) {
|
|
451
|
-
if (typeof value === "string") return /* @__PURE__ */ jsx6(EditableText, { path, children: value });
|
|
452
|
-
return /* @__PURE__ */ jsx6(Fragment3, { children: value.map((span, i) => {
|
|
453
|
-
let node = /* @__PURE__ */ jsx6(EditableText, { path: path && { ...path, span: i }, children: span.text });
|
|
454
|
-
if (span.italic) node = /* @__PURE__ */ jsx6("em", { className: "italic", children: node });
|
|
455
|
-
if (span.bold) node = /* @__PURE__ */ jsx6("strong", { className: "font-semibold text-[var(--deck-ink)]", children: node });
|
|
456
|
-
return /* @__PURE__ */ jsx6(Fragment2, { children: node }, i);
|
|
457
|
-
}) });
|
|
458
|
-
}
|
|
459
|
-
function DeckRichText({ content, slot }) {
|
|
460
|
-
const { kicker, heading, subheading, paragraphs, bullets } = content;
|
|
461
|
-
const at = (field, line) => slot === void 0 ? void 0 : { slot, field, line };
|
|
462
|
-
return /* @__PURE__ */ jsxs3("div", { "data-deck-component": "richText", className: "flex flex-col gap-[28px]", children: [
|
|
463
|
-
kicker !== void 0 && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-[18px]", children: [
|
|
464
|
-
/* @__PURE__ */ jsx6("p", { className: "text-[22px] font-semibold tracking-[0.2em] text-[var(--deck-accent)] [text-transform:var(--nav-text-transform)]", children: /* @__PURE__ */ jsx6(EditableText, { path: at("kicker"), children: kicker }) }),
|
|
465
|
-
/* @__PURE__ */ jsx6(
|
|
466
|
-
"span",
|
|
467
|
-
{
|
|
468
|
-
"aria-hidden": "true",
|
|
469
|
-
style: { alignSelf: "var(--deck-align, start)" },
|
|
470
|
-
className: "h-[4px] w-[84px] rounded-[var(--radius-inner)] bg-[var(--deck-accent)]"
|
|
471
|
-
}
|
|
472
|
-
)
|
|
473
|
-
] }),
|
|
474
|
-
heading !== void 0 && /* @__PURE__ */ jsx6("h1", { className: "font-heading text-[88px] leading-[1.06] font-medium tracking-[-0.015em] text-[var(--deck-ink)] [text-transform:var(--heading-text-transform)]", children: /* @__PURE__ */ jsx6(EditableText, { path: at("heading"), children: heading }) }),
|
|
475
|
-
subheading !== void 0 && /* @__PURE__ */ jsx6("h2", { className: "font-heading text-[38px] leading-[1.25] font-normal text-[var(--deck-ink-muted)] [text-transform:var(--subheading-text-transform)]", children: /* @__PURE__ */ jsx6(EditableText, { path: at("subheading"), children: subheading }) }),
|
|
476
|
-
paragraphs !== void 0 && paragraphs.length > 0 && /* @__PURE__ */ jsx6("div", { className: "flex max-w-[1000px] flex-col gap-[18px] self-[var(--deck-align,start)]", children: paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx6("p", { className: "text-[26px] leading-[1.6] text-[var(--deck-ink-muted)]", children: /* @__PURE__ */ jsx6(InlineText, { value: paragraph, path: at("paragraphs", i) }) }, i)) }),
|
|
477
|
-
bullets !== void 0 && bullets.length > 0 && /* @__PURE__ */ jsx6("ul", { className: "flex flex-col gap-[16px] self-[var(--deck-align,start)] text-left", children: bullets.map((bullet, i) => /* @__PURE__ */ jsxs3("li", { className: "flex items-start gap-[18px] text-[26px] leading-[1.45] text-[var(--deck-ink)]", children: [
|
|
478
|
-
/* @__PURE__ */ jsx6("span", { "aria-hidden": "true", className: "mt-[14px] size-[10px] shrink-0 rounded-full bg-[var(--deck-accent)]" }),
|
|
479
|
-
/* @__PURE__ */ jsx6("span", { children: /* @__PURE__ */ jsx6(InlineText, { value: bullet, path: at("bullets", i) }) })
|
|
480
|
-
] }, i)) })
|
|
481
|
-
] });
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// src/deck/components/DeckVideo.tsx
|
|
485
|
-
import { Play } from "lucide-react";
|
|
486
|
-
import { useRef as useRef4, useState as useState4 } from "react";
|
|
487
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
488
|
-
function DeckVideo({ content }) {
|
|
489
|
-
const asset = useDeckMedia(content.media);
|
|
490
|
-
const videoRef = useRef4(null);
|
|
491
|
-
const [playing, setPlaying] = useState4(false);
|
|
492
|
-
const start = () => {
|
|
493
|
-
setPlaying(true);
|
|
494
|
-
videoRef.current?.play()?.catch(() => void 0);
|
|
495
|
-
};
|
|
496
|
-
return /* @__PURE__ */ jsxs4(
|
|
497
|
-
"div",
|
|
498
|
-
{
|
|
499
|
-
"data-deck-component": "video",
|
|
500
|
-
"data-deck-video-state": playing ? "playing" : "idle",
|
|
501
|
-
style: DECK_ELEVATION,
|
|
502
|
-
className: "relative size-full overflow-hidden bg-base-200",
|
|
503
|
-
children: [
|
|
504
|
-
asset === null ? /* @__PURE__ */ jsx7(DeckMissingMedia, {}) : /* @__PURE__ */ jsx7(
|
|
505
|
-
"video",
|
|
506
|
-
{
|
|
507
|
-
ref: videoRef,
|
|
508
|
-
src: asset.src,
|
|
509
|
-
poster: asset.poster,
|
|
510
|
-
preload: "none",
|
|
511
|
-
playsInline: true,
|
|
512
|
-
controls: playing,
|
|
513
|
-
onEnded: () => setPlaying(false),
|
|
514
|
-
className: "size-full object-cover"
|
|
515
|
-
}
|
|
516
|
-
),
|
|
517
|
-
!playing && asset !== null && /* @__PURE__ */ jsx7(
|
|
518
|
-
"button",
|
|
519
|
-
{
|
|
520
|
-
type: "button",
|
|
521
|
-
"data-deck-video-play": "",
|
|
522
|
-
onClick: start,
|
|
523
|
-
"aria-label": content.title === void 0 ? "Play video" : `Play ${content.title}`,
|
|
524
|
-
className: "group absolute inset-0 grid cursor-pointer place-items-center",
|
|
525
|
-
children: /* @__PURE__ */ jsx7("span", { className: "grid size-[108px] place-items-center rounded-full bg-primary text-[var(--color-on-primary)] shadow-[var(--deck-lift)] transition-transform duration-200 group-hover:scale-105", children: /* @__PURE__ */ jsx7(Play, { "aria-hidden": "true", className: "ml-[6px] size-[44px] fill-current" }) })
|
|
526
|
-
}
|
|
527
|
-
),
|
|
528
|
-
!playing && content.title !== void 0 && /* @__PURE__ */ jsx7(
|
|
529
|
-
"span",
|
|
530
|
-
{
|
|
531
|
-
"data-deck-surface": "brand",
|
|
532
|
-
style: surfaceInk("brand"),
|
|
533
|
-
className: "pointer-events-none absolute right-0 bottom-0 left-0 bg-primary px-[28px] py-[18px] text-[18px] tracking-[0.06em] text-[var(--deck-ink)] [text-transform:var(--nav-text-transform)]",
|
|
534
|
-
children: content.title
|
|
535
|
-
}
|
|
536
|
-
)
|
|
537
|
-
]
|
|
538
|
-
}
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// src/deck/DeckComponentView.tsx
|
|
543
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
544
|
-
function DeckComponentView({ component, slot }) {
|
|
545
|
-
switch (component.type) {
|
|
546
|
-
case "richText":
|
|
547
|
-
return /* @__PURE__ */ jsx8(DeckRichText, { content: component, slot });
|
|
548
|
-
case "image":
|
|
549
|
-
return /* @__PURE__ */ jsx8(DeckImage, { content: component });
|
|
550
|
-
case "imageGrid":
|
|
551
|
-
return /* @__PURE__ */ jsx8(DeckImageGrid, { content: component });
|
|
552
|
-
case "video":
|
|
553
|
-
return /* @__PURE__ */ jsx8(DeckVideo, { content: component });
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
// src/deck/layouts/CenteredTextLayout.tsx
|
|
558
|
-
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
559
|
-
function CenteredTextLayout({ layout }) {
|
|
560
|
-
return /* @__PURE__ */ jsx9(
|
|
561
|
-
"div",
|
|
562
|
-
{
|
|
563
|
-
"data-deck-layout": "centeredText",
|
|
564
|
-
"data-deck-surface": layout.background,
|
|
565
|
-
style: { ...surfaceInk(layout.background), ...deckAlign("center") },
|
|
566
|
-
className: cn(
|
|
567
|
-
"flex size-full flex-col items-center justify-center px-[180px] py-[110px] text-center",
|
|
568
|
-
SURFACE_BACKGROUND[layout.background]
|
|
569
|
-
),
|
|
570
|
-
children: /* @__PURE__ */ jsx9(DeckComponentView, { component: layout.content, slot: "content" })
|
|
571
|
-
}
|
|
572
|
-
);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
// src/deck/layouts/ColumnSplitLayout.tsx
|
|
576
|
-
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
577
|
-
var RATIO = {
|
|
578
|
-
"1-2": "grid-cols-[1fr_2fr]",
|
|
579
|
-
"2-1": "grid-cols-[2fr_1fr]"
|
|
580
|
-
};
|
|
581
|
-
var COLUMN_PADDING = {
|
|
582
|
-
richText: "flex flex-col justify-center px-[64px] py-[96px]",
|
|
583
|
-
image: "",
|
|
584
|
-
imageGrid: "p-[44px]",
|
|
585
|
-
video: "p-[44px]"
|
|
586
|
-
};
|
|
587
|
-
function ColumnSplitLayout({ layout }) {
|
|
588
|
-
const seam = layout.left.type === "richText" ? "left" : layout.right.type === "richText" ? "right" : null;
|
|
589
|
-
return /* @__PURE__ */ jsxs5(
|
|
590
|
-
"div",
|
|
591
|
-
{
|
|
592
|
-
"data-deck-layout": "columnSplit",
|
|
593
|
-
"data-deck-ratio": layout.ratio,
|
|
594
|
-
"data-deck-surface": "base",
|
|
595
|
-
style: { ...surfaceInk("base"), ...deckAlign("start") },
|
|
596
|
-
className: cn("grid size-full text-left", RATIO[layout.ratio], SURFACE_BACKGROUND.base),
|
|
597
|
-
children: [
|
|
598
|
-
/* @__PURE__ */ jsx10(Column, { component: layout.left, side: "left", rule: seam === "left" }),
|
|
599
|
-
/* @__PURE__ */ jsx10(Column, { component: layout.right, side: "right", rule: seam === "right" })
|
|
600
|
-
]
|
|
601
|
-
}
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
function Column({ component, side, rule }) {
|
|
605
|
-
return /* @__PURE__ */ jsx10(
|
|
606
|
-
"div",
|
|
607
|
-
{
|
|
608
|
-
"data-deck-column": side,
|
|
609
|
-
className: cn(
|
|
610
|
-
"relative min-w-0 overflow-hidden",
|
|
611
|
-
COLUMN_PADDING[component.type],
|
|
612
|
-
rule && (side === "left" ? "border-r border-base-200" : "border-l border-base-200")
|
|
613
|
-
),
|
|
614
|
-
children: /* @__PURE__ */ jsx10(DeckComponentView, { component, slot: side })
|
|
615
|
-
}
|
|
616
|
-
);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// src/deck/layouts/FullBleedImageLayout.tsx
|
|
620
|
-
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
621
|
-
var PLACEMENT = {
|
|
622
|
-
sideLeft: "top-0 bottom-0 left-0 w-[40%] justify-center px-[72px] py-[90px]",
|
|
623
|
-
sideRight: "top-0 bottom-0 right-0 w-[40%] justify-center px-[72px] py-[90px]",
|
|
624
|
-
bottomBand: "right-0 bottom-0 left-0 justify-end px-[96px] py-[56px]"
|
|
625
|
-
};
|
|
626
|
-
function FullBleedImageLayout({ layout }) {
|
|
627
|
-
const asset = useDeckMedia(layout.media);
|
|
628
|
-
const { overlay } = layout;
|
|
629
|
-
return /* @__PURE__ */ jsxs6(
|
|
630
|
-
"div",
|
|
631
|
-
{
|
|
632
|
-
"data-deck-layout": "fullBleedImage",
|
|
633
|
-
"data-deck-surface": "base",
|
|
634
|
-
style: { ...surfaceInk("base"), ...deckAlign("start") },
|
|
635
|
-
className: cn("relative size-full overflow-hidden", SURFACE_BACKGROUND.base),
|
|
636
|
-
children: [
|
|
637
|
-
asset === null ? /* @__PURE__ */ jsx11(DeckMissingMedia, { className: "absolute inset-0" }) : /* @__PURE__ */ jsx11("img", { src: asset.src, alt: asset.alt, className: "absolute inset-0 size-full object-cover" }),
|
|
638
|
-
overlay !== void 0 && /* @__PURE__ */ jsx11(
|
|
639
|
-
"div",
|
|
640
|
-
{
|
|
641
|
-
"data-deck-overlay": overlay.placement,
|
|
642
|
-
"data-deck-surface": "brand",
|
|
643
|
-
style: surfaceInk("brand"),
|
|
644
|
-
className: cn("absolute z-[2] flex flex-col text-left", SURFACE_BACKGROUND.brand, PLACEMENT[overlay.placement]),
|
|
645
|
-
children: /* @__PURE__ */ jsx11(DeckRichText, { content: overlay.content, slot: "overlay" })
|
|
646
|
-
}
|
|
647
|
-
)
|
|
648
|
-
]
|
|
649
|
-
}
|
|
650
|
-
);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// src/deck/DeckSlideView.tsx
|
|
654
|
-
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
655
|
-
function LayoutView({ slide }) {
|
|
656
|
-
const { layout } = slide;
|
|
657
|
-
switch (layout.type) {
|
|
658
|
-
case "centeredText":
|
|
659
|
-
return /* @__PURE__ */ jsx12(CenteredTextLayout, { layout });
|
|
660
|
-
case "fullBleedImage":
|
|
661
|
-
return /* @__PURE__ */ jsx12(FullBleedImageLayout, { layout });
|
|
662
|
-
case "columnSplit":
|
|
663
|
-
return /* @__PURE__ */ jsx12(ColumnSplitLayout, { layout });
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
function DeckSlideView({ slide }) {
|
|
667
|
-
return /* @__PURE__ */ jsx12("div", { "data-deck-slide": slide.id, className: "size-full", children: /* @__PURE__ */ jsx12(LayoutView, { slide }) }, slide.id);
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// src/deck/DeckPlayer.tsx
|
|
671
|
-
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
672
|
-
function clamp(index, length) {
|
|
673
|
-
return Math.min(Math.max(index, 0), length - 1);
|
|
674
|
-
}
|
|
675
|
-
function isTypingTarget(target) {
|
|
676
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
677
|
-
return target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
|
|
678
|
-
}
|
|
679
|
-
function isActivatableTarget(target) {
|
|
680
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
681
|
-
if (target.tagName === "BUTTON" || target.tagName === "SUMMARY") return true;
|
|
682
|
-
if (target.tagName === "A" && target.hasAttribute("href")) return true;
|
|
683
|
-
return target.getAttribute("role") === "button";
|
|
684
|
-
}
|
|
685
|
-
var NAV_BUTTON = "flex size-[38px] items-center justify-center rounded-[var(--radius-outer)] border border-base-200 text-base-contrast transition-colors hover:bg-base-accent disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent";
|
|
686
|
-
function DeckPlayer({ deck, initialSlide = 0, keyboard = true, resolveMedia, mediaAssets, className }) {
|
|
687
|
-
const total = deck.slides.length;
|
|
688
|
-
const [index, setIndex] = useState5(() => clamp(initialSlide, total));
|
|
689
|
-
const resolve = useMemo2(
|
|
690
|
-
() => resolveMedia ?? ((ref) => ref.kind === "portal" && mediaAssets !== void 0 && Object.hasOwn(mediaAssets, ref.id) ? mediaAssets[ref.id] : null),
|
|
691
|
-
[resolveMedia, mediaAssets]
|
|
692
|
-
);
|
|
693
|
-
const current = clamp(index, total);
|
|
694
|
-
const slide = deck.slides[current];
|
|
695
|
-
const goTo = useCallback2((next) => setIndex(clamp(next, total)), [total]);
|
|
696
|
-
const step = useCallback2(
|
|
697
|
-
(delta) => setIndex((prev) => clamp(clamp(prev, total) + delta, total)),
|
|
698
|
-
[total]
|
|
699
|
-
);
|
|
700
|
-
useEffect4(() => {
|
|
701
|
-
if (!keyboard) return;
|
|
702
|
-
const onKeyDown = (event) => {
|
|
703
|
-
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
|
704
|
-
if (isTypingTarget(event.target)) return;
|
|
705
|
-
switch (event.key) {
|
|
706
|
-
case " ":
|
|
707
|
-
if (isActivatableTarget(event.target)) return;
|
|
708
|
-
event.preventDefault();
|
|
709
|
-
step(1);
|
|
710
|
-
break;
|
|
711
|
-
case "ArrowRight":
|
|
712
|
-
case "PageDown":
|
|
713
|
-
event.preventDefault();
|
|
714
|
-
step(1);
|
|
715
|
-
break;
|
|
716
|
-
case "ArrowLeft":
|
|
717
|
-
case "PageUp":
|
|
718
|
-
event.preventDefault();
|
|
719
|
-
step(-1);
|
|
720
|
-
break;
|
|
721
|
-
case "Home":
|
|
722
|
-
event.preventDefault();
|
|
723
|
-
setIndex(0);
|
|
724
|
-
break;
|
|
725
|
-
case "End":
|
|
726
|
-
event.preventDefault();
|
|
727
|
-
setIndex(total - 1);
|
|
728
|
-
break;
|
|
729
|
-
}
|
|
730
|
-
};
|
|
731
|
-
window.addEventListener("keydown", onKeyDown);
|
|
732
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
733
|
-
}, [keyboard, step, total]);
|
|
734
|
-
return /* @__PURE__ */ jsxs7("div", { "data-deck-player": deck.id, className: cn("flex h-full min-h-0 w-full flex-col gap-4 bg-base p-4", className), children: [
|
|
735
|
-
/* @__PURE__ */ jsx13(DeckStage, { className: "flex-1", children: /* @__PURE__ */ jsx13(DeckMediaProvider, { resolve, children: /* @__PURE__ */ jsx13(DeckSlideView, { slide }) }) }),
|
|
736
|
-
/* @__PURE__ */ jsxs7("nav", { "aria-label": `${deck.title} slides`, className: "flex shrink-0 items-center justify-center gap-4", children: [
|
|
737
|
-
/* @__PURE__ */ jsx13("button", { type: "button", className: NAV_BUTTON, onClick: () => step(-1), disabled: current === 0, "aria-label": "Previous slide", children: /* @__PURE__ */ jsx13(ChevronLeft, { className: "size-5", "aria-hidden": "true" }) }),
|
|
738
|
-
/* @__PURE__ */ jsx13("ol", { className: "flex items-center gap-2", children: deck.slides.map((s, i) => /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsx13(
|
|
739
|
-
"button",
|
|
740
|
-
{
|
|
741
|
-
type: "button",
|
|
742
|
-
onClick: () => goTo(i),
|
|
743
|
-
"aria-current": i === current ? "true" : void 0,
|
|
744
|
-
"aria-label": s.title ? `Slide ${i + 1}: ${s.title}` : `Slide ${i + 1}`,
|
|
745
|
-
className: cn(
|
|
746
|
-
"size-[10px] rounded-full transition-colors",
|
|
747
|
-
i === current ? "bg-primary" : "bg-base-300 hover:bg-base-contrast-light"
|
|
748
|
-
)
|
|
749
|
-
}
|
|
750
|
-
) }, s.id)) }),
|
|
751
|
-
/* @__PURE__ */ jsx13("button", { type: "button", className: NAV_BUTTON, onClick: () => step(1), disabled: current === total - 1, "aria-label": "Next slide", children: /* @__PURE__ */ jsx13(ChevronRight, { className: "size-5", "aria-hidden": "true" }) }),
|
|
752
|
-
/* @__PURE__ */ jsxs7("p", { "aria-live": "polite", className: "ml-2 text-sm tabular-nums text-base-contrast-light", children: [
|
|
753
|
-
current + 1,
|
|
754
|
-
" / ",
|
|
755
|
-
total
|
|
756
|
-
] })
|
|
757
|
-
] })
|
|
758
|
-
] });
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
export {
|
|
762
|
-
DeckMediaProvider,
|
|
763
|
-
useDeckMedia,
|
|
764
|
-
useDeckMediaResolver,
|
|
765
|
-
DeckMissingMedia,
|
|
766
|
-
useStageScale,
|
|
767
|
-
DeckStage,
|
|
768
|
-
surfaceInk,
|
|
769
|
-
SURFACE_BACKGROUND,
|
|
770
|
-
deckAlign,
|
|
771
|
-
DECK_ELEVATION,
|
|
772
|
-
DeckImage,
|
|
773
|
-
DeckImageGrid,
|
|
774
|
-
DeckTextEditProvider,
|
|
775
|
-
EditableText,
|
|
776
|
-
DeckRichText,
|
|
777
|
-
DeckVideo,
|
|
778
|
-
DeckComponentView,
|
|
779
|
-
CenteredTextLayout,
|
|
780
|
-
ColumnSplitLayout,
|
|
781
|
-
FullBleedImageLayout,
|
|
782
|
-
DeckSlideView,
|
|
783
|
-
DeckPlayer
|
|
784
|
-
};
|