@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
@@ -2,11 +2,7 @@
2
2
  import type { HTMLAttributes } from "svelte/elements";
3
3
  import { cn, type WithElementRef } from "../../lib/utils.js";
4
4
 
5
- // WHY: card titles render as a div by default for backwards compatibility,
6
-
7
- // but a page whose sections are all cards ends up with no headings below the h1, so screen readers cannot navigate it by heading (WCAG 2.4.6).
8
-
9
- // Pass `as="h2"` on real section titles.
5
+ // WHY: card titles default to a div, so pass `as="h2"` on real section titles or a page of cards has no headings for screen readers (WCAG 2.4.6).
10
6
  let {
11
7
  ref = $bindable(null),
12
8
  class: className,
@@ -6,19 +6,8 @@ import {
6
6
  import type { GrammarState } from "shiki/core";
7
7
 
8
8
  /**
9
- * Highlights `code` in `language`. `current` holds one entry per line: a plain
10
- * string until the highlighter loads, then the line's tokens. Pass each one to
11
- * the `code` prop of a `CodeBlock.Line`.
12
- *
13
- * ```svelte
14
- * <script lang="ts">
15
- * const lines = useHighlightedCode(() => code, () => "json");
16
- * </script>
17
- *
18
- * {#each lines.current as line, index (index)}
19
- * <CodeBlock.Line code={line} />
20
- * {/each}
21
- * ```
9
+ * Highlights `code`. Each `current` entry is a plain string until the highlighter loads, then
10
+ * tokens, so pass it to `CodeBlock.Line`'s `code` prop either way.
22
11
  */
23
12
  export function useHighlightedCode(value: () => string, language: () => string) {
24
13
  let loaded = $state.raw<{
@@ -29,10 +29,8 @@
29
29
  children: Snippet;
30
30
  } = $props();
31
31
 
32
- // Side classes are plain utilities, not `data-[side=x]:` variants. An attribute
33
- // variant outranks a plain class and tailwind-merge won't dedupe across
34
- // modifier sets, so a caller's `sm:max-w-xl` lost to the default 384px.
35
- // Plain utilities let `cn` drop the default when a caller passes its own.
32
+ // Plain side utilities, not `data-[side=x]:` variants, because the variant outranks a
33
+ // caller's `sm:max-w-xl` and tailwind-merge can't dedupe across modifier sets.
36
34
  const SIDE_CLASS: Record<Side, string> = {
37
35
  // h-dvh, not h-full: on iOS Safari a fixed panel sizes against the layout
38
36
  // viewport, which is taller than the visible area, so h-full hides the footer.
@@ -19,9 +19,8 @@
19
19
  {@render children?.()}
20
20
  </td>
21
21
 
22
- <!-- WHY here: a link in a cell is 20px tall, and a cell is the only place that knows it sits in a
23
- row of them. On a coarse pointer the link grows a 44px box centred on it, wider when the link
24
- is. A link that positions itself (a stretched row link) keeps its own box. -->
22
+ <!-- A cell's link is 20px tall, so on a coarse pointer it grows a 44px hit box here, unless it
23
+ positions itself, like a stretched row link. -->
25
24
  <style>
26
25
  @media (any-pointer: coarse) {
27
26
  td :global(a[href]:not([class*="absolute"], [class*="fixed"], [class*="sticky"])) {
@@ -1,11 +1,6 @@
1
- /* Tailwind utilities the shadcn Attachment and Message components rely on:
2
- scroll-fade-x and scrollbar-none for Attachment.Group's snap-scroller,
3
- shimmer for a processing/uploading Attachment.Title. Vendored from
4
- shadcn-svelte's own tailwind.css bundle (MIT) so this package stays
5
- dependency-free (docs/decisions.md, "The package stays dependency-free").
6
- `no-scrollbar` is deliberately left out: consumers already define it, and
7
- a duplicate @utility breaks their build. Import this file once, after
8
- Tailwind, alongside `@heyramzi/ui/design`. */
1
+ /* Utilities the shadcn Attachment and Message parts need, vendored from
2
+ shadcn-svelte (MIT); `no-scrollbar` stays out because consumers define it
3
+ and a duplicate @utility breaks their build. */
9
4
 
10
5
  @utility scrollbar-none {
11
6
  -ms-overflow-style: none;
@@ -1,138 +1,164 @@
1
1
  <script lang="ts">
2
- import type { DeckController } from './deck-controller.svelte.js';
2
+ import type { DeckController } from "./deck-controller.svelte.js";
3
3
 
4
- interface Props {
5
- deck: DeckController;
6
- /** Shown only when the deck has somewhere to open the presenter view. */
7
- onpresenter?: () => void;
8
- onfullscreen: () => void;
9
- };
4
+ interface Props {
5
+ deck: DeckController;
6
+ /** Shown only when the deck has somewhere to open the presenter view. */
7
+ onpresenter?: () => void;
8
+ onfullscreen: () => void;
9
+ }
10
10
 
11
- let { deck, onpresenter, onfullscreen }: Props = $props();
11
+ let { deck, onpresenter, onfullscreen }: Props = $props();
12
12
 
13
- const icons = {
14
- prev: 'M15 5 8 12l7 7',
15
- next: 'm9 5 7 7-7 7',
16
- overview: 'M4 5h6v6H4zM14 5h6v6h-6zM4 15h6v4H4zM14 15h6v4h-6z',
17
- presenter: 'M4 5h16v10H4zM8 19h8M12 15v4',
18
- fullscreen: 'M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5',
19
- };
13
+ const icons = {
14
+ prev: "M15 5 8 12l7 7",
15
+ next: "m9 5 7 7-7 7",
16
+ overview: "M4 5h6v6H4zM14 5h6v6h-6zM4 15h6v4H4zM14 15h6v4h-6z",
17
+ presenter: "M4 5h16v10H4zM8 19h8M12 15v4",
18
+ fullscreen: "M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5",
19
+ };
20
20
  </script>
21
21
 
22
- {#snippet button(icon: keyof typeof icons, label: string, onclick: () => void, disabled = false, pressed?: boolean)}
23
- <button type="button" class="deck__button" {onclick} {disabled} aria-label={label} aria-pressed={pressed}>
24
- <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
25
- <path d={icons[icon]} fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" />
26
- </svg>
27
- </button>
22
+ {#snippet button(
23
+ icon: keyof typeof icons,
24
+ label: string,
25
+ onclick: () => void,
26
+ disabled = false,
27
+ pressed?: boolean,
28
+ )}
29
+ <button
30
+ type="button"
31
+ class="deck__button"
32
+ {onclick}
33
+ {disabled}
34
+ aria-label={label}
35
+ aria-pressed={pressed}
36
+ >
37
+ <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
38
+ <path
39
+ d={icons[icon]}
40
+ fill="none"
41
+ stroke="currentColor"
42
+ stroke-width="1.75"
43
+ stroke-linecap="round"
44
+ stroke-linejoin="round"
45
+ />
46
+ </svg>
47
+ </button>
28
48
  {/snippet}
29
49
 
30
50
  <div class="deck__controls deck__chrome">
31
- {@render button('prev', deck.labels.previous, () => deck.prev(), deck.atStart)}
32
- <span class="deck__counter" aria-hidden="true">{deck.ordinal.n} / {deck.ordinal.of}</span>
33
- {@render button('next', deck.labels.next, () => deck.next(), deck.atEnd)}
34
- <span class="deck__divider" aria-hidden="true"></span>
35
- {@render button('overview', deck.labels.overview, () => deck.toggleOverview(), false, deck.overview)}
36
- {#if onpresenter}
37
- {@render button('presenter', deck.labels.presenter, onpresenter)}
38
- {/if}
39
- {@render button('fullscreen', deck.labels.fullscreen, onfullscreen)}
51
+ {@render button("prev", deck.labels.previous, () => deck.prev(), deck.atStart)}
52
+ <span class="deck__counter" aria-hidden="true">{deck.ordinal.n} / {deck.ordinal.of}</span>
53
+ {@render button("next", deck.labels.next, () => deck.next(), deck.atEnd)}
54
+ <span class="deck__divider" aria-hidden="true"></span>
55
+ {@render button(
56
+ "overview",
57
+ deck.labels.overview,
58
+ () => deck.toggleOverview(),
59
+ false,
60
+ deck.overview,
61
+ )}
62
+ {#if onpresenter}
63
+ {@render button("presenter", deck.labels.presenter, onpresenter)}
64
+ {/if}
65
+ {@render button("fullscreen", deck.labels.fullscreen, onfullscreen)}
40
66
  </div>
41
67
 
42
68
  <style>
43
- .deck__controls {
44
- position: absolute;
45
- right: 12px;
46
- bottom: 14px;
47
- z-index: 5;
48
- display: flex;
49
- align-items: center;
50
- gap: 2px;
51
- padding: 4px;
52
- color: var(--deck-fg);
53
- background: color-mix(in srgb, var(--deck-bg) 72%, transparent);
54
- border: 1px solid var(--deck-line);
55
- border-radius: 12px;
56
- backdrop-filter: blur(var(--blur-large, 8px));
57
- opacity: 0.55;
58
- transition: opacity var(--deck-t-quick) var(--deck-ease);
59
- }
60
- .deck__controls:focus-within {
61
- opacity: 1;
62
- }
63
- @media (hover: hover) and (pointer: fine) {
64
- .deck__controls:hover {
65
- opacity: 1;
66
- }
67
- }
68
- .deck__button {
69
- display: grid;
70
- place-items: center;
71
- width: 32px;
72
- height: 32px;
73
- padding: 0;
74
- color: inherit;
75
- background: transparent;
76
- border: 0;
77
- border-radius: 8px;
78
- cursor: pointer;
79
- transition:
80
- background-color var(--deck-t-quick) var(--deck-ease),
81
- transform var(--deck-t-quick) var(--deck-ease);
82
- }
83
- @media (hover: hover) and (pointer: fine) {
84
- .deck__button:hover:not(:disabled) {
85
- background: var(--deck-line);
86
- }
87
- }
88
- .deck__button:active:not(:disabled) {
89
- transform: scale(var(--scale-medium, 0.97));
90
- }
91
- .deck__button[aria-pressed='true'] {
92
- color: var(--deck-on-accent);
93
- background: var(--deck-accent);
94
- }
95
- .deck__button:disabled {
96
- opacity: 0.3;
97
- cursor: default;
98
- }
99
- .deck__button:focus-visible {
100
- outline: 2px solid var(--deck-accent);
101
- outline-offset: 1px;
102
- }
103
- .deck__counter {
104
- min-width: 52px;
105
- font: 500 12px/1 var(--deck-font);
106
- font-variant-numeric: tabular-nums;
107
- text-align: center;
108
- color: var(--deck-muted);
109
- }
110
- .deck__divider {
111
- width: 1px;
112
- height: 16px;
113
- margin: 0 4px;
114
- background: var(--deck-line);
115
- }
69
+ .deck__controls {
70
+ position: absolute;
71
+ right: 12px;
72
+ bottom: 14px;
73
+ z-index: 5;
74
+ display: flex;
75
+ align-items: center;
76
+ gap: 2px;
77
+ padding: 4px;
78
+ color: var(--deck-fg);
79
+ background: color-mix(in srgb, var(--deck-bg) 72%, transparent);
80
+ border: 1px solid var(--deck-line);
81
+ border-radius: 12px;
82
+ backdrop-filter: blur(var(--blur-large, 8px));
83
+ opacity: 0.55;
84
+ transition: opacity var(--deck-t-quick) var(--deck-ease);
85
+ }
86
+ .deck__controls:focus-within {
87
+ opacity: 1;
88
+ }
89
+ @media (hover: hover) and (pointer: fine) {
90
+ .deck__controls:hover {
91
+ opacity: 1;
92
+ }
93
+ }
94
+ .deck__button {
95
+ display: grid;
96
+ place-items: center;
97
+ width: 32px;
98
+ height: 32px;
99
+ padding: 0;
100
+ color: inherit;
101
+ background: transparent;
102
+ border: 0;
103
+ border-radius: 8px;
104
+ cursor: pointer;
105
+ transition:
106
+ background-color var(--deck-t-quick) var(--deck-ease),
107
+ transform var(--deck-t-quick) var(--deck-ease);
108
+ }
109
+ @media (hover: hover) and (pointer: fine) {
110
+ .deck__button:hover:not(:disabled) {
111
+ background: var(--deck-line);
112
+ }
113
+ }
114
+ .deck__button:active:not(:disabled) {
115
+ transform: scale(var(--scale-medium, 0.97));
116
+ }
117
+ .deck__button[aria-pressed="true"] {
118
+ color: var(--deck-on-accent);
119
+ background: var(--deck-accent);
120
+ }
121
+ .deck__button:disabled {
122
+ opacity: 0.3;
123
+ cursor: default;
124
+ }
125
+ .deck__button:focus-visible {
126
+ outline: 2px solid var(--deck-accent);
127
+ outline-offset: 1px;
128
+ }
129
+ .deck__counter {
130
+ min-width: 52px;
131
+ font: 500 12px/1 var(--deck-font);
132
+ font-variant-numeric: tabular-nums;
133
+ text-align: center;
134
+ color: var(--deck-muted);
135
+ }
136
+ .deck__divider {
137
+ width: 1px;
138
+ height: 16px;
139
+ margin: 0 4px;
140
+ background: var(--deck-line);
141
+ }
116
142
 
117
- @media (hover: none) {
118
- .deck__controls {
119
- opacity: 0.9;
120
- }
121
- }
122
- /* On a small deck the controls shrink and drop the extras, so they don't cover the slide. */
123
- @container (max-width: 520px) {
124
- .deck__controls {
125
- right: 6px;
126
- bottom: 10px;
127
- padding: 2px;
128
- }
129
- .deck__button {
130
- width: 28px;
131
- height: 28px;
132
- }
133
- .deck__counter,
134
- .deck__divider {
135
- display: none;
136
- }
137
- }
143
+ @media (hover: none) {
144
+ .deck__controls {
145
+ opacity: 0.9;
146
+ }
147
+ }
148
+ /* On a small deck the controls shrink and drop the extras, so they don't cover the slide. */
149
+ @container (max-width: 520px) {
150
+ .deck__controls {
151
+ right: 6px;
152
+ bottom: 10px;
153
+ padding: 2px;
154
+ }
155
+ .deck__button {
156
+ width: 28px;
157
+ height: 28px;
158
+ }
159
+ .deck__counter,
160
+ .deck__divider {
161
+ display: none;
162
+ }
163
+ }
138
164
  </style>