@tldraw/editor 3.11.0-canary.de52f4d709d2 → 3.11.0-canary.e0e5f2c27ecc
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/CHANGELOG.md +2 -2
- package/dist-cjs/index.d.ts +17 -9
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +4 -4
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +34 -26
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/config/TLUserPreferences.js +1 -1
- package/dist-cjs/lib/config/TLUserPreferences.js.map +1 -1
- package/dist-cjs/lib/config/createTLStore.js +2 -1
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/constants.js +1 -1
- package/dist-cjs/lib/constants.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +18 -14
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/FocusManager.js +15 -0
- package/dist-cjs/lib/editor/managers/FocusManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager.js +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/exports/StyleEmbedder.js +16 -1
- package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
- package/dist-cjs/lib/exports/exportToSvg.js.map +1 -1
- package/dist-cjs/lib/exports/parseCss.js +27 -2
- package/dist-cjs/lib/exports/parseCss.js.map +2 -2
- package/dist-cjs/lib/hooks/useLocalStore.js +3 -0
- package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +5 -0
- package/dist-cjs/lib/license/Watermark.js.map +2 -2
- package/dist-cjs/lib/utils/sync/LocalIndexedDb.js +8 -0
- package/dist-cjs/lib/utils/sync/LocalIndexedDb.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 +17 -9
- package/dist-esm/index.mjs +4 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +4 -4
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +34 -26
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +1 -1
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +1 -1
- package/dist-esm/lib/config/createTLStore.mjs +2 -1
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/constants.mjs +1 -1
- package/dist-esm/lib/constants.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +18 -14
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/FocusManager.mjs +15 -0
- package/dist-esm/lib/editor/managers/FocusManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/exports/StyleEmbedder.mjs +22 -2
- package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
- package/dist-esm/lib/exports/exportToSvg.mjs.map +1 -1
- package/dist-esm/lib/exports/parseCss.mjs +27 -2
- package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
- package/dist-esm/lib/hooks/useLocalStore.mjs +3 -0
- package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +5 -0
- package/dist-esm/lib/license/Watermark.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/LocalIndexedDb.mjs +8 -0
- package/dist-esm/lib/utils/sync/LocalIndexedDb.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +10 -1
- package/package.json +10 -7
- package/src/index.ts +4 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +4 -4
- package/src/lib/components/default-components/DefaultShapeIndicators.tsx +52 -31
- package/src/lib/config/TLUserPreferences.ts +1 -1
- package/src/lib/config/createTLStore.ts +1 -0
- package/src/lib/constants.ts +1 -1
- package/src/lib/editor/Editor.ts +20 -17
- package/src/lib/editor/managers/FocusManager.ts +18 -0
- package/src/lib/editor/managers/UserPreferencesManager.ts +1 -1
- package/src/lib/exports/StyleEmbedder.ts +23 -4
- package/src/lib/exports/exportToSvg.tsx +1 -1
- package/src/lib/exports/parseCss.ts +36 -2
- package/src/lib/hooks/useLocalStore.ts +3 -0
- package/src/lib/license/Watermark.tsx +5 -0
- package/src/lib/utils/sync/LocalIndexedDb.ts +9 -0
- package/src/version.ts +3 -3
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "3.11.0-canary.
|
|
1
|
+
const version = "3.11.0-canary.e0e5f2c27ecc";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2024-09-13T14:36:29.063Z",
|
|
4
|
-
minor: "2025-03-
|
|
5
|
-
patch: "2025-03-
|
|
4
|
+
minor: "2025-03-20T12:02:56.724Z",
|
|
5
|
+
patch: "2025-03-20T12:02:56.724Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.11.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.11.0-canary.e0e5f2c27ecc'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-20T12:02:56.724Z',\n\tpatch: '2025-03-20T12:02:56.724Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/editor.css
CHANGED
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
--color-panel-contrast: hsl(0, 0%, 100%);
|
|
148
148
|
--color-panel-overlay: hsl(0, 0%, 100%, 82%);
|
|
149
149
|
--color-panel: hsl(0, 0%, 99%);
|
|
150
|
-
--color-focus: hsl(
|
|
150
|
+
--color-focus: hsl(219, 65%, 50%);
|
|
151
151
|
--color-selected: hsl(214, 84%, 56%);
|
|
152
152
|
--color-selected-contrast: hsl(0, 0%, 100%);
|
|
153
153
|
--color-selection-fill: hsl(210, 100%, 56%, 24%);
|
|
@@ -953,6 +953,15 @@ input,
|
|
|
953
953
|
.tl-rich-text ol {
|
|
954
954
|
text-align: left;
|
|
955
955
|
margin: 0;
|
|
956
|
+
padding-left: 3.25ch;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
.tl-rich-text ol:has(> li:nth-child(10)) {
|
|
960
|
+
padding-left: 4.25ch;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
.tl-rich-text ol:has(> li:nth-child(100)) {
|
|
964
|
+
padding-left: 5.25ch;
|
|
956
965
|
}
|
|
957
966
|
|
|
958
967
|
.tl-rich-text h1,
|
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.11.0-canary.
|
|
4
|
+
"version": "3.11.0-canary.e0e5f2c27ecc",
|
|
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.11.0-canary.
|
|
52
|
-
"@tldraw/state-react": "3.11.0-canary.
|
|
53
|
-
"@tldraw/store": "3.11.0-canary.
|
|
54
|
-
"@tldraw/tlschema": "3.11.0-canary.
|
|
55
|
-
"@tldraw/utils": "3.11.0-canary.
|
|
56
|
-
"@tldraw/validate": "3.11.0-canary.
|
|
51
|
+
"@tldraw/state": "3.11.0-canary.e0e5f2c27ecc",
|
|
52
|
+
"@tldraw/state-react": "3.11.0-canary.e0e5f2c27ecc",
|
|
53
|
+
"@tldraw/store": "3.11.0-canary.e0e5f2c27ecc",
|
|
54
|
+
"@tldraw/tlschema": "3.11.0-canary.e0e5f2c27ecc",
|
|
55
|
+
"@tldraw/utils": "3.11.0-canary.e0e5f2c27ecc",
|
|
56
|
+
"@tldraw/validate": "3.11.0-canary.e0e5f2c27ecc",
|
|
57
57
|
"@types/core-js": "^2.5.8",
|
|
58
58
|
"@use-gesture/react": "^10.3.1",
|
|
59
59
|
"classnames": "^2.5.1",
|
|
@@ -72,12 +72,15 @@
|
|
|
72
72
|
"@testing-library/jest-dom": "^5.17.0",
|
|
73
73
|
"@testing-library/react": "^15.0.7",
|
|
74
74
|
"@types/benchmark": "^2.1.5",
|
|
75
|
+
"@types/react": "^18.3.18",
|
|
75
76
|
"@types/wicg-file-system-access": "^2020.9.8",
|
|
76
77
|
"benchmark": "^2.1.4",
|
|
77
78
|
"fake-indexeddb": "^4.0.2",
|
|
78
79
|
"jest-canvas-mock": "^2.5.2",
|
|
79
80
|
"jest-environment-jsdom": "^29.7.0",
|
|
80
81
|
"lazyrepo": "0.0.0-alpha.27",
|
|
82
|
+
"react": "^18.3.1",
|
|
83
|
+
"react-dom": "^18.3.1",
|
|
81
84
|
"resize-observer-polyfill": "^1.5.1"
|
|
82
85
|
},
|
|
83
86
|
"jest": {
|
package/src/index.ts
CHANGED
|
@@ -109,7 +109,10 @@ export {
|
|
|
109
109
|
type TLShapeIndicatorProps,
|
|
110
110
|
} from './lib/components/default-components/DefaultShapeIndicator'
|
|
111
111
|
export { type TLShapeIndicatorErrorFallbackComponent } from './lib/components/default-components/DefaultShapeIndicatorErrorFallback'
|
|
112
|
-
export {
|
|
112
|
+
export {
|
|
113
|
+
DefaultShapeIndicators,
|
|
114
|
+
type TLShapeIndicatorsProps,
|
|
115
|
+
} from './lib/components/default-components/DefaultShapeIndicators'
|
|
113
116
|
export {
|
|
114
117
|
DefaultSnapIndicator,
|
|
115
118
|
type TLSnapIndicatorProps,
|
|
@@ -9,15 +9,15 @@ 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 = ({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {
|
|
12
|
+
const EvenInnererIndicator = memo(({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {
|
|
13
13
|
return useStateTracking('Indicator: ' + shape.type, () =>
|
|
14
14
|
// always fetch the latest shape from the store even if the props/meta have not changed, to avoid
|
|
15
15
|
// calling the render method with stale data.
|
|
16
16
|
util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)
|
|
17
17
|
)
|
|
18
|
-
}
|
|
18
|
+
})
|
|
19
19
|
|
|
20
|
-
const InnerIndicator = ({ editor, id }: { editor: Editor; id: TLShapeId }) => {
|
|
20
|
+
const InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId }) => {
|
|
21
21
|
const shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])
|
|
22
22
|
|
|
23
23
|
const { ShapeIndicatorErrorFallback } = useEditorComponents()
|
|
@@ -34,7 +34,7 @@ const InnerIndicator = ({ editor, id }: { editor: Editor; id: TLShapeId }) => {
|
|
|
34
34
|
<EvenInnererIndicator key={shape.id} shape={shape} util={editor.getShapeUtil(shape)} />
|
|
35
35
|
</OptionalErrorBoundary>
|
|
36
36
|
)
|
|
37
|
-
}
|
|
37
|
+
})
|
|
38
38
|
|
|
39
39
|
/** @public */
|
|
40
40
|
export interface TLShapeIndicatorProps {
|
|
@@ -4,10 +4,24 @@ import { memo, useRef } from 'react'
|
|
|
4
4
|
import { useEditor } from '../../hooks/useEditor'
|
|
5
5
|
import { useEditorComponents } from '../../hooks/useEditorComponents'
|
|
6
6
|
|
|
7
|
+
/** @public */
|
|
8
|
+
export interface TLShapeIndicatorsProps {
|
|
9
|
+
/** Whether to hide all of the indicators */
|
|
10
|
+
hideAll?: boolean
|
|
11
|
+
/** Whether to show all of the indicators */
|
|
12
|
+
showAll?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
/** @public @react */
|
|
8
|
-
export const DefaultShapeIndicators = memo(function DefaultShapeIndicators(
|
|
16
|
+
export const DefaultShapeIndicators = memo(function DefaultShapeIndicators({
|
|
17
|
+
hideAll,
|
|
18
|
+
showAll,
|
|
19
|
+
}: TLShapeIndicatorsProps) {
|
|
9
20
|
const editor = useEditor()
|
|
10
21
|
|
|
22
|
+
if (hideAll && showAll)
|
|
23
|
+
throw Error('You cannot set both hideAll and showAll props to true, cmon now')
|
|
24
|
+
|
|
11
25
|
const rPreviousSelectedShapeIds = useRef<Set<TLShapeId>>(new Set())
|
|
12
26
|
|
|
13
27
|
const idsToDisplay = useValue(
|
|
@@ -16,34 +30,38 @@ export const DefaultShapeIndicators = memo(function DefaultShapeIndicators() {
|
|
|
16
30
|
const prev = rPreviousSelectedShapeIds.current
|
|
17
31
|
const next = new Set<TLShapeId>()
|
|
18
32
|
|
|
19
|
-
|
|
20
|
-
// We only show indicators when in the following states...
|
|
21
|
-
editor.isInAny(
|
|
22
|
-
'select.idle',
|
|
23
|
-
'select.brushing',
|
|
24
|
-
'select.scribble_brushing',
|
|
25
|
-
'select.editing_shape',
|
|
26
|
-
'select.pointing_shape',
|
|
27
|
-
'select.pointing_selection',
|
|
28
|
-
'select.pointing_handle'
|
|
29
|
-
) &&
|
|
30
|
-
// ...but we hide indicators when we've just changed a style (so that the user can see the change)
|
|
31
|
-
!editor.getInstanceState().isChangingStyle
|
|
32
|
-
) {
|
|
33
|
-
// We always want to show indicators for the selected shapes, if any
|
|
34
|
-
const selected = editor.getSelectedShapeIds()
|
|
35
|
-
for (const id of selected) {
|
|
36
|
-
next.add(id)
|
|
37
|
-
}
|
|
33
|
+
const instanceState = editor.getInstanceState()
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
const isChangingStyle = instanceState.isChangingStyle
|
|
36
|
+
|
|
37
|
+
// todo: this is tldraw specific and is duplicated at the tldraw layer. What should we do here instead?
|
|
38
|
+
|
|
39
|
+
const isIdleOrEditing = editor.isInAny('select.idle', 'select.editing_shape')
|
|
40
|
+
|
|
41
|
+
const isInSelectState = editor.isInAny(
|
|
42
|
+
'select.brushing',
|
|
43
|
+
'select.scribble_brushing',
|
|
44
|
+
'select.pointing_shape',
|
|
45
|
+
'select.pointing_selection',
|
|
46
|
+
'select.pointing_handle'
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
// We hide all indicators if we're changing style or in certain interactions
|
|
50
|
+
// todo: move this to some kind of Tool.hideIndicators property
|
|
51
|
+
if (isChangingStyle || !(isIdleOrEditing || isInSelectState)) {
|
|
52
|
+
rPreviousSelectedShapeIds.current = next
|
|
53
|
+
return next
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// We always want to show indicators for the selected shapes, if any
|
|
57
|
+
for (const id of editor.getSelectedShapeIds()) {
|
|
58
|
+
next.add(id)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// If we're idle or editing a shape, we want to also show an indicator for the hovered shape, if any
|
|
62
|
+
if (isIdleOrEditing && instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) {
|
|
63
|
+
const hovered = editor.getHoveredShapeId()
|
|
64
|
+
if (hovered) next.add(hovered)
|
|
47
65
|
}
|
|
48
66
|
|
|
49
67
|
// Ok, has anything changed?
|
|
@@ -54,7 +72,7 @@ export const DefaultShapeIndicators = memo(function DefaultShapeIndicators() {
|
|
|
54
72
|
return next
|
|
55
73
|
}
|
|
56
74
|
|
|
57
|
-
//
|
|
75
|
+
// Set difference check
|
|
58
76
|
for (const id of next) {
|
|
59
77
|
if (!prev.has(id)) {
|
|
60
78
|
rPreviousSelectedShapeIds.current = next
|
|
@@ -62,7 +80,6 @@ export const DefaultShapeIndicators = memo(function DefaultShapeIndicators() {
|
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
82
|
|
|
65
|
-
// If nothing has changed, then return the previous value
|
|
66
83
|
return prev
|
|
67
84
|
},
|
|
68
85
|
[editor]
|
|
@@ -75,6 +92,10 @@ export const DefaultShapeIndicators = memo(function DefaultShapeIndicators() {
|
|
|
75
92
|
if (!ShapeIndicator) return null
|
|
76
93
|
|
|
77
94
|
return renderingShapes.map(({ id }) => (
|
|
78
|
-
<ShapeIndicator
|
|
95
|
+
<ShapeIndicator
|
|
96
|
+
key={id + '_indicator'}
|
|
97
|
+
shapeId={id}
|
|
98
|
+
hidden={!showAll && (hideAll || !idsToDisplay.has(id))}
|
|
99
|
+
/>
|
|
79
100
|
))
|
|
80
101
|
})
|
package/src/lib/constants.ts
CHANGED
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -2102,12 +2102,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2102
2102
|
* @public
|
|
2103
2103
|
*/
|
|
2104
2104
|
setRichTextEditor(textEditor: TiptapEditor | null) {
|
|
2105
|
-
// If the new editor is different from the current one, destroy the current one
|
|
2106
|
-
const current = this._currentRichTextEditor.__unsafe__getWithoutCapture()
|
|
2107
|
-
if (current !== textEditor) {
|
|
2108
|
-
current?.destroy()
|
|
2109
|
-
}
|
|
2110
|
-
|
|
2111
2105
|
this._currentRichTextEditor.set(textEditor)
|
|
2112
2106
|
return this
|
|
2113
2107
|
}
|
|
@@ -4218,7 +4212,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4218
4212
|
: (assets as TLAsset[]).map((a) => a.id)
|
|
4219
4213
|
if (ids.length <= 0) return this
|
|
4220
4214
|
|
|
4221
|
-
this.run(
|
|
4215
|
+
this.run(
|
|
4216
|
+
() => {
|
|
4217
|
+
this.store.props.assets.remove?.(ids)
|
|
4218
|
+
this.store.remove(ids)
|
|
4219
|
+
},
|
|
4220
|
+
{ history: 'ignore' }
|
|
4221
|
+
)
|
|
4222
4222
|
return this
|
|
4223
4223
|
}
|
|
4224
4224
|
|
|
@@ -6328,21 +6328,22 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6328
6328
|
*
|
|
6329
6329
|
* @example
|
|
6330
6330
|
* ```ts
|
|
6331
|
-
* editor.stackShapes([box1, box2], 'horizontal'
|
|
6332
|
-
* editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal'
|
|
6331
|
+
* editor.stackShapes([box1, box2], 'horizontal')
|
|
6332
|
+
* editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal')
|
|
6333
6333
|
* ```
|
|
6334
6334
|
*
|
|
6335
6335
|
* @param shapes - The shapes (or shape ids) to stack.
|
|
6336
6336
|
* @param operation - Whether to stack horizontally or vertically.
|
|
6337
|
-
* @param gap - The gap to leave between shapes.
|
|
6337
|
+
* @param gap - The gap to leave between shapes. By default, uses the editor's `adjacentShapeMargin` option.
|
|
6338
6338
|
*
|
|
6339
6339
|
* @public
|
|
6340
6340
|
*/
|
|
6341
6341
|
stackShapes(
|
|
6342
6342
|
shapes: TLShapeId[] | TLShape[],
|
|
6343
6343
|
operation: 'horizontal' | 'vertical',
|
|
6344
|
-
gap
|
|
6344
|
+
gap?: number
|
|
6345
6345
|
): this {
|
|
6346
|
+
const _gap = gap ?? this.options.adjacentShapeMargin
|
|
6346
6347
|
const ids =
|
|
6347
6348
|
typeof shapes[0] === 'string'
|
|
6348
6349
|
? (shapes as TLShapeId[])
|
|
@@ -6400,7 +6401,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6400
6401
|
}
|
|
6401
6402
|
|
|
6402
6403
|
const len = shapeClustersToStack.length
|
|
6403
|
-
if ((
|
|
6404
|
+
if ((_gap === 0 && len < 3) || len < 2) return this
|
|
6404
6405
|
|
|
6405
6406
|
let val: 'x' | 'y'
|
|
6406
6407
|
let min: 'minX' | 'minY'
|
|
@@ -6421,7 +6422,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6421
6422
|
|
|
6422
6423
|
let shapeGap: number = 0
|
|
6423
6424
|
|
|
6424
|
-
if (
|
|
6425
|
+
if (_gap === 0) {
|
|
6425
6426
|
// note: this is not used in the current tldraw.com; there we use a specified stack
|
|
6426
6427
|
|
|
6427
6428
|
const gaps: Record<number, number> = {}
|
|
@@ -6461,7 +6462,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6461
6462
|
}
|
|
6462
6463
|
} else {
|
|
6463
6464
|
// If a gap was provided, then use that instead.
|
|
6464
|
-
shapeGap =
|
|
6465
|
+
shapeGap = _gap
|
|
6465
6466
|
}
|
|
6466
6467
|
|
|
6467
6468
|
const changes: TLShapePartial[] = []
|
|
@@ -6500,17 +6501,19 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6500
6501
|
*
|
|
6501
6502
|
* @example
|
|
6502
6503
|
* ```ts
|
|
6503
|
-
* editor.packShapes([box1, box2]
|
|
6504
|
+
* editor.packShapes([box1, box2])
|
|
6504
6505
|
* editor.packShapes(editor.getSelectedShapeIds(), 32)
|
|
6505
6506
|
* ```
|
|
6506
6507
|
*
|
|
6507
6508
|
*
|
|
6508
6509
|
* @param shapes - The shapes (or shape ids) to pack.
|
|
6509
|
-
* @param gap - The padding to apply to the packed shapes. Defaults to
|
|
6510
|
+
* @param gap - The padding to apply to the packed shapes. Defaults to the editor's `adjacentShapeMargin` option.
|
|
6510
6511
|
*/
|
|
6511
|
-
packShapes(shapes: TLShapeId[] | TLShape[],
|
|
6512
|
+
packShapes(shapes: TLShapeId[] | TLShape[], _gap?: number): this {
|
|
6512
6513
|
if (this.getIsReadonly()) return this
|
|
6513
6514
|
|
|
6515
|
+
const gap = _gap ?? this.options.adjacentShapeMargin
|
|
6516
|
+
|
|
6514
6517
|
const ids =
|
|
6515
6518
|
typeof shapes[0] === 'string'
|
|
6516
6519
|
? (shapes as TLShapeId[])
|
|
@@ -30,6 +30,9 @@ export class FocusManager {
|
|
|
30
30
|
editor.updateInstanceState({ isFocused: !!autoFocus })
|
|
31
31
|
}
|
|
32
32
|
this.updateContainerClass()
|
|
33
|
+
|
|
34
|
+
document.body.addEventListener('keydown', this.handleKeyDown.bind(this))
|
|
35
|
+
document.body.addEventListener('mousedown', this.handleMouseDown.bind(this))
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
/**
|
|
@@ -50,6 +53,19 @@ export class FocusManager {
|
|
|
50
53
|
} else {
|
|
51
54
|
container.classList.remove('tl-container__focused')
|
|
52
55
|
}
|
|
56
|
+
container.classList.add('tl-container__no-focus-ring')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private handleKeyDown(keyEvent: KeyboardEvent) {
|
|
60
|
+
const container = this.editor.getContainer()
|
|
61
|
+
if (keyEvent.key === 'Tab') {
|
|
62
|
+
container.classList.remove('tl-container__no-focus-ring')
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private handleMouseDown() {
|
|
67
|
+
const container = this.editor.getContainer()
|
|
68
|
+
container.classList.add('tl-container__no-focus-ring')
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
focus() {
|
|
@@ -62,6 +78,8 @@ export class FocusManager {
|
|
|
62
78
|
}
|
|
63
79
|
|
|
64
80
|
dispose() {
|
|
81
|
+
document.body.removeEventListener('keydown', this.handleKeyDown.bind(this))
|
|
82
|
+
document.body.removeEventListener('mousedown', this.handleMouseDown.bind(this))
|
|
65
83
|
this.disposeSideEffectListener?.()
|
|
66
84
|
}
|
|
67
85
|
}
|
|
@@ -80,7 +80,7 @@ export class UserPreferencesManager {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
@computed getName() {
|
|
83
|
-
return this.user.userPreferences.get().name ?? defaultUserPreferences.name
|
|
83
|
+
return this.user.userPreferences.get().name?.trim() ?? defaultUserPreferences.name
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
@computed getLocale() {
|
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
getRenderedChildren,
|
|
8
8
|
} from './domUtils'
|
|
9
9
|
import { resourceToDataUrl } from './fetchCache'
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
isPropertyCoveredByCurrentColor,
|
|
12
|
+
isPropertyInherited,
|
|
13
|
+
parseCssValueUrls,
|
|
14
|
+
shouldIncludeCssProperty,
|
|
15
|
+
} from './parseCss'
|
|
11
16
|
|
|
12
17
|
type Styles = { [K in string]?: string }
|
|
13
18
|
type ReadonlyStyles = { readonly [K in string]?: string }
|
|
@@ -53,9 +58,20 @@ export class StyleEmbedder {
|
|
|
53
58
|
? getDefaultStylesForTagName(element.tagName.toLowerCase())
|
|
54
59
|
: NO_STYLES
|
|
55
60
|
|
|
56
|
-
const parentStyles =
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
const parentStyles = Object.assign({}, NO_STYLES) as Styles
|
|
62
|
+
if (shouldSkipInheritedParentStyles) {
|
|
63
|
+
let el = element.parentElement
|
|
64
|
+
// Keep going up the tree to find all the relevant styles
|
|
65
|
+
while (el) {
|
|
66
|
+
const currentStyles = this.styles.get(el)?.self
|
|
67
|
+
for (const style in currentStyles) {
|
|
68
|
+
if (!parentStyles[style]) {
|
|
69
|
+
parentStyles[style] = currentStyles[style]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
el = el.parentElement
|
|
73
|
+
}
|
|
74
|
+
}
|
|
59
75
|
|
|
60
76
|
const info: ElementStyleInfo = {
|
|
61
77
|
self: styleFromElement(element, { defaultStyles, parentStyles }),
|
|
@@ -230,6 +246,8 @@ function styleFromComputedStyleMap(
|
|
|
230
246
|
|
|
231
247
|
if (defaultStyles[property] === value) continue
|
|
232
248
|
if (parentStyles[property] === value && isPropertyInherited(property)) continue
|
|
249
|
+
if (isPropertyCoveredByCurrentColor(style.get('color')?.toString() || '', property, value))
|
|
250
|
+
continue
|
|
233
251
|
|
|
234
252
|
styles[property] = value
|
|
235
253
|
}
|
|
@@ -249,6 +267,7 @@ function styleFromComputedStyle(
|
|
|
249
267
|
|
|
250
268
|
if (defaultStyles[property] === value) continue
|
|
251
269
|
if (parentStyles[property] === value && isPropertyInherited(property)) continue
|
|
270
|
+
if (isPropertyCoveredByCurrentColor(style.color, property, value)) continue
|
|
252
271
|
|
|
253
272
|
styles[property] = value
|
|
254
273
|
}
|
|
@@ -62,7 +62,7 @@ export async function exportToSvg(
|
|
|
62
62
|
const svg = renderTarget.firstElementChild
|
|
63
63
|
assert(svg instanceof SVGSVGElement, 'Expected an SVG element')
|
|
64
64
|
|
|
65
|
-
// And apply any changes to <foreignObject> elements that we need to make.
|
|
65
|
+
// And apply any changes to <foreignObject> elements that we need to make. while we're in
|
|
66
66
|
// the document, these elements work exactly as we'd expect from other dom elements - they
|
|
67
67
|
// can load external resources, and any stylesheets in the document apply to them as we
|
|
68
68
|
// would expect them to. But when we pull the SVG into its own file or draw it to a canvas
|
|
@@ -111,11 +111,43 @@ export function parseCssValueUrls(value: string) {
|
|
|
111
111
|
}))
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
const currentColorProperties = new Set([
|
|
115
|
+
'border-block-end-color',
|
|
116
|
+
'border-block-start-color',
|
|
117
|
+
'border-bottom-color',
|
|
118
|
+
'border-inline-end-color',
|
|
119
|
+
'border-inline-start-color',
|
|
120
|
+
'border-left-color',
|
|
121
|
+
'border-right-color',
|
|
122
|
+
'border-top-color',
|
|
123
|
+
'caret-color',
|
|
124
|
+
'column-rule-color',
|
|
125
|
+
'outline-color',
|
|
126
|
+
'text-decoration',
|
|
127
|
+
'text-decoration-color',
|
|
128
|
+
'text-emphasis-color',
|
|
129
|
+
])
|
|
130
|
+
|
|
131
|
+
export function isPropertyCoveredByCurrentColor(
|
|
132
|
+
currentColor: string,
|
|
133
|
+
property: string,
|
|
134
|
+
value: string
|
|
135
|
+
) {
|
|
136
|
+
if (currentColorProperties.has(property)) {
|
|
137
|
+
return (
|
|
138
|
+
value === 'currentColor' ||
|
|
139
|
+
value === currentColor ||
|
|
140
|
+
(property === 'text-decoration' && value === `none solid ${currentColor}`)
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
114
145
|
const inheritedProperties = new Set([
|
|
115
146
|
'border-collapse',
|
|
116
147
|
'border-spacing',
|
|
117
148
|
'caption-side',
|
|
118
|
-
'color',
|
|
149
|
+
// N.B. We shouldn't inherit 'color' because there's some UA styling, e.g. `mark` elements
|
|
150
|
+
// 'color',
|
|
119
151
|
'cursor',
|
|
120
152
|
'direction',
|
|
121
153
|
'empty-cells',
|
|
@@ -136,16 +168,18 @@ const inheritedProperties = new Set([
|
|
|
136
168
|
'orphans',
|
|
137
169
|
'overflow-wrap',
|
|
138
170
|
'quotes',
|
|
171
|
+
'stroke-linecap',
|
|
172
|
+
'stroke-linejoin',
|
|
139
173
|
'tab-size',
|
|
140
174
|
'text-align',
|
|
141
175
|
'text-align-last',
|
|
142
|
-
'text-decoration-color',
|
|
143
176
|
'text-indent',
|
|
144
177
|
'text-justify',
|
|
145
178
|
'text-shadow',
|
|
146
179
|
'text-transform',
|
|
147
180
|
'visibility',
|
|
148
181
|
'white-space',
|
|
182
|
+
'white-space-collapse',
|
|
149
183
|
'widows',
|
|
150
184
|
'word-break',
|
|
151
185
|
'word-spacing',
|
|
@@ -157,8 +157,13 @@ To remove the watermark, please purchase a license at tldraw.dev.
|
|
|
157
157
|
animation: delayed_link 0.2s forwards ease-in-out;
|
|
158
158
|
animation-delay: 0.32s;
|
|
159
159
|
}
|
|
160
|
+
|
|
161
|
+
.${className} > a:focus-visible {
|
|
162
|
+
opacity: 1;
|
|
163
|
+
}
|
|
160
164
|
}
|
|
161
165
|
|
|
166
|
+
|
|
162
167
|
@keyframes delayed_link {
|
|
163
168
|
0% {
|
|
164
169
|
cursor: inherit;
|
|
@@ -303,6 +303,15 @@ export class LocalIndexedDb {
|
|
|
303
303
|
await assetsStore.put(blob, assetId)
|
|
304
304
|
})
|
|
305
305
|
}
|
|
306
|
+
|
|
307
|
+
async removeAssets(assetId: string[]) {
|
|
308
|
+
await this.tx('readwrite', [Table.Assets], async (tx) => {
|
|
309
|
+
const assetsStore = tx.objectStore(Table.Assets)
|
|
310
|
+
for (const id of assetId) {
|
|
311
|
+
await assetsStore.delete(id)
|
|
312
|
+
}
|
|
313
|
+
})
|
|
314
|
+
}
|
|
306
315
|
}
|
|
307
316
|
|
|
308
317
|
/** @internal */
|
package/src/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '3.11.0-canary.
|
|
4
|
+
export const version = '3.11.0-canary.e0e5f2c27ecc'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-03-
|
|
8
|
-
patch: '2025-03-
|
|
7
|
+
minor: '2025-03-20T12:02:56.724Z',
|
|
8
|
+
patch: '2025-03-20T12:02:56.724Z',
|
|
9
9
|
}
|