@heyramzi/ui 2.11.1 → 2.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/helpers.js +38 -38
- package/dist/agents/page-state.js +49 -50
- package/dist/agents/vendor/color.js +146 -127
- package/dist/agents/vendor/draw.js +617 -508
- package/dist/agents/vendor/engine.js +698 -599
- package/dist/agents/vendor/mesh.js +653 -683
- package/dist/agents/vendor/plastic.js +3913 -3112
- package/dist/agents/vendor/presets.js +163 -164
- package/dist/agents/vendor/shapes.js +21 -20
- package/dist/agents/vendor/ticker.js +41 -42
- package/dist/agents/vendor/types.js +1 -0
- package/dist/agents/vendor/wear.js +1421 -1448
- package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
- package/dist/ai/confirmation/index.js +3 -1
- package/dist/ai/index.js +33 -0
- package/dist/ai/prompt-input/index.js +3 -1
- package/dist/ai/reasoning/index.js +3 -1
- package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
- package/dist/ai/suggestion/index.js +3 -1
- package/dist/ai/typing-dots/index.js +3 -1
- package/dist/animations/text-swap.js +24 -24
- package/dist/brand/index.js +54 -48
- package/dist/canvas/card/resize.js +5 -3
- package/dist/canvas/edges/edge-path.js +255 -242
- package/dist/canvas/editor/context-menu.js +39 -36
- package/dist/canvas/editor/dispatch.svelte.js +154 -151
- package/dist/canvas/editor/editor-context.js +7 -2
- package/dist/canvas/editor/editor-mode.js +1 -0
- package/dist/canvas/editor/frame.js +73 -76
- package/dist/canvas/editor/hand-context.js +5 -2
- package/dist/canvas/editor/history-core.js +163 -191
- package/dist/canvas/editor/keymap.js +95 -169
- package/dist/canvas/editor/layout-actions.js +143 -144
- package/dist/canvas/editor/lock.js +52 -51
- package/dist/canvas/editor/rebase.js +217 -240
- package/dist/canvas/editor/style.js +132 -137
- package/dist/canvas/editor/text-field-context.js +7 -2
- package/dist/canvas/editor/z-order.js +65 -70
- package/dist/canvas/headless/alignment.js +22 -16
- package/dist/canvas/headless/break-apart-find.js +286 -279
- package/dist/canvas/headless/break-apart-pieces.js +62 -58
- package/dist/canvas/headless/break-apart-plan.js +299 -325
- package/dist/canvas/headless/break-apart-style.js +75 -70
- package/dist/canvas/headless/break-apart.js +188 -181
- package/dist/canvas/headless/canvas-cleanup.js +78 -58
- package/dist/canvas/headless/edge-anchors.js +115 -116
- package/dist/canvas/headless/edge-memo.js +24 -22
- package/dist/canvas/headless/edge-serialization.js +17 -27
- package/dist/canvas/headless/figure-geometry.js +232 -264
- package/dist/canvas/headless/fit-viewport.js +84 -67
- package/dist/canvas/headless/grid.js +88 -86
- package/dist/canvas/headless/icon-node.js +44 -36
- package/dist/canvas/headless/index.js +1 -0
- package/dist/canvas/headless/linkify.js +17 -19
- package/dist/canvas/headless/pen-marks.js +101 -95
- package/dist/canvas/headless/sketch.js +231 -209
- package/dist/canvas/headless/snap-guides.js +99 -83
- package/dist/canvas/headless/svg-figure.js +133 -117
- package/dist/canvas/headless/table-layout.js +146 -107
- package/dist/canvas/index.js +2 -0
- package/dist/canvas/lod/lod-mode.svelte.js +20 -18
- package/dist/canvas/lod/render-all.svelte.js +36 -39
- package/dist/canvas/ops/arrange.js +78 -71
- package/dist/canvas/ops/ops.js +260 -255
- package/dist/canvas/pen/colors.js +37 -35
- package/dist/canvas/pen/eraser.js +28 -27
- package/dist/canvas/pen/geometry.js +120 -130
- package/dist/canvas/pen/index.js +1 -0
- package/dist/canvas/pen/ops.js +11 -11
- package/dist/canvas/pen/pen-session.js +150 -159
- package/dist/canvas/pen/plugin.js +107 -104
- package/dist/canvas/pen/shapes.js +73 -68
- package/dist/canvas/pen/stroke-path.js +32 -30
- package/dist/canvas/pen/types.js +21 -21
- package/dist/canvas/pen/ui.js +10 -8
- package/dist/canvas/plugin.js +46 -46
- package/dist/canvas/screen/glyphs.js +12 -11
- package/dist/canvas/screen/labels.js +22 -22
- package/dist/canvas/screen/parts.js +98 -111
- package/dist/canvas/screen/plugin.js +47 -56
- package/dist/canvas/screen/types.js +30 -35
- package/dist/canvas/screen/ui.js +7 -7
- package/dist/canvas/test-utils.js +14 -14
- package/dist/canvas/types.js +1 -0
- package/dist/canvas/ui/forward-wheel.js +24 -25
- package/dist/canvas/ui/icons.js +64 -131
- package/dist/canvas/ui/place-panel.js +58 -49
- package/dist/canvas/ui/shortcut-tip.js +14 -12
- package/dist/canvas/ui/tools.js +300 -385
- package/dist/charts/dashboard/chart.js +4 -0
- package/dist/charts/dashboard/data-table.js +11 -0
- package/dist/charts/dashboard/windows.js +8 -3
- package/dist/charts/edge-fade.js +10 -5
- package/dist/charts/hover-band.js +16 -11
- package/dist/charts/index.js +0 -1
- package/dist/charts/motion.js +11 -7
- package/dist/charts/primitives/chart-utils.js +12 -12
- package/dist/components/copy/clipboard.js +32 -32
- package/dist/components/copy/copied.svelte.js +31 -23
- package/dist/components/data-table/data-table.js +39 -39
- package/dist/components/docs/index.js +4 -0
- package/dist/components/docs/scroll-spy.svelte.js +73 -68
- package/dist/components/list-page/filter-section.js +4 -1
- package/dist/components/list-page/index.js +2 -0
- package/dist/components/list-page/list-table.js +7 -2
- package/dist/components/list-page/queue-rail.js +14 -0
- package/dist/components/list-page/section-host.js +4 -2
- package/dist/components/list-page/step.js +4 -3
- package/dist/components/list-page/types.js +1 -0
- package/dist/components/picker/trigger.js +48 -30
- package/dist/components/picker/types.js +1 -0
- package/dist/components/segmented/collapse.js +38 -27
- package/dist/components/segmented/index.js +8 -0
- package/dist/components/segmented/segmented.js +67 -42
- package/dist/components/star-rating-input/index.js +3 -1
- package/dist/components/table-view/types.js +1 -0
- package/dist/components/tags-input/tags.js +81 -69
- package/dist/components/theme/index.js +4 -0
- package/dist/components/toolbar/index.js +4 -0
- package/dist/components/toolbar/toolbar-trigger.js +14 -1
- package/dist/editor/anchors.js +17 -13
- package/dist/editor/block-id.js +52 -51
- package/dist/editor/block-ops.js +108 -80
- package/dist/editor/doc-blocks.js +155 -166
- package/dist/editor/extensions.js +139 -180
- package/dist/editor/index.js +4 -0
- package/dist/editor/markdown-test-helpers.js +4 -2
- package/dist/editor/markdown.js +420 -408
- package/dist/editor/serializer.js +204 -200
- package/dist/editor/slash-items.js +89 -101
- package/dist/editor/youtube-url.js +25 -20
- package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
- package/dist/effects/animated-beam/types.js +1 -0
- package/dist/effects/border-beam/css.js +92 -78
- package/dist/effects/border-beam/presets.js +1705 -1720
- package/dist/effects/border-beam/register-properties.js +43 -33
- package/dist/effects/border-beam/types.js +1 -0
- package/dist/effects/image-comparison/compare.js +3 -2
- package/dist/effects/image-reveal/types.js +1 -0
- package/dist/effects/magnetic/magnetic.js +58 -52
- package/dist/effects/reveal/observe.js +50 -40
- package/dist/effects/reveal/types.js +1 -0
- package/dist/effects/shader-gradient/color.js +36 -29
- package/dist/effects/shader-gradient/renderer.js +384 -295
- package/dist/effects/shader-gradient/shaders.js +31 -0
- package/dist/effects/shader-gradient/types.js +1 -0
- package/dist/icons/apple-symbol-exports.js +99 -124
- package/dist/icons/sf-symbols.js +357 -461
- package/dist/icons/trades.js +43 -28
- package/dist/inbox/index.js +1 -0
- package/dist/inbox/logic.js +126 -122
- package/dist/inbox/types.js +43 -43
- package/dist/lib/arrive.js +19 -12
- package/dist/lib/icon-types.js +1 -0
- package/dist/lib/initials.js +16 -10
- package/dist/lib/layout.js +5 -0
- package/dist/lib/panel.js +13 -0
- package/dist/lib/result.js +22 -22
- package/dist/lib/sliding-pill.js +59 -44
- package/dist/lib/theme-transition.js +43 -43
- package/dist/lib/tone.js +31 -24
- package/dist/lib/utils.js +3 -1
- package/dist/onboarding/define-tours.js +24 -23
- package/dist/onboarding/onboarding.svelte.js +16 -12
- package/dist/onboarding/pick.js +10 -6
- package/dist/onboarding/stores.js +40 -41
- package/dist/onboarding/wait.js +24 -23
- package/dist/panel/side-panel-types.js +1 -0
- package/dist/record/demo-data.js +459 -486
- package/dist/record/fields.js +129 -131
- package/dist/record/format.js +70 -82
- package/dist/record/gutter.js +1 -0
- package/dist/record/kinds.js +95 -105
- package/dist/record/logic.js +238 -219
- package/dist/record/types.js +49 -48
- package/dist/shadcn/accordion/index.js +3 -1
- package/dist/shadcn/alert/index.js +3 -1
- package/dist/shadcn/alert-dialog/index.js +3 -1
- package/dist/shadcn/attachment/index.js +3 -1
- package/dist/shadcn/avatar/index.js +3 -1
- package/dist/shadcn/breadcrumb/index.js +3 -1
- package/dist/shadcn/bubble/index.js +3 -1
- package/dist/shadcn/button/index.js +3 -1
- package/dist/shadcn/calendar/index.js +3 -1
- package/dist/shadcn/card/index.js +3 -1
- package/dist/shadcn/checkbox/index.js +3 -1
- package/dist/shadcn/code-block/index.js +3 -1
- package/dist/shadcn/collapsible/index.js +3 -1
- package/dist/shadcn/command/index.js +4 -1
- package/dist/shadcn/context-menu/index.js +3 -1
- package/dist/shadcn/dialog/index.js +3 -1
- package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
- package/dist/shadcn/empty/index.js +3 -1
- package/dist/shadcn/field/index.js +3 -1
- package/dist/shadcn/hooks/highlighter.js +77 -75
- package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
- package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
- package/dist/shadcn/input/index.js +3 -1
- package/dist/shadcn/kbd/index.js +3 -1
- package/dist/shadcn/label/index.js +3 -1
- package/dist/shadcn/marker/index.js +3 -1
- package/dist/shadcn/message/index.js +3 -1
- package/dist/shadcn/message-scroller/index.js +3 -1
- package/dist/shadcn/popover/index.js +3 -1
- package/dist/shadcn/progress/index.js +3 -1
- package/dist/shadcn/progress/tone.js +8 -7
- package/dist/shadcn/radio-group/index.js +3 -1
- package/dist/shadcn/scroll-area/index.js +3 -1
- package/dist/shadcn/select/index.js +3 -1
- package/dist/shadcn/separator/index.js +3 -1
- package/dist/shadcn/sheet/index.js +3 -1
- package/dist/shadcn/sidebar/context.svelte.js +42 -28
- package/dist/shadcn/sidebar/index.js +3 -1
- package/dist/shadcn/skeleton/index.js +3 -1
- package/dist/shadcn/slider/index.js +3 -1
- package/dist/shadcn/switch/index.js +3 -1
- package/dist/shadcn/table/index.js +3 -1
- package/dist/shadcn/tabs/index.js +3 -1
- package/dist/shadcn/textarea/index.js +3 -1
- package/dist/shadcn/toggle/index.js +3 -1
- package/dist/shadcn/toggle-group/index.js +3 -1
- package/dist/shadcn/tooltip/context.js +7 -2
- package/dist/shadcn/tooltip/index.js +3 -1
- package/dist/shadcn/trace/index.js +3 -1
- package/dist/slides/bridges.js +65 -59
- package/dist/slides/deck-controller.svelte.js +210 -207
- package/dist/slides/export/capture.js +66 -71
- package/dist/slides/export/ffmpeg.js +76 -72
- package/dist/slides/export/index.js +3 -0
- package/dist/slides/export/launch.js +9 -6
- package/dist/slides/export/pdf.js +60 -54
- package/dist/slides/export/types.js +1 -0
- package/dist/slides/labels.js +24 -24
- package/dist/slides/layout.js +39 -41
- package/dist/slides/model.js +9 -7
- package/dist/slides/navigation.js +78 -73
- package/dist/slides/types.js +2 -2
- package/dist/status/define-statuses.js +18 -14
- package/dist/status/status-types.js +1 -0
- package/dist/test-setup.js +24 -20
- package/dist/thread/logic.js +73 -77
- package/dist/thread/types.js +21 -21
- package/dist/work/board-order.js +94 -90
- package/dist/work/dates.js +16 -9
- package/dist/work/detail/detail-types.js +18 -18
- package/dist/work/docs/edited.js +32 -29
- package/dist/work/docs/index.js +4 -0
- package/dist/work/docs/labels.js +34 -34
- package/dist/work/docs/menu.js +113 -106
- package/dist/work/docs/outline.js +39 -29
- package/dist/work/gantt/logic.js +211 -235
- package/dist/work/inbox/inbox-logic.js +71 -75
- package/dist/work/inbox/inbox-statuses.js +75 -72
- package/dist/work/inbox/inbox-types.js +1 -0
- package/dist/work/kanban-drag.js +27 -22
- package/dist/work/kanban-types.js +1 -0
- package/dist/work/presets/sales.js +36 -32
- package/dist/work/reorder.js +9 -8
- package/dist/work/task-types.js +1 -0
- package/dist/work/time/duration.js +51 -46
- package/dist/work/time/time-types.js +23 -23
- package/dist/work/use-kanban-dnd.svelte.js +126 -125
- package/package.json +3 -1
- package/src/components/list-page/master-detail.svelte +3 -1
- package/src/components/list-page/rail-row.svelte +4 -4
- package/src/editor/markdown.ts +30 -35
|
@@ -1,140 +1,127 @@
|
|
|
1
|
+
// Pure edits on a screen's parts, so the card and the CLI op change a screen the same way.
|
|
2
|
+
// Each function returns a new list.
|
|
1
3
|
import { MAX_LABEL, MAX_LIST_ITEMS, MAX_PARTS, PART_DEFAULTS, PART_KINDS, SCREEN_MODES, SCREEN_NODE, SCREEN_WIDTH } from "./types.js";
|
|
2
|
-
const isKind = (value)=>typeof value === "string" && PART_KINDS.includes(value);
|
|
3
|
-
const text = (value, fallback = "")=>typeof value === "string" ? value.slice(0, MAX_LABEL) : fallback;
|
|
4
|
+
const isKind = (value) => typeof value === "string" && PART_KINDS.includes(value);
|
|
5
|
+
const text = (value, fallback = "") => typeof value === "string" ? value.slice(0, MAX_LABEL) : fallback;
|
|
6
|
+
/** The next id no part of this screen holds: p1, p2, and so on. */
|
|
4
7
|
export function nextPartId(parts) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
const taken = new Set(parts.map((part) => part.id));
|
|
9
|
+
let n = parts.length + 1;
|
|
10
|
+
while (taken.has(`p${n}`)) n += 1;
|
|
11
|
+
return `p${n}`;
|
|
9
12
|
}
|
|
13
|
+
/** A part of this kind with its starting words. */
|
|
10
14
|
export function createPart(kind, parts, seed = {}) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
];
|
|
21
|
-
return part;
|
|
15
|
+
const base = PART_DEFAULTS[kind];
|
|
16
|
+
const part = {
|
|
17
|
+
...base,
|
|
18
|
+
...seed,
|
|
19
|
+
id: nextPartId(parts),
|
|
20
|
+
kind
|
|
21
|
+
};
|
|
22
|
+
if (part.items) part.items = [...part.items];
|
|
23
|
+
return part;
|
|
22
24
|
}
|
|
25
|
+
/** A stored id kept when it is a new string, else the next free one. */
|
|
23
26
|
function uniquePartId(raw, parts, seen) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const id = typeof raw === "string" && raw ? raw : "";
|
|
28
|
+
const unique = !id || seen.has(id) ? nextPartId(parts) : id;
|
|
29
|
+
seen.add(unique);
|
|
30
|
+
return unique;
|
|
28
31
|
}
|
|
32
|
+
/** What only one kind of part carries: a list's rows, a modal's body, a button's weight. */
|
|
29
33
|
function kindFields(kind, part) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
text: text(part.text, PART_DEFAULTS.modal.text)
|
|
38
|
-
};
|
|
39
|
-
if (kind === "button") return {
|
|
40
|
-
variant: part.variant === "secondary" ? "secondary" : "primary"
|
|
41
|
-
};
|
|
42
|
-
return {};
|
|
34
|
+
if (kind === "list") {
|
|
35
|
+
const items = Array.isArray(part.items) ? part.items : PART_DEFAULTS.list.items;
|
|
36
|
+
return { items: (items ?? []).slice(0, MAX_LIST_ITEMS).map((item) => text(item)) };
|
|
37
|
+
}
|
|
38
|
+
if (kind === "modal") return { text: text(part.text, PART_DEFAULTS.modal.text) };
|
|
39
|
+
if (kind === "button") return { variant: part.variant === "secondary" ? "secondary" : "primary" };
|
|
40
|
+
return {};
|
|
43
41
|
}
|
|
42
|
+
/** One stored part as a part that draws, or null when its kind is not one we know. */
|
|
44
43
|
function normalizePart(entry, parts, seen) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
const part = entry ?? {};
|
|
45
|
+
if (!isKind(part.kind)) return null;
|
|
46
|
+
const kind = part.kind;
|
|
47
|
+
const id = uniquePartId(part.id, parts, seen);
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
kind,
|
|
51
|
+
label: text(part.label, PART_DEFAULTS[kind].label),
|
|
52
|
+
...kindFields(kind, part)
|
|
53
|
+
};
|
|
55
54
|
}
|
|
55
|
+
/** A screen as stored may be old, hand-written or half-typed: this one always draws. */
|
|
56
56
|
export function normalizeScreen(data) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
const raw = data ?? {};
|
|
58
|
+
const seen = new Set();
|
|
59
|
+
const parts = [];
|
|
60
|
+
const rawParts = Array.isArray(raw.parts) ? raw.parts : [];
|
|
61
|
+
for (const entry of rawParts.slice(0, MAX_PARTS)) {
|
|
62
|
+
const next = normalizePart(entry, parts, seen);
|
|
63
|
+
if (next) parts.push(next);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
label: text(raw.label),
|
|
67
|
+
mode: SCREEN_MODES.includes(raw.mode) ? raw.mode : "wireframe",
|
|
68
|
+
parts
|
|
69
|
+
};
|
|
70
70
|
}
|
|
71
71
|
export function addPart(parts, kind, seed, index = parts.length) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
...parts.slice(at)
|
|
80
|
-
];
|
|
72
|
+
if (parts.length >= MAX_PARTS) return [...parts];
|
|
73
|
+
const at = Math.max(0, Math.min(index, parts.length));
|
|
74
|
+
return [
|
|
75
|
+
...parts.slice(0, at),
|
|
76
|
+
createPart(kind, parts, seed),
|
|
77
|
+
...parts.slice(at)
|
|
78
|
+
];
|
|
81
79
|
}
|
|
82
80
|
export function removePart(parts, id) {
|
|
83
|
-
|
|
81
|
+
return parts.filter((part) => part.id !== id);
|
|
84
82
|
}
|
|
83
|
+
/** One step up (-1) or down (1). The ends stay put. */
|
|
85
84
|
export function movePart(parts, id, step) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
...parts
|
|
93
|
-
];
|
|
94
|
-
[next[from], next[to]] = [
|
|
95
|
-
next[to],
|
|
96
|
-
next[from]
|
|
97
|
-
];
|
|
98
|
-
return next;
|
|
85
|
+
const from = parts.findIndex((part) => part.id === id);
|
|
86
|
+
const to = from + step;
|
|
87
|
+
if (from < 0 || to < 0 || to >= parts.length) return [...parts];
|
|
88
|
+
const next = [...parts];
|
|
89
|
+
[next[from], next[to]] = [next[to], next[from]];
|
|
90
|
+
return next;
|
|
99
91
|
}
|
|
100
92
|
export function patchPart(parts, id, patch) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
93
|
+
return parts.map((part) => part.id === id ? {
|
|
94
|
+
...part,
|
|
95
|
+
...patch
|
|
96
|
+
} : part);
|
|
105
97
|
}
|
|
98
|
+
/** A list row's words. Rows are added and cut at the end, never reordered. */
|
|
106
99
|
export function setItem(items, index, value) {
|
|
107
|
-
|
|
100
|
+
return items.map((item, i) => i === index ? value : item);
|
|
108
101
|
}
|
|
109
102
|
export function addItem(items) {
|
|
110
|
-
|
|
111
|
-
...items
|
|
112
|
-
] : [
|
|
113
|
-
...items,
|
|
114
|
-
"Item"
|
|
115
|
-
];
|
|
103
|
+
return items.length >= MAX_LIST_ITEMS ? [...items] : [...items, "Item"];
|
|
116
104
|
}
|
|
117
105
|
export function removeItem(items, index) {
|
|
118
|
-
|
|
106
|
+
return items.filter((_, i) => i !== index);
|
|
119
107
|
}
|
|
108
|
+
/** A ready node for a board, as the CLI and the palette both build it. */
|
|
120
109
|
export function buildScreenNode(options) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
};
|
|
110
|
+
let parts = [];
|
|
111
|
+
for (const entry of options.parts ?? []) {
|
|
112
|
+
const { kind, ...seed } = entry;
|
|
113
|
+
parts = addPart(parts, kind, seed);
|
|
114
|
+
}
|
|
115
|
+
const data = normalizeScreen({
|
|
116
|
+
label: options.label,
|
|
117
|
+
mode: options.mode,
|
|
118
|
+
parts
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
id: options.id,
|
|
122
|
+
type: SCREEN_NODE,
|
|
123
|
+
position: options.position,
|
|
124
|
+
data,
|
|
125
|
+
style: { width: options.width ?? SCREEN_WIDTH }
|
|
126
|
+
};
|
|
140
127
|
}
|
|
@@ -1,71 +1,62 @@
|
|
|
1
|
+
// The Screen card's kind and its add op, with no DOM, so the CLI can put a screen on a board.
|
|
2
|
+
// ui.ts adds the renderer.
|
|
1
3
|
import { z } from "zod";
|
|
2
4
|
import { CanvasOpError } from "../ops/ops.js";
|
|
3
5
|
import { definePlugin } from "../plugin.js";
|
|
4
6
|
import { buildScreenNode } from "./parts.js";
|
|
5
7
|
import { MAX_LABEL, MAX_LIST_ITEMS, MAX_PARTS, PART_KINDS, SCREEN_MODES, SCREEN_NODE, SCREEN_WIDTH } from "./types.js";
|
|
6
8
|
const partSchema = z.object({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"primary",
|
|
13
|
-
"secondary"
|
|
14
|
-
]).optional()
|
|
9
|
+
kind: z.enum(PART_KINDS),
|
|
10
|
+
label: z.string().max(MAX_LABEL).optional(),
|
|
11
|
+
items: z.array(z.string().max(MAX_LABEL)).max(MAX_LIST_ITEMS).optional(),
|
|
12
|
+
text: z.string().max(MAX_LABEL).optional(),
|
|
13
|
+
variant: z.enum(["primary", "secondary"]).optional()
|
|
15
14
|
});
|
|
16
15
|
const addScreenOp = z.object({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
kind: z.literal("addScreen"),
|
|
17
|
+
id: z.string().min(1).optional(),
|
|
18
|
+
at: z.object({
|
|
19
|
+
x: z.number(),
|
|
20
|
+
y: z.number()
|
|
21
|
+
}),
|
|
22
|
+
label: z.string().max(MAX_LABEL).optional(),
|
|
23
|
+
mode: z.enum(SCREEN_MODES).optional(),
|
|
24
|
+
parts: z.array(partSchema).max(MAX_PARTS).optional(),
|
|
25
|
+
width: z.number().positive().optional()
|
|
27
26
|
});
|
|
28
27
|
function applyAddScreen(state, op, opIndex) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
...state.nodes,
|
|
43
|
-
node
|
|
44
|
-
];
|
|
28
|
+
const id = op.id ?? crypto.randomUUID();
|
|
29
|
+
if (state.nodes.some((node) => node.id === id)) {
|
|
30
|
+
throw new CanvasOpError(`Node id already exists: ${id}`, opIndex);
|
|
31
|
+
}
|
|
32
|
+
const node = buildScreenNode({
|
|
33
|
+
id,
|
|
34
|
+
position: op.at,
|
|
35
|
+
label: op.label,
|
|
36
|
+
mode: op.mode,
|
|
37
|
+
parts: op.parts,
|
|
38
|
+
width: op.width
|
|
39
|
+
});
|
|
40
|
+
state.nodes = [...state.nodes, node];
|
|
45
41
|
}
|
|
42
|
+
/** Content-sized: the parts decide the height, so a layout never pins a stale one. */
|
|
46
43
|
export const screenKind = {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
parts: []
|
|
57
|
-
})
|
|
44
|
+
type: SCREEN_NODE,
|
|
45
|
+
label: "Screen",
|
|
46
|
+
sizing: "content-sized",
|
|
47
|
+
size: { width: SCREEN_WIDTH },
|
|
48
|
+
createData: () => ({
|
|
49
|
+
label: "",
|
|
50
|
+
mode: "wireframe",
|
|
51
|
+
parts: []
|
|
52
|
+
})
|
|
58
53
|
};
|
|
59
54
|
export const screenPlugin = definePlugin({
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
schema: addScreenOp,
|
|
68
|
-
apply: applyAddScreen
|
|
69
|
-
}
|
|
70
|
-
]
|
|
55
|
+
id: "screen",
|
|
56
|
+
nodes: [screenKind],
|
|
57
|
+
ops: [{
|
|
58
|
+
kind: "addScreen",
|
|
59
|
+
schema: addScreenOp,
|
|
60
|
+
apply: applyAddScreen
|
|
61
|
+
}]
|
|
71
62
|
});
|
|
@@ -1,44 +1,39 @@
|
|
|
1
|
+
// The Screen card's data shape: a stack of kit parts drawn as a wireframe or a mockup.
|
|
1
2
|
export const SCREEN_NODE = "screen";
|
|
3
|
+
/** Card width before anyone resizes it. The height follows the parts. */
|
|
2
4
|
export const SCREEN_WIDTH = 320;
|
|
3
5
|
export const PART_KINDS = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
];
|
|
11
|
-
export const SCREEN_MODES = [
|
|
12
|
-
"wireframe",
|
|
13
|
-
"mockup"
|
|
6
|
+
"header",
|
|
7
|
+
"button",
|
|
8
|
+
"input",
|
|
9
|
+
"image",
|
|
10
|
+
"list",
|
|
11
|
+
"modal"
|
|
14
12
|
];
|
|
13
|
+
export const SCREEN_MODES = ["wireframe", "mockup"];
|
|
14
|
+
/** A board holds screens of a handful of parts. One past this is a paste from a file. */
|
|
15
15
|
export const MAX_PARTS = 24;
|
|
16
16
|
export const MAX_LIST_ITEMS = 12;
|
|
17
17
|
export const MAX_LABEL = 120;
|
|
18
|
+
/** What a new part of each kind starts with. Words are labels, never sentences. */
|
|
18
19
|
export const PART_DEFAULTS = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
]
|
|
39
|
-
},
|
|
40
|
-
modal: {
|
|
41
|
-
label: "Title",
|
|
42
|
-
text: "Text"
|
|
43
|
-
}
|
|
20
|
+
header: { label: "Title" },
|
|
21
|
+
button: {
|
|
22
|
+
label: "Button",
|
|
23
|
+
variant: "primary"
|
|
24
|
+
},
|
|
25
|
+
input: { label: "Label" },
|
|
26
|
+
image: { label: "Image" },
|
|
27
|
+
list: {
|
|
28
|
+
label: "List",
|
|
29
|
+
items: [
|
|
30
|
+
"Item",
|
|
31
|
+
"Item",
|
|
32
|
+
"Item"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
modal: {
|
|
36
|
+
label: "Title",
|
|
37
|
+
text: "Text"
|
|
38
|
+
}
|
|
44
39
|
};
|
package/dist/canvas/screen/ui.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
// The browser registers `screenUiPlugin`, and a server registers `screenPlugin`.
|
|
2
|
+
// Never both, because a kind has one owner.
|
|
1
3
|
import { definePlugin } from "../plugin.js";
|
|
2
4
|
import { screenKind, screenPlugin } from "./plugin.js";
|
|
3
5
|
import ScreenCard from "../../../src/canvas/screen/ScreenCard.svelte";
|
|
4
6
|
export { ScreenCard };
|
|
5
7
|
export const screenUiPlugin = definePlugin({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
]
|
|
8
|
+
...screenPlugin,
|
|
9
|
+
nodes: [{
|
|
10
|
+
...screenKind,
|
|
11
|
+
component: ScreenCard
|
|
12
|
+
}]
|
|
13
13
|
});
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
+
/** A node for tests. Overrides win. */
|
|
1
2
|
export function makeNode(overrides = {}) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
...overrides
|
|
13
|
-
};
|
|
3
|
+
return {
|
|
4
|
+
id: overrides.id ?? `node-${Math.random().toString(36).slice(2, 8)}`,
|
|
5
|
+
type: "node",
|
|
6
|
+
position: {
|
|
7
|
+
x: 0,
|
|
8
|
+
y: 0
|
|
9
|
+
},
|
|
10
|
+
data: { label: "Test Node" },
|
|
11
|
+
...overrides
|
|
12
|
+
};
|
|
14
13
|
}
|
|
14
|
+
/** Narrows a lookup in a test so a miss fails with a name, not a TypeError. */
|
|
15
15
|
export function expectDefined(value, what = "value") {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
if (value === null || value === undefined) throw new Error(`Expected ${what} to be defined`);
|
|
17
|
+
return value;
|
|
18
18
|
}
|
package/dist/canvas/types.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
+
// An overlay above xyflow's zoom pane never sees a wheel or a pinch, so it hands them down.
|
|
1
2
|
export function forwardWheel(node) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
26
|
-
return ()=>node.removeEventListener("wheel", handler);
|
|
3
|
+
const handler = (event) => {
|
|
4
|
+
const zoomPane = node.closest(".svelte-flow")?.querySelector(".svelte-flow__zoom");
|
|
5
|
+
if (!zoomPane) return;
|
|
6
|
+
event.preventDefault();
|
|
7
|
+
zoomPane.dispatchEvent(new WheelEvent("wheel", {
|
|
8
|
+
deltaX: event.deltaX,
|
|
9
|
+
deltaY: event.deltaY,
|
|
10
|
+
deltaZ: event.deltaZ,
|
|
11
|
+
deltaMode: event.deltaMode,
|
|
12
|
+
clientX: event.clientX,
|
|
13
|
+
clientY: event.clientY,
|
|
14
|
+
screenX: event.screenX,
|
|
15
|
+
screenY: event.screenY,
|
|
16
|
+
ctrlKey: event.ctrlKey,
|
|
17
|
+
shiftKey: event.shiftKey,
|
|
18
|
+
altKey: event.altKey,
|
|
19
|
+
metaKey: event.metaKey,
|
|
20
|
+
bubbles: true,
|
|
21
|
+
cancelable: true
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
24
|
+
node.addEventListener("wheel", handler, { passive: false });
|
|
25
|
+
return () => node.removeEventListener("wheel", handler);
|
|
27
26
|
}
|