UBERF-3997: Fix Tab navigation in text editors (#3832)

* fix tab focus switch for styled text editor

Signed-off-by: Anna No <anna.no@xored.com>

* fix tab focus switch for styled text editor

Signed-off-by: Anna No <anna.no@xored.com>

* fix tab focus switch for styled text editor

Signed-off-by: Anna No <anna.no@xored.com>

---------

Signed-off-by: Anna No <anna.no@xored.com>
This commit is contained in:
Anna No
2023-10-12 17:43:57 +07:00
committed by GitHub
parent 0a822d18f8
commit 16ac563eba
4 changed files with 74 additions and 28 deletions
@@ -22,6 +22,7 @@
import { completionConfig } from './extensions'
import { EmojiExtension } from './extension/emoji'
import { FocusExtension } from './extension/focus'
import { ImageRef, FileAttachFunction } from './imageExt'
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
@@ -70,6 +71,8 @@
mode = Mode.View
}
let canBlur = true
let focused = false
let rawValue: string
let oldContent = ''
let modified: boolean = false
@@ -103,7 +106,6 @@
textEditor.setContent(data)
}
const dispatch = createEventDispatcher()
let focused = false
export function isFocused (): boolean {
return focused
@@ -129,7 +131,7 @@
isFocus: () => focused,
canBlur: () => {
if (focused) {
return !textEditor.catHandleTab()
return canBlur
}
return true
}
@@ -140,6 +142,20 @@
}
}
const handleFocus = (value: boolean) => {
focused = value
if (focused) {
updateFocus()
dispatch('focus')
} else {
dispatch('blur', rawValue)
if (alwaysEdit) {
dispatch('value', rawValue)
content = rawValue
}
}
}
const attachments = new Map<string, ProseMirrorNode>()
/**
@@ -169,10 +185,14 @@
}
})
const extensions: AnyExtension[] = [imagePlugin]
const extensions: AnyExtension[] = []
if (enableBackReferences) {
extensions.unshift(completionPlugin)
extensions.push(completionPlugin)
}
extensions.push(
imagePlugin,
FocusExtension.configure({ onCanBlur: (value: boolean) => (canBlur = value), onFocus: handleFocus })
)
if (enableEmojiReplace) {
extensions.push(EmojiExtension.configure())
}
@@ -217,19 +237,6 @@
bind:content={rawValue}
bind:this={textEditor}
on:attach
on:focus={() => {
focused = true
updateFocus()
dispatch('focus')
}}
on:blur={() => {
focused = false
dispatch('blur', rawValue)
if (alwaysEdit) {
dispatch('value', rawValue)
content = rawValue
}
}}
on:value={(evt) => {
rawValue = evt.detail
if (alwaysEdit) {
@@ -85,14 +85,6 @@
export function insertText (text: string): void {
textEditor.insertText(text)
}
export function catHandleTab (): boolean {
return (
textEditor.checkIsActive('bulletList') ||
textEditor.checkIsActive('orderedList') ||
textEditor.checkIsActive('code') ||
textEditor.checkIsActive('codeBlock')
)
}
$: varsStyle =
maxHeight === 'card'
@@ -165,13 +165,13 @@
// force re-render so `editor.isActive` works as expected
editor = editor
},
onBlur: ({ event }) => {
onBlur: () => {
focused = false
dispatch('blur', event)
dispatch('blur')
},
onFocus: () => {
focused = true
dispatch('focus', editor.getHTML())
dispatch('focus')
},
onUpdate: () => {
content = editor.getHTML()
@@ -0,0 +1,47 @@
import { Editor, Extension } from '@tiptap/core'
const canBlur = (editor: Editor, options: FocusOptions): boolean => {
return (
options.canBlur?.(editor) ??
(!editor.isActive('bulletList') &&
!editor.isActive('orderedList') &&
!editor.isActive('code') &&
!editor.isActive('codeBlock'))
)
}
export interface FocusOptions {
canBlur?: (editor: Editor) => boolean
onCanBlur?: (canBlur: boolean) => void
onFocus?: (focused: boolean) => void
}
export interface FocusStorage {
canBlur: boolean
}
export const FocusExtension = Extension.create<FocusOptions, FocusStorage>({
addStorage () {
return { canBlur: true }
},
onCreate () {
this.options.onFocus?.(this.editor.isFocused)
this.storage.canBlur = canBlur(this.editor, this.options)
this.options.onCanBlur?.(this.storage.canBlur)
},
onBlur () {
this.options.onFocus?.(false)
},
onFocus () {
this.options.onFocus?.(true)
},
onSelectionUpdate () {
const canBlurNow = canBlur(this.editor, this.options)
if (this.storage.canBlur !== canBlurNow) {
this.storage.canBlur = canBlurNow
this.options.onCanBlur?.(this.storage.canBlur)
}
}
})