@heyramzi/ui 2.1.0 → 2.2.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.
Files changed (312) hide show
  1. package/package.json +7 -8
  2. package/scripts/sync-shadcn.mjs +3 -4
  3. package/src/agents/agent-avatar.svelte +604 -575
  4. package/src/agents/agent-cast.svelte +179 -183
  5. package/src/agents/demo.svelte +125 -113
  6. package/src/agents/helpers.ts +23 -17
  7. package/src/agents/index.ts +4 -4
  8. package/src/agents/page-state.ts +6 -6
  9. package/src/agents/types.ts +6 -6
  10. package/src/ai/ai-button/AiButton.svelte +4 -12
  11. package/src/ai/generation-progress/GenerationProgress.svelte +10 -3
  12. package/src/ai/prompt-input/PromptInputTextarea.svelte +1 -2
  13. package/src/ai/response/Response.css +2 -3
  14. package/src/animations/avatar-group-hover.css +2 -16
  15. package/src/animations/card-tilt.css +3 -6
  16. package/src/animations/digit-pop-in.css +2 -15
  17. package/src/animations/dropdown.css +4 -17
  18. package/src/animations/input-clear-dissolve.css +5 -18
  19. package/src/animations/input-shake.css +9 -41
  20. package/src/animations/learn-more-hover.css +17 -9
  21. package/src/animations/like-button.css +2 -4
  22. package/src/animations/page-side-by-side.css +2 -10
  23. package/src/animations/plus-menu-morph.css +2 -5
  24. package/src/animations/shimmer-text.css +5 -18
  25. package/src/animations/spinning-counter.css +2 -6
  26. package/src/animations/success-check.css +2 -15
  27. package/src/animations/thinking-states.css +2 -7
  28. package/src/brand/brand.test.ts +21 -5
  29. package/src/brand/index.ts +4 -10
  30. package/src/canvas/card/card-frame.svelte +43 -39
  31. package/src/canvas/card/resize-handles.svelte +89 -80
  32. package/src/canvas/chrome/chrome-zoom.svelte +101 -100
  33. package/src/canvas/chrome/lock-badge.svelte +8 -8
  34. package/src/canvas/chrome/side-handles.svelte +24 -19
  35. package/src/canvas/chrome/size-chip.svelte +30 -30
  36. package/src/canvas/chrome/snap-guides.svelte +20 -20
  37. package/src/canvas/components/icons/ToolIcon.svelte +8 -8
  38. package/src/canvas/components/shared/svg/PreviewSvg.svelte +19 -19
  39. package/src/canvas/components/shared/svg/ShapeOutline.svelte +71 -48
  40. package/src/canvas/components/shared/svg/StrokeNode.svelte +21 -27
  41. package/src/canvas/components/shared/svg/TextRule.svelte +25 -17
  42. package/src/canvas/edges/bend-handle.svelte +46 -46
  43. package/src/canvas/edges/edge-gradient.svelte +10 -10
  44. package/src/canvas/edges/gradient-edge.svelte +45 -29
  45. package/src/canvas/editor/lock.test.ts +6 -1
  46. package/src/canvas/editor/style.ts +7 -1
  47. package/src/canvas/headless/svg-figure.test.ts +5 -1
  48. package/src/canvas/lod/lod-switch.svelte +111 -106
  49. package/src/canvas/pen/PenField.svelte +87 -81
  50. package/src/canvas/pen/PenOverlay.svelte +127 -127
  51. package/src/canvas/pen/ShapeNode.svelte +31 -32
  52. package/src/canvas/pen/TextNode.svelte +54 -53
  53. package/src/canvas/pen/host-field.test.svelte +7 -7
  54. package/src/canvas/pen/shapes.ts +7 -1
  55. package/src/canvas/screen/GlyphIcon.svelte +22 -17
  56. package/src/canvas/screen/PartView.svelte +138 -72
  57. package/src/canvas/screen/ScreenBody.svelte +81 -60
  58. package/src/canvas/screen/ScreenCard.svelte +20 -20
  59. package/src/canvas/ui/CanvasToolbar.svelte +173 -85
  60. package/src/canvas/ui/FrameLayer.svelte +59 -59
  61. package/src/canvas/ui/PenLayer.svelte +39 -30
  62. package/src/canvas/ui/StylePanel.svelte +119 -102
  63. package/src/canvas/ui/canvas-grid.svelte +137 -129
  64. package/src/charts/animated-value.svelte +1 -1
  65. package/src/charts/area-chart.css +2 -5
  66. package/src/charts/area-chart.svelte +1 -1
  67. package/src/charts/bar-chart.css +2 -3
  68. package/src/charts/bar-chart.svelte +1 -1
  69. package/src/charts/charts.css +5 -17
  70. package/src/charts/crosshair.svelte +1 -1
  71. package/src/charts/dashboard/dashboard-empty.svelte +25 -25
  72. package/src/charts/dashboard/dashboard-section.svelte +24 -24
  73. package/src/charts/dashboard/data-panel.svelte +50 -50
  74. package/src/charts/dashboard/data-sort-head.svelte +56 -56
  75. package/src/charts/dashboard/data-table.svelte +138 -138
  76. package/src/charts/dashboard/panel-grid.svelte +30 -30
  77. package/src/charts/dashboard/period-filter.svelte +25 -25
  78. package/src/charts/dashboard/rating-chip.svelte +19 -19
  79. package/src/charts/dashboard/stat-band.svelte +32 -32
  80. package/src/charts/dashboard/stat-tile.svelte +106 -99
  81. package/src/charts/donut-chart.svelte +1 -1
  82. package/src/charts/edge-fade.svelte +1 -1
  83. package/src/charts/figure.svelte +1 -1
  84. package/src/charts/gauge-chart.css +4 -7
  85. package/src/charts/gauge-chart.svelte +1 -1
  86. package/src/charts/hover-focus.svelte +1 -1
  87. package/src/charts/legend.css +1 -3
  88. package/src/charts/legend.svelte +1 -1
  89. package/src/charts/line-chart.svelte +1 -1
  90. package/src/charts/number-chart.css +6 -9
  91. package/src/charts/number-chart.svelte +1 -1
  92. package/src/charts/reference-line.svelte +19 -19
  93. package/src/charts/reveal.svelte +1 -1
  94. package/src/charts/ring-chart.css +2 -4
  95. package/src/charts/ring-chart.svelte +1 -1
  96. package/src/charts/sparkline.svelte +5 -2
  97. package/src/charts/stat-card.svelte +1 -1
  98. package/src/charts/time-series-chart.css +2 -5
  99. package/src/charts/trend-pill.css +2 -4
  100. package/src/charts/trend-pill.svelte +1 -1
  101. package/src/components/copy/copy-button.svelte +93 -98
  102. package/src/components/copy/copy-button.test.ts +10 -2
  103. package/src/components/data-table/infinite-scroll.svelte +42 -42
  104. package/src/components/data-table/pagination.svelte +34 -22
  105. package/src/components/data-table/row-arrow.svelte +19 -16
  106. package/src/components/data-table/row-context-menu.svelte +52 -52
  107. package/src/components/data-table/sortable-head.svelte +25 -25
  108. package/src/components/data-table/table-skeleton.svelte +41 -36
  109. package/src/components/docs/doc-page.svelte +18 -9
  110. package/src/components/docs/on-this-page.svelte +16 -3
  111. package/src/components/docs/scroll-spy.svelte.ts +2 -3
  112. package/src/components/field-row/field-row.svelte +10 -8
  113. package/src/components/hold-to-confirm/hold-to-confirm.svelte +5 -1
  114. package/src/components/icon/icon.svelte +14 -14
  115. package/src/components/language-flag/language-flag.svelte +3 -1
  116. package/src/components/list-page/detail-empty.svelte +34 -34
  117. package/src/components/list-page/detail-header.svelte +55 -47
  118. package/src/components/list-page/detail-panel.svelte +51 -59
  119. package/src/components/list-page/detail-row.svelte +19 -19
  120. package/src/components/list-page/detail-stack.svelte +21 -21
  121. package/src/components/list-page/empty-state.svelte +30 -30
  122. package/src/components/list-page/filter-item.svelte +20 -20
  123. package/src/components/list-page/filter-popover.svelte +60 -55
  124. package/src/components/list-page/grouped-list.svelte +4 -2
  125. package/src/components/list-page/index.ts +5 -1
  126. package/src/components/list-page/list-page-shell.svelte +2 -5
  127. package/src/components/list-page/master-detail.svelte +87 -88
  128. package/src/components/list-page/notice-bar.svelte +38 -38
  129. package/src/components/list-page/prev-next.svelte +63 -63
  130. package/src/components/list-page/rail-body.svelte +18 -18
  131. package/src/components/list-page/rail-empty.svelte +23 -30
  132. package/src/components/list-page/rail-head.svelte +24 -24
  133. package/src/components/list-page/rail-row.svelte +77 -73
  134. package/src/components/list-page/section-host.ts +2 -3
  135. package/src/components/locale-switch/locale-switch.svelte +41 -41
  136. package/src/components/mark/mark.svelte +34 -38
  137. package/src/components/open-in/index.ts +1 -5
  138. package/src/components/open-in/open-in.svelte +40 -40
  139. package/src/components/picker/mark-picker.svelte +49 -49
  140. package/src/components/picker/picker.svelte +5 -3
  141. package/src/components/section-header/section-header.test.ts +7 -1
  142. package/src/components/section-header/section-label.svelte +20 -20
  143. package/src/components/segmented/animated-tabs.svelte +31 -2
  144. package/src/components/segmented/collapse.test.ts +2 -1
  145. package/src/components/segmented/index.ts +2 -0
  146. package/src/components/segmented/segment.svelte +52 -49
  147. package/src/components/segmented/segmented-filter.svelte +79 -80
  148. package/src/components/segmented/segmented-nav.svelte +34 -40
  149. package/src/components/segmented/segmented-overflow.svelte +53 -50
  150. package/src/components/segmented/segmented-track.svelte +62 -46
  151. package/src/components/segmented/segmented.ts +2 -3
  152. package/src/components/star-rating-input/star-rating-input.svelte +103 -103
  153. package/src/components/svg/svg.svelte +4 -4
  154. package/src/components/table-view/table-view.svelte +17 -2
  155. package/src/components/table-view/table-view.test.ts +7 -1
  156. package/src/components/table-view/types.ts +11 -11
  157. package/src/components/tags-input/index.ts +13 -0
  158. package/src/components/tags-input/tags-input.svelte +305 -0
  159. package/src/components/tags-input/tags.test.ts +64 -0
  160. package/src/components/tags-input/tags.ts +142 -0
  161. package/src/components/theme/index.ts +2 -4
  162. package/src/components/theme/theme-provider.svelte +1 -3
  163. package/src/components/toolbar/toolbar-search.svelte +25 -25
  164. package/src/components/toolbar/toolbar.svelte +11 -7
  165. package/src/components/toolbar/toolbar.test.ts +10 -1
  166. package/src/design/index.css +21 -78
  167. package/src/design/polish.css +26 -35
  168. package/src/editor/editor-toolbar.svelte +104 -99
  169. package/src/editor/editor.svelte +296 -266
  170. package/src/editor/image-toolbar.svelte +20 -22
  171. package/src/editor/index.ts +1 -4
  172. package/src/editor/inline-editor.svelte +280 -238
  173. package/src/editor/markdown.ts +15 -15
  174. package/src/editor/renderer.svelte +71 -71
  175. package/src/editor/slash-menu.svelte +24 -27
  176. package/src/effects/animated-beam/diagrams/BeamSvg.svelte +1 -1
  177. package/src/effects/image-comparison/ImageComparison.svelte +11 -1
  178. package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +59 -46
  179. package/src/effects/magic-card/MagicCard.css +14 -7
  180. package/src/effects/marquee/Marquee.svelte +3 -5
  181. package/src/effects/reveal/observe.ts +0 -3
  182. package/src/effects/spotlight/Spotlight.svelte +1 -1
  183. package/src/effects/theme-toggle/ThemeToggle.css +25 -22
  184. package/src/effects/theme-toggle/ThemeToggle.svelte +6 -7
  185. package/src/gallery.test.ts +14 -4
  186. package/src/inbox/README.md +1 -3
  187. package/src/inbox/inbox.test.ts +181 -138
  188. package/src/inbox/index.ts +20 -20
  189. package/src/inbox/logic.ts +114 -111
  190. package/src/inbox/thread-inbox.svelte +227 -151
  191. package/src/inbox/types.ts +130 -108
  192. package/src/lib/theme-transition.ts +2 -4
  193. package/src/lib/tone.ts +2 -4
  194. package/src/lib/utils.ts +2 -2
  195. package/src/modules.test.ts +79 -69
  196. package/src/onboarding/define-tours.test.ts +55 -40
  197. package/src/onboarding/define-tours.ts +23 -23
  198. package/src/onboarding/demo.svelte +24 -5
  199. package/src/onboarding/index.ts +1 -8
  200. package/src/onboarding/onboarding-provider.svelte +19 -7
  201. package/src/onboarding/onboarding.svelte.ts +16 -16
  202. package/src/onboarding/pick.test.ts +61 -52
  203. package/src/onboarding/pick.ts +16 -13
  204. package/src/onboarding/stores.test.ts +80 -80
  205. package/src/onboarding/stores.ts +41 -39
  206. package/src/onboarding/tour-card.svelte +30 -5
  207. package/src/onboarding/tour-runner.svelte +12 -3
  208. package/src/onboarding/types.ts +20 -12
  209. package/src/onboarding/wait.ts +22 -22
  210. package/src/panel/side-panel.svelte +94 -93
  211. package/src/record/demo-data.ts +291 -225
  212. package/src/record/field-section.svelte +38 -34
  213. package/src/record/fields.ts +148 -96
  214. package/src/record/format.ts +63 -56
  215. package/src/record/index.ts +49 -35
  216. package/src/record/info-list.svelte +145 -114
  217. package/src/record/kinds.ts +31 -31
  218. package/src/record/logic.ts +216 -214
  219. package/src/record/next-up.svelte +45 -34
  220. package/src/record/project-list.svelte +56 -50
  221. package/src/record/record-demo.svelte +130 -110
  222. package/src/record/record-header.svelte +37 -28
  223. package/src/record/record-shell.svelte +54 -54
  224. package/src/record/record-stats.svelte +25 -25
  225. package/src/record/record-timeline.svelte +134 -114
  226. package/src/record/record.test.ts +430 -309
  227. package/src/record/steps-rail.svelte +225 -216
  228. package/src/record/types.ts +234 -215
  229. package/src/record/where-we-are.svelte +62 -58
  230. package/src/shadcn/button/button.svelte +1 -1
  231. package/src/shadcn/card/card-title.svelte +1 -5
  232. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +2 -13
  233. package/src/shadcn/sheet/sheet-content.svelte +2 -4
  234. package/src/shadcn/table/table-cell.svelte +2 -3
  235. package/src/shadcn/utilities.css +3 -8
  236. package/src/slides/Controls.svelte +150 -124
  237. package/src/slides/Deck.svelte +243 -238
  238. package/src/slides/Fragment.svelte +64 -57
  239. package/src/slides/Overview.svelte +106 -101
  240. package/src/slides/Presenter.svelte +300 -266
  241. package/src/slides/Slide.svelte +185 -170
  242. package/src/slides/SlideList.svelte +16 -12
  243. package/src/slides/ambient.d.ts +1 -1
  244. package/src/slides/bridges.ts +42 -23
  245. package/src/slides/deck-controller.svelte.ts +47 -35
  246. package/src/slides/demo-slides.svelte +330 -306
  247. package/src/slides/demo.svelte +164 -160
  248. package/src/slides/export/capture.ts +20 -16
  249. package/src/slides/export/ffmpeg.ts +43 -38
  250. package/src/slides/export/index.ts +5 -5
  251. package/src/slides/export/launch.ts +3 -1
  252. package/src/slides/export/pdf.ts +30 -27
  253. package/src/slides/export/types.ts +10 -8
  254. package/src/slides/index.ts +11 -11
  255. package/src/slides/labels.ts +22 -19
  256. package/src/slides/layout.ts +9 -2
  257. package/src/slides/model.ts +4 -4
  258. package/src/slides/navigation.ts +43 -31
  259. package/src/slides/theme.css +5 -7
  260. package/src/slides/types.ts +9 -10
  261. package/src/status/define-statuses.ts +17 -24
  262. package/src/status/index.ts +5 -5
  263. package/src/status/status-badge.svelte +3 -1
  264. package/src/status/status-dot.svelte +1 -3
  265. package/src/status/status-icon.svelte +1 -1
  266. package/src/status/status-types.ts +21 -21
  267. package/src/tasks/board-order.ts +2 -4
  268. package/src/tasks/demo.svelte +189 -31
  269. package/src/tasks/detail/detail-demo.svelte +73 -13
  270. package/src/tasks/detail/detail-types.ts +45 -45
  271. package/src/tasks/detail/task-detail.svelte +40 -10
  272. package/src/tasks/detail/task-property.svelte +8 -2
  273. package/src/tasks/detail/task-thread.svelte +53 -12
  274. package/src/tasks/gantt/gantt-bar.svelte +17 -6
  275. package/src/tasks/gantt/gantt-grid.svelte +40 -9
  276. package/src/tasks/gantt/gantt-group-row.svelte +8 -2
  277. package/src/tasks/gantt/gantt-header.svelte +9 -3
  278. package/src/tasks/gantt/gantt-task-row.svelte +26 -6
  279. package/src/tasks/gantt/gantt.css +2 -1
  280. package/src/tasks/gantt/gantt.test.ts +3 -1
  281. package/src/tasks/gantt/logic.test.ts +110 -20
  282. package/src/tasks/gantt/logic.ts +42 -6
  283. package/src/tasks/inbox/inbox-card.svelte +13 -5
  284. package/src/tasks/inbox/inbox-draft.svelte +1 -1
  285. package/src/tasks/inbox/inbox-logic.ts +6 -40
  286. package/src/tasks/inbox/inbox-statuses.ts +23 -23
  287. package/src/tasks/inbox/inbox-trace.svelte +9 -3
  288. package/src/tasks/inbox/inbox-types.ts +54 -58
  289. package/src/tasks/inbox/index.ts +22 -21
  290. package/src/tasks/index.ts +49 -52
  291. package/src/tasks/kanban-board.svelte +16 -12
  292. package/src/tasks/kanban-types.ts +2 -3
  293. package/src/tasks/presets/sales.ts +6 -6
  294. package/src/tasks/task-gantt.svelte +28 -8
  295. package/src/tasks/task-list.svelte +41 -17
  296. package/src/tasks/time/duration.ts +40 -40
  297. package/src/tasks/time/time-chip.svelte +9 -2
  298. package/src/tasks/time/time-dot.svelte +1 -1
  299. package/src/tasks/time/time-ring.svelte +11 -3
  300. package/src/tasks/time/time-tracker.svelte +57 -15
  301. package/src/tasks/time/time-types.ts +57 -57
  302. package/src/tasks/use-kanban-dnd.svelte.ts +2 -3
  303. package/src/thread/index.ts +7 -7
  304. package/src/thread/logic.ts +36 -33
  305. package/src/thread/thread.svelte +82 -16
  306. package/src/thread/thread.test.ts +58 -47
  307. package/src/thread/types.ts +68 -68
  308. package/src/tokens/craft.css +17 -53
  309. package/src/tokens/index.css +3 -13
  310. package/src/tokens/palette.css +13 -11
  311. package/src/tokens/primitives.css +10 -23
  312. package/src/tasks/inbox/inbox.svelte +0 -203
@@ -1,271 +1,276 @@
1
1
  <script lang="ts">
2
- import './theme.css';
3
- import { flushSync, onMount, setContext, untrack } from 'svelte';
4
- import { attachBridge, attachChannel, attachUrlSync } from './bridges.js';
5
- import Controls from './Controls.svelte';
6
- import { DeckController } from './deck-controller.svelte.js';
7
- import Overview from './Overview.svelte';
8
- import SlideList from './SlideList.svelte';
9
- import { DECK_KEY, DEFAULT_CANVAS, type DeckProps } from './types.js';
2
+ import "./theme.css";
3
+ import { flushSync, onMount, setContext, untrack } from "svelte";
4
+ import { attachBridge, attachChannel, attachUrlSync } from "./bridges.js";
5
+ import Controls from "./Controls.svelte";
6
+ import { DeckController } from "./deck-controller.svelte.js";
7
+ import Overview from "./Overview.svelte";
8
+ import SlideList from "./SlideList.svelte";
9
+ import { DECK_KEY, DEFAULT_CANVAS, type DeckProps } from "./types.js";
10
10
 
11
- let {
12
- index = $bindable(0),
13
- step = $bindable(0),
14
- controller = $bindable(),
15
- id,
16
- title,
17
- locale,
18
- canvas = DEFAULT_CANVAS,
19
- theme = 'ink',
20
- transition = 'fade',
21
- slides,
22
- registry,
23
- progress = true,
24
- controls = true,
25
- loop = false,
26
- keyboard = true,
27
- fragments = true,
28
- urlSync = false,
29
- bridge = false,
30
- sync,
31
- presenter,
32
- labels,
33
- class: className,
34
- style,
35
- onchange,
36
- children,
37
- }: DeckProps = $props();
11
+ let {
12
+ index = $bindable(0),
13
+ step = $bindable(0),
14
+ controller = $bindable(),
15
+ id,
16
+ title,
17
+ locale,
18
+ canvas = DEFAULT_CANVAS,
19
+ theme = "ink",
20
+ transition = "fade",
21
+ slides,
22
+ registry,
23
+ progress = true,
24
+ controls = true,
25
+ loop = false,
26
+ keyboard = true,
27
+ fragments = true,
28
+ urlSync = false,
29
+ bridge = false,
30
+ sync,
31
+ presenter,
32
+ labels,
33
+ class: className,
34
+ style,
35
+ onchange,
36
+ children,
37
+ }: DeckProps = $props();
38
38
 
39
- /* The accessors read and write the bindable props, so the controller keeps no copy of them. */
40
- const deck = new DeckController({
41
- get index() {
42
- return index;
43
- },
44
- set index(value) {
45
- index = value;
46
- },
47
- get step() {
48
- return step;
49
- },
50
- set step(value) {
51
- step = value;
52
- },
53
- get loop() {
54
- return loop;
55
- },
56
- get fragments() {
57
- return fragments;
58
- },
59
- get keyboard() {
60
- return keyboard;
61
- },
62
- get presenter() {
63
- return !!presenter;
64
- },
65
- get controls() {
66
- return controls;
67
- },
68
- get canvas() {
69
- return canvas;
70
- },
71
- get labels() {
72
- return labels;
73
- },
74
- transition: viewTransition,
75
- });
76
- controller = deck;
77
- setContext(DECK_KEY, deck);
39
+ /* The accessors read and write the bindable props, so the controller keeps no copy of them. */
40
+ const deck = new DeckController({
41
+ get index() {
42
+ return index;
43
+ },
44
+ set index(value) {
45
+ index = value;
46
+ },
47
+ get step() {
48
+ return step;
49
+ },
50
+ set step(value) {
51
+ step = value;
52
+ },
53
+ get loop() {
54
+ return loop;
55
+ },
56
+ get fragments() {
57
+ return fragments;
58
+ },
59
+ get keyboard() {
60
+ return keyboard;
61
+ },
62
+ get presenter() {
63
+ return !!presenter;
64
+ },
65
+ get controls() {
66
+ return controls;
67
+ },
68
+ get canvas() {
69
+ return canvas;
70
+ },
71
+ get labels() {
72
+ return labels;
73
+ },
74
+ transition: viewTransition,
75
+ });
76
+ controller = deck;
77
+ setContext(DECK_KEY, deck);
78
78
 
79
- let root = $state<HTMLElement>();
80
- let stage = $state<HTMLElement>();
79
+ let root = $state<HTMLElement>();
80
+ let stage = $state<HTMLElement>();
81
81
 
82
- /* Morph hands the swap to the browser, which animates elements sharing a `data-morph` name. */
83
- function viewTransition(update: () => void) {
84
- const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches;
85
- if (transition !== 'morph' || reduced || !document.startViewTransition) return update();
86
- document.documentElement.dataset.deckVt = '';
87
- const run = document.startViewTransition(() => flushSync(update));
88
- run.finished.finally(() => delete document.documentElement.dataset.deckVt);
89
- }
82
+ /* Morph hands the swap to the browser, which animates elements sharing a `data-morph` name. */
83
+ function viewTransition(update: () => void) {
84
+ const reduced = matchMedia("(prefers-reduced-motion: reduce)").matches;
85
+ if (transition !== "morph" || reduced || !document.startViewTransition) return update();
86
+ document.documentElement.dataset.deckVt = "";
87
+ const run = document.startViewTransition(() => flushSync(update));
88
+ run.finished.finally(() => delete document.documentElement.dataset.deckVt);
89
+ }
90
90
 
91
- onMount(() => deck.mount());
91
+ onMount(() => deck.mount());
92
92
 
93
- $effect(() => deck.listen((position) => onchange?.(position.index, position.step)));
94
- $effect(() => {
95
- const options = urlSync;
96
- if (options) return untrack(() => attachUrlSync(deck, options === true ? {} : options));
97
- });
98
- $effect(() => {
99
- const options = bridge;
100
- if (options) return untrack(() => attachBridge(deck, options === true ? {} : options));
101
- });
102
- $effect(() => {
103
- const name = sync;
104
- if (name) return untrack(() => attachChannel(deck, name));
105
- });
93
+ $effect(() => deck.listen((position) => onchange?.(position.index, position.step)));
94
+ $effect(() => {
95
+ const options = urlSync;
96
+ if (options) return untrack(() => attachUrlSync(deck, options === true ? {} : options));
97
+ });
98
+ $effect(() => {
99
+ const options = bridge;
100
+ if (options) return untrack(() => attachBridge(deck, options === true ? {} : options));
101
+ });
102
+ $effect(() => {
103
+ const name = sync;
104
+ if (name) return untrack(() => attachChannel(deck, name));
105
+ });
106
106
 
107
- $effect(() => {
108
- const el = stage;
109
- if (!el) return;
110
- const measure = () => (deck.size = { w: el.offsetWidth, h: el.offsetHeight });
111
- measure();
112
- const observer = new ResizeObserver(measure);
113
- observer.observe(el);
114
- return () => observer.disconnect();
115
- });
107
+ $effect(() => {
108
+ const el = stage;
109
+ if (!el) return;
110
+ const measure = () => (deck.size = { w: el.offsetWidth, h: el.offsetHeight });
111
+ measure();
112
+ const observer = new ResizeObserver(measure);
113
+ observer.observe(el);
114
+ return () => observer.disconnect();
115
+ });
116
116
 
117
- async function toggleFullscreen() {
118
- try {
119
- if (document.fullscreenElement) await document.exitFullscreen();
120
- else await root?.requestFullscreen();
121
- } catch {
122
- /* A browser without the API, or a denied request. */
123
- }
124
- }
117
+ async function toggleFullscreen() {
118
+ try {
119
+ if (document.fullscreenElement) await document.exitFullscreen();
120
+ else await root?.requestFullscreen();
121
+ } catch {
122
+ /* A browser without the API, or a denied request. */
123
+ }
124
+ }
125
125
 
126
- const openPresenter = $derived(
127
- presenter ? () => void window.open(presenter, `heyramzi-slides-${id ?? ''}`, 'popup,width=1280,height=800') : undefined,
128
- );
126
+ const openPresenter = $derived(
127
+ presenter
128
+ ? () =>
129
+ void window.open(presenter, `heyramzi-slides-${id ?? ""}`, "popup,width=1280,height=800")
130
+ : undefined,
131
+ );
129
132
 
130
- function onkeydown(event: KeyboardEvent) {
131
- const action = deck.handleKey(event);
132
- if (action === 'fullscreen') void toggleFullscreen();
133
- else if (action === 'presenter') openPresenter?.();
134
- }
133
+ function onkeydown(event: KeyboardEvent) {
134
+ const action = deck.handleKey(event);
135
+ if (action === "fullscreen") void toggleFullscreen();
136
+ else if (action === "presenter") openPresenter?.();
137
+ }
135
138
 
136
- let swipe: { x: number; y: number } | null = null;
137
- function onpointerdown(event: PointerEvent) {
138
- deck.activate();
139
- swipe = event.pointerType === 'mouse' ? null : { x: event.clientX, y: event.clientY };
140
- }
141
- function onpointerup(event: PointerEvent) {
142
- if (!swipe || deck.overview) return;
143
- const dx = event.clientX - swipe.x;
144
- const dy = event.clientY - swipe.y;
145
- swipe = null;
146
- if (Math.abs(dx) < 48 || Math.abs(dx) < Math.abs(dy)) return;
147
- if (dx < 0) deck.next();
148
- else deck.prev();
149
- }
139
+ let swipe: { x: number; y: number } | null = null;
140
+ function onpointerdown(event: PointerEvent) {
141
+ deck.activate();
142
+ swipe = event.pointerType === "mouse" ? null : { x: event.clientX, y: event.clientY };
143
+ }
144
+ function onpointerup(event: PointerEvent) {
145
+ if (!swipe || deck.overview) return;
146
+ const dx = event.clientX - swipe.x;
147
+ const dy = event.clientY - swipe.y;
148
+ swipe = null;
149
+ if (Math.abs(dx) < 48 || Math.abs(dx) < Math.abs(dy)) return;
150
+ if (dx < 0) deck.next();
151
+ else deck.prev();
152
+ }
150
153
  </script>
151
154
 
152
155
  <svelte:head>
153
- {@html `<style>@page{size:${canvas.w}px ${canvas.h}px;margin:0}</style>`}
156
+ {@html `<style>@page{size:${canvas.w}px ${canvas.h}px;margin:0}</style>`}
154
157
  </svelte:head>
155
158
  <svelte:window {onkeydown} />
156
159
 
157
160
  <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
158
161
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
159
162
  <div
160
- bind:this={root}
161
- class={['deck', `deck--${theme}`, className]}
162
- style:aspect-ratio="{canvas.w} / {canvas.h}"
163
- style:--deck-dir={deck.direction}
164
- {style}
165
- lang={locale}
166
- role="region"
167
- aria-roledescription={deck.labels.deckRole}
168
- aria-label={title ?? deck.labels.deck}
169
- tabindex="0"
170
- data-deck={id}
171
- data-view={deck.view}
172
- data-transition={transition}
173
- data-morphing={deck.morphing || undefined}
174
- onfocusin={() => deck.activate()}
175
- onpointerenter={() => deck.activate()}
176
- {onpointerdown}
177
- {onpointerup}
163
+ bind:this={root}
164
+ class={["deck", `deck--${theme}`, className]}
165
+ style:aspect-ratio="{canvas.w} / {canvas.h}"
166
+ style:--deck-dir={deck.direction}
167
+ {style}
168
+ lang={locale}
169
+ role="region"
170
+ aria-roledescription={deck.labels.deckRole}
171
+ aria-label={title ?? deck.labels.deck}
172
+ tabindex="0"
173
+ data-deck={id}
174
+ data-view={deck.view}
175
+ data-transition={transition}
176
+ data-morphing={deck.morphing || undefined}
177
+ onfocusin={() => deck.activate()}
178
+ onpointerenter={() => deck.activate()}
179
+ {onpointerdown}
180
+ {onpointerup}
178
181
  >
179
- <div bind:this={stage} class="deck__stage">
180
- {#if slides && registry}
181
- <SlideList {slides} {registry} unknownLabel={deck.labels.unknownType} />
182
- {:else}
183
- {@render children?.()}
184
- {/if}
185
- {#if deck.overview}
186
- <Overview {deck} returnFocus={root} />
187
- {/if}
188
- </div>
182
+ <div bind:this={stage} class="deck__stage">
183
+ {#if slides && registry}
184
+ <SlideList {slides} {registry} unknownLabel={deck.labels.unknownType} />
185
+ {:else}
186
+ {@render children?.()}
187
+ {/if}
188
+ {#if deck.overview}
189
+ <Overview {deck} returnFocus={root} />
190
+ {/if}
191
+ </div>
189
192
 
190
- <div class="deck__sr" aria-live="polite" aria-atomic="true">{deck.labels.slide(deck.ordinal.n, deck.ordinal.of)}</div>
193
+ <div class="deck__sr" aria-live="polite" aria-atomic="true">
194
+ {deck.labels.slide(deck.ordinal.n, deck.ordinal.of)}
195
+ </div>
191
196
 
192
- {#if progress}
193
- <div
194
- class="deck__progress deck__chrome"
195
- role="progressbar"
196
- aria-label={deck.labels.progress}
197
- aria-valuemin="1"
198
- aria-valuemax={deck.ordinal.of}
199
- aria-valuenow={deck.ordinal.n}
200
- aria-valuetext={deck.labels.slide(deck.ordinal.n, deck.ordinal.of)}
201
- >
202
- <div class="deck__progress-fill" style:transform="scaleX({deck.progress})"></div>
203
- </div>
204
- {/if}
197
+ {#if progress}
198
+ <div
199
+ class="deck__progress deck__chrome"
200
+ role="progressbar"
201
+ aria-label={deck.labels.progress}
202
+ aria-valuemin="1"
203
+ aria-valuemax={deck.ordinal.of}
204
+ aria-valuenow={deck.ordinal.n}
205
+ aria-valuetext={deck.labels.slide(deck.ordinal.n, deck.ordinal.of)}
206
+ >
207
+ <div class="deck__progress-fill" style:transform="scaleX({deck.progress})"></div>
208
+ </div>
209
+ {/if}
205
210
 
206
- {#if controls}
207
- <Controls {deck} onpresenter={openPresenter} onfullscreen={toggleFullscreen} />
208
- {/if}
211
+ {#if controls}
212
+ <Controls {deck} onpresenter={openPresenter} onfullscreen={toggleFullscreen} />
213
+ {/if}
209
214
  </div>
210
215
 
211
216
  <style>
212
- .deck {
213
- position: relative;
214
- display: block;
215
- width: 100%;
216
- height: 100%;
217
- min-height: 0;
218
- overflow: hidden;
219
- container-type: inline-size;
220
- background: var(--deck-letterbox);
221
- color: var(--deck-fg);
222
- font-family: var(--deck-font);
223
- outline: none;
224
- touch-action: pan-y;
225
- -webkit-tap-highlight-color: transparent;
226
- }
227
- .deck:focus-visible {
228
- outline: 2px solid var(--deck-accent);
229
- outline-offset: -2px;
230
- }
231
- .deck:fullscreen {
232
- background: var(--deck-bg);
233
- }
217
+ .deck {
218
+ position: relative;
219
+ display: block;
220
+ width: 100%;
221
+ height: 100%;
222
+ min-height: 0;
223
+ overflow: hidden;
224
+ container-type: inline-size;
225
+ background: var(--deck-letterbox);
226
+ color: var(--deck-fg);
227
+ font-family: var(--deck-font);
228
+ outline: none;
229
+ touch-action: pan-y;
230
+ -webkit-tap-highlight-color: transparent;
231
+ }
232
+ .deck:focus-visible {
233
+ outline: 2px solid var(--deck-accent);
234
+ outline-offset: -2px;
235
+ }
236
+ .deck:fullscreen {
237
+ background: var(--deck-bg);
238
+ }
234
239
 
235
- .deck__stage {
236
- position: absolute;
237
- inset: 0;
238
- overflow: hidden;
239
- }
240
+ .deck__stage {
241
+ position: absolute;
242
+ inset: 0;
243
+ overflow: hidden;
244
+ }
240
245
 
241
- .deck__progress {
242
- position: absolute;
243
- right: 0;
244
- bottom: 0;
245
- left: 0;
246
- z-index: 5;
247
- height: 3px;
248
- background: var(--deck-line);
249
- }
250
- .deck__progress-fill {
251
- height: 100%;
252
- background: var(--deck-accent);
253
- transform-origin: 0 50%;
254
- transition: transform var(--deck-t-morph) var(--deck-ease);
255
- }
246
+ .deck__progress {
247
+ position: absolute;
248
+ right: 0;
249
+ bottom: 0;
250
+ left: 0;
251
+ z-index: 5;
252
+ height: 3px;
253
+ background: var(--deck-line);
254
+ }
255
+ .deck__progress-fill {
256
+ height: 100%;
257
+ background: var(--deck-accent);
258
+ transform-origin: 0 50%;
259
+ transition: transform var(--deck-t-morph) var(--deck-ease);
260
+ }
256
261
 
257
- .deck__sr {
258
- position: absolute;
259
- width: 1px;
260
- height: 1px;
261
- overflow: hidden;
262
- clip-path: inset(50%);
263
- white-space: nowrap;
264
- }
262
+ .deck__sr {
263
+ position: absolute;
264
+ width: 1px;
265
+ height: 1px;
266
+ overflow: hidden;
267
+ clip-path: inset(50%);
268
+ white-space: nowrap;
269
+ }
265
270
 
266
- @media (prefers-reduced-motion: reduce) {
267
- .deck__progress-fill {
268
- transition: none;
269
- }
270
- }
271
+ @media (prefers-reduced-motion: reduce) {
272
+ .deck__progress-fill {
273
+ transition: none;
274
+ }
275
+ }
271
276
  </style>
@@ -1,71 +1,78 @@
1
1
  <script lang="ts">
2
- import { getContext, type Snippet } from 'svelte';
3
- import { SLIDE_KEY, type SlideContext } from './types.js';
2
+ import { getContext, type Snippet } from "svelte";
3
+ import { SLIDE_KEY, type SlideContext } from "./types.js";
4
4
 
5
- interface Props {
6
- /** Reveal at this step. `1` is the first press of the arrow key. */
7
- step?: number;
8
- /** How it arrives: `rise` (default), `fade` or `scale`. */
9
- reveal?: 'rise' | 'fade' | 'scale';
10
- /** The element to render, so a fragment can be an `li` inside a `ul`. */
11
- as?: string;
12
- class?: string;
13
- style?: string;
14
- children?: Snippet;
15
- };
5
+ interface Props {
6
+ /** Reveal at this step. `1` is the first press of the arrow key. */
7
+ step?: number;
8
+ /** How it arrives: `rise` (default), `fade` or `scale`. */
9
+ reveal?: "rise" | "fade" | "scale";
10
+ /** The element to render, so a fragment can be an `li` inside a `ul`. */
11
+ as?: string;
12
+ class?: string;
13
+ style?: string;
14
+ children?: Snippet;
15
+ }
16
16
 
17
- let { step = 1, reveal = 'rise', as: tag = 'div', class: className, style, children }: Props = $props();
17
+ let {
18
+ step = 1,
19
+ reveal = "rise",
20
+ as: tag = "div",
21
+ class: className,
22
+ style,
23
+ children,
24
+ }: Props = $props();
18
25
 
19
- const slide = getContext<SlideContext | undefined>(SLIDE_KEY);
20
- const visible = $derived(slide ? slide.shown(step) : true);
26
+ const slide = getContext<SlideContext | undefined>(SLIDE_KEY);
27
+ const visible = $derived(slide ? slide.shown(step) : true);
21
28
 
22
- /* Fragments that share a step arrive one after another, in the order they mounted. */
23
- let order = $state(0);
24
- $effect(() => {
25
- if (!slide) return;
26
- const joined = slide.join(step);
27
- order = joined.order;
28
- return joined.leave;
29
- });
29
+ /* Fragments that share a step arrive one after another, in the order they mounted. */
30
+ let order = $state(0);
31
+ $effect(() => {
32
+ if (!slide) return;
33
+ const joined = slide.join(step);
34
+ order = joined.order;
35
+ return joined.leave;
36
+ });
30
37
  </script>
31
38
 
32
39
  <svelte:element
33
- this={tag}
34
- class={['deck-fragment', className]}
35
- {style}
36
- style:--frag-i={order}
37
- data-reveal={reveal}
38
- data-visible={visible}
39
- aria-hidden={!visible}
40
- inert={!visible}
40
+ this={tag}
41
+ class={["deck-fragment", className]}
42
+ {style}
43
+ style:--frag-i={order}
44
+ data-reveal={reveal}
45
+ data-visible={visible}
46
+ aria-hidden={!visible}
47
+ inert={!visible}
41
48
  >
42
- {@render children?.()}
49
+ {@render children?.()}
43
50
  </svelte:element>
44
51
 
45
52
  <style>
46
- .deck-fragment {
47
- opacity: 0;
48
- transition:
49
- opacity var(--deck-t-slide) var(--deck-ease),
50
- transform var(--deck-t-slide) var(--deck-ease);
51
- }
52
- .deck-fragment[data-reveal='rise'] {
53
- transform: translateY(var(--deck-shift));
54
- }
55
- .deck-fragment[data-reveal='scale'] {
56
- transform: scale(var(--scale-large, 0.96));
57
- }
58
- .deck-fragment[data-visible='true'] {
59
- opacity: 1;
60
- transform: none;
61
- transition-delay: calc(var(--frag-i) * var(--deck-stagger));
62
- }
53
+ .deck-fragment {
54
+ opacity: 0;
55
+ transition:
56
+ opacity var(--deck-t-slide) var(--deck-ease),
57
+ transform var(--deck-t-slide) var(--deck-ease);
58
+ }
59
+ .deck-fragment[data-reveal="rise"] {
60
+ transform: translateY(var(--deck-shift));
61
+ }
62
+ .deck-fragment[data-reveal="scale"] {
63
+ transform: scale(var(--scale-large, 0.96));
64
+ }
65
+ .deck-fragment[data-visible="true"] {
66
+ opacity: 1;
67
+ transform: none;
68
+ transition-delay: calc(var(--frag-i) * var(--deck-stagger));
69
+ }
63
70
 
64
- @media (prefers-reduced-motion: reduce) {
65
- .deck-fragment {
66
- transform: none !important;
67
- transition: opacity var(--deck-t-quick) linear;
68
- transition-delay: 0s !important;
69
- }
70
- }
71
+ @media (prefers-reduced-motion: reduce) {
72
+ .deck-fragment {
73
+ transform: none !important;
74
+ transition: opacity var(--deck-t-quick) linear;
75
+ transition-delay: 0s !important;
76
+ }
77
+ }
71
78
  </style>