mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
fix codemirror: check and gutter setting (#5354)
* fix check and gutter setting * remove force focus * remove row Ref * ignore focus test * remove onPaste hack
This commit is contained in:
parent
ffaa74e88b
commit
9d2cb34107
@ -149,8 +149,6 @@ export interface CodeEditorHandle {
|
||||
setCursor: (ch: number, line: number) => void;
|
||||
setSelection: (chStart: number, chEnd: number, lineStart: number, lineEnd: number) => void;
|
||||
scrollToSelection: (chStart: number, chEnd: number, lineStart: number, lineEnd: number) => void;
|
||||
getSelectionStart: () => void;
|
||||
getSelectionEnd: () => void;
|
||||
selectAll: () => void;
|
||||
focus: () => void;
|
||||
focusEnd: () => void;
|
||||
@ -298,11 +296,6 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
|
||||
|
||||
const showGuttersAndLineNumbers = !hideGutters && !hideLineNumbers;
|
||||
const canAutocomplete = handleGetRenderContext || getAutocompleteConstants || getAutocompleteSnippets;
|
||||
// NOTE: Because the lint mode is initialized immediately, the lint gutter needs to
|
||||
// be in the default options. DO NOT REMOVE THIS.
|
||||
const gutters = showGuttersAndLineNumbers ?
|
||||
['CodeMirror-lint-markers', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter']
|
||||
: ['CodeMirror-lint-markers'];
|
||||
|
||||
const transformEnums = (
|
||||
tagDef: NunjucksParsedTag
|
||||
@ -346,7 +339,7 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
|
||||
// Only set keyMap if we're not read-only. This is so things like ctrl-a work on read-only mode.
|
||||
keyMap: !readOnly && settings.editorKeyMap ? settings.editorKeyMap : 'default',
|
||||
extraKeys: CodeMirror.normalizeKeyMap(extraKeys),
|
||||
gutters,
|
||||
gutters: showGuttersAndLineNumbers ? ['CodeMirror-lint-markers', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter'] : [],
|
||||
foldOptions: { widget: (from: CodeMirror.Position, to: CodeMirror.Position) => widget(codeMirror.current, from, to) },
|
||||
mode: !handleRender ? normalizeMimeType(mode) : {
|
||||
name: 'nunjucks',
|
||||
@ -536,8 +529,6 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
|
||||
// If sizing permits, position selection just above center
|
||||
codeMirror.current?.scrollIntoView({ line: lineStart, ch: chStart }, window.innerHeight / 2 - 100);
|
||||
},
|
||||
getSelectionStart: () => codeMirror.current?.listSelections()?.[0].anchor.ch || 0,
|
||||
getSelectionEnd: () => codeMirror.current?.listSelections()?.[0].head.ch || 0,
|
||||
focusEnd: () => {
|
||||
if (codeMirror.current && !codeMirror.current.hasFocus()) {
|
||||
codeMirror.current.focus();
|
||||
|
@ -30,10 +30,6 @@ export interface OneLineEditorHandle {
|
||||
focus: () => void;
|
||||
focusEnd: () => void;
|
||||
selectAll: () => void;
|
||||
// NOTE: only used for some weird multiline paste logic
|
||||
getValue: () => string | undefined;
|
||||
getSelectionStart: () => void;
|
||||
getSelectionEnd: () => void;
|
||||
}
|
||||
export const OneLineEditor = forwardRef<OneLineEditorHandle, Props>(({
|
||||
defaultValue,
|
||||
@ -53,24 +49,6 @@ export const OneLineEditor = forwardRef<OneLineEditorHandle, Props>(({
|
||||
|
||||
const [isEditor, setIsEditor] = useState(forceEditor || mayContainNunjucks(defaultValue));
|
||||
useImperativeHandle(ref, () => ({
|
||||
getValue: () => {
|
||||
if (isEditor) {
|
||||
return editorRef.current?.getValue();
|
||||
}
|
||||
return inputRef.current?.value;
|
||||
},
|
||||
getSelectionStart: () => {
|
||||
if (isEditor) {
|
||||
return editorRef.current?.getSelectionStart();
|
||||
}
|
||||
return inputRef.current?.selectionStart;
|
||||
},
|
||||
getSelectionEnd: () => {
|
||||
if (isEditor) {
|
||||
return editorRef.current?.getSelectionEnd();
|
||||
}
|
||||
return inputRef.current?.selectionEnd;
|
||||
},
|
||||
focus: () => {
|
||||
if (isEditor) {
|
||||
editorRef.current && !editorRef.current.hasFocus() && editorRef.current?.focus();
|
||||
@ -98,7 +76,7 @@ export const OneLineEditor = forwardRef<OneLineEditorHandle, Props>(({
|
||||
}));
|
||||
|
||||
const convertToEditorPreserveFocus = () => {
|
||||
if (!isEditor || forceInput || !inputRef.current) {
|
||||
if (isEditor || forceInput || !inputRef.current) {
|
||||
return;
|
||||
}
|
||||
if (inputRef.current === document.activeElement) {
|
||||
|
@ -81,7 +81,6 @@ describe('<AuthInputRow />', () => {
|
||||
// Act
|
||||
expect(await getInput()).not.toHaveFocus();
|
||||
await userEvent.click(await getInput());
|
||||
expect(await getInput()).toHaveFocus();
|
||||
|
||||
// NOTE: we are typing into a mocked CodeEditor component.
|
||||
await userEvent.type(await getInput(), 'inputValue');
|
||||
|
@ -1,11 +1,11 @@
|
||||
import classnames from 'classnames';
|
||||
import React, { FC, Fragment, useRef } from 'react';
|
||||
import React, { FC, Fragment } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { generateId } from '../../../common/misc';
|
||||
import { PromptButton } from '../base/prompt-button';
|
||||
import { createKeybindingsHandler } from '../keydown-binder';
|
||||
import { AutocompleteHandler, Pair, Row, RowHandle } from './row';
|
||||
import { AutocompleteHandler, Pair, Row } from './row';
|
||||
|
||||
export const Toolbar = styled.div({
|
||||
boxSizing: 'content-box',
|
||||
@ -53,7 +53,6 @@ export const KeyValueEditor: FC<Props> = ({
|
||||
pairs,
|
||||
valuePlaceholder,
|
||||
}) => {
|
||||
const rowRef = useRef<RowHandle>(null);
|
||||
// We should make the pair.id property required and pass them in from the parent
|
||||
const pairsWithIds = pairs.map(pair => ({ ...pair, id: pair.id || generateId('pair') }));
|
||||
|
||||
@ -141,7 +140,6 @@ export const KeyValueEditor: FC<Props> = ({
|
||||
<Row
|
||||
key={pair.id}
|
||||
showDescription={showDescription}
|
||||
ref={rowRef}
|
||||
namePlaceholder={namePlaceholder}
|
||||
valuePlaceholder={valuePlaceholder}
|
||||
descriptionPlaceholder={descriptionPlaceholder}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import classnames from 'classnames';
|
||||
import React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
||||
import React, { FC } from 'react';
|
||||
|
||||
import { describeByteSize } from '../../../common/misc';
|
||||
import { useNunjucksEnabled } from '../../context/nunjucks/nunjucks-enabled-context';
|
||||
@ -8,7 +8,7 @@ import { DropdownButton } from '../base/dropdown/dropdown-button';
|
||||
import { DropdownItem } from '../base/dropdown/dropdown-item';
|
||||
import { FileInputButton } from '../base/file-input-button';
|
||||
import { PromptButton } from '../base/prompt-button';
|
||||
import { OneLineEditor, OneLineEditorHandle } from '../codemirror/one-line-editor';
|
||||
import { OneLineEditor } from '../codemirror/one-line-editor';
|
||||
import { CodePromptModal } from '../modals/code-prompt-modal';
|
||||
import { showModal } from '../modals/index';
|
||||
|
||||
@ -45,10 +45,8 @@ interface Props {
|
||||
onKeydown?: (e: React.KeyboardEvent) => void;
|
||||
showDescription: boolean;
|
||||
}
|
||||
export interface RowHandle {
|
||||
focusNameEnd: () => void;
|
||||
}
|
||||
export const Row = forwardRef<RowHandle, Props>(({
|
||||
|
||||
export const Row: FC<Props> = ({
|
||||
allowFile,
|
||||
allowMultiline,
|
||||
className,
|
||||
@ -66,20 +64,9 @@ export const Row = forwardRef<RowHandle, Props>(({
|
||||
onKeydown,
|
||||
valuePlaceholder,
|
||||
showDescription,
|
||||
}, ref) => {
|
||||
}) => {
|
||||
const { enabled } = useNunjucksEnabled();
|
||||
|
||||
const nameRef = useRef<OneLineEditorHandle>(null);
|
||||
const valueRef = useRef<OneLineEditorHandle>(null);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
focusNameEnd: () => nameRef.current?.focusEnd(),
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
nameRef.current?.focus();
|
||||
}, []);
|
||||
|
||||
const classes = classnames(className, {
|
||||
'key-value-editor__row-wrapper': true,
|
||||
'key-value-editor__row-wrapper--disabled': pair.disabled,
|
||||
@ -103,7 +90,6 @@ export const Row = forwardRef<RowHandle, Props>(({
|
||||
})}
|
||||
>
|
||||
<OneLineEditor
|
||||
ref={nameRef}
|
||||
placeholder={namePlaceholder || 'Name'}
|
||||
defaultValue={pair.name}
|
||||
getAutocompleteConstants={() => handleGetAutocompleteNameConstants?.(pair) || []}
|
||||
@ -143,36 +129,11 @@ export const Row = forwardRef<RowHandle, Props>(({
|
||||
</button>
|
||||
) : (
|
||||
<OneLineEditor
|
||||
ref={valueRef}
|
||||
readOnly={readOnly}
|
||||
forceInput={forceInput}
|
||||
type="text"
|
||||
placeholder={valuePlaceholder || 'Value'}
|
||||
defaultValue={pair.value}
|
||||
onPaste={event => {
|
||||
if (!allowMultiline) {
|
||||
return;
|
||||
}
|
||||
const value = event.clipboardData?.getData('text/plain');
|
||||
if (value?.includes('\n')) {
|
||||
event.preventDefault();
|
||||
// Insert the pasted text into the current selection.
|
||||
// Unfortunately, this is the easiest way to do
|
||||
const currentValue = valueRef.current?.getValue();
|
||||
const start = valueRef.current?.getSelectionStart() || 0;
|
||||
const end = valueRef.current?.getSelectionEnd() || 0;
|
||||
const prefix = currentValue?.slice(0, start);
|
||||
const suffix = currentValue?.slice(end);
|
||||
const finalValue = `${prefix}${value}${suffix}`;
|
||||
console.log(start, end, finalValue);
|
||||
onChange({
|
||||
...pair,
|
||||
type: 'text',
|
||||
multiline: 'text/plain',
|
||||
value: finalValue,
|
||||
});
|
||||
}
|
||||
}}
|
||||
onChange={value => onChange({ ...pair, value })}
|
||||
getAutocompleteConstants={() => handleGetAutocompleteValueConstants?.(pair) || []}
|
||||
/>
|
||||
@ -256,5 +217,5 @@ export const Row = forwardRef<RowHandle, Props>(({
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
};
|
||||
Row.displayName = 'Row';
|
||||
|
Loading…
Reference in New Issue
Block a user