@teriusu/rich-editor 0.10.0 → 0.10.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"TabsBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/TabsBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AA4DrD;;;;;GAKG;AACH,eAAO,MAAM,GAAG,gBAqDd,CAAC;AAEH,eAAO,MAAM,SAAS,gBA6lBpB,CAAC;AAEH,OAAO,QAAQ,cAAc,CAAC;IAC7B,UAAU,QAAQ,CAAC,UAAU;QAC5B,IAAI,EAAE;YACL,qCAAqC;YACrC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;SACxC,CAAC;KACF;CACD"}
1
+ {"version":3,"file":"TabsBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/TabsBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AA4DrD;;;;;GAKG;AACH,eAAO,MAAM,GAAG,gBAqDd,CAAC;AAEH,eAAO,MAAM,SAAS,gBAinBpB,CAAC;AAEH,OAAO,QAAQ,cAAc,CAAC;IAC7B,UAAU,QAAQ,CAAC,UAAU;QAC5B,IAAI,EAAE;YACL,qCAAqC;YACrC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;SACxC,CAAC;KACF;CACD"}
@@ -395,18 +395,12 @@ export const TabsBlock = Node.create({
395
395
  if (!state)
396
396
  return;
397
397
  dragging = null;
398
- document.removeEventListener("keydown", onEscape, true);
398
+ detachDragListeners();
399
399
  // ⚠️ 드래그 동안 꺼 뒀던 것을 되돌린다(이름 고치기와 같은 이유).
400
400
  dom.draggable = true;
401
401
  bar.classList.remove("is-dragging");
402
402
  state.chip.classList.remove("is-dragged");
403
403
  markDrop(-1);
404
- try {
405
- state.chip.releasePointerCapture(state.pointerId);
406
- }
407
- catch {
408
- // 이미 놓였거나 캡처를 못 잡은 포인터 — 무시해도 된다.
409
- }
410
404
  // 임계값을 못 넘겼으면 드래그가 아니다. 뒤따르는 click 이 탭 전환을 한다.
411
405
  if (!state.moved)
412
406
  return;
@@ -415,6 +409,56 @@ export const TabsBlock = Node.create({
415
409
  return;
416
410
  moveTab(state.index, state.drop);
417
411
  };
412
+ /*
413
+ * 끄는 동안의 move·up 은 **문서에서** 받는다.
414
+ *
415
+ * ⚠️ **`setPointerCapture` 를 쓰지 않는다.** 칩에 캡처를 걸면 뒤따르는 호환 마우스
416
+ * 이벤트가 캡처 대상(칩)으로 **재타겟팅**된다. 그러면 칩 **안**의 라벨 버튼에 건
417
+ * 리스너를 건너뛰어, 더블클릭 이름 고치기가 통째로 죽는다 — 실측 로그에서 두 번째
418
+ * 클릭의 `target` 이 라벨이 아니라 칩으로 찍혔고 `dblclick` 은 아예 오지 않았다.
419
+ * 문서에 걸면 칩 밖으로 빠르게 끌어도 놓치지 않으므로 캡처가 필요 없다.
420
+ */
421
+ const onDragMove = (e) => {
422
+ if (!dragging || dragging.pointerId !== e.pointerId)
423
+ return;
424
+ if (!dragging.moved) {
425
+ // ⚠️ 임계값 전에는 드래그가 아니다 — 넘지 않고 떼면 전환 클릭이 살아야 한다.
426
+ const dx = Math.abs(e.clientX - dragging.startX);
427
+ const dy = Math.abs(e.clientY - dragging.startY);
428
+ if (dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD)
429
+ return;
430
+ dragging.moved = true;
431
+ // 끄는 동안에는 블록 통째로 끌기를 꺼 둔다.
432
+ dom.draggable = false;
433
+ bar.classList.add("is-dragging");
434
+ dragging.chip.classList.add("is-dragged");
435
+ }
436
+ e.preventDefault();
437
+ dragging.drop = dropIndexAt(e.clientX, e.clientY);
438
+ markDrop(dragging.drop);
439
+ };
440
+ const onDragUp = (e) => {
441
+ if (!dragging || dragging.pointerId !== e.pointerId)
442
+ return;
443
+ endDrag(true);
444
+ };
445
+ const onDragCancel = (e) => {
446
+ if (!dragging || dragging.pointerId !== e.pointerId)
447
+ return;
448
+ endDrag(false);
449
+ };
450
+ function attachDragListeners() {
451
+ document.addEventListener("pointermove", onDragMove, true);
452
+ document.addEventListener("pointerup", onDragUp, true);
453
+ document.addEventListener("pointercancel", onDragCancel, true);
454
+ document.addEventListener("keydown", onEscape, true);
455
+ }
456
+ function detachDragListeners() {
457
+ document.removeEventListener("pointermove", onDragMove, true);
458
+ document.removeEventListener("pointerup", onDragUp, true);
459
+ document.removeEventListener("pointercancel", onDragCancel, true);
460
+ document.removeEventListener("keydown", onEscape, true);
461
+ }
418
462
  /** 칩을 두 번 누르면 그 자리에서 이름을 고친다. */
419
463
  const startRename = (index, chip, label) => {
420
464
  if (renaming !== null)
@@ -493,35 +537,8 @@ export const TabsBlock = Node.create({
493
537
  moved: false,
494
538
  drop: index
495
539
  };
496
- try {
497
- chip.setPointerCapture(e.pointerId);
498
- }
499
- catch {
500
- // 캡처를 못 잡아도 아래 move/up 리스너가 칩 위에 있으니 굴러간다.
501
- }
502
- document.addEventListener("keydown", onEscape, true);
503
- });
504
- chip.addEventListener("pointermove", (e) => {
505
- if (!dragging || dragging.pointerId !== e.pointerId)
506
- return;
507
- if (!dragging.moved) {
508
- // ⚠️ 임계값 전에는 드래그가 아니다 — 넘지 않고 떼면 전환 클릭이 살아야 한다.
509
- const dx = Math.abs(e.clientX - dragging.startX);
510
- const dy = Math.abs(e.clientY - dragging.startY);
511
- if (dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD)
512
- return;
513
- dragging.moved = true;
514
- // 끄는 동안에는 블록 통째로 끌기를 꺼 둔다.
515
- dom.draggable = false;
516
- bar.classList.add("is-dragging");
517
- chip.classList.add("is-dragged");
518
- }
519
- e.preventDefault();
520
- dragging.drop = dropIndexAt(e.clientX, e.clientY);
521
- markDrop(dragging.drop);
540
+ attachDragListeners();
522
541
  });
523
- chip.addEventListener("pointerup", () => endDrag(true));
524
- chip.addEventListener("pointercancel", () => endDrag(false));
525
542
  }
526
543
  const label = document.createElement("button");
527
544
  label.type = "button";
@@ -629,8 +646,8 @@ export const TabsBlock = Node.create({
629
646
  return true;
630
647
  },
631
648
  destroy: () => {
632
- // 드래그 도중에 노드가 사라질 수 있다 — 문서에 건 Esc 리스너를 남기지 않는다.
633
- document.removeEventListener("keydown", onEscape, true);
649
+ // 드래그 도중에 노드가 사라질 수 있다 — 문서에 건 리스너를 남기지 않는다.
650
+ detachDragListeners();
634
651
  },
635
652
  // 탭바 위의 이벤트는 ProseMirror 가 가로채면 안 된다.
636
653
  stopEvent: (event) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teriusu/rich-editor",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "TipTap 기반 Notion-style 리치 텍스트 에디터 (Svelte)",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",