Skip to content

Commit

Permalink
fix(vision): debounce type setState to fix cursor jump (#8238)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrobonamin authored Jan 14, 2025
1 parent 0ab9c5b commit 15cba9a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
13 changes: 10 additions & 3 deletions packages/@sanity/vision/src/components/ParamsEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {debounce} from 'lodash'
import {useCallback, useEffect, useMemo, useState} from 'react'
import {type ClipboardEvent, useCallback, useEffect, useMemo, useState} from 'react'
import {type TFunction, useTranslation} from 'sanity'

import {VisionCodeMirror} from '../codemirror/VisionCodeMirror'
Expand All @@ -18,14 +18,15 @@ export interface ParamsEditorChangeEvent {
export interface ParamsEditorProps {
value: string
onChange: (changeEvt: ParamsEditorChangeEvent) => void
onPasteCapture: (event: ClipboardEvent<HTMLDivElement>) => void
}

export interface ParamsEditorChange {
valid: boolean
}

export function ParamsEditor(props: ParamsEditorProps) {
const {onChange} = props
const {onChange, onPasteCapture} = props
const {t} = useTranslation(visionLocaleNamespace)
const {raw: value, error, parsed, valid} = eventFromValue(props.value, t)
const [isValid, setValid] = useState(valid)
Expand All @@ -49,7 +50,13 @@ export function ParamsEditor(props: ParamsEditorProps) {
)

const handleChange = useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw])
return <VisionCodeMirror value={props.value || defaultValue} onChange={handleChange} />
return (
<VisionCodeMirror
value={props.value || defaultValue}
onChange={handleChange}
onPasteCapture={onPasteCapture}
/>
)
}

function eventFromValue(
Expand Down
30 changes: 24 additions & 6 deletions packages/@sanity/vision/src/components/VisionGui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Tooltip,
} from '@sanity/ui'
import {isHotkey} from 'is-hotkey-esm'
import {debounce} from 'lodash'
import {type ChangeEvent, createRef, PureComponent, type RefObject} from 'react'
import {type TFunction, Translate} from 'sanity'

Expand Down Expand Up @@ -256,12 +257,13 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
this.handleListenExecution = this.handleListenExecution.bind(this)
this.handleListenerEvent = this.handleListenerEvent.bind(this)
this.handleQueryExecution = this.handleQueryExecution.bind(this)
this.handleQueryChange = this.handleQueryChange.bind(this)
this.handleQueryChange = debounce(this.handleQueryChange, 300).bind(this)
this.handleParamsChange = this.handleParamsChange.bind(this)
this.handleCopyUrl = this.handleCopyUrl.bind(this)
this.handlePaste = this.handlePaste.bind(this)
this.handleKeyDown = this.handleKeyDown.bind(this)
this.handleResize = this.handleResize.bind(this)
this.handleOnPasteCapture = this.handleOnPasteCapture.bind(this)
}

componentDidMount() {
Expand Down Expand Up @@ -302,8 +304,8 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
}
}

handlePaste(evt: ClipboardEvent) {
if (!evt.clipboardData) {
handlePaste(evt: React.ClipboardEvent<HTMLDivElement> | ClipboardEvent, stopPropagation = false) {
if (!evt?.clipboardData) {
return
}

Expand Down Expand Up @@ -340,7 +342,7 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
? parts.options.perspective
: undefined

if (!isSupportedPerspective(parts.options.perspective)) {
if (perspective && !isSupportedPerspective(perspective)) {
this.props.toast.push({
closable: true,
id: 'vision-paste-unsupported-perspective',
Expand All @@ -350,6 +352,10 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
}

evt.preventDefault()
if (stopPropagation) {
// Stops propagation for the pasteEvent that occurs in the CodeMirror element if it has a match
evt.stopPropagation()
}
this.setState(
(prevState) => ({
dataset: this.props.datasets.includes(usedDataset) ? usedDataset : prevState.dataset,
Expand Down Expand Up @@ -385,6 +391,10 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
)
}

handleOnPasteCapture(ev: React.ClipboardEvent<HTMLDivElement>) {
this.handlePaste(ev, true)
}

cancelQuery() {
if (!this._querySubscription) {
return
Expand Down Expand Up @@ -846,7 +856,11 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
<StyledLabel muted>{t('query.label')}</StyledLabel>
</Flex>
</InputBackgroundContainerLeft>
<VisionCodeMirror value={query} onChange={this.handleQueryChange} />
<VisionCodeMirror
value={query}
onChange={this.handleQueryChange}
onPasteCapture={this.handleOnPasteCapture}
/>
</Box>
</InputContainer>
<InputContainer display="flex" ref={this._paramsEditorContainer}>
Expand All @@ -865,7 +879,11 @@ export class VisionGui extends PureComponent<VisionGuiProps, VisionGuiState> {
)}
</Flex>
</InputBackgroundContainerLeft>
<ParamsEditor value={rawParams} onChange={this.handleParamsChange} />
<ParamsEditor
value={rawParams}
onChange={this.handleParamsChange}
onPasteCapture={this.handleOnPasteCapture}
/>
</Card>
{/* Controls (listen/run) */}
<ControlsContainer>
Expand Down

0 comments on commit 15cba9a

Please sign in to comment.