@drawnagency/primitives 0.1.118 → 0.1.120
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-4NSOKEA7.js → chunk-HFHM4MNK.js} +12 -7
- package/dist/{chunk-CEFFP3CH.js → chunk-HZTPF6OK.js} +304 -83
- 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-UZBFVVTC.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/AudienceIndicator.d.ts +3 -1
- package/dist/components/editor/AudienceIndicator.d.ts.map +1 -1
- package/dist/components/editor/IndicatorPill.d.ts +3 -1
- package/dist/components/editor/IndicatorPill.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/SectionBulkEditModal.d.ts +25 -0
- package/dist/components/editor/SectionBulkEditModal.d.ts.map +1 -0
- package/dist/components/editor/StatusIndicator.d.ts +3 -1
- package/dist/components/editor/StatusIndicator.d.ts.map +1 -1
- package/dist/components/editor/index.js +28 -26
- 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/shared/Popover.d.ts +1 -1
- package/dist/components/shared/Popover.d.ts.map +1 -1
- package/dist/components/shared/SectionSummaryRow.d.ts +1 -1
- package/dist/components/shell/AudienceChips.d.ts +1 -3
- package/dist/components/shell/AudienceChips.d.ts.map +1 -1
- package/dist/components/shell/EditorModal.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/AudienceIndicator.tsx +8 -4
- package/src/components/editor/IndicatorPill.tsx +4 -0
- package/src/components/editor/PagesModal.tsx +1 -15
- package/src/components/editor/SectionBulkEditModal.tsx +328 -0
- package/src/components/editor/StatusIndicator.tsx +7 -6
- package/src/components/shared/Popover.tsx +17 -4
- package/src/components/shared/SectionSummaryRow.tsx +1 -1
- package/src/components/shell/AudienceChips.tsx +1 -3
- package/src/components/shell/EditorModal.tsx +5 -2
- package/src/components/shell/EditorShell.tsx +15 -119
- 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/editor/SectionOrderingModal.d.ts +0 -10
- package/dist/components/editor/SectionOrderingModal.d.ts.map +0 -1
- 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/editor/SectionOrderingModal.tsx +0 -80
- 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/src/deck/flip.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FLIP for the image grid's expand/collapse.
|
|
3
|
-
*
|
|
4
|
-
* The grid changes layout via React state, so the "First" rects have to be
|
|
5
|
-
* taken in the event handler (before `setState`) and the invert applied in a
|
|
6
|
-
* layout effect (after the DOM has moved, before paint).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const TILE_SELECTOR = "[data-deck-tile]";
|
|
10
|
-
|
|
11
|
-
export type TileRects = Map<Element, DOMRect>;
|
|
12
|
-
|
|
13
|
-
export function captureTileRects(grid: HTMLElement): TileRects {
|
|
14
|
-
const rects: TileRects = new Map();
|
|
15
|
-
for (const tile of grid.querySelectorAll(TILE_SELECTOR)) rects.set(tile, tile.getBoundingClientRect());
|
|
16
|
-
return rects;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Rects are screen-space but the transform applies inside the stage, which is
|
|
21
|
-
* itself scaled — so translations divide by that scale or the tile overshoots
|
|
22
|
-
* by exactly the stage factor. `DeckStage` publishes it as `data-deck-scale`.
|
|
23
|
-
*/
|
|
24
|
-
function stageScale(el: Element): number {
|
|
25
|
-
const raw = el.closest("[data-deck-stage]")?.getAttribute("data-deck-scale");
|
|
26
|
-
const value = raw === null || raw === undefined ? Number.NaN : Number(raw);
|
|
27
|
-
return Number.isFinite(value) && value > 0 ? value : 1;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function playTileFlip(grid: HTMLElement, before: TileRects): void {
|
|
31
|
-
const scale = stageScale(grid);
|
|
32
|
-
const moved: HTMLElement[] = [];
|
|
33
|
-
|
|
34
|
-
for (const tile of grid.querySelectorAll<HTMLElement>(TILE_SELECTOR)) {
|
|
35
|
-
const first = before.get(tile);
|
|
36
|
-
if (!first) continue;
|
|
37
|
-
const last = tile.getBoundingClientRect();
|
|
38
|
-
// Unmeasurable boxes (jsdom, a hidden ancestor) invert to NaN; skip them
|
|
39
|
-
// and the tile simply lands without an animation.
|
|
40
|
-
if (!first.width || !last.width) continue;
|
|
41
|
-
|
|
42
|
-
// Inverted about the element's CENTER, which is `transform-origin`'s
|
|
43
|
-
// default — so this never sets the property and never has to clean it up.
|
|
44
|
-
// A top-left origin would have to be cleared, and clearing it synchronously
|
|
45
|
-
// jumps an in-flight animation while leaving it behind makes the tile's
|
|
46
|
-
// next hover scale from its corner instead of its middle.
|
|
47
|
-
const dx = (first.left + first.width / 2 - (last.left + last.width / 2)) / scale;
|
|
48
|
-
const dy = (first.top + first.height / 2 - (last.top + last.height / 2)) / scale;
|
|
49
|
-
const sx = first.width / last.width;
|
|
50
|
-
const sy = first.height / last.height;
|
|
51
|
-
if (Math.abs(dx) < 0.5 && Math.abs(dy) < 0.5 && Math.abs(sx - 1) < 0.002) continue;
|
|
52
|
-
|
|
53
|
-
tile.style.transition = "none";
|
|
54
|
-
tile.style.transform = `translate(${dx}px, ${dy}px) scale(${sx}, ${sy})`;
|
|
55
|
-
moved.push(tile);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (moved.length === 0) return;
|
|
59
|
-
|
|
60
|
-
// Commit the inverted start state with a synchronous reflow, NOT
|
|
61
|
-
// requestAnimationFrame: rAF does not run in a background tab, and a deck
|
|
62
|
-
// left on an inactive tab would come back with every tile stranded under its
|
|
63
|
-
// inverse transform.
|
|
64
|
-
void grid.offsetWidth;
|
|
65
|
-
|
|
66
|
-
for (const tile of moved) {
|
|
67
|
-
tile.style.transition = "";
|
|
68
|
-
tile.style.transform = "";
|
|
69
|
-
}
|
|
70
|
-
}
|
package/src/deck/index.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The deck runtime — a sealed subtree, like ./document.
|
|
3
|
-
*
|
|
4
|
-
* NOT re-exported from the primitives root barrel, and deliberately not a
|
|
5
|
-
* section type: nothing on an ordinary viewer page may pull this graph in.
|
|
6
|
-
* Only deck surfaces (the Deck Builder, in-portal deck views, the Public Link
|
|
7
|
-
* route) import from here.
|
|
8
|
-
*/
|
|
9
|
-
export { DeckPlayer } from "./DeckPlayer";
|
|
10
|
-
export { DeckStage } from "./DeckStage";
|
|
11
|
-
export { DeckSlideView } from "./DeckSlideView";
|
|
12
|
-
export { DeckComponentView } from "./DeckComponentView";
|
|
13
|
-
export { CenteredTextLayout } from "./layouts/CenteredTextLayout";
|
|
14
|
-
export { ColumnSplitLayout } from "./layouts/ColumnSplitLayout";
|
|
15
|
-
export { FullBleedImageLayout } from "./layouts/FullBleedImageLayout";
|
|
16
|
-
export { DeckRichText } from "./components/DeckRichText";
|
|
17
|
-
export { DeckImage } from "./components/DeckImage";
|
|
18
|
-
export { DeckImageGrid } from "./components/DeckImageGrid";
|
|
19
|
-
export { DeckVideo } from "./components/DeckVideo";
|
|
20
|
-
export {
|
|
21
|
-
DeckMediaProvider,
|
|
22
|
-
DeckMissingMedia,
|
|
23
|
-
useDeckMedia,
|
|
24
|
-
useDeckMediaResolver,
|
|
25
|
-
type DeckMediaAsset,
|
|
26
|
-
type DeckMediaResolver,
|
|
27
|
-
} from "./media";
|
|
28
|
-
export { DeckTextEditProvider, EditableText, type DeckTextEditor } from "./editing";
|
|
29
|
-
export { useStageScale } from "./useStageScale";
|
|
30
|
-
export { deckAlign, surfaceInk, DECK_ELEVATION, SURFACE_BACKGROUND, type DeckSurface } from "./tokens";
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { cn } from "../../lib/cn";
|
|
2
|
-
import type { CenteredTextLayout as CenteredTextLayoutNode } from "../../schemas/deck";
|
|
3
|
-
import { DeckComponentView } from "../DeckComponentView";
|
|
4
|
-
import { deckAlign, SURFACE_BACKGROUND, surfaceInk } from "../tokens";
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
layout: CenteredTextLayoutNode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Layout — centered text. A full-slide title card holding one Deck Component,
|
|
12
|
-
* centered on both axes. The Layout owns the surface (background + ink tokens)
|
|
13
|
-
* and the stage-relative padding; the component owns nothing but its own type.
|
|
14
|
-
*/
|
|
15
|
-
export function CenteredTextLayout({ layout }: Props) {
|
|
16
|
-
return (
|
|
17
|
-
<div
|
|
18
|
-
data-deck-layout="centeredText"
|
|
19
|
-
data-deck-surface={layout.background}
|
|
20
|
-
style={{ ...surfaceInk(layout.background), ...deckAlign("center") }}
|
|
21
|
-
className={cn(
|
|
22
|
-
"flex size-full flex-col items-center justify-center px-[180px] py-[110px] text-center",
|
|
23
|
-
SURFACE_BACKGROUND[layout.background],
|
|
24
|
-
)}
|
|
25
|
-
>
|
|
26
|
-
<DeckComponentView component={layout.content} slot="content" />
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { cn } from "../../lib/cn";
|
|
2
|
-
import type { ColumnSplitLayout as ColumnSplitLayoutNode, DeckComponent, DeckSplitRatio } from "../../schemas/deck";
|
|
3
|
-
import { DeckComponentView } from "../DeckComponentView";
|
|
4
|
-
import { deckAlign, SURFACE_BACKGROUND, surfaceInk } from "../tokens";
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
layout: ColumnSplitLayoutNode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const RATIO: Record<DeckSplitRatio, string> = {
|
|
11
|
-
"1-2": "grid-cols-[1fr_2fr]",
|
|
12
|
-
"2-1": "grid-cols-[2fr_1fr]",
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* How much air a column gives its component. Text needs generous margins; an
|
|
17
|
-
* image is meant to run to the stage edge; a grid and a video need enough
|
|
18
|
-
* breathing room for a tile to lift without clipping.
|
|
19
|
-
*/
|
|
20
|
-
const COLUMN_PADDING: Record<DeckComponent["type"], string> = {
|
|
21
|
-
richText: "flex flex-col justify-center px-[64px] py-[96px]",
|
|
22
|
-
image: "",
|
|
23
|
-
imageGrid: "p-[44px]",
|
|
24
|
-
video: "p-[44px]",
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Layout — left/right column split.
|
|
29
|
-
*
|
|
30
|
-
* The hairline runs down the text column's inner edge, which is the editorial
|
|
31
|
-
* treatment's only separator: the columns are set apart by the type and the
|
|
32
|
-
* crop, not by a card or a shadow.
|
|
33
|
-
*/
|
|
34
|
-
export function ColumnSplitLayout({ layout }: Props) {
|
|
35
|
-
// The rule belongs to the seam, so exactly one column ever draws it. Asking
|
|
36
|
-
// each text column for its own inner border drew a 2px rule whenever both
|
|
37
|
-
// columns held text — the one case where the hairline is doing the most work.
|
|
38
|
-
const seam = layout.left.type === "richText" ? "left" : layout.right.type === "richText" ? "right" : null;
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<div
|
|
42
|
-
data-deck-layout="columnSplit"
|
|
43
|
-
data-deck-ratio={layout.ratio}
|
|
44
|
-
data-deck-surface="base"
|
|
45
|
-
style={{ ...surfaceInk("base"), ...deckAlign("start") }}
|
|
46
|
-
className={cn("grid size-full text-left", RATIO[layout.ratio], SURFACE_BACKGROUND.base)}
|
|
47
|
-
>
|
|
48
|
-
<Column component={layout.left} side="left" rule={seam === "left"} />
|
|
49
|
-
<Column component={layout.right} side="right" rule={seam === "right"} />
|
|
50
|
-
</div>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// `side` doubles as the edit-seam slot name (see DeckTextPath) — the two are
|
|
55
|
-
// the same coordinate, so keeping one avoids a mapping that could drift.
|
|
56
|
-
function Column({ component, side, rule }: { component: DeckComponent; side: "left" | "right"; rule: boolean }) {
|
|
57
|
-
return (
|
|
58
|
-
<div
|
|
59
|
-
data-deck-column={side}
|
|
60
|
-
className={cn(
|
|
61
|
-
"relative min-w-0 overflow-hidden",
|
|
62
|
-
COLUMN_PADDING[component.type],
|
|
63
|
-
rule && (side === "left" ? "border-r border-base-200" : "border-l border-base-200"),
|
|
64
|
-
)}
|
|
65
|
-
>
|
|
66
|
-
<DeckComponentView component={component} slot={side} />
|
|
67
|
-
</div>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { cn } from "../../lib/cn";
|
|
2
|
-
import type { DeckOverlayPlacement, FullBleedImageLayout as FullBleedImageLayoutNode } from "../../schemas/deck";
|
|
3
|
-
import { DeckRichText } from "../components/DeckRichText";
|
|
4
|
-
import { DeckMissingMedia, useDeckMedia } from "../media";
|
|
5
|
-
import { deckAlign, SURFACE_BACKGROUND, surfaceInk } from "../tokens";
|
|
6
|
-
|
|
7
|
-
interface Props {
|
|
8
|
-
layout: FullBleedImageLayoutNode;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Panel geometry, stage-relative. Hard edges and full bleed to the stage sides
|
|
13
|
-
* — the panel is a block of brand color laid over the picture, not a card
|
|
14
|
-
* floating on it.
|
|
15
|
-
*/
|
|
16
|
-
const PLACEMENT: Record<DeckOverlayPlacement, string> = {
|
|
17
|
-
sideLeft: "top-0 bottom-0 left-0 w-[40%] justify-center px-[72px] py-[90px]",
|
|
18
|
-
sideRight: "top-0 bottom-0 right-0 w-[40%] justify-center px-[72px] py-[90px]",
|
|
19
|
-
bottomBand: "right-0 bottom-0 left-0 justify-end px-[96px] py-[56px]",
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Layout — full-bleed image with an optional text overlay panel.
|
|
24
|
-
*
|
|
25
|
-
* The Layout owns both surfaces: the slide is base (the image covers it), the
|
|
26
|
-
* panel declares brand, so the rich text inside reads on-primary ink without
|
|
27
|
-
* knowing it sits over a photograph.
|
|
28
|
-
*/
|
|
29
|
-
export function FullBleedImageLayout({ layout }: Props) {
|
|
30
|
-
const asset = useDeckMedia(layout.media);
|
|
31
|
-
const { overlay } = layout;
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<div
|
|
35
|
-
data-deck-layout="fullBleedImage"
|
|
36
|
-
data-deck-surface="base"
|
|
37
|
-
style={{ ...surfaceInk("base"), ...deckAlign("start") }}
|
|
38
|
-
className={cn("relative size-full overflow-hidden", SURFACE_BACKGROUND.base)}
|
|
39
|
-
>
|
|
40
|
-
{asset === null ? (
|
|
41
|
-
<DeckMissingMedia className="absolute inset-0" />
|
|
42
|
-
) : (
|
|
43
|
-
<img src={asset.src} alt={asset.alt} className="absolute inset-0 size-full object-cover" />
|
|
44
|
-
)}
|
|
45
|
-
|
|
46
|
-
{overlay !== undefined && (
|
|
47
|
-
<div
|
|
48
|
-
data-deck-overlay={overlay.placement}
|
|
49
|
-
data-deck-surface="brand"
|
|
50
|
-
style={surfaceInk("brand")}
|
|
51
|
-
className={cn("absolute z-[2] flex flex-col text-left", SURFACE_BACKGROUND.brand, PLACEMENT[overlay.placement])}
|
|
52
|
-
>
|
|
53
|
-
<DeckRichText content={overlay.content} slot="overlay" />
|
|
54
|
-
</div>
|
|
55
|
-
)}
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
}
|
package/src/deck/media.tsx
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, type ReactNode } from "react";
|
|
2
|
-
import { cn } from "../lib/cn";
|
|
3
|
-
import type { DeckMediaAsset, DeckMediaRef, DeckMediaResolver } from "../schemas/deck";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The runtime's media seam.
|
|
7
|
-
*
|
|
8
|
-
* Deck JSON stores references, never URLs (ADR 0001), so something outside the
|
|
9
|
-
* runtime has to turn `{ kind: "portal", id }` into bytes. That something is a
|
|
10
|
-
* resolver injected through context: the Deck Builder passes the manifest-backed
|
|
11
|
-
* one, the dev preview route passes placeholders, and the components below never
|
|
12
|
-
* learn which. Absent a provider every reference resolves to `null`, which is
|
|
13
|
-
* also what a deleted asset resolves to — one path, one rendering.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
export type { DeckMediaAsset, DeckMediaResolver } from "../schemas/deck";
|
|
17
|
-
|
|
18
|
-
const NO_MEDIA: DeckMediaResolver = () => null;
|
|
19
|
-
|
|
20
|
-
const DeckMediaContext = createContext<DeckMediaResolver>(NO_MEDIA);
|
|
21
|
-
|
|
22
|
-
export function DeckMediaProvider({ resolve, children }: { resolve: DeckMediaResolver; children: ReactNode }) {
|
|
23
|
-
return <DeckMediaContext.Provider value={resolve}>{children}</DeckMediaContext.Provider>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function useDeckMedia(ref: DeckMediaRef): DeckMediaAsset | null {
|
|
27
|
-
return useContext(DeckMediaContext)(ref);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* The resolver itself, for a component that has to resolve a whole set before
|
|
32
|
-
* it can lay any of it out — the image grid packs its masonry columns from
|
|
33
|
-
* every tile's aspect ratio, which it cannot learn one `useDeckMedia` at a time.
|
|
34
|
-
*/
|
|
35
|
-
export function useDeckMediaResolver(): DeckMediaResolver {
|
|
36
|
-
return useContext(DeckMediaContext);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* What an unresolvable reference renders. A published deck can outlive the
|
|
41
|
-
* media it points at (ADR 0002 flags the GC hazard), and a torn alt string over
|
|
42
|
-
* a presentation is worse than a quiet gap.
|
|
43
|
-
*/
|
|
44
|
-
export function DeckMissingMedia({ className }: { className?: string }) {
|
|
45
|
-
return <span data-deck-media="missing" aria-hidden="true" className={cn("block size-full bg-base-200", className)} />;
|
|
46
|
-
}
|
package/src/deck/tokens.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import type { CSSProperties } from "react";
|
|
2
|
-
import type { DeckSurface } from "../schemas/deck";
|
|
3
|
-
|
|
4
|
-
export type { DeckSurface } from "../schemas/deck";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Deck ink is indirected through three custom properties so a Deck Component
|
|
8
|
-
* never has to know what it is sitting on: a Layout declares the palette for
|
|
9
|
-
* its surface, components read `--deck-ink` / `--deck-ink-muted` /
|
|
10
|
-
* `--deck-accent`. Every value resolves to a portal brand token — nothing in
|
|
11
|
-
* the deck runtime carries a literal color.
|
|
12
|
-
*/
|
|
13
|
-
const SURFACE_INK: Record<DeckSurface, CSSProperties> = {
|
|
14
|
-
base: {
|
|
15
|
-
"--deck-ink": "var(--color-base-contrast)",
|
|
16
|
-
"--deck-ink-muted": "var(--color-base-contrast-light)",
|
|
17
|
-
"--deck-accent": "var(--color-primary)",
|
|
18
|
-
} as CSSProperties,
|
|
19
|
-
brand: {
|
|
20
|
-
"--deck-ink": "var(--color-on-primary)",
|
|
21
|
-
"--deck-ink-muted": "color-mix(in srgb, var(--color-on-primary) 72%, transparent)",
|
|
22
|
-
"--deck-accent": "var(--color-primary-contrast)",
|
|
23
|
-
} as CSSProperties,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export function surfaceInk(surface: DeckSurface): CSSProperties {
|
|
27
|
-
return SURFACE_INK[surface];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Tailwind background utility for a surface — both are brand tokens. */
|
|
31
|
-
export const SURFACE_BACKGROUND: Record<DeckSurface, string> = {
|
|
32
|
-
base: "bg-base-accent",
|
|
33
|
-
brand: "bg-primary",
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Alignment travels the same way the ink does: a Layout declares how its slot
|
|
38
|
-
* reads, components resolve `--deck-align` (an `align-self` value). Without it
|
|
39
|
-
* a component would have to know whether it sits on a centered title card or in
|
|
40
|
-
* a left-aligned column, which is precisely what the indirection prevents.
|
|
41
|
-
*/
|
|
42
|
-
export type DeckAlign = "center" | "start";
|
|
43
|
-
|
|
44
|
-
export function deckAlign(align: DeckAlign): CSSProperties {
|
|
45
|
-
return { "--deck-align": align } as CSSProperties;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Elevation for media that lifts off the slide — grid tiles on hover, the video
|
|
50
|
-
* play affordance. Declared as `--deck-*` custom properties rather than as
|
|
51
|
-
* arbitrary Tailwind values so the shadow can be mixed from the site's ink
|
|
52
|
-
* token instead of a literal rgba, and so a hover variant can reference it.
|
|
53
|
-
*/
|
|
54
|
-
export const DECK_ELEVATION: CSSProperties = {
|
|
55
|
-
"--deck-lift": "0 26px 46px -18px color-mix(in srgb, var(--color-base-contrast) 45%, transparent)",
|
|
56
|
-
"--deck-lift-strong": "0 30px 60px -22px color-mix(in srgb, var(--color-base-contrast) 58%, transparent)",
|
|
57
|
-
} as CSSProperties;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { useEffect, useLayoutEffect, useState, type RefObject } from "react";
|
|
2
|
-
import { DECK_STAGE_HEIGHT, DECK_STAGE_WIDTH } from "../schemas/deck";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The first measurement has to happen before paint or the stage shows one frame
|
|
6
|
-
* unscaled — a full-bleed 1600x900 flash on a laptop viewport. useLayoutEffect
|
|
7
|
-
* warns when React renders on the server (Astro SSRs this island), and there is
|
|
8
|
-
* nothing to measure there anyway, so fall back to useEffect off the browser.
|
|
9
|
-
*/
|
|
10
|
-
const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* The factor that fits the fixed 1600x900 stage inside `fitRef`'s box.
|
|
14
|
-
*
|
|
15
|
-
* `null` until the box has been measured — an unmeasured box (SSR, jsdom, a
|
|
16
|
-
* hidden ancestor) reports 0x0, and scaling the stage to 0 would blank it. The
|
|
17
|
-
* caller renders the stage unscaled until a real measurement arrives.
|
|
18
|
-
*/
|
|
19
|
-
export function useStageScale(fitRef: RefObject<HTMLElement | null>): number | null {
|
|
20
|
-
const [scale, setScale] = useState<number | null>(null);
|
|
21
|
-
|
|
22
|
-
useIsomorphicLayoutEffect(() => {
|
|
23
|
-
const el = fitRef.current;
|
|
24
|
-
if (!el) return;
|
|
25
|
-
|
|
26
|
-
const measure = () => {
|
|
27
|
-
const { clientWidth, clientHeight } = el;
|
|
28
|
-
if (!clientWidth || !clientHeight) return;
|
|
29
|
-
setScale(Math.min(clientWidth / DECK_STAGE_WIDTH, clientHeight / DECK_STAGE_HEIGHT));
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
measure();
|
|
33
|
-
|
|
34
|
-
if (typeof ResizeObserver === "undefined") {
|
|
35
|
-
window.addEventListener("resize", measure);
|
|
36
|
-
return () => window.removeEventListener("resize", measure);
|
|
37
|
-
}
|
|
38
|
-
const observer = new ResizeObserver(measure);
|
|
39
|
-
observer.observe(el);
|
|
40
|
-
return () => observer.disconnect();
|
|
41
|
-
}, [fitRef]);
|
|
42
|
-
|
|
43
|
-
return scale;
|
|
44
|
-
}
|