@heyramzi/ui 2.20.0 → 2.21.1
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/README.md +2 -0
- package/dist/charts/dashboard/data-table.js +1 -2
- package/dist/components/list-page/filter-section.js +1 -1
- package/dist/components/list-page/list-table.js +5 -6
- package/dist/components/list-page/queue-rail.js +2 -1
- package/dist/components/picker/trigger.js +3 -3
- package/dist/components/segmented/segmented.js +5 -5
- package/dist/components/work-parts/looks.js +1 -1
- package/dist/shadcn/alert/alert-variants.js +9 -0
- package/dist/shadcn/alert/index.js +1 -1
- package/dist/shadcn/badge/badge-variants.js +17 -0
- package/dist/shadcn/badge/index.js +1 -1
- package/dist/shadcn/dialog/index.js +3 -2
- package/dist/shadcn/dropdown-menu/menu-item.js +1 -1
- package/dist/shadcn/sheet/index.js +3 -2
- package/dist/shadcn/skeleton/index.js +3 -2
- package/dist/shadcn/toggle/index.js +1 -1
- package/dist/shadcn/toggle/toggle-variants.js +20 -0
- package/dist/status/index.js +2 -0
- package/dist/status/pill-tint.js +13 -0
- package/dist/work/kanban-drag.js +13 -7
- package/package.json +23 -23
- package/src/ai/confirmation/ConfirmationTitle.svelte +1 -4
- package/src/ai/loading-state/PixelLoader.svelte +1 -1
- package/src/animations/dropdown.css +19 -10
- package/src/animations/modal.css +7 -2
- package/src/charts/charts.css +3 -5
- package/src/charts/dashboard/dashboard-section.svelte +1 -1
- package/src/charts/dashboard/data-table.ts +1 -2
- package/src/charts/dashboard/stat-tile.svelte +1 -1
- package/src/charts/number-chart.css +8 -7
- package/src/charts/pop-value.svelte +68 -0
- package/src/charts/primitives/chart-tooltip.svelte +1 -1
- package/src/charts/reference-line.css +1 -1
- package/src/charts/stat-card.css +4 -4
- package/src/components/copy/copy-button.svelte +11 -10
- package/src/components/data-table/row-arrow.svelte +1 -1
- package/src/components/data-table/row-context-menu.svelte +1 -1
- package/src/components/data-table/sortable-head.svelte +2 -2
- package/src/components/data-table/table-skeleton.svelte +5 -5
- package/src/components/docs/doc-page.svelte +1 -3
- package/src/components/docs/on-this-page.svelte +4 -4
- package/src/components/field-row/field-row.svelte +1 -1
- package/src/components/list-page/detail-empty.svelte +3 -8
- package/src/components/list-page/detail-header.svelte +1 -1
- package/src/components/list-page/detail-row.svelte +2 -1
- package/src/components/list-page/empty-state.svelte +15 -7
- package/src/components/list-page/filter-item.svelte +2 -2
- package/src/components/list-page/filter-popover.svelte +1 -1
- package/src/components/list-page/filter-section.ts +1 -4
- package/src/components/list-page/grouped-list.svelte +37 -8
- package/src/components/list-page/list-page-shell.svelte +1 -1
- package/src/components/list-page/list-table.ts +6 -6
- package/src/components/list-page/master-detail.svelte +1 -1
- package/src/components/list-page/queue-rail.ts +2 -2
- package/src/components/list-page/rail-empty.svelte +1 -1
- package/src/components/list-page/rail-row.svelte +5 -5
- package/src/components/open-in/open-in.svelte +2 -1
- package/src/components/picker/trigger.ts +6 -5
- package/src/components/section-card/section-card.svelte +1 -1
- package/src/components/section-header/section-header.svelte +4 -2
- package/src/components/section-header/section-label.svelte +2 -2
- package/src/components/segmented/animated-tabs.svelte +1 -1
- package/src/components/segmented/section-runs.svelte +1 -1
- package/src/components/segmented/segment.svelte +4 -6
- package/src/components/segmented/segmented-track.svelte +18 -52
- package/src/components/segmented/segmented.ts +5 -5
- package/src/components/table-view/table-view.svelte +43 -24
- package/src/components/tags-input/tags-input.svelte +17 -31
- package/src/components/work-parts/looks.ts +1 -1
- package/src/editor/content.css +3 -3
- package/src/editor/editor.svelte +1 -1
- package/src/inbox/thread-inbox.svelte +2 -9
- package/src/panel/side-panel.svelte +9 -4
- package/src/record/info-list.svelte +7 -8
- package/src/record/project-list.svelte +1 -1
- package/src/record/record-demo.svelte +2 -4
- package/src/record/record-rail.svelte +5 -1
- package/src/record/record-shell.svelte +1 -1
- package/src/record/record-stats.svelte +9 -3
- package/src/record/steps-rail.svelte +7 -11
- package/src/shadcn/accordion/accordion-trigger.svelte +1 -1
- package/src/shadcn/alert/alert-variants.ts +17 -0
- package/src/shadcn/alert/alert.svelte +2 -16
- package/src/shadcn/alert/index.ts +1 -1
- package/src/shadcn/alert-dialog/alert-dialog-content.svelte +5 -1
- package/src/shadcn/alert-dialog/alert-dialog-footer.svelte +12 -2
- package/src/shadcn/alert-dialog/alert-dialog-header.svelte +1 -1
- package/src/shadcn/alert-dialog/alert-dialog-title.svelte +1 -1
- package/src/shadcn/badge/badge-variants.ts +23 -0
- package/src/shadcn/badge/badge.svelte +2 -20
- package/src/shadcn/badge/index.ts +1 -1
- package/src/shadcn/bubble/bubble-content.svelte +1 -1
- package/src/shadcn/bubble/bubble.svelte +1 -1
- package/src/shadcn/button/button.svelte +11 -5
- package/src/shadcn/calendar/calendar-month-select.svelte +1 -1
- package/src/shadcn/calendar/calendar-year-select.svelte +1 -1
- package/src/shadcn/calendar/calendar.svelte +1 -1
- package/src/shadcn/card/card.svelte +2 -1
- package/src/shadcn/checkbox/checkbox.svelte +1 -1
- package/src/shadcn/code-block/code-block-actions.svelte +1 -1
- package/src/shadcn/command/command-dialog.svelte +2 -2
- package/src/shadcn/command/command-group.svelte +1 -1
- package/src/shadcn/command/command-input.svelte +1 -1
- package/src/shadcn/command/command-item.svelte +1 -1
- package/src/shadcn/dialog/dialog-body.svelte +22 -0
- package/src/shadcn/dialog/dialog-content.svelte +19 -4
- package/src/shadcn/dialog/dialog-footer.svelte +19 -1
- package/src/shadcn/dialog/dialog-header.svelte +6 -1
- package/src/shadcn/dialog/dialog-title.svelte +2 -1
- package/src/shadcn/dialog/index.ts +3 -0
- package/src/shadcn/dropdown-menu/dropdown-menu-content.svelte +5 -1
- package/src/shadcn/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
- package/src/shadcn/dropdown-menu/menu-item.ts +1 -1
- package/src/shadcn/field/field-separator.svelte +1 -1
- package/src/shadcn/hover-card/hover-card-content.svelte +1 -1
- package/src/shadcn/input/input.svelte +2 -2
- package/src/shadcn/input-otp/input-otp-slot.svelte +1 -1
- package/src/shadcn/message-scroller/message-scroller-button.svelte +1 -1
- package/src/shadcn/popover/popover-content.svelte +1 -1
- package/src/shadcn/radio-group/radio-group-item.svelte +1 -1
- package/src/shadcn/scroll-area/scroll-area.svelte +1 -1
- package/src/shadcn/select/select-content.svelte +6 -2
- package/src/shadcn/select/select-item.svelte +1 -1
- package/src/shadcn/select/select-trigger.svelte +1 -1
- package/src/shadcn/sheet/index.ts +3 -0
- package/src/shadcn/sheet/sheet-body.svelte +22 -0
- package/src/shadcn/sheet/sheet-content.svelte +27 -5
- package/src/shadcn/sheet/sheet-footer.svelte +14 -2
- package/src/shadcn/sheet/sheet-header.svelte +1 -1
- package/src/shadcn/sheet/sheet-title.svelte +1 -1
- package/src/shadcn/sheet/sheet.css +11 -5
- package/src/shadcn/sidebar/sidebar-group-action.svelte +1 -1
- package/src/shadcn/sidebar/sidebar-group-label.svelte +1 -1
- package/src/shadcn/sidebar/sidebar-inset.svelte +1 -1
- package/src/shadcn/sidebar/sidebar-menu-action.svelte +1 -1
- package/src/shadcn/sidebar/sidebar-menu-button.svelte +2 -2
- package/src/shadcn/sidebar/sidebar-menu-sub-button.svelte +1 -1
- package/src/shadcn/sidebar/sidebar-menu.svelte +1 -1
- package/src/shadcn/sidebar/sidebar.svelte +1 -1
- package/src/shadcn/skeleton/index.ts +3 -0
- package/src/shadcn/skeleton/skeleton-delay.svelte +63 -0
- package/src/shadcn/skeleton/skeleton-delay.svelte.test.ts +57 -0
- package/src/shadcn/skeleton/skeleton.svelte +5 -1
- package/src/shadcn/slider/slider.svelte +1 -1
- package/src/shadcn/switch/switch.svelte +2 -2
- package/src/shadcn/table/table-row.svelte +1 -1
- package/src/shadcn/tabs/tabs-list.svelte +1 -1
- package/src/shadcn/tabs/tabs-trigger.svelte +2 -1
- package/src/shadcn/textarea/textarea.svelte +1 -1
- package/src/shadcn/toggle/index.ts +1 -1
- package/src/shadcn/toggle/toggle-variants.ts +26 -0
- package/src/shadcn/toggle/toggle.svelte +7 -25
- package/src/shadcn/toggle-group/toggle-group.svelte +1 -1
- package/src/shadcn/tooltip/tooltip-content.svelte +1 -1
- package/src/shadcn/trace/trace-collapsible-trigger.svelte +1 -1
- package/src/shadcn/trace/trace.svelte +1 -1
- package/src/status/README.md +1 -1
- package/src/status/index.ts +2 -0
- package/src/status/pill-tint.ts +16 -0
- package/src/status/status-badge.svelte +21 -7
- package/src/status/status-dot.svelte +6 -11
- package/src/status/status-pill.svelte +40 -0
- package/src/svelte-reexports.test.ts +43 -0
- package/src/thread/thread.svelte +54 -136
- package/src/tokens/craft.css +55 -36
- package/src/tokens/palette.css +16 -9
- package/src/work/demo.svelte +48 -42
- package/src/work/detail/detail-demo.svelte +33 -24
- package/src/work/detail/task-chip.svelte +4 -4
- package/src/work/detail/task-detail.svelte +41 -108
- package/src/work/detail/task-property.svelte +7 -13
- package/src/work/detail/task-thread.svelte +48 -119
- package/src/work/docs/doc-editor-page.svelte +5 -4
- package/src/work/docs/doc-menu.svelte +9 -4
- package/src/work/docs/docs-demo.svelte +4 -4
- package/src/work/docs/edited-chip.svelte +11 -4
- package/src/work/gantt/gantt-bar.svelte +18 -14
- package/src/work/gantt/gantt-grid.svelte +7 -7
- package/src/work/gantt/gantt-group-row.svelte +7 -10
- package/src/work/gantt/gantt-header.svelte +3 -1
- package/src/work/gantt/gantt-task-row.svelte +19 -9
- package/src/work/gantt/gantt.css +4 -5
- package/src/work/inbox/inbox-card.svelte +32 -10
- package/src/work/inbox/inbox-draft.svelte +2 -2
- package/src/work/kanban-column.svelte +7 -15
- package/src/work/kanban-drag.ts +13 -8
- package/src/work/task-gantt.svelte +2 -1
- package/src/work/task-list.svelte +54 -53
- package/src/work/time/time-chip.svelte +16 -19
- package/src/work/time/time-dot.svelte +2 -1
- package/src/work/time/time-ring.svelte +2 -3
- package/src/work/time/time-tracker.svelte +72 -166
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { Tone } from "../lib/tone.js";
|
|
15
15
|
import { cn } from "../lib/utils.js";
|
|
16
16
|
import StatusBadge from "../status/status-badge.svelte";
|
|
17
|
+
import PopValue from "../charts/pop-value.svelte";
|
|
17
18
|
|
|
18
19
|
// =========================
|
|
19
20
|
// PROPS
|
|
@@ -113,7 +114,8 @@
|
|
|
113
114
|
side="right"
|
|
114
115
|
bind:ref={panel}
|
|
115
116
|
tabindex={-1}
|
|
116
|
-
|
|
117
|
+
floating
|
|
118
|
+
class={cn("flex w-full flex-col gap-0 overflow-hidden p-0", WIDTH[width])}
|
|
117
119
|
{onOpenAutoFocus}
|
|
118
120
|
>
|
|
119
121
|
{#if bare}
|
|
@@ -165,11 +167,14 @@
|
|
|
165
167
|
<div class="min-w-0">
|
|
166
168
|
<dt class="text-xs text-muted-foreground">{stat.label}</dt>
|
|
167
169
|
<dd
|
|
168
|
-
class={cn(
|
|
170
|
+
class={cn(
|
|
171
|
+
"text-lg leading-tight font-semibold tabular-nums",
|
|
172
|
+
STAT_TONE[stat.tone ?? "default"],
|
|
173
|
+
)}
|
|
169
174
|
>
|
|
170
|
-
{stat.value}
|
|
175
|
+
<PopValue value={stat.value} />
|
|
171
176
|
{#if stat.sub}
|
|
172
|
-
<span class="text-xs font-normal text-muted-foreground">{stat.sub}</span>
|
|
177
|
+
<span class="ms-1 text-xs font-normal text-muted-foreground">{stat.sub}</span>
|
|
173
178
|
{/if}
|
|
174
179
|
</dd>
|
|
175
180
|
</div>
|
|
@@ -171,15 +171,16 @@
|
|
|
171
171
|
{/each}
|
|
172
172
|
</span>
|
|
173
173
|
{:else if row.tone && row.value}
|
|
174
|
-
<StatusBadge tone={row.tone} capitalize={false} class="w-fit max-w-full"
|
|
174
|
+
<StatusBadge tone={row.tone} capitalize={false} class="w-fit max-w-full"
|
|
175
|
+
>{row.value}</StatusBadge
|
|
176
|
+
>
|
|
175
177
|
{:else if row.href && row.value}
|
|
176
178
|
<a
|
|
177
179
|
href={row.href}
|
|
178
180
|
title={row.value}
|
|
179
181
|
class={cn(
|
|
180
182
|
"min-w-0 truncate text-sm font-medium underline-offset-2 hover:underline",
|
|
181
|
-
clamp &&
|
|
182
|
-
"rounded-xs focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
|
|
183
|
+
clamp && "rounded-xs focus-visible:shadow-(--ring-focus) focus-visible:outline-none",
|
|
183
184
|
)}>{row.value}</a
|
|
184
185
|
>
|
|
185
186
|
{:else if row.value}
|
|
@@ -299,12 +300,10 @@
|
|
|
299
300
|
{:else if shown.length > 0}
|
|
300
301
|
<div class={cn("flex flex-col gap-2", className)}>
|
|
301
302
|
{#if title}
|
|
302
|
-
<h2 class="text-xs font-medium
|
|
303
|
+
<h2 class="text-xs font-medium text-muted-foreground">{title}</h2>
|
|
303
304
|
{/if}
|
|
304
305
|
<!-- Labels size to their text, capped at 45%; the dt's min-w-20 is the 5rem floor. min() can't take max-content, so a min() template is dropped whole. -->
|
|
305
|
-
<dl
|
|
306
|
-
class="grid grid-cols-[fit-content(45%)_minmax(0,1fr)] items-start gap-x-4 gap-y-2.5"
|
|
307
|
-
>
|
|
306
|
+
<dl class="grid grid-cols-[fit-content(45%)_minmax(0,1fr)] items-start gap-x-4 gap-y-2.5">
|
|
308
307
|
{#each shown as row, index (row.divider ? `divider-${index}` : keyOf(row))}
|
|
309
308
|
{#if row.divider}
|
|
310
309
|
<div class="col-span-2 -my-0.5 border-t border-border/50"></div>
|
|
@@ -355,7 +354,7 @@
|
|
|
355
354
|
<Select.Trigger
|
|
356
355
|
size="sm"
|
|
357
356
|
aria-label={t.edit(row.label)}
|
|
358
|
-
class="-ml-1.5 min-h-7 h-auto w-fit max-w-full gap-1.5 border-transparent bg-transparent px-1.5 shadow-none transition-colors hover:bg-muted/60 focus-visible:ring-
|
|
357
|
+
class="-ml-1.5 min-h-7 h-auto w-fit max-w-full gap-1.5 border-transparent bg-transparent px-1.5 shadow-none transition-colors hover:bg-muted/60 focus-visible:shadow-(--ring-focus) data-[state=open]:bg-muted/60"
|
|
359
358
|
>
|
|
360
359
|
<span data-slot="select-value" class="flex min-w-0 items-center gap-1.5">
|
|
361
360
|
{@render display(row)}
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
aria-current={active ? "page" : undefined}
|
|
123
123
|
class={cn(
|
|
124
124
|
"flex flex-col gap-1.5 rounded-lg px-2 py-2 transition-colors any-pointer-coarse:py-3",
|
|
125
|
-
"outline-none focus-visible:ring-
|
|
125
|
+
"outline-none focus-visible:shadow-(--ring-focus)",
|
|
126
126
|
active ? "bg-muted" : "hover:bg-muted/60",
|
|
127
127
|
)}
|
|
128
128
|
>
|
|
@@ -183,7 +183,7 @@
|
|
|
183
183
|
</div>
|
|
184
184
|
|
|
185
185
|
<div class={narrow ? "mx-auto w-full max-w-[390px]" : "w-full"}>
|
|
186
|
-
<div class="overflow-hidden rounded-xl
|
|
186
|
+
<div class="overflow-hidden rounded-xl shadow-card">
|
|
187
187
|
{#if fixture === "project"}
|
|
188
188
|
<RecordShell
|
|
189
189
|
bind:tab
|
|
@@ -320,9 +320,7 @@
|
|
|
320
320
|
{#snippet rail()}
|
|
321
321
|
<div class="flex flex-col gap-6">
|
|
322
322
|
<section class="flex flex-col gap-2">
|
|
323
|
-
<h2 class="px-2 text-xs font-medium
|
|
324
|
-
Projects
|
|
325
|
-
</h2>
|
|
323
|
+
<h2 class="px-2 text-xs font-medium text-muted-foreground">Projects</h2>
|
|
326
324
|
<ProjectList projects={summaries} {stages} today={DEMO_TODAY} {locale} />
|
|
327
325
|
</section>
|
|
328
326
|
<FieldSection
|
|
@@ -51,7 +51,11 @@
|
|
|
51
51
|
|
|
52
52
|
<!-- A record's side rail with tabs: the fields in one, a thread or a log in the next,
|
|
53
53
|
so the thread sits beside the record and not a screen below it. One tab draws no strip. -->
|
|
54
|
-
<Tabs.Root
|
|
54
|
+
<Tabs.Root
|
|
55
|
+
value={open}
|
|
56
|
+
onValueChange={(next) => (value = next)}
|
|
57
|
+
class={cn("min-w-0 gap-0", className)}
|
|
58
|
+
>
|
|
55
59
|
{#if tabs.length > 1}
|
|
56
60
|
<div class={cn("pb-3", listClass)}>
|
|
57
61
|
<Tabs.List size="sm" class="w-full" aria-label={label}>
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<!-- =========================== -->
|
|
63
63
|
<!-- WHY a container query: the record sits in a page with its own sidebar, so the
|
|
64
64
|
viewport says nothing about how much room it has. -->
|
|
65
|
-
<div class={cn("@container flex min-w-0 flex-col bg-
|
|
65
|
+
<div class={cn("@container flex min-w-0 flex-col bg-card", className)}>
|
|
66
66
|
{@render header()}
|
|
67
67
|
{@render banner?.()}
|
|
68
68
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// IMPORTS
|
|
4
4
|
// =========================
|
|
5
5
|
import { cn } from "../lib/utils.js";
|
|
6
|
+
import PopValue from "../charts/pop-value.svelte";
|
|
6
7
|
import type { PanelStat } from "../panel/side-panel-types.js";
|
|
7
8
|
import { gutterClass } from "./gutter.js";
|
|
8
9
|
|
|
@@ -36,10 +37,15 @@
|
|
|
36
37
|
{#each stats as stat (stat.label)}
|
|
37
38
|
<div class="min-w-0">
|
|
38
39
|
<dt class="text-xs text-muted-foreground">{stat.label}</dt>
|
|
39
|
-
<dd
|
|
40
|
-
{
|
|
40
|
+
<dd
|
|
41
|
+
class={cn(
|
|
42
|
+
"text-lg leading-tight font-semibold tabular-nums",
|
|
43
|
+
TONE[stat.tone ?? "default"],
|
|
44
|
+
)}
|
|
45
|
+
>
|
|
46
|
+
<PopValue value={stat.value} />
|
|
41
47
|
{#if stat.sub}
|
|
42
|
-
<span class="text-xs font-normal text-muted-foreground">{stat.sub}</span>
|
|
48
|
+
<span class="ms-1 text-xs font-normal text-muted-foreground">{stat.sub}</span>
|
|
43
49
|
{/if}
|
|
44
50
|
</dd>
|
|
45
51
|
</div>
|
|
@@ -245,21 +245,21 @@
|
|
|
245
245
|
<Check class="size-2.5" weight="bold" />
|
|
246
246
|
</span>
|
|
247
247
|
{:else if kind === "current"}
|
|
248
|
-
<span class="rounded-full bg-
|
|
248
|
+
<span class="rounded-full bg-card p-0.75">
|
|
249
249
|
<span
|
|
250
250
|
class="block size-2 rounded-full bg-[color:var(--tone-accent,var(--color-primary))] ring-3 ring-[color-mix(in_oklab,var(--tone-accent,var(--color-primary))_20%,transparent)]"
|
|
251
251
|
></span>
|
|
252
252
|
</span>
|
|
253
253
|
{:else if kind === "late"}
|
|
254
|
-
<span class="size-2 rounded-full border-2 border-warning bg-
|
|
254
|
+
<span class="size-2 rounded-full border-2 border-warning bg-card"></span>
|
|
255
255
|
{:else}
|
|
256
|
-
<span class="size-2 rounded-full border border-muted-foreground/40 bg-
|
|
256
|
+
<span class="size-2 rounded-full border border-muted-foreground/40 bg-card"></span>
|
|
257
257
|
{/if}
|
|
258
258
|
{/snippet}
|
|
259
259
|
|
|
260
260
|
<div class={cn("flex flex-col", className)}>
|
|
261
261
|
<div class="mb-2 flex min-h-7 items-center gap-2 px-2">
|
|
262
|
-
<h2 class="text-xs font-medium
|
|
262
|
+
<h2 class="text-xs font-medium text-muted-foreground">{t.steps}</h2>
|
|
263
263
|
{#if !loading}
|
|
264
264
|
<span class="text-xs tabular-nums text-muted-foreground">
|
|
265
265
|
{t.stepsCount(progress.done, progress.total)}
|
|
@@ -290,9 +290,7 @@
|
|
|
290
290
|
<Popover.Content align="end" class="w-64 p-1">
|
|
291
291
|
{#each menuBuckets as bucket (bucket.key)}
|
|
292
292
|
{#if bucket.label}
|
|
293
|
-
<p
|
|
294
|
-
class="px-2 pt-2 pb-1 text-xs font-medium tracking-wide text-muted-foreground uppercase"
|
|
295
|
-
>
|
|
293
|
+
<p class="px-2 pt-2 pb-1 text-xs font-medium text-muted-foreground">
|
|
296
294
|
{bucket.label}
|
|
297
295
|
</p>
|
|
298
296
|
{/if}
|
|
@@ -342,9 +340,7 @@
|
|
|
342
340
|
{#each buckets as bucket (bucket.key)}
|
|
343
341
|
<div class="flex flex-col">
|
|
344
342
|
{#if bucket.label}
|
|
345
|
-
<h3
|
|
346
|
-
class="mb-1 px-2 text-xs font-medium tracking-wide text-muted-foreground uppercase select-none"
|
|
347
|
-
>
|
|
343
|
+
<h3 class="mb-1 px-2 text-xs font-medium text-muted-foreground select-none">
|
|
348
344
|
{bucket.label}
|
|
349
345
|
</h3>
|
|
350
346
|
{/if}
|
|
@@ -375,7 +371,7 @@
|
|
|
375
371
|
draggable={canReorder && !renaming}
|
|
376
372
|
class={cn(
|
|
377
373
|
"relative flex min-h-9 w-full items-start gap-2.5 rounded-lg px-2 py-2 text-left transition-colors any-pointer-coarse:min-h-11 any-pointer-coarse:py-3",
|
|
378
|
-
"outline-none focus-visible:ring-
|
|
374
|
+
"outline-none focus-visible:shadow-(--ring-focus)",
|
|
379
375
|
canReorder && "active:cursor-grabbing",
|
|
380
376
|
active ? "bg-muted" : "hover:bg-muted/60",
|
|
381
377
|
)}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
data-slot="accordion-trigger"
|
|
25
25
|
bind:ref
|
|
26
26
|
class={cn(
|
|
27
|
-
"
|
|
27
|
+
" focus-visible:border-ring focus-visible:after:border-ring **:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-md py-4 text-left text-sm font-medium hover:underline focus-visible:shadow-(--ring-focus) **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between border border-transparent transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] outline-none disabled:pointer-events-none disabled:opacity-50",
|
|
28
28
|
className,
|
|
29
29
|
)}
|
|
30
30
|
{...restProps}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type VariantProps, tv } from "tailwind-variants";
|
|
2
|
+
|
|
3
|
+
export const alertVariants = tv({
|
|
4
|
+
base: "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
|
|
5
|
+
variants: {
|
|
6
|
+
variant: {
|
|
7
|
+
default: "bg-card text-card-foreground",
|
|
8
|
+
destructive:
|
|
9
|
+
"text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
defaultVariants: {
|
|
13
|
+
variant: "default",
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type AlertVariant = VariantProps<typeof alertVariants>["variant"];
|
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import { type
|
|
2
|
+
import { alertVariants, type AlertVariant } from "./alert-variants.js";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
base: "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
|
|
6
|
-
variants: {
|
|
7
|
-
variant: {
|
|
8
|
-
default: "bg-card text-card-foreground",
|
|
9
|
-
destructive:
|
|
10
|
-
"text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current",
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
defaultVariants: {
|
|
14
|
-
variant: "default",
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
export type AlertVariant = VariantProps<typeof alertVariants>["variant"];
|
|
4
|
+
export { alertVariants, type AlertVariant };
|
|
19
5
|
</script>
|
|
20
6
|
|
|
21
7
|
<script lang="ts">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Root from "./alert.svelte";
|
|
2
2
|
import Description from "./alert-description.svelte";
|
|
3
3
|
import Title from "./alert-title.svelte";
|
|
4
|
-
export { alertVariants, type AlertVariant } from "./alert.
|
|
4
|
+
export { alertVariants, type AlertVariant } from "./alert-variants.js";
|
|
5
5
|
|
|
6
6
|
export {
|
|
7
7
|
Root,
|
|
@@ -21,7 +21,11 @@
|
|
|
21
21
|
bind:ref
|
|
22
22
|
data-slot="alert-dialog-content"
|
|
23
23
|
class={cn(
|
|
24
|
-
|
|
24
|
+
// The dialog's surface: white popover, the edge and depth from `shadow-edge-overlay`,
|
|
25
|
+
// the overlay radius. `overflow-hidden` lets a banded footer follow the bottom corners.
|
|
26
|
+
"t-modal bg-popover text-popover-foreground shadow-edge-overlay fixed inset-0 z-50 m-auto grid h-fit w-full max-w-[calc(100%-2rem)] gap-4 overflow-hidden rounded-2xl text-sm outline-none sm:max-w-md",
|
|
27
|
+
// Same padding variable as the dialog, so `AlertDialog.Footer band` reads one number.
|
|
28
|
+
"[--dialog-pad:1.25rem] sm:[--dialog-pad:1.5rem] p-(--dialog-pad)",
|
|
25
29
|
className,
|
|
26
30
|
)}
|
|
27
31
|
{...restProps}
|
|
@@ -6,14 +6,24 @@
|
|
|
6
6
|
ref = $bindable(null),
|
|
7
7
|
class: className,
|
|
8
8
|
children,
|
|
9
|
+
band = false,
|
|
9
10
|
...restProps
|
|
10
|
-
}: WithElementRef<HTMLAttributes<HTMLDivElement>>
|
|
11
|
+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
|
12
|
+
/** A hairline and a quiet surface out to both edges and the bottom corners. Last child only. */
|
|
13
|
+
band?: boolean;
|
|
14
|
+
} = $props();
|
|
11
15
|
</script>
|
|
12
16
|
|
|
13
17
|
<div
|
|
14
18
|
bind:this={ref}
|
|
15
19
|
data-slot="alert-dialog-footer"
|
|
16
|
-
|
|
20
|
+
data-band={band || undefined}
|
|
21
|
+
class={cn(
|
|
22
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:items-center sm:justify-end",
|
|
23
|
+
"data-band:border-border data-band:bg-muted/50 data-band:mt-2 data-band:border-t",
|
|
24
|
+
"data-band:mx-[calc(-1*var(--dialog-pad))] data-band:mb-[calc(-1*var(--dialog-pad))] data-band:px-(--dialog-pad) data-band:py-4",
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
17
27
|
{...restProps}
|
|
18
28
|
>
|
|
19
29
|
{@render children?.()}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<div
|
|
14
14
|
bind:this={ref}
|
|
15
15
|
data-slot="alert-dialog-header"
|
|
16
|
-
class={cn("flex flex-col gap-
|
|
16
|
+
class={cn("flex flex-col gap-1.5 text-center sm:text-start", className)}
|
|
17
17
|
{...restProps}
|
|
18
18
|
>
|
|
19
19
|
{@render children?.()}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type VariantProps, tv } from "tailwind-variants";
|
|
2
|
+
|
|
3
|
+
export const badgeVariants = tv({
|
|
4
|
+
// The chip radius, not a pill: DESIGN.md keeps `rounded-full` for status and counts,
|
|
5
|
+
// which `StatusBadge` owns. Tabular figures so a count that ticks doesn't shift.
|
|
6
|
+
base: "h-5 gap-1 rounded-sm border border-transparent px-2 py-0.5 text-xs font-medium tabular-nums has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit max-w-full shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-[background-color,border-color,color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] [&>svg]:pointer-events-none",
|
|
7
|
+
variants: {
|
|
8
|
+
// Three weights a label can carry: filled, tinted, outlined. Severity is the
|
|
9
|
+
// `tone` prop, which reads `TONE_CLASS`, not a variant.
|
|
10
|
+
variant: {
|
|
11
|
+
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
12
|
+
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
13
|
+
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
|
14
|
+
// For a consumer that wants one "this is wrong" badge without a tone prop.
|
|
15
|
+
destructive: "bg-destructive/10 text-destructive-ink [a]:hover:bg-destructive/20",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
variant: "default",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type BadgeVariant = VariantProps<typeof badgeVariants>["variant"];
|
|
@@ -1,25 +1,7 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import { type
|
|
2
|
+
import { badgeVariants, type BadgeVariant } from "./badge-variants.js";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
base: "h-5 gap-1 rounded-full border border-transparent px-2 py-0.5 text-xs font-medium has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit max-w-full shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-[background-color,border-color,color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none",
|
|
6
|
-
variants: {
|
|
7
|
-
// Three weights a label can carry: filled, tinted, outlined. Severity is the
|
|
8
|
-
// `tone` prop, which reads `TONE_CLASS`, not a variant.
|
|
9
|
-
variant: {
|
|
10
|
-
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
11
|
-
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
12
|
-
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
|
13
|
-
// For a consumer that wants one "this is wrong" badge without a tone prop.
|
|
14
|
-
destructive: "bg-destructive/10 text-destructive-ink [a]:hover:bg-destructive/20",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
defaultVariants: {
|
|
18
|
-
variant: "default",
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
export type BadgeVariant = VariantProps<typeof badgeVariants>["variant"];
|
|
4
|
+
export { badgeVariants, type BadgeVariant };
|
|
23
5
|
</script>
|
|
24
6
|
|
|
25
7
|
<script lang="ts">
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default as Badge } from "./badge.svelte";
|
|
2
|
-
export { badgeVariants, type BadgeVariant } from "./badge.
|
|
2
|
+
export { badgeVariants, type BadgeVariant } from "./badge-variants.js";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const mergedProps = $derived({
|
|
16
16
|
class: cn(
|
|
17
|
-
"cn-bubble-content w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-left [button,a]:transition-colors rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-
|
|
17
|
+
"cn-bubble-content w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-left [button,a]:transition-colors rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:shadow-(--ring-focus) group-data-[align=end]/bubble:self-end",
|
|
18
18
|
className,
|
|
19
19
|
),
|
|
20
20
|
"data-slot": "bubble-content",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
tinted:
|
|
15
15
|
"cn-bubble-variant-tinted *:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]",
|
|
16
16
|
outline:
|
|
17
|
-
"cn-bubble-variant-outline *:data-[slot=bubble-content]:bg-
|
|
17
|
+
"cn-bubble-variant-outline *:data-[slot=bubble-content]:bg-card *:data-[slot=bubble-content]:border-border [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30",
|
|
18
18
|
ghost:
|
|
19
19
|
"cn-bubble-variant-ghost *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50 border-none",
|
|
20
20
|
destructive:
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
import { type VariantProps, tv } from "tailwind-variants";
|
|
5
5
|
|
|
6
6
|
export const buttonVariants = tv({
|
|
7
|
-
|
|
7
|
+
// Focus is the kit's one ring, `--ring-focus`, written as a utility because the
|
|
8
|
+
// variant shadows (`shadow-key`, `shadow-btn`) would otherwise cover the base-layer rule.
|
|
9
|
+
base: "t-press 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 rounded-lg border border-transparent bg-clip-padding text-sm font-medium aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
8
10
|
variants: {
|
|
9
11
|
// Five roles: fill, outline, ghost, destructive, and dashed for an empty
|
|
10
12
|
// slot. `secondary` and `link` went on 4 Sep 2026, one real caller between
|
|
@@ -13,14 +15,18 @@
|
|
|
13
15
|
default:
|
|
14
16
|
"bg-primary text-primary-foreground shadow-key hover:bg-primary/90 active:shadow-none [a]:hover:bg-primary/80",
|
|
15
17
|
outline:
|
|
16
|
-
|
|
18
|
+
// `bg-card`, not `bg-background`: the background is the grey canvas now, so an
|
|
19
|
+
// outline button on a white panel read as a grey slab.
|
|
20
|
+
"border-border bg-card shadow-btn hover:bg-muted hover:border-foreground/15 hover:text-foreground active:shadow-none dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
21
|
+
// A foreground wash, not `bg-muted`: muted is L 0.94 and the canvas 0.945, so a
|
|
22
|
+
// ghost hover on the page drew nothing. The wash reads on canvas and card alike.
|
|
17
23
|
ghost:
|
|
18
|
-
"hover:bg-
|
|
24
|
+
"hover:bg-foreground/6 hover:text-foreground aria-expanded:bg-foreground/6 aria-expanded:text-foreground",
|
|
19
25
|
destructive:
|
|
20
|
-
"bg-destructive/10 hover:bg-destructive/20
|
|
26
|
+
"bg-destructive/10 hover:bg-destructive/20 dark:bg-destructive/20 text-destructive dark:text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
|
21
27
|
// Quiet text that opens an editor or a menu: a ghost that wraps to as many lines as its
|
|
22
28
|
// label needs, aligned left, never a fixed-height square.
|
|
23
|
-
text: "hover:bg-
|
|
29
|
+
text: "hover:bg-foreground/6 hover:text-foreground aria-expanded:bg-foreground/6 aria-expanded:text-foreground",
|
|
24
30
|
// WHY a variant and not a class every call site writes: "add another
|
|
25
31
|
|
|
26
32
|
// row", "add a step", "attach a call" is one affordance, and it was hand-drawn eleven times across the app with four radii, three text sizes and three different hover hues.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<span
|
|
16
16
|
class={cn(
|
|
17
|
-
"has-focus:border-ring border-input
|
|
17
|
+
"has-focus:border-ring border-input relative flex rounded-md border shadow-field has-focus:shadow-(--ring-focus)",
|
|
18
18
|
className,
|
|
19
19
|
)}
|
|
20
20
|
>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
<span
|
|
15
15
|
class={cn(
|
|
16
|
-
"has-focus:border-ring border-input
|
|
16
|
+
"has-focus:border-ring border-input relative flex rounded-md border shadow-field has-focus:shadow-(--ring-focus)",
|
|
17
17
|
className,
|
|
18
18
|
)}
|
|
19
19
|
>
|
|
@@ -59,7 +59,7 @@ get along, so we shut typescript up by casting `value` to `never`.
|
|
|
59
59
|
{weekStartsOn}
|
|
60
60
|
{fixedWeeks}
|
|
61
61
|
class={cn(
|
|
62
|
-
"bg-
|
|
62
|
+
"bg-card group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
63
63
|
className,
|
|
64
64
|
)}
|
|
65
65
|
{locale}
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
data-slot="card"
|
|
17
17
|
data-size={size}
|
|
18
18
|
class={cn(
|
|
19
|
-
|
|
19
|
+
// `shadow-card` draws its own hairline, so a ring on top made a 2px edge.
|
|
20
|
+
"bg-card text-card-foreground gap-6 overflow-hidden rounded-xl py-6 text-sm shadow-card has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col",
|
|
20
21
|
className,
|
|
21
22
|
)}
|
|
22
23
|
{...restProps}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
bind:ref
|
|
17
17
|
data-slot="checkbox"
|
|
18
18
|
class={cn(
|
|
19
|
-
"border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-
|
|
19
|
+
"border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 not-data-checked:enabled:hover:border-foreground/30 focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-sm border shadow-btn transition-[background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] group-has-disabled/field:opacity-50 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 any-pointer-coarse:after:-inset-[15px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
20
20
|
className,
|
|
21
21
|
)}
|
|
22
22
|
bind:checked
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
bind:this={ref}
|
|
15
15
|
data-slot="code-block-actions"
|
|
16
16
|
class={cn(
|
|
17
|
-
"-my-1 -me-1.5 gap-1 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:top-3 [[data-slot=code-block]>&]:end-3 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-2 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:*:[button]:bg-
|
|
17
|
+
"-my-1 -me-1.5 gap-1 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:top-3 [[data-slot=code-block]>&]:end-3 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-2 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:*:[button]:bg-card [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10 ms-auto flex shrink-0 items-center [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 [[data-slot=code-block]>&]:pointer-coarse:opacity-100",
|
|
18
18
|
className
|
|
19
19
|
)}
|
|
20
20
|
{...restProps}
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
// WHY: search is the one dialog that must sit above the keyboard rather
|
|
38
38
|
|
|
39
39
|
// than under it, so it stays top-anchored on phones instead of taking the shared bottom-sheet position, and hugs the safe area at the top.
|
|
40
|
-
"rounded-
|
|
40
|
+
"rounded-2xl! top-[max(0.5rem,env(safe-area-inset-top))] right-2 bottom-auto left-2 w-auto max-h-[70svh] translate-y-0 gap-0 overflow-hidden p-0 sm:p-0",
|
|
41
41
|
// WHY no border and no card background here: the palette is a floating
|
|
42
42
|
|
|
43
43
|
// object, so its edge is a lit rim and a cast shadow rather than a drawn line, and the surface itself belongs to the Command root beneath so its translucency
|
|
44
44
|
|
|
45
45
|
// can read the dimmed page through it.
|
|
46
|
-
"border-0 bg-transparent
|
|
46
|
+
"border-0 bg-transparent shadow-edge-overlay",
|
|
47
47
|
// WHY a third of the way down rather than centred: the eye is already at
|
|
48
48
|
|
|
49
49
|
// the top of the screen when the shortcut is pressed, and a list that grows downward should not push its first row past the fold.
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
>
|
|
32
32
|
{#if heading}
|
|
33
33
|
<CommandPrimitive.GroupHeading
|
|
34
|
-
class="text-muted-foreground px-2.5 pt-2.5 pb-1.5 text-xs font-medium
|
|
34
|
+
class="text-muted-foreground px-2.5 pt-2.5 pb-1.5 text-xs font-medium"
|
|
35
35
|
>
|
|
36
36
|
{heading}
|
|
37
37
|
</CommandPrimitive.GroupHeading>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"caret-brand placeholder:text-muted-foreground/70 w-full bg-transparent outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
|
50
50
|
// A combobox popover's search line is 36px, measured; `lg` is the
|
|
51
51
|
// standalone palette header and keeps its own larger rhythm.
|
|
52
|
-
size === "lg" ? "py-3.5 text-[15px]" : "py-2 text-
|
|
52
|
+
size === "lg" ? "py-3.5 text-[15px]" : "py-2 text-(length:--text-control)",
|
|
53
53
|
className,
|
|
54
54
|
)}
|
|
55
55
|
bind:ref
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
// at half strength is a two-percent lightness step on the dark surface, so the one row the arrow keys are on was the hardest row to find.
|
|
23
23
|
|
|
24
24
|
// A foreground wash plus an inset hairline works in both modes from one rule.
|
|
25
|
-
"group/command-item data-selected:bg-foreground/6 data-selected:ring-foreground/10 data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex min-h-8 cursor-default items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-
|
|
25
|
+
"group/command-item data-selected:bg-foreground/6 data-selected:ring-foreground/10 data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex min-h-8 cursor-default items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-(length:--text-control) outline-hidden select-none active:translate-y-px data-selected:ring-1 data-selected:ring-inset data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
26
26
|
className,
|
|
27
27
|
)}
|
|
28
28
|
{...restProps}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
import { cn, type WithElementRef } from "../../lib/utils.js";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
class: className,
|
|
8
|
+
children,
|
|
9
|
+
...restProps
|
|
10
|
+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!-- The fields between the header and the footer. No padding of its own: the content's
|
|
14
|
+
`--dialog-pad` already lines it up with the title. -->
|
|
15
|
+
<div
|
|
16
|
+
bind:this={ref}
|
|
17
|
+
data-slot="dialog-body"
|
|
18
|
+
class={cn("flex min-w-0 flex-col gap-4", className)}
|
|
19
|
+
{...restProps}
|
|
20
|
+
>
|
|
21
|
+
{@render children?.()}
|
|
22
|
+
</div>
|