@heyramzi/ui 3.1.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 (144) hide show
  1. package/dist/lib/sliding-pill.js +2 -2
  2. package/dist/record/measure-clamp.js +23 -0
  3. package/dist/shadcn/button-group/index.js +6 -0
  4. package/dist/shadcn/checkbox/checkbox-box.js +3 -0
  5. package/dist/shadcn/input-group/index.js +9 -0
  6. package/dist/shadcn/item/index.js +13 -0
  7. package/dist/shadcn/native-select/index.js +6 -0
  8. package/dist/shadcn/pagination/index.js +12 -0
  9. package/package.json +1 -1
  10. package/scripts/sync-shadcn.mjs +0 -5
  11. package/src/ai/generation-progress/GenerationProgress.svelte +14 -12
  12. package/src/canvas/pen/PenOverlay.svelte +1 -30
  13. package/src/canvas/screen/PartView.svelte +13 -8
  14. package/src/canvas/screen/ScreenBody.svelte +18 -11
  15. package/src/canvas/ui/BarTooltip.svelte +46 -0
  16. package/src/canvas/ui/BarTooltip.svelte.d.ts +17 -0
  17. package/src/canvas/ui/CanvasToolbar.svelte +170 -156
  18. package/src/canvas/ui/StylePanel.svelte +179 -102
  19. package/src/canvas/ui/canvas-ui.css +12 -76
  20. package/src/charts/dashboard/data-table.svelte +80 -80
  21. package/src/charts/dashboard/hint.svelte +34 -0
  22. package/src/charts/dashboard/hint.svelte.d.ts +10 -0
  23. package/src/charts/dashboard/rating-chip.svelte +4 -3
  24. package/src/charts/legend.css +0 -8
  25. package/src/charts/legend.svelte +26 -30
  26. package/src/components/copy/copy-button.svelte +10 -2
  27. package/src/components/copy/copy-button.test.ts +7 -0
  28. package/src/components/data-table/table-skeleton.svelte +15 -7
  29. package/src/components/data-table/table-skeleton.svelte.d.ts +4 -0
  30. package/src/components/docs/on-this-page.svelte +2 -2
  31. package/src/components/hold-to-confirm/hold-to-confirm.svelte +2 -1
  32. package/src/components/list-page/filter-item.svelte +20 -7
  33. package/src/components/list-page/filter-popover.svelte +41 -16
  34. package/src/components/list-page/filter-popover.svelte.d.ts +1 -1
  35. package/src/components/list-page/grouped-list.svelte +41 -23
  36. package/src/components/picker/picker.svelte +8 -3
  37. package/src/components/picker/picker.svelte.d.ts +2 -1
  38. package/src/components/segmented/segmented-filter.svelte +19 -10
  39. package/src/components/segmented/segmented-track.svelte +11 -3
  40. package/src/components/table-view/table-view.svelte +22 -6
  41. package/src/components/tags-input/tags-input.svelte +94 -77
  42. package/src/components/toolbar/toolbar.svelte +2 -1
  43. package/src/components/toolbar/toolbar.test.ts +5 -4
  44. package/src/components/work-parts/group-head.svelte +28 -9
  45. package/src/components/work-parts/group-head.svelte.d.ts +5 -2
  46. package/src/editor/editor-toolbar.svelte +223 -193
  47. package/src/editor/editor.svelte +56 -38
  48. package/src/editor/image-toolbar.svelte +99 -37
  49. package/src/editor/image-toolbar.svelte.d.ts +4 -5
  50. package/src/editor/url-dialog.svelte +96 -0
  51. package/src/editor/url-dialog.svelte.d.ts +15 -0
  52. package/src/effects/theme-toggle/ThemeToggle.css +8 -8
  53. package/src/effects/theme-toggle/ThemeToggle.svelte +20 -6
  54. package/src/inbox/thread-inbox.svelte +9 -1
  55. package/src/lib/live-region.svelte +12 -4
  56. package/src/lib/live-region.svelte.d.ts +5 -1
  57. package/src/lib/sliding-pill.ts +3 -2
  58. package/src/record/info-list.svelte +33 -59
  59. package/src/record/measure-clamp.ts +31 -0
  60. package/src/record/record-shell.svelte +38 -39
  61. package/src/record/record-timeline.svelte +10 -5
  62. package/src/record/steps-rail.svelte +50 -36
  63. package/src/record/where-we-are.svelte +5 -19
  64. package/src/shadcn/button-group/button-group-separator.svelte +23 -0
  65. package/src/shadcn/button-group/button-group-separator.svelte.d.ts +13 -0
  66. package/src/shadcn/button-group/button-group-text.svelte +28 -0
  67. package/src/shadcn/button-group/button-group-text.svelte.d.ts +11 -0
  68. package/src/shadcn/button-group/button-group.svelte +46 -0
  69. package/src/shadcn/button-group/button-group.svelte.d.ts +16 -0
  70. package/src/shadcn/button-group/index.ts +15 -0
  71. package/src/shadcn/checkbox/checkbox-box.ts +4 -0
  72. package/src/shadcn/checkbox/checkbox.svelte +2 -4
  73. package/src/shadcn/input-group/index.ts +22 -0
  74. package/src/shadcn/input-group/input-group-addon.svelte +51 -0
  75. package/src/shadcn/input-group/input-group-addon.svelte.d.ts +18 -0
  76. package/src/shadcn/input-group/input-group-button.svelte +49 -0
  77. package/src/shadcn/input-group/input-group-button.svelte.d.ts +18 -0
  78. package/src/shadcn/input-group/input-group-input.svelte +20 -0
  79. package/src/shadcn/input-group/input-group-input.svelte.d.ts +11 -0
  80. package/src/shadcn/input-group/input-group-text.svelte +19 -0
  81. package/src/shadcn/input-group/input-group-text.svelte.d.ts +5 -0
  82. package/src/shadcn/input-group/input-group-textarea.svelte +20 -0
  83. package/src/shadcn/input-group/input-group-textarea.svelte.d.ts +3 -0
  84. package/src/shadcn/input-group/input-group.svelte +24 -0
  85. package/src/shadcn/input-group/input-group.svelte.d.ts +5 -0
  86. package/src/shadcn/item/index.ts +34 -0
  87. package/src/shadcn/item/item-actions.svelte +20 -0
  88. package/src/shadcn/item/item-actions.svelte.d.ts +5 -0
  89. package/src/shadcn/item/item-content.svelte +23 -0
  90. package/src/shadcn/item/item-content.svelte.d.ts +5 -0
  91. package/src/shadcn/item/item-description.svelte +23 -0
  92. package/src/shadcn/item/item-description.svelte.d.ts +5 -0
  93. package/src/shadcn/item/item-footer.svelte +20 -0
  94. package/src/shadcn/item/item-footer.svelte.d.ts +5 -0
  95. package/src/shadcn/item/item-group.svelte +21 -0
  96. package/src/shadcn/item/item-group.svelte.d.ts +5 -0
  97. package/src/shadcn/item/item-header.svelte +20 -0
  98. package/src/shadcn/item/item-header.svelte.d.ts +5 -0
  99. package/src/shadcn/item/item-media.svelte +42 -0
  100. package/src/shadcn/item/item-media.svelte.d.ts +17 -0
  101. package/src/shadcn/item/item-separator.svelte +19 -0
  102. package/src/shadcn/item/item-separator.svelte.d.ts +13 -0
  103. package/src/shadcn/item/item-title.svelte +20 -0
  104. package/src/shadcn/item/item-title.svelte.d.ts +5 -0
  105. package/src/shadcn/item/item.svelte +61 -0
  106. package/src/shadcn/item/item.svelte.d.ts +28 -0
  107. package/src/shadcn/native-select/index.ts +13 -0
  108. package/src/shadcn/native-select/native-select-opt-group.svelte +20 -0
  109. package/src/shadcn/native-select/native-select-opt-group.svelte.d.ts +5 -0
  110. package/src/shadcn/native-select/native-select-option.svelte +20 -0
  111. package/src/shadcn/native-select/native-select-option.svelte.d.ts +5 -0
  112. package/src/shadcn/native-select/native-select.svelte +45 -0
  113. package/src/shadcn/native-select/native-select.svelte.d.ts +8 -0
  114. package/src/shadcn/pagination/index.ts +31 -0
  115. package/src/shadcn/pagination/pagination-content.svelte +20 -0
  116. package/src/shadcn/pagination/pagination-content.svelte.d.ts +5 -0
  117. package/src/shadcn/pagination/pagination-ellipsis.svelte +22 -0
  118. package/src/shadcn/pagination/pagination-ellipsis.svelte.d.ts +5 -0
  119. package/src/shadcn/pagination/pagination-item.svelte +14 -0
  120. package/src/shadcn/pagination/pagination-item.svelte.d.ts +5 -0
  121. package/src/shadcn/pagination/pagination-link.svelte +41 -0
  122. package/src/shadcn/pagination/pagination-link.svelte.d.ts +9 -0
  123. package/src/shadcn/pagination/pagination-next-button.svelte +34 -0
  124. package/src/shadcn/pagination/pagination-next-button.svelte.d.ts +4 -0
  125. package/src/shadcn/pagination/pagination-next.svelte +26 -0
  126. package/src/shadcn/pagination/pagination-next.svelte.d.ts +4 -0
  127. package/src/shadcn/pagination/pagination-prev-button.svelte +34 -0
  128. package/src/shadcn/pagination/pagination-prev-button.svelte.d.ts +4 -0
  129. package/src/shadcn/pagination/pagination-previous.svelte +30 -0
  130. package/src/shadcn/pagination/pagination-previous.svelte.d.ts +4 -0
  131. package/src/shadcn/pagination/pagination.svelte +27 -0
  132. package/src/shadcn/pagination/pagination.svelte.d.ts +4 -0
  133. package/src/slides/Controls.svelte +39 -36
  134. package/src/slides/Deck.svelte +11 -8
  135. package/src/thread/thread.svelte +15 -8
  136. package/src/work/detail/task-detail.svelte +1 -1
  137. package/src/work/gantt/gantt-task-row.svelte +3 -6
  138. package/src/work/inbox/inbox-card.svelte +7 -5
  139. package/src/work/inbox/inbox-trace.svelte +14 -10
  140. package/src/work/kanban-board.svelte +40 -25
  141. package/src/work/kanban-hidden-rail.svelte +67 -65
  142. package/src/work/task-list.svelte +145 -124
  143. package/src/work/task-list.svelte.test.ts +5 -2
  144. 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";
@@ -205,17 +206,19 @@
205
206
  </div>
206
207
 
207
208
  {#if progress}
208
- <div
209
- class="deck__progress deck__chrome"
210
- role="progressbar"
209
+ <Progress.Root
210
+ min={1}
211
+ max={deck.ordinal.of}
212
+ value={deck.ordinal.n}
211
213
  aria-label={deck.labels.progress}
212
- aria-valuemin="1"
213
- aria-valuemax={deck.ordinal.of}
214
- aria-valuenow={deck.ordinal.n}
215
214
  aria-valuetext={deck.labels.slide(deck.ordinal.n, deck.ordinal.of)}
216
215
  >
217
- <div class="deck__progress-fill" style:transform="scaleX({deck.progress})"></div>
218
- </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>
219
222
  {/if}
220
223
 
221
224
  {#if controls}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from "svelte";
3
+ import { Toggle } from "bits-ui";
3
4
  import { ArrowBendDownRight, Check, MapPin, PencilSimple, Trash } from "phosphor-svelte";
4
5
  import { cn } from "../lib/utils.js";
5
6
  import { focusAfterRender } from "../lib/focus.js";
@@ -338,14 +339,20 @@
338
339
  {labels.title}
339
340
  </h2>
340
341
  {#if resolved > 0}
341
- <Button
342
- variant="ghost"
343
- size="sm"
344
- aria-expanded={showResolved}
345
- onclick={() => (showResolved = !showResolved)}
346
- >
347
- {showResolved ? labels.hideResolved : fillCount(labels.showResolved, resolved)}
348
- </Button>
342
+ <!-- A filter on the list, so it reports pressed, not expanded. The wash it had as an
343
+ expanded ghost button moves to aria-pressed. -->
344
+ <Toggle.Root bind:pressed={showResolved}>
345
+ {#snippet child({ props })}
346
+ <Button
347
+ {...props}
348
+ variant="ghost"
349
+ size="sm"
350
+ class="aria-pressed:bg-foreground/6 aria-pressed:text-foreground"
351
+ >
352
+ {showResolved ? labels.hideResolved : fillCount(labels.showResolved, resolved)}
353
+ </Button>
354
+ {/snippet}
355
+ </Toggle.Root>
349
356
  {/if}
350
357
  </div>
351
358
 
@@ -159,7 +159,7 @@
159
159
  variant="text"
160
160
  onclick={startTitle}
161
161
  disabled={!onTitleChange}
162
- aria-label={labels.editTitle}
162
+ aria-label="{labels.editTitle}: {title}"
163
163
  class={cn(
164
164
  "group -mx-2 -my-1 px-2 py-1 text-2xl leading-tight font-semibold tracking-tight disabled:opacity-100",
165
165
  !onTitleChange && "hover:bg-transparent",
@@ -140,9 +140,8 @@
140
140
  </button>
141
141
  {:else if !row.own}
142
142
  <!-- A parent with no dates of its own: the span of what is below it. Not draggable. -->
143
- <div
144
- role="button"
145
- tabindex="0"
143
+ <button
144
+ type="button"
146
145
  aria-label="{title}, {describe(span)}"
147
146
  title="{title}, {describe(span)}"
148
147
  class={cn(
@@ -155,11 +154,9 @@
155
154
  style:width="{barWidth(span, layout)}px"
156
155
  style:height="{Math.max(layout.rowHeight - 24, 10)}px"
157
156
  onclick={() => onSelect?.(row.id)}
158
- onkeydown={(e) =>
159
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), onSelect?.(row.id))}
160
157
  onpointerenter={() => onHover(row.id, true)}
161
158
  onpointerleave={() => onHover(row.id, false)}
162
- ></div>
159
+ ></button>
163
160
  {:else}
164
161
  <GanttBar
165
162
  id={row.id}
@@ -28,6 +28,7 @@
28
28
  import InboxTraceView from "./inbox-trace.svelte";
29
29
  import { TagChip } from "../../components/chip/index.js";
30
30
  import { workLooks } from "../../components/work-parts/looks.js";
31
+ import { measureClamp } from "../../record/measure-clamp.js";
31
32
  import { FolderSimple } from "phosphor-svelte";
32
33
  import { Copied } from "../../components/copy/copied.svelte.js";
33
34
  import type { InboxDraftEdits, InboxItem, InboxVerdict } from "./inbox-types.js";
@@ -68,10 +69,7 @@
68
69
  // for a link the host already shows.
69
70
  let hasTrace = $derived(item.trace.evidence.length > 0 || !!why);
70
71
  let expanded = $state(false);
71
- let longCommand = $derived(
72
- !!facts.command &&
73
- (facts.command.text.length > 240 || facts.command.text.split("\n").length > 3),
74
- );
72
+ let commandCut = $state(false);
75
73
 
76
74
  let pickedDraft = $state<string>();
77
75
  let edits = $state<InboxDraftEdits>({});
@@ -210,13 +208,17 @@
210
208
  <!-- The padding sits on a wrapper: on the clamped box itself, the 4th line showed through it. -->
211
209
  <div class={cn(workLooks.inset, "w-full px-2.5 py-2")}>
212
210
  <pre
211
+ {@attach measureClamp(
212
+ () => expanded,
213
+ (cut) => (commandCut = cut),
214
+ )}
213
215
  class={cn(
214
216
  "text-foreground font-mono text-xs leading-5 break-words whitespace-pre-wrap",
215
217
  !expanded && "line-clamp-3",
216
218
  )}><span class="text-muted-foreground select-none"
217
219
  >{facts.command.tool} </span>{facts.command.text}</pre>
218
220
  </div>
219
- {#if longCommand}
221
+ {#if commandCut || expanded}
220
222
  <button
221
223
  type="button"
222
224
  class="text-muted-foreground hover:text-foreground text-xs underline-offset-2 hover:underline"