@heyramzi/ui 2.0.1 → 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 +48 -24
- 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/README.md +9 -12
- 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 +8 -4
- 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/index.ts +1 -0
- package/src/components/section-header/section-header.svelte +1 -1
- package/src/components/section-header/section-header.test.ts +7 -1
- package/src/components/section-header/section-label.svelte +39 -0
- 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/index.ts +2 -0
- package/src/components/{list-page → toolbar}/toolbar-search.svelte +25 -25
- package/src/components/toolbar/toolbar.svelte +13 -9
- 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 +27 -0
- package/src/inbox/inbox.test.ts +214 -0
- package/src/inbox/index.ts +31 -0
- package/src/inbox/logic.ts +169 -0
- package/src/inbox/thread-inbox.svelte +439 -0
- package/src/inbox/types.ts +161 -0
- 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 +105 -0
- 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/README.md +5 -0
- package/src/panel/index.ts +2 -0
- package/src/panel/side-panel.svelte +194 -0
- package/src/record/README.md +3 -0
- package/src/record/demo-data.ts +352 -0
- package/src/record/field-section.svelte +57 -0
- package/src/record/fields.ts +194 -0
- package/src/record/format.ts +94 -0
- package/src/{tasks/record → record}/index.ts +49 -35
- package/src/{tasks/record → record}/info-list.svelte +145 -114
- package/src/record/kinds.ts +42 -0
- package/src/record/logic.ts +326 -0
- package/src/record/next-up.svelte +81 -0
- package/src/{tasks/record → record}/project-list.svelte +56 -50
- package/src/{tasks/record → record}/record-demo.svelte +130 -110
- package/src/{tasks/record → record}/record-header.svelte +37 -28
- package/src/{tasks/record → record}/record-shell.svelte +54 -54
- package/src/record/record-stats.svelte +48 -0
- package/src/record/record-timeline.svelte +251 -0
- package/src/record/record.test.ts +471 -0
- package/src/{tasks/record → record}/steps-rail.svelte +225 -216
- package/src/record/types.ts +299 -0
- package/src/record/where-we-are.svelte +125 -0
- 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/README.md +18 -0
- package/src/status/define-statuses.ts +25 -0
- package/src/status/index.ts +11 -0
- package/src/{tasks → status}/status-badge.svelte +3 -1
- package/src/{tasks → status}/status-dot.svelte +1 -3
- package/src/{tasks → status}/status-icon.svelte +1 -1
- package/src/status/status-types.ts +40 -0
- package/src/tasks/README.md +1 -1
- package/src/tasks/board-order.ts +2 -4
- package/src/tasks/demo.svelte +192 -34
- package/src/tasks/detail/detail-demo.svelte +75 -15
- 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 +4 -2
- package/src/tasks/gantt/logic.test.ts +110 -20
- package/src/tasks/gantt/logic.ts +42 -6
- package/src/tasks/inbox/inbox-card.svelte +15 -7
- 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 +24 -24
- 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 +52 -53
- package/src/tasks/kanban-board.svelte +16 -12
- package/src/tasks/kanban-types.ts +2 -3
- package/src/tasks/presets/sales.ts +7 -7
- 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/README.md +31 -0
- package/src/thread/index.ts +12 -0
- package/src/thread/logic.ts +61 -0
- package/src/thread/thread.svelte +432 -0
- package/src/thread/thread.test.ts +73 -0
- package/src/thread/types.ts +93 -0
- 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/components/list-page/section-label.svelte +0 -39
- package/src/tasks/define-statuses.ts +0 -32
- package/src/tasks/inbox/inbox.svelte +0 -203
- package/src/tasks/record/demo-data.ts +0 -286
- package/src/tasks/record/field-section.svelte +0 -53
- package/src/tasks/record/fields.ts +0 -142
- package/src/tasks/record/format.ts +0 -87
- package/src/tasks/record/kinds.ts +0 -42
- package/src/tasks/record/logic.ts +0 -324
- package/src/tasks/record/next-up.svelte +0 -70
- package/src/tasks/record/record-stats.svelte +0 -48
- package/src/tasks/record/record-timeline.svelte +0 -231
- package/src/tasks/record/record.test.ts +0 -350
- package/src/tasks/record/types.ts +0 -280
- package/src/tasks/record/where-we-are.svelte +0 -121
- package/src/tasks/side-panel.svelte +0 -193
- package/src/tasks/status-types.ts +0 -40
- /package/src/components/{list-page → toolbar}/toolbar-trigger.ts +0 -0
- /package/src/{tasks → panel}/side-panel-types.ts +0 -0
- /package/src/{tasks/record → record}/gutter.ts +0 -0
|
@@ -1,43 +1,46 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
6
|
-
import { cn } from "../../lib/utils.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { cn } from "../../lib/utils.js";
|
|
7
|
+
import {
|
|
8
|
+
segmentedTrackClass,
|
|
9
|
+
type SegmentedVariant,
|
|
10
|
+
} from "./segmented.js";
|
|
11
|
+
import { slidingPill } from "../../lib/sliding-pill.js";
|
|
12
|
+
|
|
13
|
+
// =========================
|
|
14
|
+
// TYPES
|
|
15
|
+
// =========================
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Fill the row rather than sit at its natural width. */
|
|
18
|
+
fill?: boolean;
|
|
19
|
+
/** `pill`, a bordered well with a travelling highlight, or `underline`, a travelling rule. */
|
|
20
|
+
variant?: SegmentedVariant;
|
|
21
|
+
class?: string;
|
|
22
|
+
children: Snippet;
|
|
23
|
+
/**
|
|
24
|
+
* A last segment that isn't an item: today the overflow trigger. It's inside
|
|
25
|
+
* the track but outside the ARIA container, so a `tablist` owns only tabs.
|
|
26
|
+
*/
|
|
27
|
+
after?: Snippet;
|
|
28
|
+
// What the ARIA shapes differ by: `role`/`aria-label` for the filter, nothing
|
|
29
|
+
// for the nav (its <nav> has it), bits-ui's wiring for tabs.
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// =========================
|
|
34
|
+
// PROPS
|
|
35
|
+
// =========================
|
|
36
|
+
let {
|
|
37
|
+
fill = false,
|
|
38
|
+
variant = "pill",
|
|
39
|
+
class: className,
|
|
40
|
+
children,
|
|
41
|
+
after,
|
|
42
|
+
...rest
|
|
43
|
+
}: Props = $props();
|
|
41
44
|
</script>
|
|
42
45
|
|
|
43
46
|
<!-- =========================== -->
|
|
@@ -86,7 +89,10 @@ let {
|
|
|
86
89
|
.track :global(.ui-segment[data-state="active"] + .ui-segment)::before,
|
|
87
90
|
.track :global(.ui-segment[aria-current="page"] + .ui-segment)::before,
|
|
88
91
|
.track :global(.ui-segment[aria-pressed="true"] + .ui-segment)::before,
|
|
89
|
-
.track
|
|
92
|
+
.track
|
|
93
|
+
:global(
|
|
94
|
+
[data-slot="tabs-list"]:has(> .ui-segment:last-child[data-state="active"]) + .ui-segment
|
|
95
|
+
)::before {
|
|
90
96
|
opacity: 0;
|
|
91
97
|
}
|
|
92
98
|
|
|
@@ -109,7 +115,12 @@ let {
|
|
|
109
115
|
@media (hover: hover) {
|
|
110
116
|
.track
|
|
111
117
|
:global(
|
|
112
|
-
.ui-segment:hover:not(
|
|
118
|
+
.ui-segment:hover:not(
|
|
119
|
+
[data-state="active"],
|
|
120
|
+
[aria-current="page"],
|
|
121
|
+
[aria-pressed="true"],
|
|
122
|
+
[data-state="open"]
|
|
123
|
+
)
|
|
113
124
|
) {
|
|
114
125
|
background-color: color-mix(in oklch, var(--color-muted) 55%, transparent);
|
|
115
126
|
}
|
|
@@ -139,7 +150,8 @@ let {
|
|
|
139
150
|
|
|
140
151
|
/* Before the attachment measures, the active segment draws the pill itself,
|
|
141
152
|
so a server-rendered strip is right before any JS arrives. */
|
|
142
|
-
.track:not([data-pill="on"])
|
|
153
|
+
.track:not([data-pill="on"])
|
|
154
|
+
:global(:is([data-state="active"], [aria-current="page"], [aria-pressed="true"])) {
|
|
143
155
|
background-color: var(--color-muted);
|
|
144
156
|
box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--color-foreground) 6%, transparent);
|
|
145
157
|
}
|
|
@@ -153,7 +165,12 @@ let {
|
|
|
153
165
|
@media (hover: hover) {
|
|
154
166
|
.track[data-variant="underline"]
|
|
155
167
|
:global(
|
|
156
|
-
.ui-segment:hover:not(
|
|
168
|
+
.ui-segment:hover:not(
|
|
169
|
+
[data-state="active"],
|
|
170
|
+
[aria-current="page"],
|
|
171
|
+
[aria-pressed="true"],
|
|
172
|
+
[data-state="open"]
|
|
173
|
+
)
|
|
157
174
|
) {
|
|
158
175
|
background-color: transparent;
|
|
159
176
|
}
|
|
@@ -174,9 +191,8 @@ let {
|
|
|
174
191
|
box-shadow: inset 0 -2px 0 var(--segmented-rule, var(--color-foreground));
|
|
175
192
|
}
|
|
176
193
|
|
|
177
|
-
/* On a coarse pointer the well
|
|
178
|
-
|
|
179
|
-
over the segments, and the pill keeps its 2px gap inside that ring. */
|
|
194
|
+
/* On a coarse pointer the well grows to 44px and its segments are the hit area, since a
|
|
195
|
+
clipped well can't hold one hanging outside it. */
|
|
180
196
|
@media (any-pointer: coarse) {
|
|
181
197
|
.track[data-variant="pill"]::after {
|
|
182
198
|
content: "";
|
|
@@ -52,9 +52,8 @@ export const segmentedTriggerClass = tv({
|
|
|
52
52
|
"h-full text-xs",
|
|
53
53
|
],
|
|
54
54
|
variants: {
|
|
55
|
-
// The pill
|
|
56
|
-
//
|
|
57
|
-
// rule under a label is as wide as the label.
|
|
55
|
+
// The pill sits concentric in the track's 2px inset; the underline has no well, so
|
|
56
|
+
// no padding, and its rule is as wide as the label.
|
|
58
57
|
variant: {
|
|
59
58
|
pill: "rounded-[calc(var(--radius-lg)-3px)] px-2.5 any-pointer-coarse:px-3.5",
|
|
60
59
|
underline: "rounded-sm px-0",
|
|
@@ -1,109 +1,109 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// A middle `md` step used to exist. Nobody could place it, so the same question
|
|
7
|
-
// ended up asked at three sizes.
|
|
8
|
-
export type StarRatingSize = "sm" | "lg";
|
|
9
|
-
|
|
10
|
-
const STAR_SIZE: Record<StarRatingSize, string> = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const HIT_SIZE: Record<StarRatingSize, string> = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/** Pop duration plus the longest stagger, after which the class can come off. */
|
|
21
|
-
const POP_WINDOW_MS = 350 + 4 * 40;
|
|
2
|
+
/**
|
|
3
|
+
* Two sizes, picked by the job: `sm` reads a value back in a row or cell,
|
|
4
|
+
* `lg` is the ask.
|
|
5
|
+
*/
|
|
6
|
+
// A middle `md` step used to exist. Nobody could place it, so the same question
|
|
7
|
+
// ended up asked at three sizes.
|
|
8
|
+
export type StarRatingSize = "sm" | "lg";
|
|
9
|
+
|
|
10
|
+
const STAR_SIZE: Record<StarRatingSize, string> = {
|
|
11
|
+
sm: "size-4",
|
|
12
|
+
lg: "size-7",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const HIT_SIZE: Record<StarRatingSize, string> = {
|
|
16
|
+
sm: "p-0.5",
|
|
17
|
+
lg: "p-1",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Pop duration plus the longest stagger, after which the class can come off. */
|
|
21
|
+
const POP_WINDOW_MS = 350 + 4 * 40;
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
24
|
<script lang="ts">
|
|
25
|
-
import { Star } from "phosphor-svelte";
|
|
26
|
-
import { cn } from "../../lib/utils.js";
|
|
27
|
-
|
|
28
|
-
interface Props {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
let {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}: Props = $props();
|
|
64
|
-
|
|
65
|
-
let hover = $state(0);
|
|
66
|
-
/** Held for the length of the pop, then dropped so the next pick can replay it. */
|
|
67
|
-
let popping = $state(false);
|
|
68
|
-
let popTimer: ReturnType<typeof setTimeout> | undefined;
|
|
69
|
-
let displayed = $derived(hover || value);
|
|
70
|
-
let starSize = $derived(STAR_SIZE[size]);
|
|
71
|
-
let hitSize = $derived(HIT_SIZE[size]);
|
|
72
|
-
let groupAriaLabel = $derived(ariaLabel ?? `Rating, ${max} stars`);
|
|
73
|
-
let labelText = $derived(
|
|
74
|
-
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
function buttonAriaLabel(step: number): string {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function setRating(step: number) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function handleEnter(step: number) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function handleLeave() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
25
|
+
import { Star } from "phosphor-svelte";
|
|
26
|
+
import { cn } from "../../lib/utils.js";
|
|
27
|
+
|
|
28
|
+
interface Props {
|
|
29
|
+
/** Current rating value (0 = unrated). */
|
|
30
|
+
value: number;
|
|
31
|
+
/** Maximum rating. Defaults to 5. */
|
|
32
|
+
max?: number;
|
|
33
|
+
/** Visual size of each star. `sm` reads back, `lg` asks. */
|
|
34
|
+
size?: StarRatingSize;
|
|
35
|
+
/** Render as static display, no hover or click. */
|
|
36
|
+
readonly?: boolean;
|
|
37
|
+
/** Disable interaction. */
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/** Form field name for native submission. When set, a hidden input is rendered. */
|
|
40
|
+
name?: string;
|
|
41
|
+
/** ARIA label for the radiogroup. */
|
|
42
|
+
ariaLabel?: string;
|
|
43
|
+
/** Per-step descriptive labels (length must equal max). */
|
|
44
|
+
labels?: readonly string[];
|
|
45
|
+
/** Show the label of the currently hovered/selected step beside the stars. */
|
|
46
|
+
showLabel?: boolean;
|
|
47
|
+
class?: string;
|
|
48
|
+
onchange?: (value: number) => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let {
|
|
52
|
+
value = $bindable(0),
|
|
53
|
+
max = 5,
|
|
54
|
+
size = "sm",
|
|
55
|
+
readonly = false,
|
|
56
|
+
disabled = false,
|
|
57
|
+
name,
|
|
58
|
+
ariaLabel,
|
|
59
|
+
labels,
|
|
60
|
+
showLabel = false,
|
|
61
|
+
class: className,
|
|
62
|
+
onchange,
|
|
63
|
+
}: Props = $props();
|
|
64
|
+
|
|
65
|
+
let hover = $state(0);
|
|
66
|
+
/** Held for the length of the pop, then dropped so the next pick can replay it. */
|
|
67
|
+
let popping = $state(false);
|
|
68
|
+
let popTimer: ReturnType<typeof setTimeout> | undefined;
|
|
69
|
+
let displayed = $derived(hover || value);
|
|
70
|
+
let starSize = $derived(STAR_SIZE[size]);
|
|
71
|
+
let hitSize = $derived(HIT_SIZE[size]);
|
|
72
|
+
let groupAriaLabel = $derived(ariaLabel ?? `Rating, ${max} stars`);
|
|
73
|
+
let labelText = $derived(
|
|
74
|
+
displayed > 0 && labels && labels.length >= displayed ? labels[displayed - 1] : "",
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
function buttonAriaLabel(step: number): string {
|
|
78
|
+
const stepLabel = labels?.[step - 1];
|
|
79
|
+
const base = `${step} of ${max}`;
|
|
80
|
+
return stepLabel ? `${base} (${stepLabel})` : base;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function setRating(step: number) {
|
|
84
|
+
if (readonly || disabled) return;
|
|
85
|
+
value = step;
|
|
86
|
+
onchange?.(step);
|
|
87
|
+
|
|
88
|
+
// Drop the class before re-adding it, or a second pick inside the animation
|
|
89
|
+
// window finds it already set and nothing replays.
|
|
90
|
+
popping = false;
|
|
91
|
+
clearTimeout(popTimer);
|
|
92
|
+
requestAnimationFrame(() => {
|
|
93
|
+
popping = true;
|
|
94
|
+
popTimer = setTimeout(() => (popping = false), POP_WINDOW_MS);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function handleEnter(step: number) {
|
|
99
|
+
if (readonly || disabled) return;
|
|
100
|
+
hover = step;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function handleLeave() {
|
|
104
|
+
if (readonly || disabled) return;
|
|
105
|
+
hover = 0;
|
|
106
|
+
}
|
|
107
107
|
</script>
|
|
108
108
|
|
|
109
109
|
<!-- One star, drawn once. It used to be written twice, once per branch, and the
|
|
@@ -152,7 +152,7 @@ function handleLeave() {
|
|
|
152
152
|
{/if}
|
|
153
153
|
|
|
154
154
|
{#if name}
|
|
155
|
-
<input type="hidden" {name}
|
|
155
|
+
<input type="hidden" {name} {value} />
|
|
156
156
|
{/if}
|
|
157
157
|
</div>
|
|
158
158
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// Renders a drawing kept in its own .svg file, imported with `?raw`.
|
|
3
|
-
// The markup is ours and static, so rendering it as HTML is safe.
|
|
4
|
-
let { src, class: className = "" }: { src: string; class?: string } = $props();
|
|
2
|
+
// Renders a drawing kept in its own .svg file, imported with `?raw`.
|
|
3
|
+
// The markup is ours and static, so rendering it as HTML is safe.
|
|
4
|
+
let { src, class: className = "" }: { src: string; class?: string } = $props();
|
|
5
5
|
|
|
6
|
-
const markup = $derived(className ? src.replace("<svg", `<svg class="${className}"`) : src);
|
|
6
|
+
const markup = $derived(className ? src.replace("<svg", `<svg class="${className}"`) : src);
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
9
|
{@html markup}
|
|
@@ -36,7 +36,17 @@
|
|
|
36
36
|
// =========================
|
|
37
37
|
// PROPS
|
|
38
38
|
// =========================
|
|
39
|
-
let {
|
|
39
|
+
let {
|
|
40
|
+
columns,
|
|
41
|
+
rows,
|
|
42
|
+
rowKey,
|
|
43
|
+
label,
|
|
44
|
+
footer,
|
|
45
|
+
cell,
|
|
46
|
+
rowClass,
|
|
47
|
+
minWidth = "0",
|
|
48
|
+
class: className,
|
|
49
|
+
}: Props = $props();
|
|
40
50
|
|
|
41
51
|
// =========================
|
|
42
52
|
// FUNCTIONS
|
|
@@ -63,7 +73,12 @@
|
|
|
63
73
|
)}
|
|
64
74
|
>
|
|
65
75
|
{#if cell}
|
|
66
|
-
{@render cell({
|
|
76
|
+
{@render cell({
|
|
77
|
+
row,
|
|
78
|
+
column,
|
|
79
|
+
value: (row as Record<string, unknown>)[column.key],
|
|
80
|
+
text: textOf(column, row),
|
|
81
|
+
})}
|
|
67
82
|
{:else}
|
|
68
83
|
{textOf(column, row)}
|
|
69
84
|
{/if}
|
|
@@ -25,7 +25,13 @@ function render(extra: Record<string, unknown> = {}) {
|
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
27
|
flushSync();
|
|
28
|
-
return {
|
|
28
|
+
return {
|
|
29
|
+
target,
|
|
30
|
+
done: () => {
|
|
31
|
+
void unmount(app);
|
|
32
|
+
target.remove();
|
|
33
|
+
},
|
|
34
|
+
};
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
describe("TableView", () => {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/** One column of a `TableView`. */
|
|
2
2
|
export interface TableColumn<Row> {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
/** The key of the value in the row. */
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
/** A number or an amount: right-aligned, tabular figures, never wraps. */
|
|
7
|
+
numeric?: boolean;
|
|
8
|
+
/** Turns the raw value into the text shown. A string value that has no `format` prints as it is. A money column passes its own currency formatter. */
|
|
9
|
+
format?: (value: unknown, row: Row) => string;
|
|
10
|
+
/** A column width such as `"30%"` or `"8rem"`. Leave it out and the table shares the rest. */
|
|
11
|
+
width?: string;
|
|
12
|
+
/** Draws the column in the muted colour. */
|
|
13
|
+
muted?: boolean;
|
|
14
14
|
}
|