Skip to content

Commit 0221a3b

Browse files
committed
feat: CodeMirror - ReadOnly tooltip - show tooltip only on keypress
1 parent 8474032 commit 0221a3b

File tree

2 files changed

+32
-35
lines changed

2 files changed

+32
-35
lines changed

src/Common/CodeMirror/CodeEditor.constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ export const REPLACE_SHORTCUT_KEYS: SupportedKeyboardKeysType[] = ['Enter']
2323
export const REPLACE_ALL_SHORTCUT_KEYS: SupportedKeyboardKeysType[] = [IS_PLATFORM_MAC_OS ? 'Meta' : 'Control', 'Enter']
2424
export const SELECT_ALL_SHORTCUT_KEYS: SupportedKeyboardKeysType[] = ['Alt', 'Enter']
2525
export const CLOSE_SEARCH_SHORTCUT_KEYS: SupportedKeyboardKeysType[] = ['Escape']
26+
27+
export const READ_ONLY_TOOLTIP_TIMEOUT = 2000

src/Common/CodeMirror/Extensions/readOnlyTooltip.ts

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {
18-
EditorView,
19-
Extension,
20-
showTooltip,
21-
StateEffect,
22-
StateField,
23-
Tooltip,
24-
ViewPlugin,
25-
ViewUpdate,
26-
} from '@uiw/react-codemirror'
17+
import { EditorView, Extension, showTooltip, StateEffect, StateField, Tooltip, ViewPlugin } from '@uiw/react-codemirror'
2718

2819
import { getReadOnlyElement } from '../utils'
20+
import { READ_ONLY_TOOLTIP_TIMEOUT } from '../CodeEditor.constants'
2921

3022
// Effect to update the tooltip in the editor state
3123
const updateTooltipEffect = StateEffect.define<Tooltip | null>()
@@ -76,43 +68,46 @@ const createTooltip = (view: EditorView): Tooltip => {
7668
}
7769
}
7870

79-
// Define a plugin to manage tooltip updates
80-
const focusTooltipPlugin = ViewPlugin.fromClass(
71+
// Plugin to show and remove tooltip on keypress
72+
const keypressTooltipPlugin = ViewPlugin.fromClass(
8173
class {
82-
// Tracks whether an update is scheduled
83-
public scheduled: boolean = false
74+
private timeoutId: number | null = null
8475

8576
constructor(public view: EditorView) {
86-
this.scheduleUpdate()
77+
this.view.dom.addEventListener('keydown', this.handleKeyPress)
8778
}
8879

89-
// Called when the editor state changes
90-
update(update: ViewUpdate) {
91-
if (update.focusChanged || update.selectionSet) {
92-
this.scheduleUpdate()
80+
destroy() {
81+
this.view.dom.removeEventListener('keydown', this.handleKeyPress)
82+
if (this.timeoutId) {
83+
clearTimeout(this.timeoutId)
9384
}
9485
}
9586

96-
// Schedules a tooltip update in the next microtask
97-
scheduleUpdate() {
98-
if (this.scheduled) return
99-
this.scheduled = true
100-
101-
// Update the tooltip asynchronously
102-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
103-
Promise.resolve().then(() => {
104-
this.scheduled = false
105-
const tooltip = this.view.state.readOnly && this.view.hasFocus ? createTooltip(this.view) : null
106-
this.view.dispatch({
107-
effects: updateTooltipEffect.of(tooltip),
108-
})
109-
})
87+
handleKeyPress = () => {
88+
if (!this.view.state.readOnly) {
89+
return
90+
}
91+
92+
// Show tooltip
93+
const tooltip = createTooltip(this.view)
94+
this.view.dispatch({ effects: updateTooltipEffect.of(tooltip) })
95+
96+
// Reset the timer after every key press
97+
if (this.timeoutId) {
98+
clearTimeout(this.timeoutId)
99+
}
100+
101+
// Remove tooltip after timeout time
102+
this.timeoutId = setTimeout(() => {
103+
this.view.dispatch({ effects: updateTooltipEffect.of(null) })
104+
}, READ_ONLY_TOOLTIP_TIMEOUT)
110105
}
111106
},
112107
)
113108

114109
/**
115110
* The read-only tooltip extension for CodeMirror. \
116-
* Displays a tooltip at the cursor position when the editor is read-only and focused.
111+
* Displays a tooltip at the cursor position when the editor is read-only and key is pressed.
117112
*/
118-
export const readOnlyTooltip: Extension = [tooltipField, focusTooltipPlugin]
113+
export const readOnlyTooltip: Extension = [tooltipField, keypressTooltipPlugin]

0 commit comments

Comments
 (0)