tldraw 3.16.0-canary.faec5de49906 → 3.16.0-canary.fe4babe9c1ad
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 +7 -5
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/defaultExternalContentHandlers.js +10 -0
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -2
- package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
- package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
- package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +1 -1
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/LanguageMenu.js +1 -0
- package/dist-cjs/lib/ui/components/LanguageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -0
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +11 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +5 -4
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +6 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +5 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +1 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +14 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +3 -0
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +6 -0
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.d.mts +7 -5
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +10 -0
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +5 -5
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +3 -3
- package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
- package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +4 -3
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -3
- package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
- package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/LanguageMenu.mjs +1 -0
- package/dist-esm/lib/ui/components/LanguageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -0
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +11 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +5 -4
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +1 -1
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +6 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +1 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +6 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +1 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +14 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +3 -0
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +6 -0
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
- package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/lib/defaultExternalContentHandlers.ts +14 -0
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +2 -2
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +5 -5
- package/src/lib/shapes/frame/components/FrameLabelInput.tsx +3 -3
- package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
- package/src/lib/shapes/shared/useEditablePlainText.ts +5 -3
- package/src/lib/shapes/text/PlainTextArea.tsx +3 -3
- package/src/lib/shapes/text/RichTextArea.tsx +3 -4
- package/src/lib/ui/components/A11y.tsx +2 -2
- package/src/lib/ui/components/LanguageMenu.tsx +1 -0
- package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -0
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +2 -2
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +9 -2
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
- package/src/lib/ui/components/Toolbar/LinkEditor.tsx +6 -5
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +1 -1
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +9 -2
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +2 -2
- package/src/lib/ui/components/primitives/TldrawUiInput.tsx +6 -3
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +2 -1
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +16 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +4 -0
- package/src/lib/ui/context/actions.tsx +13 -0
- package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +10 -0
- package/tldraw.css +10 -0
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
TLShapeId,
|
|
4
4
|
TLUnknownShape,
|
|
5
5
|
getPointerInfo,
|
|
6
|
+
markEventAsHandled,
|
|
6
7
|
noop,
|
|
7
8
|
preventDefault,
|
|
8
|
-
stopEventPropagation,
|
|
9
9
|
tlenv,
|
|
10
10
|
useEditor,
|
|
11
11
|
useValue,
|
|
@@ -136,7 +136,7 @@ export function useEditableTextCommon(shapeId: TLShapeId) {
|
|
|
136
136
|
shape: editor.getShape(shapeId)!,
|
|
137
137
|
})
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
e.stopPropagation() // we need to prevent blurring the input
|
|
140
140
|
},
|
|
141
141
|
[editor, shapeId]
|
|
142
142
|
)
|
|
@@ -157,11 +157,13 @@ export function useEditableTextCommon(shapeId: TLShapeId) {
|
|
|
157
157
|
[editor, shapeId]
|
|
158
158
|
)
|
|
159
159
|
|
|
160
|
+
const handleDoubleClick: (e: React.MouseEvent) => void = markEventAsHandled
|
|
161
|
+
|
|
160
162
|
return {
|
|
161
163
|
handleFocus: noop,
|
|
162
164
|
handleBlur: noop,
|
|
163
165
|
handleInputPointerDown,
|
|
164
|
-
handleDoubleClick
|
|
166
|
+
handleDoubleClick,
|
|
165
167
|
handlePaste,
|
|
166
168
|
isEditing,
|
|
167
169
|
isReadyForEditing,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { markEventAsHandled, preventDefault } from '@tldraw/editor'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import { TextAreaProps } from './RichTextArea'
|
|
4
4
|
|
|
@@ -46,8 +46,8 @@ export const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps
|
|
|
46
46
|
onChange={onChange}
|
|
47
47
|
onKeyDown={(e) => handleKeyDown(e.nativeEvent)}
|
|
48
48
|
onBlur={handleBlur}
|
|
49
|
-
onTouchEnd={
|
|
50
|
-
onContextMenu={isEditing ?
|
|
49
|
+
onTouchEnd={markEventAsHandled}
|
|
50
|
+
onContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}
|
|
51
51
|
onPointerDown={handleInputPointerDown}
|
|
52
52
|
onPaste={handlePaste}
|
|
53
53
|
onDoubleClick={handleDoubleClick}
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
TLRichText,
|
|
11
11
|
TLShapeId,
|
|
12
12
|
preventDefault,
|
|
13
|
-
stopEventPropagation,
|
|
14
13
|
useEditor,
|
|
15
14
|
useEvent,
|
|
16
15
|
useUniqueSafeId,
|
|
@@ -233,13 +232,13 @@ export const RichTextArea = React.forwardRef<HTMLDivElement, TextAreaProps>(func
|
|
|
233
232
|
tabIndex={-1}
|
|
234
233
|
data-testid="rich-text-area"
|
|
235
234
|
className="tl-rich-text tl-text tl-text-input"
|
|
236
|
-
onContextMenu={isEditing ?
|
|
235
|
+
onContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}
|
|
237
236
|
// N.B. When PointerStateExtension was introduced, this was moved there.
|
|
238
237
|
// However, that caused selecting over list items to break.
|
|
239
238
|
// The handleDOMEvents in TipTap don't seem to support the pointerDownCapture event.
|
|
240
|
-
onPointerDownCapture={
|
|
239
|
+
onPointerDownCapture={(e) => e.stopPropagation()}
|
|
241
240
|
// This onTouchEnd is important for Android to be able to change selection on text.
|
|
242
|
-
onTouchEnd={
|
|
241
|
+
onTouchEnd={(e) => e.stopPropagation()}
|
|
243
242
|
// On FF, there's a behavior where dragging a selection will grab that selection into
|
|
244
243
|
// the drag event. However, once the drag is over, and you select away from the textarea,
|
|
245
244
|
// starting a drag over the textarea will restart a selection drag instead of a shape drag.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
debugFlags,
|
|
3
3
|
Editor,
|
|
4
|
-
|
|
4
|
+
markEventAsHandled,
|
|
5
5
|
TLGeoShape,
|
|
6
6
|
TLShapeId,
|
|
7
7
|
unsafe__withoutCapture,
|
|
@@ -23,7 +23,7 @@ export function SkipToMainContent() {
|
|
|
23
23
|
|
|
24
24
|
const handleNavigateToFirstShape = useCallback(
|
|
25
25
|
(e: MouseEvent | KeyboardEvent) => {
|
|
26
|
-
|
|
26
|
+
markEventAsHandled(e)
|
|
27
27
|
button.current?.blur()
|
|
28
28
|
const shapes = editor.getCurrentPageShapesInReadingOrder()
|
|
29
29
|
if (!shapes.length) return
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PageRecordType,
|
|
3
3
|
TLPageId,
|
|
4
|
+
markEventAsHandled,
|
|
4
5
|
releasePointerCapture,
|
|
5
6
|
setPointerCapture,
|
|
6
|
-
stopEventPropagation,
|
|
7
7
|
tlenv,
|
|
8
8
|
useEditor,
|
|
9
9
|
useValue,
|
|
@@ -451,7 +451,7 @@ export const DefaultPageMenu = memo(function DefaultPageMenu() {
|
|
|
451
451
|
if (e.key === 'Enter') {
|
|
452
452
|
if (page.id === currentPage.id) {
|
|
453
453
|
toggleEditing()
|
|
454
|
-
|
|
454
|
+
markEventAsHandled(e)
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
457
|
}}
|
|
@@ -137,6 +137,7 @@ export const StylePanelButtonPicker = memo(function StylePanelButtonPicker<T ext
|
|
|
137
137
|
>
|
|
138
138
|
<Layout>
|
|
139
139
|
{items.map((item) => {
|
|
140
|
+
const isActive = value.type === 'shared' && value.value === item.value
|
|
140
141
|
const label =
|
|
141
142
|
title + ' — ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
|
|
142
143
|
return (
|
|
@@ -145,10 +146,16 @@ export const StylePanelButtonPicker = memo(function StylePanelButtonPicker<T ext
|
|
|
145
146
|
key={item.value}
|
|
146
147
|
data-id={item.value}
|
|
147
148
|
data-testid={`style.${uiType}.${item.value}`}
|
|
148
|
-
aria-label={label}
|
|
149
|
+
aria-label={label + (isActive ? ` (${msg('style-panel.selected')})` : '')}
|
|
150
|
+
tooltip={
|
|
151
|
+
<>
|
|
152
|
+
<div>{label}</div>
|
|
153
|
+
{isActive ? <div>({msg('style-panel.selected')})</div> : null}
|
|
154
|
+
</>
|
|
155
|
+
}
|
|
149
156
|
value={item.value}
|
|
150
157
|
data-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}
|
|
151
|
-
data-isactive={
|
|
158
|
+
data-isactive={isActive}
|
|
152
159
|
title={label}
|
|
153
160
|
style={
|
|
154
161
|
style === (DefaultColorStyle as StyleProp<unknown>)
|
|
@@ -2,9 +2,9 @@ import { preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'
|
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
3
3
|
import { useUiEvents } from '../../context/events'
|
|
4
4
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
5
|
+
import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
|
|
5
6
|
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
|
|
6
7
|
import { TldrawUiInput } from '../primitives/TldrawUiInput'
|
|
7
|
-
import { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
8
8
|
|
|
9
9
|
/** @public */
|
|
10
10
|
export interface AltTextEditorProps {
|
|
@@ -70,13 +70,14 @@ export function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps)
|
|
|
70
70
|
data-testid="media-toolbar.alt-text-input"
|
|
71
71
|
value={altText}
|
|
72
72
|
placeholder={msg('tool.media-alt-text-desc')}
|
|
73
|
+
aria-label={msg('tool.media-alt-text-desc')}
|
|
73
74
|
onValueChange={handleValueChange}
|
|
74
75
|
onComplete={handleComplete}
|
|
75
76
|
onCancel={handleAltTextCancel}
|
|
76
77
|
disabled={isReadonly}
|
|
77
78
|
/>
|
|
78
79
|
{!isReadonly && (
|
|
79
|
-
<
|
|
80
|
+
<TldrawUiButton
|
|
80
81
|
title={msg('tool.media-alt-text-confirm')}
|
|
81
82
|
data-testid="tool.media-alt-text-confirm"
|
|
82
83
|
type="icon"
|
|
@@ -84,7 +85,7 @@ export function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps)
|
|
|
84
85
|
onClick={handleConfirm}
|
|
85
86
|
>
|
|
86
87
|
<TldrawUiButtonIcon small icon="check" />
|
|
87
|
-
</
|
|
88
|
+
</TldrawUiButton>
|
|
88
89
|
)}
|
|
89
90
|
</>
|
|
90
91
|
)
|
|
@@ -2,9 +2,9 @@ import { preventDefault, TiptapEditor, useEditor } from '@tldraw/editor'
|
|
|
2
2
|
import { useEffect, useRef, useState } from 'react'
|
|
3
3
|
import { useUiEvents } from '../../context/events'
|
|
4
4
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
5
|
+
import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
|
|
5
6
|
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
|
|
6
7
|
import { TldrawUiInput } from '../primitives/TldrawUiInput'
|
|
7
|
-
import { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
8
8
|
|
|
9
9
|
/** @public */
|
|
10
10
|
export interface LinkEditorProps {
|
|
@@ -75,8 +75,9 @@ export function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEdi
|
|
|
75
75
|
onComplete={handleLinkComplete}
|
|
76
76
|
onCancel={handleLinkCancel}
|
|
77
77
|
placeholder="example.com"
|
|
78
|
+
aria-label="example.com"
|
|
78
79
|
/>
|
|
79
|
-
<
|
|
80
|
+
<TldrawUiButton
|
|
80
81
|
className="tlui-rich-text__toolbar-link-visit"
|
|
81
82
|
title={msg('tool.rich-text-link-visit')}
|
|
82
83
|
type="icon"
|
|
@@ -85,8 +86,8 @@ export function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEdi
|
|
|
85
86
|
disabled={!value}
|
|
86
87
|
>
|
|
87
88
|
<TldrawUiButtonIcon small icon="external-link" />
|
|
88
|
-
</
|
|
89
|
-
<
|
|
89
|
+
</TldrawUiButton>
|
|
90
|
+
<TldrawUiButton
|
|
90
91
|
className="tlui-rich-text__toolbar-link-remove"
|
|
91
92
|
title={msg('tool.rich-text-link-remove')}
|
|
92
93
|
data-testid="rich-text.link-remove"
|
|
@@ -95,7 +96,7 @@ export function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEdi
|
|
|
95
96
|
onClick={handleRemoveLink}
|
|
96
97
|
>
|
|
97
98
|
<TldrawUiButtonIcon small icon="trash" />
|
|
98
|
-
</
|
|
99
|
+
</TldrawUiButton>
|
|
99
100
|
</>
|
|
100
101
|
)
|
|
101
102
|
}
|
|
@@ -101,7 +101,7 @@ export function OverflowingToolbar({
|
|
|
101
101
|
items: collectItems(child.children),
|
|
102
102
|
element: child as HTMLElement,
|
|
103
103
|
})
|
|
104
|
-
} else {
|
|
104
|
+
} else if (!child.hasAttribute('data-radix-popper-content-wrapper')) {
|
|
105
105
|
items.push({ type: 'item', element: child as HTMLElement })
|
|
106
106
|
}
|
|
107
107
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { useEditor, useValue } from '@tldraw/editor'
|
|
2
2
|
import classNames from 'classnames'
|
|
3
3
|
import { PORTRAIT_BREAKPOINT } from '../../constants'
|
|
4
|
+
import { useActions } from '../../context/actions'
|
|
4
5
|
import { useBreakpoint } from '../../context/breakpoints'
|
|
5
6
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
7
|
+
import { kbdStr } from '../../kbd-utils'
|
|
6
8
|
import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
|
|
7
9
|
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
|
|
8
10
|
import { TldrawUiTooltip } from '../primitives/TldrawUiTooltip'
|
|
@@ -17,6 +19,7 @@ export function ToggleToolLockedButton({ activeToolId }: ToggleToolLockedButtonP
|
|
|
17
19
|
const editor = useEditor()
|
|
18
20
|
const breakpoint = useBreakpoint()
|
|
19
21
|
const msg = useTranslation()
|
|
22
|
+
const actions = useActions()
|
|
20
23
|
|
|
21
24
|
const isToolLocked = useValue('is tool locked', () => editor.getInstanceState().isToolLocked, [
|
|
22
25
|
editor,
|
|
@@ -25,11 +28,15 @@ export function ToggleToolLockedButton({ activeToolId }: ToggleToolLockedButtonP
|
|
|
25
28
|
|
|
26
29
|
if (!activeToolId || !tool.isLockable) return null
|
|
27
30
|
|
|
31
|
+
const toggleLockAction = actions['toggle-tool-lock']
|
|
32
|
+
const tooltipContent = toggleLockAction?.kbd
|
|
33
|
+
? `${msg('action.toggle-tool-lock')} ${kbdStr(toggleLockAction.kbd)}`
|
|
34
|
+
: msg('action.toggle-tool-lock')
|
|
35
|
+
|
|
28
36
|
return (
|
|
29
|
-
<TldrawUiTooltip content={
|
|
37
|
+
<TldrawUiTooltip content={tooltipContent}>
|
|
30
38
|
<TldrawUiButton
|
|
31
39
|
type="normal"
|
|
32
|
-
title={msg('action.toggle-tool-lock')}
|
|
33
40
|
data-testid="tool-lock"
|
|
34
41
|
className={classNames('tlui-main-toolbar__lock-button', {
|
|
35
42
|
'tlui-main-toolbar__lock-button__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
Box,
|
|
4
4
|
clamp,
|
|
5
5
|
Editor,
|
|
6
|
+
markEventAsHandled,
|
|
6
7
|
react,
|
|
7
|
-
stopEventPropagation,
|
|
8
8
|
useAtom,
|
|
9
9
|
useEditor,
|
|
10
10
|
usePassThroughMouseOverEvents,
|
|
@@ -170,7 +170,7 @@ export const TldrawUiContextualToolbar = ({
|
|
|
170
170
|
data-visible={false}
|
|
171
171
|
data-testid="contextual-toolbar"
|
|
172
172
|
className={classNames('tlui-contextual-toolbar', className)}
|
|
173
|
-
onPointerDown={
|
|
173
|
+
onPointerDown={markEventAsHandled}
|
|
174
174
|
>
|
|
175
175
|
<TldrawUiToolbar
|
|
176
176
|
orientation="horizontal"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { tlenv, tltime, useMaybeEditor } from '@tldraw/editor'
|
|
2
2
|
import classNames from 'classnames'
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
|
@@ -35,6 +35,7 @@ export interface TLUiInputProps {
|
|
|
35
35
|
shouldManuallyMaintainScrollPositionWhenFocused?: boolean
|
|
36
36
|
value?: string
|
|
37
37
|
'data-testid'?: string
|
|
38
|
+
'aria-label'?: string
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
/** @public @react */
|
|
@@ -60,6 +61,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
|
|
|
60
61
|
value,
|
|
61
62
|
'data-testid': dataTestId,
|
|
62
63
|
disabled,
|
|
64
|
+
'aria-label': ariaLabel,
|
|
63
65
|
},
|
|
64
66
|
ref
|
|
65
67
|
) {
|
|
@@ -118,7 +120,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
|
|
|
118
120
|
// `onChange` with a duplicated text value.
|
|
119
121
|
if (isComposing.current) return
|
|
120
122
|
e.currentTarget.blur()
|
|
121
|
-
|
|
123
|
+
e.stopPropagation()
|
|
122
124
|
onComplete?.(e.currentTarget.value)
|
|
123
125
|
break
|
|
124
126
|
}
|
|
@@ -126,7 +128,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
|
|
|
126
128
|
e.currentTarget.value = rInitialValue.current
|
|
127
129
|
onCancel?.(e.currentTarget.value)
|
|
128
130
|
e.currentTarget.blur()
|
|
129
|
-
|
|
131
|
+
e.stopPropagation()
|
|
130
132
|
break
|
|
131
133
|
}
|
|
132
134
|
}
|
|
@@ -198,6 +200,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
|
|
|
198
200
|
onCompositionStart={handleCompositionStart}
|
|
199
201
|
onCompositionEnd={handleCompositionEnd}
|
|
200
202
|
autoFocus={autoFocus}
|
|
203
|
+
aria-label={ariaLabel}
|
|
201
204
|
placeholder={placeholder}
|
|
202
205
|
value={value}
|
|
203
206
|
data-testid={dataTestId}
|
|
@@ -71,6 +71,7 @@ export const TldrawUiToolbarButton = React.forwardRef<HTMLButtonElement, TLUiToo
|
|
|
71
71
|
draggable={false}
|
|
72
72
|
data-isactive={isActive}
|
|
73
73
|
{...props}
|
|
74
|
+
aria-label={props.title}
|
|
74
75
|
// The tooltip takes care of this.
|
|
75
76
|
title={undefined}
|
|
76
77
|
className={classnames('tlui-button', `tlui-button__${type}`, props.className)}
|
|
@@ -127,7 +128,7 @@ export interface TLUiToolbarToggleItemProps extends React.HTMLAttributes<HTMLBut
|
|
|
127
128
|
className?: string
|
|
128
129
|
type: 'icon' | 'tool'
|
|
129
130
|
value: string
|
|
130
|
-
tooltip?:
|
|
131
|
+
tooltip?: React.ReactNode
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
/** @public @react */
|
|
@@ -171,6 +171,20 @@ function TooltipSingleton() {
|
|
|
171
171
|
}
|
|
172
172
|
}, [cameraState, isOpen, currentTooltip, editor])
|
|
173
173
|
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
function handleKeyDown(event: KeyboardEvent) {
|
|
176
|
+
if (event.key === 'Escape' && currentTooltip && isOpen) {
|
|
177
|
+
tooltipManager.hideTooltip(editor, currentTooltip.id)
|
|
178
|
+
event.stopPropagation()
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
document.addEventListener('keydown', handleKeyDown, { capture: true })
|
|
183
|
+
return () => {
|
|
184
|
+
document.removeEventListener('keydown', handleKeyDown, { capture: true })
|
|
185
|
+
}
|
|
186
|
+
}, [editor, currentTooltip, isOpen])
|
|
187
|
+
|
|
174
188
|
// Update open state and trigger position
|
|
175
189
|
useEffect(() => {
|
|
176
190
|
let timer: ReturnType<typeof setTimeout> | null = null
|
|
@@ -293,9 +307,9 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
|
|
|
293
307
|
}
|
|
294
308
|
|
|
295
309
|
// Fallback to old behavior if no provider
|
|
296
|
-
if (!hasProvider) {
|
|
310
|
+
if (!hasProvider || showUiLabels) {
|
|
297
311
|
return (
|
|
298
|
-
<_Tooltip.Root delayDuration={delayDurationToUse} disableHoverableContent>
|
|
312
|
+
<_Tooltip.Root delayDuration={delayDurationToUse} disableHoverableContent={!showUiLabels}>
|
|
299
313
|
<_Tooltip.Trigger asChild ref={ref}>
|
|
300
314
|
{children}
|
|
301
315
|
</_Tooltip.Trigger>
|
|
@@ -19,6 +19,7 @@ export interface TLUiMenuCheckboxItemProps<
|
|
|
19
19
|
kbd?: string
|
|
20
20
|
title?: string
|
|
21
21
|
label?: TranslationKey | { [key: string]: TranslationKey }
|
|
22
|
+
lang?: string
|
|
22
23
|
readonlyOk?: boolean
|
|
23
24
|
onSelect(source: TLUiEventSource): Promise<void> | void
|
|
24
25
|
toggle?: boolean
|
|
@@ -34,6 +35,7 @@ export function TldrawUiMenuCheckboxItem<
|
|
|
34
35
|
id,
|
|
35
36
|
kbd,
|
|
36
37
|
label,
|
|
38
|
+
lang,
|
|
37
39
|
readonlyOk,
|
|
38
40
|
onSelect,
|
|
39
41
|
toggle = false,
|
|
@@ -55,6 +57,7 @@ export function TldrawUiMenuCheckboxItem<
|
|
|
55
57
|
return (
|
|
56
58
|
<_DropdownMenu.CheckboxItem
|
|
57
59
|
dir="ltr"
|
|
60
|
+
lang={lang}
|
|
58
61
|
className="tlui-button tlui-button__menu tlui-button__checkbox"
|
|
59
62
|
title={labelStr}
|
|
60
63
|
onSelect={(e) => {
|
|
@@ -84,6 +87,7 @@ export function TldrawUiMenuCheckboxItem<
|
|
|
84
87
|
key={id}
|
|
85
88
|
className="tlui-button tlui-button__menu tlui-button__checkbox"
|
|
86
89
|
dir="ltr"
|
|
90
|
+
lang={lang}
|
|
87
91
|
title={labelStr}
|
|
88
92
|
onSelect={(e) => {
|
|
89
93
|
onSelect(sourceId)
|
|
@@ -1584,6 +1584,19 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
|
|
1584
1584
|
onSelect: async (source) => {
|
|
1585
1585
|
if (!canApplySelectionAction()) return
|
|
1586
1586
|
|
|
1587
|
+
const onlySelectedShape = editor.getOnlySelectedShape()
|
|
1588
|
+
if (
|
|
1589
|
+
onlySelectedShape &&
|
|
1590
|
+
(editor.isShapeOfType<TLImageShape>(onlySelectedShape, 'image') ||
|
|
1591
|
+
editor.isShapeOfType<TLVideoShape>(onlySelectedShape, 'video'))
|
|
1592
|
+
) {
|
|
1593
|
+
const firstToolbarButton = editor
|
|
1594
|
+
.getContainer()
|
|
1595
|
+
.querySelector('.tlui-contextual-toolbar button:first-child') as HTMLElement | null
|
|
1596
|
+
firstToolbarButton?.focus()
|
|
1597
|
+
return
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1587
1600
|
const firstButton = editor
|
|
1588
1601
|
.getContainer()
|
|
1589
1602
|
.querySelector('.tlui-style-panel button') as HTMLElement | null
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
assert,
|
|
8
8
|
compact,
|
|
9
9
|
isDefined,
|
|
10
|
+
markEventAsHandled,
|
|
10
11
|
preventDefault,
|
|
11
|
-
stopEventPropagation,
|
|
12
12
|
uniq,
|
|
13
13
|
useEditor,
|
|
14
14
|
useMaybeEditor,
|
|
@@ -763,7 +763,7 @@ export function useNativeClipboardEvents() {
|
|
|
763
763
|
|
|
764
764
|
const paste = (e: ClipboardEvent) => {
|
|
765
765
|
if (disablingMiddleClickPaste) {
|
|
766
|
-
|
|
766
|
+
markEventAsHandled(e)
|
|
767
767
|
return
|
|
768
768
|
}
|
|
769
769
|
|
|
@@ -122,6 +122,7 @@ export type TLUiTranslationKey =
|
|
|
122
122
|
| 'action.zoom-to-fit'
|
|
123
123
|
| 'action.zoom-to-selection'
|
|
124
124
|
| 'assets.files.size-too-big'
|
|
125
|
+
| 'assets.files.maximum-size'
|
|
125
126
|
| 'assets.files.type-not-allowed'
|
|
126
127
|
| 'assets.files.upload-failed'
|
|
127
128
|
| 'assets.files.amount-too-many'
|
|
@@ -411,6 +412,7 @@ export type TLUiTranslationKey =
|
|
|
411
412
|
| 'style-panel.opacity'
|
|
412
413
|
| 'style-panel.size'
|
|
413
414
|
| 'style-panel.spline'
|
|
415
|
+
| 'style-panel.selected'
|
|
414
416
|
| 'tool-panel.title'
|
|
415
417
|
| 'tool-panel.more'
|
|
416
418
|
| 'navigation-zone.title'
|
|
@@ -123,6 +123,7 @@ export const DEFAULT_TRANSLATION = {
|
|
|
123
123
|
'action.zoom-to-fit': 'Zoom to fit',
|
|
124
124
|
'action.zoom-to-selection': 'Zoom to selection',
|
|
125
125
|
'assets.files.size-too-big': 'File size is too big',
|
|
126
|
+
'assets.files.maximum-size': 'Maximum file size is {size}',
|
|
126
127
|
'assets.files.type-not-allowed': 'File type is not allowed',
|
|
127
128
|
'assets.files.upload-failed': 'Upload failed',
|
|
128
129
|
'assets.files.amount-too-many': 'Too many files',
|
|
@@ -414,6 +415,7 @@ export const DEFAULT_TRANSLATION = {
|
|
|
414
415
|
'style-panel.opacity': 'Opacity',
|
|
415
416
|
'style-panel.size': 'Size',
|
|
416
417
|
'style-panel.spline': 'Spline',
|
|
418
|
+
'style-panel.selected': 'selected',
|
|
417
419
|
'tool-panel.title': 'Tools',
|
|
418
420
|
'tool-panel.more': 'More',
|
|
419
421
|
'navigation-zone.title': 'Navigation',
|
package/src/lib/ui/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.16.0-canary.
|
|
4
|
+
export const version = '3.16.0-canary.fe4babe9c1ad'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-09-
|
|
8
|
-
patch: '2025-09-
|
|
7
|
+
minor: '2025-09-17T14:16:55.791Z',
|
|
8
|
+
patch: '2025-09-17T14:16:55.791Z',
|
|
9
9
|
}
|
package/src/lib/ui.css
CHANGED
|
@@ -494,6 +494,10 @@
|
|
|
494
494
|
-webkit-user-select: auto !important;
|
|
495
495
|
}
|
|
496
496
|
|
|
497
|
+
.tlui-input::placeholder {
|
|
498
|
+
color: var(--tl-color-text-3);
|
|
499
|
+
}
|
|
500
|
+
|
|
497
501
|
.tlui-input__wrapper {
|
|
498
502
|
width: 100%;
|
|
499
503
|
height: 44px;
|
|
@@ -578,6 +582,12 @@
|
|
|
578
582
|
box-shadow: var(--tl-shadow-3);
|
|
579
583
|
}
|
|
580
584
|
|
|
585
|
+
@media (max-height: 600px) {
|
|
586
|
+
.tlui-menu {
|
|
587
|
+
max-height: 70vh;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
581
591
|
.tlui-menu::-webkit-scrollbar {
|
|
582
592
|
display: none;
|
|
583
593
|
}
|
package/tldraw.css
CHANGED
|
@@ -2290,6 +2290,10 @@ it from receiving any pointer events or affecting the cursor. */
|
|
|
2290
2290
|
-webkit-user-select: auto !important;
|
|
2291
2291
|
}
|
|
2292
2292
|
|
|
2293
|
+
.tlui-input::placeholder {
|
|
2294
|
+
color: var(--tl-color-text-3);
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2293
2297
|
.tlui-input__wrapper {
|
|
2294
2298
|
width: 100%;
|
|
2295
2299
|
height: 44px;
|
|
@@ -2374,6 +2378,12 @@ it from receiving any pointer events or affecting the cursor. */
|
|
|
2374
2378
|
box-shadow: var(--tl-shadow-3);
|
|
2375
2379
|
}
|
|
2376
2380
|
|
|
2381
|
+
@media (max-height: 600px) {
|
|
2382
|
+
.tlui-menu {
|
|
2383
|
+
max-height: 70vh;
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2377
2387
|
.tlui-menu::-webkit-scrollbar {
|
|
2378
2388
|
display: none;
|
|
2379
2389
|
}
|