@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,10 +1,5 @@
|
|
|
1
|
-
/* Thinking states
|
|
2
|
-
|
|
3
|
-
swap: JS exits the old line upward and enters the new one from below, held
|
|
4
|
-
back by --think-gap. The sweep is `.t-shimmer` from shimmer-text.css — put
|
|
5
|
-
both classes on the line and keep data-text in sync with the text, or the
|
|
6
|
-
shimmer paints the wrong words. The hidden sizer carries your longest state
|
|
7
|
-
and is what stops the box resizing mid-swap. */
|
|
1
|
+
/* Thinking states, transitions.dev 28: put `.t-shimmer` on the line too and
|
|
2
|
+
keep data-text in sync with the text, or the shimmer paints the wrong words. */
|
|
8
3
|
:root {
|
|
9
4
|
--think-hold: 2000ms;
|
|
10
5
|
--think-swap: var(--duration-quick, 150ms);
|
package/src/brand/brand.test.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { readFileSync, readdirSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { describe, expect, it } from "vite-plus/test";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
BRAND_COLOR_VARS,
|
|
6
|
+
applyBrand,
|
|
7
|
+
brandCss,
|
|
8
|
+
brandStyle,
|
|
9
|
+
brandVars,
|
|
10
|
+
defineBrand,
|
|
11
|
+
} from "./index.js";
|
|
5
12
|
|
|
6
13
|
const TOKENS = join(import.meta.dirname, "..", "tokens");
|
|
7
14
|
const palette = readFileSync(join(TOKENS, "palette.css"), "utf8");
|
|
@@ -9,7 +16,10 @@ const palette = readFileSync(join(TOKENS, "palette.css"), "utf8");
|
|
|
9
16
|
describe("brandVars", () => {
|
|
10
17
|
it("sets only the roles a brand names", () => {
|
|
11
18
|
const brand = defineBrand({ colors: { brand: "oklch(0.5 0.2 272)", signal: "#f0503d" } });
|
|
12
|
-
expect(brandVars(brand)).toEqual({
|
|
19
|
+
expect(brandVars(brand)).toEqual({
|
|
20
|
+
"--brand": "oklch(0.5 0.2 272)",
|
|
21
|
+
"--brand-signal": "#f0503d",
|
|
22
|
+
});
|
|
13
23
|
});
|
|
14
24
|
|
|
15
25
|
it("maps fonts and extra properties", () => {
|
|
@@ -27,7 +37,9 @@ describe("brandVars", () => {
|
|
|
27
37
|
});
|
|
28
38
|
|
|
29
39
|
it("refuses a value that would break out of its declaration", () => {
|
|
30
|
-
expect(() => brandVars({ colors: { brand: "red; } body { display: none" } })).toThrow(
|
|
40
|
+
expect(() => brandVars({ colors: { brand: "red; } body { display: none" } })).toThrow(
|
|
41
|
+
/--brand/,
|
|
42
|
+
);
|
|
31
43
|
});
|
|
32
44
|
});
|
|
33
45
|
|
|
@@ -36,7 +48,9 @@ describe("the three ways to apply one", () => {
|
|
|
36
48
|
|
|
37
49
|
it("writes a style attribute and a rule", () => {
|
|
38
50
|
expect(brandStyle(brand)).toBe("--brand:blue;--brand-ink:black");
|
|
39
|
-
expect(brandCss(brand, ".client")).toBe(
|
|
51
|
+
expect(brandCss(brand, ".client")).toBe(
|
|
52
|
+
".client {\n --brand: blue;\n --brand-ink: black;\n}\n",
|
|
53
|
+
);
|
|
40
54
|
});
|
|
41
55
|
|
|
42
56
|
it("applies to an element and puts back what it found", () => {
|
|
@@ -61,7 +75,9 @@ describe("the tokens", () => {
|
|
|
61
75
|
it("carry no client palette", () => {
|
|
62
76
|
for (const file of readdirSync(TOKENS).filter((f) => f.endsWith(".css"))) {
|
|
63
77
|
const css = readFileSync(join(TOKENS, file), "utf8");
|
|
64
|
-
expect(css, file).not.toMatch(
|
|
78
|
+
expect(css, file).not.toMatch(
|
|
79
|
+
/brand-(indigo|sand|terra|night|veil|dusk|cream|linen|mist)|--(indigo|sand|terra)-\d/,
|
|
80
|
+
);
|
|
65
81
|
}
|
|
66
82
|
});
|
|
67
83
|
});
|
package/src/brand/index.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A
|
|
3
|
-
*
|
|
4
|
-
* export const brand = defineBrand({ colors: { brand: "oklch(0.5 0.2 272)" } });
|
|
5
|
-
*
|
|
6
|
-
* `@heyramzi/ui/tokens.css` ships a neutral look. A brand replaces only the roles it names:
|
|
7
|
-
* - on the server, put `brandStyle(brand)` on the `<html style>` so the first paint is right;
|
|
8
|
-
* - or call `applyBrand(brand)` once in the browser;
|
|
9
|
-
* - or write `brandCss(brand)` into a stylesheet.
|
|
10
|
-
* Light and dark come from the tokens, which read these roles, so a brand never types both.
|
|
2
|
+
* A brand replaces only the token roles it names. Put `brandStyle(brand)` on the server's
|
|
3
|
+
* `<html style>`, or the first paint shows the neutral look.
|
|
11
4
|
*/
|
|
12
5
|
|
|
13
6
|
/** Any CSS colour: oklch(), hex, a named colour or a var(). */
|
|
@@ -86,7 +79,8 @@ export function defineBrand<const B extends Brand>(brand: B): B {
|
|
|
86
79
|
}
|
|
87
80
|
|
|
88
81
|
function checked(name: string, value: string): string {
|
|
89
|
-
if (/[;{}<>]/.test(value))
|
|
82
|
+
if (/[;{}<>]/.test(value))
|
|
83
|
+
throw new Error(`brand: ${name} holds a character CSS would read as more than a value`);
|
|
90
84
|
return value;
|
|
91
85
|
}
|
|
92
86
|
|
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
6
|
-
import { getDiagramEditorContext } from "../editor/editor-context.js";
|
|
7
|
-
import { isLocked } from "../editor/lock.js";
|
|
8
|
-
import { userHeightOf, type CardResize } from "./resize.js";
|
|
9
|
-
import ResizeHandles from "./resize-handles.svelte";
|
|
10
|
-
import "./card.css";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { getDiagramEditorContext } from "../editor/editor-context.js";
|
|
7
|
+
import { isLocked } from "../editor/lock.js";
|
|
8
|
+
import { userHeightOf, type CardResize } from "./resize.js";
|
|
9
|
+
import ResizeHandles from "./resize-handles.svelte";
|
|
10
|
+
import "./card.css";
|
|
11
11
|
|
|
12
|
-
// The frame every card sits in: it keeps the saved height as a floor and draws the grips
|
|
13
|
-
// on a selected card. A card whose policy is `false` has neither.
|
|
12
|
+
// The frame every card sits in: it keeps the saved height as a floor and draws the grips
|
|
13
|
+
// on a selected card. A card whose policy is `false` has neither.
|
|
14
14
|
|
|
15
|
-
// =========================
|
|
16
|
-
// TYPES
|
|
17
|
-
// =========================
|
|
18
|
-
interface Props {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
15
|
+
// =========================
|
|
16
|
+
// TYPES
|
|
17
|
+
// =========================
|
|
18
|
+
interface Props {
|
|
19
|
+
id: string;
|
|
20
|
+
data?: unknown;
|
|
21
|
+
selected?: boolean;
|
|
22
|
+
/** How this card type resizes, or false when its size isn't the person's to set. */
|
|
23
|
+
resize: CardResize | false;
|
|
24
|
+
children: Snippet;
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
// =========================
|
|
28
|
-
// PROPS
|
|
29
|
-
// =========================
|
|
30
|
-
let { id, data, selected = false, resize, children }: Props = $props();
|
|
27
|
+
// =========================
|
|
28
|
+
// PROPS
|
|
29
|
+
// =========================
|
|
30
|
+
let { id, data, selected = false, resize, children }: Props = $props();
|
|
31
31
|
|
|
32
|
-
// =========================
|
|
33
|
-
// STATE
|
|
34
|
-
// =========================
|
|
35
|
-
const editor = getDiagramEditorContext();
|
|
36
|
-
let frame = $state<HTMLElement>();
|
|
32
|
+
// =========================
|
|
33
|
+
// STATE
|
|
34
|
+
// =========================
|
|
35
|
+
const editor = getDiagramEditorContext();
|
|
36
|
+
let frame = $state<HTMLElement>();
|
|
37
37
|
|
|
38
|
-
// =========================
|
|
39
|
-
// DERIVED
|
|
40
|
-
// =========================
|
|
41
|
-
let floor = $derived(userHeightOf(data));
|
|
42
|
-
// A box card is sized by the node itself, so it needs no frame.
|
|
43
|
-
let framed = $derived(!!resize && resize.store !== "box");
|
|
44
|
-
let grips = $derived(!!resize && !!editor && selected && !isLocked({ data }));
|
|
38
|
+
// =========================
|
|
39
|
+
// DERIVED
|
|
40
|
+
// =========================
|
|
41
|
+
let floor = $derived(userHeightOf(data));
|
|
42
|
+
// A box card is sized by the node itself, so it needs no frame.
|
|
43
|
+
let framed = $derived(!!resize && resize.store !== "box");
|
|
44
|
+
let grips = $derived(!!resize && !!editor && selected && !isLocked({ data }));
|
|
45
45
|
</script>
|
|
46
46
|
|
|
47
47
|
<!-- =========================== -->
|
|
@@ -53,7 +53,11 @@ let grips = $derived(!!resize && !!editor && selected && !isLocked({ data }));
|
|
|
53
53
|
{/if}
|
|
54
54
|
|
|
55
55
|
{#if framed}
|
|
56
|
-
<div
|
|
56
|
+
<div
|
|
57
|
+
class="cv-card-frame"
|
|
58
|
+
bind:this={frame}
|
|
59
|
+
style:--cv-card-h={floor > 0 ? `${floor}px` : undefined}
|
|
60
|
+
>
|
|
57
61
|
{@render children()}
|
|
58
62
|
</div>
|
|
59
63
|
{:else}
|
|
@@ -1,98 +1,103 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import { NodeResizeControl, ResizeControlVariant, useSvelteFlow } from "@xyflow/svelte";
|
|
6
|
-
import { getDiagramEditorContext } from "../editor/editor-context.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "./resize.js";
|
|
14
|
-
import "./card.css";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import { NodeResizeControl, ResizeControlVariant, useSvelteFlow } from "@xyflow/svelte";
|
|
6
|
+
import { getDiagramEditorContext } from "../editor/editor-context.js";
|
|
7
|
+
import {
|
|
8
|
+
DEFAULT_MAX_WIDTH,
|
|
9
|
+
DEFAULT_MIN_HEIGHT,
|
|
10
|
+
DEFAULT_MIN_WIDTH,
|
|
11
|
+
keptHeight,
|
|
12
|
+
type CardResize,
|
|
13
|
+
} from "./resize.js";
|
|
14
|
+
import "./card.css";
|
|
15
15
|
|
|
16
|
-
// The grips of a selected card. One drag is one undo step: width, kept height and extra data close together.
|
|
16
|
+
// The grips of a selected card. One drag is one undo step: width, kept height and extra data close together.
|
|
17
17
|
|
|
18
|
-
// =========================
|
|
19
|
-
// TYPES
|
|
20
|
-
// =========================
|
|
21
|
-
interface Props {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
18
|
+
// =========================
|
|
19
|
+
// TYPES
|
|
20
|
+
// =========================
|
|
21
|
+
interface Props {
|
|
22
|
+
id: string;
|
|
23
|
+
resize: CardResize;
|
|
24
|
+
/** The framed element, read for the height its content needs. */
|
|
25
|
+
frame?: HTMLElement;
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
// =========================
|
|
29
|
-
// CONSTANTS
|
|
30
|
-
// =========================
|
|
31
|
-
const CORNERS = ["top-left", "top-right", "bottom-left", "bottom-right"] as const;
|
|
32
|
-
const EDGES = ["left", "right", "top", "bottom"] as const;
|
|
33
|
-
const SIDES = ["left", "right"] as const;
|
|
28
|
+
// =========================
|
|
29
|
+
// CONSTANTS
|
|
30
|
+
// =========================
|
|
31
|
+
const CORNERS = ["top-left", "top-right", "bottom-left", "bottom-right"] as const;
|
|
32
|
+
const EDGES = ["left", "right", "top", "bottom"] as const;
|
|
33
|
+
const SIDES = ["left", "right"] as const;
|
|
34
34
|
|
|
35
|
-
// =========================
|
|
36
|
-
// PROPS
|
|
37
|
-
// =========================
|
|
38
|
-
let { id, resize, frame }: Props = $props();
|
|
35
|
+
// =========================
|
|
36
|
+
// PROPS
|
|
37
|
+
// =========================
|
|
38
|
+
let { id, resize, frame }: Props = $props();
|
|
39
39
|
|
|
40
|
-
// =========================
|
|
41
|
-
// STATE
|
|
42
|
-
// =========================
|
|
43
|
-
const editor = getDiagramEditorContext();
|
|
44
|
-
const { updateNode } = useSvelteFlow();
|
|
45
|
-
let endGesture: (() => void) | null = null;
|
|
46
|
-
// The height the content needs, read when a drag starts.
|
|
47
|
-
let contentHeight = $state(DEFAULT_MIN_HEIGHT);
|
|
40
|
+
// =========================
|
|
41
|
+
// STATE
|
|
42
|
+
// =========================
|
|
43
|
+
const editor = getDiagramEditorContext();
|
|
44
|
+
const { updateNode } = useSvelteFlow();
|
|
45
|
+
let endGesture: (() => void) | null = null;
|
|
46
|
+
// The height the content needs, read when a drag starts.
|
|
47
|
+
let contentHeight = $state(DEFAULT_MIN_HEIGHT);
|
|
48
48
|
|
|
49
|
-
// =========================
|
|
50
|
-
// DERIVED
|
|
51
|
-
// =========================
|
|
52
|
-
let both = $derived(resize.axes === "both");
|
|
53
|
-
let ratio = $derived(resize.axes === "ratio");
|
|
54
|
-
let direction = $derived(both || ratio ? undefined : ("horizontal" as const));
|
|
55
|
-
let box = $derived(resize.store === "box");
|
|
56
|
-
let minWidth = $derived(resize.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
57
|
-
let maxWidth = $derived(resize.maxWidth ?? DEFAULT_MAX_WIDTH);
|
|
58
|
-
let minHeight = $derived(both && !box ? contentHeight : (resize.minHeight ?? DEFAULT_MIN_HEIGHT));
|
|
49
|
+
// =========================
|
|
50
|
+
// DERIVED
|
|
51
|
+
// =========================
|
|
52
|
+
let both = $derived(resize.axes === "both");
|
|
53
|
+
let ratio = $derived(resize.axes === "ratio");
|
|
54
|
+
let direction = $derived(both || ratio ? undefined : ("horizontal" as const));
|
|
55
|
+
let box = $derived(resize.store === "box");
|
|
56
|
+
let minWidth = $derived(resize.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
57
|
+
let maxWidth = $derived(resize.maxWidth ?? DEFAULT_MAX_WIDTH);
|
|
58
|
+
let minHeight = $derived(both && !box ? contentHeight : (resize.minHeight ?? DEFAULT_MIN_HEIGHT));
|
|
59
59
|
|
|
60
|
-
// =========================
|
|
61
|
-
// FUNCTIONS
|
|
62
|
-
// =========================
|
|
63
|
-
function measureContent() {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
60
|
+
// =========================
|
|
61
|
+
// FUNCTIONS
|
|
62
|
+
// =========================
|
|
63
|
+
function measureContent() {
|
|
64
|
+
if (!frame) return;
|
|
65
|
+
// With the saved floor dropped, the frame is as tall as the content needs.
|
|
66
|
+
frame.setAttribute("data-resizing", "");
|
|
67
|
+
contentHeight = Math.max(DEFAULT_MIN_HEIGHT, Math.ceil(frame.offsetHeight));
|
|
68
|
+
}
|
|
69
69
|
|
|
70
|
-
function start() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
70
|
+
function start() {
|
|
71
|
+
endGesture = editor?.startGesture() ?? null;
|
|
72
|
+
if (both && !box) measureContent();
|
|
73
|
+
}
|
|
74
74
|
|
|
75
|
-
function finish(size: { width: number; height: number }) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
function finish(size: { width: number; height: number }) {
|
|
76
|
+
frame?.removeAttribute("data-resizing");
|
|
77
|
+
const width = Math.round(size.width);
|
|
78
|
+
if (!box) {
|
|
79
|
+
editor?.setNodeWidth(id, width);
|
|
80
|
+
const patch: Record<string, unknown> = {
|
|
81
|
+
...resize.extraData?.({ width, height: size.height }),
|
|
82
|
+
};
|
|
83
|
+
// A text card keeps growing with its words, and an image's height follows its width.
|
|
84
|
+
if (both) patch.userHeight = keptHeight(size.height, contentHeight);
|
|
85
|
+
if (Object.keys(patch).length > 0) editor?.patchNodeData(id, patch);
|
|
86
|
+
// The drag gave the node a height; the content and the saved floor size it from here.
|
|
87
|
+
updateNode(id, { height: undefined });
|
|
88
|
+
}
|
|
89
|
+
endGesture?.();
|
|
90
|
+
endGesture = null;
|
|
86
91
|
}
|
|
87
|
-
endGesture?.();
|
|
88
|
-
endGesture = null;
|
|
89
|
-
}
|
|
90
92
|
</script>
|
|
91
93
|
|
|
92
94
|
<!-- =========================== -->
|
|
93
95
|
<!-- MARKUP -->
|
|
94
96
|
<!-- =========================== -->
|
|
95
|
-
{#snippet control(
|
|
97
|
+
{#snippet control(
|
|
98
|
+
position: (typeof CORNERS)[number] | (typeof EDGES)[number],
|
|
99
|
+
variant: ResizeControlVariant,
|
|
100
|
+
)}
|
|
96
101
|
<NodeResizeControl
|
|
97
102
|
nodeId={id}
|
|
98
103
|
{position}
|
|
@@ -102,7 +107,11 @@ function finish(size: { width: number; height: number }) {
|
|
|
102
107
|
{minHeight}
|
|
103
108
|
keepAspectRatio={ratio}
|
|
104
109
|
resizeDirection={direction}
|
|
105
|
-
class={variant === ResizeControlVariant.Line
|
|
110
|
+
class={variant === ResizeControlVariant.Line
|
|
111
|
+
? "cv-edge"
|
|
112
|
+
: direction
|
|
113
|
+
? "cv-grip cv-grip-x"
|
|
114
|
+
: "cv-grip"}
|
|
106
115
|
onResizeStart={start}
|
|
107
116
|
onResizeEnd={(_, size) => finish(size)}
|
|
108
117
|
/>
|
|
@@ -1,120 +1,121 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import { useConnection, useStore } from "@xyflow/svelte";
|
|
6
|
-
import { untrack } from "svelte";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import { useConnection, useStore } from "@xyflow/svelte";
|
|
6
|
+
import { untrack } from "svelte";
|
|
7
7
|
|
|
8
|
-
// A root `--canvas-unzoom` restyled every card per zoom frame. It lives only on nodes showing chrome: selected, hovered, or all while a link is dragged.
|
|
8
|
+
// A root `--canvas-unzoom` restyled every card per zoom frame. It lives only on nodes showing chrome: selected, hovered, or all while a link is dragged.
|
|
9
9
|
|
|
10
|
-
// =========================
|
|
11
|
-
// CONSTANTS
|
|
12
|
-
// =========================
|
|
13
|
-
const MIN_ZOOM = 0.05;
|
|
14
|
-
const NODE = ".svelte-flow__node";
|
|
10
|
+
// =========================
|
|
11
|
+
// CONSTANTS
|
|
12
|
+
// =========================
|
|
13
|
+
const MIN_ZOOM = 0.05;
|
|
14
|
+
const NODE = ".svelte-flow__node";
|
|
15
15
|
|
|
16
|
-
// =========================
|
|
17
|
-
// STATE
|
|
18
|
-
// =========================
|
|
19
|
-
const store = useStore();
|
|
20
|
-
const connection = useConnection();
|
|
16
|
+
// =========================
|
|
17
|
+
// STATE
|
|
18
|
+
// =========================
|
|
19
|
+
const store = useStore();
|
|
20
|
+
const connection = useConnection();
|
|
21
21
|
|
|
22
|
-
// Plain collections: they change on selection and hover, never per frame, and nothing reads them reactively.
|
|
23
|
-
const selected = new Set<HTMLElement>();
|
|
24
|
-
let hovered: HTMLElement | null = null;
|
|
22
|
+
// Plain collections: they change on selection and hover, never per frame, and nothing reads them reactively.
|
|
23
|
+
const selected = new Set<HTMLElement>();
|
|
24
|
+
let hovered: HTMLElement | null = null;
|
|
25
25
|
|
|
26
|
-
// =========================
|
|
27
|
-
// DERIVED
|
|
28
|
-
// =========================
|
|
29
|
-
let unzoom = $derived(String(1 / Math.max(store.viewport.zoom, MIN_ZOOM)));
|
|
30
|
-
let linking = $derived(connection.current.inProgress);
|
|
26
|
+
// =========================
|
|
27
|
+
// DERIVED
|
|
28
|
+
// =========================
|
|
29
|
+
let unzoom = $derived(String(1 / Math.max(store.viewport.zoom, MIN_ZOOM)));
|
|
30
|
+
let linking = $derived(connection.current.inProgress);
|
|
31
31
|
|
|
32
|
-
// =========================
|
|
33
|
-
// FUNCTIONS
|
|
34
|
-
// =========================
|
|
35
|
-
const paint = (node: HTMLElement | null, value = unzoom) =>
|
|
32
|
+
// =========================
|
|
33
|
+
// FUNCTIONS
|
|
34
|
+
// =========================
|
|
35
|
+
const paint = (node: HTMLElement | null, value = unzoom) =>
|
|
36
|
+
node?.style.setProperty("--canvas-unzoom", value);
|
|
36
37
|
|
|
37
|
-
function paintShowing(value: string) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
paint(hovered, value);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Chrome that belongs to one card (grips, quick-add) hides while several are selected: see chrome.css.
|
|
46
|
-
function flagMulti() {
|
|
47
|
-
store.domNode?.toggleAttribute("data-cv-multi", selected.size > 1);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function track(node: HTMLElement) {
|
|
51
|
-
if (node.classList.contains("selected")) {
|
|
52
|
-
if (!selected.has(node)) {
|
|
53
|
-
selected.add(node);
|
|
54
|
-
paint(node);
|
|
38
|
+
function paintShowing(value: string) {
|
|
39
|
+
for (const node of selected) {
|
|
40
|
+
if (node.isConnected) paint(node, value);
|
|
41
|
+
else selected.delete(node);
|
|
55
42
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
43
|
+
paint(hovered, value);
|
|
44
|
+
}
|
|
59
45
|
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
paintShowing(unzoom);
|
|
65
|
-
});
|
|
46
|
+
// Chrome that belongs to one card (grips, quick-add) hides while several are selected: see chrome.css.
|
|
47
|
+
function flagMulti() {
|
|
48
|
+
store.domNode?.toggleAttribute("data-cv-multi", selected.size > 1);
|
|
49
|
+
}
|
|
66
50
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
51
|
+
function track(node: HTMLElement) {
|
|
52
|
+
if (node.classList.contains("selected")) {
|
|
53
|
+
if (!selected.has(node)) {
|
|
54
|
+
selected.add(node);
|
|
55
|
+
paint(node);
|
|
56
|
+
}
|
|
57
|
+
} else selected.delete(node);
|
|
58
|
+
flagMulti();
|
|
75
59
|
}
|
|
76
|
-
});
|
|
77
60
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
85
|
-
root.addEventListener("pointerover", over, { passive: true });
|
|
61
|
+
// =========================
|
|
62
|
+
// EFFECTS
|
|
63
|
+
// =========================
|
|
64
|
+
$effect(() => {
|
|
65
|
+
paintShowing(unzoom);
|
|
66
|
+
});
|
|
86
67
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
68
|
+
$effect(() => {
|
|
69
|
+
const root = store.domNode;
|
|
70
|
+
if (!root) return;
|
|
71
|
+
if (linking) {
|
|
72
|
+
root.dataset.cvLinking = "";
|
|
73
|
+
const value = unzoom;
|
|
74
|
+
for (const node of root.querySelectorAll<HTMLElement>(NODE)) paint(node, value);
|
|
75
|
+
return () => delete root.dataset.cvLinking;
|
|
93
76
|
}
|
|
94
77
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
78
|
+
|
|
79
|
+
function watch(root: HTMLElement) {
|
|
80
|
+
const over = (event: PointerEvent) => {
|
|
81
|
+
const node = (event.target as Element | null)?.closest<HTMLElement>(NODE) ?? null;
|
|
82
|
+
if (node === hovered) return;
|
|
83
|
+
hovered = node;
|
|
84
|
+
paint(node);
|
|
85
|
+
};
|
|
86
|
+
root.addEventListener("pointerover", over, { passive: true });
|
|
87
|
+
|
|
88
|
+
// A node picks up or loses the `selected` class when the selection changes, and arrives selected when pasted or created.
|
|
89
|
+
for (const node of root.querySelectorAll<HTMLElement>(`${NODE}.selected`)) track(node);
|
|
90
|
+
const classes = new MutationObserver((records) => {
|
|
91
|
+
for (const record of records) {
|
|
92
|
+
const node = record.target as HTMLElement;
|
|
93
|
+
if (node.matches(NODE)) track(node);
|
|
100
94
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
});
|
|
96
|
+
classes.observe(root, { attributes: true, attributeFilter: ["class"], subtree: true });
|
|
97
|
+
const arrivals = new MutationObserver((records) => {
|
|
98
|
+
for (const record of records) {
|
|
99
|
+
for (const added of record.addedNodes) {
|
|
100
|
+
if (added instanceof HTMLElement && added.matches(NODE)) track(added);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const layer = root.querySelector(".svelte-flow__nodes");
|
|
105
|
+
if (layer) arrivals.observe(layer, { childList: true });
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
107
|
+
return () => {
|
|
108
|
+
root.removeEventListener("pointerover", over);
|
|
109
|
+
classes.disconnect();
|
|
110
|
+
arrivals.disconnect();
|
|
111
|
+
selected.clear();
|
|
112
|
+
root.removeAttribute("data-cv-multi");
|
|
113
|
+
};
|
|
114
|
+
}
|
|
114
115
|
|
|
115
|
-
$effect(() => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
});
|
|
116
|
+
$effect(() => {
|
|
117
|
+
const root = store.domNode;
|
|
118
|
+
if (!root) return;
|
|
119
|
+
return untrack(() => watch(root));
|
|
120
|
+
});
|
|
120
121
|
</script>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
// =========================
|
|
3
|
-
// IMPORTS
|
|
4
|
-
// =========================
|
|
5
|
-
import type { Snippet } from "svelte";
|
|
2
|
+
// =========================
|
|
3
|
+
// IMPORTS
|
|
4
|
+
// =========================
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
6
|
|
|
7
|
-
// =========================
|
|
8
|
-
// PROPS
|
|
9
|
-
// =========================
|
|
10
|
-
let { label, children }: { label: string; children: Snippet } = $props();
|
|
7
|
+
// =========================
|
|
8
|
+
// PROPS
|
|
9
|
+
// =========================
|
|
10
|
+
let { label, children }: { label: string; children: Snippet } = $props();
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
13
|
<!-- =========================== -->
|