diff --git a/packages/@sanity/vision/src/components/ParamsEditor.tsx b/packages/@sanity/vision/src/components/ParamsEditor.tsx index cbf02b8281b..0686c05e101 100644 --- a/packages/@sanity/vision/src/components/ParamsEditor.tsx +++ b/packages/@sanity/vision/src/components/ParamsEditor.tsx @@ -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' @@ -18,6 +18,7 @@ export interface ParamsEditorChangeEvent { export interface ParamsEditorProps { value: string onChange: (changeEvt: ParamsEditorChangeEvent) => void + onPasteCapture: (event: ClipboardEvent) => void } export interface ParamsEditorChange { @@ -25,7 +26,7 @@ export interface ParamsEditorChange { } 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) @@ -49,7 +50,13 @@ export function ParamsEditor(props: ParamsEditorProps) { ) const handleChange = useMemo(() => debounce(handleChangeRaw, 333), [handleChangeRaw]) - return + return ( + + ) } function eventFromValue( diff --git a/packages/@sanity/vision/src/components/VisionGui.tsx b/packages/@sanity/vision/src/components/VisionGui.tsx index 11823bfb8b6..7db5d1bf068 100644 --- a/packages/@sanity/vision/src/components/VisionGui.tsx +++ b/packages/@sanity/vision/src/components/VisionGui.tsx @@ -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' @@ -256,12 +257,13 @@ export class VisionGui extends PureComponent { 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() { @@ -302,8 +304,8 @@ export class VisionGui extends PureComponent { } } - handlePaste(evt: ClipboardEvent) { - if (!evt.clipboardData) { + handlePaste(evt: React.ClipboardEvent | ClipboardEvent, stopPropagation = false) { + if (!evt?.clipboardData) { return } @@ -340,7 +342,7 @@ export class VisionGui extends PureComponent { ? parts.options.perspective : undefined - if (!isSupportedPerspective(parts.options.perspective)) { + if (perspective && !isSupportedPerspective(perspective)) { this.props.toast.push({ closable: true, id: 'vision-paste-unsupported-perspective', @@ -350,6 +352,10 @@ export class VisionGui extends PureComponent { } 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, @@ -385,6 +391,10 @@ export class VisionGui extends PureComponent { ) } + handleOnPasteCapture(ev: React.ClipboardEvent) { + this.handlePaste(ev, true) + } + cancelQuery() { if (!this._querySubscription) { return @@ -846,7 +856,11 @@ export class VisionGui extends PureComponent { {t('query.label')} - + @@ -865,7 +879,11 @@ export class VisionGui extends PureComponent { )} - + {/* Controls (listen/run) */}