@vanduo-oss/vd3-cbun 1.0.0 → 1.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.
@@ -0,0 +1,301 @@
1
+ /* Draw tool styles — a local --vd-draw-* token layer over the global --vd-*
2
+ design tokens. Chrome (surface, grid, toolbar, panel, selection UI) reads
3
+ only the locals, so dark/light + palette changes flow through the cascade
4
+ with no JS. Marks carry an explicit, user-picked color and do not re-theme.
5
+ Override any local (no !important needed) to retheme. */
6
+ :root {
7
+ --vd-draw-surface: var(--vd-bg-primary, #fcfbf7);
8
+ --vd-draw-panel: color-mix(in srgb, var(--vd-bg-secondary, #f4efe2) 88%, #ffffff);
9
+ --vd-draw-border: color-mix(in srgb, var(--vd-border-color, #d5ccba) 80%, #ffffff);
10
+ --vd-draw-accent: var(--vd-color-primary, #245f52);
11
+ --vd-draw-text: var(--vd-text-primary, #1f2720);
12
+ --vd-draw-muted: var(--vd-text-muted, #67746a);
13
+ --vd-draw-grid: color-mix(in srgb, var(--vd-border-color, #d5ccba) 55%, transparent);
14
+ /* Default ink for a fresh mark (theme-aware first stroke). */
15
+ --vd-draw-ink: var(--vd-text-primary, #1f2720);
16
+ --vd-draw-shape-stroke: var(--vd-color-primary, #245f52);
17
+ --vd-draw-sticky-fill: color-mix(in srgb, var(--vd-color-primary, #245f52) 12%, #fdf6d8);
18
+ --vd-draw-selection: var(--vd-color-primary, #245f52);
19
+ --vd-draw-handle-fill: var(--vd-bg-primary, #ffffff);
20
+ --vd-draw-guide: color-mix(in srgb, var(--vd-color-primary, #245f52) 60%, #d6336c);
21
+ /* SVG <text> does not inherit font-family reliably; set it explicitly. */
22
+ --vd-draw-font: inherit;
23
+ }
24
+
25
+ .vd-draw-host {
26
+ height: 560px;
27
+ font-family: var(--vd-draw-font);
28
+ }
29
+
30
+ .vd-draw-shell {
31
+ display: grid;
32
+ grid-template-rows: auto auto minmax(0, 1fr);
33
+ height: 100%;
34
+ min-height: 380px;
35
+ border: 1px solid var(--vd-draw-border);
36
+ border-radius: 8px;
37
+ background: var(--vd-draw-surface);
38
+ color: var(--vd-draw-text);
39
+ overflow: hidden;
40
+ }
41
+
42
+ /* ── Toolbar ─────────────────────────────────────────────────────────── */
43
+ .vd-draw-toolbar {
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: space-between;
47
+ gap: 0.75rem;
48
+ flex-wrap: wrap;
49
+ padding: 0.4rem 0.55rem;
50
+ border-bottom: 1px solid var(--vd-draw-border);
51
+ background: var(--vd-draw-panel);
52
+ }
53
+
54
+ .vd-draw-toolbar-group {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 0.25rem;
58
+ flex-wrap: wrap;
59
+ }
60
+
61
+ .vd-draw-tool {
62
+ display: inline-flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ width: 2.1rem;
66
+ height: 2.1rem;
67
+ padding: 0;
68
+ color: var(--vd-draw-text);
69
+ background: transparent;
70
+ border: 1px solid transparent;
71
+ border-radius: 7px;
72
+ cursor: pointer;
73
+ transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
74
+ }
75
+
76
+ .vd-draw-tool:hover {
77
+ background: color-mix(in srgb, var(--vd-draw-accent) 12%, transparent);
78
+ }
79
+
80
+ .vd-draw-tool[aria-pressed='true'] {
81
+ background: color-mix(in srgb, var(--vd-draw-accent) 20%, transparent);
82
+ border-color: var(--vd-draw-accent);
83
+ color: var(--vd-draw-accent);
84
+ }
85
+
86
+ .vd-draw-tool:focus-visible {
87
+ outline: 2px solid var(--vd-draw-accent);
88
+ outline-offset: 1px;
89
+ }
90
+
91
+ /* Inline Phosphor icons — sized + a soft drop-shadow for visibility. */
92
+ .vd-draw-icon {
93
+ width: 20px;
94
+ height: 20px;
95
+ display: block;
96
+ flex: none;
97
+ filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.32));
98
+ }
99
+
100
+ /* ── Style panel (brushes, colors, sliders) ──────────────────────────── */
101
+ .vd-draw-panel {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 0.9rem;
105
+ flex-wrap: wrap;
106
+ padding: 0.4rem 0.6rem;
107
+ border-bottom: 1px solid var(--vd-draw-border);
108
+ background: color-mix(in srgb, var(--vd-draw-panel) 60%, var(--vd-draw-surface));
109
+ }
110
+
111
+ .vd-draw-panel-group {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 0.3rem;
115
+ flex-wrap: wrap;
116
+ padding-right: 0.6rem;
117
+ border-right: 1px solid color-mix(in srgb, var(--vd-draw-border) 60%, transparent);
118
+ }
119
+
120
+ .vd-draw-panel-group:last-child {
121
+ border-right: none;
122
+ }
123
+
124
+ .vd-draw-panel-label {
125
+ font-size: 0.68rem;
126
+ font-weight: 600;
127
+ text-transform: uppercase;
128
+ letter-spacing: 0.05em;
129
+ color: var(--vd-draw-muted);
130
+ margin-right: 0.1rem;
131
+ }
132
+
133
+ .vd-draw-value {
134
+ min-width: 2.6em;
135
+ font-size: 0.75rem;
136
+ font-variant-numeric: tabular-nums;
137
+ color: var(--vd-draw-text);
138
+ }
139
+
140
+ .vd-draw-panel input[type='range'] {
141
+ width: 90px;
142
+ accent-color: var(--vd-draw-accent);
143
+ cursor: pointer;
144
+ }
145
+
146
+ .vd-draw-brush {
147
+ padding: 0.25rem 0.55rem;
148
+ font-size: 0.8rem;
149
+ line-height: 1.2;
150
+ color: var(--vd-draw-muted);
151
+ background: transparent;
152
+ border: 1px solid var(--vd-draw-border);
153
+ border-radius: 999px;
154
+ cursor: pointer;
155
+ transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
156
+ }
157
+
158
+ .vd-draw-brush:hover {
159
+ color: var(--vd-draw-text);
160
+ }
161
+
162
+ .vd-draw-brush[aria-pressed='true'] {
163
+ color: var(--vd-draw-accent);
164
+ border-color: var(--vd-draw-accent);
165
+ background: color-mix(in srgb, var(--vd-draw-accent) 12%, transparent);
166
+ }
167
+
168
+ .vd-draw-swatch {
169
+ width: 1.15rem;
170
+ height: 1.15rem;
171
+ padding: 0;
172
+ background: var(--sw, #000);
173
+ border: 1px solid color-mix(in srgb, var(--vd-draw-text) 22%, transparent);
174
+ border-radius: 50%;
175
+ cursor: pointer;
176
+ box-shadow: 0 1px 1.5px rgba(0, 0, 0, 0.2);
177
+ transition: transform 0.12s ease;
178
+ }
179
+
180
+ .vd-draw-swatch:hover {
181
+ transform: scale(1.15);
182
+ }
183
+
184
+ .vd-draw-swatch[aria-pressed='true'] {
185
+ outline: 2px solid var(--vd-draw-accent);
186
+ outline-offset: 1px;
187
+ }
188
+
189
+ .vd-draw-color-input {
190
+ width: 1.6rem;
191
+ height: 1.4rem;
192
+ padding: 0;
193
+ background: none;
194
+ border: 1px solid var(--vd-draw-border);
195
+ border-radius: 5px;
196
+ cursor: pointer;
197
+ }
198
+
199
+ .vd-draw-recent {
200
+ display: inline-flex;
201
+ gap: 0.2rem;
202
+ }
203
+
204
+ /* ── Canvas ──────────────────────────────────────────────────────────── */
205
+ .vd-draw-canvas {
206
+ position: relative;
207
+ overflow: hidden;
208
+ background: var(--vd-draw-surface);
209
+ touch-action: none;
210
+ user-select: none;
211
+ cursor: crosshair;
212
+ }
213
+
214
+ .vd-draw-canvas:focus {
215
+ outline: none;
216
+ }
217
+
218
+ .vd-draw-svg {
219
+ display: block;
220
+ width: 100%;
221
+ height: 100%;
222
+ }
223
+
224
+ .vd-draw-grid-rect {
225
+ pointer-events: none;
226
+ }
227
+
228
+ /* Diagram shapes — outline in the current/themed stroke color. */
229
+ .vd-draw-shape {
230
+ stroke: var(--vd-draw-shape-stroke);
231
+ fill: none;
232
+ }
233
+
234
+ /* Freehand brush strokes — filled outline in the mark's color (or themed ink). */
235
+ .vd-draw-ink {
236
+ fill: var(--vd-draw-ink);
237
+ stroke: none;
238
+ }
239
+
240
+ .vd-draw-sticky {
241
+ fill: var(--vd-draw-sticky-fill);
242
+ stroke: color-mix(in srgb, var(--vd-draw-accent) 30%, var(--vd-draw-border));
243
+ stroke-width: 1;
244
+ }
245
+
246
+ .vd-draw-text {
247
+ fill: var(--vd-draw-text);
248
+ font-family: var(--vd-draw-font);
249
+ font-size: 16px;
250
+ dominant-baseline: hanging;
251
+ }
252
+
253
+ .vd-draw-selection-box {
254
+ stroke: var(--vd-draw-selection);
255
+ stroke-width: 1.5;
256
+ stroke-dasharray: 4 3;
257
+ pointer-events: none;
258
+ }
259
+
260
+ .vd-draw-handle {
261
+ fill: var(--vd-draw-handle-fill);
262
+ stroke: var(--vd-draw-selection);
263
+ stroke-width: 1.5;
264
+ cursor: nwse-resize;
265
+ }
266
+
267
+ .vd-draw-marquee-rect {
268
+ fill: color-mix(in srgb, var(--vd-draw-selection) 12%, transparent);
269
+ stroke: var(--vd-draw-selection);
270
+ stroke-width: 1;
271
+ stroke-dasharray: 3 2;
272
+ pointer-events: none;
273
+ }
274
+
275
+ .vd-draw-guide {
276
+ stroke: var(--vd-draw-guide);
277
+ stroke-width: 1;
278
+ pointer-events: none;
279
+ }
280
+
281
+ .vd-draw-text-layer {
282
+ position: absolute;
283
+ inset: 0;
284
+ pointer-events: none;
285
+ }
286
+
287
+ .vd-draw-text-editor {
288
+ position: absolute;
289
+ margin: 0;
290
+ padding: 2px 4px;
291
+ font-family: var(--vd-draw-font);
292
+ font-size: 16px;
293
+ color: var(--vd-draw-text);
294
+ background: var(--vd-draw-surface);
295
+ border: 1px solid var(--vd-draw-selection);
296
+ border-radius: 3px;
297
+ resize: none;
298
+ overflow: hidden;
299
+ pointer-events: auto;
300
+ box-sizing: border-box;
301
+ }
@@ -0,0 +1,68 @@
1
+ import type { DefineComponent } from 'vue';
2
+ import type {
3
+ DrawDocument,
4
+ DrawTool,
5
+ DrawChangeEvent,
6
+ DrawSelectEvent,
7
+ DrawViewportEvent,
8
+ VdDraw as VdDrawCore,
9
+ } from './core';
10
+
11
+ /** Loosely-typed document accepted by the `data` prop. */
12
+ export interface VdDrawDocument extends Partial<DrawDocument> {
13
+ shapes?: Array<Record<string, unknown>>;
14
+ [key: string]: unknown;
15
+ }
16
+
17
+ export interface VdDrawProps {
18
+ /** Drawing document ({ shapes, viewport }). */
19
+ data?: VdDrawDocument;
20
+ /** Render as a non-editable viewer. */
21
+ readonly?: boolean;
22
+ /** Active tool — updated live without recreating the editor. */
23
+ tool?: DrawTool;
24
+ /** Background grid size in px. */
25
+ gridSize?: number;
26
+ /** Show the background grid (default true). */
27
+ showGrid?: boolean;
28
+ /** Snap to nearby edges/centres while moving/resizing. */
29
+ snap?: boolean;
30
+ /** Fit the view to content once the editor reports a measurable size. */
31
+ autoFit?: boolean;
32
+ /** Enable the built-in undo/redo history (default true). */
33
+ history?: boolean;
34
+ /** Maximum number of history entries to retain. */
35
+ historyLimit?: number;
36
+ }
37
+
38
+ export interface VdDrawEmits {
39
+ (event: 'change', payload: DrawChangeEvent): void;
40
+ (event: 'select', payload: DrawSelectEvent): void;
41
+ (event: 'viewport', payload: DrawViewportEvent): void;
42
+ (event: 'ready', instance: VdDrawCore): void;
43
+ }
44
+
45
+ /** Methods exposed via a template ref. */
46
+ export interface VdDrawExposed {
47
+ getInstance(): VdDrawCore | null;
48
+ setTool(tool: DrawTool): void;
49
+ undo(): void;
50
+ redo(): void;
51
+ canUndo(): boolean;
52
+ canRedo(): boolean;
53
+ toSVG(): string | undefined;
54
+ toPNG(options?: { scale?: number }): Promise<string> | undefined;
55
+ }
56
+
57
+ /* eslint-disable @typescript-eslint/no-empty-object-type -- DefineComponent filler params */
58
+ export declare const VdDraw: DefineComponent<
59
+ VdDrawProps,
60
+ VdDrawExposed,
61
+ {},
62
+ {},
63
+ {},
64
+ {},
65
+ {},
66
+ VdDrawEmits
67
+ >;
68
+ /* eslint-enable @typescript-eslint/no-empty-object-type */
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@
7
7
  */
8
8
  export declare const VD3_CBUN_VERSIONS: Readonly<{
9
9
  charts: string;
10
+ 'code-editor': string;
11
+ draw: string;
10
12
  flowchart: string;
11
13
  'hex-grid': string;
12
14
  'music-player': string;
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  // src/index.js
2
2
  var VD3_CBUN_VERSIONS = Object.freeze({
3
3
  charts: "1.0.0",
4
+ "code-editor": "1.0.0",
5
+ draw: "1.1.0",
4
6
  flowchart: "1.2.0",
5
7
  "hex-grid": "1.0.0",
6
8
  "music-player": "1.0.0"
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.js"],
4
- "sourcesContent": ["// Root entry of @vanduo-oss/vd3-cbun.\n//\n// Exposes ONLY the per-component VERSION-constants map. Component APIs live on\n// the subpath exports (./charts, ./flowchart, ./hex-grid, ./music-player) so\n// importing one component never pulls in another (tree-shaking contract).\n//\n// The values below are hardcoded mirrors of component-versions.json (the\n// manifest is the source of truth). The version-consistency check \u2014\n// tests/smoke.spec.ts \u2014 asserts the two stay in sync; bump both together.\n// Note: `flowchart` continues the old-line 1.2.0 lineage because\n// VD_FLOWCHART_VERSION is serialized into user documents via toJSON().version.\n\nexport const VD3_CBUN_VERSIONS = Object.freeze({\n charts: '1.0.0',\n flowchart: '1.2.0',\n 'hex-grid': '1.0.0',\n 'music-player': '1.0.0',\n});\n"],
5
- "mappings": ";AAYO,IAAM,oBAAoB,OAAO,OAAO;AAAA,EAC7C,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,gBAAgB;AAClB,CAAC;",
4
+ "sourcesContent": ["// Root entry of @vanduo-oss/vd3-cbun.\n//\n// Exposes ONLY the per-component VERSION-constants map. Component APIs live on\n// the subpath exports (./charts, ./flowchart, ./hex-grid, ./music-player) so\n// importing one component never pulls in another (tree-shaking contract).\n//\n// The values below are hardcoded mirrors of component-versions.json (the\n// manifest is the source of truth). The version-consistency check \u2014\n// tests/smoke.spec.ts \u2014 asserts the two stay in sync; bump both together.\n// Note: `flowchart` continues the old-line 1.2.0 lineage because\n// VD_FLOWCHART_VERSION is serialized into user documents via toJSON().version.\n\nexport const VD3_CBUN_VERSIONS = Object.freeze({\n charts: '1.0.0',\n 'code-editor': '1.0.0',\n draw: '1.1.0',\n flowchart: '1.2.0',\n 'hex-grid': '1.0.0',\n 'music-player': '1.0.0',\n});\n"],
5
+ "mappings": ";AAYO,IAAM,oBAAoB,OAAO,OAAO;AAAA,EAC7C,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,MAAM;AAAA,EACN,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,gBAAgB;AAClB,CAAC;",
6
6
  "names": []
7
7
  }