@heyramzi/ui 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -8
- package/scripts/sync-shadcn.mjs +3 -4
- package/src/agents/agent-avatar.svelte +604 -575
- package/src/agents/agent-cast.svelte +179 -183
- package/src/agents/demo.svelte +125 -113
- package/src/agents/helpers.ts +23 -17
- package/src/agents/index.ts +4 -4
- package/src/agents/page-state.ts +6 -6
- package/src/agents/types.ts +6 -6
- package/src/ai/ai-button/AiButton.svelte +4 -12
- package/src/ai/generation-progress/GenerationProgress.svelte +10 -3
- package/src/ai/prompt-input/PromptInputTextarea.svelte +1 -2
- package/src/ai/response/Response.css +2 -3
- package/src/animations/avatar-group-hover.css +2 -16
- package/src/animations/card-tilt.css +3 -6
- package/src/animations/digit-pop-in.css +2 -15
- package/src/animations/dropdown.css +4 -17
- package/src/animations/input-clear-dissolve.css +5 -18
- package/src/animations/input-shake.css +9 -41
- package/src/animations/learn-more-hover.css +17 -9
- package/src/animations/like-button.css +2 -4
- package/src/animations/page-side-by-side.css +2 -10
- package/src/animations/plus-menu-morph.css +2 -5
- package/src/animations/shimmer-text.css +5 -18
- package/src/animations/spinning-counter.css +2 -6
- package/src/animations/success-check.css +2 -15
- package/src/animations/thinking-states.css +2 -7
- package/src/brand/brand.test.ts +21 -5
- package/src/brand/index.ts +4 -10
- package/src/canvas/card/card-frame.svelte +43 -39
- package/src/canvas/card/resize-handles.svelte +89 -80
- package/src/canvas/chrome/chrome-zoom.svelte +101 -100
- package/src/canvas/chrome/lock-badge.svelte +8 -8
- package/src/canvas/chrome/side-handles.svelte +24 -19
- package/src/canvas/chrome/size-chip.svelte +30 -30
- package/src/canvas/chrome/snap-guides.svelte +20 -20
- package/src/canvas/components/icons/ToolIcon.svelte +8 -8
- package/src/canvas/components/shared/svg/PreviewSvg.svelte +19 -19
- package/src/canvas/components/shared/svg/ShapeOutline.svelte +71 -48
- package/src/canvas/components/shared/svg/StrokeNode.svelte +21 -27
- package/src/canvas/components/shared/svg/TextRule.svelte +25 -17
- package/src/canvas/edges/bend-handle.svelte +46 -46
- package/src/canvas/edges/edge-gradient.svelte +10 -10
- package/src/canvas/edges/gradient-edge.svelte +45 -29
- package/src/canvas/editor/lock.test.ts +6 -1
- package/src/canvas/editor/style.ts +7 -1
- package/src/canvas/headless/svg-figure.test.ts +5 -1
- package/src/canvas/lod/lod-switch.svelte +111 -106
- package/src/canvas/pen/PenField.svelte +87 -81
- package/src/canvas/pen/PenOverlay.svelte +127 -127
- package/src/canvas/pen/ShapeNode.svelte +31 -32
- package/src/canvas/pen/TextNode.svelte +54 -53
- package/src/canvas/pen/host-field.test.svelte +7 -7
- package/src/canvas/pen/shapes.ts +7 -1
- package/src/canvas/screen/GlyphIcon.svelte +22 -17
- package/src/canvas/screen/PartView.svelte +138 -72
- package/src/canvas/screen/ScreenBody.svelte +81 -60
- package/src/canvas/screen/ScreenCard.svelte +20 -20
- package/src/canvas/ui/CanvasToolbar.svelte +173 -85
- package/src/canvas/ui/FrameLayer.svelte +59 -59
- package/src/canvas/ui/PenLayer.svelte +39 -30
- package/src/canvas/ui/StylePanel.svelte +119 -102
- package/src/canvas/ui/canvas-grid.svelte +137 -129
- package/src/charts/animated-value.svelte +1 -1
- package/src/charts/area-chart.css +2 -5
- package/src/charts/area-chart.svelte +1 -1
- package/src/charts/bar-chart.css +2 -3
- package/src/charts/bar-chart.svelte +1 -1
- package/src/charts/charts.css +5 -17
- package/src/charts/crosshair.svelte +1 -1
- package/src/charts/dashboard/dashboard-empty.svelte +25 -25
- package/src/charts/dashboard/dashboard-section.svelte +24 -24
- package/src/charts/dashboard/data-panel.svelte +50 -50
- package/src/charts/dashboard/data-sort-head.svelte +56 -56
- package/src/charts/dashboard/data-table.svelte +138 -138
- package/src/charts/dashboard/panel-grid.svelte +30 -30
- package/src/charts/dashboard/period-filter.svelte +25 -25
- package/src/charts/dashboard/rating-chip.svelte +19 -19
- package/src/charts/dashboard/stat-band.svelte +32 -32
- package/src/charts/dashboard/stat-tile.svelte +106 -99
- package/src/charts/donut-chart.svelte +1 -1
- package/src/charts/edge-fade.svelte +1 -1
- package/src/charts/figure.svelte +1 -1
- package/src/charts/gauge-chart.css +4 -7
- package/src/charts/gauge-chart.svelte +1 -1
- package/src/charts/hover-focus.svelte +1 -1
- package/src/charts/legend.css +1 -3
- package/src/charts/legend.svelte +1 -1
- package/src/charts/line-chart.svelte +1 -1
- package/src/charts/number-chart.css +6 -9
- package/src/charts/number-chart.svelte +1 -1
- package/src/charts/reference-line.svelte +19 -19
- package/src/charts/reveal.svelte +1 -1
- package/src/charts/ring-chart.css +2 -4
- package/src/charts/ring-chart.svelte +1 -1
- package/src/charts/sparkline.svelte +5 -2
- package/src/charts/stat-card.svelte +1 -1
- package/src/charts/time-series-chart.css +2 -5
- package/src/charts/trend-pill.css +2 -4
- package/src/charts/trend-pill.svelte +1 -1
- package/src/components/copy/copy-button.svelte +93 -98
- package/src/components/copy/copy-button.test.ts +10 -2
- package/src/components/data-table/infinite-scroll.svelte +42 -42
- package/src/components/data-table/pagination.svelte +34 -22
- package/src/components/data-table/row-arrow.svelte +19 -16
- package/src/components/data-table/row-context-menu.svelte +52 -52
- package/src/components/data-table/sortable-head.svelte +25 -25
- package/src/components/data-table/table-skeleton.svelte +41 -36
- package/src/components/docs/doc-page.svelte +18 -9
- package/src/components/docs/on-this-page.svelte +16 -3
- package/src/components/docs/scroll-spy.svelte.ts +2 -3
- package/src/components/field-row/field-row.svelte +10 -8
- package/src/components/hold-to-confirm/hold-to-confirm.svelte +5 -1
- package/src/components/icon/icon.svelte +14 -14
- package/src/components/language-flag/language-flag.svelte +3 -1
- package/src/components/list-page/detail-empty.svelte +34 -34
- package/src/components/list-page/detail-header.svelte +55 -47
- package/src/components/list-page/detail-panel.svelte +51 -59
- package/src/components/list-page/detail-row.svelte +19 -19
- package/src/components/list-page/detail-stack.svelte +21 -21
- package/src/components/list-page/empty-state.svelte +30 -30
- package/src/components/list-page/filter-item.svelte +20 -20
- package/src/components/list-page/filter-popover.svelte +60 -55
- package/src/components/list-page/grouped-list.svelte +4 -2
- package/src/components/list-page/index.ts +5 -1
- package/src/components/list-page/list-page-shell.svelte +2 -5
- package/src/components/list-page/master-detail.svelte +87 -88
- package/src/components/list-page/notice-bar.svelte +38 -38
- package/src/components/list-page/prev-next.svelte +63 -63
- package/src/components/list-page/rail-body.svelte +18 -18
- package/src/components/list-page/rail-empty.svelte +23 -30
- package/src/components/list-page/rail-head.svelte +24 -24
- package/src/components/list-page/rail-row.svelte +77 -73
- package/src/components/list-page/section-host.ts +2 -3
- package/src/components/locale-switch/locale-switch.svelte +41 -41
- package/src/components/mark/mark.svelte +34 -38
- package/src/components/open-in/index.ts +1 -5
- package/src/components/open-in/open-in.svelte +40 -40
- package/src/components/picker/mark-picker.svelte +49 -49
- package/src/components/picker/picker.svelte +5 -3
- package/src/components/section-header/section-header.test.ts +7 -1
- package/src/components/section-header/section-label.svelte +20 -20
- package/src/components/segmented/animated-tabs.svelte +31 -2
- package/src/components/segmented/collapse.test.ts +2 -1
- package/src/components/segmented/index.ts +2 -0
- package/src/components/segmented/segment.svelte +52 -49
- package/src/components/segmented/segmented-filter.svelte +79 -80
- package/src/components/segmented/segmented-nav.svelte +34 -40
- package/src/components/segmented/segmented-overflow.svelte +53 -50
- package/src/components/segmented/segmented-track.svelte +62 -46
- package/src/components/segmented/segmented.ts +2 -3
- package/src/components/star-rating-input/star-rating-input.svelte +103 -103
- package/src/components/svg/svg.svelte +4 -4
- package/src/components/table-view/table-view.svelte +17 -2
- package/src/components/table-view/table-view.test.ts +7 -1
- package/src/components/table-view/types.ts +11 -11
- package/src/components/tags-input/index.ts +13 -0
- package/src/components/tags-input/tags-input.svelte +305 -0
- package/src/components/tags-input/tags.test.ts +64 -0
- package/src/components/tags-input/tags.ts +142 -0
- package/src/components/theme/index.ts +2 -4
- package/src/components/theme/theme-provider.svelte +1 -3
- package/src/components/toolbar/toolbar-search.svelte +25 -25
- package/src/components/toolbar/toolbar.svelte +11 -7
- package/src/components/toolbar/toolbar.test.ts +10 -1
- package/src/design/index.css +21 -78
- package/src/design/polish.css +26 -35
- package/src/editor/editor-toolbar.svelte +104 -99
- package/src/editor/editor.svelte +296 -266
- package/src/editor/image-toolbar.svelte +20 -22
- package/src/editor/index.ts +1 -4
- package/src/editor/inline-editor.svelte +280 -238
- package/src/editor/markdown.ts +15 -15
- package/src/editor/renderer.svelte +71 -71
- package/src/editor/slash-menu.svelte +24 -27
- package/src/effects/animated-beam/diagrams/BeamSvg.svelte +1 -1
- package/src/effects/image-comparison/ImageComparison.svelte +11 -1
- package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +59 -46
- package/src/effects/magic-card/MagicCard.css +14 -7
- package/src/effects/marquee/Marquee.svelte +3 -5
- package/src/effects/reveal/observe.ts +0 -3
- package/src/effects/spotlight/Spotlight.svelte +1 -1
- package/src/effects/theme-toggle/ThemeToggle.css +25 -22
- package/src/effects/theme-toggle/ThemeToggle.svelte +6 -7
- package/src/gallery.test.ts +14 -4
- package/src/inbox/README.md +1 -3
- package/src/inbox/inbox.test.ts +181 -138
- package/src/inbox/index.ts +20 -20
- package/src/inbox/logic.ts +114 -111
- package/src/inbox/thread-inbox.svelte +227 -151
- package/src/inbox/types.ts +130 -108
- package/src/lib/theme-transition.ts +2 -4
- package/src/lib/tone.ts +2 -4
- package/src/lib/utils.ts +2 -2
- package/src/modules.test.ts +79 -69
- package/src/onboarding/define-tours.test.ts +55 -40
- package/src/onboarding/define-tours.ts +23 -23
- package/src/onboarding/demo.svelte +24 -5
- package/src/onboarding/index.ts +1 -8
- package/src/onboarding/onboarding-provider.svelte +19 -7
- package/src/onboarding/onboarding.svelte.ts +16 -16
- package/src/onboarding/pick.test.ts +61 -52
- package/src/onboarding/pick.ts +16 -13
- package/src/onboarding/stores.test.ts +80 -80
- package/src/onboarding/stores.ts +41 -39
- package/src/onboarding/tour-card.svelte +30 -5
- package/src/onboarding/tour-runner.svelte +12 -3
- package/src/onboarding/types.ts +20 -12
- package/src/onboarding/wait.ts +22 -22
- package/src/panel/side-panel.svelte +94 -93
- package/src/record/demo-data.ts +291 -225
- package/src/record/field-section.svelte +38 -34
- package/src/record/fields.ts +148 -96
- package/src/record/format.ts +63 -56
- package/src/record/index.ts +49 -35
- package/src/record/info-list.svelte +145 -114
- package/src/record/kinds.ts +31 -31
- package/src/record/logic.ts +216 -214
- package/src/record/next-up.svelte +45 -34
- package/src/record/project-list.svelte +56 -50
- package/src/record/record-demo.svelte +130 -110
- package/src/record/record-header.svelte +37 -28
- package/src/record/record-shell.svelte +54 -54
- package/src/record/record-stats.svelte +25 -25
- package/src/record/record-timeline.svelte +134 -114
- package/src/record/record.test.ts +430 -309
- package/src/record/steps-rail.svelte +225 -216
- package/src/record/types.ts +234 -215
- package/src/record/where-we-are.svelte +62 -58
- package/src/shadcn/button/button.svelte +1 -1
- package/src/shadcn/card/card-title.svelte +1 -5
- package/src/shadcn/hooks/use-highlighted-code.svelte.ts +2 -13
- package/src/shadcn/sheet/sheet-content.svelte +2 -4
- package/src/shadcn/table/table-cell.svelte +2 -3
- package/src/shadcn/utilities.css +3 -8
- package/src/slides/Controls.svelte +150 -124
- package/src/slides/Deck.svelte +243 -238
- package/src/slides/Fragment.svelte +64 -57
- package/src/slides/Overview.svelte +106 -101
- package/src/slides/Presenter.svelte +300 -266
- package/src/slides/Slide.svelte +185 -170
- package/src/slides/SlideList.svelte +16 -12
- package/src/slides/ambient.d.ts +1 -1
- package/src/slides/bridges.ts +42 -23
- package/src/slides/deck-controller.svelte.ts +47 -35
- package/src/slides/demo-slides.svelte +330 -306
- package/src/slides/demo.svelte +164 -160
- package/src/slides/export/capture.ts +20 -16
- package/src/slides/export/ffmpeg.ts +43 -38
- package/src/slides/export/index.ts +5 -5
- package/src/slides/export/launch.ts +3 -1
- package/src/slides/export/pdf.ts +30 -27
- package/src/slides/export/types.ts +10 -8
- package/src/slides/index.ts +11 -11
- package/src/slides/labels.ts +22 -19
- package/src/slides/layout.ts +9 -2
- package/src/slides/model.ts +4 -4
- package/src/slides/navigation.ts +43 -31
- package/src/slides/theme.css +5 -7
- package/src/slides/types.ts +9 -10
- package/src/status/define-statuses.ts +17 -24
- package/src/status/index.ts +5 -5
- package/src/status/status-badge.svelte +3 -1
- package/src/status/status-dot.svelte +1 -3
- package/src/status/status-icon.svelte +1 -1
- package/src/status/status-types.ts +21 -21
- package/src/tasks/board-order.ts +2 -4
- package/src/tasks/demo.svelte +189 -31
- package/src/tasks/detail/detail-demo.svelte +73 -13
- package/src/tasks/detail/detail-types.ts +45 -45
- package/src/tasks/detail/task-detail.svelte +40 -10
- package/src/tasks/detail/task-property.svelte +8 -2
- package/src/tasks/detail/task-thread.svelte +53 -12
- package/src/tasks/gantt/gantt-bar.svelte +17 -6
- package/src/tasks/gantt/gantt-grid.svelte +40 -9
- package/src/tasks/gantt/gantt-group-row.svelte +8 -2
- package/src/tasks/gantt/gantt-header.svelte +9 -3
- package/src/tasks/gantt/gantt-task-row.svelte +26 -6
- package/src/tasks/gantt/gantt.css +2 -1
- package/src/tasks/gantt/gantt.test.ts +3 -1
- package/src/tasks/gantt/logic.test.ts +110 -20
- package/src/tasks/gantt/logic.ts +42 -6
- package/src/tasks/inbox/inbox-card.svelte +13 -5
- package/src/tasks/inbox/inbox-draft.svelte +1 -1
- package/src/tasks/inbox/inbox-logic.ts +6 -40
- package/src/tasks/inbox/inbox-statuses.ts +23 -23
- package/src/tasks/inbox/inbox-trace.svelte +9 -3
- package/src/tasks/inbox/inbox-types.ts +54 -58
- package/src/tasks/inbox/index.ts +22 -21
- package/src/tasks/index.ts +49 -52
- package/src/tasks/kanban-board.svelte +16 -12
- package/src/tasks/kanban-types.ts +2 -3
- package/src/tasks/presets/sales.ts +6 -6
- package/src/tasks/task-gantt.svelte +28 -8
- package/src/tasks/task-list.svelte +41 -17
- package/src/tasks/time/duration.ts +40 -40
- package/src/tasks/time/time-chip.svelte +9 -2
- package/src/tasks/time/time-dot.svelte +1 -1
- package/src/tasks/time/time-ring.svelte +11 -3
- package/src/tasks/time/time-tracker.svelte +57 -15
- package/src/tasks/time/time-types.ts +57 -57
- package/src/tasks/use-kanban-dnd.svelte.ts +2 -3
- package/src/thread/index.ts +7 -7
- package/src/thread/logic.ts +36 -33
- package/src/thread/thread.svelte +82 -16
- package/src/thread/thread.test.ts +58 -47
- package/src/thread/types.ts +68 -68
- package/src/tokens/craft.css +17 -53
- package/src/tokens/index.css +3 -13
- package/src/tokens/palette.css +13 -11
- package/src/tokens/primitives.css +10 -23
- package/src/tasks/inbox/inbox.svelte +0 -203
|
@@ -1,91 +1,94 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
6
|
-
import { setContext } from "svelte";
|
|
7
|
-
import { CaretLeft } from "phosphor-svelte";
|
|
8
|
-
import { cn } from "../../lib/utils.js";
|
|
9
|
-
import { Button } from "../../shadcn/button/index.js";
|
|
10
|
-
import {
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { setContext } from "svelte";
|
|
7
|
+
import { CaretLeft } from "phosphor-svelte";
|
|
8
|
+
import { cn } from "../../lib/utils.js";
|
|
9
|
+
import { Button } from "../../shadcn/button/index.js";
|
|
10
|
+
import {
|
|
11
|
+
MASTER_DETAIL_PANE,
|
|
12
|
+
type MasterDetailPane,
|
|
13
|
+
} from "./queue-rail.js";
|
|
11
14
|
|
|
12
|
-
// =========================
|
|
13
|
-
// TYPES
|
|
14
|
-
// =========================
|
|
15
|
-
interface Props {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
15
|
+
// =========================
|
|
16
|
+
// TYPES
|
|
17
|
+
// =========================
|
|
18
|
+
interface Props {
|
|
19
|
+
// The list rail (an <aside>) and the content pane. Pages style both; this
|
|
20
|
+
// shell owns the two columns and the min-h-0/min-w-0 scroll containment.
|
|
21
|
+
rail: Snippet;
|
|
22
|
+
detail: Snippet;
|
|
23
|
+
// A full-width strip above both columns for facts to read before acting,
|
|
24
|
+
// like a posting cap. Pages wrapping the shell to add one broke the padding.
|
|
25
|
+
banner?: Snippet;
|
|
26
|
+
// WHY: a CSS grid track for the rail column ("16rem", "minmax(280px, 340px)").
|
|
27
|
+
// Queue pages pass `queueRailWidth` rather than a literal.
|
|
28
|
+
railWidth?: string;
|
|
29
|
+
// Stack to one column below this. "lg" because rail and detail can't both be
|
|
30
|
+
// read under 1024px. null only for a rail narrow enough for a phone.
|
|
31
|
+
stackBelow?: "lg" | "xl" | null;
|
|
32
|
+
// WHY: the phone back button says where it goes back to. "Back" alone is the
|
|
33
|
+
// browser's word and the reader has to remember what they left.
|
|
34
|
+
backLabel?: string;
|
|
35
|
+
// Bindable so a url naming a record opens on it after a refresh or a pasted
|
|
36
|
+
// link. The page sets it. Ignored above the stack breakpoint.
|
|
37
|
+
pane?: "rail" | "detail";
|
|
38
|
+
gap?: boolean;
|
|
39
|
+
pad?: boolean;
|
|
40
|
+
railClass?: string;
|
|
41
|
+
detailClass?: string;
|
|
42
|
+
class?: string;
|
|
43
|
+
}
|
|
41
44
|
|
|
42
|
-
// =========================
|
|
43
|
-
// PROPS
|
|
44
|
-
// =========================
|
|
45
|
-
let {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}: Props = $props();
|
|
45
|
+
// =========================
|
|
46
|
+
// PROPS
|
|
47
|
+
// =========================
|
|
48
|
+
let {
|
|
49
|
+
rail,
|
|
50
|
+
detail,
|
|
51
|
+
banner,
|
|
52
|
+
railWidth = "minmax(260px, 320px)",
|
|
53
|
+
stackBelow = "lg",
|
|
54
|
+
backLabel = "Back to the list",
|
|
55
|
+
// The rail wins by default: an unpicked detail is an empty state or a
|
|
56
|
+
// guessed row, both worse than the list.
|
|
57
|
+
pane = $bindable("rail"),
|
|
58
|
+
gap = true,
|
|
59
|
+
pad = true,
|
|
60
|
+
railClass,
|
|
61
|
+
detailClass,
|
|
62
|
+
class: className,
|
|
63
|
+
}: Props = $props();
|
|
61
64
|
|
|
62
|
-
// =========================
|
|
63
|
-
// DERIVED
|
|
64
|
-
// =========================
|
|
65
|
-
// One pane at a time when stacked. Two rows put a 34svh list scroller on top of
|
|
66
|
-
// a record scroller, and neither was readable.
|
|
67
|
-
let gridClass = $derived(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
);
|
|
74
|
-
// Hidden while stacked; back to normal above the breakpoint, where both panes show.
|
|
75
|
-
let hideWhileStacked = $derived(stackBelow === "xl" ? "max-xl:hidden" : "max-lg:hidden");
|
|
76
|
-
// Drawn only while stacked. The back bar has no job beside a visible rail.
|
|
77
|
-
let stackedOnly = $derived(stackBelow === "xl" ? "xl:hidden" : "lg:hidden");
|
|
65
|
+
// =========================
|
|
66
|
+
// DERIVED
|
|
67
|
+
// =========================
|
|
68
|
+
// One pane at a time when stacked. Two rows put a 34svh list scroller on top of
|
|
69
|
+
// a record scroller, and neither was readable.
|
|
70
|
+
let gridClass = $derived(
|
|
71
|
+
stackBelow === "xl"
|
|
72
|
+
? "grid-cols-1 grid-rows-[minmax(0,1fr)] xl:grid-rows-1 xl:[grid-template-columns:var(--md-cols)]"
|
|
73
|
+
: stackBelow === "lg"
|
|
74
|
+
? "grid-cols-1 grid-rows-[minmax(0,1fr)] lg:grid-rows-1 lg:[grid-template-columns:var(--md-cols)]"
|
|
75
|
+
: "[grid-template-columns:var(--md-cols)]",
|
|
76
|
+
);
|
|
77
|
+
// Hidden while stacked; back to normal above the breakpoint, where both panes show.
|
|
78
|
+
let hideWhileStacked = $derived(stackBelow === "xl" ? "max-xl:hidden" : "max-lg:hidden");
|
|
79
|
+
// Drawn only while stacked. The back bar has no job beside a visible rail.
|
|
80
|
+
let stackedOnly = $derived(stackBelow === "xl" ? "xl:hidden" : "lg:hidden");
|
|
78
81
|
|
|
79
|
-
// =========================
|
|
80
|
-
// FUNCTIONS
|
|
81
|
-
// =========================
|
|
82
|
-
// `RailRow` calls this when a record is picked. Above the breakpoint the classes
|
|
83
|
-
// that read `pane` are all prefixed away, so the flag changes nothing there.
|
|
84
|
-
setContext<MasterDetailPane>(MASTER_DETAIL_PANE, {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
});
|
|
82
|
+
// =========================
|
|
83
|
+
// FUNCTIONS
|
|
84
|
+
// =========================
|
|
85
|
+
// `RailRow` calls this when a record is picked. Above the breakpoint the classes
|
|
86
|
+
// that read `pane` are all prefixed away, so the flag changes nothing there.
|
|
87
|
+
setContext<MasterDetailPane>(MASTER_DETAIL_PANE, {
|
|
88
|
+
open: () => {
|
|
89
|
+
if (stackBelow) pane = "detail";
|
|
90
|
+
},
|
|
91
|
+
});
|
|
89
92
|
</script>
|
|
90
93
|
|
|
91
94
|
<!-- =========================== -->
|
|
@@ -106,11 +109,7 @@ setContext<MasterDetailPane>(MASTER_DETAIL_PANE, {
|
|
|
106
109
|
data-stack={stackBelow ?? undefined}
|
|
107
110
|
>
|
|
108
111
|
<aside
|
|
109
|
-
class={cn(
|
|
110
|
-
"md-rail min-h-0",
|
|
111
|
-
railClass,
|
|
112
|
-
stackBelow && pane === "detail" && hideWhileStacked,
|
|
113
|
-
)}
|
|
112
|
+
class={cn("md-rail min-h-0", railClass, stackBelow && pane === "detail" && hideWhileStacked)}
|
|
114
113
|
>
|
|
115
114
|
{@render rail()}
|
|
116
115
|
</aside>
|
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
6
|
-
import { Warning, Info, CheckCircle, WarningCircle } from "phosphor-svelte";
|
|
7
|
-
import { cn } from "../../lib/utils.js";
|
|
8
|
-
import { Alert } from "../../shadcn/alert/index.js";
|
|
9
|
-
import { TONE_CLASS, type Tone as SeverityTone } from "../../lib/tone.js";
|
|
10
|
-
import type { PhosphorIcon } from "../../lib/icon-types.js";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { Warning, Info, CheckCircle, WarningCircle } from "phosphor-svelte";
|
|
7
|
+
import { cn } from "../../lib/utils.js";
|
|
8
|
+
import { Alert } from "../../shadcn/alert/index.js";
|
|
9
|
+
import { TONE_CLASS, type Tone as SeverityTone } from "../../lib/tone.js";
|
|
10
|
+
import type { PhosphorIcon } from "../../lib/icon-types.js";
|
|
11
11
|
|
|
12
|
-
// =========================
|
|
13
|
-
// TYPES
|
|
14
|
-
// =========================
|
|
15
|
-
// A strip that stops the reader is a severity. Neutral and accent are chip tones.
|
|
16
|
-
type Tone = Extract<SeverityTone, "destructive" | "warning" | "info" | "success">;
|
|
12
|
+
// =========================
|
|
13
|
+
// TYPES
|
|
14
|
+
// =========================
|
|
15
|
+
// A strip that stops the reader is a severity. Neutral and accent are chip tones.
|
|
16
|
+
type Tone = Extract<SeverityTone, "destructive" | "warning" | "info" | "success">;
|
|
17
17
|
|
|
18
|
-
interface Props {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
18
|
+
interface Props {
|
|
19
|
+
// The "look at this before you act" strip. Hand-rolled ones used raw amber
|
|
20
|
+
// and sky, so one severity showed two colours one route apart.
|
|
21
|
+
tone?: Tone;
|
|
22
|
+
icon?: PhosphorIcon;
|
|
23
|
+
// The trailing control: a retry, a jump to the thing that needs fixing.
|
|
24
|
+
actions?: Snippet;
|
|
25
|
+
children: Snippet;
|
|
26
|
+
class?: string;
|
|
27
|
+
}
|
|
28
28
|
|
|
29
|
-
const TONE_ICON: Record<Tone, PhosphorIcon> = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
29
|
+
const TONE_ICON: Record<Tone, PhosphorIcon> = {
|
|
30
|
+
destructive: Warning,
|
|
31
|
+
warning: WarningCircle,
|
|
32
|
+
info: Info,
|
|
33
|
+
success: CheckCircle,
|
|
34
|
+
};
|
|
35
35
|
|
|
36
|
-
// =========================
|
|
37
|
-
// PROPS
|
|
38
|
-
// =========================
|
|
39
|
-
let { tone = "destructive", icon, actions, children, class: className }: Props = $props();
|
|
36
|
+
// =========================
|
|
37
|
+
// PROPS
|
|
38
|
+
// =========================
|
|
39
|
+
let { tone = "destructive", icon, actions, children, class: className }: Props = $props();
|
|
40
40
|
|
|
41
|
-
// =========================
|
|
42
|
-
// DERIVED
|
|
43
|
-
// =========================
|
|
44
|
-
let Icon = $derived(icon ?? TONE_ICON[tone]);
|
|
41
|
+
// =========================
|
|
42
|
+
// DERIVED
|
|
43
|
+
// =========================
|
|
44
|
+
let Icon = $derived(icon ?? TONE_ICON[tone]);
|
|
45
45
|
</script>
|
|
46
46
|
|
|
47
47
|
<!-- =========================== -->
|
|
@@ -1,74 +1,74 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import { CaretLeft, CaretRight } from "phosphor-svelte";
|
|
6
|
-
import { cn } from "../../lib/utils.js";
|
|
7
|
-
import { Button } from "../../shadcn/button/index.js";
|
|
8
|
-
import { stepTo } from "./step.js";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import { CaretLeft, CaretRight } from "phosphor-svelte";
|
|
6
|
+
import { cn } from "../../lib/utils.js";
|
|
7
|
+
import { Button } from "../../shadcn/button/index.js";
|
|
8
|
+
import { stepTo } from "./step.js";
|
|
9
9
|
|
|
10
|
-
// =========================
|
|
11
|
-
// TYPES
|
|
12
|
-
// =========================
|
|
13
|
-
interface Props {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
10
|
+
// =========================
|
|
11
|
+
// TYPES
|
|
12
|
+
// =========================
|
|
13
|
+
interface Props {
|
|
14
|
+
/** Ids in the order the list shows them. */
|
|
15
|
+
ids: readonly string[];
|
|
16
|
+
current: string | null | undefined;
|
|
17
|
+
onselect: (id: string) => void;
|
|
18
|
+
previousLabel?: string;
|
|
19
|
+
nextLabel?: string;
|
|
20
|
+
/** Off when two steppers share a page, so one key press moves one list. */
|
|
21
|
+
keys?: boolean;
|
|
22
|
+
class?: string;
|
|
23
|
+
}
|
|
24
24
|
|
|
25
|
-
// =========================
|
|
26
|
-
// PROPS
|
|
27
|
-
// =========================
|
|
28
|
-
let {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}: Props = $props();
|
|
25
|
+
// =========================
|
|
26
|
+
// PROPS
|
|
27
|
+
// =========================
|
|
28
|
+
let {
|
|
29
|
+
ids,
|
|
30
|
+
current,
|
|
31
|
+
onselect,
|
|
32
|
+
previousLabel = "Previous",
|
|
33
|
+
nextLabel = "Next",
|
|
34
|
+
keys = true,
|
|
35
|
+
class: className,
|
|
36
|
+
}: Props = $props();
|
|
37
37
|
|
|
38
|
-
// =========================
|
|
39
|
-
// DERIVED
|
|
40
|
-
// =========================
|
|
41
|
-
let index = $derived(current ? ids.indexOf(current) : -1);
|
|
42
|
-
let prev = $derived(stepTo(ids, current, -1));
|
|
43
|
-
let next = $derived(stepTo(ids, current, 1));
|
|
38
|
+
// =========================
|
|
39
|
+
// DERIVED
|
|
40
|
+
// =========================
|
|
41
|
+
let index = $derived(current ? ids.indexOf(current) : -1);
|
|
42
|
+
let prev = $derived(stepTo(ids, current, -1));
|
|
43
|
+
let next = $derived(stepTo(ids, current, 1));
|
|
44
44
|
|
|
45
|
-
// =========================
|
|
46
|
-
// HANDLERS
|
|
47
|
-
// =========================
|
|
48
|
-
function isTyping(event: KeyboardEvent): boolean {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
45
|
+
// =========================
|
|
46
|
+
// HANDLERS
|
|
47
|
+
// =========================
|
|
48
|
+
function isTyping(event: KeyboardEvent): boolean {
|
|
49
|
+
const target = event.target as HTMLElement | null;
|
|
50
|
+
return Boolean(target?.closest("input, textarea, select, [contenteditable='true']"));
|
|
51
|
+
}
|
|
52
52
|
|
|
53
|
-
function ignored(event: KeyboardEvent): boolean {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
53
|
+
function ignored(event: KeyboardEvent): boolean {
|
|
54
|
+
const modified = event.metaKey || event.ctrlKey || event.altKey;
|
|
55
|
+
return !keys || modified || event.defaultPrevented || isTyping(event);
|
|
56
|
+
}
|
|
57
57
|
|
|
58
|
-
// K and J, as in Gmail: the arrows already belong to slide viewers and text fields.
|
|
59
|
-
function targetFor(key: string): string | null {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
58
|
+
// K and J, as in Gmail: the arrows already belong to slide viewers and text fields.
|
|
59
|
+
function targetFor(key: string): string | null {
|
|
60
|
+
if (key === "k") return prev;
|
|
61
|
+
if (key === "j") return next;
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
64
|
|
|
65
|
-
function onkeydown(event: KeyboardEvent) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
65
|
+
function onkeydown(event: KeyboardEvent) {
|
|
66
|
+
if (ignored(event)) return;
|
|
67
|
+
const id = targetFor(event.key);
|
|
68
|
+
if (!id) return;
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
onselect(id);
|
|
71
|
+
}
|
|
72
72
|
</script>
|
|
73
73
|
|
|
74
74
|
<svelte:window {onkeydown} />
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
6
|
-
import { cn } from "../../lib/utils.js";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { cn } from "../../lib/utils.js";
|
|
7
7
|
|
|
8
|
-
// =========================
|
|
9
|
-
// TYPES
|
|
10
|
-
// =========================
|
|
11
|
-
interface Props {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
8
|
+
// =========================
|
|
9
|
+
// TYPES
|
|
10
|
+
// =========================
|
|
11
|
+
interface Props {
|
|
12
|
+
// The scroller under `RailHead`. `min-h-0` makes a flex child scroll instead
|
|
13
|
+
// of growing its parent, and it's the line hand-rolled rails forgot.
|
|
14
|
+
children: Snippet;
|
|
15
|
+
class?: string;
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
// =========================
|
|
19
|
-
// PROPS
|
|
20
|
-
// =========================
|
|
21
|
-
let { children, class: className }: Props = $props();
|
|
18
|
+
// =========================
|
|
19
|
+
// PROPS
|
|
20
|
+
// =========================
|
|
21
|
+
let { children, class: className }: Props = $props();
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
24
|
<!-- =========================== -->
|
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import { cn } from "../../lib/utils.js";
|
|
6
|
-
import * as Empty from "../../shadcn/empty/index.js";
|
|
7
|
-
import type { PhosphorIcon, IconWeight } from "../../lib/icon-types.js";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
import * as Empty from "../../shadcn/empty/index.js";
|
|
7
|
+
import type { PhosphorIcon, IconWeight } from "../../lib/icon-types.js";
|
|
8
8
|
|
|
9
|
-
// =========================
|
|
10
|
-
// TYPES
|
|
11
|
-
// =========================
|
|
12
|
-
interface Props {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
9
|
+
// =========================
|
|
10
|
+
// TYPES
|
|
11
|
+
// =========================
|
|
12
|
+
interface Props {
|
|
13
|
+
// Not `EmptyState`, which has a 48px icon and an action. This says a filter
|
|
14
|
+
// came back empty, in one sentence that fits a 280px rail.
|
|
15
|
+
icon?: PhosphorIcon;
|
|
16
|
+
iconWeight?: IconWeight;
|
|
17
|
+
iconClass?: string;
|
|
18
|
+
title: string;
|
|
19
|
+
hint?: string;
|
|
20
|
+
class?: string;
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
// =========================
|
|
24
|
-
// PROPS
|
|
25
|
-
// =========================
|
|
26
|
-
let {
|
|
27
|
-
icon: Icon,
|
|
28
|
-
iconWeight,
|
|
29
|
-
iconClass,
|
|
30
|
-
title,
|
|
31
|
-
hint,
|
|
32
|
-
class: className,
|
|
33
|
-
}: Props = $props();
|
|
23
|
+
// =========================
|
|
24
|
+
// PROPS
|
|
25
|
+
// =========================
|
|
26
|
+
let { icon: Icon, iconWeight, iconClass, title, hint, class: className }: Props = $props();
|
|
34
27
|
</script>
|
|
35
28
|
|
|
36
29
|
<!-- =========================== -->
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
6
|
-
import SectionLabel from "../section-header/section-label.svelte";
|
|
7
|
-
import { cn } from "../../lib/utils.js";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import SectionLabel from "../section-header/section-label.svelte";
|
|
7
|
+
import { cn } from "../../lib/utils.js";
|
|
8
8
|
|
|
9
|
-
// =========================
|
|
10
|
-
// TYPES
|
|
11
|
-
// =========================
|
|
12
|
-
interface Props {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
9
|
+
// =========================
|
|
10
|
+
// TYPES
|
|
11
|
+
// =========================
|
|
12
|
+
interface Props {
|
|
13
|
+
// The fixed top of a queue rail: label, filter, search. A fixed height, so
|
|
14
|
+
// rows start on the same line on every queue page.
|
|
15
|
+
label?: string;
|
|
16
|
+
// A low-emphasis control beside the label (compose, refresh).
|
|
17
|
+
action?: Snippet;
|
|
18
|
+
// The filter, the search, whatever narrows the list. Optional: a rail of four
|
|
19
|
+
// records has nothing to narrow, and an empty strip under the label is chrome.
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
class?: string;
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
// =========================
|
|
25
|
-
// PROPS
|
|
26
|
-
// =========================
|
|
27
|
-
let { label, action, children, class: className }: Props = $props();
|
|
24
|
+
// =========================
|
|
25
|
+
// PROPS
|
|
26
|
+
// =========================
|
|
27
|
+
let { label, action, children, class: className }: Props = $props();
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
30
|
<!-- =========================== -->
|