@tldraw/editor 5.1.0 → 5.2.0-canary.083e81484bc9

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 (108) hide show
  1. package/README.md +1 -1
  2. package/dist-cjs/index.d.ts +10 -46
  3. package/dist-cjs/index.js +3 -4
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +4 -1
  6. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +3 -3
  7. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js.map +2 -2
  9. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js +1 -1
  10. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js.map +3 -3
  11. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js.map +2 -2
  13. package/dist-cjs/lib/editor/Editor.js +51 -15
  14. package/dist-cjs/lib/editor/Editor.js.map +3 -3
  15. package/dist-cjs/lib/editor/derivations/bindingsIndex.js +2 -2
  16. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  17. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +2 -2
  18. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  19. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js +2 -2
  20. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js.map +2 -2
  21. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +8 -58
  22. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  23. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +1 -1
  24. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -2
  26. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js +79 -0
  28. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js.map +7 -0
  29. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  30. package/dist-cjs/lib/editor/types/event-types.js +0 -2
  31. package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
  32. package/dist-cjs/lib/license/LicenseProvider.js +3 -1
  33. package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
  34. package/dist-cjs/lib/primitives/utils.js +2 -2
  35. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  36. package/dist-cjs/lib/utils/dom.js +5 -3
  37. package/dist-cjs/lib/utils/dom.js.map +2 -2
  38. package/dist-cjs/version.js +3 -3
  39. package/dist-cjs/version.js.map +1 -1
  40. package/dist-esm/index.d.mts +10 -46
  41. package/dist-esm/index.mjs +2 -6
  42. package/dist-esm/index.mjs.map +2 -2
  43. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +4 -1
  44. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +3 -3
  45. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs +2 -2
  46. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map +2 -2
  47. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs +1 -1
  48. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map +3 -3
  49. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs +2 -2
  50. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs.map +2 -2
  51. package/dist-esm/lib/editor/Editor.mjs +51 -15
  52. package/dist-esm/lib/editor/Editor.mjs.map +3 -3
  53. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +2 -2
  54. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  55. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +2 -2
  56. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  57. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs +2 -2
  58. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs.map +2 -2
  59. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +8 -58
  60. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  61. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +1 -1
  62. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
  63. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -2
  64. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  65. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs +59 -0
  66. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs.map +7 -0
  67. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  68. package/dist-esm/lib/editor/types/event-types.mjs +0 -2
  69. package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
  70. package/dist-esm/lib/license/LicenseProvider.mjs +3 -1
  71. package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
  72. package/dist-esm/lib/primitives/utils.mjs +2 -2
  73. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  74. package/dist-esm/lib/utils/dom.mjs +5 -3
  75. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  76. package/dist-esm/version.mjs +3 -3
  77. package/dist-esm/version.mjs.map +1 -1
  78. package/editor.css +2 -0
  79. package/package.json +8 -8
  80. package/src/index.ts +1 -5
  81. package/src/lib/components/default-components/DefaultErrorFallback.tsx +4 -1
  82. package/src/lib/components/default-components/DefaultLoadingScreen.tsx +1 -1
  83. package/src/lib/components/default-components/DefaultShapeErrorFallback.tsx +4 -3
  84. package/src/lib/components/default-components/DefaultSvgDefs.tsx +1 -1
  85. package/src/lib/editor/Editor.ts +83 -23
  86. package/src/lib/editor/derivations/bindingsIndex.ts +1 -1
  87. package/src/lib/editor/derivations/parentsToChildren.ts +1 -1
  88. package/src/lib/editor/derivations/shapeIdsInCurrentPage.ts +1 -1
  89. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +54 -74
  90. package/src/lib/editor/managers/ClickManager/ClickManager.ts +15 -65
  91. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts +14 -0
  92. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +6 -3
  93. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +4 -4
  94. package/src/lib/editor/managers/FocusManager/FocusManager.ts +1 -2
  95. package/src/lib/editor/managers/FontManager/FontManager.test.ts +13 -9
  96. package/src/lib/editor/managers/TextManager/TextManager.test.ts +16 -14
  97. package/src/lib/editor/overlays/strokeShapeIndicators.ts +86 -0
  98. package/src/lib/editor/tools/StateNode.ts +0 -2
  99. package/src/lib/editor/types/event-types.ts +2 -6
  100. package/src/lib/license/LicenseProvider.tsx +3 -1
  101. package/src/lib/primitives/utils.ts +1 -1
  102. package/src/lib/utils/dom.ts +5 -3
  103. package/src/version.ts +3 -3
  104. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +0 -161
  105. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +0 -7
  106. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +0 -141
  107. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +0 -7
  108. package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +0 -216
@@ -43,7 +43,7 @@ function fromScratch(bindingsQuery) {
43
43
  }
44
44
  return shapesToBindings;
45
45
  }
46
- const bindingsIndex = (editor) => {
46
+ function bindingsIndex(editor) {
47
47
  const { store } = editor;
48
48
  const bindingsHistory = store.query.filterHistory("binding");
49
49
  const bindingsQuery = store.query.records("binding");
@@ -104,5 +104,5 @@ const bindingsIndex = (editor) => {
104
104
  }
105
105
  return nextValue ?? lastValue;
106
106
  });
107
- };
107
+ }
108
108
  //# sourceMappingURL=bindingsIndex.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/derivations/bindingsIndex.ts"],
4
- "sourcesContent": ["import { Computed, RESET_VALUE, computed, isUninitialized } from '@tldraw/state'\nimport { TLBinding, TLShapeId } from '@tldraw/tlschema'\nimport { objectMapValues } from '@tldraw/utils'\nimport type { Editor } from '../Editor'\n\ntype TLBindingsIndex = Map<TLShapeId, TLBinding[]>\n\nfunction fromScratch(bindingsQuery: Computed<TLBinding[], unknown>) {\n\tconst allBindings = bindingsQuery.get() as TLBinding[]\n\n\tconst shapesToBindings: TLBindingsIndex = new Map()\n\n\tfor (const binding of allBindings) {\n\t\tconst { fromId, toId } = binding\n\t\tconst bindingsForFromShape = shapesToBindings.get(fromId)\n\t\tif (!bindingsForFromShape) {\n\t\t\tshapesToBindings.set(fromId, [binding])\n\t\t} else {\n\t\t\tbindingsForFromShape.push(binding)\n\t\t}\n\t\tconst bindingsForToShape = shapesToBindings.get(toId)\n\t\tif (!bindingsForToShape) {\n\t\t\tshapesToBindings.set(toId, [binding])\n\t\t} else {\n\t\t\tbindingsForToShape.push(binding)\n\t\t}\n\t}\n\n\treturn shapesToBindings\n}\n\nexport const bindingsIndex = (editor: Editor): Computed<TLBindingsIndex> => {\n\tconst { store } = editor\n\tconst bindingsHistory = store.query.filterHistory('binding')\n\tconst bindingsQuery = store.query.records('binding')\n\n\treturn computed<TLBindingsIndex>('arrowBindingsIndex', (_lastValue, lastComputedEpoch) => {\n\t\tif (isUninitialized(_lastValue)) {\n\t\t\treturn fromScratch(bindingsQuery)\n\t\t}\n\n\t\tconst lastValue = _lastValue\n\n\t\tconst diff = bindingsHistory.getDiffSince(lastComputedEpoch)\n\n\t\tif (diff === RESET_VALUE) {\n\t\t\treturn fromScratch(bindingsQuery)\n\t\t}\n\n\t\tlet nextValue: TLBindingsIndex | undefined = undefined\n\n\t\tfunction removingBinding(binding: TLBinding) {\n\t\t\tnextValue ??= new Map(lastValue)\n\t\t\tconst prevFrom = nextValue.get(binding.fromId)\n\t\t\tconst nextFrom = prevFrom?.filter((b) => b.id !== binding.id)\n\t\t\tif (!nextFrom?.length) {\n\t\t\t\tnextValue.delete(binding.fromId)\n\t\t\t} else {\n\t\t\t\tnextValue.set(binding.fromId, nextFrom)\n\t\t\t}\n\t\t\tconst prevTo = nextValue.get(binding.toId)\n\t\t\tconst nextTo = prevTo?.filter((b) => b.id !== binding.id)\n\t\t\tif (!nextTo?.length) {\n\t\t\t\tnextValue.delete(binding.toId)\n\t\t\t} else {\n\t\t\t\tnextValue.set(binding.toId, nextTo)\n\t\t\t}\n\t\t}\n\n\t\tfunction ensureNewArray(shapeId: TLShapeId) {\n\t\t\tnextValue ??= new Map(lastValue)\n\n\t\t\tlet result = nextValue.get(shapeId)\n\t\t\tif (!result) {\n\t\t\t\tresult = []\n\t\t\t\tnextValue.set(shapeId, result)\n\t\t\t} else if (result === lastValue.get(shapeId)) {\n\t\t\t\tresult = result.slice(0)\n\t\t\t\tnextValue.set(shapeId, result)\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\n\t\tfunction addBinding(binding: TLBinding) {\n\t\t\tensureNewArray(binding.fromId).push(binding)\n\t\t\tensureNewArray(binding.toId).push(binding)\n\t\t}\n\n\t\tfor (const changes of diff) {\n\t\t\tfor (const newBinding of objectMapValues(changes.added)) {\n\t\t\t\taddBinding(newBinding)\n\t\t\t}\n\n\t\t\tfor (const [prev, next] of objectMapValues(changes.updated)) {\n\t\t\t\tremovingBinding(prev)\n\t\t\t\taddBinding(next)\n\t\t\t}\n\n\t\t\tfor (const prev of objectMapValues(changes.removed)) {\n\t\t\t\tremovingBinding(prev)\n\t\t\t}\n\t\t}\n\n\t\t// TODO: add diff entries if we need them\n\t\treturn nextValue ?? lastValue\n\t})\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Computed, RESET_VALUE, computed, isUninitialized } from '@tldraw/state'\nimport { TLBinding, TLShapeId } from '@tldraw/tlschema'\nimport { objectMapValues } from '@tldraw/utils'\nimport type { Editor } from '../Editor'\n\ntype TLBindingsIndex = Map<TLShapeId, TLBinding[]>\n\nfunction fromScratch(bindingsQuery: Computed<TLBinding[], unknown>) {\n\tconst allBindings = bindingsQuery.get() as TLBinding[]\n\n\tconst shapesToBindings: TLBindingsIndex = new Map()\n\n\tfor (const binding of allBindings) {\n\t\tconst { fromId, toId } = binding\n\t\tconst bindingsForFromShape = shapesToBindings.get(fromId)\n\t\tif (!bindingsForFromShape) {\n\t\t\tshapesToBindings.set(fromId, [binding])\n\t\t} else {\n\t\t\tbindingsForFromShape.push(binding)\n\t\t}\n\t\tconst bindingsForToShape = shapesToBindings.get(toId)\n\t\tif (!bindingsForToShape) {\n\t\t\tshapesToBindings.set(toId, [binding])\n\t\t} else {\n\t\t\tbindingsForToShape.push(binding)\n\t\t}\n\t}\n\n\treturn shapesToBindings\n}\n\nexport function bindingsIndex(editor: Editor): Computed<TLBindingsIndex> {\n\tconst { store } = editor\n\tconst bindingsHistory = store.query.filterHistory('binding')\n\tconst bindingsQuery = store.query.records('binding')\n\n\treturn computed<TLBindingsIndex>('arrowBindingsIndex', (_lastValue, lastComputedEpoch) => {\n\t\tif (isUninitialized(_lastValue)) {\n\t\t\treturn fromScratch(bindingsQuery)\n\t\t}\n\n\t\tconst lastValue = _lastValue\n\n\t\tconst diff = bindingsHistory.getDiffSince(lastComputedEpoch)\n\n\t\tif (diff === RESET_VALUE) {\n\t\t\treturn fromScratch(bindingsQuery)\n\t\t}\n\n\t\tlet nextValue: TLBindingsIndex | undefined = undefined\n\n\t\tfunction removingBinding(binding: TLBinding) {\n\t\t\tnextValue ??= new Map(lastValue)\n\t\t\tconst prevFrom = nextValue.get(binding.fromId)\n\t\t\tconst nextFrom = prevFrom?.filter((b) => b.id !== binding.id)\n\t\t\tif (!nextFrom?.length) {\n\t\t\t\tnextValue.delete(binding.fromId)\n\t\t\t} else {\n\t\t\t\tnextValue.set(binding.fromId, nextFrom)\n\t\t\t}\n\t\t\tconst prevTo = nextValue.get(binding.toId)\n\t\t\tconst nextTo = prevTo?.filter((b) => b.id !== binding.id)\n\t\t\tif (!nextTo?.length) {\n\t\t\t\tnextValue.delete(binding.toId)\n\t\t\t} else {\n\t\t\t\tnextValue.set(binding.toId, nextTo)\n\t\t\t}\n\t\t}\n\n\t\tfunction ensureNewArray(shapeId: TLShapeId) {\n\t\t\tnextValue ??= new Map(lastValue)\n\n\t\t\tlet result = nextValue.get(shapeId)\n\t\t\tif (!result) {\n\t\t\t\tresult = []\n\t\t\t\tnextValue.set(shapeId, result)\n\t\t\t} else if (result === lastValue.get(shapeId)) {\n\t\t\t\tresult = result.slice(0)\n\t\t\t\tnextValue.set(shapeId, result)\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\n\t\tfunction addBinding(binding: TLBinding) {\n\t\t\tensureNewArray(binding.fromId).push(binding)\n\t\t\tensureNewArray(binding.toId).push(binding)\n\t\t}\n\n\t\tfor (const changes of diff) {\n\t\t\tfor (const newBinding of objectMapValues(changes.added)) {\n\t\t\t\taddBinding(newBinding)\n\t\t\t}\n\n\t\t\tfor (const [prev, next] of objectMapValues(changes.updated)) {\n\t\t\t\tremovingBinding(prev)\n\t\t\t\taddBinding(next)\n\t\t\t}\n\n\t\t\tfor (const prev of objectMapValues(changes.removed)) {\n\t\t\t\tremovingBinding(prev)\n\t\t\t}\n\t\t}\n\n\t\t// TODO: add diff entries if we need them\n\t\treturn nextValue ?? lastValue\n\t})\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiE;AAEjE,mBAAgC;AAKhC,SAAS,YAAY,eAA+C;AACnE,QAAM,cAAc,cAAc,IAAI;AAEtC,QAAM,mBAAoC,oBAAI,IAAI;AAElD,aAAW,WAAW,aAAa;AAClC,UAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,UAAM,uBAAuB,iBAAiB,IAAI,MAAM;AACxD,QAAI,CAAC,sBAAsB;AAC1B,uBAAiB,IAAI,QAAQ,CAAC,OAAO,CAAC;AAAA,IACvC,OAAO;AACN,2BAAqB,KAAK,OAAO;AAAA,IAClC;AACA,UAAM,qBAAqB,iBAAiB,IAAI,IAAI;AACpD,QAAI,CAAC,oBAAoB;AACxB,uBAAiB,IAAI,MAAM,CAAC,OAAO,CAAC;AAAA,IACrC,OAAO;AACN,yBAAmB,KAAK,OAAO;AAAA,IAChC;AAAA,EACD;AAEA,SAAO;AACR;AAEO,SAAS,cAAc,QAA2C;AACxE,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,kBAAkB,MAAM,MAAM,cAAc,SAAS;AAC3D,QAAM,gBAAgB,MAAM,MAAM,QAAQ,SAAS;AAEnD,aAAO,uBAA0B,sBAAsB,CAAC,YAAY,sBAAsB;AACzF,YAAI,8BAAgB,UAAU,GAAG;AAChC,aAAO,YAAY,aAAa;AAAA,IACjC;AAEA,UAAM,YAAY;AAElB,UAAM,OAAO,gBAAgB,aAAa,iBAAiB;AAE3D,QAAI,SAAS,0BAAa;AACzB,aAAO,YAAY,aAAa;AAAA,IACjC;AAEA,QAAI,YAAyC;AAE7C,aAAS,gBAAgB,SAAoB;AAC5C,oBAAc,IAAI,IAAI,SAAS;AAC/B,YAAM,WAAW,UAAU,IAAI,QAAQ,MAAM;AAC7C,YAAM,WAAW,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE;AAC5D,UAAI,CAAC,UAAU,QAAQ;AACtB,kBAAU,OAAO,QAAQ,MAAM;AAAA,MAChC,OAAO;AACN,kBAAU,IAAI,QAAQ,QAAQ,QAAQ;AAAA,MACvC;AACA,YAAM,SAAS,UAAU,IAAI,QAAQ,IAAI;AACzC,YAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE;AACxD,UAAI,CAAC,QAAQ,QAAQ;AACpB,kBAAU,OAAO,QAAQ,IAAI;AAAA,MAC9B,OAAO;AACN,kBAAU,IAAI,QAAQ,MAAM,MAAM;AAAA,MACnC;AAAA,IACD;AAEA,aAAS,eAAe,SAAoB;AAC3C,oBAAc,IAAI,IAAI,SAAS;AAE/B,UAAI,SAAS,UAAU,IAAI,OAAO;AAClC,UAAI,CAAC,QAAQ;AACZ,iBAAS,CAAC;AACV,kBAAU,IAAI,SAAS,MAAM;AAAA,MAC9B,WAAW,WAAW,UAAU,IAAI,OAAO,GAAG;AAC7C,iBAAS,OAAO,MAAM,CAAC;AACvB,kBAAU,IAAI,SAAS,MAAM;AAAA,MAC9B;AACA,aAAO;AAAA,IACR;AAEA,aAAS,WAAW,SAAoB;AACvC,qBAAe,QAAQ,MAAM,EAAE,KAAK,OAAO;AAC3C,qBAAe,QAAQ,IAAI,EAAE,KAAK,OAAO;AAAA,IAC1C;AAEA,eAAW,WAAW,MAAM;AAC3B,iBAAW,kBAAc,8BAAgB,QAAQ,KAAK,GAAG;AACxD,mBAAW,UAAU;AAAA,MACtB;AAEA,iBAAW,CAAC,MAAM,IAAI,SAAK,8BAAgB,QAAQ,OAAO,GAAG;AAC5D,wBAAgB,IAAI;AACpB,mBAAW,IAAI;AAAA,MAChB;AAEA,iBAAW,YAAQ,8BAAgB,QAAQ,OAAO,GAAG;AACpD,wBAAgB,IAAI;AAAA,MACrB;AAAA,IACD;AAGA,WAAO,aAAa;AAAA,EACrB,CAAC;AACF;",
6
6
  "names": []
7
7
  }
@@ -34,7 +34,7 @@ function fromScratch(shapeIdsQuery, store) {
34
34
  });
35
35
  return result;
36
36
  }
37
- const parentsToChildren = (store) => {
37
+ function parentsToChildren(store) {
38
38
  const shapeIdsQuery = store.query.ids("shape");
39
39
  const shapeHistory = store.query.filterHistory("shape");
40
40
  return (0, import_state.computed)(
@@ -108,5 +108,5 @@ const parentsToChildren = (store) => {
108
108
  return newValue ?? lastValue;
109
109
  }
110
110
  );
111
- };
111
+ }
112
112
  //# sourceMappingURL=parentsToChildren.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/derivations/parentsToChildren.ts"],
4
- "sourcesContent": ["import { Computed, computed, isUninitialized, RESET_VALUE } from '@tldraw/state'\nimport { CollectionDiff, RecordsDiff } from '@tldraw/store'\nimport { isShape, TLParentId, TLRecord, TLShape, TLShapeId, TLStore } from '@tldraw/tlschema'\nimport { sortByIndex } from '@tldraw/utils'\n\ntype ParentShapeIdsToChildShapeIds = Record<TLParentId, TLShapeId[]>\n\nfunction fromScratch(\n\tshapeIdsQuery: Computed<Set<TLShapeId>, CollectionDiff<TLShapeId>>,\n\tstore: TLStore\n) {\n\tconst result: ParentShapeIdsToChildShapeIds = {}\n\tconst shapeIds = shapeIdsQuery.get()\n\tconst sortedShapes = Array.from(shapeIds, (id) => store.get(id)!).sort(sortByIndex)\n\n\t// Populate the result object with an array for each parent.\n\tsortedShapes.forEach((shape) => {\n\t\tresult[shape.parentId] ??= []\n\t\tresult[shape.parentId].push(shape.id)\n\t})\n\n\treturn result\n}\n\nexport const parentsToChildren = (store: TLStore) => {\n\tconst shapeIdsQuery = store.query.ids<'shape'>('shape')\n\tconst shapeHistory = store.query.filterHistory('shape')\n\n\treturn computed<ParentShapeIdsToChildShapeIds>(\n\t\t'parentsToChildrenWithIndexes',\n\t\t(lastValue, lastComputedEpoch) => {\n\t\t\tif (isUninitialized(lastValue)) {\n\t\t\t\treturn fromScratch(shapeIdsQuery, store)\n\t\t\t}\n\n\t\t\tconst diff = shapeHistory.getDiffSince(lastComputedEpoch)\n\n\t\t\tif (diff === RESET_VALUE) {\n\t\t\t\treturn fromScratch(shapeIdsQuery, store)\n\t\t\t}\n\n\t\t\tif (diff.length === 0) return lastValue\n\n\t\t\tlet newValue: Record<TLParentId, TLShapeId[]> | null = null\n\n\t\t\tconst ensureNewArray = (parentId: TLParentId) => {\n\t\t\t\tif (!newValue) {\n\t\t\t\t\tnewValue = { ...lastValue }\n\t\t\t\t}\n\t\t\t\tif (!newValue[parentId]) {\n\t\t\t\t\tnewValue[parentId] = []\n\t\t\t\t} else if (newValue[parentId] === lastValue[parentId]) {\n\t\t\t\t\tnewValue[parentId] = [...newValue[parentId]!]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst toSort = new Set<TLShapeId[]>()\n\n\t\t\tlet changes: RecordsDiff<TLRecord>\n\n\t\t\tfor (let i = 0, n = diff.length; i < n; i++) {\n\t\t\t\tchanges = diff[i]\n\n\t\t\t\t// Iterate through the added shapes, add them to the new value and mark them for sorting\n\t\t\t\tfor (const record of Object.values(changes.added)) {\n\t\t\t\t\tif (!isShape(record)) continue\n\t\t\t\t\tensureNewArray(record.parentId)\n\t\t\t\t\tnewValue![record.parentId].push(record.id)\n\t\t\t\t\ttoSort.add(newValue![record.parentId])\n\t\t\t\t}\n\n\t\t\t\t// Iterate through the updated shapes, add them to their parents in the new value and mark them for sorting\n\t\t\t\tfor (const [from, to] of Object.values(changes.updated)) {\n\t\t\t\t\tif (!isShape(to)) continue\n\t\t\t\t\tif (!isShape(from)) continue\n\n\t\t\t\t\tif (from.parentId !== to.parentId) {\n\t\t\t\t\t\t// If the parents have changed, remove the new value from the old parent and add it to the new parent\n\t\t\t\t\t\tensureNewArray(from.parentId)\n\t\t\t\t\t\tensureNewArray(to.parentId)\n\t\t\t\t\t\tnewValue![from.parentId].splice(newValue![from.parentId].indexOf(to.id), 1)\n\t\t\t\t\t\tnewValue![to.parentId].push(to.id)\n\t\t\t\t\t\ttoSort.add(newValue![to.parentId])\n\t\t\t\t\t} else if (from.index !== to.index) {\n\t\t\t\t\t\t// If the parent is the same but the index has changed (e.g. if they've been reordered), update the parent's array at the new index\n\t\t\t\t\t\tensureNewArray(to.parentId)\n\t\t\t\t\t\tconst idx = newValue![to.parentId].indexOf(to.id)\n\t\t\t\t\t\tnewValue![to.parentId][idx] = to.id\n\t\t\t\t\t\ttoSort.add(newValue![to.parentId])\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Iterate through the removed shapes, remove them from their parents in new value\n\t\t\t\tfor (const record of Object.values(changes.removed)) {\n\t\t\t\t\tif (!isShape(record)) continue\n\t\t\t\t\tensureNewArray(record.parentId)\n\t\t\t\t\tnewValue![record.parentId].splice(newValue![record.parentId].indexOf(record.id), 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Sort the arrays that have been marked for sorting (in-place to avoid intermediate arrays)\n\t\t\tfor (const arr of toSort) {\n\t\t\t\t// Filter out any deleted shapes in-place\n\t\t\t\tlet writeIdx = 0\n\t\t\t\tfor (let readIdx = 0; readIdx < arr.length; readIdx++) {\n\t\t\t\t\tif (store.get(arr[readIdx])) {\n\t\t\t\t\t\tarr[writeIdx++] = arr[readIdx]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tarr.length = writeIdx\n\n\t\t\t\t// Sort in-place by index\n\t\t\t\tarr.sort((a, b) => {\n\t\t\t\t\tconst shapeA = store.get(a) as TLShape\n\t\t\t\t\tconst shapeB = store.get(b) as TLShape\n\t\t\t\t\treturn sortByIndex(shapeA, shapeB)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn newValue ?? lastValue\n\t\t}\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Computed, computed, isUninitialized, RESET_VALUE } from '@tldraw/state'\nimport { CollectionDiff, RecordsDiff } from '@tldraw/store'\nimport { isShape, TLParentId, TLRecord, TLShape, TLShapeId, TLStore } from '@tldraw/tlschema'\nimport { sortByIndex } from '@tldraw/utils'\n\ntype ParentShapeIdsToChildShapeIds = Record<TLParentId, TLShapeId[]>\n\nfunction fromScratch(\n\tshapeIdsQuery: Computed<Set<TLShapeId>, CollectionDiff<TLShapeId>>,\n\tstore: TLStore\n) {\n\tconst result: ParentShapeIdsToChildShapeIds = {}\n\tconst shapeIds = shapeIdsQuery.get()\n\tconst sortedShapes = Array.from(shapeIds, (id) => store.get(id)!).sort(sortByIndex)\n\n\t// Populate the result object with an array for each parent.\n\tsortedShapes.forEach((shape) => {\n\t\tresult[shape.parentId] ??= []\n\t\tresult[shape.parentId].push(shape.id)\n\t})\n\n\treturn result\n}\n\nexport function parentsToChildren(store: TLStore) {\n\tconst shapeIdsQuery = store.query.ids<'shape'>('shape')\n\tconst shapeHistory = store.query.filterHistory('shape')\n\n\treturn computed<ParentShapeIdsToChildShapeIds>(\n\t\t'parentsToChildrenWithIndexes',\n\t\t(lastValue, lastComputedEpoch) => {\n\t\t\tif (isUninitialized(lastValue)) {\n\t\t\t\treturn fromScratch(shapeIdsQuery, store)\n\t\t\t}\n\n\t\t\tconst diff = shapeHistory.getDiffSince(lastComputedEpoch)\n\n\t\t\tif (diff === RESET_VALUE) {\n\t\t\t\treturn fromScratch(shapeIdsQuery, store)\n\t\t\t}\n\n\t\t\tif (diff.length === 0) return lastValue\n\n\t\t\tlet newValue: Record<TLParentId, TLShapeId[]> | null = null\n\n\t\t\tconst ensureNewArray = (parentId: TLParentId) => {\n\t\t\t\tif (!newValue) {\n\t\t\t\t\tnewValue = { ...lastValue }\n\t\t\t\t}\n\t\t\t\tif (!newValue[parentId]) {\n\t\t\t\t\tnewValue[parentId] = []\n\t\t\t\t} else if (newValue[parentId] === lastValue[parentId]) {\n\t\t\t\t\tnewValue[parentId] = [...newValue[parentId]!]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst toSort = new Set<TLShapeId[]>()\n\n\t\t\tlet changes: RecordsDiff<TLRecord>\n\n\t\t\tfor (let i = 0, n = diff.length; i < n; i++) {\n\t\t\t\tchanges = diff[i]\n\n\t\t\t\t// Iterate through the added shapes, add them to the new value and mark them for sorting\n\t\t\t\tfor (const record of Object.values(changes.added)) {\n\t\t\t\t\tif (!isShape(record)) continue\n\t\t\t\t\tensureNewArray(record.parentId)\n\t\t\t\t\tnewValue![record.parentId].push(record.id)\n\t\t\t\t\ttoSort.add(newValue![record.parentId])\n\t\t\t\t}\n\n\t\t\t\t// Iterate through the updated shapes, add them to their parents in the new value and mark them for sorting\n\t\t\t\tfor (const [from, to] of Object.values(changes.updated)) {\n\t\t\t\t\tif (!isShape(to)) continue\n\t\t\t\t\tif (!isShape(from)) continue\n\n\t\t\t\t\tif (from.parentId !== to.parentId) {\n\t\t\t\t\t\t// If the parents have changed, remove the new value from the old parent and add it to the new parent\n\t\t\t\t\t\tensureNewArray(from.parentId)\n\t\t\t\t\t\tensureNewArray(to.parentId)\n\t\t\t\t\t\tnewValue![from.parentId].splice(newValue![from.parentId].indexOf(to.id), 1)\n\t\t\t\t\t\tnewValue![to.parentId].push(to.id)\n\t\t\t\t\t\ttoSort.add(newValue![to.parentId])\n\t\t\t\t\t} else if (from.index !== to.index) {\n\t\t\t\t\t\t// If the parent is the same but the index has changed (e.g. if they've been reordered), update the parent's array at the new index\n\t\t\t\t\t\tensureNewArray(to.parentId)\n\t\t\t\t\t\tconst idx = newValue![to.parentId].indexOf(to.id)\n\t\t\t\t\t\tnewValue![to.parentId][idx] = to.id\n\t\t\t\t\t\ttoSort.add(newValue![to.parentId])\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Iterate through the removed shapes, remove them from their parents in new value\n\t\t\t\tfor (const record of Object.values(changes.removed)) {\n\t\t\t\t\tif (!isShape(record)) continue\n\t\t\t\t\tensureNewArray(record.parentId)\n\t\t\t\t\tnewValue![record.parentId].splice(newValue![record.parentId].indexOf(record.id), 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Sort the arrays that have been marked for sorting (in-place to avoid intermediate arrays)\n\t\t\tfor (const arr of toSort) {\n\t\t\t\t// Filter out any deleted shapes in-place\n\t\t\t\tlet writeIdx = 0\n\t\t\t\tfor (let readIdx = 0; readIdx < arr.length; readIdx++) {\n\t\t\t\t\tif (store.get(arr[readIdx])) {\n\t\t\t\t\t\tarr[writeIdx++] = arr[readIdx]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tarr.length = writeIdx\n\n\t\t\t\t// Sort in-place by index\n\t\t\t\tarr.sort((a, b) => {\n\t\t\t\t\tconst shapeA = store.get(a) as TLShape\n\t\t\t\t\tconst shapeB = store.get(b) as TLShape\n\t\t\t\t\treturn sortByIndex(shapeA, shapeB)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn newValue ?? lastValue\n\t\t}\n\t)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiE;AAEjE,sBAA2E;AAC3E,mBAA4B;AAI5B,SAAS,YACR,eACA,OACC;AACD,QAAM,SAAwC,CAAC;AAC/C,QAAM,WAAW,cAAc,IAAI;AACnC,QAAM,eAAe,MAAM,KAAK,UAAU,CAAC,OAAO,MAAM,IAAI,EAAE,CAAE,EAAE,KAAK,wBAAW;AAGlF,eAAa,QAAQ,CAAC,UAAU;AAC/B,WAAO,MAAM,QAAQ,MAAM,CAAC;AAC5B,WAAO,MAAM,QAAQ,EAAE,KAAK,MAAM,EAAE;AAAA,EACrC,CAAC;AAED,SAAO;AACR;AAEO,SAAS,kBAAkB,OAAgB;AACjD,QAAM,gBAAgB,MAAM,MAAM,IAAa,OAAO;AACtD,QAAM,eAAe,MAAM,MAAM,cAAc,OAAO;AAEtD,aAAO;AAAA,IACN;AAAA,IACA,CAAC,WAAW,sBAAsB;AACjC,cAAI,8BAAgB,SAAS,GAAG;AAC/B,eAAO,YAAY,eAAe,KAAK;AAAA,MACxC;AAEA,YAAM,OAAO,aAAa,aAAa,iBAAiB;AAExD,UAAI,SAAS,0BAAa;AACzB,eAAO,YAAY,eAAe,KAAK;AAAA,MACxC;AAEA,UAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,UAAI,WAAmD;AAEvD,YAAM,iBAAiB,CAAC,aAAyB;AAChD,YAAI,CAAC,UAAU;AACd,qBAAW,EAAE,GAAG,UAAU;AAAA,QAC3B;AACA,YAAI,CAAC,SAAS,QAAQ,GAAG;AACxB,mBAAS,QAAQ,IAAI,CAAC;AAAA,QACvB,WAAW,SAAS,QAAQ,MAAM,UAAU,QAAQ,GAAG;AACtD,mBAAS,QAAQ,IAAI,CAAC,GAAG,SAAS,QAAQ,CAAE;AAAA,QAC7C;AAAA,MACD;AAEA,YAAM,SAAS,oBAAI,IAAiB;AAEpC,UAAI;AAEJ,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK;AAC5C,kBAAU,KAAK,CAAC;AAGhB,mBAAW,UAAU,OAAO,OAAO,QAAQ,KAAK,GAAG;AAClD,cAAI,KAAC,yBAAQ,MAAM,EAAG;AACtB,yBAAe,OAAO,QAAQ;AAC9B,mBAAU,OAAO,QAAQ,EAAE,KAAK,OAAO,EAAE;AACzC,iBAAO,IAAI,SAAU,OAAO,QAAQ,CAAC;AAAA,QACtC;AAGA,mBAAW,CAAC,MAAM,EAAE,KAAK,OAAO,OAAO,QAAQ,OAAO,GAAG;AACxD,cAAI,KAAC,yBAAQ,EAAE,EAAG;AAClB,cAAI,KAAC,yBAAQ,IAAI,EAAG;AAEpB,cAAI,KAAK,aAAa,GAAG,UAAU;AAElC,2BAAe,KAAK,QAAQ;AAC5B,2BAAe,GAAG,QAAQ;AAC1B,qBAAU,KAAK,QAAQ,EAAE,OAAO,SAAU,KAAK,QAAQ,EAAE,QAAQ,GAAG,EAAE,GAAG,CAAC;AAC1E,qBAAU,GAAG,QAAQ,EAAE,KAAK,GAAG,EAAE;AACjC,mBAAO,IAAI,SAAU,GAAG,QAAQ,CAAC;AAAA,UAClC,WAAW,KAAK,UAAU,GAAG,OAAO;AAEnC,2BAAe,GAAG,QAAQ;AAC1B,kBAAM,MAAM,SAAU,GAAG,QAAQ,EAAE,QAAQ,GAAG,EAAE;AAChD,qBAAU,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG;AACjC,mBAAO,IAAI,SAAU,GAAG,QAAQ,CAAC;AAAA,UAClC;AAAA,QACD;AAGA,mBAAW,UAAU,OAAO,OAAO,QAAQ,OAAO,GAAG;AACpD,cAAI,KAAC,yBAAQ,MAAM,EAAG;AACtB,yBAAe,OAAO,QAAQ;AAC9B,mBAAU,OAAO,QAAQ,EAAE,OAAO,SAAU,OAAO,QAAQ,EAAE,QAAQ,OAAO,EAAE,GAAG,CAAC;AAAA,QACnF;AAAA,MACD;AAGA,iBAAW,OAAO,QAAQ;AAEzB,YAAI,WAAW;AACf,iBAAS,UAAU,GAAG,UAAU,IAAI,QAAQ,WAAW;AACtD,cAAI,MAAM,IAAI,IAAI,OAAO,CAAC,GAAG;AAC5B,gBAAI,UAAU,IAAI,IAAI,OAAO;AAAA,UAC9B;AAAA,QACD;AACA,YAAI,SAAS;AAGb,YAAI,KAAK,CAAC,GAAG,MAAM;AAClB,gBAAM,SAAS,MAAM,IAAI,CAAC;AAC1B,gBAAM,SAAS,MAAM,IAAI,CAAC;AAC1B,qBAAO,0BAAY,QAAQ,MAAM;AAAA,QAClC,CAAC;AAAA,MACF;AAEA,aAAO,YAAY;AAAA,IACpB;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }
@@ -32,7 +32,7 @@ const isShapeInPage = (store, pageId, shape) => {
32
32
  }
33
33
  return shape.parentId === pageId;
34
34
  };
35
- const deriveShapeIdsInCurrentPage = (store, getCurrentPageId) => {
35
+ function deriveShapeIdsInCurrentPage(store, getCurrentPageId) {
36
36
  const shapesIndex = store.query.ids("shape");
37
37
  let lastPageId = null;
38
38
  function fromScratch() {
@@ -84,5 +84,5 @@ const deriveShapeIdsInCurrentPage = (store, getCurrentPageId) => {
84
84
  }
85
85
  return (0, import_state.withDiff)(result.value, result.diff);
86
86
  });
87
- };
87
+ }
88
88
  //# sourceMappingURL=shapeIdsInCurrentPage.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/derivations/shapeIdsInCurrentPage.ts"],
4
- "sourcesContent": ["import { computed, isUninitialized, RESET_VALUE, withDiff } from '@tldraw/state'\nimport { IncrementalSetConstructor } from '@tldraw/store'\nimport {\n\tisPageId,\n\tisShape,\n\tisShapeId,\n\tTLPageId,\n\tTLShape,\n\tTLShapeId,\n\tTLStore,\n} from '@tldraw/tlschema'\n\n/**\n * Get whether a shape is in the current page.\n *\n * @param store - The tldraw store.\n * @param pageId - The id of the page to check.\n * @param shape - The the shape to check.\n */\nconst isShapeInPage = (store: TLStore, pageId: TLPageId, shape: TLShape): boolean => {\n\twhile (!isPageId(shape.parentId)) {\n\t\tconst parent = store.get(shape.parentId)\n\t\tif (!parent) return false\n\t\tshape = parent\n\t}\n\n\treturn shape.parentId === pageId\n}\n\n/**\n * A derivation that returns a list of shape ids in the current page.\n *\n * @param store - The tldraw store.\n * @param getCurrentPageId - A function that returns the current page id.\n */\nexport const deriveShapeIdsInCurrentPage = (store: TLStore, getCurrentPageId: () => TLPageId) => {\n\tconst shapesIndex = store.query.ids('shape')\n\tlet lastPageId: null | TLPageId = null\n\tfunction fromScratch() {\n\t\tconst currentPageId = getCurrentPageId()\n\t\tlastPageId = currentPageId\n\t\treturn new Set(\n\t\t\t[...shapesIndex.get()].filter((id) => isShapeInPage(store, currentPageId, store.get(id)!))\n\t\t)\n\t}\n\treturn computed<Set<TLShapeId>>('_shapeIdsInCurrentPage', (prevValue, lastComputedEpoch) => {\n\t\tif (isUninitialized(prevValue)) {\n\t\t\treturn fromScratch()\n\t\t}\n\n\t\tconst currentPageId = getCurrentPageId()\n\n\t\tif (currentPageId !== lastPageId) {\n\t\t\treturn fromScratch()\n\t\t}\n\n\t\tconst diff = store.history.getDiffSince(lastComputedEpoch)\n\n\t\tif (diff === RESET_VALUE) {\n\t\t\treturn fromScratch()\n\t\t}\n\n\t\tconst builder = new IncrementalSetConstructor<TLShapeId>(\n\t\t\tprevValue\n\t\t) as IncrementalSetConstructor<TLShapeId>\n\n\t\tfor (const changes of diff) {\n\t\t\tfor (const record of Object.values(changes.added)) {\n\t\t\t\tif (isShape(record) && isShapeInPage(store, currentPageId, record)) {\n\t\t\t\t\tbuilder.add(record.id)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const [_from, to] of Object.values(changes.updated)) {\n\t\t\t\tif (isShape(to)) {\n\t\t\t\t\tif (isShapeInPage(store, currentPageId, to)) {\n\t\t\t\t\t\tbuilder.add(to.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuilder.remove(to.id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of Object.keys(changes.removed)) {\n\t\t\t\tif (isShapeId(id)) {\n\t\t\t\t\tbuilder.remove(id)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst result = builder.get()\n\t\tif (!result) {\n\t\t\treturn prevValue\n\t\t}\n\n\t\treturn withDiff(result.value, result.diff)\n\t})\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiE;AACjE,mBAA0C;AAC1C,sBAQO;AASP,MAAM,gBAAgB,CAAC,OAAgB,QAAkB,UAA4B;AACpF,SAAO,KAAC,0BAAS,MAAM,QAAQ,GAAG;AACjC,UAAM,SAAS,MAAM,IAAI,MAAM,QAAQ;AACvC,QAAI,CAAC,OAAQ,QAAO;AACpB,YAAQ;AAAA,EACT;AAEA,SAAO,MAAM,aAAa;AAC3B;AAQO,MAAM,8BAA8B,CAAC,OAAgB,qBAAqC;AAChG,QAAM,cAAc,MAAM,MAAM,IAAI,OAAO;AAC3C,MAAI,aAA8B;AAClC,WAAS,cAAc;AACtB,UAAM,gBAAgB,iBAAiB;AACvC,iBAAa;AACb,WAAO,IAAI;AAAA,MACV,CAAC,GAAG,YAAY,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,cAAc,OAAO,eAAe,MAAM,IAAI,EAAE,CAAE,CAAC;AAAA,IAC1F;AAAA,EACD;AACA,aAAO,uBAAyB,0BAA0B,CAAC,WAAW,sBAAsB;AAC3F,YAAI,8BAAgB,SAAS,GAAG;AAC/B,aAAO,YAAY;AAAA,IACpB;AAEA,UAAM,gBAAgB,iBAAiB;AAEvC,QAAI,kBAAkB,YAAY;AACjC,aAAO,YAAY;AAAA,IACpB;AAEA,UAAM,OAAO,MAAM,QAAQ,aAAa,iBAAiB;AAEzD,QAAI,SAAS,0BAAa;AACzB,aAAO,YAAY;AAAA,IACpB;AAEA,UAAM,UAAU,IAAI;AAAA,MACnB;AAAA,IACD;AAEA,eAAW,WAAW,MAAM;AAC3B,iBAAW,UAAU,OAAO,OAAO,QAAQ,KAAK,GAAG;AAClD,gBAAI,yBAAQ,MAAM,KAAK,cAAc,OAAO,eAAe,MAAM,GAAG;AACnE,kBAAQ,IAAI,OAAO,EAAE;AAAA,QACtB;AAAA,MACD;AAEA,iBAAW,CAAC,OAAO,EAAE,KAAK,OAAO,OAAO,QAAQ,OAAO,GAAG;AACzD,gBAAI,yBAAQ,EAAE,GAAG;AAChB,cAAI,cAAc,OAAO,eAAe,EAAE,GAAG;AAC5C,oBAAQ,IAAI,GAAG,EAAE;AAAA,UAClB,OAAO;AACN,oBAAQ,OAAO,GAAG,EAAE;AAAA,UACrB;AAAA,QACD;AAAA,MACD;AAEA,iBAAW,MAAM,OAAO,KAAK,QAAQ,OAAO,GAAG;AAC9C,gBAAI,2BAAU,EAAE,GAAG;AAClB,kBAAQ,OAAO,EAAE;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AAEA,UAAM,SAAS,QAAQ,IAAI;AAC3B,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AAEA,eAAO,uBAAS,OAAO,OAAO,OAAO,IAAI;AAAA,EAC1C,CAAC;AACF;",
4
+ "sourcesContent": ["import { computed, isUninitialized, RESET_VALUE, withDiff } from '@tldraw/state'\nimport { IncrementalSetConstructor } from '@tldraw/store'\nimport {\n\tisPageId,\n\tisShape,\n\tisShapeId,\n\tTLPageId,\n\tTLShape,\n\tTLShapeId,\n\tTLStore,\n} from '@tldraw/tlschema'\n\n/**\n * Get whether a shape is in the current page.\n *\n * @param store - The tldraw store.\n * @param pageId - The id of the page to check.\n * @param shape - The the shape to check.\n */\nconst isShapeInPage = (store: TLStore, pageId: TLPageId, shape: TLShape): boolean => {\n\twhile (!isPageId(shape.parentId)) {\n\t\tconst parent = store.get(shape.parentId)\n\t\tif (!parent) return false\n\t\tshape = parent\n\t}\n\n\treturn shape.parentId === pageId\n}\n\n/**\n * A derivation that returns a list of shape ids in the current page.\n *\n * @param store - The tldraw store.\n * @param getCurrentPageId - A function that returns the current page id.\n */\nexport function deriveShapeIdsInCurrentPage(store: TLStore, getCurrentPageId: () => TLPageId) {\n\tconst shapesIndex = store.query.ids('shape')\n\tlet lastPageId: null | TLPageId = null\n\tfunction fromScratch() {\n\t\tconst currentPageId = getCurrentPageId()\n\t\tlastPageId = currentPageId\n\t\treturn new Set(\n\t\t\t[...shapesIndex.get()].filter((id) => isShapeInPage(store, currentPageId, store.get(id)!))\n\t\t)\n\t}\n\treturn computed<Set<TLShapeId>>('_shapeIdsInCurrentPage', (prevValue, lastComputedEpoch) => {\n\t\tif (isUninitialized(prevValue)) {\n\t\t\treturn fromScratch()\n\t\t}\n\n\t\tconst currentPageId = getCurrentPageId()\n\n\t\tif (currentPageId !== lastPageId) {\n\t\t\treturn fromScratch()\n\t\t}\n\n\t\tconst diff = store.history.getDiffSince(lastComputedEpoch)\n\n\t\tif (diff === RESET_VALUE) {\n\t\t\treturn fromScratch()\n\t\t}\n\n\t\tconst builder = new IncrementalSetConstructor<TLShapeId>(\n\t\t\tprevValue\n\t\t) as IncrementalSetConstructor<TLShapeId>\n\n\t\tfor (const changes of diff) {\n\t\t\tfor (const record of Object.values(changes.added)) {\n\t\t\t\tif (isShape(record) && isShapeInPage(store, currentPageId, record)) {\n\t\t\t\t\tbuilder.add(record.id)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const [_from, to] of Object.values(changes.updated)) {\n\t\t\t\tif (isShape(to)) {\n\t\t\t\t\tif (isShapeInPage(store, currentPageId, to)) {\n\t\t\t\t\t\tbuilder.add(to.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuilder.remove(to.id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of Object.keys(changes.removed)) {\n\t\t\t\tif (isShapeId(id)) {\n\t\t\t\t\tbuilder.remove(id)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst result = builder.get()\n\t\tif (!result) {\n\t\t\treturn prevValue\n\t\t}\n\n\t\treturn withDiff(result.value, result.diff)\n\t})\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAiE;AACjE,mBAA0C;AAC1C,sBAQO;AASP,MAAM,gBAAgB,CAAC,OAAgB,QAAkB,UAA4B;AACpF,SAAO,KAAC,0BAAS,MAAM,QAAQ,GAAG;AACjC,UAAM,SAAS,MAAM,IAAI,MAAM,QAAQ;AACvC,QAAI,CAAC,OAAQ,QAAO;AACpB,YAAQ;AAAA,EACT;AAEA,SAAO,MAAM,aAAa;AAC3B;AAQO,SAAS,4BAA4B,OAAgB,kBAAkC;AAC7F,QAAM,cAAc,MAAM,MAAM,IAAI,OAAO;AAC3C,MAAI,aAA8B;AAClC,WAAS,cAAc;AACtB,UAAM,gBAAgB,iBAAiB;AACvC,iBAAa;AACb,WAAO,IAAI;AAAA,MACV,CAAC,GAAG,YAAY,IAAI,CAAC,EAAE,OAAO,CAAC,OAAO,cAAc,OAAO,eAAe,MAAM,IAAI,EAAE,CAAE,CAAC;AAAA,IAC1F;AAAA,EACD;AACA,aAAO,uBAAyB,0BAA0B,CAAC,WAAW,sBAAsB;AAC3F,YAAI,8BAAgB,SAAS,GAAG;AAC/B,aAAO,YAAY;AAAA,IACpB;AAEA,UAAM,gBAAgB,iBAAiB;AAEvC,QAAI,kBAAkB,YAAY;AACjC,aAAO,YAAY;AAAA,IACpB;AAEA,UAAM,OAAO,MAAM,QAAQ,aAAa,iBAAiB;AAEzD,QAAI,SAAS,0BAAa;AACzB,aAAO,YAAY;AAAA,IACpB;AAEA,UAAM,UAAU,IAAI;AAAA,MACnB;AAAA,IACD;AAEA,eAAW,WAAW,MAAM;AAC3B,iBAAW,UAAU,OAAO,OAAO,QAAQ,KAAK,GAAG;AAClD,gBAAI,yBAAQ,MAAM,KAAK,cAAc,OAAO,eAAe,MAAM,GAAG;AACnE,kBAAQ,IAAI,OAAO,EAAE;AAAA,QACtB;AAAA,MACD;AAEA,iBAAW,CAAC,OAAO,EAAE,KAAK,OAAO,OAAO,QAAQ,OAAO,GAAG;AACzD,gBAAI,yBAAQ,EAAE,GAAG;AAChB,cAAI,cAAc,OAAO,eAAe,EAAE,GAAG;AAC5C,oBAAQ,IAAI,GAAG,EAAE;AAAA,UAClB,OAAO;AACN,oBAAQ,OAAO,GAAG,EAAE;AAAA,UACrB;AAAA,QACD;AAAA,MACD;AAEA,iBAAW,MAAM,OAAO,KAAK,QAAQ,OAAO,GAAG;AAC9C,gBAAI,2BAAU,EAAE,GAAG;AAClB,kBAAQ,OAAO,EAAE;AAAA,QAClB;AAAA,MACD;AAAA,IACD;AAEA,UAAM,SAAS,QAAQ,IAAI;AAC3B,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AAEA,eAAO,uBAAS,OAAO,OAAO,OAAO,IAAI;AAAA,EAC1C,CAAC;AACF;",
6
6
  "names": []
7
7
  }
@@ -41,6 +41,7 @@ class ClickManager {
41
41
  _clickTimeout;
42
42
  _clickScreenPoint;
43
43
  _previousScreenPoint;
44
+ _isPressingWhilePending = false;
44
45
  _getClickTimeout(state, id = (0, import_utils.uniqueId)()) {
45
46
  this._clickId = id;
46
47
  clearTimeout(this._clickTimeout);
@@ -48,30 +49,12 @@ class ClickManager {
48
49
  () => {
49
50
  if (this._clickState === state && this._clickId === id) {
50
51
  switch (this._clickState) {
51
- case "pendingTriple": {
52
- this.editor.dispatch({
53
- ...this.lastPointerInfo,
54
- type: "click",
55
- name: "double_click",
56
- phase: "settle"
57
- });
58
- break;
59
- }
60
- case "pendingQuadruple": {
61
- this.editor.dispatch({
62
- ...this.lastPointerInfo,
63
- type: "click",
64
- name: "triple_click",
65
- phase: "settle"
66
- });
67
- break;
68
- }
69
52
  case "pendingOverflow": {
70
53
  this.editor.dispatch({
71
54
  ...this.lastPointerInfo,
72
55
  type: "click",
73
- name: "quadruple_click",
74
- phase: "settle"
56
+ name: "double_click",
57
+ phase: this._isPressingWhilePending ? "settle-down" : "settle-up"
75
58
  });
76
59
  break;
77
60
  }
@@ -105,6 +88,7 @@ class ClickManager {
105
88
  case "pointer_down": {
106
89
  if (!this._clickState) return info;
107
90
  this._clickScreenPoint = import_Vec.Vec.From(info.point);
91
+ this._isPressingWhilePending = true;
108
92
  if (this._previousScreenPoint && import_Vec.Vec.Dist2(this._previousScreenPoint, this._clickScreenPoint) > MAX_CLICK_DISTANCE ** 2) {
109
93
  this._clickState = "idle";
110
94
  }
@@ -112,32 +96,12 @@ class ClickManager {
112
96
  this.lastPointerInfo = info;
113
97
  switch (this._clickState) {
114
98
  case "pendingDouble": {
115
- this._clickState = "pendingTriple";
116
- this._clickTimeout = this._getClickTimeout(this._clickState);
117
- return {
118
- ...info,
119
- type: "click",
120
- name: "double_click",
121
- phase: "down"
122
- };
123
- }
124
- case "pendingTriple": {
125
- this._clickState = "pendingQuadruple";
126
- this._clickTimeout = this._getClickTimeout(this._clickState);
127
- return {
128
- ...info,
129
- type: "click",
130
- name: "triple_click",
131
- phase: "down"
132
- };
133
- }
134
- case "pendingQuadruple": {
135
99
  this._clickState = "pendingOverflow";
136
100
  this._clickTimeout = this._getClickTimeout(this._clickState);
137
101
  return {
138
102
  ...info,
139
103
  type: "click",
140
- name: "quadruple_click",
104
+ name: "double_click",
141
105
  phase: "down"
142
106
  };
143
107
  }
@@ -158,28 +122,13 @@ class ClickManager {
158
122
  case "pointer_up": {
159
123
  if (!this._clickState) return info;
160
124
  this._clickScreenPoint = import_Vec.Vec.From(info.point);
125
+ this._isPressingWhilePending = false;
161
126
  switch (this._clickState) {
162
- case "pendingTriple": {
163
- return {
164
- ...this.lastPointerInfo,
165
- type: "click",
166
- name: "double_click",
167
- phase: "up"
168
- };
169
- }
170
- case "pendingQuadruple": {
171
- return {
172
- ...this.lastPointerInfo,
173
- type: "click",
174
- name: "triple_click",
175
- phase: "up"
176
- };
177
- }
178
127
  case "pendingOverflow": {
179
128
  return {
180
129
  ...this.lastPointerInfo,
181
130
  type: "click",
182
- name: "quadruple_click",
131
+ name: "double_click",
183
132
  phase: "up"
184
133
  };
185
134
  }
@@ -200,6 +149,7 @@ class ClickManager {
200
149
  cancelDoubleClickTimeout() {
201
150
  this._clickTimeout = clearTimeout(this._clickTimeout);
202
151
  this._clickState = "idle";
152
+ this._isPressingWhilePending = false;
203
153
  }
204
154
  }
205
155
  __decorateClass([
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/editor/managers/ClickManager/ClickManager.ts"],
4
- "sourcesContent": ["import { bind, uniqueId } from '@tldraw/utils'\nimport { Vec } from '../../../primitives/Vec'\nimport type { Editor } from '../../Editor'\nimport { TLClickEventInfo, TLPointerEventInfo } from '../../types/event-types'\n\n/** @public */\nexport type TLClickState =\n\t| 'idle'\n\t| 'pendingDouble'\n\t| 'pendingTriple'\n\t| 'pendingQuadruple'\n\t| 'pendingOverflow'\n\t| 'overflow'\n\nconst MAX_CLICK_DISTANCE = 40\n\n/** @public */\nexport class ClickManager {\n\tconstructor(public editor: Editor) {}\n\n\tprivate _clickId = ''\n\n\tprivate _clickTimeout?: any\n\n\tprivate _clickScreenPoint?: Vec\n\n\tprivate _previousScreenPoint?: Vec\n\n\t@bind\n\t_getClickTimeout(state: TLClickState, id = uniqueId()) {\n\t\tthis._clickId = id\n\t\tclearTimeout(this._clickTimeout)\n\t\tthis._clickTimeout = this.editor.timers.setTimeout(\n\t\t\t() => {\n\t\t\t\tif (this._clickState === state && this._clickId === id) {\n\t\t\t\t\tswitch (this._clickState) {\n\t\t\t\t\t\tcase 'pendingTriple': {\n\t\t\t\t\t\t\tthis.editor.dispatch({\n\t\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\t\tname: 'double_click',\n\t\t\t\t\t\t\t\tphase: 'settle',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'pendingQuadruple': {\n\t\t\t\t\t\t\tthis.editor.dispatch({\n\t\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\t\tname: 'triple_click',\n\t\t\t\t\t\t\t\tphase: 'settle',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'pendingOverflow': {\n\t\t\t\t\t\t\tthis.editor.dispatch({\n\t\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\t\tname: 'quadruple_click',\n\t\t\t\t\t\t\t\tphase: 'settle',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// noop\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._clickState = 'idle'\n\t\t\t\t}\n\t\t\t},\n\t\t\tstate === 'idle' || state === 'pendingDouble'\n\t\t\t\t? this.editor.options.doubleClickDurationMs\n\t\t\t\t: this.editor.options.multiClickDurationMs\n\t\t)\n\t}\n\n\t/**\n\t * The current click state.\n\t *\n\t * @internal\n\t */\n\tprivate _clickState?: TLClickState = 'idle'\n\n\t/**\n\t * The current click state.\n\t *\n\t * @public\n\t */\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget clickState() {\n\t\treturn this._clickState\n\t}\n\n\tlastPointerInfo = {} as TLPointerEventInfo\n\n\thandlePointerEvent(info: TLPointerEventInfo): TLPointerEventInfo | TLClickEventInfo {\n\t\tswitch (info.name) {\n\t\t\tcase 'pointer_down': {\n\t\t\t\tif (!this._clickState) return info\n\t\t\t\tthis._clickScreenPoint = Vec.From(info.point)\n\n\t\t\t\tif (\n\t\t\t\t\tthis._previousScreenPoint &&\n\t\t\t\t\tVec.Dist2(this._previousScreenPoint, this._clickScreenPoint) > MAX_CLICK_DISTANCE ** 2\n\t\t\t\t) {\n\t\t\t\t\tthis._clickState = 'idle'\n\t\t\t\t}\n\n\t\t\t\tthis._previousScreenPoint = this._clickScreenPoint\n\n\t\t\t\tthis.lastPointerInfo = info\n\n\t\t\t\tswitch (this._clickState) {\n\t\t\t\t\tcase 'pendingDouble': {\n\t\t\t\t\t\tthis._clickState = 'pendingTriple'\n\t\t\t\t\t\tthis._clickTimeout = this._getClickTimeout(this._clickState)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'double_click',\n\t\t\t\t\t\t\tphase: 'down',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pendingTriple': {\n\t\t\t\t\t\tthis._clickState = 'pendingQuadruple'\n\t\t\t\t\t\tthis._clickTimeout = this._getClickTimeout(this._clickState)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'triple_click',\n\t\t\t\t\t\t\tphase: 'down',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pendingQuadruple': {\n\t\t\t\t\t\tthis._clickState = 'pendingOverflow'\n\t\t\t\t\t\tthis._clickTimeout = this._getClickTimeout(this._clickState)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'quadruple_click',\n\t\t\t\t\t\t\tphase: 'down',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'idle': {\n\t\t\t\t\t\tthis._clickState = 'pendingDouble'\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pendingOverflow': {\n\t\t\t\t\t\tthis._clickState = 'overflow'\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\t// overflow\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._clickTimeout = this._getClickTimeout(this._clickState)\n\t\t\t\treturn info\n\t\t\t}\n\t\t\tcase 'pointer_up': {\n\t\t\t\tif (!this._clickState) return info\n\t\t\t\tthis._clickScreenPoint = Vec.From(info.point)\n\n\t\t\t\tswitch (this._clickState) {\n\t\t\t\t\tcase 'pendingTriple': {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'double_click',\n\t\t\t\t\t\t\tphase: 'up',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pendingQuadruple': {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'triple_click',\n\t\t\t\t\t\t\tphase: 'up',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pendingOverflow': {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'quadruple_click',\n\t\t\t\t\t\t\tphase: 'up',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\t// idle, pendingDouble, overflow\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn info\n\t\t\t}\n\t\t\tcase 'pointer_move': {\n\t\t\t\tif (\n\t\t\t\t\tthis._clickState !== 'idle' &&\n\t\t\t\t\tthis._clickScreenPoint &&\n\t\t\t\t\tVec.Dist2(this._clickScreenPoint, this.editor.inputs.getCurrentScreenPoint()) >\n\t\t\t\t\t\t(this.editor.getInstanceState().isCoarsePointer\n\t\t\t\t\t\t\t? this.editor.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t: this.editor.options.dragDistanceSquared)\n\t\t\t\t) {\n\t\t\t\t\tthis.cancelDoubleClickTimeout()\n\t\t\t\t}\n\t\t\t\treturn info\n\t\t\t}\n\t\t}\n\t\treturn info\n\t}\n\n\t/**\n\t * Cancel the double click timeout.\n\t *\n\t * @internal\n\t */\n\t@bind\n\tcancelDoubleClickTimeout() {\n\t\tthis._clickTimeout = clearTimeout(this._clickTimeout)\n\t\tthis._clickState = 'idle'\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { bind, uniqueId } from '@tldraw/utils'\nimport { Vec } from '../../../primitives/Vec'\nimport type { Editor } from '../../Editor'\nimport { TLClickEventInfo, TLPointerEventInfo } from '../../types/event-types'\n\n/** @public */\nexport type TLClickState = 'idle' | 'pendingDouble' | 'pendingOverflow' | 'overflow'\n\nconst MAX_CLICK_DISTANCE = 40\n\n/** @public */\nexport class ClickManager {\n\tconstructor(public editor: Editor) {}\n\n\tprivate _clickId = ''\n\n\tprivate _clickTimeout?: any\n\n\tprivate _clickScreenPoint?: Vec\n\n\tprivate _previousScreenPoint?: Vec\n\n\tprivate _isPressingWhilePending = false\n\n\t@bind\n\t_getClickTimeout(state: TLClickState, id = uniqueId()) {\n\t\tthis._clickId = id\n\t\tclearTimeout(this._clickTimeout)\n\t\tthis._clickTimeout = this.editor.timers.setTimeout(\n\t\t\t() => {\n\t\t\t\tif (this._clickState === state && this._clickId === id) {\n\t\t\t\t\tswitch (this._clickState) {\n\t\t\t\t\t\tcase 'pendingOverflow': {\n\t\t\t\t\t\t\tthis.editor.dispatch({\n\t\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\t\tname: 'double_click',\n\t\t\t\t\t\t\t\tphase: this._isPressingWhilePending ? 'settle-down' : 'settle-up',\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t// noop\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._clickState = 'idle'\n\t\t\t\t}\n\t\t\t},\n\t\t\tstate === 'idle' || state === 'pendingDouble'\n\t\t\t\t? this.editor.options.doubleClickDurationMs\n\t\t\t\t: this.editor.options.multiClickDurationMs\n\t\t)\n\t}\n\n\t/**\n\t * The current click state.\n\t *\n\t * @internal\n\t */\n\tprivate _clickState?: TLClickState = 'idle'\n\n\t/**\n\t * The current click state.\n\t *\n\t * @public\n\t */\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget clickState() {\n\t\treturn this._clickState\n\t}\n\n\tlastPointerInfo = {} as TLPointerEventInfo\n\n\thandlePointerEvent(info: TLPointerEventInfo): TLPointerEventInfo | TLClickEventInfo {\n\t\tswitch (info.name) {\n\t\t\tcase 'pointer_down': {\n\t\t\t\tif (!this._clickState) return info\n\t\t\t\tthis._clickScreenPoint = Vec.From(info.point)\n\n\t\t\t\tthis._isPressingWhilePending = true\n\n\t\t\t\tif (\n\t\t\t\t\tthis._previousScreenPoint &&\n\t\t\t\t\tVec.Dist2(this._previousScreenPoint, this._clickScreenPoint) > MAX_CLICK_DISTANCE ** 2\n\t\t\t\t) {\n\t\t\t\t\tthis._clickState = 'idle'\n\t\t\t\t}\n\n\t\t\t\tthis._previousScreenPoint = this._clickScreenPoint\n\n\t\t\t\tthis.lastPointerInfo = info\n\n\t\t\t\tswitch (this._clickState) {\n\t\t\t\t\tcase 'pendingDouble': {\n\t\t\t\t\t\tthis._clickState = 'pendingOverflow'\n\t\t\t\t\t\tthis._clickTimeout = this._getClickTimeout(this._clickState)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'double_click',\n\t\t\t\t\t\t\tphase: 'down',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'idle': {\n\t\t\t\t\t\tthis._clickState = 'pendingDouble'\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pendingOverflow': {\n\t\t\t\t\t\tthis._clickState = 'overflow'\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\t// overflow\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._clickTimeout = this._getClickTimeout(this._clickState)\n\t\t\t\treturn info\n\t\t\t}\n\t\t\tcase 'pointer_up': {\n\t\t\t\tif (!this._clickState) return info\n\n\t\t\t\tthis._clickScreenPoint = Vec.From(info.point)\n\n\t\t\t\tthis._isPressingWhilePending = false\n\n\t\t\t\tswitch (this._clickState) {\n\t\t\t\t\tcase 'pendingOverflow': {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...this.lastPointerInfo,\n\t\t\t\t\t\t\ttype: 'click',\n\t\t\t\t\t\t\tname: 'double_click',\n\t\t\t\t\t\t\tphase: 'up',\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\t// idle, pendingDouble, overflow\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn info\n\t\t\t}\n\t\t\tcase 'pointer_move': {\n\t\t\t\tif (\n\t\t\t\t\tthis._clickState !== 'idle' &&\n\t\t\t\t\tthis._clickScreenPoint &&\n\t\t\t\t\tVec.Dist2(this._clickScreenPoint, this.editor.inputs.getCurrentScreenPoint()) >\n\t\t\t\t\t\t(this.editor.getInstanceState().isCoarsePointer\n\t\t\t\t\t\t\t? this.editor.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t: this.editor.options.dragDistanceSquared)\n\t\t\t\t) {\n\t\t\t\t\tthis.cancelDoubleClickTimeout()\n\t\t\t\t}\n\t\t\t\treturn info\n\t\t\t}\n\t\t}\n\t\treturn info\n\t}\n\n\t/**\n\t * Cancel the double click timeout.\n\t *\n\t * @internal\n\t */\n\t@bind\n\tcancelDoubleClickTimeout() {\n\t\tthis._clickTimeout = clearTimeout(this._clickTimeout)\n\t\tthis._clickState = 'idle'\n\t\t// when a double click is cancelled, we are no longer pending any further\n\t\t// clicks, so we set this to false even if the user is still pressing\n\t\tthis._isPressingWhilePending = false\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAC/B,iBAAoB;AAOpB,MAAM,qBAAqB;AAGpB,MAAM,aAAa;AAAA,EACzB,YAAmB,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAAjB;AAAA,EAEX,WAAW;AAAA,EAEX;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,0BAA0B;AAAA,EAGlC,iBAAiB,OAAqB,SAAK,uBAAS,GAAG;AACtD,SAAK,WAAW;AAChB,iBAAa,KAAK,aAAa;AAC/B,SAAK,gBAAgB,KAAK,OAAO,OAAO;AAAA,MACvC,MAAM;AACL,YAAI,KAAK,gBAAgB,SAAS,KAAK,aAAa,IAAI;AACvD,kBAAQ,KAAK,aAAa;AAAA,YACzB,KAAK,mBAAmB;AACvB,mBAAK,OAAO,SAAS;AAAA,gBACpB,GAAG,KAAK;AAAA,gBACR,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,OAAO,KAAK,0BAA0B,gBAAgB;AAAA,cACvD,CAAC;AACD;AAAA,YACD;AAAA,YACA,SAAS;AAAA,YAET;AAAA,UACD;AAEA,eAAK,cAAc;AAAA,QACpB;AAAA,MACD;AAAA,MACA,UAAU,UAAU,UAAU,kBAC3B,KAAK,OAAO,QAAQ,wBACpB,KAAK,OAAO,QAAQ;AAAA,IACxB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrC,IAAI,aAAa;AAChB,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,kBAAkB,CAAC;AAAA,EAEnB,mBAAmB,MAAiE;AACnF,YAAQ,KAAK,MAAM;AAAA,MAClB,KAAK,gBAAgB;AACpB,YAAI,CAAC,KAAK,YAAa,QAAO;AAC9B,aAAK,oBAAoB,eAAI,KAAK,KAAK,KAAK;AAE5C,aAAK,0BAA0B;AAE/B,YACC,KAAK,wBACL,eAAI,MAAM,KAAK,sBAAsB,KAAK,iBAAiB,IAAI,sBAAsB,GACpF;AACD,eAAK,cAAc;AAAA,QACpB;AAEA,aAAK,uBAAuB,KAAK;AAEjC,aAAK,kBAAkB;AAEvB,gBAAQ,KAAK,aAAa;AAAA,UACzB,KAAK,iBAAiB;AACrB,iBAAK,cAAc;AACnB,iBAAK,gBAAgB,KAAK,iBAAiB,KAAK,WAAW;AAC3D,mBAAO;AAAA,cACN,GAAG;AAAA,cACH,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,KAAK,QAAQ;AACZ,iBAAK,cAAc;AACnB;AAAA,UACD;AAAA,UACA,KAAK,mBAAmB;AACvB,iBAAK,cAAc;AACnB;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UAET;AAAA,QACD;AACA,aAAK,gBAAgB,KAAK,iBAAiB,KAAK,WAAW;AAC3D,eAAO;AAAA,MACR;AAAA,MACA,KAAK,cAAc;AAClB,YAAI,CAAC,KAAK,YAAa,QAAO;AAE9B,aAAK,oBAAoB,eAAI,KAAK,KAAK,KAAK;AAE5C,aAAK,0BAA0B;AAE/B,gBAAQ,KAAK,aAAa;AAAA,UACzB,KAAK,mBAAmB;AACvB,mBAAO;AAAA,cACN,GAAG,KAAK;AAAA,cACR,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UAET;AAAA,QACD;AAEA,eAAO;AAAA,MACR;AAAA,MACA,KAAK,gBAAgB;AACpB,YACC,KAAK,gBAAgB,UACrB,KAAK,qBACL,eAAI,MAAM,KAAK,mBAAmB,KAAK,OAAO,OAAO,sBAAsB,CAAC,KAC1E,KAAK,OAAO,iBAAiB,EAAE,kBAC7B,KAAK,OAAO,QAAQ,4BACpB,KAAK,OAAO,QAAQ,sBACvB;AACD,eAAK,yBAAyB;AAAA,QAC/B;AACA,eAAO;AAAA,MACR;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAQA,2BAA2B;AAC1B,SAAK,gBAAgB,aAAa,KAAK,aAAa;AACpD,SAAK,cAAc;AAGnB,SAAK,0BAA0B;AAAA,EAChC;AACD;AAnJC;AAAA,EADC;AAAA,GAbW,aAcZ;AA4IA;AAAA,EADC;AAAA,GAzJW,aA0JZ;",
6
6
  "names": []
7
7
  }
@@ -82,7 +82,7 @@ class CollaboratorsManager {
82
82
  const currentUserId = this.editor.user.getId();
83
83
  return collaborators.filter((presence) => {
84
84
  const { lastActivityTimestamp, userId, chatMessage } = presence;
85
- const elapsed = Math.max(0, now - (lastActivityTimestamp ?? now));
85
+ const elapsed = lastActivityTimestamp ? Math.max(0, now - lastActivityTimestamp) : 0;
86
86
  if (elapsed > collaboratorInactiveTimeoutMs) {
87
87
  return followingUserId === userId || highlightedUserIds.includes(userId);
88
88
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts"],
4
- "sourcesContent": ["import { EMPTY_ARRAY, atom, computed } from '@tldraw/state'\nimport type { TLInstancePresence } from '@tldraw/tlschema'\nimport { maxBy } from '@tldraw/utils'\nimport type { Editor } from '../../Editor'\n\n/**\n * Tracks remote peers and exposes the collaborator-related queries used by the\n * editor and its overlays. Encapsulates the visibility clock that periodically\n * re-evaluates which collaborators should be visible based on activity.\n *\n * Accessed via {@link Editor.collaborators}.\n *\n * @public\n */\nexport class CollaboratorsManager {\n\tconstructor(private readonly editor: Editor) {}\n\n\tprivate _visibilityClockStarted = false\n\n\tprivate _startVisibilityClock() {\n\t\tif (this._visibilityClockStarted) return\n\t\tthis._visibilityClockStarted = true\n\n\t\t// Editor disposes `editor.timers` on its own teardown, so the interval is\n\t\t// automatically cleared when the editor is disposed.\n\t\tthis.editor.timers.setInterval(() => {\n\t\t\tthis._visibilityClock.set(Date.now())\n\t\t}, this.editor.options.collaboratorCheckIntervalMs)\n\t}\n\n\t/**\n\t * Drives reactive re-evaluation of {@link CollaboratorsManager.getVisibleCollaborators}.\n\t * Ticked on a fixed interval so callers don't need to manage their own activity timers.\n\t */\n\tprivate readonly _visibilityClock = atom('collaboratorVisibilityClock', Date.now())\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.editor.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.editor.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t */\n\t@computed\n\tgetCollaborators(): TLInstancePresence[] {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = maxBy(\n\t\t\t\tallPresenceRecords.filter((c) => c.userId === id),\n\t\t\t\t(p) => p.lastActivityTimestamp ?? 0\n\t\t\t)\n\t\t\treturn latestPresence!\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage(): TLInstancePresence[] {\n\t\tconst currentPageId = this.editor.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t/**\n\t * Returns a list of presence records for peer collaborators who should currently be\n\t * shown in the UI. Filters {@link CollaboratorsManager.getCollaborators} by activity\n\t * state (active / idle / inactive) and visibility rules such as following and\n\t * highlighted users. Re-evaluates on the visibility clock, so callers don't need to\n\t * drive their own activity timer.\n\t */\n\t@computed\n\tgetVisibleCollaborators(): TLInstancePresence[] {\n\t\tconst { editor } = this\n\t\tconst { collaboratorInactiveTimeoutMs, collaboratorIdleTimeoutMs } = editor.options\n\n\t\tthis._startVisibilityClock()\n\t\tthis._visibilityClock.get()\n\t\tconst now = Date.now()\n\t\tconst collaborators = this.getCollaborators()\n\t\tif (!collaborators.length) return EMPTY_ARRAY\n\n\t\tconst { followingUserId, highlightedUserIds } = this.editor.getInstanceState()\n\t\tconst currentUserId = this.editor.user.getId()\n\n\t\treturn collaborators.filter((presence) => {\n\t\t\tconst { lastActivityTimestamp, userId, chatMessage } = presence\n\n\t\t\t// Treat a missing `lastActivityTimestamp` as \"active right now\" (elapsed = 0)\n\t\t\t// so newly-joined peers aren't immediately classified as idle/inactive.\n\t\t\tconst elapsed = Math.max(0, now - (lastActivityTimestamp ?? now))\n\n\t\t\tif (elapsed > collaboratorInactiveTimeoutMs) {\n\t\t\t\t// Inactive: If they're inactive, only show if we're following them or they're highlighted\n\t\t\t\treturn followingUserId === userId || highlightedUserIds.includes(userId)\n\t\t\t}\n\n\t\t\tif (elapsed > collaboratorIdleTimeoutMs) {\n\t\t\t\t// Idle: If they're idle and following us, hide them unless they have a chat message or are highlighted\n\t\t\t\tif (presence.followingUserId === currentUserId) {\n\t\t\t\t\treturn !!(chatMessage || highlightedUserIds.includes(userId))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Active\n\t\t\treturn true\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for peer collaborators who should currently be\n\t * shown in the UI, filtered to those on the current page.\n\t */\n\t@computed\n\tgetVisibleCollaboratorsOnCurrentPage(): TLInstancePresence[] {\n\t\tconst currentPageId = this.editor.getCurrentPageId()\n\t\treturn this.getVisibleCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4C;AAE5C,mBAAsB;AAYf,MAAM,qBAAqB;AAAA,EACjC,YAA6B,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAAjB;AAAA,EAErB,0BAA0B;AAAA,EAE1B,wBAAwB;AAC/B,QAAI,KAAK,wBAAyB;AAClC,SAAK,0BAA0B;AAI/B,SAAK,OAAO,OAAO,YAAY,MAAM;AACpC,WAAK,iBAAiB,IAAI,KAAK,IAAI,CAAC;AAAA,IACrC,GAAG,KAAK,OAAO,QAAQ,2BAA2B;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMiB,uBAAmB,mBAAK,+BAA+B,KAAK,IAAI,CAAC;AAAA,EAG1E,yBAAyB;AAChC,WAAO,KAAK,OAAO,MAAM,MAAM,QAAQ,qBAAqB,OAAO;AAAA,MAClE,QAAQ,EAAE,KAAK,KAAK,OAAO,KAAK,MAAM,EAAE;AAAA,IACzC,EAAE;AAAA,EACH;AAAA,EAOA,mBAAyC;AACxC,UAAM,qBAAqB,KAAK,uBAAuB,EAAE,IAAI;AAC7D,QAAI,CAAC,mBAAmB,OAAQ,QAAO;AACvC,UAAM,UAAU,CAAC,GAAG,IAAI,IAAI,mBAAmB,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK;AAC3E,WAAO,QAAQ,IAAI,CAAC,OAAO;AAC1B,YAAM,qBAAiB;AAAA,QACtB,mBAAmB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE;AAAA,QAChD,CAAC,MAAM,EAAE,yBAAyB;AAAA,MACnC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAOA,gCAAsD;AACrD,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AACnD,WAAO,KAAK,iBAAiB,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,aAAa;AAAA,EAC/E;AAAA,EAUA,0BAAgD;AAC/C,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,EAAE,+BAA+B,0BAA0B,IAAI,OAAO;AAE5E,SAAK,sBAAsB;AAC3B,SAAK,iBAAiB,IAAI;AAC1B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAI,CAAC,cAAc,OAAQ,QAAO;AAElC,UAAM,EAAE,iBAAiB,mBAAmB,IAAI,KAAK,OAAO,iBAAiB;AAC7E,UAAM,gBAAgB,KAAK,OAAO,KAAK,MAAM;AAE7C,WAAO,cAAc,OAAO,CAAC,aAAa;AACzC,YAAM,EAAE,uBAAuB,QAAQ,YAAY,IAAI;AAIvD,YAAM,UAAU,KAAK,IAAI,GAAG,OAAO,yBAAyB,IAAI;AAEhE,UAAI,UAAU,+BAA+B;AAE5C,eAAO,oBAAoB,UAAU,mBAAmB,SAAS,MAAM;AAAA,MACxE;AAEA,UAAI,UAAU,2BAA2B;AAExC,YAAI,SAAS,oBAAoB,eAAe;AAC/C,iBAAO,CAAC,EAAE,eAAe,mBAAmB,SAAS,MAAM;AAAA,QAC5D;AAAA,MACD;AAGA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAOA,uCAA6D;AAC5D,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AACnD,WAAO,KAAK,wBAAwB,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,aAAa;AAAA,EACtF;AACD;AAxFS;AAAA,EADP;AAAA,GAtBW,qBAuBJ;AAWR;AAAA,EADC;AAAA,GAjCW,qBAkCZ;AAkBA;AAAA,EADC;AAAA,GAnDW,qBAoDZ;AAaA;AAAA,EADC;AAAA,GAhEW,qBAiEZ;AA0CA;AAAA,EADC;AAAA,GA1GW,qBA2GZ;",
4
+ "sourcesContent": ["import { EMPTY_ARRAY, atom, computed } from '@tldraw/state'\nimport type { TLInstancePresence } from '@tldraw/tlschema'\nimport { maxBy } from '@tldraw/utils'\nimport type { Editor } from '../../Editor'\n\n/**\n * Tracks remote peers and exposes the collaborator-related queries used by the\n * editor and its overlays. Encapsulates the visibility clock that periodically\n * re-evaluates which collaborators should be visible based on activity.\n *\n * Accessed via {@link Editor.collaborators}.\n *\n * @public\n */\nexport class CollaboratorsManager {\n\tconstructor(private readonly editor: Editor) {}\n\n\tprivate _visibilityClockStarted = false\n\n\tprivate _startVisibilityClock() {\n\t\tif (this._visibilityClockStarted) return\n\t\tthis._visibilityClockStarted = true\n\n\t\t// Editor disposes `editor.timers` on its own teardown, so the interval is\n\t\t// automatically cleared when the editor is disposed.\n\t\tthis.editor.timers.setInterval(() => {\n\t\t\tthis._visibilityClock.set(Date.now())\n\t\t}, this.editor.options.collaboratorCheckIntervalMs)\n\t}\n\n\t/**\n\t * Drives reactive re-evaluation of {@link CollaboratorsManager.getVisibleCollaborators}.\n\t * Ticked on a fixed interval so callers don't need to manage their own activity timers.\n\t */\n\tprivate readonly _visibilityClock = atom('collaboratorVisibilityClock', Date.now())\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.editor.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.editor.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t */\n\t@computed\n\tgetCollaborators(): TLInstancePresence[] {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = maxBy(\n\t\t\t\tallPresenceRecords.filter((c) => c.userId === id),\n\t\t\t\t(p) => p.lastActivityTimestamp ?? 0\n\t\t\t)\n\t\t\treturn latestPresence!\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage(): TLInstancePresence[] {\n\t\tconst currentPageId = this.editor.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t/**\n\t * Returns a list of presence records for peer collaborators who should currently be\n\t * shown in the UI. Filters {@link CollaboratorsManager.getCollaborators} by activity\n\t * state (active / idle / inactive) and visibility rules such as following and\n\t * highlighted users. Re-evaluates on the visibility clock, so callers don't need to\n\t * drive their own activity timer.\n\t */\n\t@computed\n\tgetVisibleCollaborators(): TLInstancePresence[] {\n\t\tconst { editor } = this\n\t\tconst { collaboratorInactiveTimeoutMs, collaboratorIdleTimeoutMs } = editor.options\n\n\t\tthis._startVisibilityClock()\n\t\tthis._visibilityClock.get()\n\t\tconst now = Date.now()\n\t\tconst collaborators = this.getCollaborators()\n\t\tif (!collaborators.length) return EMPTY_ARRAY\n\n\t\tconst { followingUserId, highlightedUserIds } = this.editor.getInstanceState()\n\t\tconst currentUserId = this.editor.user.getId()\n\n\t\treturn collaborators.filter((presence) => {\n\t\t\tconst { lastActivityTimestamp, userId, chatMessage } = presence\n\n\t\t\t// Treat a missing or zero `lastActivityTimestamp` as \"active right now\"\n\t\t\t// (elapsed = 0) so newly-joined peers aren't immediately classified as\n\t\t\t// idle/inactive. The broadcast default for peers who haven't moved their\n\t\t\t// pointer yet is `0` (e.g. someone on a touch device who joins and just\n\t\t\t// watches), so a plain `?? now` would leave them hidden. See issue #9017.\n\t\t\tconst elapsed = lastActivityTimestamp ? Math.max(0, now - lastActivityTimestamp) : 0\n\n\t\t\tif (elapsed > collaboratorInactiveTimeoutMs) {\n\t\t\t\t// Inactive: If they're inactive, only show if we're following them or they're highlighted\n\t\t\t\treturn followingUserId === userId || highlightedUserIds.includes(userId)\n\t\t\t}\n\n\t\t\tif (elapsed > collaboratorIdleTimeoutMs) {\n\t\t\t\t// Idle: If they're idle and following us, hide them unless they have a chat message or are highlighted\n\t\t\t\tif (presence.followingUserId === currentUserId) {\n\t\t\t\t\treturn !!(chatMessage || highlightedUserIds.includes(userId))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Active\n\t\t\treturn true\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for peer collaborators who should currently be\n\t * shown in the UI, filtered to those on the current page.\n\t */\n\t@computed\n\tgetVisibleCollaboratorsOnCurrentPage(): TLInstancePresence[] {\n\t\tconst currentPageId = this.editor.getCurrentPageId()\n\t\treturn this.getVisibleCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4C;AAE5C,mBAAsB;AAYf,MAAM,qBAAqB;AAAA,EACjC,YAA6B,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAAjB;AAAA,EAErB,0BAA0B;AAAA,EAE1B,wBAAwB;AAC/B,QAAI,KAAK,wBAAyB;AAClC,SAAK,0BAA0B;AAI/B,SAAK,OAAO,OAAO,YAAY,MAAM;AACpC,WAAK,iBAAiB,IAAI,KAAK,IAAI,CAAC;AAAA,IACrC,GAAG,KAAK,OAAO,QAAQ,2BAA2B;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMiB,uBAAmB,mBAAK,+BAA+B,KAAK,IAAI,CAAC;AAAA,EAG1E,yBAAyB;AAChC,WAAO,KAAK,OAAO,MAAM,MAAM,QAAQ,qBAAqB,OAAO;AAAA,MAClE,QAAQ,EAAE,KAAK,KAAK,OAAO,KAAK,MAAM,EAAE;AAAA,IACzC,EAAE;AAAA,EACH;AAAA,EAOA,mBAAyC;AACxC,UAAM,qBAAqB,KAAK,uBAAuB,EAAE,IAAI;AAC7D,QAAI,CAAC,mBAAmB,OAAQ,QAAO;AACvC,UAAM,UAAU,CAAC,GAAG,IAAI,IAAI,mBAAmB,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK;AAC3E,WAAO,QAAQ,IAAI,CAAC,OAAO;AAC1B,YAAM,qBAAiB;AAAA,QACtB,mBAAmB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE;AAAA,QAChD,CAAC,MAAM,EAAE,yBAAyB;AAAA,MACnC;AACA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAOA,gCAAsD;AACrD,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AACnD,WAAO,KAAK,iBAAiB,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,aAAa;AAAA,EAC/E;AAAA,EAUA,0BAAgD;AAC/C,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,EAAE,+BAA+B,0BAA0B,IAAI,OAAO;AAE5E,SAAK,sBAAsB;AAC3B,SAAK,iBAAiB,IAAI;AAC1B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAI,CAAC,cAAc,OAAQ,QAAO;AAElC,UAAM,EAAE,iBAAiB,mBAAmB,IAAI,KAAK,OAAO,iBAAiB;AAC7E,UAAM,gBAAgB,KAAK,OAAO,KAAK,MAAM;AAE7C,WAAO,cAAc,OAAO,CAAC,aAAa;AACzC,YAAM,EAAE,uBAAuB,QAAQ,YAAY,IAAI;AAOvD,YAAM,UAAU,wBAAwB,KAAK,IAAI,GAAG,MAAM,qBAAqB,IAAI;AAEnF,UAAI,UAAU,+BAA+B;AAE5C,eAAO,oBAAoB,UAAU,mBAAmB,SAAS,MAAM;AAAA,MACxE;AAEA,UAAI,UAAU,2BAA2B;AAExC,YAAI,SAAS,oBAAoB,eAAe;AAC/C,iBAAO,CAAC,EAAE,eAAe,mBAAmB,SAAS,MAAM;AAAA,QAC5D;AAAA,MACD;AAGA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAOA,uCAA6D;AAC5D,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AACnD,WAAO,KAAK,wBAAwB,EAAE,OAAO,CAAC,MAAM,EAAE,kBAAkB,aAAa;AAAA,EACtF;AACD;AA3FS;AAAA,EADP;AAAA,GAtBW,qBAuBJ;AAWR;AAAA,EADC;AAAA,GAjCW,qBAkCZ;AAkBA;AAAA,EADC;AAAA,GAnDW,qBAoDZ;AAaA;AAAA,EADC;AAAA,GAhEW,qBAiEZ;AA6CA;AAAA,EADC;AAAA,GA7GW,qBA8GZ;",
6
6
  "names": []
7
7
  }
@@ -74,8 +74,7 @@ class FocusManager {
74
74
  handleKeyDown(keyEvent) {
75
75
  const container = this.editor.getContainer();
76
76
  const activeEl = container.ownerDocument.activeElement;
77
- if (this.editor.isIn("select.editing_shape") && !activeEl?.closest(".tlui-contextual-toolbar"))
78
- return;
77
+ if (this.editor.getEditingShapeId() && !activeEl?.closest(".tlui-contextual-toolbar")) return;
79
78
  if (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return;
80
79
  if (["Tab", "ArrowUp", "ArrowDown"].includes(keyEvent.key)) {
81
80
  container.classList.remove("tl-container__no-focus-ring");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/editor/managers/FocusManager/FocusManager.ts"],
4
- "sourcesContent": ["import { bind } from '@tldraw/utils'\nimport type { Editor } from '../../Editor'\n\n/**\n * A manager for ensuring correct focus across the editor.\n * It will listen for changes in the instance state to make sure the\n * container is focused when the editor is focused.\n * Also, it will make sure that the focus is on things like text\n * labels when the editor is in editing mode.\n *\n * @internal\n */\nexport class FocusManager {\n\tprivate disposeSideEffectListener?: () => void\n\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tautoFocus?: boolean\n\t) {\n\t\tthis.disposeSideEffectListener = editor.sideEffects.registerAfterChangeHandler(\n\t\t\t'instance',\n\t\t\t(prev, next) => {\n\t\t\t\tif (prev.isFocused !== next.isFocused) {\n\t\t\t\t\tthis.updateContainerClass()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tconst currentFocusState = editor.getInstanceState().isFocused\n\t\tif (autoFocus !== currentFocusState) {\n\t\t\teditor.updateInstanceState({ isFocused: !!autoFocus })\n\t\t}\n\t\tthis.updateContainerClass()\n\n\t\tconst body = editor.getContainerDocument().body\n\t\tbody.addEventListener('keydown', this.handleKeyDown)\n\t\tbody.addEventListener('mousedown', this.handleMouseDown)\n\t}\n\n\t/**\n\t * The editor's focus state and the container's focus state\n\t * are not necessarily always in sync. For that reason we\n\t * can't rely on the css `:focus` or `:focus-within` selectors to style the\n\t * editor when it is in focus.\n\t *\n\t * For that reason we synchronize the editor's focus state with a\n\t * special class on the container: tl-container__focused\n\t */\n\tprivate updateContainerClass() {\n\t\tconst container = this.editor.getContainer()\n\t\tconst instanceState = this.editor.getInstanceState()\n\n\t\tif (instanceState.isFocused) {\n\t\t\tcontainer.classList.add('tl-container__focused')\n\t\t} else {\n\t\t\tcontainer.classList.remove('tl-container__focused')\n\t\t}\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\t@bind private handleKeyDown(keyEvent: KeyboardEvent) {\n\t\tconst container = this.editor.getContainer()\n\t\tconst activeEl = container.ownerDocument.activeElement\n\t\t// Edit mode should remove the focus ring, however if the active element's\n\t\t// parent is the contextual toolbar, then allow it.\n\t\tif (this.editor.isIn('select.editing_shape') && !activeEl?.closest('.tlui-contextual-toolbar'))\n\t\t\treturn\n\t\tif (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return\n\t\tif (['Tab', 'ArrowUp', 'ArrowDown'].includes(keyEvent.key)) {\n\t\t\tcontainer.classList.remove('tl-container__no-focus-ring')\n\t\t}\n\t}\n\n\t@bind private handleMouseDown() {\n\t\tconst container = this.editor.getContainer()\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tfocus() {\n\t\tthis.editor.getContainer().focus()\n\t}\n\n\tblur({ blurContainer = true } = {}) {\n\t\tthis.editor.complete() // stop any interaction\n\t\tif (blurContainer) this.editor.getContainer().blur() // blur the container\n\t}\n\n\tdispose() {\n\t\tconst body = this.editor.getContainerDocument().body\n\t\tbody.removeEventListener('keydown', this.handleKeyDown)\n\t\tbody.removeEventListener('mousedown', this.handleMouseDown)\n\t\tthis.disposeSideEffectListener?.()\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAqB;AAYd,MAAM,aAAa;AAAA,EAGzB,YACQ,QACP,WACC;AAFM;AAGP,SAAK,4BAA4B,OAAO,YAAY;AAAA,MACnD;AAAA,MACA,CAAC,MAAM,SAAS;AACf,YAAI,KAAK,cAAc,KAAK,WAAW;AACtC,eAAK,qBAAqB;AAAA,QAC3B;AAAA,MACD;AAAA,IACD;AAEA,UAAM,oBAAoB,OAAO,iBAAiB,EAAE;AACpD,QAAI,cAAc,mBAAmB;AACpC,aAAO,oBAAoB,EAAE,WAAW,CAAC,CAAC,UAAU,CAAC;AAAA,IACtD;AACA,SAAK,qBAAqB;AAE1B,UAAM,OAAO,OAAO,qBAAqB,EAAE;AAC3C,SAAK,iBAAiB,WAAW,KAAK,aAAa;AACnD,SAAK,iBAAiB,aAAa,KAAK,eAAe;AAAA,EACxD;AAAA,EArBQ;AAAA,EAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmCA,uBAAuB;AAC9B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,QAAI,cAAc,WAAW;AAC5B,gBAAU,UAAU,IAAI,uBAAuB;AAAA,IAChD,OAAO;AACN,gBAAU,UAAU,OAAO,uBAAuB;AAAA,IACnD;AACA,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEc,cAAc,UAAyB;AACpD,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,WAAW,UAAU,cAAc;AAGzC,QAAI,KAAK,OAAO,KAAK,sBAAsB,KAAK,CAAC,UAAU,QAAQ,0BAA0B;AAC5F;AACD,QAAI,aAAa,aAAa,KAAK,OAAO,oBAAoB,EAAE,SAAS,EAAG;AAC5E,QAAI,CAAC,OAAO,WAAW,WAAW,EAAE,SAAS,SAAS,GAAG,GAAG;AAC3D,gBAAU,UAAU,OAAO,6BAA6B;AAAA,IACzD;AAAA,EACD;AAAA,EAEc,kBAAkB;AAC/B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEA,QAAQ;AACP,SAAK,OAAO,aAAa,EAAE,MAAM;AAAA,EAClC;AAAA,EAEA,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG;AACnC,SAAK,OAAO,SAAS;AACrB,QAAI,cAAe,MAAK,OAAO,aAAa,EAAE,KAAK;AAAA,EACpD;AAAA,EAEA,UAAU;AACT,UAAM,OAAO,KAAK,OAAO,qBAAqB,EAAE;AAChD,SAAK,oBAAoB,WAAW,KAAK,aAAa;AACtD,SAAK,oBAAoB,aAAa,KAAK,eAAe;AAC1D,SAAK,4BAA4B;AAAA,EAClC;AACD;AAjCe;AAAA,EAAb;AAAA,GAhDW,aAgDE;AAaA;AAAA,EAAb;AAAA,GA7DW,aA6DE;",
4
+ "sourcesContent": ["import { bind } from '@tldraw/utils'\nimport type { Editor } from '../../Editor'\n\n/**\n * A manager for ensuring correct focus across the editor.\n * It will listen for changes in the instance state to make sure the\n * container is focused when the editor is focused.\n * Also, it will make sure that the focus is on things like text\n * labels when the editor is in editing mode.\n *\n * @internal\n */\nexport class FocusManager {\n\tprivate disposeSideEffectListener?: () => void\n\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tautoFocus?: boolean\n\t) {\n\t\tthis.disposeSideEffectListener = editor.sideEffects.registerAfterChangeHandler(\n\t\t\t'instance',\n\t\t\t(prev, next) => {\n\t\t\t\tif (prev.isFocused !== next.isFocused) {\n\t\t\t\t\tthis.updateContainerClass()\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tconst currentFocusState = editor.getInstanceState().isFocused\n\t\tif (autoFocus !== currentFocusState) {\n\t\t\teditor.updateInstanceState({ isFocused: !!autoFocus })\n\t\t}\n\t\tthis.updateContainerClass()\n\n\t\tconst body = editor.getContainerDocument().body\n\t\tbody.addEventListener('keydown', this.handleKeyDown)\n\t\tbody.addEventListener('mousedown', this.handleMouseDown)\n\t}\n\n\t/**\n\t * The editor's focus state and the container's focus state\n\t * are not necessarily always in sync. For that reason we\n\t * can't rely on the css `:focus` or `:focus-within` selectors to style the\n\t * editor when it is in focus.\n\t *\n\t * For that reason we synchronize the editor's focus state with a\n\t * special class on the container: tl-container__focused\n\t */\n\tprivate updateContainerClass() {\n\t\tconst container = this.editor.getContainer()\n\t\tconst instanceState = this.editor.getInstanceState()\n\n\t\tif (instanceState.isFocused) {\n\t\t\tcontainer.classList.add('tl-container__focused')\n\t\t} else {\n\t\t\tcontainer.classList.remove('tl-container__focused')\n\t\t}\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\t@bind private handleKeyDown(keyEvent: KeyboardEvent) {\n\t\tconst container = this.editor.getContainer()\n\t\tconst activeEl = container.ownerDocument.activeElement\n\t\t// Edit mode should remove the focus ring, however if the active element's\n\t\t// parent is the contextual toolbar, then allow it.\n\t\tif (this.editor.getEditingShapeId() && !activeEl?.closest('.tlui-contextual-toolbar')) return\n\t\tif (activeEl === container && this.editor.getSelectedShapeIds().length > 0) return\n\t\tif (['Tab', 'ArrowUp', 'ArrowDown'].includes(keyEvent.key)) {\n\t\t\tcontainer.classList.remove('tl-container__no-focus-ring')\n\t\t}\n\t}\n\n\t@bind private handleMouseDown() {\n\t\tconst container = this.editor.getContainer()\n\t\tcontainer.classList.add('tl-container__no-focus-ring')\n\t}\n\n\tfocus() {\n\t\tthis.editor.getContainer().focus()\n\t}\n\n\tblur({ blurContainer = true } = {}) {\n\t\tthis.editor.complete() // stop any interaction\n\t\tif (blurContainer) this.editor.getContainer().blur() // blur the container\n\t}\n\n\tdispose() {\n\t\tconst body = this.editor.getContainerDocument().body\n\t\tbody.removeEventListener('keydown', this.handleKeyDown)\n\t\tbody.removeEventListener('mousedown', this.handleMouseDown)\n\t\tthis.disposeSideEffectListener?.()\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAqB;AAYd,MAAM,aAAa;AAAA,EAGzB,YACQ,QACP,WACC;AAFM;AAGP,SAAK,4BAA4B,OAAO,YAAY;AAAA,MACnD;AAAA,MACA,CAAC,MAAM,SAAS;AACf,YAAI,KAAK,cAAc,KAAK,WAAW;AACtC,eAAK,qBAAqB;AAAA,QAC3B;AAAA,MACD;AAAA,IACD;AAEA,UAAM,oBAAoB,OAAO,iBAAiB,EAAE;AACpD,QAAI,cAAc,mBAAmB;AACpC,aAAO,oBAAoB,EAAE,WAAW,CAAC,CAAC,UAAU,CAAC;AAAA,IACtD;AACA,SAAK,qBAAqB;AAE1B,UAAM,OAAO,OAAO,qBAAqB,EAAE;AAC3C,SAAK,iBAAiB,WAAW,KAAK,aAAa;AACnD,SAAK,iBAAiB,aAAa,KAAK,eAAe;AAAA,EACxD;AAAA,EArBQ;AAAA,EAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmCA,uBAAuB;AAC9B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,QAAI,cAAc,WAAW;AAC5B,gBAAU,UAAU,IAAI,uBAAuB;AAAA,IAChD,OAAO;AACN,gBAAU,UAAU,OAAO,uBAAuB;AAAA,IACnD;AACA,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEc,cAAc,UAAyB;AACpD,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,WAAW,UAAU,cAAc;AAGzC,QAAI,KAAK,OAAO,kBAAkB,KAAK,CAAC,UAAU,QAAQ,0BAA0B,EAAG;AACvF,QAAI,aAAa,aAAa,KAAK,OAAO,oBAAoB,EAAE,SAAS,EAAG;AAC5E,QAAI,CAAC,OAAO,WAAW,WAAW,EAAE,SAAS,SAAS,GAAG,GAAG;AAC3D,gBAAU,UAAU,OAAO,6BAA6B;AAAA,IACzD;AAAA,EACD;AAAA,EAEc,kBAAkB;AAC/B,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,cAAU,UAAU,IAAI,6BAA6B;AAAA,EACtD;AAAA,EAEA,QAAQ;AACP,SAAK,OAAO,aAAa,EAAE,MAAM;AAAA,EAClC;AAAA,EAEA,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG;AACnC,SAAK,OAAO,SAAS;AACrB,QAAI,cAAe,MAAK,OAAO,aAAa,EAAE,KAAK;AAAA,EACpD;AAAA,EAEA,UAAU;AACT,UAAM,OAAO,KAAK,OAAO,qBAAqB,EAAE;AAChD,SAAK,oBAAoB,WAAW,KAAK,aAAa;AACtD,SAAK,oBAAoB,aAAa,KAAK,eAAe;AAC1D,SAAK,4BAA4B;AAAA,EAClC;AACD;AAhCe;AAAA,EAAb;AAAA,GAhDW,aAgDE;AAYA;AAAA,EAAb;AAAA,GA5DW,aA4DE;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var strokeShapeIndicators_exports = {};
20
+ __export(strokeShapeIndicators_exports, {
21
+ strokeShapeIndicators: () => strokeShapeIndicators
22
+ });
23
+ module.exports = __toCommonJS(strokeShapeIndicators_exports);
24
+ var import_store = require("@tldraw/store");
25
+ const indicatorPathCache = (0, import_store.createComputedCache)(
26
+ "shapeIndicatorPath",
27
+ (editor, shape) => {
28
+ const util = editor.getShapeUtil(shape);
29
+ return util.getIndicatorPath(shape);
30
+ },
31
+ {
32
+ areRecordsEqual(a, b) {
33
+ return a.props === b.props;
34
+ }
35
+ }
36
+ );
37
+ function strokeShapeIndicators(editor, ctx, shapeIds) {
38
+ if (shapeIds.length === 0) return;
39
+ const batched = new Path2D();
40
+ for (const shapeId of shapeIds) {
41
+ const shape = editor.getShape(shapeId);
42
+ if (!shape || shape.isLocked) continue;
43
+ const pageTransform = editor.getShapePageTransform(shape);
44
+ if (!pageTransform) continue;
45
+ const indicatorPath = indicatorPathCache.get(editor, shape.id);
46
+ if (!indicatorPath) continue;
47
+ if (indicatorPath instanceof Path2D) {
48
+ batched.addPath(indicatorPath, pageTransform);
49
+ continue;
50
+ }
51
+ const { path, clipPath, additionalPaths } = indicatorPath;
52
+ if (!clipPath) {
53
+ batched.addPath(path, pageTransform);
54
+ if (additionalPaths) {
55
+ for (const p of additionalPaths) batched.addPath(p, pageTransform);
56
+ }
57
+ continue;
58
+ }
59
+ ctx.save();
60
+ ctx.transform(
61
+ pageTransform.a,
62
+ pageTransform.b,
63
+ pageTransform.c,
64
+ pageTransform.d,
65
+ pageTransform.e,
66
+ pageTransform.f
67
+ );
68
+ ctx.save();
69
+ ctx.clip(clipPath, "evenodd");
70
+ ctx.stroke(path);
71
+ ctx.restore();
72
+ if (additionalPaths) {
73
+ for (const p of additionalPaths) ctx.stroke(p);
74
+ }
75
+ ctx.restore();
76
+ }
77
+ ctx.stroke(batched);
78
+ }
79
+ //# sourceMappingURL=strokeShapeIndicators.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/lib/editor/overlays/strokeShapeIndicators.ts"],
4
+ "sourcesContent": ["import { createComputedCache } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport type { Editor } from '../Editor'\n\nconst indicatorPathCache = createComputedCache(\n\t'shapeIndicatorPath',\n\t(editor: Editor, shape: TLShape) => {\n\t\tconst util = editor.getShapeUtil(shape)\n\t\treturn util.getIndicatorPath(shape)\n\t},\n\t{\n\t\tareRecordsEqual(a, b) {\n\t\t\treturn a.props === b.props\n\t\t},\n\t}\n)\n\n/**\n * Combine every batchable shape indicator into a single page-space `Path2D` and\n * emit one stroke call. Shapes whose indicator needs an evenodd clip (e.g.\n * arrows with labels or complex arrowheads) can't be batched \u2014 they still\n * stroke individually inside a save/restore with `ctx.clip` applied.\n *\n * Shared by any overlay util that paints shape indicators (e.g. collaborator\n * selections).\n *\n * @public\n */\nexport function strokeShapeIndicators(\n\teditor: Editor,\n\tctx: CanvasRenderingContext2D,\n\tshapeIds: TLShapeId[]\n): void {\n\tif (shapeIds.length === 0) return\n\n\tconst batched = new Path2D()\n\n\tfor (const shapeId of shapeIds) {\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape || shape.isLocked) continue\n\n\t\tconst pageTransform = editor.getShapePageTransform(shape)\n\t\tif (!pageTransform) continue\n\n\t\tconst indicatorPath = indicatorPathCache.get(editor, shape.id)\n\t\tif (!indicatorPath) continue\n\n\t\tif (indicatorPath instanceof Path2D) {\n\t\t\tbatched.addPath(indicatorPath, pageTransform)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst { path, clipPath, additionalPaths } = indicatorPath\n\n\t\tif (!clipPath) {\n\t\t\tbatched.addPath(path, pageTransform)\n\t\t\tif (additionalPaths) {\n\t\t\t\tfor (const p of additionalPaths) batched.addPath(p, pageTransform)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Clipped case: fall back to an individual stroke. Rare (arrows with\n\t\t// labels / complex arrowheads), so the extra save/restore/stroke\n\t\t// pair per such shape isn't worth batching away.\n\t\tctx.save()\n\t\tctx.transform(\n\t\t\tpageTransform.a,\n\t\t\tpageTransform.b,\n\t\t\tpageTransform.c,\n\t\t\tpageTransform.d,\n\t\t\tpageTransform.e,\n\t\t\tpageTransform.f\n\t\t)\n\t\tctx.save()\n\t\tctx.clip(clipPath, 'evenodd')\n\t\tctx.stroke(path)\n\t\tctx.restore()\n\t\tif (additionalPaths) {\n\t\t\tfor (const p of additionalPaths) ctx.stroke(p)\n\t\t}\n\t\tctx.restore()\n\t}\n\n\tctx.stroke(batched)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAoC;AAIpC,MAAM,yBAAqB;AAAA,EAC1B;AAAA,EACA,CAAC,QAAgB,UAAmB;AACnC,UAAM,OAAO,OAAO,aAAa,KAAK;AACtC,WAAO,KAAK,iBAAiB,KAAK;AAAA,EACnC;AAAA,EACA;AAAA,IACC,gBAAgB,GAAG,GAAG;AACrB,aAAO,EAAE,UAAU,EAAE;AAAA,IACtB;AAAA,EACD;AACD;AAaO,SAAS,sBACf,QACA,KACA,UACO;AACP,MAAI,SAAS,WAAW,EAAG;AAE3B,QAAM,UAAU,IAAI,OAAO;AAE3B,aAAW,WAAW,UAAU;AAC/B,UAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,QAAI,CAAC,SAAS,MAAM,SAAU;AAE9B,UAAM,gBAAgB,OAAO,sBAAsB,KAAK;AACxD,QAAI,CAAC,cAAe;AAEpB,UAAM,gBAAgB,mBAAmB,IAAI,QAAQ,MAAM,EAAE;AAC7D,QAAI,CAAC,cAAe;AAEpB,QAAI,yBAAyB,QAAQ;AACpC,cAAQ,QAAQ,eAAe,aAAa;AAC5C;AAAA,IACD;AAEA,UAAM,EAAE,MAAM,UAAU,gBAAgB,IAAI;AAE5C,QAAI,CAAC,UAAU;AACd,cAAQ,QAAQ,MAAM,aAAa;AACnC,UAAI,iBAAiB;AACpB,mBAAW,KAAK,gBAAiB,SAAQ,QAAQ,GAAG,aAAa;AAAA,MAClE;AACA;AAAA,IACD;AAKA,QAAI,KAAK;AACT,QAAI;AAAA,MACH,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,IACf;AACA,QAAI,KAAK;AACT,QAAI,KAAK,UAAU,SAAS;AAC5B,QAAI,OAAO,IAAI;AACf,QAAI,QAAQ;AACZ,QAAI,iBAAiB;AACpB,iBAAW,KAAK,gBAAiB,KAAI,OAAO,CAAC;AAAA,IAC9C;AACA,QAAI,QAAQ;AAAA,EACb;AAEA,MAAI,OAAO,OAAO;AACnB;",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/tools/StateNode.ts"],
4
- "sourcesContent": ["import { Atom, Computed, atom, computed } from '@tldraw/state'\nimport { PerformanceTracker } from '@tldraw/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport type { Editor } from '../Editor'\nimport {\n\tEVENT_NAME_MAP,\n\tTLCancelEventInfo,\n\tTLClickEventInfo,\n\tTLCompleteEventInfo,\n\tTLEventHandlers,\n\tTLEventInfo,\n\tTLInterruptEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLTickEventInfo,\n\tTLWheelEventInfo,\n} from '../types/event-types'\n\n/** @public */\nexport interface TLStateNodeConstructor {\n\tnew (editor: Editor, parent?: StateNode): StateNode\n\tid: string\n\tinitial?: string\n\tchildren?(): TLStateNodeConstructor[]\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n\ttrackPerformance: boolean\n}\n\n/** @public */\nexport abstract class StateNode implements Partial<TLEventHandlers> {\n\tperformanceTracker: PerformanceTracker\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tparent?: StateNode\n\t) {\n\t\tconst { id, children, initial, isLockable, useCoalescedEvents } = this\n\t\t\t.constructor as TLStateNodeConstructor\n\n\t\tthis.id = id\n\t\tthis._isActive = atom<boolean>('toolIsActive' + this.id, false)\n\t\tthis._current = atom<StateNode | undefined>('toolState' + this.id, undefined)\n\n\t\tthis._path = computed('toolPath' + this.id, () => {\n\t\t\tconst current = this.getCurrent()\n\t\t\treturn this.id + (current ? `.${current.getPath()}` : '')\n\t\t})\n\n\t\tthis.parent = parent ?? ({} as any)\n\n\t\tif (parent) {\n\t\t\tif (children && initial) {\n\t\t\t\tthis.type = 'branch'\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t} else {\n\t\t\t\tthis.type = 'leaf'\n\t\t\t}\n\t\t} else {\n\t\t\tthis.type = 'root'\n\n\t\t\tif (children && initial) {\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t}\n\t\t}\n\t\tthis.isLockable = isLockable\n\t\tthis.useCoalescedEvents = useCoalescedEvents\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tstatic id: string\n\tstatic initial?: string\n\tstatic children?: () => TLStateNodeConstructor[]\n\tstatic isLockable = true\n\tstatic useCoalescedEvents = false\n\t/** Set to `true` in subclasses to emit interaction-start/end performance events when this state is entered/exited. */\n\tstatic trackPerformance = false\n\n\tid: string\n\ttype: 'branch' | 'leaf' | 'root'\n\tshapeType?: string\n\tinitial?: string\n\tchildren?: Record<string, StateNode>\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n\tparent: StateNode\n\n\t/**\n\t * This node's path of active state nodes\n\t *\n\t * @public\n\t */\n\tgetPath() {\n\t\treturn this._path.get()\n\t}\n\t_path: Computed<string>\n\n\t/**\n\t * This node's current active child node, if any.\n\t *\n\t * @public\n\t */\n\tgetCurrent() {\n\t\treturn this._current.get()\n\t}\n\tprivate _current: Atom<StateNode | undefined>\n\n\t/**\n\t * Whether this node is active.\n\t *\n\t * @public\n\t */\n\tgetIsActive() {\n\t\treturn this._isActive.get()\n\t}\n\tprivate _isActive: Atom<boolean>\n\n\t/**\n\t * Transition to a new active child state node.\n\t *\n\t * @example\n\t * ```ts\n\t * parentState.transition('childStateA')\n\t * parentState.transition('childStateB', { myData: 4 })\n\t *```\n\t *\n\t * @param id - The id of the child state node to transition to.\n\t * @param info - Any data to pass to the `onEnter` and `onExit` handlers.\n\t *\n\t * @public\n\t */\n\ttransition(id: string, info: any = {}) {\n\t\tconst path = id.split('.')\n\n\t\tlet currState = this as StateNode\n\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tconst id = path[i]\n\t\t\tconst prevChildState = currState.getCurrent()\n\t\t\tconst nextChildState = currState.children?.[id]\n\n\t\t\tif (!nextChildState) {\n\t\t\t\tthrow Error(`${currState.id} - no child state exists with the id ${id}.`)\n\t\t\t}\n\n\t\t\tif (prevChildState?.id !== nextChildState.id) {\n\t\t\t\tprevChildState?.exit(info, id)\n\t\t\t\tcurrState._current.set(nextChildState)\n\t\t\t\tnextChildState.enter(info, prevChildState?.id || 'initial')\n\t\t\t\tif (!nextChildState.getIsActive()) break\n\t\t\t}\n\n\t\t\tcurrState = nextChildState\n\t\t}\n\n\t\treturn this\n\t}\n\n\thandleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>) {\n\t\tconst cbName = EVENT_NAME_MAP[info.name]\n\t\tconst currentActiveChild = this._current.__unsafe__getWithoutCapture()\n\n\t\tthis[cbName]?.(info as any)\n\t\tif (\n\t\t\tthis._isActive.__unsafe__getWithoutCapture() &&\n\t\t\tcurrentActiveChild &&\n\t\t\tcurrentActiveChild === this._current.__unsafe__getWithoutCapture()\n\t\t) {\n\t\t\tcurrentActiveChild.handleEvent(info)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\tenter(info: any, from: string) {\n\t\tconst track = (this.constructor as TLStateNodeConstructor).trackPerformance\n\t\tif (track) {\n\t\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\t\tthis.performanceTracker.start(this.id)\n\t\t\t}\n\t\t\tthis.editor.performance._notifyInteractionStart(this.id, this.getPath())\n\t\t}\n\n\t\tthis._isActive.set(true)\n\t\tthis.onEnter?.(info, from)\n\n\t\tif (this.children && this.initial && this.getIsActive()) {\n\t\t\tconst initial = this.children[this.initial]\n\t\t\tthis._current.set(initial)\n\t\t\tinitial.enter(info, from)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\texit(info: any, to: string) {\n\t\tconst track = (this.constructor as TLStateNodeConstructor).trackPerformance\n\t\tif (track) {\n\t\t\tif (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}\n\t\t\tthis.editor.performance._notifyInteractionEnd()\n\t\t}\n\n\t\tthis._isActive.set(false)\n\t\tthis.onExit?.(info, to)\n\n\t\tif (!this.getIsActive()) {\n\t\t\tthis.getCurrent()?.exit(info, to)\n\t\t}\n\t}\n\n\t/**\n\t * This is a hack / escape hatch that will tell the editor to\n\t * report a different state as active (in `getCurrentToolId()`) when\n\t * this state is active. This is usually used when a tool transitions\n\t * to a child of a different state for a certain interaction and then\n\t * returns to the original tool when that interaction completes; and\n\t * where we would want to show the original tool as active in the UI.\n\t *\n\t * @public\n\t */\n\t_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)\n\n\tgetCurrentToolIdMask() {\n\t\treturn this._currentToolIdMask.get()\n\t}\n\n\tsetCurrentToolIdMask(id: string | undefined) {\n\t\tthis._currentToolIdMask.set(id)\n\t}\n\n\t/**\n\t * Add a child node to this state node.\n\t *\n\t * @public\n\t */\n\taddChild(childConstructor: TLStateNodeConstructor): this {\n\t\tif (this.type === 'leaf') {\n\t\t\tthrow new Error('StateNode.addChild: cannot add child to a leaf node')\n\t\t}\n\n\t\t// Initialize children if it's undefined (for root nodes without static children)\n\t\tif (!this.children) {\n\t\t\tthis.children = {}\n\t\t}\n\n\t\tconst child = new childConstructor(this.editor, this)\n\n\t\t// Check if a child with this ID already exists\n\t\tif (this.children[child.id]) {\n\t\t\tthrow new Error(`StateNode.addChild: a child with id '${child.id}' already exists`)\n\t\t}\n\n\t\tthis.children[child.id] = child\n\t\treturn this\n\t}\n\n\tonWheel?(info: TLWheelEventInfo): void\n\tonPointerDown?(info: TLPointerEventInfo): void\n\tonPointerMove?(info: TLPointerEventInfo): void\n\tonLongPress?(info: TLPointerEventInfo): void\n\tonPointerUp?(info: TLPointerEventInfo): void\n\tonDoubleClick?(info: TLClickEventInfo): void\n\tonTripleClick?(info: TLClickEventInfo): void\n\tonQuadrupleClick?(info: TLClickEventInfo): void\n\tonRightClick?(info: TLPointerEventInfo): void\n\tonMiddleClick?(info: TLPointerEventInfo): void\n\tonKeyDown?(info: TLKeyboardEventInfo): void\n\tonKeyUp?(info: TLKeyboardEventInfo): void\n\tonKeyRepeat?(info: TLKeyboardEventInfo): void\n\tonCancel?(info: TLCancelEventInfo): void\n\tonComplete?(info: TLCompleteEventInfo): void\n\tonInterrupt?(info: TLInterruptEventInfo): void\n\tonTick?(info: TLTickEventInfo): void\n\n\tonEnter?(info: any, from: string): void\n\tonExit?(info: any, to: string): void\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Atom, Computed, atom, computed } from '@tldraw/state'\nimport { PerformanceTracker } from '@tldraw/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport type { Editor } from '../Editor'\nimport {\n\tEVENT_NAME_MAP,\n\tTLCancelEventInfo,\n\tTLClickEventInfo,\n\tTLCompleteEventInfo,\n\tTLEventHandlers,\n\tTLEventInfo,\n\tTLInterruptEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLTickEventInfo,\n\tTLWheelEventInfo,\n} from '../types/event-types'\n\n/** @public */\nexport interface TLStateNodeConstructor {\n\tnew (editor: Editor, parent?: StateNode): StateNode\n\tid: string\n\tinitial?: string\n\tchildren?(): TLStateNodeConstructor[]\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n\ttrackPerformance: boolean\n}\n\n/** @public */\nexport abstract class StateNode implements Partial<TLEventHandlers> {\n\tperformanceTracker: PerformanceTracker\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tparent?: StateNode\n\t) {\n\t\tconst { id, children, initial, isLockable, useCoalescedEvents } = this\n\t\t\t.constructor as TLStateNodeConstructor\n\n\t\tthis.id = id\n\t\tthis._isActive = atom<boolean>('toolIsActive' + this.id, false)\n\t\tthis._current = atom<StateNode | undefined>('toolState' + this.id, undefined)\n\n\t\tthis._path = computed('toolPath' + this.id, () => {\n\t\t\tconst current = this.getCurrent()\n\t\t\treturn this.id + (current ? `.${current.getPath()}` : '')\n\t\t})\n\n\t\tthis.parent = parent ?? ({} as any)\n\n\t\tif (parent) {\n\t\t\tif (children && initial) {\n\t\t\t\tthis.type = 'branch'\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t} else {\n\t\t\t\tthis.type = 'leaf'\n\t\t\t}\n\t\t} else {\n\t\t\tthis.type = 'root'\n\n\t\t\tif (children && initial) {\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t}\n\t\t}\n\t\tthis.isLockable = isLockable\n\t\tthis.useCoalescedEvents = useCoalescedEvents\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tstatic id: string\n\tstatic initial?: string\n\tstatic children?: () => TLStateNodeConstructor[]\n\tstatic isLockable = true\n\tstatic useCoalescedEvents = false\n\t/** Set to `true` in subclasses to emit interaction-start/end performance events when this state is entered/exited. */\n\tstatic trackPerformance = false\n\n\tid: string\n\ttype: 'branch' | 'leaf' | 'root'\n\tshapeType?: string\n\tinitial?: string\n\tchildren?: Record<string, StateNode>\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n\tparent: StateNode\n\n\t/**\n\t * This node's path of active state nodes\n\t *\n\t * @public\n\t */\n\tgetPath() {\n\t\treturn this._path.get()\n\t}\n\t_path: Computed<string>\n\n\t/**\n\t * This node's current active child node, if any.\n\t *\n\t * @public\n\t */\n\tgetCurrent() {\n\t\treturn this._current.get()\n\t}\n\tprivate _current: Atom<StateNode | undefined>\n\n\t/**\n\t * Whether this node is active.\n\t *\n\t * @public\n\t */\n\tgetIsActive() {\n\t\treturn this._isActive.get()\n\t}\n\tprivate _isActive: Atom<boolean>\n\n\t/**\n\t * Transition to a new active child state node.\n\t *\n\t * @example\n\t * ```ts\n\t * parentState.transition('childStateA')\n\t * parentState.transition('childStateB', { myData: 4 })\n\t *```\n\t *\n\t * @param id - The id of the child state node to transition to.\n\t * @param info - Any data to pass to the `onEnter` and `onExit` handlers.\n\t *\n\t * @public\n\t */\n\ttransition(id: string, info: any = {}) {\n\t\tconst path = id.split('.')\n\n\t\tlet currState = this as StateNode\n\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tconst id = path[i]\n\t\t\tconst prevChildState = currState.getCurrent()\n\t\t\tconst nextChildState = currState.children?.[id]\n\n\t\t\tif (!nextChildState) {\n\t\t\t\tthrow Error(`${currState.id} - no child state exists with the id ${id}.`)\n\t\t\t}\n\n\t\t\tif (prevChildState?.id !== nextChildState.id) {\n\t\t\t\tprevChildState?.exit(info, id)\n\t\t\t\tcurrState._current.set(nextChildState)\n\t\t\t\tnextChildState.enter(info, prevChildState?.id || 'initial')\n\t\t\t\tif (!nextChildState.getIsActive()) break\n\t\t\t}\n\n\t\t\tcurrState = nextChildState\n\t\t}\n\n\t\treturn this\n\t}\n\n\thandleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>) {\n\t\tconst cbName = EVENT_NAME_MAP[info.name]\n\t\tconst currentActiveChild = this._current.__unsafe__getWithoutCapture()\n\n\t\tthis[cbName]?.(info as any)\n\t\tif (\n\t\t\tthis._isActive.__unsafe__getWithoutCapture() &&\n\t\t\tcurrentActiveChild &&\n\t\t\tcurrentActiveChild === this._current.__unsafe__getWithoutCapture()\n\t\t) {\n\t\t\tcurrentActiveChild.handleEvent(info)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\tenter(info: any, from: string) {\n\t\tconst track = (this.constructor as TLStateNodeConstructor).trackPerformance\n\t\tif (track) {\n\t\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\t\tthis.performanceTracker.start(this.id)\n\t\t\t}\n\t\t\tthis.editor.performance._notifyInteractionStart(this.id, this.getPath())\n\t\t}\n\n\t\tthis._isActive.set(true)\n\t\tthis.onEnter?.(info, from)\n\n\t\tif (this.children && this.initial && this.getIsActive()) {\n\t\t\tconst initial = this.children[this.initial]\n\t\t\tthis._current.set(initial)\n\t\t\tinitial.enter(info, from)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\texit(info: any, to: string) {\n\t\tconst track = (this.constructor as TLStateNodeConstructor).trackPerformance\n\t\tif (track) {\n\t\t\tif (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}\n\t\t\tthis.editor.performance._notifyInteractionEnd()\n\t\t}\n\n\t\tthis._isActive.set(false)\n\t\tthis.onExit?.(info, to)\n\n\t\tif (!this.getIsActive()) {\n\t\t\tthis.getCurrent()?.exit(info, to)\n\t\t}\n\t}\n\n\t/**\n\t * This is a hack / escape hatch that will tell the editor to\n\t * report a different state as active (in `getCurrentToolId()`) when\n\t * this state is active. This is usually used when a tool transitions\n\t * to a child of a different state for a certain interaction and then\n\t * returns to the original tool when that interaction completes; and\n\t * where we would want to show the original tool as active in the UI.\n\t *\n\t * @public\n\t */\n\t_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)\n\n\tgetCurrentToolIdMask() {\n\t\treturn this._currentToolIdMask.get()\n\t}\n\n\tsetCurrentToolIdMask(id: string | undefined) {\n\t\tthis._currentToolIdMask.set(id)\n\t}\n\n\t/**\n\t * Add a child node to this state node.\n\t *\n\t * @public\n\t */\n\taddChild(childConstructor: TLStateNodeConstructor): this {\n\t\tif (this.type === 'leaf') {\n\t\t\tthrow new Error('StateNode.addChild: cannot add child to a leaf node')\n\t\t}\n\n\t\t// Initialize children if it's undefined (for root nodes without static children)\n\t\tif (!this.children) {\n\t\t\tthis.children = {}\n\t\t}\n\n\t\tconst child = new childConstructor(this.editor, this)\n\n\t\t// Check if a child with this ID already exists\n\t\tif (this.children[child.id]) {\n\t\t\tthrow new Error(`StateNode.addChild: a child with id '${child.id}' already exists`)\n\t\t}\n\n\t\tthis.children[child.id] = child\n\t\treturn this\n\t}\n\n\tonWheel?(info: TLWheelEventInfo): void\n\tonPointerDown?(info: TLPointerEventInfo): void\n\tonPointerMove?(info: TLPointerEventInfo): void\n\tonLongPress?(info: TLPointerEventInfo): void\n\tonPointerUp?(info: TLPointerEventInfo): void\n\tonDoubleClick?(info: TLClickEventInfo): void\n\tonRightClick?(info: TLPointerEventInfo): void\n\tonMiddleClick?(info: TLPointerEventInfo): void\n\tonKeyDown?(info: TLKeyboardEventInfo): void\n\tonKeyUp?(info: TLKeyboardEventInfo): void\n\tonKeyRepeat?(info: TLKeyboardEventInfo): void\n\tonCancel?(info: TLCancelEventInfo): void\n\tonComplete?(info: TLCompleteEventInfo): void\n\tonInterrupt?(info: TLInterruptEventInfo): void\n\tonTick?(info: TLTickEventInfo): void\n\n\tonEnter?(info: any, from: string): void\n\tonExit?(info: any, to: string): void\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["id"]
7
7
  }
@@ -36,8 +36,6 @@ const EVENT_NAME_MAP = {
36
36
  complete: "onComplete",
37
37
  interrupt: "onInterrupt",
38
38
  double_click: "onDoubleClick",
39
- triple_click: "onTripleClick",
40
- quadruple_click: "onQuadrupleClick",
41
39
  tick: "onTick"
42
40
  };
43
41
  //# sourceMappingURL=event-types.js.map