dynim-core 1.0.3 → 1.0.5

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 (40) hide show
  1. package/README.md +9 -282
  2. package/dist/builder/builder-client.d.ts +1 -5
  3. package/dist/builder/builder-client.d.ts.map +1 -1
  4. package/dist/builder/builder-client.js +2 -22
  5. package/dist/builder/builder.d.ts +0 -4
  6. package/dist/builder/builder.d.ts.map +1 -1
  7. package/dist/builder/builder.js +21 -232
  8. package/dist/builder/code-client.js +1 -1
  9. package/dist/builder/editor-overlays.d.ts +1 -10
  10. package/dist/builder/editor-overlays.d.ts.map +1 -1
  11. package/dist/builder/editor-overlays.js +1 -103
  12. package/dist/builder/editor-state.d.ts +2 -21
  13. package/dist/builder/editor-state.d.ts.map +1 -1
  14. package/dist/builder/editor-state.js +2 -34
  15. package/dist/builder/element-utils.d.ts +0 -11
  16. package/dist/builder/element-utils.d.ts.map +1 -1
  17. package/dist/builder/element-utils.js +0 -58
  18. package/dist/builder/freeze-overlay.d.ts +1 -1
  19. package/dist/builder/freeze-overlay.d.ts.map +1 -1
  20. package/dist/builder/freeze-overlay.js +1 -2
  21. package/dist/builder/index.d.ts +5 -9
  22. package/dist/builder/index.d.ts.map +1 -1
  23. package/dist/builder/index.js +3 -7
  24. package/dist/builder/{drag-engine.d.ts → interaction-engine.d.ts} +6 -20
  25. package/dist/builder/interaction-engine.d.ts.map +1 -0
  26. package/dist/builder/interaction-engine.js +101 -0
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +1 -1
  29. package/package.json +1 -1
  30. package/src/README.md +10 -0
  31. package/src/styles/builder.css +0 -192
  32. package/src/styles/editor.css +2 -61
  33. package/dist/builder/diff-state.d.ts +0 -24
  34. package/dist/builder/diff-state.d.ts.map +0 -1
  35. package/dist/builder/diff-state.js +0 -134
  36. package/dist/builder/drag-engine.d.ts.map +0 -1
  37. package/dist/builder/drag-engine.js +0 -686
  38. package/dist/builder/history-state.d.ts +0 -41
  39. package/dist/builder/history-state.d.ts.map +0 -1
  40. package/dist/builder/history-state.js +0 -76
@@ -5,30 +5,26 @@
5
5
  import { createState } from './state';
6
6
  import { createWidget } from './widget';
7
7
  import { createEditorState } from './editor-state';
8
- import { createHistoryState } from './history-state';
9
- import { createDiffState } from './diff-state';
10
8
  import { createTreeState } from './tree-state';
11
9
  import { createFreezeOverlay } from './freeze-overlay';
12
10
  import { createOverlays } from './editor-overlays';
13
- import { createDragEngine } from './drag-engine';
11
+ import { createInteractionEngine } from './interaction-engine';
14
12
  import { scanDOM } from './dom-scanner';
15
13
  import { createAIPromptPopover } from './ai-prompt-popover';
16
14
  import { createCodeClient } from './code-client';
17
15
  import { createBuilderClient } from './builder-client';
18
16
  import { buildElementIdentifier, getRelevantStyles } from './element-utils';
19
17
  export function createBuilder(config = {}) {
20
- const { logo = 'Builder', onSave, onExit, onEnter, chatConfig = {}, contentRoot = document.body, pageId = window.location.pathname, apiBase = 'http://localhost:8080', sessionToken, refreshToken, getSession, codeClient: externalCodeClient } = config;
18
+ const { logo = 'Builder', onExit, onEnter, chatConfig = {}, contentRoot = document.body, pageId = window.location.pathname, apiBase = 'http://localhost:8080', sessionToken, refreshToken, getSession, codeClient: externalCodeClient } = config;
21
19
  let isActive = false;
22
20
  let chatWidget = null;
23
21
  let state = null;
24
22
  let client = null;
25
23
  let editorState = null;
26
- let historyState = null;
27
- let diffState = null;
28
24
  let treeState = null;
29
25
  let freezeOverlay = null;
30
26
  let overlays = null;
31
- let dragEngine = null;
27
+ let interactionEngine = null;
32
28
  let aiPromptPopover = null;
33
29
  const root = document.createElement('div');
34
30
  root.className = 'builder';
@@ -42,23 +38,6 @@ export function createBuilder(config = {}) {
42
38
  </div>
43
39
  <div class="builder-bar__divider"></div>
44
40
  <div class="builder-bar__actions">
45
- <button class="builder-bar__btn builder-bar__btn--undo" title="Undo (Cmd+Z)" style="display: none;">
46
- <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
47
- <path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/>
48
- </svg>
49
- </button>
50
- <button class="builder-bar__btn builder-bar__btn--preview" title="Preview">
51
- <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
52
- <path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/>
53
- </svg>
54
- Preview
55
- </button>
56
- <button class="builder-bar__btn builder-bar__btn--save" title="Save changes" disabled style="background: rgba(100, 116, 139, 0.5); color: rgba(255, 255, 255, 0.4); cursor: not-allowed; pointer-events: none;">
57
- <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
58
- <path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/>
59
- </svg>
60
- Save
61
- </button>
62
41
  <button class="builder-bar__btn builder-bar__btn--exit">
63
42
  <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
64
43
  <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
@@ -67,23 +46,7 @@ export function createBuilder(config = {}) {
67
46
  </button>
68
47
  </div>
69
48
  </div>
70
-
71
- <div class="builder-modal" style="display: none;">
72
- <div class="builder-modal__backdrop"></div>
73
- <div class="builder-modal__dialog">
74
- <div class="builder-modal__title">Unsaved Changes</div>
75
- <div class="builder-modal__message">You have unsaved changes. What would you like to do?</div>
76
- <div class="builder-modal__actions">
77
- <button class="builder-modal__btn builder-modal__btn--cancel">Cancel</button>
78
- <button class="builder-modal__btn builder-modal__btn--discard">Discard Changes</button>
79
- <button class="builder-modal__btn builder-modal__btn--save">Save & Exit</button>
80
- </div>
81
- </div>
82
- </div>
83
49
  `;
84
- const saveBtn = root.querySelector('.builder-bar__btn--save');
85
- const undoBtn = root.querySelector('.builder-bar__btn--undo');
86
- const modal = root.querySelector('.builder-modal');
87
50
  let builderClient = null;
88
51
  // Track unsubscribe function for external client
89
52
  let unsubscribeFromClient = null;
@@ -162,35 +125,11 @@ export function createBuilder(config = {}) {
162
125
  }
163
126
  });
164
127
  }
165
- function updateButtonStates() {
166
- if (!historyState)
167
- return;
168
- // Show/hide undo button contextually
169
- const canUndo = historyState.canUndo();
170
- undoBtn.style.display = canUndo ? 'flex' : 'none';
171
- const hasActualChanges = diffState ? diffState.getDiff().length > 0 : false;
172
- saveBtn.disabled = !hasActualChanges;
173
- if (hasActualChanges) {
174
- saveBtn.style.background = '#3b82f6';
175
- saveBtn.style.color = '#ffffff';
176
- saveBtn.style.opacity = '1';
177
- saveBtn.style.cursor = 'pointer';
178
- saveBtn.style.pointerEvents = 'auto';
179
- }
180
- else {
181
- saveBtn.style.background = 'rgba(100, 116, 139, 0.5)';
182
- saveBtn.style.color = 'rgba(255, 255, 255, 0.4)';
183
- saveBtn.style.opacity = '1';
184
- saveBtn.style.cursor = 'not-allowed';
185
- saveBtn.style.pointerEvents = 'none';
186
- }
187
- }
188
128
  function performScan() {
189
129
  const tree = scanDOM(contentRoot);
190
130
  if (tree) {
191
131
  treeState?.setTree(tree);
192
132
  }
193
- updateButtonStates();
194
133
  }
195
134
  function enter() {
196
135
  if (isActive)
@@ -199,36 +138,28 @@ export function createBuilder(config = {}) {
199
138
  root.classList.add('builder--active');
200
139
  document.body.classList.add('builder-mode-active');
201
140
  editorState = createEditorState();
202
- historyState = createHistoryState();
203
- diffState = createDiffState();
204
141
  treeState = createTreeState();
205
- diffState.snapshotInitialState(contentRoot);
206
- historyState.subscribe(updateButtonStates);
207
142
  overlays = createOverlays();
208
143
  overlays.mount();
209
- dragEngine = createDragEngine({
144
+ interactionEngine = createInteractionEngine({
210
145
  contentRoot,
211
146
  editorState,
212
- historyState,
213
- diffState,
214
- treeState,
215
147
  overlays,
216
148
  freezeOverlay: null,
217
- onRescan: performScan
218
149
  });
219
150
  freezeOverlay = createFreezeOverlay({
220
151
  contentRoot,
221
- onMouseDown: (e, el) => dragEngine?.handleMouseDown(e, el),
222
- onMouseMove: (e, el) => dragEngine?.handleMouseMove(e, el),
223
- onMouseUp: (e, el) => dragEngine?.handleMouseUp(e, el),
224
- onMouseLeave: (e) => dragEngine?.handleMouseLeave(e),
225
- onClick: (e, el) => dragEngine?.handleClick(e, el),
226
- onDoubleClick: (e, el) => dragEngine?.handleDoubleClick(e, el),
227
- onWheel: (e) => dragEngine?.handleWheel(e)
152
+ onMouseDown: (e, el) => interactionEngine?.handleMouseDown(e, el),
153
+ onMouseMove: (e, el) => interactionEngine?.handleMouseMove(e, el),
154
+ onMouseUp: (e, el) => interactionEngine?.handleMouseUp(e, el),
155
+ onMouseLeave: (e) => interactionEngine?.handleMouseLeave(e),
156
+ onClick: (e, el) => interactionEngine?.handleClick(e, el),
157
+ onDoubleClick: (e, el) => interactionEngine?.handleDoubleClick(e, el),
158
+ onWheel: (e) => interactionEngine?.handleWheel(e)
228
159
  });
229
160
  freezeOverlay.mount();
230
- dragEngine.setFreezeOverlay(freezeOverlay);
231
- dragEngine.attach();
161
+ interactionEngine.setFreezeOverlay(freezeOverlay);
162
+ interactionEngine.attach();
232
163
  aiPromptPopover = createAIPromptPopover({
233
164
  onSubmit: (prompt) => {
234
165
  const selectedEl = editorState?.getState().selectedElement;
@@ -272,35 +203,23 @@ export function createBuilder(config = {}) {
272
203
  }
273
204
  });
274
205
  aiPromptPopover.mount();
275
- let chatWasOpenBeforeDrag = false;
276
206
  let chatWasOpenBeforeSelection = false;
277
207
  editorState.subscribe((newState, prevState) => {
278
208
  if (chatWidget) {
279
- const dragStarted = newState.isDragging && !prevState?.isDragging;
280
- const dragEnded = !newState.isDragging && prevState?.isDragging;
281
- if (dragStarted) {
282
- chatWasOpenBeforeDrag = chatWidget.isOpen();
283
- if (chatWasOpenBeforeDrag) {
284
- chatWidget.close();
285
- }
286
- }
287
- else if (dragEnded && chatWasOpenBeforeDrag) {
288
- chatWidget.open();
289
- }
290
209
  const selectionStarted = newState.selectedElement && !prevState?.selectedElement;
291
210
  const selectionEnded = !newState.selectedElement && prevState?.selectedElement;
292
- if (selectionStarted && !newState.isDragging) {
211
+ if (selectionStarted) {
293
212
  chatWasOpenBeforeSelection = chatWidget.isOpen();
294
213
  if (chatWasOpenBeforeSelection) {
295
214
  chatWidget.close();
296
215
  }
297
216
  }
298
- else if (selectionEnded && chatWasOpenBeforeSelection && !newState.isDragging) {
217
+ else if (selectionEnded && chatWasOpenBeforeSelection) {
299
218
  chatWidget.open();
300
219
  chatWasOpenBeforeSelection = false;
301
220
  }
302
221
  }
303
- if (newState.selectedElement && newState.selectionRect && !newState.isDragging) {
222
+ if (newState.selectedElement && newState.selectionRect) {
304
223
  aiPromptPopover?.show(newState.selectionRect);
305
224
  }
306
225
  else {
@@ -312,10 +231,10 @@ export function createBuilder(config = {}) {
312
231
  state = createState();
313
232
  state.addMessage({
314
233
  role: 'assistant',
315
- text: 'Hi! I\'m here to help you build. Select an element by clicking on it, or drag elements to rearrange them.'
234
+ text: 'Hi! I\'m here to help you build. Select an element by clicking on it to make changes.'
316
235
  });
317
236
  initCodeClient(state);
318
- initBuilderClient(); // For visual builder operations (saveDiffs, preview, exit)
237
+ initBuilderClient();
319
238
  // Pre-warm the cache for faster chat responses (projectId comes from JWT)
320
239
  if (client) {
321
240
  client.warmCache();
@@ -351,22 +270,18 @@ export function createBuilder(config = {}) {
351
270
  onEnter?.();
352
271
  }
353
272
  function cleanup() {
354
- modal.style.display = 'none';
355
273
  root.classList.remove('builder--active');
356
274
  document.body.classList.remove('builder-mode-active');
357
- dragEngine?.detach();
275
+ interactionEngine?.detach();
358
276
  aiPromptPopover?.unmount();
359
277
  overlays?.unmount();
360
278
  freezeOverlay?.unmount();
361
- dragEngine = null;
279
+ interactionEngine = null;
362
280
  aiPromptPopover = null;
363
281
  overlays = null;
364
282
  freezeOverlay = null;
365
283
  editorState = null;
366
- historyState = null;
367
- diffState = null;
368
284
  treeState = null;
369
- undoBtn.style.display = 'none';
370
285
  if (chatWidget) {
371
286
  chatWidget.close();
372
287
  chatWidget.root.style.display = 'none';
@@ -377,7 +292,7 @@ export function createBuilder(config = {}) {
377
292
  if (!isActive)
378
293
  return;
379
294
  isActive = false;
380
- // Notify server of exit (discarding changes)
295
+ // Notify server of exit
381
296
  if (builderClient) {
382
297
  try {
383
298
  await builderClient.exit(pageId, true);
@@ -387,155 +302,29 @@ export function createBuilder(config = {}) {
387
302
  console.error('[Builder] Exit notification failed:', error);
388
303
  }
389
304
  }
390
- while (historyState?.canUndo()) {
391
- dragEngine?.executeUndo();
392
- }
393
305
  cleanup();
394
306
  }
395
- async function save() {
396
- console.log('[Builder] Save called, isActive:', isActive);
397
- if (!isActive)
398
- return;
399
- isActive = false;
400
- const diffs = diffState?.getDiff() || [];
401
- console.log('[Builder] Diffs count:', diffs.length);
402
- console.log('[Builder] builderClient exists:', !!builderClient);
403
- if (builderClient && diffs.length > 0) {
404
- try {
405
- console.log('[Builder] Saving diffs to backend:', { pageId, diffs });
406
- const result = await builderClient.saveDiffs(pageId, diffs);
407
- console.log('[Builder] Save result:', result);
408
- }
409
- catch (error) {
410
- console.error('[Builder] Save failed:', error);
411
- }
412
- }
413
- else {
414
- console.log('[Builder] Skipping save - no client or no diffs');
415
- }
416
- onSave?.(diffs);
417
- cleanup();
418
- }
419
- async function preview() {
420
- if (!isActive)
421
- return;
422
- const diffs = diffState?.getDiff() || [];
423
- console.log('[Builder] Preview called, diffs:', diffs.length);
424
- if (builderClient) {
425
- try {
426
- const result = await builderClient.preview(pageId, diffs);
427
- console.log('[Builder] Preview result:', result);
428
- // TODO: Handle preview result (e.g., open preview URL, toggle preview mode)
429
- if (result.previewUrl) {
430
- window.open(result.previewUrl, '_blank');
431
- }
432
- }
433
- catch (error) {
434
- console.error('[Builder] Preview failed:', error);
435
- }
436
- }
437
- }
438
- function showModal() {
439
- modal.style.display = '';
440
- }
441
- function hideModal() {
442
- modal.style.display = 'none';
443
- }
444
- function hasUnsavedChanges() {
445
- const hasDiffs = diffState ? diffState.getDiff().length > 0 : false;
446
- const hasHistory = historyState ? historyState.canUndo() : false;
447
- return hasDiffs || hasHistory;
448
- }
449
- function handleExitClick() {
450
- if (hasUnsavedChanges()) {
451
- showModal();
452
- }
453
- else {
454
- exit();
455
- }
456
- }
457
307
  root.addEventListener('click', (e) => {
458
308
  const target = e.target;
459
309
  if (target.closest('.builder-bar__btn--exit')) {
460
310
  e.stopPropagation();
461
- handleExitClick();
462
- return;
463
- }
464
- if (target.closest('.builder-bar__btn--save')) {
465
- e.stopPropagation();
466
- save();
467
- return;
468
- }
469
- if (target.closest('.builder-bar__btn--preview')) {
470
- e.stopPropagation();
471
- preview();
472
- return;
473
- }
474
- if (target.closest('.builder-bar__btn--undo')) {
475
- e.stopPropagation();
476
- dragEngine?.executeUndo();
477
- return;
478
- }
479
- if (target.closest('.builder-modal__btn--cancel')) {
480
- e.stopPropagation();
481
- hideModal();
482
- return;
483
- }
484
- if (target.closest('.builder-modal__btn--discard')) {
485
- e.stopPropagation();
486
- hideModal();
487
311
  exit();
488
312
  return;
489
313
  }
490
- if (target.closest('.builder-modal__btn--save')) {
491
- e.stopPropagation();
492
- hideModal();
493
- save();
494
- return;
495
- }
496
- if (target.closest('.builder-modal__backdrop')) {
497
- e.stopPropagation();
498
- hideModal();
499
- return;
500
- }
501
314
  });
502
315
  document.addEventListener('click', (e) => {
503
316
  const target = e.target;
504
317
  if (target.closest('.builder-bar__btn--exit')) {
505
318
  e.preventDefault();
506
319
  e.stopPropagation();
507
- handleExitClick();
508
- }
509
- else if (target.closest('.builder-bar__btn--save') && !saveBtn.disabled) {
510
- e.preventDefault();
511
- e.stopPropagation();
512
- save();
513
- }
514
- else if (target.closest('.builder-modal__btn--discard')) {
515
- e.preventDefault();
516
- e.stopPropagation();
517
- hideModal();
518
320
  exit();
519
321
  }
520
- else if (target.closest('.builder-modal__btn--save')) {
521
- e.preventDefault();
522
- e.stopPropagation();
523
- hideModal();
524
- save();
525
- }
526
- else if (target.closest('.builder-modal__btn--cancel')) {
527
- e.preventDefault();
528
- e.stopPropagation();
529
- hideModal();
530
- }
531
322
  }, true);
532
323
  document.body.appendChild(root);
533
324
  return {
534
325
  enter,
535
326
  exit,
536
- save,
537
327
  isActive: () => isActive,
538
- getChanges: () => diffState?.getDiff() || [],
539
328
  getEditorState: () => editorState?.getState(),
540
329
  getTreeState: () => treeState?.getState(),
541
330
  destroy: () => {
@@ -38,7 +38,7 @@ export function createCodeClient(config = {}) {
38
38
  const messageListeners = new Set();
39
39
  /** Notify all listeners of message update */
40
40
  function notifyListeners() {
41
- notifyListeners();
41
+ onMessageUpdate?.(currentMessage);
42
42
  messageListeners.forEach(listener => listener(currentMessage));
43
43
  }
44
44
  /** Update message state and notify listeners */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Visual overlays for the editor
3
- * Hover highlight, selection box, drag ghost, drop indicator
3
+ * Hover highlight, selection box, and tooltip
4
4
  * Uses CSS classes with !important to prevent Dark Reader interference
5
5
  */
6
6
  export interface OverlaysConfig {
@@ -14,15 +14,6 @@ export interface Overlays {
14
14
  hideHover: () => void;
15
15
  showSelection: (rect: DOMRect | null) => void;
16
16
  hideSelection: () => void;
17
- showDragGhost: (sourceRect: DOMRect | null, cursorPos: {
18
- x: number;
19
- y: number;
20
- } | null, grabOffsetX?: number | null, grabOffsetY?: number | null) => void;
21
- hideDragGhost: () => void;
22
- showDropIndicator: (targetRect: DOMRect | null, position: string | null, parentRect?: DOMRect | null) => void;
23
- hideDropIndicator: () => void;
24
- showNoDropIndicator: (rect: DOMRect | null) => void;
25
- hideNoDropIndicator: () => void;
26
17
  showTooltip: (text: string | null, rect: DOMRect | null) => void;
27
18
  hideTooltip: () => void;
28
19
  hideAll: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"editor-overlays.d.ts","sourceRoot":"","sources":["../../src/builder/editor-overlays.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1J,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,iBAAiB,EAAE,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9G,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IACpD,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AASD,wBAAgB,cAAc,CAAC,MAAM,GAAE,cAAmB,GAAG,QAAQ,CA4NpE"}
1
+ {"version":3,"file":"editor-overlays.d.ts","sourceRoot":"","sources":["../../src/builder/editor-overlays.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AASD,wBAAgB,cAAc,CAAC,MAAM,GAAE,cAAmB,GAAG,QAAQ,CAuGpE"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Visual overlays for the editor
3
- * Hover highlight, selection box, drag ghost, drop indicator
3
+ * Hover highlight, selection box, and tooltip
4
4
  * Uses CSS classes with !important to prevent Dark Reader interference
5
5
  */
6
6
  function createOverlayElement(className) {
@@ -21,20 +21,10 @@ export function createOverlays(config = {}) {
21
21
  `;
22
22
  const hoverOverlay = createOverlayElement('editor-hover-overlay');
23
23
  const selectionOverlay = createOverlayElement('editor-selection-overlay');
24
- const dragGhost = createOverlayElement('editor-drag-ghost');
25
- const dropLine = createOverlayElement('editor-drop-line');
26
- const dropTarget = createOverlayElement('editor-drop-target');
27
- const parentHighlight = createOverlayElement('editor-parent-highlight');
28
24
  const tooltip = createOverlayElement('editor-tooltip');
29
- const noDropIndicator = createOverlayElement('editor-no-drop-indicator');
30
25
  container.appendChild(hoverOverlay);
31
26
  container.appendChild(selectionOverlay);
32
- container.appendChild(dragGhost);
33
- container.appendChild(dropTarget);
34
- container.appendChild(parentHighlight);
35
- container.appendChild(dropLine);
36
27
  container.appendChild(tooltip);
37
- container.appendChild(noDropIndicator);
38
28
  function mount() {
39
29
  document.body.appendChild(container);
40
30
  }
@@ -73,89 +63,6 @@ export function createOverlays(config = {}) {
73
63
  selectionOverlay.classList.remove('active');
74
64
  selectionOverlay.style.display = 'none';
75
65
  }
76
- function showDragGhost(sourceRect, cursorPos, grabOffsetX = null, grabOffsetY = null) {
77
- if (!sourceRect || !cursorPos) {
78
- hideDragGhost();
79
- return;
80
- }
81
- const ghostX = grabOffsetX !== null ? cursorPos.x - grabOffsetX : cursorPos.x - sourceRect.width / 2;
82
- const ghostY = grabOffsetY !== null ? cursorPos.y - grabOffsetY : cursorPos.y - sourceRect.height / 2;
83
- dragGhost.style.left = `${ghostX}px`;
84
- dragGhost.style.top = `${ghostY}px`;
85
- dragGhost.style.width = `${sourceRect.width}px`;
86
- dragGhost.style.height = `${sourceRect.height}px`;
87
- dragGhost.style.display = 'block';
88
- dragGhost.classList.add('active');
89
- }
90
- function hideDragGhost() {
91
- dragGhost.classList.remove('active');
92
- dragGhost.style.display = 'none';
93
- }
94
- function showDropIndicator(targetRect, position, _parentRect) {
95
- if (!targetRect || !position) {
96
- hideDropIndicator();
97
- return;
98
- }
99
- dropTarget.style.left = `${targetRect.x}px`;
100
- dropTarget.style.top = `${targetRect.y}px`;
101
- dropTarget.style.width = `${targetRect.width}px`;
102
- dropTarget.style.height = `${targetRect.height}px`;
103
- dropTarget.style.display = 'block';
104
- dropTarget.classList.add('active');
105
- parentHighlight.classList.remove('active');
106
- parentHighlight.style.display = 'none';
107
- const lineThickness = 4;
108
- if (position === 'top') {
109
- dropLine.style.left = `${targetRect.x}px`;
110
- dropLine.style.top = `${targetRect.y - lineThickness / 2}px`;
111
- dropLine.style.width = `${targetRect.width}px`;
112
- dropLine.style.height = `${lineThickness}px`;
113
- }
114
- else if (position === 'bottom') {
115
- dropLine.style.left = `${targetRect.x}px`;
116
- dropLine.style.top = `${targetRect.y + targetRect.height - lineThickness / 2}px`;
117
- dropLine.style.width = `${targetRect.width}px`;
118
- dropLine.style.height = `${lineThickness}px`;
119
- }
120
- else if (position === 'left') {
121
- dropLine.style.left = `${targetRect.x - lineThickness / 2}px`;
122
- dropLine.style.top = `${targetRect.y}px`;
123
- dropLine.style.width = `${lineThickness}px`;
124
- dropLine.style.height = `${targetRect.height}px`;
125
- }
126
- else if (position === 'right') {
127
- dropLine.style.left = `${targetRect.x + targetRect.width - lineThickness / 2}px`;
128
- dropLine.style.top = `${targetRect.y}px`;
129
- dropLine.style.width = `${lineThickness}px`;
130
- dropLine.style.height = `${targetRect.height}px`;
131
- }
132
- dropLine.style.display = 'block';
133
- dropLine.classList.add('active');
134
- }
135
- function hideDropIndicator() {
136
- dropTarget.classList.remove('active');
137
- dropTarget.style.display = 'none';
138
- dropLine.classList.remove('active');
139
- dropLine.style.display = 'none';
140
- parentHighlight.classList.remove('active');
141
- parentHighlight.style.display = 'none';
142
- }
143
- function showNoDropIndicator(rect) {
144
- if (!rect) {
145
- hideNoDropIndicator();
146
- return;
147
- }
148
- noDropIndicator.style.left = `${rect.x}px`;
149
- noDropIndicator.style.top = `${rect.y}px`;
150
- noDropIndicator.style.width = `${rect.width}px`;
151
- noDropIndicator.style.height = `${rect.height}px`;
152
- noDropIndicator.style.display = 'block';
153
- noDropIndicator.classList.add('active');
154
- }
155
- function hideNoDropIndicator() {
156
- noDropIndicator.classList.remove('active');
157
- noDropIndicator.style.display = 'none';
158
- }
159
66
  function showTooltip(text, rect) {
160
67
  if (!text || !rect) {
161
68
  hideTooltip();
@@ -176,9 +83,6 @@ export function createOverlays(config = {}) {
176
83
  function hideAll() {
177
84
  hideHover();
178
85
  hideSelection();
179
- hideDragGhost();
180
- hideDropIndicator();
181
- hideNoDropIndicator();
182
86
  hideTooltip();
183
87
  }
184
88
  return {
@@ -189,12 +93,6 @@ export function createOverlays(config = {}) {
189
93
  hideHover,
190
94
  showSelection,
191
95
  hideSelection,
192
- showDragGhost,
193
- hideDragGhost,
194
- showDropIndicator,
195
- hideDropIndicator,
196
- showNoDropIndicator,
197
- hideNoDropIndicator,
198
96
  showTooltip,
199
97
  hideTooltip,
200
98
  hideAll
@@ -1,12 +1,7 @@
1
1
  /**
2
- * Editor state management - Selection, hover, and drag state
3
- * Uses event emitters for framework-agnostic reactivity (matching state.js pattern)
2
+ * Editor state management - Selection and hover state
3
+ * Uses event emitters for framework-agnostic reactivity
4
4
  */
5
- export interface DropIndicator {
6
- rect: DOMRect;
7
- position: string;
8
- parentRect?: DOMRect | null;
9
- }
10
5
  export interface EditorStateData {
11
6
  selectedIds: string[];
12
7
  primarySelectedId: string | null;
@@ -17,14 +12,6 @@ export interface EditorStateData {
17
12
  hoveredElement: HTMLElement | null;
18
13
  drillDepth: number;
19
14
  isMultiSelectActive: boolean;
20
- isDragging: boolean;
21
- dragSourceElement: HTMLElement | null;
22
- dragSourceRect: DOMRect | null;
23
- dragGhostPos: {
24
- x: number;
25
- y: number;
26
- } | null;
27
- dropIndicator: DropIndicator | null;
28
15
  }
29
16
  export type EditorStateListener = (state: EditorStateData, prevState?: EditorStateData) => void;
30
17
  export interface EditorState {
@@ -39,12 +26,6 @@ export interface EditorState {
39
26
  clearHover: () => void;
40
27
  incrementDrillDepth: () => void;
41
28
  resetDrillDepth: () => void;
42
- startDrag: (element: HTMLElement, rect: DOMRect) => void;
43
- updateDrag: (ghostPos: {
44
- x: number;
45
- y: number;
46
- } | null, dropIndicator: DropIndicator | null) => void;
47
- endDrag: () => void;
48
29
  }
49
30
  export declare function createEditorState(initialState?: Partial<EditorStateData>): EditorState;
50
31
  //# sourceMappingURL=editor-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-state.d.ts","sourceRoot":"","sources":["../../src/builder/editor-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;AAEhG,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,eAAe,CAAC;IAChC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IACtD,SAAS,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,MAAM,IAAI,CAAC;IACzD,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1E,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IACzF,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,SAAS,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,UAAU,EAAE,CAAC,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;IACrG,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,WAAW,CA+I1F"}
1
+ {"version":3,"file":"editor-state.d.ts","sourceRoot":"","sources":["../../src/builder/editor-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;AAEhG,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,eAAe,CAAC;IAChC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IACtD,SAAS,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,MAAM,IAAI,CAAC;IACzD,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1E,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IACzF,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,GAAG,WAAW,CA4G1F"}