@heyramzi/ui 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/sliding-pill.js +2 -2
- package/dist/record/measure-clamp.js +23 -0
- package/dist/shadcn/button-group/index.js +6 -0
- package/dist/shadcn/checkbox/checkbox-box.js +3 -0
- package/dist/shadcn/drawer/index.js +14 -0
- package/dist/shadcn/input-group/index.js +9 -0
- package/dist/shadcn/item/index.js +13 -0
- package/dist/shadcn/native-select/index.js +6 -0
- package/dist/shadcn/pagination/index.js +12 -0
- package/package.json +7 -2
- package/scripts/sync-shadcn.mjs +0 -6
- package/src/ai/generation-progress/GenerationProgress.svelte +14 -12
- package/src/canvas/pen/PenOverlay.svelte +1 -30
- package/src/canvas/screen/PartView.svelte +13 -8
- package/src/canvas/screen/ScreenBody.svelte +18 -11
- package/src/canvas/ui/BarTooltip.svelte +46 -0
- package/src/canvas/ui/BarTooltip.svelte.d.ts +17 -0
- package/src/canvas/ui/CanvasToolbar.svelte +170 -156
- package/src/canvas/ui/StylePanel.svelte +179 -102
- package/src/canvas/ui/canvas-ui.css +12 -76
- package/src/charts/dashboard/data-table.svelte +80 -80
- package/src/charts/dashboard/hint.svelte +34 -0
- package/src/charts/dashboard/hint.svelte.d.ts +10 -0
- package/src/charts/dashboard/rating-chip.svelte +4 -3
- package/src/charts/legend.css +0 -8
- package/src/charts/legend.svelte +26 -30
- package/src/components/copy/copy-button.svelte +10 -2
- package/src/components/copy/copy-button.test.ts +7 -0
- package/src/components/data-table/table-skeleton.svelte +15 -7
- package/src/components/data-table/table-skeleton.svelte.d.ts +4 -0
- package/src/components/docs/on-this-page.svelte +2 -2
- package/src/components/hold-to-confirm/hold-to-confirm.svelte +2 -1
- package/src/components/list-page/filter-item.svelte +20 -7
- package/src/components/list-page/filter-popover.svelte +41 -16
- package/src/components/list-page/filter-popover.svelte.d.ts +1 -1
- package/src/components/list-page/grouped-list.svelte +41 -23
- package/src/components/picker/picker.svelte +8 -3
- package/src/components/picker/picker.svelte.d.ts +2 -1
- package/src/components/segmented/segmented-filter.svelte +19 -10
- package/src/components/segmented/segmented-track.svelte +11 -3
- package/src/components/table-view/table-view.svelte +22 -6
- package/src/components/tags-input/tags-input.svelte +94 -77
- package/src/components/toolbar/toolbar.svelte +2 -1
- package/src/components/toolbar/toolbar.test.ts +5 -4
- package/src/components/work-parts/group-head.svelte +28 -9
- package/src/components/work-parts/group-head.svelte.d.ts +5 -2
- package/src/editor/editor-toolbar.svelte +223 -193
- package/src/editor/editor.svelte +56 -38
- package/src/editor/image-toolbar.svelte +99 -37
- package/src/editor/image-toolbar.svelte.d.ts +4 -5
- package/src/editor/url-dialog.svelte +96 -0
- package/src/editor/url-dialog.svelte.d.ts +15 -0
- package/src/effects/theme-toggle/ThemeToggle.css +8 -8
- package/src/effects/theme-toggle/ThemeToggle.svelte +20 -6
- package/src/inbox/thread-inbox.svelte +9 -1
- package/src/lib/live-region.svelte +12 -4
- package/src/lib/live-region.svelte.d.ts +5 -1
- package/src/lib/sliding-pill.ts +3 -2
- package/src/record/info-list.svelte +33 -59
- package/src/record/measure-clamp.ts +31 -0
- package/src/record/record-shell.svelte +38 -39
- package/src/record/record-timeline.svelte +10 -5
- package/src/record/steps-rail.svelte +50 -36
- package/src/record/where-we-are.svelte +5 -19
- package/src/shadcn/button-group/button-group-separator.svelte +23 -0
- package/src/shadcn/button-group/button-group-separator.svelte.d.ts +13 -0
- package/src/shadcn/button-group/button-group-text.svelte +28 -0
- package/src/shadcn/button-group/button-group-text.svelte.d.ts +11 -0
- package/src/shadcn/button-group/button-group.svelte +46 -0
- package/src/shadcn/button-group/button-group.svelte.d.ts +16 -0
- package/src/shadcn/button-group/index.ts +15 -0
- package/src/shadcn/checkbox/checkbox-box.ts +4 -0
- package/src/shadcn/checkbox/checkbox.svelte +2 -4
- package/src/shadcn/drawer/drawer-close.svelte +7 -0
- package/src/shadcn/drawer/drawer-close.svelte.d.ts +4 -0
- package/src/shadcn/drawer/drawer-content.svelte +36 -0
- package/src/shadcn/drawer/drawer-content.svelte.d.ts +10 -0
- package/src/shadcn/drawer/drawer-description.svelte +17 -0
- package/src/shadcn/drawer/drawer-description.svelte.d.ts +4 -0
- package/src/shadcn/drawer/drawer-footer.svelte +20 -0
- package/src/shadcn/drawer/drawer-footer.svelte.d.ts +5 -0
- package/src/shadcn/drawer/drawer-header.svelte +23 -0
- package/src/shadcn/drawer/drawer-header.svelte.d.ts +5 -0
- package/src/shadcn/drawer/drawer-nested.svelte +12 -0
- package/src/shadcn/drawer/drawer-nested.svelte.d.ts +3 -0
- package/src/shadcn/drawer/drawer-overlay.svelte +20 -0
- package/src/shadcn/drawer/drawer-overlay.svelte.d.ts +4 -0
- package/src/shadcn/drawer/drawer-portal.svelte +7 -0
- package/src/shadcn/drawer/drawer-portal.svelte.d.ts +3 -0
- package/src/shadcn/drawer/drawer-title.svelte +17 -0
- package/src/shadcn/drawer/drawer-title.svelte.d.ts +4 -0
- package/src/shadcn/drawer/drawer-trigger.svelte +7 -0
- package/src/shadcn/drawer/drawer-trigger.svelte.d.ts +4 -0
- package/src/shadcn/drawer/drawer.svelte +12 -0
- package/src/shadcn/drawer/drawer.svelte.d.ts +3 -0
- package/src/shadcn/drawer/index.ts +38 -0
- package/src/shadcn/input-group/index.ts +22 -0
- package/src/shadcn/input-group/input-group-addon.svelte +51 -0
- package/src/shadcn/input-group/input-group-addon.svelte.d.ts +18 -0
- package/src/shadcn/input-group/input-group-button.svelte +49 -0
- package/src/shadcn/input-group/input-group-button.svelte.d.ts +18 -0
- package/src/shadcn/input-group/input-group-input.svelte +20 -0
- package/src/shadcn/input-group/input-group-input.svelte.d.ts +11 -0
- package/src/shadcn/input-group/input-group-text.svelte +19 -0
- package/src/shadcn/input-group/input-group-text.svelte.d.ts +5 -0
- package/src/shadcn/input-group/input-group-textarea.svelte +20 -0
- package/src/shadcn/input-group/input-group-textarea.svelte.d.ts +3 -0
- package/src/shadcn/input-group/input-group.svelte +24 -0
- package/src/shadcn/input-group/input-group.svelte.d.ts +5 -0
- package/src/shadcn/item/index.ts +34 -0
- package/src/shadcn/item/item-actions.svelte +20 -0
- package/src/shadcn/item/item-actions.svelte.d.ts +5 -0
- package/src/shadcn/item/item-content.svelte +23 -0
- package/src/shadcn/item/item-content.svelte.d.ts +5 -0
- package/src/shadcn/item/item-description.svelte +23 -0
- package/src/shadcn/item/item-description.svelte.d.ts +5 -0
- package/src/shadcn/item/item-footer.svelte +20 -0
- package/src/shadcn/item/item-footer.svelte.d.ts +5 -0
- package/src/shadcn/item/item-group.svelte +21 -0
- package/src/shadcn/item/item-group.svelte.d.ts +5 -0
- package/src/shadcn/item/item-header.svelte +20 -0
- package/src/shadcn/item/item-header.svelte.d.ts +5 -0
- package/src/shadcn/item/item-media.svelte +42 -0
- package/src/shadcn/item/item-media.svelte.d.ts +17 -0
- package/src/shadcn/item/item-separator.svelte +19 -0
- package/src/shadcn/item/item-separator.svelte.d.ts +13 -0
- package/src/shadcn/item/item-title.svelte +20 -0
- package/src/shadcn/item/item-title.svelte.d.ts +5 -0
- package/src/shadcn/item/item.svelte +61 -0
- package/src/shadcn/item/item.svelte.d.ts +28 -0
- package/src/shadcn/native-select/index.ts +13 -0
- package/src/shadcn/native-select/native-select-opt-group.svelte +20 -0
- package/src/shadcn/native-select/native-select-opt-group.svelte.d.ts +5 -0
- package/src/shadcn/native-select/native-select-option.svelte +20 -0
- package/src/shadcn/native-select/native-select-option.svelte.d.ts +5 -0
- package/src/shadcn/native-select/native-select.svelte +45 -0
- package/src/shadcn/native-select/native-select.svelte.d.ts +8 -0
- package/src/shadcn/pagination/index.ts +31 -0
- package/src/shadcn/pagination/pagination-content.svelte +20 -0
- package/src/shadcn/pagination/pagination-content.svelte.d.ts +5 -0
- package/src/shadcn/pagination/pagination-ellipsis.svelte +22 -0
- package/src/shadcn/pagination/pagination-ellipsis.svelte.d.ts +5 -0
- package/src/shadcn/pagination/pagination-item.svelte +14 -0
- package/src/shadcn/pagination/pagination-item.svelte.d.ts +5 -0
- package/src/shadcn/pagination/pagination-link.svelte +41 -0
- package/src/shadcn/pagination/pagination-link.svelte.d.ts +9 -0
- package/src/shadcn/pagination/pagination-next-button.svelte +34 -0
- package/src/shadcn/pagination/pagination-next-button.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination-next.svelte +26 -0
- package/src/shadcn/pagination/pagination-next.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination-prev-button.svelte +34 -0
- package/src/shadcn/pagination/pagination-prev-button.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination-previous.svelte +30 -0
- package/src/shadcn/pagination/pagination-previous.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination.svelte +27 -0
- package/src/shadcn/pagination/pagination.svelte.d.ts +4 -0
- package/src/slides/Controls.svelte +39 -36
- package/src/slides/Deck.svelte +11 -8
- package/src/thread/thread.svelte +15 -8
- package/src/work/detail/task-detail.svelte +1 -1
- package/src/work/gantt/gantt-task-row.svelte +3 -6
- package/src/work/inbox/inbox-card.svelte +7 -5
- package/src/work/inbox/inbox-trace.svelte +14 -10
- package/src/work/kanban-board.svelte +40 -25
- package/src/work/kanban-hidden-rail.svelte +67 -65
- package/src/work/task-list.svelte +145 -124
- package/src/work/task-list.svelte.test.ts +5 -2
- package/src/work/time/time-tracker.svelte +35 -10
|
@@ -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
|
+
/>
|
|
@@ -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
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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;
|
package/src/slides/Deck.svelte
CHANGED
|
@@ -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
|
-
<
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
218
|
-
|
|
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}
|
package/src/thread/thread.svelte
CHANGED
|
@@ -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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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
|
-
<
|
|
144
|
-
|
|
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
|
-
></
|
|
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
|
|
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
|
|
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"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { Brain } from "phosphor-svelte";
|
|
3
|
+
import * as Trace from "../../shadcn/trace/index.js";
|
|
3
4
|
import type { InboxTrace } from "./inbox-types.js";
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
@@ -18,13 +19,16 @@
|
|
|
18
19
|
);
|
|
19
20
|
</script>
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
<Trace.Collapsible class="text-sm">
|
|
23
|
+
<Trace.CollapsibleTrigger class="gap-2">
|
|
24
|
+
<Trace.Line>
|
|
25
|
+
<Trace.Icon><Brain aria-hidden="true" /></Trace.Icon>
|
|
26
|
+
<Trace.Title
|
|
27
|
+
>Trace{count > 0 ? ` · ${count} ${count === 1 ? "quote" : "quotes"}` : ""}</Trace.Title
|
|
28
|
+
>
|
|
29
|
+
</Trace.Line>
|
|
30
|
+
</Trace.CollapsibleTrigger>
|
|
31
|
+
<Trace.CollapsibleContent class="mt-3 mb-0 ml-0 border-l-2 pr-0 pl-3">
|
|
28
32
|
<div class="flex flex-col gap-3">
|
|
29
33
|
{#if label || trace.source.href}
|
|
30
34
|
<p class="text-foreground">
|
|
@@ -54,5 +58,5 @@
|
|
|
54
58
|
<p><span class="text-foreground font-medium">Why:</span> {reasoning}</p>
|
|
55
59
|
{/if}
|
|
56
60
|
</div>
|
|
57
|
-
</
|
|
58
|
-
</
|
|
61
|
+
</Trace.CollapsibleContent>
|
|
62
|
+
</Trace.Collapsible>
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
type KanbanColumnView,
|
|
15
15
|
} from "./kanban-board-state.svelte.js";
|
|
16
16
|
import { Button } from "../shadcn/button/index.js";
|
|
17
|
+
import * as Collapsible from "../shadcn/collapsible/index.js";
|
|
17
18
|
import { workLooks } from "../components/work-parts/looks.js";
|
|
18
19
|
import type {
|
|
19
20
|
KanbanCardContext,
|
|
@@ -278,33 +279,47 @@
|
|
|
278
279
|
</div>
|
|
279
280
|
{/if}
|
|
280
281
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
282
|
+
<!-- The root renders no element, so the fold and its button stay items of the column's flex well. -->
|
|
283
|
+
<Collapsible.Root
|
|
284
|
+
bind:open={() => open, (next) => (next ? board.expand(column.id) : board.collapse(column.id))}
|
|
285
|
+
>
|
|
286
|
+
{#snippet child()}
|
|
287
|
+
{#if showTail}
|
|
288
|
+
<!-- The tail sits shut in a 0fr row, so opening and closing animate its height. -->
|
|
289
|
+
<Collapsible.Content forceMount>
|
|
290
|
+
{#snippet child({ props })}
|
|
291
|
+
<div {...props} class="kanban-fold" data-open={open} inert={!open}>
|
|
292
|
+
<div class="kanban-fold-inner" role="list">
|
|
293
|
+
{#each tail as item, index (getId(item))}
|
|
294
|
+
{@render card(column, item, head.length + index, list)}
|
|
295
|
+
{/each}
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
{/snippet}
|
|
299
|
+
</Collapsible.Content>
|
|
300
|
+
{/if}
|
|
291
301
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
302
|
+
{#if dnd.showIndicatorEnd(column.id) && board.idAt(shown, shown.length - 1) !== dnd.draggedId}
|
|
303
|
+
{@render dropSlot()}
|
|
304
|
+
{/if}
|
|
295
305
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
{#if tail.length > 0 || open}
|
|
307
|
+
<Collapsible.Trigger>
|
|
308
|
+
{#snippet child({ props })}
|
|
309
|
+
<Button
|
|
310
|
+
{...props}
|
|
311
|
+
variant="ghost"
|
|
312
|
+
size="sm"
|
|
313
|
+
class="shrink-0 justify-start gap-1.5 px-2 text-xs font-normal text-muted-foreground"
|
|
314
|
+
>
|
|
315
|
+
<KanbanFoldChevron {open} class="size-2.5" />
|
|
316
|
+
<span class="tabular-nums">{open ? lessLabel : moreLabel(tail.length)}</span>
|
|
317
|
+
</Button>
|
|
318
|
+
{/snippet}
|
|
319
|
+
</Collapsible.Trigger>
|
|
320
|
+
{/if}
|
|
321
|
+
{/snippet}
|
|
322
|
+
</Collapsible.Root>
|
|
308
323
|
|
|
309
324
|
{#if columnFooter}
|
|
310
325
|
{@render columnFooter(column, context)}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { CaretDown } from "phosphor-svelte";
|
|
4
4
|
import { cn } from "../lib/utils.js";
|
|
5
5
|
import { Button } from "../shadcn/button/index.js";
|
|
6
|
+
import * as Collapsible from "../shadcn/collapsible/index.js";
|
|
6
7
|
import { workLooks } from "../components/work-parts/looks.js";
|
|
7
8
|
import type { KanbanRailState } from "./kanban-rail-state.svelte.js";
|
|
8
9
|
import type { KanbanColumn as KanbanColumnDef } from "./kanban-types.js";
|
|
@@ -21,79 +22,80 @@
|
|
|
21
22
|
let { columns, rail, countOf, hiddenLabel, showAllLabel, hiddenItem }: Props = $props();
|
|
22
23
|
</script>
|
|
23
24
|
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"size-2.5 transition-transform duration-fast ease-smooth-out motion-reduce:transition-none [&>svg]:size-full",
|
|
35
|
-
!rail.railOpen && "-rotate-90",
|
|
36
|
-
)}
|
|
37
|
-
aria-hidden="true"><CaretDown aria-hidden="true" weight="bold" /></span
|
|
38
|
-
>
|
|
39
|
-
{hiddenLabel}
|
|
40
|
-
</Button>
|
|
41
|
-
|
|
42
|
-
{#if rail.railOpen}
|
|
43
|
-
<div class="flex flex-col gap-0.5">
|
|
44
|
-
{#each columns as column (column.id)}
|
|
45
|
-
{@const count = countOf(column.id)}
|
|
46
|
-
{@const over = rail.dragOverHidden === column.id}
|
|
47
|
-
{@const hue = column.hue ?? "var(--color-primary)"}
|
|
48
|
-
<div
|
|
49
|
-
role="region"
|
|
50
|
-
aria-label={column.ariaLabel ?? column.label}
|
|
25
|
+
<Collapsible.Root bind:open={rail.railOpen} class="kanban-rail flex w-40 shrink-0 flex-col gap-1">
|
|
26
|
+
<Collapsible.Trigger>
|
|
27
|
+
{#snippet child({ props })}
|
|
28
|
+
<Button
|
|
29
|
+
{...props}
|
|
30
|
+
variant="ghost"
|
|
31
|
+
size="sm"
|
|
32
|
+
class="justify-start px-2 text-xs font-normal text-muted-foreground"
|
|
33
|
+
>
|
|
34
|
+
<span
|
|
51
35
|
class={cn(
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
rail.leaving.has(column.id) && "kanban-rail-item-leaving",
|
|
36
|
+
"size-2.5 transition-transform duration-fast ease-smooth-out motion-reduce:transition-none [&>svg]:size-full",
|
|
37
|
+
!rail.railOpen && "-rotate-90",
|
|
55
38
|
)}
|
|
56
|
-
|
|
57
|
-
{over ? 10 : 0}%, transparent)"
|
|
58
|
-
style:outline="1px solid color-mix(in oklch, {hue}
|
|
59
|
-
{over ? 28 : 0}%, transparent)"
|
|
60
|
-
ondragover={(e) => rail.onHiddenDragOver(e, column.id)}
|
|
61
|
-
ondragleave={rail.onHiddenDragLeave}
|
|
62
|
-
ondrop={(e) => rail.onHiddenDrop(e, column.id)}
|
|
39
|
+
aria-hidden="true"><CaretDown aria-hidden="true" weight="bold" /></span
|
|
63
40
|
>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class="w-full justify-start gap-2 text-xs text-muted-foreground"
|
|
69
|
-
>
|
|
70
|
-
{#if hiddenItem}
|
|
71
|
-
{@render hiddenItem(column, { count, active: over })}
|
|
72
|
-
{:else}
|
|
73
|
-
<span class="truncate whitespace-nowrap">{column.label}</span>
|
|
74
|
-
{#if count > 0}
|
|
75
|
-
<span class="ms-auto text-xs text-muted-foreground/60 tabular-nums"
|
|
76
|
-
>{count.toLocaleString()}</span
|
|
77
|
-
>
|
|
78
|
-
{/if}
|
|
79
|
-
{/if}
|
|
80
|
-
</Button>
|
|
81
|
-
</div>
|
|
82
|
-
{/each}
|
|
41
|
+
{hiddenLabel}
|
|
42
|
+
</Button>
|
|
43
|
+
{/snippet}
|
|
44
|
+
</Collapsible.Trigger>
|
|
83
45
|
|
|
84
|
-
|
|
46
|
+
<Collapsible.Content class="flex flex-col gap-0.5">
|
|
47
|
+
{#each columns as column (column.id)}
|
|
48
|
+
{@const count = countOf(column.id)}
|
|
49
|
+
{@const over = rail.dragOverHidden === column.id}
|
|
50
|
+
{@const hue = column.hue ?? "var(--color-primary)"}
|
|
51
|
+
<div
|
|
52
|
+
role="region"
|
|
53
|
+
aria-label={column.ariaLabel ?? column.label}
|
|
54
|
+
class={cn(
|
|
55
|
+
"kanban-rail-item transition-[background-color,outline-color] duration-quick ease-smooth-out",
|
|
56
|
+
workLooks.row,
|
|
57
|
+
rail.leaving.has(column.id) && "kanban-rail-item-leaving",
|
|
58
|
+
)}
|
|
59
|
+
style:background="color-mix(in oklch, {hue}
|
|
60
|
+
{over ? 10 : 0}%, transparent)"
|
|
61
|
+
style:outline="1px solid color-mix(in oklch, {hue}
|
|
62
|
+
{over ? 28 : 0}%, transparent)"
|
|
63
|
+
ondragover={(e) => rail.onHiddenDragOver(e, column.id)}
|
|
64
|
+
ondragleave={rail.onHiddenDragLeave}
|
|
65
|
+
ondrop={(e) => rail.onHiddenDrop(e, column.id)}
|
|
66
|
+
>
|
|
85
67
|
<Button
|
|
86
68
|
variant="ghost"
|
|
87
|
-
size="
|
|
88
|
-
onclick={rail.
|
|
89
|
-
class="
|
|
69
|
+
size="lg"
|
|
70
|
+
onclick={() => rail.show(column.id)}
|
|
71
|
+
class="w-full justify-start gap-2 text-xs text-muted-foreground"
|
|
90
72
|
>
|
|
91
|
-
{
|
|
73
|
+
{#if hiddenItem}
|
|
74
|
+
{@render hiddenItem(column, { count, active: over })}
|
|
75
|
+
{:else}
|
|
76
|
+
<span class="truncate whitespace-nowrap">{column.label}</span>
|
|
77
|
+
{#if count > 0}
|
|
78
|
+
<span class="ms-auto text-xs text-muted-foreground/60 tabular-nums"
|
|
79
|
+
>{count.toLocaleString()}</span
|
|
80
|
+
>
|
|
81
|
+
{/if}
|
|
82
|
+
{/if}
|
|
92
83
|
</Button>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
84
|
+
</div>
|
|
85
|
+
{/each}
|
|
86
|
+
|
|
87
|
+
{#if columns.length > 1}
|
|
88
|
+
<Button
|
|
89
|
+
variant="ghost"
|
|
90
|
+
size="sm"
|
|
91
|
+
onclick={rail.showAll}
|
|
92
|
+
class="mt-1 justify-start text-xs font-normal text-muted-foreground"
|
|
93
|
+
>
|
|
94
|
+
{showAllLabel}
|
|
95
|
+
</Button>
|
|
96
|
+
{/if}
|
|
97
|
+
</Collapsible.Content>
|
|
98
|
+
</Collapsible.Root>
|
|
97
99
|
|
|
98
100
|
<style>
|
|
99
101
|
/* Unlayered: the row's transition-[background-color,outline-color] utility would otherwise drop the fade out. */
|