@tldraw/editor 3.13.0-canary.d403fcffd1eb → 3.13.0-canary.d6fe56e14603
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.
- package/dist-cjs/index.d.ts +114 -111
- package/dist-cjs/index.js +7 -22
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +2 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +12 -8
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +27 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +14 -12
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +17 -11
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +58 -34
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager.js +10 -0
- package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js +12 -3
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +3 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +16 -15
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +8 -1
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +16 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Mat.js +1 -1
- package/dist-cjs/lib/primitives/Mat.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +20 -0
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +91 -20
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +55 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
- package/dist-cjs/lib/utils/areShapesContentEqual.js +25 -0
- package/dist-cjs/lib/utils/areShapesContentEqual.js.map +7 -0
- package/dist-cjs/lib/utils/debug-flags.js +5 -2
- package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +3 -3
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/nearestMultiple.js +34 -0
- package/dist-cjs/lib/utils/nearestMultiple.js.map +7 -0
- package/dist-cjs/lib/utils/rotation.js +5 -5
- package/dist-cjs/lib/utils/rotation.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +114 -111
- package/dist-esm/index.mjs +9 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +2 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +12 -8
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +27 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +14 -12
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +17 -11
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +58 -34
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager.mjs +10 -0
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +12 -3
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +3 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +16 -15
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +8 -1
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +16 -0
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Mat.mjs +1 -1
- package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +20 -0
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +92 -21
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +55 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
- package/dist-esm/lib/utils/areShapesContentEqual.mjs +5 -0
- package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +7 -0
- package/dist-esm/lib/utils/debug-flags.mjs +5 -2
- package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +3 -3
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/nearestMultiple.mjs +14 -0
- package/dist-esm/lib/utils/nearestMultiple.mjs.map +7 -0
- package/dist-esm/lib/utils/rotation.mjs +5 -5
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +40 -4
- package/package.json +7 -7
- package/src/index.ts +16 -31
- package/src/lib/TldrawEditor.tsx +6 -1
- package/src/lib/components/Shape.tsx +14 -10
- package/src/lib/components/default-components/DefaultCanvas.tsx +32 -2
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +25 -14
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +17 -8
- package/src/lib/components/default-components/DefaultSpinner.tsx +1 -1
- package/src/lib/editor/Editor.test.ts +1 -1
- package/src/lib/editor/Editor.ts +55 -33
- package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +0 -1
- package/src/lib/editor/managers/TextManager.ts +12 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +22 -2
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
- package/src/lib/exports/getSvgJsx.tsx +16 -7
- package/src/lib/hooks/useDocumentEvents.ts +7 -2
- package/src/lib/hooks/useEditorComponents.tsx +32 -28
- package/src/lib/license/LicenseManager.test.ts +40 -0
- package/src/lib/license/LicenseManager.ts +13 -1
- package/src/lib/options.ts +4 -0
- package/src/lib/primitives/Box.ts +20 -0
- package/src/lib/primitives/Mat.ts +5 -4
- package/src/lib/primitives/Vec.ts +23 -0
- package/src/lib/primitives/geometry/Arc2d.ts +5 -5
- package/src/lib/primitives/geometry/Circle2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
- package/src/lib/primitives/geometry/Edge2d.ts +3 -3
- package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
- package/src/lib/primitives/geometry/Geometry2d.test.ts +42 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +123 -35
- package/src/lib/primitives/geometry/Group2d.ts +70 -7
- package/src/lib/primitives/geometry/Point2d.ts +2 -2
- package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
- package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
- package/src/lib/test/currentToolIdMask.test.ts +1 -1
- package/src/lib/test/user.test.ts +1 -1
- package/src/lib/utils/areShapesContentEqual.ts +4 -0
- package/src/lib/utils/debug-flags.ts +7 -2
- package/src/lib/utils/dom.ts +4 -4
- package/src/lib/utils/nearestMultiple.ts +13 -0
- package/src/lib/utils/rotation.ts +8 -6
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
- package/src/version.ts +3 -3
package/editor.css
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
/* User handles need to be above selection edges / corners, matters for sticky note clone handles */
|
|
45
45
|
--layer-overlays-user-handles: 105;
|
|
46
46
|
--layer-overlays-user-indicator-hint: 110;
|
|
47
|
+
--layer-overlays-custom: 115;
|
|
47
48
|
--layer-overlays-collaborator-cursor-hint: 120;
|
|
48
49
|
--layer-overlays-collaborator-cursor: 130;
|
|
49
50
|
|
|
@@ -472,6 +473,10 @@ input,
|
|
|
472
473
|
stroke-width: calc(2.5px * var(--tl-scale));
|
|
473
474
|
}
|
|
474
475
|
|
|
476
|
+
.tl-custom-overlays {
|
|
477
|
+
z-index: var(--layer-overlays-custom);
|
|
478
|
+
}
|
|
479
|
+
|
|
475
480
|
/* behind collaborator cursor */
|
|
476
481
|
.tl-collaborator__cursor-hint {
|
|
477
482
|
z-index: var(--layer-overlays-collaborator-cursor-hint);
|
|
@@ -595,6 +600,31 @@ input,
|
|
|
595
600
|
}
|
|
596
601
|
}
|
|
597
602
|
|
|
603
|
+
/* --------------------- Arrow Hints -------------------- */
|
|
604
|
+
|
|
605
|
+
.tl-arrow-hint-handle {
|
|
606
|
+
fill: var(--color-selected-contrast);
|
|
607
|
+
stroke: var(--color-selection-stroke);
|
|
608
|
+
stroke-width: calc(1.5px * var(--tl-scale));
|
|
609
|
+
r: calc(4px * var(--tl-scale));
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.tl-arrow-hint-snap {
|
|
613
|
+
stroke: transparent;
|
|
614
|
+
fill: var(--color-selection-fill);
|
|
615
|
+
r: calc(12px * var(--tl-scale));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.tl-arrow-hint-snap__none,
|
|
619
|
+
.tl-arrow-hint-snap__center,
|
|
620
|
+
.tl-arrow-hint-snap__axis {
|
|
621
|
+
display: none;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
.tl-arrow-hint-snap__edge {
|
|
625
|
+
r: calc(8px * var(--tl-scale));
|
|
626
|
+
}
|
|
627
|
+
|
|
598
628
|
/* ------------------ Bounds Detail ----------------- */
|
|
599
629
|
|
|
600
630
|
.tl-image,
|
|
@@ -964,6 +994,8 @@ input,
|
|
|
964
994
|
|
|
965
995
|
.tl-rich-text p {
|
|
966
996
|
margin: 0;
|
|
997
|
+
/* Depending on the extensions, <p> tags can be empty, without a <br />. */
|
|
998
|
+
min-height: 1lh;
|
|
967
999
|
}
|
|
968
1000
|
|
|
969
1001
|
.tl-rich-text ul,
|
|
@@ -971,6 +1003,8 @@ input,
|
|
|
971
1003
|
text-align: left;
|
|
972
1004
|
margin: 0;
|
|
973
1005
|
padding-left: 3.25ch;
|
|
1006
|
+
/* Some resets, like Tailwind, nix the list styling. */
|
|
1007
|
+
list-style: revert;
|
|
974
1008
|
}
|
|
975
1009
|
|
|
976
1010
|
.tl-rich-text ol:has(> li:nth-child(10)) {
|
|
@@ -1348,10 +1382,6 @@ input,
|
|
|
1348
1382
|
opacity: 0;
|
|
1349
1383
|
}
|
|
1350
1384
|
|
|
1351
|
-
.tl-arrow-label[data-isediting='true'] > .tl-arrow-label__inner {
|
|
1352
|
-
background-color: var(--color-background);
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
1385
|
.tl-arrow-label__inner {
|
|
1356
1386
|
border-radius: var(--radius-1);
|
|
1357
1387
|
box-sizing: content-box;
|
|
@@ -1710,6 +1740,12 @@ it from receiving any pointer events or affecting the cursor. */
|
|
|
1710
1740
|
background-color: var(--color-primary);
|
|
1711
1741
|
color: var(--color-selected-contrast);
|
|
1712
1742
|
}
|
|
1743
|
+
.tl-container__focused:not(.tl-container__no-focus-ring)
|
|
1744
|
+
.tlui-button.tl-error-boundary__refresh:focus-visible {
|
|
1745
|
+
border-radius: 8px;
|
|
1746
|
+
outline-offset: 0;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1713
1749
|
/* --------------------- Coarse --------------------- */
|
|
1714
1750
|
|
|
1715
1751
|
.tl-hidden {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "A tiny little drawing app (editor).",
|
|
4
|
-
"version": "3.13.0-canary.
|
|
4
|
+
"version": "3.13.0-canary.d6fe56e14603",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"@tiptap/core": "^2.9.1",
|
|
49
49
|
"@tiptap/pm": "^2.9.1",
|
|
50
50
|
"@tiptap/react": "^2.9.1",
|
|
51
|
-
"@tldraw/state": "3.13.0-canary.
|
|
52
|
-
"@tldraw/state-react": "3.13.0-canary.
|
|
53
|
-
"@tldraw/store": "3.13.0-canary.
|
|
54
|
-
"@tldraw/tlschema": "3.13.0-canary.
|
|
55
|
-
"@tldraw/utils": "3.13.0-canary.
|
|
56
|
-
"@tldraw/validate": "3.13.0-canary.
|
|
51
|
+
"@tldraw/state": "3.13.0-canary.d6fe56e14603",
|
|
52
|
+
"@tldraw/state-react": "3.13.0-canary.d6fe56e14603",
|
|
53
|
+
"@tldraw/store": "3.13.0-canary.d6fe56e14603",
|
|
54
|
+
"@tldraw/tlschema": "3.13.0-canary.d6fe56e14603",
|
|
55
|
+
"@tldraw/utils": "3.13.0-canary.d6fe56e14603",
|
|
56
|
+
"@tldraw/validate": "3.13.0-canary.d6fe56e14603",
|
|
57
57
|
"@types/core-js": "^2.5.8",
|
|
58
58
|
"@use-gesture/react": "^10.3.1",
|
|
59
59
|
"classnames": "^2.5.1",
|
package/src/index.ts
CHANGED
|
@@ -4,37 +4,11 @@ import 'core-js/stable/array/flat-map.js'
|
|
|
4
4
|
import 'core-js/stable/array/flat.js'
|
|
5
5
|
import 'core-js/stable/string/at.js'
|
|
6
6
|
import 'core-js/stable/string/replace-all.js'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
react,
|
|
13
|
-
transact,
|
|
14
|
-
transaction,
|
|
15
|
-
whyAmIRunning,
|
|
16
|
-
type Atom,
|
|
17
|
-
type Signal,
|
|
18
|
-
} from '@tldraw/state'
|
|
19
|
-
export {
|
|
20
|
-
track,
|
|
21
|
-
useAtom,
|
|
22
|
-
useComputed,
|
|
23
|
-
useQuickReactor,
|
|
24
|
-
useReactor,
|
|
25
|
-
useStateTracking,
|
|
26
|
-
useValue,
|
|
27
|
-
} from '@tldraw/state-react'
|
|
28
|
-
export { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'
|
|
29
|
-
export {
|
|
30
|
-
getFontsFromRichText,
|
|
31
|
-
type RichTextFontVisitor,
|
|
32
|
-
type RichTextFontVisitorState,
|
|
33
|
-
type TLTextOptions,
|
|
34
|
-
type TiptapEditor,
|
|
35
|
-
type TiptapNode,
|
|
36
|
-
} from './lib/utils/richText'
|
|
37
|
-
export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line local/no-export-star
|
|
9
|
+
export * from '@tldraw/state'
|
|
10
|
+
// eslint-disable-next-line local/no-export-star
|
|
11
|
+
export * from '@tldraw/state-react'
|
|
38
12
|
// eslint-disable-next-line local/no-export-star
|
|
39
13
|
export * from '@tldraw/store'
|
|
40
14
|
// eslint-disable-next-line local/no-export-star
|
|
@@ -43,6 +17,7 @@ export * from '@tldraw/tlschema'
|
|
|
43
17
|
export * from '@tldraw/utils'
|
|
44
18
|
// eslint-disable-next-line local/no-export-star
|
|
45
19
|
export * from '@tldraw/validate'
|
|
20
|
+
|
|
46
21
|
export {
|
|
47
22
|
ErrorScreen,
|
|
48
23
|
LoadingScreen,
|
|
@@ -212,6 +187,7 @@ export {
|
|
|
212
187
|
export { GroupShapeUtil } from './lib/editor/shapes/group/GroupShapeUtil'
|
|
213
188
|
export { getPerfectDashProps } from './lib/editor/shapes/shared/getPerfectDashProps'
|
|
214
189
|
export { resizeBox, type ResizeBoxOptions } from './lib/editor/shapes/shared/resizeBox'
|
|
190
|
+
export { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'
|
|
215
191
|
export { BaseBoxShapeTool } from './lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool'
|
|
216
192
|
export { maybeSnapToGrid } from './lib/editor/tools/BaseBoxShapeTool/children/Pointing'
|
|
217
193
|
export { StateNode, type TLStateNodeConstructor } from './lib/editor/tools/StateNode'
|
|
@@ -459,12 +435,21 @@ export { hardResetEditor } from './lib/utils/hardResetEditor'
|
|
|
459
435
|
export { isAccelKey } from './lib/utils/keyboard'
|
|
460
436
|
export { normalizeWheel } from './lib/utils/normalizeWheel'
|
|
461
437
|
export { refreshPage } from './lib/utils/refreshPage'
|
|
438
|
+
export {
|
|
439
|
+
getFontsFromRichText,
|
|
440
|
+
type RichTextFontVisitor,
|
|
441
|
+
type RichTextFontVisitorState,
|
|
442
|
+
type TLTextOptions,
|
|
443
|
+
type TiptapEditor,
|
|
444
|
+
type TiptapNode,
|
|
445
|
+
} from './lib/utils/richText'
|
|
462
446
|
export {
|
|
463
447
|
applyRotationToSnapshotShapes,
|
|
464
448
|
getRotationSnapshot,
|
|
465
449
|
type TLRotationSnapshot,
|
|
466
450
|
} from './lib/utils/rotation'
|
|
467
451
|
export { runtime, setRuntimeOverrides } from './lib/utils/runtime'
|
|
452
|
+
export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
|
|
468
453
|
export { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'
|
|
469
454
|
export { hardReset } from './lib/utils/sync/hardReset'
|
|
470
455
|
export { uniq } from './lib/utils/uniq'
|
package/src/lib/TldrawEditor.tsx
CHANGED
|
@@ -285,6 +285,7 @@ export const TldrawEditor = memo(function TldrawEditor({
|
|
|
285
285
|
onPointerDown={stopEventPropagation}
|
|
286
286
|
tabIndex={-1}
|
|
287
287
|
role="application"
|
|
288
|
+
aria-label={_options?.branding ?? 'tldraw'}
|
|
288
289
|
>
|
|
289
290
|
<OptionalErrorBoundary
|
|
290
291
|
fallback={ErrorFallback}
|
|
@@ -669,7 +670,11 @@ export interface LoadingScreenProps {
|
|
|
669
670
|
|
|
670
671
|
/** @public @react */
|
|
671
672
|
export function LoadingScreen({ children }: LoadingScreenProps) {
|
|
672
|
-
return
|
|
673
|
+
return (
|
|
674
|
+
<div className="tl-loading" aria-busy="true" tabIndex={0}>
|
|
675
|
+
{children}
|
|
676
|
+
</div>
|
|
677
|
+
)
|
|
673
678
|
}
|
|
674
679
|
|
|
675
680
|
/** @public @react */
|
|
@@ -6,6 +6,7 @@ import { ShapeUtil } from '../editor/shapes/ShapeUtil'
|
|
|
6
6
|
import { useEditor } from '../hooks/useEditor'
|
|
7
7
|
import { useEditorComponents } from '../hooks/useEditorComponents'
|
|
8
8
|
import { Mat } from '../primitives/Mat'
|
|
9
|
+
import { areShapesContentEqual } from '../utils/areShapesContentEqual'
|
|
9
10
|
import { setStyleProperty } from '../utils/dom'
|
|
10
11
|
import { OptionalErrorBoundary } from './ErrorBoundary'
|
|
11
12
|
|
|
@@ -27,6 +28,7 @@ export const Shape = memo(function Shape({
|
|
|
27
28
|
index,
|
|
28
29
|
backgroundIndex,
|
|
29
30
|
opacity,
|
|
31
|
+
dprMultiple,
|
|
30
32
|
}: {
|
|
31
33
|
id: TLShapeId
|
|
32
34
|
shape: TLShape
|
|
@@ -34,6 +36,7 @@ export const Shape = memo(function Shape({
|
|
|
34
36
|
index: number
|
|
35
37
|
backgroundIndex: number
|
|
36
38
|
opacity: number
|
|
39
|
+
dprMultiple: number
|
|
37
40
|
}) {
|
|
38
41
|
const editor = useEditor()
|
|
39
42
|
|
|
@@ -88,14 +91,18 @@ export const Shape = memo(function Shape({
|
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
// Width / Height
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
// We round the shape width and height up to the nearest multiple of dprMultiple
|
|
95
|
+
// to avoid the browser making miscalculations when applying the transform.
|
|
96
|
+
const widthRemainder = bounds.w % dprMultiple
|
|
97
|
+
const heightRemainder = bounds.h % dprMultiple
|
|
98
|
+
const width = widthRemainder === 0 ? bounds.w : bounds.w + (dprMultiple - widthRemainder)
|
|
99
|
+
const height = heightRemainder === 0 ? bounds.h : bounds.h + (dprMultiple - heightRemainder)
|
|
93
100
|
|
|
94
101
|
if (width !== prev.width || height !== prev.height) {
|
|
95
|
-
setStyleProperty(containerRef.current, 'width', width + 'px')
|
|
96
|
-
setStyleProperty(containerRef.current, 'height', height + 'px')
|
|
97
|
-
setStyleProperty(bgContainerRef.current, 'width', width + 'px')
|
|
98
|
-
setStyleProperty(bgContainerRef.current, 'height', height + 'px')
|
|
102
|
+
setStyleProperty(containerRef.current, 'width', Math.max(width, dprMultiple) + 'px')
|
|
103
|
+
setStyleProperty(containerRef.current, 'height', Math.max(height, dprMultiple) + 'px')
|
|
104
|
+
setStyleProperty(bgContainerRef.current, 'width', Math.max(width, dprMultiple) + 'px')
|
|
105
|
+
setStyleProperty(bgContainerRef.current, 'height', Math.max(height, dprMultiple) + 'px')
|
|
99
106
|
prev.width = width
|
|
100
107
|
prev.height = height
|
|
101
108
|
}
|
|
@@ -184,10 +191,7 @@ export const InnerShape = memo(
|
|
|
184
191
|
[util, shape.id]
|
|
185
192
|
)
|
|
186
193
|
},
|
|
187
|
-
(prev, next) =>
|
|
188
|
-
prev.shape.props === next.shape.props &&
|
|
189
|
-
prev.shape.meta === next.shape.meta &&
|
|
190
|
-
prev.util === next.util
|
|
194
|
+
(prev, next) => areShapesContentEqual(prev.shape, next.shape) && prev.util === next.util
|
|
191
195
|
)
|
|
192
196
|
|
|
193
197
|
export const InnerShapeBackground = memo(
|
|
@@ -22,6 +22,7 @@ import { Vec } from '../../primitives/Vec'
|
|
|
22
22
|
import { toDomPrecision } from '../../primitives/utils'
|
|
23
23
|
import { debugFlags } from '../../utils/debug-flags'
|
|
24
24
|
import { setStyleProperty } from '../../utils/dom'
|
|
25
|
+
import { nearestMultiple } from '../../utils/nearestMultiple'
|
|
25
26
|
import { GeometryDebuggingView } from '../GeometryDebuggingView'
|
|
26
27
|
import { LiveCollaborators } from '../LiveCollaborators'
|
|
27
28
|
import { MenuClickCapture } from '../MenuClickCapture'
|
|
@@ -168,6 +169,7 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
|
|
|
168
169
|
<SnapIndicatorWrapper />
|
|
169
170
|
<SelectionForegroundWrapper />
|
|
170
171
|
<HandlesWrapper />
|
|
172
|
+
<OverlaysWrapper />
|
|
171
173
|
<LiveCollaborators />
|
|
172
174
|
</div>
|
|
173
175
|
</div>
|
|
@@ -372,14 +374,33 @@ function HandleWrapper({
|
|
|
372
374
|
)
|
|
373
375
|
}
|
|
374
376
|
|
|
377
|
+
function OverlaysWrapper() {
|
|
378
|
+
const { Overlays } = useEditorComponents()
|
|
379
|
+
if (!Overlays) return null
|
|
380
|
+
return (
|
|
381
|
+
<div className="tl-custom-overlays tl-overlays__item">
|
|
382
|
+
<Overlays />
|
|
383
|
+
</div>
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
|
|
375
387
|
function ShapesWithSVGs() {
|
|
376
388
|
const editor = useEditor()
|
|
377
389
|
|
|
378
390
|
const renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])
|
|
379
391
|
|
|
392
|
+
const dprMultiple = useValue(
|
|
393
|
+
'dpr multiple',
|
|
394
|
+
() =>
|
|
395
|
+
// dprMultiple is the smallest number we can multiply dpr by to get an integer
|
|
396
|
+
// it's usually 1, 2, or 4 (for e.g. dpr of 2, 2.5 and 2.25 respectively)
|
|
397
|
+
nearestMultiple(Math.floor(editor.getInstanceState().devicePixelRatio * 100) / 100),
|
|
398
|
+
[editor]
|
|
399
|
+
)
|
|
400
|
+
|
|
380
401
|
return renderingShapes.map((result) => (
|
|
381
402
|
<Fragment key={result.id + '_fragment'}>
|
|
382
|
-
<Shape {...result} />
|
|
403
|
+
<Shape {...result} dprMultiple={dprMultiple} />
|
|
383
404
|
<DebugSvgCopy id={result.id} mode="iframe" />
|
|
384
405
|
</Fragment>
|
|
385
406
|
))
|
|
@@ -414,10 +435,19 @@ function ShapesToDisplay() {
|
|
|
414
435
|
|
|
415
436
|
const renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])
|
|
416
437
|
|
|
438
|
+
const dprMultiple = useValue(
|
|
439
|
+
'dpr multiple',
|
|
440
|
+
() =>
|
|
441
|
+
// dprMultiple is the smallest number we can multiply dpr by to get an integer
|
|
442
|
+
// it's usually 1, 2, or 4 (for e.g. dpr of 2, 2.5 and 2.25 respectively)
|
|
443
|
+
nearestMultiple(Math.floor(editor.getInstanceState().devicePixelRatio * 100) / 100),
|
|
444
|
+
[editor]
|
|
445
|
+
)
|
|
446
|
+
|
|
417
447
|
return (
|
|
418
448
|
<>
|
|
419
449
|
{renderingShapes.map((result) => (
|
|
420
|
-
<Shape key={result.id + '_shape'} {...result} />
|
|
450
|
+
<Shape key={result.id + '_shape'} {...result} dprMultiple={dprMultiple} />
|
|
421
451
|
))}
|
|
422
452
|
{tlenv.isSafari && <ReflowIfNeeded />}
|
|
423
453
|
</>
|
|
@@ -157,8 +157,10 @@ My browser: ${navigator.userAgent}`
|
|
|
157
157
|
<h2>Are you sure?</h2>
|
|
158
158
|
<p>Resetting your data will delete your drawing and cannot be undone.</p>
|
|
159
159
|
<div className="tl-error-boundary__content__actions">
|
|
160
|
-
<button onClick={() => setShouldShowResetConfirmation(false)}>
|
|
161
|
-
|
|
160
|
+
<button className="tlui-button" onClick={() => setShouldShowResetConfirmation(false)}>
|
|
161
|
+
Cancel
|
|
162
|
+
</button>
|
|
163
|
+
<button className="tlui-button tl-error-boundary__reset" onClick={resetLocalState}>
|
|
162
164
|
Reset data
|
|
163
165
|
</button>
|
|
164
166
|
</div>
|
|
@@ -166,16 +168,23 @@ My browser: ${navigator.userAgent}`
|
|
|
166
168
|
) : (
|
|
167
169
|
<>
|
|
168
170
|
<h2>Something went wrong</h2>
|
|
169
|
-
<p>Please refresh
|
|
171
|
+
<p>Please refresh your browser.</p>
|
|
172
|
+
<p>
|
|
173
|
+
If the issue continues after refreshing, you may need to reset the tldraw data stored
|
|
174
|
+
on your device.
|
|
175
|
+
</p>
|
|
170
176
|
<p>
|
|
171
|
-
|
|
172
|
-
<a href={url.toString()}>GitHub issue</a> or ask for help on{' '}
|
|
173
|
-
<a href="https://discord.tldraw.com/?utm_source=sdk&utm_medium=organic&utm_campaign=error-screen">
|
|
174
|
-
Discord
|
|
175
|
-
</a>
|
|
176
|
-
. If you are still stuck, you can reset the tldraw data on your machine. This may
|
|
177
|
-
erase the project you were working on, so try to get help first.
|
|
177
|
+
<strong>Note:</strong> Resetting will erase your current project and any unsaved work.
|
|
178
178
|
</p>
|
|
179
|
+
{process.env.NODE_ENV !== 'production' && (
|
|
180
|
+
<p>
|
|
181
|
+
If you're developing with the SDK and need help, join us on{' '}
|
|
182
|
+
<a href="https://discord.tldraw.com/?utm_source=sdk&utm_medium=organic&utm_campaign=error-screen">
|
|
183
|
+
Discord
|
|
184
|
+
</a>
|
|
185
|
+
.
|
|
186
|
+
</p>
|
|
187
|
+
)}
|
|
179
188
|
{shouldShowError && (
|
|
180
189
|
<>
|
|
181
190
|
Message:
|
|
@@ -187,22 +196,24 @@ My browser: ${navigator.userAgent}`
|
|
|
187
196
|
<pre>
|
|
188
197
|
<code>{errorStack ?? errorMessage}</code>
|
|
189
198
|
</pre>
|
|
190
|
-
<button onClick={copyError}>
|
|
199
|
+
<button className="tlui-button" onClick={copyError}>
|
|
200
|
+
{didCopy ? 'Copied!' : 'Copy'}
|
|
201
|
+
</button>
|
|
191
202
|
</div>
|
|
192
203
|
</>
|
|
193
204
|
)}
|
|
194
205
|
<div className="tl-error-boundary__content__actions">
|
|
195
|
-
<button onClick={() => setShouldShowError(!shouldShowError)}>
|
|
206
|
+
<button className="tlui-button" onClick={() => setShouldShowError(!shouldShowError)}>
|
|
196
207
|
{shouldShowError ? 'Hide details' : 'Show details'}
|
|
197
208
|
</button>
|
|
198
209
|
<div className="tl-error-boundary__content__actions__group">
|
|
199
210
|
<button
|
|
200
|
-
className="tl-error-boundary__reset"
|
|
211
|
+
className="tlui-button tl-error-boundary__reset"
|
|
201
212
|
onClick={() => setShouldShowResetConfirmation(true)}
|
|
202
213
|
>
|
|
203
214
|
Reset data
|
|
204
215
|
</button>
|
|
205
|
-
<button className="tl-error-boundary__refresh" onClick={refresh}>
|
|
216
|
+
<button className="tlui-button tl-error-boundary__refresh" onClick={refresh}>
|
|
206
217
|
Refresh Page
|
|
207
218
|
</button>
|
|
208
219
|
</div>
|
|
@@ -9,13 +9,21 @@ import { useEditorComponents } from '../../hooks/useEditorComponents'
|
|
|
9
9
|
import { OptionalErrorBoundary } from '../ErrorBoundary'
|
|
10
10
|
|
|
11
11
|
// need an extra layer of indirection here to allow hooks to be used inside the indicator render
|
|
12
|
-
const EvenInnererIndicator = memo(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
const EvenInnererIndicator = memo(
|
|
13
|
+
({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {
|
|
14
|
+
return useStateTracking('Indicator: ' + shape.type, () =>
|
|
15
|
+
// always fetch the latest shape from the store even if the props/meta have not changed, to avoid
|
|
16
|
+
// calling the render method with stale data.
|
|
17
|
+
util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)
|
|
18
|
+
)
|
|
19
|
+
},
|
|
20
|
+
(prevProps, nextProps) => {
|
|
21
|
+
return (
|
|
22
|
+
prevProps.shape.props === nextProps.shape.props &&
|
|
23
|
+
prevProps.shape.meta === nextProps.shape.meta
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
)
|
|
19
27
|
|
|
20
28
|
const InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId }) => {
|
|
21
29
|
const shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])
|
|
@@ -61,13 +69,14 @@ export const DefaultShapeIndicator = memo(function DefaultShapeIndicator({
|
|
|
61
69
|
useQuickReactor(
|
|
62
70
|
'indicator transform',
|
|
63
71
|
() => {
|
|
72
|
+
if (hidden) return
|
|
64
73
|
const elm = rIndicator.current
|
|
65
74
|
if (!elm) return
|
|
66
75
|
const pageTransform = editor.getShapePageTransform(shapeId)
|
|
67
76
|
if (!pageTransform) return
|
|
68
77
|
elm.style.setProperty('transform', pageTransform.toCssString())
|
|
69
78
|
},
|
|
70
|
-
[editor, shapeId]
|
|
79
|
+
[editor, shapeId, hidden]
|
|
71
80
|
)
|
|
72
81
|
|
|
73
82
|
useLayoutEffect(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @public @react */
|
|
2
2
|
export function DefaultSpinner() {
|
|
3
3
|
return (
|
|
4
|
-
<svg width={16} height={16} viewBox="0 0 16 16">
|
|
4
|
+
<svg width={16} height={16} viewBox="0 0 16 16" aria-hidden="false">
|
|
5
5
|
<g strokeWidth={2} fill="none" fillRule="evenodd">
|
|
6
6
|
<circle strokeOpacity={0.25} cx={8} cy={8} r={7} stroke="currentColor" />
|
|
7
7
|
<path strokeLinecap="round" d="M15 8c0-4.5-4.5-7-7-7" stroke="currentColor">
|
|
@@ -52,7 +52,7 @@ beforeEach(() => {
|
|
|
52
52
|
shapeUtils: [CustomShape],
|
|
53
53
|
bindingUtils: [],
|
|
54
54
|
tools: [],
|
|
55
|
-
store: createTLStore({ shapeUtils: [CustomShape] }),
|
|
55
|
+
store: createTLStore({ shapeUtils: [CustomShape], bindingUtils: [] }),
|
|
56
56
|
getContainer: () => document.body,
|
|
57
57
|
})
|
|
58
58
|
editor.setCameraOptions({ isLocked: true })
|