@heyramzi/ui 1.54.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +3 -2
- package/README.md +34 -9
- package/package.json +198 -6
- package/src/ai/generation-progress/GenerationProgress.svelte +12 -12
- package/src/ambient.d.ts +8 -0
- package/src/brand/brand.test.ts +67 -0
- package/src/brand/index.ts +137 -0
- package/src/canvas/README.md +236 -0
- package/src/canvas/card/card-frame.svelte +61 -0
- package/src/canvas/card/card.css +39 -0
- package/src/canvas/card/resize-handles.svelte +119 -0
- package/src/canvas/card/resize.ts +33 -0
- package/src/canvas/chrome/chrome-zoom.svelte +120 -0
- package/src/canvas/chrome/chrome.css +231 -0
- package/src/canvas/chrome/lock-badge.svelte +18 -0
- package/src/canvas/chrome/side-handles.svelte +30 -0
- package/src/canvas/chrome/size-chip.svelte +45 -0
- package/src/canvas/chrome/snap-guides.svelte +69 -0
- package/src/canvas/components/icons/ToolIcon.svelte +30 -0
- package/src/canvas/components/shared/svg/PreviewSvg.svelte +67 -0
- package/src/canvas/components/shared/svg/ShapeOutline.svelte +76 -0
- package/src/canvas/components/shared/svg/StrokeNode.svelte +69 -0
- package/src/canvas/components/shared/svg/TextRule.svelte +37 -0
- package/src/canvas/edges/bend-handle.svelte +76 -0
- package/src/canvas/edges/edge-gradient.svelte +30 -0
- package/src/canvas/edges/edge-path.test.ts +58 -0
- package/src/canvas/edges/edge-path.ts +293 -0
- package/src/canvas/edges/gradient-edge.svelte +43 -0
- package/src/canvas/editor/context-menu.test.ts +65 -0
- package/src/canvas/editor/context-menu.ts +48 -0
- package/src/canvas/editor/dispatch.svelte.test.ts +243 -0
- package/src/canvas/editor/dispatch.svelte.ts +205 -0
- package/src/canvas/editor/editor-context.ts +62 -0
- package/src/canvas/editor/editor-mode.ts +67 -0
- package/src/canvas/editor/frame.ts +98 -0
- package/src/canvas/editor/hand-context.ts +15 -0
- package/src/canvas/editor/history-core.test.ts +239 -0
- package/src/canvas/editor/history-core.ts +247 -0
- package/src/canvas/editor/keymap.test.ts +161 -0
- package/src/canvas/editor/keymap.ts +151 -0
- package/src/canvas/editor/layout-actions.test.ts +156 -0
- package/src/canvas/editor/layout-actions.ts +219 -0
- package/src/canvas/editor/lock.test.ts +68 -0
- package/src/canvas/editor/lock.ts +87 -0
- package/src/canvas/editor/rebase.test.ts +208 -0
- package/src/canvas/editor/rebase.ts +272 -0
- package/src/canvas/editor/style.ts +184 -0
- package/src/canvas/editor/text-field-context.ts +41 -0
- package/src/canvas/editor/z-order.test.ts +75 -0
- package/src/canvas/editor/z-order.ts +87 -0
- package/src/canvas/headless/alignment.test.ts +59 -0
- package/src/canvas/headless/alignment.ts +23 -0
- package/src/canvas/headless/break-apart-find.ts +418 -0
- package/src/canvas/headless/break-apart-pieces.ts +104 -0
- package/src/canvas/headless/break-apart-plan.ts +439 -0
- package/src/canvas/headless/break-apart-style.ts +106 -0
- package/src/canvas/headless/break-apart.ts +244 -0
- package/src/canvas/headless/canvas-cleanup.test.ts +181 -0
- package/src/canvas/headless/canvas-cleanup.ts +102 -0
- package/src/canvas/headless/edge-anchors.test.ts +70 -0
- package/src/canvas/headless/edge-anchors.ts +143 -0
- package/src/canvas/headless/edge-memo.test.ts +58 -0
- package/src/canvas/headless/edge-memo.ts +32 -0
- package/src/canvas/headless/edge-serialization.test.ts +55 -0
- package/src/canvas/headless/edge-serialization.ts +32 -0
- package/src/canvas/headless/figure-geometry.ts +293 -0
- package/src/canvas/headless/fit-viewport.test.ts +85 -0
- package/src/canvas/headless/fit-viewport.ts +137 -0
- package/src/canvas/headless/grid.test.ts +34 -0
- package/src/canvas/headless/grid.ts +94 -0
- package/src/canvas/headless/icon-node.test.ts +23 -0
- package/src/canvas/headless/icon-node.ts +66 -0
- package/src/canvas/headless/index.ts +9 -0
- package/src/canvas/headless/linkify.test.ts +23 -0
- package/src/canvas/headless/linkify.ts +25 -0
- package/src/canvas/headless/pen-marks.ts +133 -0
- package/src/canvas/headless/sketch.test.ts +99 -0
- package/src/canvas/headless/sketch.ts +302 -0
- package/src/canvas/headless/snap-guides.test.ts +61 -0
- package/src/canvas/headless/snap-guides.ts +146 -0
- package/src/canvas/headless/svg-figure.test.ts +49 -0
- package/src/canvas/headless/svg-figure.ts +176 -0
- package/src/canvas/headless/table-layout.test.ts +158 -0
- package/src/canvas/headless/table-layout.ts +309 -0
- package/src/canvas/index.ts +35 -0
- package/src/canvas/lod/lod-mode.svelte.ts +30 -0
- package/src/canvas/lod/lod-switch.svelte +140 -0
- package/src/canvas/lod/render-all.svelte.ts +52 -0
- package/src/canvas/ops/arrange.ts +108 -0
- package/src/canvas/ops/ops.test.ts +98 -0
- package/src/canvas/ops/ops.ts +347 -0
- package/src/canvas/pen/PenField.svelte +128 -0
- package/src/canvas/pen/PenField.test.ts +87 -0
- package/src/canvas/pen/PenOverlay.svelte +172 -0
- package/src/canvas/pen/ShapeNode.svelte +64 -0
- package/src/canvas/pen/TextNode.svelte +97 -0
- package/src/canvas/pen/colors.ts +28 -0
- package/src/canvas/pen/eraser.ts +46 -0
- package/src/canvas/pen/geometry.ts +148 -0
- package/src/canvas/pen/host-field.test.svelte +13 -0
- package/src/canvas/pen/index.ts +40 -0
- package/src/canvas/pen/ops.ts +16 -0
- package/src/canvas/pen/pen-session.ts +177 -0
- package/src/canvas/pen/pen.css +149 -0
- package/src/canvas/pen/plugin.ts +139 -0
- package/src/canvas/pen/shapes.ts +104 -0
- package/src/canvas/pen/stroke-path.ts +54 -0
- package/src/canvas/pen/types.ts +96 -0
- package/src/canvas/pen/ui.ts +26 -0
- package/src/canvas/plugin.test.ts +45 -0
- package/src/canvas/plugin.ts +159 -0
- package/src/canvas/screen/GlyphIcon.svelte +25 -0
- package/src/canvas/screen/PartView.svelte +176 -0
- package/src/canvas/screen/ScreenBody.svelte +142 -0
- package/src/canvas/screen/ScreenCard.svelte +32 -0
- package/src/canvas/screen/glyphs/button.svg +1 -0
- package/src/canvas/screen/glyphs/close.svg +1 -0
- package/src/canvas/screen/glyphs/down.svg +1 -0
- package/src/canvas/screen/glyphs/header.svg +1 -0
- package/src/canvas/screen/glyphs/hills.svg +1 -0
- package/src/canvas/screen/glyphs/image.svg +1 -0
- package/src/canvas/screen/glyphs/input.svg +1 -0
- package/src/canvas/screen/glyphs/list.svg +1 -0
- package/src/canvas/screen/glyphs/modal.svg +1 -0
- package/src/canvas/screen/glyphs/plus.svg +1 -0
- package/src/canvas/screen/glyphs/up.svg +1 -0
- package/src/canvas/screen/glyphs.ts +40 -0
- package/src/canvas/screen/labels.ts +41 -0
- package/src/canvas/screen/parts.ts +164 -0
- package/src/canvas/screen/plugin.ts +67 -0
- package/src/canvas/screen/screen.css +593 -0
- package/src/canvas/screen/types.ts +47 -0
- package/src/canvas/screen/ui.ts +13 -0
- package/src/canvas/test-utils.ts +18 -0
- package/src/canvas/types.ts +53 -0
- package/src/canvas/ui/CanvasToolbar.svelte +169 -0
- package/src/canvas/ui/FrameLayer.svelte +116 -0
- package/src/canvas/ui/PenLayer.svelte +39 -0
- package/src/canvas/ui/StylePanel.svelte +268 -0
- package/src/canvas/ui/canvas-grid.svelte +156 -0
- package/src/canvas/ui/canvas-ui.css +350 -0
- package/src/canvas/ui/forward-wheel.ts +29 -0
- package/src/canvas/ui/icons.ts +124 -0
- package/src/canvas/ui/place-panel.ts +80 -0
- package/src/canvas/ui/shortcut-tip.test.ts +16 -0
- package/src/canvas/ui/shortcut-tip.ts +17 -0
- package/src/canvas/ui/tools.ts +146 -0
- package/src/charts/README.md +104 -0
- package/src/charts/ambient.d.ts +4 -0
- package/src/charts/animated-value.css +7 -0
- package/src/charts/animated-value.svelte +110 -0
- package/src/charts/area-chart.css +29 -0
- package/src/charts/area-chart.svelte +204 -0
- package/src/charts/bar-chart.css +119 -0
- package/src/charts/bar-chart.svelte +275 -0
- package/src/charts/charts.css +201 -0
- package/src/charts/crosshair.svelte +35 -0
- package/src/charts/dashboard/chart.ts +5 -0
- package/src/charts/dashboard/dashboard-empty.svelte +55 -0
- package/src/charts/dashboard/dashboard-section.svelte +58 -0
- package/src/charts/dashboard/data-panel.svelte +81 -0
- package/src/charts/dashboard/data-sort-head.svelte +102 -0
- package/src/charts/dashboard/data-table.svelte +278 -0
- package/src/charts/dashboard/data-table.ts +26 -0
- package/src/charts/dashboard/index.ts +25 -0
- package/src/charts/dashboard/panel-grid.svelte +43 -0
- package/src/charts/dashboard/period-filter.svelte +53 -0
- package/src/charts/dashboard/rating-chip.svelte +35 -0
- package/src/charts/dashboard/stat-band.svelte +47 -0
- package/src/charts/dashboard/stat-tile.svelte +176 -0
- package/src/charts/dashboard/windows.ts +8 -0
- package/src/charts/donut-chart.css +56 -0
- package/src/charts/donut-chart.svelte +158 -0
- package/src/charts/edge-fade.svelte +43 -0
- package/src/charts/edge-fade.ts +16 -0
- package/src/charts/figure.css +100 -0
- package/src/charts/figure.svelte +122 -0
- package/src/charts/gauge-chart.css +94 -0
- package/src/charts/gauge-chart.svelte +302 -0
- package/src/charts/hover-band.test.ts +30 -0
- package/src/charts/hover-band.ts +21 -0
- package/src/charts/hover-focus.svelte +85 -0
- package/src/charts/index.ts +31 -0
- package/src/charts/legend.css +136 -0
- package/src/charts/legend.svelte +112 -0
- package/src/charts/line-chart.css +26 -0
- package/src/charts/line-chart.svelte +256 -0
- package/src/charts/motion.ts +19 -0
- package/src/charts/number-chart.css +179 -0
- package/src/charts/number-chart.svelte +187 -0
- package/src/charts/primitives/chart-container.svelte +57 -0
- package/src/charts/primitives/chart-style.svelte +36 -0
- package/src/charts/primitives/chart-tooltip.svelte +161 -0
- package/src/charts/primitives/chart-utils.ts +54 -0
- package/src/charts/primitives/index.ts +11 -0
- package/src/charts/reference-line.css +18 -0
- package/src/charts/reference-line.svelte +31 -0
- package/src/charts/reveal.svelte +61 -0
- package/src/charts/ring-chart.css +104 -0
- package/src/charts/ring-chart.svelte +166 -0
- package/src/charts/sparkline.css +45 -0
- package/src/charts/sparkline.svelte +141 -0
- package/src/charts/stat-card.css +105 -0
- package/src/charts/stat-card.svelte +267 -0
- package/src/charts/time-series-chart.css +28 -0
- package/src/charts/time-series-chart.svelte +179 -0
- package/src/charts/trend-pill.css +38 -0
- package/src/charts/trend-pill.svelte +48 -0
- package/src/components/copy/copy-button.svelte +1 -1
- package/src/components/docs/doc-page.svelte +1 -1
- package/src/components/docs/on-this-page.svelte +2 -2
- package/src/components/list-page/empty-state.svelte +1 -1
- package/src/components/list-page/filter-popover.svelte +1 -1
- package/src/components/list-page/section-label.svelte +1 -1
- package/src/components/segmented/segment.svelte +4 -4
- package/src/components/theme/theme-provider.svelte +6 -4
- package/src/components/toolbar/index.ts +5 -0
- package/src/components/toolbar/toolbar.svelte +168 -0
- package/src/components/toolbar/toolbar.test.ts +66 -0
- package/src/editor/README.md +58 -0
- package/src/editor/ambient.d.ts +1 -0
- package/src/editor/block-id.ts +77 -0
- package/src/editor/block-ops.test.ts +237 -0
- package/src/editor/block-ops.ts +157 -0
- package/src/editor/content.css +418 -0
- package/src/editor/editor-toolbar.svelte +303 -0
- package/src/editor/editor.svelte +462 -0
- package/src/editor/extensions.ts +145 -0
- package/src/editor/image-toolbar.svelte +123 -0
- package/src/editor/index.ts +17 -0
- package/src/editor/inline-editor.svelte +261 -0
- package/src/editor/markdown-escaping.test.ts +158 -0
- package/src/editor/markdown-marks.test.ts +89 -0
- package/src/editor/markdown-test-helpers.ts +13 -0
- package/src/editor/markdown-youtube.test.ts +93 -0
- package/src/editor/markdown.test.ts +250 -0
- package/src/editor/markdown.ts +511 -0
- package/src/editor/renderer.svelte +92 -0
- package/src/editor/serializer.test.ts +133 -0
- package/src/editor/serializer.ts +370 -0
- package/src/editor/slash-items.ts +115 -0
- package/src/editor/slash-menu.svelte +159 -0
- package/src/editor/youtube-url.ts +35 -0
- package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +13 -13
- package/src/lib/result.ts +19 -0
- package/src/onboarding/README.md +120 -0
- package/src/onboarding/define-tours.test.ts +50 -0
- package/src/onboarding/define-tours.ts +31 -0
- package/src/onboarding/demo.svelte +86 -0
- package/src/onboarding/index.ts +12 -0
- package/src/onboarding/onboarding-provider.svelte +120 -0
- package/src/onboarding/onboarding.svelte.ts +24 -0
- package/src/onboarding/pick.test.ts +79 -0
- package/src/onboarding/pick.ts +36 -0
- package/src/onboarding/stores.test.ts +103 -0
- package/src/onboarding/stores.ts +58 -0
- package/src/onboarding/tour-card.svelte +70 -0
- package/src/onboarding/tour-runner.svelte +197 -0
- package/src/onboarding/types.ts +34 -0
- package/src/onboarding/wait.ts +29 -0
- package/src/shadcn/command/command-input.svelte +1 -1
- package/src/slides/Controls.svelte +138 -0
- package/src/slides/Deck.svelte +271 -0
- package/src/slides/Fragment.svelte +71 -0
- package/src/slides/Overview.svelte +113 -0
- package/src/slides/Presenter.svelte +292 -0
- package/src/slides/README.md +89 -0
- package/src/slides/Slide.svelte +179 -0
- package/src/slides/SlideList.svelte +19 -0
- package/src/slides/ambient.d.ts +1 -0
- package/src/slides/bridges.ts +69 -0
- package/src/slides/deck-controller.svelte.ts +292 -0
- package/src/slides/demo-slides.svelte +358 -0
- package/src/slides/demo.svelte +176 -0
- package/src/slides/export/capture.ts +113 -0
- package/src/slides/export/ffmpeg.ts +120 -0
- package/src/slides/export/index.ts +9 -0
- package/src/slides/export/launch.ts +10 -0
- package/src/slides/export/pdf.ts +152 -0
- package/src/slides/export/types.ts +48 -0
- package/src/slides/index.ts +19 -0
- package/src/slides/labels.ts +48 -0
- package/src/slides/layout.ts +51 -0
- package/src/slides/model.ts +47 -0
- package/src/slides/navigation.ts +100 -0
- package/src/slides/theme.css +205 -0
- package/src/slides/types.ts +86 -0
- package/src/tasks/README.md +312 -0
- package/src/tasks/ambient.d.ts +3 -0
- package/src/tasks/board-order.ts +137 -0
- package/src/tasks/dates.ts +31 -0
- package/src/tasks/define-statuses.ts +32 -0
- package/src/tasks/demo.svelte +389 -0
- package/src/tasks/detail/detail-demo.svelte +186 -0
- package/src/tasks/detail/detail-types.ts +54 -0
- package/src/tasks/detail/task-chip.svelte +28 -0
- package/src/tasks/detail/task-detail.svelte +315 -0
- package/src/tasks/detail/task-property.svelte +17 -0
- package/src/tasks/detail/task-thread.svelte +258 -0
- package/src/tasks/gantt/gantt-bar.svelte +243 -0
- package/src/tasks/gantt/gantt-grid.svelte +94 -0
- package/src/tasks/gantt/gantt-group-row.svelte +55 -0
- package/src/tasks/gantt/gantt-header.svelte +71 -0
- package/src/tasks/gantt/gantt-task-row.svelte +186 -0
- package/src/tasks/gantt/gantt.css +22 -0
- package/src/tasks/gantt/gantt.test.ts +77 -0
- package/src/tasks/gantt/logic.test.ts +163 -0
- package/src/tasks/gantt/logic.ts +248 -0
- package/src/tasks/inbox/inbox-card.svelte +283 -0
- package/src/tasks/inbox/inbox-draft.svelte +84 -0
- package/src/tasks/inbox/inbox-logic.ts +55 -0
- package/src/tasks/inbox/inbox-statuses.ts +48 -0
- package/src/tasks/inbox/inbox-trace.svelte +45 -0
- package/src/tasks/inbox/inbox-types.ts +108 -0
- package/src/tasks/inbox/inbox.svelte +203 -0
- package/src/tasks/inbox/index.ts +23 -0
- package/src/tasks/index.ts +85 -0
- package/src/tasks/kanban-board.svelte +561 -0
- package/src/tasks/kanban-column.svelte +117 -0
- package/src/tasks/kanban-drag.ts +38 -0
- package/src/tasks/kanban-types.ts +65 -0
- package/src/tasks/presets/sales.ts +16 -0
- package/src/tasks/record/demo-data.ts +286 -0
- package/src/tasks/record/field-section.svelte +53 -0
- package/src/tasks/record/fields.ts +142 -0
- package/src/tasks/record/format.ts +87 -0
- package/src/tasks/record/gutter.ts +2 -0
- package/src/tasks/record/index.ts +54 -0
- package/src/tasks/record/info-list.svelte +316 -0
- package/src/tasks/record/kinds.ts +42 -0
- package/src/tasks/record/logic.ts +324 -0
- package/src/tasks/record/next-up.svelte +70 -0
- package/src/tasks/record/project-list.svelte +133 -0
- package/src/tasks/record/record-demo.svelte +324 -0
- package/src/tasks/record/record-header.svelte +70 -0
- package/src/tasks/record/record-shell.svelte +138 -0
- package/src/tasks/record/record-stats.svelte +48 -0
- package/src/tasks/record/record-timeline.svelte +231 -0
- package/src/tasks/record/record.test.ts +350 -0
- package/src/tasks/record/steps-rail.svelte +474 -0
- package/src/tasks/record/types.ts +280 -0
- package/src/tasks/record/where-we-are.svelte +121 -0
- package/src/tasks/reorder.ts +19 -0
- package/src/tasks/side-panel-types.ts +16 -0
- package/src/tasks/side-panel.svelte +193 -0
- package/src/tasks/status-badge.svelte +63 -0
- package/src/tasks/status-dot.svelte +228 -0
- package/src/tasks/status-icon.svelte +30 -0
- package/src/tasks/status-types.ts +40 -0
- package/src/tasks/task-gantt.svelte +230 -0
- package/src/tasks/task-list.svelte +470 -0
- package/src/tasks/task-types.ts +33 -0
- package/src/tasks/time/duration.ts +69 -0
- package/src/tasks/time/time-chip.svelte +62 -0
- package/src/tasks/time/time-dot.svelte +58 -0
- package/src/tasks/time/time-ring.svelte +74 -0
- package/src/tasks/time/time-tracker.svelte +565 -0
- package/src/tasks/time/time-types.ts +74 -0
- package/src/tasks/use-kanban-dnd.svelte.ts +173 -0
- package/src/tokens/base.css +5 -5
- package/src/tokens/palette.css +115 -120
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Every string the package renders. Pass a partial `labels` prop to translate. */
|
|
2
|
+
export type DeckLabels = {
|
|
3
|
+
deck: string;
|
|
4
|
+
deckRole: string;
|
|
5
|
+
slideRole: string;
|
|
6
|
+
previous: string;
|
|
7
|
+
next: string;
|
|
8
|
+
fullscreen: string;
|
|
9
|
+
overview: string;
|
|
10
|
+
presenter: string;
|
|
11
|
+
progress: string;
|
|
12
|
+
slide: (n: number, of: number) => string;
|
|
13
|
+
upcoming: string;
|
|
14
|
+
current: string;
|
|
15
|
+
notes: string;
|
|
16
|
+
noNotes: string;
|
|
17
|
+
endOfDeck: string;
|
|
18
|
+
timer: string;
|
|
19
|
+
startTimer: string;
|
|
20
|
+
pauseTimer: string;
|
|
21
|
+
resetTimer: string;
|
|
22
|
+
unknownType: (type: string) => string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const defaultLabels: DeckLabels = {
|
|
26
|
+
deck: 'Slide deck',
|
|
27
|
+
deckRole: 'presentation',
|
|
28
|
+
slideRole: 'slide',
|
|
29
|
+
previous: 'Previous slide',
|
|
30
|
+
next: 'Next slide',
|
|
31
|
+
fullscreen: 'Toggle fullscreen',
|
|
32
|
+
overview: 'Slide overview',
|
|
33
|
+
presenter: 'Open presenter view',
|
|
34
|
+
progress: 'Deck progress',
|
|
35
|
+
slide: (n, of) => `Slide ${n} of ${of}`,
|
|
36
|
+
upcoming: 'Next',
|
|
37
|
+
current: 'Now',
|
|
38
|
+
notes: 'Notes',
|
|
39
|
+
noNotes: 'No notes for this slide.',
|
|
40
|
+
endOfDeck: 'End of deck.',
|
|
41
|
+
timer: 'Elapsed time',
|
|
42
|
+
startTimer: 'Start timer',
|
|
43
|
+
pauseTimer: 'Pause timer',
|
|
44
|
+
resetTimer: 'Reset timer',
|
|
45
|
+
unknownType: (type) => `Unknown slide type: ${type}`,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const resolveLabels = (labels?: Partial<DeckLabels>): DeckLabels => ({ ...defaultLabels, ...labels });
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* Where a slide sits inside the stage: centred to fit, or in the overview grid. */
|
|
2
|
+
|
|
3
|
+
import type { Canvas } from './types.js';
|
|
4
|
+
|
|
5
|
+
export type Size = { w: number; h: number };
|
|
6
|
+
|
|
7
|
+
/** A slide's place: its top-left corner in stage px and its scale. */
|
|
8
|
+
export type Box = { x: number; y: number; scale: number };
|
|
9
|
+
|
|
10
|
+
export type Grid = { cols: number; boxes: Box[] };
|
|
11
|
+
|
|
12
|
+
export function fitBox(view: Size, canvas: Canvas): Box {
|
|
13
|
+
const scale = Math.max(0, Math.min(view.w / canvas.w, view.h / canvas.h));
|
|
14
|
+
return { x: (view.w - canvas.w * scale) / 2, y: (view.h - canvas.h * scale) / 2, scale };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** The scale at which `cols` columns of `count` canvases fit the view. */
|
|
18
|
+
function scaleFor(cols: number, count: number, view: Size, canvas: Canvas, pad: number, gap: number): number {
|
|
19
|
+
const rows = Math.ceil(count / cols);
|
|
20
|
+
const byWidth = (view.w - 2 * pad - (cols - 1) * gap) / cols / canvas.w;
|
|
21
|
+
const byHeight = (view.h - 2 * pad - (rows - 1) * gap) / rows / canvas.h;
|
|
22
|
+
return Math.min(byWidth, byHeight);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Lays `count` canvases in the roomiest grid that shows them all, centred. */
|
|
26
|
+
export function gridBoxes(view: Size, canvas: Canvas, count: number): Grid {
|
|
27
|
+
if (count === 0 || view.w <= 0 || view.h <= 0) return { cols: 1, boxes: [] };
|
|
28
|
+
const pad = Math.min(56, Math.max(16, view.w * 0.04));
|
|
29
|
+
/* The gap holds the slide number that hangs below each cell. */
|
|
30
|
+
const gap = Math.max(26, pad * 0.6);
|
|
31
|
+
|
|
32
|
+
let cols = 1;
|
|
33
|
+
let scale = scaleFor(1, count, view, canvas, pad, gap);
|
|
34
|
+
for (let c = 2; c <= count; c++) {
|
|
35
|
+
const candidate = scaleFor(c, count, view, canvas, pad, gap);
|
|
36
|
+
if (candidate > scale) [cols, scale] = [c, candidate];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const cellW = canvas.w * scale;
|
|
40
|
+
const cellH = canvas.h * scale;
|
|
41
|
+
const rows = Math.ceil(count / cols);
|
|
42
|
+
const left = (view.w - (cols * cellW + (cols - 1) * gap)) / 2;
|
|
43
|
+
const top = (view.h - (rows * cellH + (rows - 1) * gap)) / 2;
|
|
44
|
+
|
|
45
|
+
const boxes = Array.from({ length: count }, (_, i) => ({
|
|
46
|
+
x: left + (i % cols) * (cellW + gap),
|
|
47
|
+
y: top + Math.floor(i / cols) * (cellH + gap),
|
|
48
|
+
scale,
|
|
49
|
+
}));
|
|
50
|
+
return { cols, boxes };
|
|
51
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* Data-driven decks: a deck is JSON, and a registry says how each slide type draws itself. */
|
|
2
|
+
|
|
3
|
+
import type { Component } from 'svelte';
|
|
4
|
+
import type { Canvas, DeckTheme } from './types.js';
|
|
5
|
+
|
|
6
|
+
export type SlideInstance<Content = unknown> = {
|
|
7
|
+
id: string;
|
|
8
|
+
type: string;
|
|
9
|
+
content: Content;
|
|
10
|
+
notes?: string;
|
|
11
|
+
hidden?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type DeckData<Content = unknown> = {
|
|
15
|
+
id: string;
|
|
16
|
+
title: string;
|
|
17
|
+
locale?: string;
|
|
18
|
+
canvas: Canvas;
|
|
19
|
+
theme?: DeckTheme;
|
|
20
|
+
slides: SlideInstance<Content>[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/** What a layout component receives. */
|
|
24
|
+
export type SlideLayoutProps<Content> = { content: Content; slide: SlideInstance<Content> };
|
|
25
|
+
|
|
26
|
+
export type SlideType<Content = any> = {
|
|
27
|
+
type: string;
|
|
28
|
+
/** Human name, used as the slide's accessible label and in editors. */
|
|
29
|
+
label: string;
|
|
30
|
+
layout: Component<SlideLayoutProps<Content>>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type SlideRegistry = Readonly<Record<string, SlideType>>;
|
|
34
|
+
|
|
35
|
+
/** Identity function that fixes `Content` from the layout. */
|
|
36
|
+
export const defineSlideType = <Content>(definition: SlideType<Content>): SlideType<Content> => definition;
|
|
37
|
+
|
|
38
|
+
/** Keys the types by their `type`. Two with the same name is a mistake worth failing on. */
|
|
39
|
+
export function defineRegistry(types: readonly SlideType[]): SlideRegistry {
|
|
40
|
+
const registry: Record<string, SlideType> = {};
|
|
41
|
+
for (const slide of types) {
|
|
42
|
+
if (slide.type in registry) throw new Error(`Slide type "${slide.type}" is registered twice.`);
|
|
43
|
+
registry[slide.type] = slide;
|
|
44
|
+
}
|
|
45
|
+
return registry;
|
|
46
|
+
}
|
|
47
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Paging rules as pure functions, so the controller stays a thin reactive shell. */
|
|
2
|
+
|
|
3
|
+
export type Position = { index: number; step: number };
|
|
4
|
+
|
|
5
|
+
/** What paging needs to know about a slide. `steps` is its highest fragment step. */
|
|
6
|
+
export type SlideState = { steps: number; hidden: boolean };
|
|
7
|
+
|
|
8
|
+
export type KeyAction =
|
|
9
|
+
| 'next'
|
|
10
|
+
| 'prev'
|
|
11
|
+
| 'up'
|
|
12
|
+
| 'down'
|
|
13
|
+
| 'first'
|
|
14
|
+
| 'last'
|
|
15
|
+
| 'select'
|
|
16
|
+
| 'overview'
|
|
17
|
+
| 'close'
|
|
18
|
+
| 'fullscreen'
|
|
19
|
+
| 'presenter';
|
|
20
|
+
|
|
21
|
+
export const visibleIndexes = (slides: readonly SlideState[]): number[] =>
|
|
22
|
+
slides.flatMap((slide, index) => (slide.hidden ? [] : [index]));
|
|
23
|
+
|
|
24
|
+
const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));
|
|
25
|
+
|
|
26
|
+
/** Snaps a position onto a visible slide and a real step. Empty decks stay at 0, 0. */
|
|
27
|
+
export function settle(slides: readonly SlideState[], position: Position): Position {
|
|
28
|
+
const visible = visibleIndexes(slides);
|
|
29
|
+
if (visible.length === 0) return { index: 0, step: 0 };
|
|
30
|
+
const index = visible.find((i) => i >= position.index) ?? visible[visible.length - 1];
|
|
31
|
+
return { index, step: clamp(position.step, 0, slides[index].steps) };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The position after one forward press, or null at the end of a deck that doesn't loop. */
|
|
35
|
+
export function nextPosition(slides: readonly SlideState[], from: Position, loop = false): Position | null {
|
|
36
|
+
const visible = visibleIndexes(slides);
|
|
37
|
+
if (visible.length === 0) return null;
|
|
38
|
+
if (from.step < slides[from.index].steps) return { index: from.index, step: from.step + 1 };
|
|
39
|
+
const next = visible.find((i) => i > from.index);
|
|
40
|
+
if (next !== undefined) return { index: next, step: 0 };
|
|
41
|
+
return loop ? { index: visible[0], step: 0 } : null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The position after one back press. Landing on an earlier slide shows it fully revealed. */
|
|
45
|
+
export function prevPosition(slides: readonly SlideState[], from: Position, loop = false): Position | null {
|
|
46
|
+
const visible = visibleIndexes(slides);
|
|
47
|
+
if (visible.length === 0) return null;
|
|
48
|
+
if (from.step > 0) return { index: from.index, step: from.step - 1 };
|
|
49
|
+
const before = visible.filter((i) => i < from.index);
|
|
50
|
+
const index = before.length ? before[before.length - 1] : loop ? visible[visible.length - 1] : undefined;
|
|
51
|
+
return index === undefined ? null : { index, step: slides[index].steps };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Where slide `index` sits among the visible ones, 1 based, for "3 of 12". */
|
|
55
|
+
export function ordinalOf(slides: readonly SlideState[], index: number): { n: number; of: number } {
|
|
56
|
+
const visible = visibleIndexes(slides);
|
|
57
|
+
return { n: Math.max(0, visible.indexOf(index)) + 1, of: visible.length };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** How far through the deck a position is, 0 to 1. A slide's fragments split its own share. */
|
|
61
|
+
export function progressOf(slides: readonly SlideState[], position: Position): number {
|
|
62
|
+
const visible = visibleIndexes(slides);
|
|
63
|
+
if (visible.length === 0) return 0;
|
|
64
|
+
const at = Math.max(0, visible.indexOf(position.index));
|
|
65
|
+
const steps = slides[position.index]?.steps ?? 0;
|
|
66
|
+
const share = steps > 0 ? (position.step + 1) / (steps + 1) : 1;
|
|
67
|
+
return (at + share) / visible.length;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Reads `?s=` as a zero based index. Anything that isn't a whole number in range is null. */
|
|
71
|
+
export function parseSlideParam(raw: string | null | undefined, total: number): number | null {
|
|
72
|
+
if (!raw || !/^\d+$/.test(raw)) return null;
|
|
73
|
+
const index = Number(raw) - 1;
|
|
74
|
+
return index >= 0 && index < total ? index : null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const KEYS: Record<string, KeyAction> = {
|
|
78
|
+
ArrowRight: 'next',
|
|
79
|
+
PageDown: 'next',
|
|
80
|
+
ArrowLeft: 'prev',
|
|
81
|
+
PageUp: 'prev',
|
|
82
|
+
ArrowUp: 'up',
|
|
83
|
+
ArrowDown: 'down',
|
|
84
|
+
Home: 'first',
|
|
85
|
+
End: 'last',
|
|
86
|
+
Enter: 'select',
|
|
87
|
+
Escape: 'close',
|
|
88
|
+
o: 'overview',
|
|
89
|
+
O: 'overview',
|
|
90
|
+
f: 'fullscreen',
|
|
91
|
+
F: 'fullscreen',
|
|
92
|
+
p: 'presenter',
|
|
93
|
+
P: 'presenter',
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/** Maps a key to what the deck does with it. Space moves forward, Shift+Space back. */
|
|
97
|
+
export function keyAction(key: string, shift = false): KeyAction | null {
|
|
98
|
+
if (key === ' ') return shift ? 'prev' : 'next';
|
|
99
|
+
return KEYS[key] ?? null;
|
|
100
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Everything global to a deck: tokens, authored type, the enter keyframes and print.
|
|
3
|
+
* Components keep their own box mechanics in scoped styles. Sizes are design px,
|
|
4
|
+
* because the whole canvas scales, so a 28px heading is 28px on a 960px canvas at any zoom.
|
|
5
|
+
* Colours are flat hex: Chromium's PDF pipeline shifts oklch.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.deck,
|
|
9
|
+
.deck-surface {
|
|
10
|
+
color-scheme: dark;
|
|
11
|
+
|
|
12
|
+
--deck-bg: light-dark(#f2f1ec, #0e1014);
|
|
13
|
+
--deck-fg: light-dark(#15171b, #f3f1ea);
|
|
14
|
+
--deck-accent: light-dark(#3e6b00, #c8f15a);
|
|
15
|
+
--deck-on-accent: light-dark(#f6f6f0, #0e1014);
|
|
16
|
+
--deck-muted: color-mix(in srgb, var(--deck-fg) 66%, transparent);
|
|
17
|
+
--deck-line: color-mix(in srgb, var(--deck-fg) 14%, transparent);
|
|
18
|
+
--deck-surface: color-mix(in srgb, var(--deck-fg) 6%, transparent);
|
|
19
|
+
--deck-letterbox: color-mix(in srgb, var(--deck-bg) 86%, var(--deck-fg));
|
|
20
|
+
|
|
21
|
+
--deck-font: ui-sans-serif, system-ui, sans-serif;
|
|
22
|
+
--deck-font-display: var(--deck-font);
|
|
23
|
+
|
|
24
|
+
--deck-pad: 64px;
|
|
25
|
+
--deck-text-display: 76px;
|
|
26
|
+
--deck-text-title: 46px;
|
|
27
|
+
--deck-text-heading: 28px;
|
|
28
|
+
--deck-text-lead: 22px;
|
|
29
|
+
--deck-text-body: 17px;
|
|
30
|
+
--deck-text-caption: 13px;
|
|
31
|
+
|
|
32
|
+
--deck-t-slide: var(--duration-fast, 250ms);
|
|
33
|
+
--deck-t-morph: var(--duration-slow, 400ms);
|
|
34
|
+
--deck-t-quick: var(--duration-quick, 150ms);
|
|
35
|
+
--deck-stagger: var(--duration-stagger, 40ms);
|
|
36
|
+
--deck-ease: var(--ease-smooth-out, cubic-bezier(0.22, 1, 0.36, 1));
|
|
37
|
+
--deck-shift: var(--distance-medium, 12px);
|
|
38
|
+
}
|
|
39
|
+
.deck--paper {
|
|
40
|
+
color-scheme: light;
|
|
41
|
+
}
|
|
42
|
+
.deck--auto {
|
|
43
|
+
color-scheme: light dark;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Authored type. Slides use these classes. */
|
|
47
|
+
.deck .deck-display,
|
|
48
|
+
.deck .deck-title,
|
|
49
|
+
.deck .deck-heading {
|
|
50
|
+
margin: 0;
|
|
51
|
+
font-family: var(--deck-font-display);
|
|
52
|
+
color: var(--deck-fg);
|
|
53
|
+
text-wrap: balance;
|
|
54
|
+
}
|
|
55
|
+
.deck .deck-display {
|
|
56
|
+
font-size: var(--deck-text-display);
|
|
57
|
+
font-weight: 800;
|
|
58
|
+
line-height: 1;
|
|
59
|
+
letter-spacing: -0.03em;
|
|
60
|
+
}
|
|
61
|
+
.deck .deck-title {
|
|
62
|
+
font-size: var(--deck-text-title);
|
|
63
|
+
font-weight: 700;
|
|
64
|
+
line-height: 1.04;
|
|
65
|
+
letter-spacing: -0.03em;
|
|
66
|
+
}
|
|
67
|
+
.deck .deck-heading {
|
|
68
|
+
font-size: var(--deck-text-heading);
|
|
69
|
+
font-weight: 650;
|
|
70
|
+
line-height: 1.15;
|
|
71
|
+
letter-spacing: -0.02em;
|
|
72
|
+
}
|
|
73
|
+
.deck .deck-lead,
|
|
74
|
+
.deck .deck-body,
|
|
75
|
+
.deck .deck-caption {
|
|
76
|
+
margin: 0;
|
|
77
|
+
color: var(--deck-muted);
|
|
78
|
+
text-wrap: pretty;
|
|
79
|
+
}
|
|
80
|
+
.deck .deck-lead {
|
|
81
|
+
font-size: var(--deck-text-lead);
|
|
82
|
+
line-height: 1.4;
|
|
83
|
+
}
|
|
84
|
+
.deck .deck-body {
|
|
85
|
+
font-size: var(--deck-text-body);
|
|
86
|
+
line-height: 1.5;
|
|
87
|
+
}
|
|
88
|
+
.deck .deck-caption {
|
|
89
|
+
font-size: var(--deck-text-caption);
|
|
90
|
+
line-height: 1.4;
|
|
91
|
+
}
|
|
92
|
+
.deck .deck-label {
|
|
93
|
+
margin: 0;
|
|
94
|
+
font-size: var(--deck-text-caption);
|
|
95
|
+
font-weight: 600;
|
|
96
|
+
letter-spacing: 0.01em;
|
|
97
|
+
color: var(--deck-accent);
|
|
98
|
+
}
|
|
99
|
+
.deck .deck-accent {
|
|
100
|
+
color: var(--deck-accent);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* How a slide enters. The slide it replaces stays put underneath, so no frame shows the page behind. */
|
|
104
|
+
@keyframes deck-fade {
|
|
105
|
+
from {
|
|
106
|
+
opacity: 0;
|
|
107
|
+
transform: translateY(var(--deck-shift));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
@keyframes deck-slide {
|
|
111
|
+
from {
|
|
112
|
+
opacity: 0;
|
|
113
|
+
transform: translateX(calc(var(--deck-dir, 1) * 48px));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
@keyframes deck-zoom {
|
|
117
|
+
from {
|
|
118
|
+
opacity: 0;
|
|
119
|
+
transform: scale(var(--scale-large, 0.96));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
.deck[data-transition='fade'] .slide[data-active='true'] .slide__surface {
|
|
123
|
+
animation-name: deck-fade;
|
|
124
|
+
}
|
|
125
|
+
.deck[data-transition='slide'] .slide[data-active='true'] .slide__surface {
|
|
126
|
+
animation-name: deck-slide;
|
|
127
|
+
}
|
|
128
|
+
.deck[data-transition='zoom'] .slide[data-active='true'] .slide__surface {
|
|
129
|
+
animation-name: deck-zoom;
|
|
130
|
+
}
|
|
131
|
+
.deck[data-morphing] .slide__surface {
|
|
132
|
+
animation: none !important;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* A morph runs on the whole page, so it gets the deck's timing while it plays. */
|
|
136
|
+
html[data-deck-vt] ::view-transition-group(*) {
|
|
137
|
+
animation-duration: var(--duration-slow, 400ms);
|
|
138
|
+
animation-timing-function: var(--ease-smooth-out, cubic-bezier(0.22, 1, 0.36, 1));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@media (prefers-reduced-motion: reduce) {
|
|
142
|
+
.deck .slide__surface {
|
|
143
|
+
animation: none !important;
|
|
144
|
+
}
|
|
145
|
+
.deck .slide {
|
|
146
|
+
transition-duration: 0s !important;
|
|
147
|
+
transition-delay: 0s !important;
|
|
148
|
+
}
|
|
149
|
+
html[data-deck-vt] ::view-transition-group(*) {
|
|
150
|
+
animation-duration: 0s;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* Print: one canvas per page, every reveal shown, no chrome. The @page size comes from the Deck. */
|
|
155
|
+
@media print {
|
|
156
|
+
.deck {
|
|
157
|
+
position: static !important;
|
|
158
|
+
display: block !important;
|
|
159
|
+
width: auto !important;
|
|
160
|
+
height: auto !important;
|
|
161
|
+
aspect-ratio: auto !important;
|
|
162
|
+
overflow: visible !important;
|
|
163
|
+
background: none !important;
|
|
164
|
+
-webkit-print-color-adjust: exact;
|
|
165
|
+
print-color-adjust: exact;
|
|
166
|
+
}
|
|
167
|
+
.deck .deck__stage {
|
|
168
|
+
position: static !important;
|
|
169
|
+
display: block !important;
|
|
170
|
+
height: auto !important;
|
|
171
|
+
overflow: visible !important;
|
|
172
|
+
background: none !important;
|
|
173
|
+
}
|
|
174
|
+
.deck .slide {
|
|
175
|
+
position: relative !important;
|
|
176
|
+
display: block !important;
|
|
177
|
+
visibility: visible !important;
|
|
178
|
+
width: var(--slide-w) !important;
|
|
179
|
+
height: var(--slide-h) !important;
|
|
180
|
+
overflow: hidden !important;
|
|
181
|
+
transform: none !important;
|
|
182
|
+
transition: none !important;
|
|
183
|
+
break-inside: avoid;
|
|
184
|
+
/* Chrome rounds the page a fraction of a px short of the canvas, which would add a blank last page. */
|
|
185
|
+
margin-bottom: -1px;
|
|
186
|
+
}
|
|
187
|
+
.deck .slide[hidden] {
|
|
188
|
+
display: none !important;
|
|
189
|
+
}
|
|
190
|
+
.deck .slide ~ .slide {
|
|
191
|
+
break-before: page;
|
|
192
|
+
}
|
|
193
|
+
.deck .slide__surface {
|
|
194
|
+
animation: none !important;
|
|
195
|
+
border-radius: 0 !important;
|
|
196
|
+
}
|
|
197
|
+
.deck .deck-fragment {
|
|
198
|
+
opacity: 1 !important;
|
|
199
|
+
transform: none !important;
|
|
200
|
+
transition: none !important;
|
|
201
|
+
}
|
|
202
|
+
.deck .deck__chrome {
|
|
203
|
+
display: none !important;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { DeckController } from './deck-controller.svelte.js';
|
|
3
|
+
import type { DeckLabels } from './labels.js';
|
|
4
|
+
import type { SlideInstance, SlideRegistry } from './model.js';
|
|
5
|
+
|
|
6
|
+
export const DECK_KEY = Symbol('heyramzi.deck');
|
|
7
|
+
export const SLIDE_KEY = Symbol('heyramzi.slide');
|
|
8
|
+
|
|
9
|
+
/** `ink` is the dark default, `paper` a light surface, `auto` follows the system. */
|
|
10
|
+
export type DeckTheme = 'ink' | 'paper' | 'auto';
|
|
11
|
+
|
|
12
|
+
/** How a slide enters. `morph` uses the View Transitions API and falls back to a cut. */
|
|
13
|
+
export type DeckTransition = 'fade' | 'slide' | 'zoom' | 'morph' | 'none';
|
|
14
|
+
|
|
15
|
+
/** The design size in px. Slides lay out inside it and the whole canvas scales to fit. */
|
|
16
|
+
export type Canvas = { w: number; h: number };
|
|
17
|
+
|
|
18
|
+
export const DEFAULT_CANVAS: Canvas = { w: 960, h: 540 };
|
|
19
|
+
|
|
20
|
+
/** Speaker notes: plain text, or a snippet for rich markup. */
|
|
21
|
+
export type SlideNotes = string | Snippet;
|
|
22
|
+
|
|
23
|
+
/** How a Slide lays out its own content. `bare` leaves the whole canvas to the author. */
|
|
24
|
+
export type SlideAlign = 'center' | 'start' | 'bare';
|
|
25
|
+
|
|
26
|
+
/** Where a deck keeps `?s=`. `write` replaces the default `history.replaceState`, so SvelteKit apps can use its own. */
|
|
27
|
+
export type UrlSync = { param?: string; write?: (url: URL) => void };
|
|
28
|
+
|
|
29
|
+
/** `origin` guards incoming messages and defaults to this page's origin. `'*'` accepts any. */
|
|
30
|
+
export type BridgeOptions = { origin?: string };
|
|
31
|
+
|
|
32
|
+
/** What a Fragment sees of the slide around it. */
|
|
33
|
+
export type SlideContext = {
|
|
34
|
+
shown: (step: number) => boolean;
|
|
35
|
+
join: (step: number) => { order: number; leave: () => void };
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Everything a Deck takes. */
|
|
39
|
+
export type DeckProps = {
|
|
40
|
+
/** Active slide, zero based, hidden slides counted. Bindable. */
|
|
41
|
+
index?: number;
|
|
42
|
+
/** Active fragment step on the active slide. Bindable. */
|
|
43
|
+
step?: number;
|
|
44
|
+
/** The controller, for apps that drive the deck from outside. Bindable, read only. */
|
|
45
|
+
controller?: DeckController;
|
|
46
|
+
/** Names the deck's channel and region. A `DeckData` spreads straight in. */
|
|
47
|
+
id?: string;
|
|
48
|
+
/** Accessible name for the deck region. */
|
|
49
|
+
title?: string;
|
|
50
|
+
/** Language of the deck, set as `lang`. */
|
|
51
|
+
locale?: string;
|
|
52
|
+
/** Design size in px. Slides lay out inside it and it scales to fit. */
|
|
53
|
+
canvas?: Canvas;
|
|
54
|
+
/** Colour surface. `ink` (default), `paper` or `auto`. */
|
|
55
|
+
theme?: DeckTheme;
|
|
56
|
+
/** How slides enter: `fade` (default), `slide`, `zoom`, `morph` or `none`. */
|
|
57
|
+
transition?: DeckTransition;
|
|
58
|
+
/** Data mode: render these instances through `registry` instead of `children`. */
|
|
59
|
+
slides?: SlideInstance[];
|
|
60
|
+
registry?: SlideRegistry;
|
|
61
|
+
/** Show the progress bar. */
|
|
62
|
+
progress?: boolean;
|
|
63
|
+
/** Show the previous, next, overview and fullscreen controls. */
|
|
64
|
+
controls?: boolean;
|
|
65
|
+
/** Wrap around at the ends. */
|
|
66
|
+
loop?: boolean;
|
|
67
|
+
/** Respond to keys. Turn off when a slide holds a form. */
|
|
68
|
+
keyboard?: boolean;
|
|
69
|
+
/** Stage fragments. Off shows everything at once, as a share view does. */
|
|
70
|
+
fragments?: boolean;
|
|
71
|
+
/** Keep `?s=` at the current slide. Pass an object to rename it or write the URL yourself. */
|
|
72
|
+
urlSync?: boolean | UrlSync;
|
|
73
|
+
/** Let a parent frame drive this deck over postMessage. */
|
|
74
|
+
bridge?: boolean | BridgeOptions;
|
|
75
|
+
/** Mirror this deck across windows of one origin under this name. */
|
|
76
|
+
sync?: string;
|
|
77
|
+
/** Where the presenter view lives. Adds a button and the `p` key. */
|
|
78
|
+
presenter?: string;
|
|
79
|
+
/** Translate or reword any string. */
|
|
80
|
+
labels?: Partial<DeckLabels>;
|
|
81
|
+
class?: string;
|
|
82
|
+
style?: string;
|
|
83
|
+
onchange?: (index: number, step: number) => void;
|
|
84
|
+
children?: Snippet;
|
|
85
|
+
};
|
|
86
|
+
|