@baron1996/klinecharts-runtime 0.8.0 → 0.9.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.
Files changed (34) hide show
  1. package/README.md +16 -2
  2. package/dist/drawing/capabilities.d.ts +3 -0
  3. package/dist/drawing/capabilities.d.ts.map +1 -1
  4. package/dist/drawing/session-controller.d.ts +1 -0
  5. package/dist/drawing/session-controller.d.ts.map +1 -1
  6. package/dist/drawing/session-controller.js +40 -2
  7. package/dist/drawing/workspace-runtime.d.ts +3 -0
  8. package/dist/drawing/workspace-runtime.d.ts.map +1 -1
  9. package/dist/drawing/workspace-runtime.js +24 -0
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -1
  13. package/dist/runtime.d.ts +3 -0
  14. package/dist/runtime.d.ts.map +1 -1
  15. package/dist/runtime.js +26 -0
  16. package/dist/toolbar/drawing-floating-toolbar-styles.d.ts +2 -0
  17. package/dist/toolbar/drawing-floating-toolbar-styles.d.ts.map +1 -0
  18. package/dist/toolbar/drawing-floating-toolbar-styles.js +250 -0
  19. package/dist/toolbar/drawing-floating-toolbar.d.ts +8 -0
  20. package/dist/toolbar/drawing-floating-toolbar.d.ts.map +1 -0
  21. package/dist/toolbar/drawing-floating-toolbar.js +373 -0
  22. package/dist/toolbar/standard-toolbar-styles.d.ts.map +1 -1
  23. package/dist/toolbar/standard-toolbar-styles.js +0 -18
  24. package/dist/toolbar/standard-toolbar.d.ts.map +1 -1
  25. package/dist/toolbar/standard-toolbar.js +15 -172
  26. package/dist/toolbar/toolbar-icons.d.ts +22 -0
  27. package/dist/toolbar/toolbar-icons.d.ts.map +1 -1
  28. package/dist/toolbar/toolbar-icons.js +8 -0
  29. package/dist/toolbar/toolbar-tools.d.ts +1 -6
  30. package/dist/toolbar/toolbar-tools.d.ts.map +1 -1
  31. package/dist/toolbar/toolbar-tools.js +0 -6
  32. package/dist/types.d.ts +9 -5
  33. package/dist/types.d.ts.map +1 -1
  34. package/package.json +2 -2
@@ -0,0 +1,250 @@
1
+ export const DRAWING_FLOATING_TOOLBAR_STYLES = String.raw `
2
+ .baron-drawing-toolbar,
3
+ .baron-drawing-toolbar * {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ .baron-drawing-toolbar {
8
+ position: fixed;
9
+ z-index: 9998;
10
+ display: flex;
11
+ align-items: center;
12
+ min-height: 48px;
13
+ padding: 5px 7px 5px 4px;
14
+ color: rgba(32, 35, 42, 1);
15
+ background: rgba(255, 255, 255, 0.98);
16
+ border: 1px solid rgba(218, 220, 226, 1);
17
+ border-radius: 12px;
18
+ box-shadow:
19
+ 0 2px 5px rgba(20, 29, 48, 0.08),
20
+ 0 10px 28px rgba(20, 29, 48, 0.13);
21
+ font-family: "Baron Sans", "Noto Sans SC", sans-serif;
22
+ font-size: 12px;
23
+ line-height: 1;
24
+ user-select: none;
25
+ transition:
26
+ opacity 120ms ease,
27
+ box-shadow 120ms ease;
28
+ }
29
+
30
+ .baron-drawing-toolbar[hidden] {
31
+ display: none;
32
+ }
33
+
34
+ .baron-drawing-toolbar[data-dragging="true"] {
35
+ box-shadow:
36
+ 0 3px 8px rgba(20, 29, 48, 0.12),
37
+ 0 16px 40px rgba(20, 29, 48, 0.18);
38
+ }
39
+
40
+ .baron-drawing-toolbar__grip {
41
+ display: grid;
42
+ flex: 0 0 auto;
43
+ grid-template-columns: repeat(2, 3px);
44
+ gap: 3px;
45
+ width: 24px;
46
+ height: 36px;
47
+ padding: 8px 6px;
48
+ place-content: center;
49
+ color: rgba(153, 158, 170, 1);
50
+ background: transparent;
51
+ border: 0;
52
+ border-radius: 7px;
53
+ cursor: grab;
54
+ touch-action: none;
55
+ }
56
+
57
+ .baron-drawing-toolbar__grip:active {
58
+ cursor: grabbing;
59
+ }
60
+
61
+ .baron-drawing-toolbar__grip-dot {
62
+ width: 3px;
63
+ height: 3px;
64
+ background: currentcolor;
65
+ border-radius: 50%;
66
+ }
67
+
68
+ .baron-drawing-toolbar__type,
69
+ .baron-drawing-toolbar__button,
70
+ .baron-drawing-toolbar__control {
71
+ position: relative;
72
+ display: grid;
73
+ flex: 0 0 auto;
74
+ height: 36px;
75
+ place-items: center;
76
+ color: rgba(32, 35, 42, 1);
77
+ background: transparent;
78
+ border: 0;
79
+ border-radius: 8px;
80
+ }
81
+
82
+ .baron-drawing-toolbar__type,
83
+ .baron-drawing-toolbar__button {
84
+ width: 38px;
85
+ }
86
+
87
+ .baron-drawing-toolbar__type {
88
+ color: rgba(62, 68, 80, 1);
89
+ }
90
+
91
+ .baron-drawing-toolbar__type svg,
92
+ .baron-drawing-toolbar__button svg {
93
+ width: 21px;
94
+ height: 21px;
95
+ }
96
+
97
+ .baron-drawing-toolbar__button {
98
+ cursor: pointer;
99
+ transition:
100
+ color 120ms ease,
101
+ background-color 120ms ease;
102
+ }
103
+
104
+ .baron-drawing-toolbar__button:hover:not(:disabled),
105
+ .baron-drawing-toolbar__grip:hover {
106
+ color: rgba(41, 98, 255, 1);
107
+ background: rgba(41, 98, 255, 0.08);
108
+ }
109
+
110
+ .baron-drawing-toolbar__button:focus-visible,
111
+ .baron-drawing-toolbar__grip:focus-visible,
112
+ .baron-drawing-toolbar__control:focus-within {
113
+ outline: 2px solid rgba(41, 98, 255, 1);
114
+ outline-offset: 1px;
115
+ }
116
+
117
+ .baron-drawing-toolbar__button:disabled,
118
+ .baron-drawing-toolbar__control:has(:disabled) {
119
+ cursor: not-allowed;
120
+ opacity: 0.42;
121
+ }
122
+
123
+ .baron-drawing-toolbar__separator {
124
+ flex: 0 0 auto;
125
+ width: 1px;
126
+ height: 26px;
127
+ margin: 0 4px;
128
+ background: rgba(218, 220, 226, 1);
129
+ }
130
+
131
+ .baron-drawing-toolbar__control {
132
+ min-width: 48px;
133
+ padding: 0 5px;
134
+ }
135
+
136
+ .baron-drawing-toolbar__control select {
137
+ height: 30px;
138
+ padding: 0 20px 0 7px;
139
+ color: inherit;
140
+ background: transparent;
141
+ border: 0;
142
+ font: inherit;
143
+ cursor: pointer;
144
+ outline: 0;
145
+ }
146
+
147
+ .baron-drawing-toolbar__control--style select {
148
+ min-width: 66px;
149
+ }
150
+
151
+ .baron-drawing-toolbar__control--width select {
152
+ min-width: 58px;
153
+ font-size: 15px;
154
+ }
155
+
156
+ .baron-drawing-toolbar__color {
157
+ position: relative;
158
+ display: grid;
159
+ flex: 0 0 auto;
160
+ width: 42px;
161
+ height: 36px;
162
+ place-items: center;
163
+ border-radius: 8px;
164
+ cursor: pointer;
165
+ }
166
+
167
+ .baron-drawing-toolbar__color:hover {
168
+ background: rgba(41, 98, 255, 0.08);
169
+ }
170
+
171
+ .baron-drawing-toolbar__color input {
172
+ position: absolute;
173
+ width: 1px;
174
+ height: 1px;
175
+ opacity: 0;
176
+ pointer-events: none;
177
+ }
178
+
179
+ .baron-drawing-toolbar__color-icon {
180
+ position: relative;
181
+ display: block;
182
+ width: 22px;
183
+ height: 22px;
184
+ }
185
+
186
+ .baron-drawing-toolbar__color-icon::before {
187
+ position: absolute;
188
+ top: 2px;
189
+ left: 7px;
190
+ width: 8px;
191
+ height: 14px;
192
+ content: "";
193
+ border: 2px solid currentcolor;
194
+ border-radius: 2px 2px 5px 2px;
195
+ transform: rotate(42deg);
196
+ }
197
+
198
+ .baron-drawing-toolbar__color-icon::after {
199
+ position: absolute;
200
+ right: 1px;
201
+ bottom: 0;
202
+ left: 1px;
203
+ height: 4px;
204
+ content: "";
205
+ background: var(--baron-drawing-line-color, rgba(41, 98, 255, 1));
206
+ border-radius: 2px;
207
+ }
208
+
209
+ .baron-drawing-toolbar__text {
210
+ width: 128px;
211
+ height: 30px;
212
+ padding: 0 9px;
213
+ color: rgba(32, 35, 42, 1);
214
+ background: rgba(248, 249, 251, 1);
215
+ border: 1px solid rgba(218, 220, 226, 1);
216
+ border-radius: 7px;
217
+ font: inherit;
218
+ outline: 0;
219
+ }
220
+
221
+ .baron-drawing-toolbar__text:focus {
222
+ border-color: rgba(41, 98, 255, 1);
223
+ }
224
+
225
+ .baron-drawing-toolbar__status {
226
+ position: absolute;
227
+ top: calc(100% + 6px);
228
+ left: 8px;
229
+ max-width: 320px;
230
+ padding: 6px 8px;
231
+ color: rgba(179, 44, 38, 1);
232
+ background: rgba(255, 247, 246, 0.98);
233
+ border: 1px solid rgba(226, 181, 177, 1);
234
+ border-radius: 6px;
235
+ font-size: 11px;
236
+ line-height: 1.35;
237
+ box-shadow: 0 6px 18px rgba(20, 29, 48, 0.1);
238
+ }
239
+
240
+ .baron-drawing-toolbar__status[hidden] {
241
+ display: none;
242
+ }
243
+
244
+ @media (prefers-reduced-motion: reduce) {
245
+ .baron-drawing-toolbar,
246
+ .baron-drawing-toolbar__button {
247
+ transition: none;
248
+ }
249
+ }
250
+ `;
@@ -0,0 +1,8 @@
1
+ import type { DrawingRuntimeCapability } from '../drawing/capabilities.js';
2
+ import type { DrawingFloatingToolbar, DrawingFloatingToolbarOptions } from '../types.js';
3
+ /**
4
+ * 创建选中 Drawing 的对象级浮动工具栏。工具栏使用 body portal,避免修改图表引擎 DOM;
5
+ * 拖动位置只保存在当前实例内,刷新后回到图表顶部中央。
6
+ */
7
+ export declare function createDrawingFloatingToolbar(target: HTMLElement, runtime: DrawingRuntimeCapability, options?: DrawingFloatingToolbarOptions): DrawingFloatingToolbar;
8
+ //# sourceMappingURL=drawing-floating-toolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing-floating-toolbar.d.ts","sourceRoot":"","sources":["../../src/toolbar/drawing-floating-toolbar.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EACX,sBAAsB,EACtB,6BAA6B,EAC7B,MAAM,aAAa,CAAC;AAgFrB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,wBAAwB,EACjC,OAAO,GAAE,6BAAkC,GACzC,sBAAsB,CA6WxB"}
@@ -0,0 +1,373 @@
1
+ import { registerRuntimeTeardown } from '../lifecycle.js';
2
+ import { createToolbarIcon } from './toolbar-icons.js';
3
+ import { OVERLAY_TOOL_PRESENTATIONS } from './toolbar-tools.js';
4
+ import { DRAWING_FLOATING_TOOLBAR_STYLES } from './drawing-floating-toolbar-styles.js';
5
+ const VIEWPORT_PADDING = 8;
6
+ const TARGET_PADDING = 10;
7
+ const TARGET_TOP_GAP = 12;
8
+ const TEXT_DRAWING_TYPES = new Set(['simpleAnnotation', 'simpleTag', 'callout', 'text']);
9
+ function htmlHexColorToSceneRgba(value) {
10
+ const match = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(value);
11
+ if (match === null) {
12
+ throw new TypeError(`Invalid HTML color value: ${value}`);
13
+ }
14
+ return `rgba(${Number.parseInt(match[1], 16)}, ${Number.parseInt(match[2], 16)}, ${Number.parseInt(match[3], 16)}, 1)`;
15
+ }
16
+ function sceneColorToHtmlHex(value) {
17
+ const hex = /^#([0-9a-f]{6})$/i.exec(value.trim());
18
+ if (hex !== null) {
19
+ return `#${hex[1].toLowerCase()}`;
20
+ }
21
+ const rgba = /^rgba?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)/i.exec(value);
22
+ if (rgba === null) {
23
+ return '#2962ff';
24
+ }
25
+ return `#${[rgba[1], rgba[2], rgba[3]]
26
+ .map((component) => Math.max(0, Math.min(255, Math.round(Number(component)))).toString(16).padStart(2, '0'))
27
+ .join('')}`;
28
+ }
29
+ function createSeparator() {
30
+ const separator = document.createElement('span');
31
+ separator.className = 'baron-drawing-toolbar__separator';
32
+ separator.setAttribute('aria-hidden', 'true');
33
+ return separator;
34
+ }
35
+ function createSelect(className, action, label, values) {
36
+ const root = document.createElement('label');
37
+ root.className = `baron-drawing-toolbar__control ${className}`;
38
+ const select = document.createElement('select');
39
+ select.dataset.action = action;
40
+ select.setAttribute('aria-label', label);
41
+ for (const item of values) {
42
+ const option = document.createElement('option');
43
+ option.value = item.value;
44
+ option.textContent = item.label;
45
+ select.append(option);
46
+ }
47
+ root.append(select);
48
+ return { label: root, select };
49
+ }
50
+ function createButton(action, label, icon) {
51
+ const button = document.createElement('button');
52
+ button.type = 'button';
53
+ button.className = 'baron-drawing-toolbar__button';
54
+ button.dataset.action = action;
55
+ button.setAttribute('aria-label', label);
56
+ button.title = label;
57
+ button.append(createToolbarIcon(icon));
58
+ return button;
59
+ }
60
+ function selectedDrawing(runtime) {
61
+ const id = runtime.getSelectedDrawingId();
62
+ return id === undefined ? undefined : runtime.getDrawing(id);
63
+ }
64
+ /**
65
+ * 创建选中 Drawing 的对象级浮动工具栏。工具栏使用 body portal,避免修改图表引擎 DOM;
66
+ * 拖动位置只保存在当前实例内,刷新后回到图表顶部中央。
67
+ */
68
+ export function createDrawingFloatingToolbar(target, runtime, options = {}) {
69
+ const style = document.createElement('style');
70
+ style.dataset.baronDrawingToolbarStyles = '';
71
+ style.textContent = DRAWING_FLOATING_TOOLBAR_STYLES;
72
+ const root = document.createElement('div');
73
+ root.className = 'baron-drawing-toolbar';
74
+ root.setAttribute('role', 'toolbar');
75
+ root.setAttribute('aria-label', '选中 Drawing 设置');
76
+ root.hidden = true;
77
+ const grip = document.createElement('button');
78
+ grip.type = 'button';
79
+ grip.className = 'baron-drawing-toolbar__grip';
80
+ grip.dataset.action = 'drag';
81
+ grip.setAttribute('aria-label', '拖动 Drawing 工具栏');
82
+ grip.title = '拖动工具栏';
83
+ for (let index = 0; index < 6; index++) {
84
+ const dot = document.createElement('span');
85
+ dot.className = 'baron-drawing-toolbar__grip-dot';
86
+ grip.append(dot);
87
+ }
88
+ grip.hidden = options.draggable === false;
89
+ const type = document.createElement('span');
90
+ type.className = 'baron-drawing-toolbar__type';
91
+ type.dataset.action = 'drawing-type';
92
+ const color = document.createElement('label');
93
+ color.className = 'baron-drawing-toolbar__color';
94
+ color.setAttribute('aria-label', '线色');
95
+ color.title = '线色';
96
+ const colorIcon = document.createElement('span');
97
+ colorIcon.className = 'baron-drawing-toolbar__color-icon';
98
+ const colorInput = document.createElement('input');
99
+ colorInput.type = 'color';
100
+ colorInput.dataset.action = 'line-color';
101
+ colorInput.setAttribute('aria-label', '线色');
102
+ color.append(colorIcon, colorInput);
103
+ const lineStyle = createSelect('baron-drawing-toolbar__control--style', 'line-style', '线型', [
104
+ { value: 'solid', label: '实线' },
105
+ { value: 'dashed', label: '虚线' },
106
+ { value: 'dotted', label: '点线' },
107
+ ]);
108
+ const lineWidth = createSelect('baron-drawing-toolbar__control--width', 'line-width', '线宽', [0.5, 1, 1.5, 2, 3, 4, 6, 8, 10].map((value) => ({
109
+ value: String(value),
110
+ label: `${value}px`,
111
+ })));
112
+ const textInput = document.createElement('input');
113
+ textInput.type = 'text';
114
+ textInput.className = 'baron-drawing-toolbar__text';
115
+ textInput.dataset.action = 'drawing-text';
116
+ textInput.setAttribute('aria-label', 'Drawing 文本');
117
+ textInput.placeholder = '输入文本';
118
+ textInput.hidden = true;
119
+ const lock = createButton('toggle-lock', '锁定 Drawing', 'lock');
120
+ const remove = createButton('delete', '删除 Drawing', 'trash');
121
+ const status = document.createElement('span');
122
+ status.className = 'baron-drawing-toolbar__status';
123
+ status.setAttribute('role', 'status');
124
+ status.setAttribute('aria-live', 'polite');
125
+ status.hidden = true;
126
+ root.append(grip, type, createSeparator(), color, lineStyle.label, lineWidth.label, textInput, createSeparator(), lock, remove, status);
127
+ document.head.append(style);
128
+ document.body.append(root);
129
+ let destroyed = false;
130
+ let userPositioned = false;
131
+ let dragging = null;
132
+ let currentId;
133
+ const setStatus = (message) => {
134
+ status.textContent = message;
135
+ status.hidden = message.length === 0;
136
+ };
137
+ const bounds = () => {
138
+ const targetRect = target.getBoundingClientRect();
139
+ const width = root.offsetWidth;
140
+ const height = root.offsetHeight;
141
+ const viewportMinLeft = VIEWPORT_PADDING;
142
+ const viewportMaxLeft = Math.max(viewportMinLeft, window.innerWidth - width - VIEWPORT_PADDING);
143
+ const targetMinLeft = targetRect.left + TARGET_PADDING;
144
+ const targetMaxLeft = targetRect.right - width - TARGET_PADDING;
145
+ const minLeft = Math.max(viewportMinLeft, Math.min(targetMinLeft, viewportMaxLeft));
146
+ const maxLeft = Math.max(minLeft, Math.min(viewportMaxLeft, targetMaxLeft));
147
+ const viewportMinTop = VIEWPORT_PADDING;
148
+ const viewportMaxTop = Math.max(viewportMinTop, window.innerHeight - height - VIEWPORT_PADDING);
149
+ const targetMinTop = targetRect.top + TARGET_PADDING;
150
+ const targetMaxTop = targetRect.bottom - height - TARGET_PADDING;
151
+ const minTop = Math.max(viewportMinTop, Math.min(targetMinTop, viewportMaxTop));
152
+ const maxTop = Math.max(minTop, Math.min(viewportMaxTop, targetMaxTop));
153
+ return { minLeft, maxLeft, minTop, maxTop };
154
+ };
155
+ const setPosition = (left, top) => {
156
+ const value = bounds();
157
+ root.style.left = `${Math.round(Math.max(value.minLeft, Math.min(value.maxLeft, left)))}px`;
158
+ root.style.top = `${Math.round(Math.max(value.minTop, Math.min(value.maxTop, top)))}px`;
159
+ };
160
+ const positionAtDefault = () => {
161
+ if (root.hidden) {
162
+ return;
163
+ }
164
+ const targetRect = target.getBoundingClientRect();
165
+ setPosition(targetRect.left + (targetRect.width - root.offsetWidth) / 2, targetRect.top + TARGET_TOP_GAP);
166
+ };
167
+ const clampCurrentPosition = () => {
168
+ if (root.hidden) {
169
+ return;
170
+ }
171
+ if (!userPositioned) {
172
+ positionAtDefault();
173
+ return;
174
+ }
175
+ const left = Number.parseFloat(root.style.left);
176
+ const top = Number.parseFloat(root.style.top);
177
+ setPosition(Number.isFinite(left) ? left : 0, Number.isFinite(top) ? top : 0);
178
+ };
179
+ const updateStyles = (drawing, change) => {
180
+ runtime.updateDrawingStyles(drawing.id, {
181
+ ...structuredClone(drawing.styles),
182
+ line: {
183
+ ...structuredClone(drawing.styles.line),
184
+ ...change,
185
+ },
186
+ });
187
+ };
188
+ const performMutation = (action) => {
189
+ const drawing = selectedDrawing(runtime);
190
+ if (drawing === undefined || runtime.getDrawingMutationState() !== 'ready') {
191
+ return;
192
+ }
193
+ try {
194
+ setStatus('');
195
+ action(drawing);
196
+ }
197
+ catch (error) {
198
+ setStatus(error instanceof Error ? error.message : String(error));
199
+ }
200
+ };
201
+ const render = () => {
202
+ if (destroyed) {
203
+ return;
204
+ }
205
+ const drawing = selectedDrawing(runtime);
206
+ if (drawing === undefined) {
207
+ currentId = undefined;
208
+ root.hidden = true;
209
+ setStatus('');
210
+ return;
211
+ }
212
+ const wasHidden = root.hidden;
213
+ root.hidden = false;
214
+ root.dataset.drawingId = drawing.id;
215
+ root.dataset.drawingType = drawing.type;
216
+ if (currentId !== drawing.id) {
217
+ currentId = drawing.id;
218
+ setStatus('');
219
+ }
220
+ type.replaceChildren();
221
+ const presentation = OVERLAY_TOOL_PRESENTATIONS[drawing.type];
222
+ type.append(createToolbarIcon(presentation.icon));
223
+ type.title = presentation.label;
224
+ type.setAttribute('aria-label', presentation.label);
225
+ const colorValue = sceneColorToHtmlHex(drawing.styles.line.color);
226
+ colorInput.value = colorValue;
227
+ colorIcon.style.setProperty('--baron-drawing-line-color', drawing.styles.line.color);
228
+ lineStyle.select.value = drawing.styles.line.style;
229
+ const widthValue = String(drawing.styles.line.size);
230
+ if (!Array.from(lineWidth.select.options).some((option) => option.value === widthValue)) {
231
+ const option = document.createElement('option');
232
+ option.value = widthValue;
233
+ option.textContent = `${widthValue}px`;
234
+ lineWidth.select.append(option);
235
+ }
236
+ lineWidth.select.value = widthValue;
237
+ const isText = TEXT_DRAWING_TYPES.has(drawing.type);
238
+ textInput.hidden = !isText;
239
+ textInput.value = isText ? drawing.text ?? '' : '';
240
+ lock.replaceChildren(createToolbarIcon(drawing.locked ? 'lock' : 'lockOpen'));
241
+ lock.setAttribute('aria-label', drawing.locked ? '解锁 Drawing' : '锁定 Drawing');
242
+ lock.title = drawing.locked ? '解锁' : '锁定';
243
+ lock.setAttribute('aria-pressed', String(drawing.locked));
244
+ const busy = runtime.getDrawingMutationState() !== 'ready';
245
+ colorInput.disabled = busy || drawing.locked;
246
+ lineStyle.select.disabled = busy || drawing.locked;
247
+ lineWidth.select.disabled = busy || drawing.locked;
248
+ textInput.disabled = busy || drawing.locked;
249
+ lock.disabled = busy;
250
+ remove.disabled = busy || drawing.locked;
251
+ root.setAttribute('aria-busy', String(busy));
252
+ if (wasHidden || !userPositioned) {
253
+ positionAtDefault();
254
+ }
255
+ else {
256
+ clampCurrentPosition();
257
+ }
258
+ };
259
+ const handleColorChange = () => performMutation((drawing) => {
260
+ updateStyles(drawing, { color: htmlHexColorToSceneRgba(colorInput.value) });
261
+ });
262
+ const handleLineStyleChange = () => performMutation((drawing) => {
263
+ updateStyles(drawing, {
264
+ style: lineStyle.select.value,
265
+ });
266
+ });
267
+ const handleLineWidthChange = () => performMutation((drawing) => {
268
+ updateStyles(drawing, { size: Number(lineWidth.select.value) });
269
+ });
270
+ const handleTextChange = () => performMutation((drawing) => {
271
+ runtime.updateDrawingText(drawing.id, textInput.value);
272
+ });
273
+ const handleLock = () => performMutation((drawing) => {
274
+ runtime.updateDrawingLocked(drawing.id, !drawing.locked);
275
+ });
276
+ const handleDelete = () => performMutation((drawing) => {
277
+ if (drawing.locked) {
278
+ return;
279
+ }
280
+ if ((options.deleteBehavior ?? 'direct') === 'request') {
281
+ runtime.requestDrawingDelete(drawing.id);
282
+ }
283
+ else {
284
+ runtime.removeDrawing(drawing.id);
285
+ }
286
+ });
287
+ const handleDragStart = (event) => {
288
+ if (options.draggable === false || event.button !== 0) {
289
+ return;
290
+ }
291
+ const rect = root.getBoundingClientRect();
292
+ dragging = {
293
+ pointerId: event.pointerId,
294
+ offsetX: event.clientX - rect.left,
295
+ offsetY: event.clientY - rect.top,
296
+ };
297
+ userPositioned = true;
298
+ root.dataset.dragging = 'true';
299
+ grip.setPointerCapture(event.pointerId);
300
+ event.preventDefault();
301
+ };
302
+ const handleDragMove = (event) => {
303
+ if (dragging === null || dragging.pointerId !== event.pointerId) {
304
+ return;
305
+ }
306
+ setPosition(event.clientX - dragging.offsetX, event.clientY - dragging.offsetY);
307
+ };
308
+ const finishDrag = (event) => {
309
+ if (dragging === null || dragging.pointerId !== event.pointerId) {
310
+ return;
311
+ }
312
+ if (grip.hasPointerCapture(event.pointerId)) {
313
+ grip.releasePointerCapture(event.pointerId);
314
+ }
315
+ dragging = null;
316
+ root.dataset.dragging = 'false';
317
+ };
318
+ colorInput.addEventListener('change', handleColorChange);
319
+ lineStyle.select.addEventListener('change', handleLineStyleChange);
320
+ lineWidth.select.addEventListener('change', handleLineWidthChange);
321
+ textInput.addEventListener('change', handleTextChange);
322
+ lock.addEventListener('click', handleLock);
323
+ remove.addEventListener('click', handleDelete);
324
+ grip.addEventListener('pointerdown', handleDragStart);
325
+ grip.addEventListener('pointermove', handleDragMove);
326
+ grip.addEventListener('pointerup', finishDrag);
327
+ grip.addEventListener('pointercancel', finishDrag);
328
+ const unsubscribe = runtime.subscribeDrawingChanges(render);
329
+ const handleViewportChange = () => clampCurrentPosition();
330
+ window.addEventListener('resize', handleViewportChange);
331
+ window.addEventListener('scroll', handleViewportChange, true);
332
+ const resizeObserver = typeof ResizeObserver === 'undefined'
333
+ ? null
334
+ : new ResizeObserver(handleViewportChange);
335
+ resizeObserver?.observe(target);
336
+ render();
337
+ let unregisterRuntime = () => { };
338
+ const toolbar = {
339
+ element: root,
340
+ resetPosition() {
341
+ if (destroyed) {
342
+ throw new Error('DRAWING_FLOATING_TOOLBAR_DESTROYED');
343
+ }
344
+ userPositioned = false;
345
+ positionAtDefault();
346
+ },
347
+ destroy() {
348
+ if (destroyed) {
349
+ return;
350
+ }
351
+ destroyed = true;
352
+ unregisterRuntime();
353
+ unsubscribe();
354
+ resizeObserver?.disconnect();
355
+ window.removeEventListener('resize', handleViewportChange);
356
+ window.removeEventListener('scroll', handleViewportChange, true);
357
+ colorInput.removeEventListener('change', handleColorChange);
358
+ lineStyle.select.removeEventListener('change', handleLineStyleChange);
359
+ lineWidth.select.removeEventListener('change', handleLineWidthChange);
360
+ textInput.removeEventListener('change', handleTextChange);
361
+ lock.removeEventListener('click', handleLock);
362
+ remove.removeEventListener('click', handleDelete);
363
+ grip.removeEventListener('pointerdown', handleDragStart);
364
+ grip.removeEventListener('pointermove', handleDragMove);
365
+ grip.removeEventListener('pointerup', finishDrag);
366
+ grip.removeEventListener('pointercancel', finishDrag);
367
+ root.remove();
368
+ style.remove();
369
+ },
370
+ };
371
+ unregisterRuntime = registerRuntimeTeardown(runtime, () => toolbar.destroy());
372
+ return toolbar;
373
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"standard-toolbar-styles.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,QAkTnC,CAAC"}
1
+ {"version":3,"file":"standard-toolbar-styles.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,QAgSnC,CAAC"}
@@ -286,22 +286,4 @@ export const STANDARD_TOOLBAR_STYLES = String.raw `
286
286
  transition: none;
287
287
  }
288
288
  }
289
-
290
- .baron-kline-context-menu {
291
- position: fixed;
292
- z-index: 1000;
293
- display: none;
294
- flex-direction: column;
295
- gap: 8px;
296
- min-width: 180px;
297
- padding: 10px;
298
- border: 1px solid rgba(203, 210, 224, 1);
299
- border-radius: 10px;
300
- background: rgba(255, 255, 255, 0.98);
301
- box-shadow: 0 12px 32px rgba(23, 32, 51, 0.16);
302
- }
303
-
304
- .baron-kline-context-menu--visible {
305
- display: flex;
306
- }
307
289
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"standard-toolbar.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,wBAAwB,EACxB,0BAA0B,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACX,eAAe,EACf,sBAAsB,EAEtB,MAAM,aAAa,CAAC;AA4ErB,KAAK,sBAAsB,GAAG,wBAAwB,GAAG,0BAA0B,CAAC;AA0LpF,2BAA2B;AAC3B,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,GAAE,sBAA2B,GAClC,eAAe,CA4ajB"}
1
+ {"version":3,"file":"standard-toolbar.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,wBAAwB,EACxB,0BAA0B,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACX,eAAe,EACf,sBAAsB,EAEtB,MAAM,aAAa,CAAC;AAgErB,KAAK,sBAAsB,GAAG,wBAAwB,GAAG,0BAA0B,CAAC;AAyKpF,2BAA2B;AAC3B,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,GAAE,sBAA2B,GAClC,eAAe,CA2QjB"}