@heyramzi/ui 3.0.0 → 3.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 (160) hide show
  1. package/dist/charts/dual-axis.js +38 -0
  2. package/dist/lib/sliding-pill.js +2 -2
  3. package/dist/record/measure-clamp.js +23 -0
  4. package/dist/shadcn/button-group/index.js +6 -0
  5. package/dist/shadcn/checkbox/checkbox-box.js +3 -0
  6. package/dist/shadcn/input-group/index.js +9 -0
  7. package/dist/shadcn/item/index.js +13 -0
  8. package/dist/shadcn/native-select/index.js +6 -0
  9. package/dist/shadcn/pagination/index.js +12 -0
  10. package/dist/slides/deck-controller.svelte.js +62 -15
  11. package/dist/slides/layout.js +3 -2
  12. package/package.json +9 -2
  13. package/scripts/svelte-dts.mjs +3 -0
  14. package/scripts/sync-shadcn.mjs +0 -5
  15. package/src/ai/generation-progress/GenerationProgress.svelte +14 -12
  16. package/src/canvas/pen/PenOverlay.svelte +1 -30
  17. package/src/canvas/screen/PartView.svelte +13 -8
  18. package/src/canvas/screen/ScreenBody.svelte +18 -11
  19. package/src/canvas/ui/BarTooltip.svelte +46 -0
  20. package/src/canvas/ui/BarTooltip.svelte.d.ts +17 -0
  21. package/src/canvas/ui/CanvasToolbar.svelte +170 -156
  22. package/src/canvas/ui/StylePanel.svelte +179 -102
  23. package/src/canvas/ui/canvas-ui.css +12 -76
  24. package/src/charts/area-chart.css +6 -0
  25. package/src/charts/area-chart.svelte +115 -17
  26. package/src/charts/area-chart.svelte.d.ts +11 -2
  27. package/src/charts/chart-tokens.css +4 -3
  28. package/src/charts/dashboard/data-table.svelte +80 -80
  29. package/src/charts/dashboard/hint.svelte +34 -0
  30. package/src/charts/dashboard/hint.svelte.d.ts +10 -0
  31. package/src/charts/dashboard/rating-chip.svelte +4 -3
  32. package/src/charts/dual-axis.test.ts +40 -0
  33. package/src/charts/dual-axis.ts +43 -0
  34. package/src/charts/legend.css +0 -8
  35. package/src/charts/legend.svelte +26 -30
  36. package/src/components/copy/copy-button.svelte +10 -2
  37. package/src/components/copy/copy-button.test.ts +7 -0
  38. package/src/components/data-table/table-skeleton.svelte +15 -7
  39. package/src/components/data-table/table-skeleton.svelte.d.ts +4 -0
  40. package/src/components/docs/on-this-page.svelte +2 -2
  41. package/src/components/hold-to-confirm/hold-to-confirm.svelte +2 -1
  42. package/src/components/list-page/filter-item.svelte +20 -7
  43. package/src/components/list-page/filter-popover.svelte +41 -16
  44. package/src/components/list-page/filter-popover.svelte.d.ts +1 -1
  45. package/src/components/list-page/grouped-list.svelte +41 -23
  46. package/src/components/picker/picker.svelte +8 -3
  47. package/src/components/picker/picker.svelte.d.ts +2 -1
  48. package/src/components/segmented/segmented-filter.svelte +19 -10
  49. package/src/components/segmented/segmented-track.svelte +11 -3
  50. package/src/components/table-view/table-view.svelte +22 -6
  51. package/src/components/tags-input/tags-input.svelte +94 -77
  52. package/src/components/toolbar/toolbar.svelte +2 -1
  53. package/src/components/toolbar/toolbar.test.ts +5 -4
  54. package/src/components/work-parts/group-head.svelte +28 -9
  55. package/src/components/work-parts/group-head.svelte.d.ts +5 -2
  56. package/src/editor/editor-toolbar.svelte +231 -193
  57. package/src/editor/editor.svelte +57 -39
  58. package/src/editor/image-toolbar.svelte +99 -37
  59. package/src/editor/image-toolbar.svelte.d.ts +4 -5
  60. package/src/editor/url-dialog.svelte +96 -0
  61. package/src/editor/url-dialog.svelte.d.ts +15 -0
  62. package/src/effects/theme-toggle/ThemeToggle.css +8 -8
  63. package/src/effects/theme-toggle/ThemeToggle.svelte +20 -6
  64. package/src/inbox/thread-inbox.svelte +9 -1
  65. package/src/lib/live-region.svelte +12 -4
  66. package/src/lib/live-region.svelte.d.ts +5 -1
  67. package/src/lib/sliding-pill.ts +3 -2
  68. package/src/record/info-list.svelte +33 -59
  69. package/src/record/measure-clamp.ts +31 -0
  70. package/src/record/record-shell.svelte +38 -39
  71. package/src/record/record-timeline.svelte +10 -5
  72. package/src/record/steps-rail.svelte +50 -36
  73. package/src/record/where-we-are.svelte +5 -19
  74. package/src/shadcn/button-group/button-group-separator.svelte +23 -0
  75. package/src/shadcn/button-group/button-group-separator.svelte.d.ts +13 -0
  76. package/src/shadcn/button-group/button-group-text.svelte +28 -0
  77. package/src/shadcn/button-group/button-group-text.svelte.d.ts +11 -0
  78. package/src/shadcn/button-group/button-group.svelte +46 -0
  79. package/src/shadcn/button-group/button-group.svelte.d.ts +16 -0
  80. package/src/shadcn/button-group/index.ts +15 -0
  81. package/src/shadcn/checkbox/checkbox-box.ts +4 -0
  82. package/src/shadcn/checkbox/checkbox.svelte +2 -4
  83. package/src/shadcn/input-group/index.ts +22 -0
  84. package/src/shadcn/input-group/input-group-addon.svelte +51 -0
  85. package/src/shadcn/input-group/input-group-addon.svelte.d.ts +18 -0
  86. package/src/shadcn/input-group/input-group-button.svelte +49 -0
  87. package/src/shadcn/input-group/input-group-button.svelte.d.ts +18 -0
  88. package/src/shadcn/input-group/input-group-input.svelte +20 -0
  89. package/src/shadcn/input-group/input-group-input.svelte.d.ts +11 -0
  90. package/src/shadcn/input-group/input-group-text.svelte +19 -0
  91. package/src/shadcn/input-group/input-group-text.svelte.d.ts +5 -0
  92. package/src/shadcn/input-group/input-group-textarea.svelte +20 -0
  93. package/src/shadcn/input-group/input-group-textarea.svelte.d.ts +3 -0
  94. package/src/shadcn/input-group/input-group.svelte +24 -0
  95. package/src/shadcn/input-group/input-group.svelte.d.ts +5 -0
  96. package/src/shadcn/item/index.ts +34 -0
  97. package/src/shadcn/item/item-actions.svelte +20 -0
  98. package/src/shadcn/item/item-actions.svelte.d.ts +5 -0
  99. package/src/shadcn/item/item-content.svelte +23 -0
  100. package/src/shadcn/item/item-content.svelte.d.ts +5 -0
  101. package/src/shadcn/item/item-description.svelte +23 -0
  102. package/src/shadcn/item/item-description.svelte.d.ts +5 -0
  103. package/src/shadcn/item/item-footer.svelte +20 -0
  104. package/src/shadcn/item/item-footer.svelte.d.ts +5 -0
  105. package/src/shadcn/item/item-group.svelte +21 -0
  106. package/src/shadcn/item/item-group.svelte.d.ts +5 -0
  107. package/src/shadcn/item/item-header.svelte +20 -0
  108. package/src/shadcn/item/item-header.svelte.d.ts +5 -0
  109. package/src/shadcn/item/item-media.svelte +42 -0
  110. package/src/shadcn/item/item-media.svelte.d.ts +17 -0
  111. package/src/shadcn/item/item-separator.svelte +19 -0
  112. package/src/shadcn/item/item-separator.svelte.d.ts +13 -0
  113. package/src/shadcn/item/item-title.svelte +20 -0
  114. package/src/shadcn/item/item-title.svelte.d.ts +5 -0
  115. package/src/shadcn/item/item.svelte +61 -0
  116. package/src/shadcn/item/item.svelte.d.ts +28 -0
  117. package/src/shadcn/native-select/index.ts +13 -0
  118. package/src/shadcn/native-select/native-select-opt-group.svelte +20 -0
  119. package/src/shadcn/native-select/native-select-opt-group.svelte.d.ts +5 -0
  120. package/src/shadcn/native-select/native-select-option.svelte +20 -0
  121. package/src/shadcn/native-select/native-select-option.svelte.d.ts +5 -0
  122. package/src/shadcn/native-select/native-select.svelte +45 -0
  123. package/src/shadcn/native-select/native-select.svelte.d.ts +8 -0
  124. package/src/shadcn/pagination/index.ts +31 -0
  125. package/src/shadcn/pagination/pagination-content.svelte +20 -0
  126. package/src/shadcn/pagination/pagination-content.svelte.d.ts +5 -0
  127. package/src/shadcn/pagination/pagination-ellipsis.svelte +22 -0
  128. package/src/shadcn/pagination/pagination-ellipsis.svelte.d.ts +5 -0
  129. package/src/shadcn/pagination/pagination-item.svelte +14 -0
  130. package/src/shadcn/pagination/pagination-item.svelte.d.ts +5 -0
  131. package/src/shadcn/pagination/pagination-link.svelte +41 -0
  132. package/src/shadcn/pagination/pagination-link.svelte.d.ts +9 -0
  133. package/src/shadcn/pagination/pagination-next-button.svelte +34 -0
  134. package/src/shadcn/pagination/pagination-next-button.svelte.d.ts +4 -0
  135. package/src/shadcn/pagination/pagination-next.svelte +26 -0
  136. package/src/shadcn/pagination/pagination-next.svelte.d.ts +4 -0
  137. package/src/shadcn/pagination/pagination-prev-button.svelte +34 -0
  138. package/src/shadcn/pagination/pagination-prev-button.svelte.d.ts +4 -0
  139. package/src/shadcn/pagination/pagination-previous.svelte +30 -0
  140. package/src/shadcn/pagination/pagination-previous.svelte.d.ts +4 -0
  141. package/src/shadcn/pagination/pagination.svelte +27 -0
  142. package/src/shadcn/pagination/pagination.svelte.d.ts +4 -0
  143. package/src/slides/Controls.svelte +39 -36
  144. package/src/slides/Deck.svelte +23 -10
  145. package/src/slides/Overview.svelte +10 -4
  146. package/src/slides/README.md +1 -1
  147. package/src/slides/Slide.svelte +17 -11
  148. package/src/slides/deck-controller.svelte.ts +62 -16
  149. package/src/slides/layout.ts +3 -2
  150. package/src/slides/theme.css +34 -5
  151. package/src/thread/thread.svelte +15 -8
  152. package/src/work/detail/task-detail.svelte +1 -1
  153. package/src/work/gantt/gantt-task-row.svelte +3 -6
  154. package/src/work/inbox/inbox-card.svelte +7 -5
  155. package/src/work/inbox/inbox-trace.svelte +14 -10
  156. package/src/work/kanban-board.svelte +40 -25
  157. package/src/work/kanban-hidden-rail.svelte +67 -65
  158. package/src/work/task-list.svelte +145 -124
  159. package/src/work/task-list.svelte.test.ts +5 -2
  160. package/src/work/time/time-tracker.svelte +35 -10
@@ -0,0 +1,45 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../lib/utils.js";
3
+ import type { HTMLSelectAttributes } from "svelte/elements";
4
+ import { CaretDown } from "phosphor-svelte";
5
+
6
+ type NativeSelectProps = Omit<WithElementRef<HTMLSelectAttributes, HTMLSelectElement>, "size"> & {
7
+ size?: "sm" | "default";
8
+ };
9
+
10
+ let {
11
+ ref = $bindable(null),
12
+ value = $bindable(),
13
+ class: className,
14
+ size = "default",
15
+ children,
16
+ ...restProps
17
+ }: NativeSelectProps = $props();
18
+ </script>
19
+
20
+ <div
21
+ class={cn(
22
+ "group/native-select relative w-fit has-[select:disabled]:opacity-50",
23
+ className,
24
+ )}
25
+ data-slot="native-select-wrapper"
26
+ data-size={size}
27
+ >
28
+ <!-- The kit's Select trigger sizes: 32px, 28px small, so the two read as one control. -->
29
+ <select
30
+ bind:value
31
+ bind:this={ref}
32
+ data-slot="native-select"
33
+ data-size={size}
34
+ class="border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 enabled:hover:border-foreground/20 focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-8 w-full min-w-0 appearance-none rounded-lg border bg-transparent py-1 pr-8 pl-2.5 text-sm shadow-field transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] select-none aria-invalid:ring-3 data-[size=sm]:h-7 data-[size=sm]:text-[0.8rem] outline-none disabled:pointer-events-none disabled:cursor-not-allowed"
35
+ {...restProps}
36
+ >
37
+ {@render children?.()}
38
+ </select>
39
+ <CaretDown
40
+ size={16}
41
+ aria-hidden="true"
42
+ data-slot="native-select-icon"
43
+ class="text-muted-foreground pointer-events-none absolute top-1/2 right-2.5 -translate-y-1/2 select-none"
44
+ />
45
+ </div>
@@ -0,0 +1,8 @@
1
+ import { type WithElementRef } from "../../lib/utils.js";
2
+ import type { HTMLSelectAttributes } from "svelte/elements";
3
+ type NativeSelectProps = Omit<WithElementRef<HTMLSelectAttributes, HTMLSelectElement>, "size"> & {
4
+ size?: "sm" | "default";
5
+ };
6
+ declare const $$Component: import("svelte").Component<NativeSelectProps, {}, "value" | "ref">;
7
+ type $$Component = ReturnType<typeof $$Component>;
8
+ export default $$Component;
@@ -0,0 +1,31 @@
1
+ import Content from "./pagination-content.svelte";
2
+ import Ellipsis from "./pagination-ellipsis.svelte";
3
+ import Item from "./pagination-item.svelte";
4
+ import Link from "./pagination-link.svelte";
5
+ import NextButton from "./pagination-next-button.svelte";
6
+ import Next from "./pagination-next.svelte";
7
+ import PrevButton from "./pagination-prev-button.svelte";
8
+ import Previous from "./pagination-previous.svelte";
9
+ import Root from "./pagination.svelte";
10
+
11
+ export {
12
+ Root,
13
+ Content,
14
+ Item,
15
+ Link,
16
+ PrevButton, // old
17
+ NextButton, // old
18
+ Ellipsis,
19
+ Previous,
20
+ Next,
21
+ //
22
+ Root as Pagination,
23
+ Content as PaginationContent,
24
+ Item as PaginationItem,
25
+ Link as PaginationLink,
26
+ PrevButton as PaginationPrevButton, // old
27
+ NextButton as PaginationNextButton, // old
28
+ Ellipsis as PaginationEllipsis,
29
+ Previous as PaginationPrevious,
30
+ Next as PaginationNext,
31
+ };
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../lib/utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLUListElement>> = $props();
11
+ </script>
12
+
13
+ <ul
14
+ bind:this={ref}
15
+ data-slot="pagination-content"
16
+ class={cn("gap-1 flex items-center", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </ul>
@@ -0,0 +1,5 @@
1
+ import { type WithElementRef } from "../../lib/utils.js";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ declare const $$Component: import("svelte").Component<WithElementRef<HTMLAttributes<HTMLUListElement>>, {}, "ref">;
4
+ type $$Component = ReturnType<typeof $$Component>;
5
+ export default $$Component;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import { DotsThree } from "phosphor-svelte";
3
+ import { cn, type WithElementRef, type WithoutChildren } from "../../lib/utils.js";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildren<WithElementRef<HTMLAttributes<HTMLSpanElement>>> = $props();
11
+ </script>
12
+
13
+ <span
14
+ bind:this={ref}
15
+ aria-hidden="true"
16
+ data-slot="pagination-ellipsis"
17
+ class={cn("size-9 items-center justify-center [&_svg:not([class*='size-'])]:size-4 flex items-center justify-center", className)}
18
+ {...restProps}
19
+ >
20
+ <DotsThree aria-hidden="true" />
21
+ <span class="sr-only">More pages</span>
22
+ </span>
@@ -0,0 +1,5 @@
1
+ import { type WithElementRef } from "../../lib/utils.js";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ declare const $$Component: import("svelte").Component<Omit<WithElementRef<HTMLAttributes<HTMLSpanElement>>, "children">, {}, "ref">;
4
+ type $$Component = ReturnType<typeof $$Component>;
5
+ export default $$Component;
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import type { WithElementRef } from "../../lib/utils.js";
3
+ import type { HTMLLiAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ children,
8
+ ...restProps
9
+ }: WithElementRef<HTMLLiAttributes> = $props();
10
+ </script>
11
+
12
+ <li bind:this={ref} data-slot="pagination-item" {...restProps}>
13
+ {@render children?.()}
14
+ </li>
@@ -0,0 +1,5 @@
1
+ import type { WithElementRef } from "../../lib/utils.js";
2
+ import type { HTMLLiAttributes } from "svelte/elements";
3
+ declare const $$Component: import("svelte").Component<WithElementRef<HTMLLiAttributes>, {}, "ref">;
4
+ type $$Component = ReturnType<typeof $$Component>;
5
+ export default $$Component;
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { buttonVariants, type ButtonSize } from "../button/index.js";
4
+ import { cn } from "../../lib/utils.js";
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ size = "default",
9
+ isActive,
10
+ page,
11
+ children,
12
+ ...restProps
13
+ }: PaginationPrimitive.PageProps & {
14
+ size?: ButtonSize;
15
+ isActive: boolean;
16
+ } = $props();
17
+ </script>
18
+
19
+ {#snippet Fallback()}
20
+ {page.value}
21
+ {/snippet}
22
+
23
+ <PaginationPrimitive.Page
24
+ bind:ref
25
+ {page}
26
+ aria-current={isActive ? "page" : undefined}
27
+ data-slot="pagination-link"
28
+ data-active={isActive}
29
+ data-size={size}
30
+ class={cn(
31
+ buttonVariants({ size, icon: true, variant: isActive ? "outline" : "ghost" }),
32
+ className
33
+ )}
34
+ {...restProps}
35
+ >
36
+ {#if children}
37
+ {@render children?.()}
38
+ {:else}
39
+ {@render Fallback()}
40
+ {/if}
41
+ </PaginationPrimitive.Page>
@@ -0,0 +1,9 @@
1
+ import { Pagination as PaginationPrimitive } from "bits-ui";
2
+ import { type ButtonSize } from "../button/index.js";
3
+ type $$ComponentProps = PaginationPrimitive.PageProps & {
4
+ size?: ButtonSize;
5
+ isActive: boolean;
6
+ };
7
+ declare const $$Component: import("svelte").Component<$$ComponentProps, {}, "ref">;
8
+ type $$Component = ReturnType<typeof $$Component>;
9
+ export default $$Component;
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { CaretRight } from "phosphor-svelte";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { buttonVariants } from "../button/index.js";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ children,
11
+ ...restProps
12
+ }: PaginationPrimitive.NextButtonProps = $props();
13
+ </script>
14
+
15
+ {#snippet Fallback()}
16
+ <span>Next</span>
17
+ <CaretRight
18
+ aria-hidden="true"
19
+ class={cn("cn-rtl-flip size-4", className)}
20
+ />
21
+ {/snippet}
22
+
23
+ <PaginationPrimitive.NextButton
24
+ bind:ref
25
+ aria-label="Go to next page"
26
+ class={cn(buttonVariants({ variant: "ghost" }), "pr-2!", className)}
27
+ {...restProps}
28
+ >
29
+ {#if children}
30
+ {@render children?.()}
31
+ {:else}
32
+ {@render Fallback()}
33
+ {/if}
34
+ </PaginationPrimitive.NextButton>
@@ -0,0 +1,4 @@
1
+ import { Pagination as PaginationPrimitive } from "bits-ui";
2
+ declare const $$Component: import("svelte").Component<PaginationPrimitive.NextButtonProps, {}, "ref">;
3
+ type $$Component = ReturnType<typeof $$Component>;
4
+ export default $$Component;
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { CaretRight } from "phosphor-svelte";
4
+ import { buttonVariants } from "../button/index.js";
5
+ import { cn } from "../../lib/utils.js";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ ...restProps
11
+ }: PaginationPrimitive.NextButtonProps = $props();
12
+ </script>
13
+
14
+ <PaginationPrimitive.NextButton
15
+ bind:ref
16
+ aria-label="Go to next page"
17
+ class={cn(buttonVariants({ variant: "ghost", size: "default" }), "pr-2!", className)}
18
+ {...restProps}
19
+ >
20
+ <span class="hidden sm:block">Next</span>
21
+ <CaretRight
22
+ aria-hidden="true"
23
+ data-icon="inline-end"
24
+ class="cn-rtl-flip"
25
+ />
26
+ </PaginationPrimitive.NextButton>
@@ -0,0 +1,4 @@
1
+ import { Pagination as PaginationPrimitive } from "bits-ui";
2
+ declare const $$Component: import("svelte").Component<PaginationPrimitive.NextButtonProps, {}, "ref">;
3
+ type $$Component = ReturnType<typeof $$Component>;
4
+ export default $$Component;
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { CaretLeft } from "phosphor-svelte";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { buttonVariants } from "../button/index.js";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ children,
11
+ ...restProps
12
+ }: PaginationPrimitive.PrevButtonProps = $props();
13
+ </script>
14
+
15
+ {#snippet Fallback()}
16
+ <CaretLeft
17
+ aria-hidden="true"
18
+ class={cn("cn-rtl-flip size-4", className)}
19
+ />
20
+ <span>Previous</span>
21
+ {/snippet}
22
+
23
+ <PaginationPrimitive.PrevButton
24
+ bind:ref
25
+ aria-label="Go to previous page"
26
+ class={cn(buttonVariants({ variant: "ghost" }), "pl-2!", className)}
27
+ {...restProps}
28
+ >
29
+ {#if children}
30
+ {@render children?.()}
31
+ {:else}
32
+ {@render Fallback()}
33
+ {/if}
34
+ </PaginationPrimitive.PrevButton>
@@ -0,0 +1,4 @@
1
+ import { Pagination as PaginationPrimitive } from "bits-ui";
2
+ declare const $$Component: import("svelte").Component<PaginationPrimitive.PrevButtonProps, {}, "ref">;
3
+ type $$Component = ReturnType<typeof $$Component>;
4
+ export default $$Component;
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { CaretLeft } from "phosphor-svelte";
4
+ import { buttonVariants } from "../button/index.js";
5
+ import { cn } from "../../lib/utils.js";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ ...restProps
11
+ }: PaginationPrimitive.PrevButtonProps = $props();
12
+ </script>
13
+
14
+ <PaginationPrimitive.PrevButton
15
+ bind:ref
16
+ aria-label="Go to previous page"
17
+ class={cn(
18
+ buttonVariants({ variant: "ghost", size: "default" }),
19
+ "pl-2!",
20
+ className
21
+ )}
22
+ {...restProps}
23
+ >
24
+ <CaretLeft
25
+ aria-hidden="true"
26
+ data-icon="inline-start"
27
+ class="cn-rtl-flip"
28
+ />
29
+ <span class="hidden sm:block">Previous</span>
30
+ </PaginationPrimitive.PrevButton>
@@ -0,0 +1,4 @@
1
+ import { Pagination as PaginationPrimitive } from "bits-ui";
2
+ declare const $$Component: import("svelte").Component<PaginationPrimitive.PrevButtonProps, {}, "ref">;
3
+ type $$Component = ReturnType<typeof $$Component>;
4
+ export default $$Component;
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { cn } from "../../lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ count = 0,
9
+ perPage = 10,
10
+ page = $bindable(1),
11
+ siblingCount = 1,
12
+ ...restProps
13
+ }: PaginationPrimitive.RootProps = $props();
14
+ </script>
15
+
16
+ <PaginationPrimitive.Root
17
+ bind:ref
18
+ bind:page
19
+ role="navigation"
20
+ aria-label="pagination"
21
+ data-slot="pagination"
22
+ {count}
23
+ {perPage}
24
+ {siblingCount}
25
+ class={cn("mx-auto flex w-full justify-center", className)}
26
+ {...restProps}
27
+ />
@@ -0,0 +1,4 @@
1
+ import { Pagination as PaginationPrimitive } from "bits-ui";
2
+ declare const $$Component: import("svelte").Component<PaginationPrimitive.RootProps, {}, "ref" | "page">;
3
+ type $$Component = ReturnType<typeof $$Component>;
4
+ export default $$Component;
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { Toolbar } from "bits-ui";
2
3
  import type { DeckController } from "./deck-controller.svelte.js";
3
4
 
4
5
  interface Props {
@@ -26,44 +27,46 @@
26
27
  disabled = false,
27
28
  pressed?: boolean,
28
29
  )}
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>
30
+ <Toolbar.Button {onclick} {disabled} aria-label={label} aria-pressed={pressed}>
31
+ {#snippet child({ props })}
32
+ <button {...props} class="deck__button">
33
+ <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
34
+ <path
35
+ d={icons[icon]}
36
+ fill="none"
37
+ stroke="currentColor"
38
+ stroke-width="1.75"
39
+ stroke-linecap="round"
40
+ stroke-linejoin="round"
41
+ />
42
+ </svg>
43
+ </button>
44
+ {/snippet}
45
+ </Toolbar.Button>
48
46
  {/snippet}
49
47
 
50
- <div class="deck__controls deck__chrome">
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)}
66
- </div>
48
+ <!-- The arrows are the toolbar's while a control has focus, so they move along it, not the deck. -->
49
+ <Toolbar.Root>
50
+ {#snippet child({ props })}
51
+ <div {...props} class="deck__controls deck__chrome">
52
+ {@render button("prev", deck.labels.previous, () => deck.prev(), deck.atStart)}
53
+ <span class="deck__counter" aria-hidden="true">{deck.ordinal.n} / {deck.ordinal.of}</span>
54
+ {@render button("next", deck.labels.next, () => deck.next(), deck.atEnd)}
55
+ <span class="deck__divider" aria-hidden="true"></span>
56
+ {@render button(
57
+ "overview",
58
+ deck.labels.overview,
59
+ () => deck.toggleOverview(),
60
+ false,
61
+ deck.overview,
62
+ )}
63
+ {#if onPresenter}
64
+ {@render button("presenter", deck.labels.presenter, onPresenter)}
65
+ {/if}
66
+ {@render button("fullscreen", deck.labels.fullscreen, onFullscreen)}
67
+ </div>
68
+ {/snippet}
69
+ </Toolbar.Root>
67
70
 
68
71
  <style>
69
72
  @layer theme, base, components, utilities;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import "./theme.css";
3
+ import { Progress } from "bits-ui";
3
4
  import { flushSync, onMount, setContext, untrack } from "svelte";
4
5
  import { attachBridge, attachChannel, attachUrlSync } from "./bridges.js";
5
6
  import Controls from "./Controls.svelte";
@@ -72,6 +73,7 @@
72
73
  return labels;
73
74
  },
74
75
  transition: viewTransition,
76
+ zoomMs,
75
77
  });
76
78
  controller = deck;
77
79
  setContext(DECK_KEY, deck);
@@ -88,6 +90,14 @@
88
90
  run.finished.finally(() => delete document.documentElement.dataset.deckVt);
89
91
  }
90
92
 
93
+ /* The overview zoom's length, read from the CSS so it follows the token. 0 under reduced motion. */
94
+ function zoomMs() {
95
+ if (!root || matchMedia("(prefers-reduced-motion: reduce)").matches) return 0;
96
+ const value = getComputedStyle(root).getPropertyValue("--deck-t-zoom").trim();
97
+ const ms = Number.parseFloat(value) * (value.endsWith("ms") ? 1 : 1000);
98
+ return Number.isFinite(ms) ? ms : 0;
99
+ }
100
+
91
101
  onMount(() => deck.mount());
92
102
 
93
103
  $effect(() => deck.listen((position) => onIndexChange?.(position.index, position.step)));
@@ -175,7 +185,7 @@
175
185
  data-deck={id}
176
186
  data-view={deck.view}
177
187
  data-transition={transition}
178
- data-morphing={deck.morphing || undefined}
188
+ data-zoom={deck.zoom ? (deck.zoom.running ? "run" : "hold") : undefined}
179
189
  {onpointerdown}
180
190
  {onpointerup}
181
191
  >
@@ -185,7 +195,8 @@
185
195
  {:else}
186
196
  {@render children?.()}
187
197
  {/if}
188
- {#if deck.overview}
198
+ <!-- The tiles mount once the camera starts pulling back, and fade in as it lands. -->
199
+ {#if deck.overview && !deck.zoom?.framed}
189
200
  <Overview {deck} returnFocus={root} />
190
201
  {/if}
191
202
  </div>
@@ -195,17 +206,19 @@
195
206
  </div>
196
207
 
197
208
  {#if progress}
198
- <div
199
- class="deck__progress deck__chrome"
200
- role="progressbar"
209
+ <Progress.Root
210
+ min={1}
211
+ max={deck.ordinal.of}
212
+ value={deck.ordinal.n}
201
213
  aria-label={deck.labels.progress}
202
- aria-valuemin="1"
203
- aria-valuemax={deck.ordinal.of}
204
- aria-valuenow={deck.ordinal.n}
205
214
  aria-valuetext={deck.labels.slide(deck.ordinal.n, deck.ordinal.of)}
206
215
  >
207
- <div class="deck__progress-fill" style:transform="scaleX({deck.progress})"></div>
208
- </div>
216
+ {#snippet child({ props })}
217
+ <div {...props} class="deck__progress deck__chrome">
218
+ <div class="deck__progress-fill" style:transform="scaleX({deck.progress})"></div>
219
+ </div>
220
+ {/snippet}
221
+ </Progress.Root>
209
222
  {/if}
210
223
 
211
224
  {#if controls}
@@ -60,7 +60,7 @@
60
60
  padding: 0;
61
61
  list-style: none;
62
62
  /* The ring and number appear once the thumbnails have landed. */
63
- animation: tiles-in var(--deck-t-quick) linear var(--deck-t-morph) backwards;
63
+ animation: tiles-in var(--deck-t-quick) linear var(--deck-t-zoom) backwards;
64
64
  }
65
65
  @media (prefers-reduced-motion: reduce) {
66
66
  .deck__tiles {
@@ -94,14 +94,20 @@
94
94
  .deck__tile:focus-visible {
95
95
  outline-color: var(--deck-fg);
96
96
  }
97
+ /*
98
+ * The number sits in the gap under its thumbnail, never on it: straddling the edge put
99
+ * half of it under the slide. 7px clears the 5px ring, and 7 + 18 fits the grid's 26px gap.
100
+ */
97
101
  .deck__tile-n {
98
102
  position: absolute;
99
- bottom: -12px;
103
+ top: calc(100% + 7px);
100
104
  left: 50%;
101
- min-width: 22px;
105
+ z-index: 1;
106
+ box-sizing: border-box;
107
+ min-width: 24px;
102
108
  transform: translateX(-50%);
103
109
  padding: 3px 6px;
104
- font: 600 11px/1 var(--deck-font);
110
+ font: 600 12px/1 var(--deck-font);
105
111
  font-variant-numeric: tabular-nums;
106
112
  text-align: center;
107
113
  color: var(--deck-fg);
@@ -43,7 +43,7 @@ Keys: arrows, Space (Shift+Space back), PageUp/PageDown, Home/End, `O` overview,
43
43
 
44
44
  ## Theming
45
45
 
46
- Set variables on `.deck`: `--deck-bg`, `--deck-fg`, `--deck-accent`, `--deck-on-accent`, `--deck-font`, `--deck-font-display`, `--deck-pad`, `--deck-text-*` (design px) and the timing tokens `--deck-t-slide`, `--deck-t-morph`, `--deck-stagger`, `--deck-ease`. They default to the `@heyramzi/ui` motion tokens when present. Motion is transform and opacity only and stops under `prefers-reduced-motion`.
46
+ Set variables on `.deck`: `--deck-bg`, `--deck-fg`, `--deck-accent`, `--deck-on-accent`, `--deck-font`, `--deck-font-display`, `--deck-pad`, `--deck-text-*` (design px) and the timing tokens `--deck-t-slide`, `--deck-t-morph`, `--deck-t-zoom` (the overview zoom), `--deck-stagger`, `--deck-ease`. They default to the `@heyramzi/ui` motion tokens when present. `--deck-accent` and `--deck-on-accent` follow the app's `--primary` and `--primary-foreground`, and fall back to the deck's ink. Motion is transform and opacity only and stops under `prefers-reduced-motion`.
47
47
 
48
48
  ## Data-driven decks
49
49