kopia lustrzana https://github.com/Tldraw/Tldraw
textfields: fix Safari cursor rendering bug, take 2 (#3513)
Take 2 on what this PR was trying to do: https://github.com/tldraw/tldraw/pull/3373 Fixes https://github.com/tldraw/tldraw/issues/3398 hopefully this time without the infinite recursion 🙃 ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [x] `bugfix` — Bug fix - [ ] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't knowpull/3515/head
rodzic
f754bebc32
commit
f9bafb2f8a
|
@ -12,24 +12,12 @@ import { INDENT, TextHelpers } from './TextHelpers'
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useEditableText(id: TLShapeId, type: string, text: string) {
|
export function useEditableText(id: TLShapeId, type: string, text: string) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const rInput = useRef<HTMLTextAreaElement>(null)
|
const rInput = useRef<HTMLTextAreaElement>(null)
|
||||||
|
const rSelectionRanges = useRef<Range[] | null>()
|
||||||
const isEditing = useValue(
|
const isEditing = useValue('isEditing', () => editor.getEditingShapeId() === id, [editor])
|
||||||
'isEditing',
|
const isEditingAnything = useValue('isEditingAnything', () => !!editor.getEditingShapeId(), [
|
||||||
() => {
|
editor,
|
||||||
return editor.getEditingShapeId() === id
|
])
|
||||||
},
|
|
||||||
[editor]
|
|
||||||
)
|
|
||||||
|
|
||||||
const isEditingAnything = useValue(
|
|
||||||
'isEditingAnything',
|
|
||||||
() => {
|
|
||||||
return editor.getEditingShapeId() !== null
|
|
||||||
},
|
|
||||||
[editor]
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function selectAllIfEditing({ shapeId }: { shapeId: TLShapeId }) {
|
function selectAllIfEditing({ shapeId }: { shapeId: TLShapeId }) {
|
||||||
|
@ -46,14 +34,13 @@ export function useEditableText(id: TLShapeId, type: string, text: string) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.on('select-all-text', selectAllIfEditing)
|
editor.on('select-all-text', selectAllIfEditing)
|
||||||
return () => {
|
return () => {
|
||||||
editor.off('select-all-text', selectAllIfEditing)
|
editor.off('select-all-text', selectAllIfEditing)
|
||||||
}
|
}
|
||||||
}, [editor, id])
|
}, [editor, id])
|
||||||
|
|
||||||
const rSelectionRanges = useRef<Range[] | null>()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isEditing) return
|
if (!isEditing) return
|
||||||
|
|
||||||
|
@ -63,10 +50,18 @@ export function useEditableText(id: TLShapeId, type: string, text: string) {
|
||||||
// Focus if we're not already focused
|
// Focus if we're not already focused
|
||||||
if (document.activeElement !== elm) {
|
if (document.activeElement !== elm) {
|
||||||
elm.focus()
|
elm.focus()
|
||||||
|
|
||||||
// On mobile etc, just select all the text when we start focusing
|
// On mobile etc, just select all the text when we start focusing
|
||||||
if (editor.getInstanceState().isCoarsePointer) {
|
if (editor.getInstanceState().isCoarsePointer) {
|
||||||
elm.select()
|
elm.select()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// This fixes iOS not showing the cursor sometimes. This "shakes" the cursor
|
||||||
|
// awake.
|
||||||
|
if (editor.environment.isSafari) {
|
||||||
|
elm.blur()
|
||||||
|
elm.focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the selection changes, save the selection ranges
|
// When the selection changes, save the selection ranges
|
||||||
|
@ -97,12 +92,14 @@ export function useEditableText(id: TLShapeId, type: string, text: string) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const elm = rInput.current
|
const elm = rInput.current
|
||||||
const editingShapeId = editor.getEditingShapeId()
|
const editingShapeId = editor.getEditingShapeId()
|
||||||
|
|
||||||
// Did we move to a different shape?
|
// Did we move to a different shape?
|
||||||
if (editingShapeId) {
|
if (editingShapeId) {
|
||||||
// important! these ^v are two different things
|
// important! these ^v are two different things
|
||||||
// is that shape OUR shape?
|
// is that shape OUR shape?
|
||||||
if (elm && editingShapeId === id) {
|
if (elm && editingShapeId === id) {
|
||||||
elm.focus()
|
elm.focus()
|
||||||
|
|
||||||
if (ranges && ranges.length) {
|
if (ranges && ranges.length) {
|
||||||
const selection = window.getSelection()
|
const selection = window.getSelection()
|
||||||
if (selection) {
|
if (selection) {
|
||||||
|
@ -181,8 +178,6 @@ export function useEditableText(id: TLShapeId, type: string, text: string) {
|
||||||
[editor, id, isEditing]
|
[editor, id, isEditing]
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleDoubleClick = stopEventPropagation
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rInput,
|
rInput,
|
||||||
handleFocus: noop,
|
handleFocus: noop,
|
||||||
|
@ -190,7 +185,7 @@ export function useEditableText(id: TLShapeId, type: string, text: string) {
|
||||||
handleKeyDown,
|
handleKeyDown,
|
||||||
handleChange,
|
handleChange,
|
||||||
handleInputPointerDown,
|
handleInputPointerDown,
|
||||||
handleDoubleClick,
|
handleDoubleClick: stopEventPropagation,
|
||||||
isEmpty: text.trim().length === 0,
|
isEmpty: text.trim().length === 0,
|
||||||
isEditing,
|
isEditing,
|
||||||
isEditingAnything,
|
isEditingAnything,
|
||||||
|
|
Ładowanie…
Reference in New Issue