Better request delete and formatting

This commit is contained in:
Gregory Schier
2023-03-15 09:41:38 -07:00
parent 8915915c47
commit 264e64a996
7 changed files with 76 additions and 41 deletions

View File

@@ -1,11 +1,12 @@
import { defaultKeymap } from '@codemirror/commands';
import { Compartment, EditorState } from '@codemirror/state';
import { keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view';
import { keymap, placeholder as placeholderExt, tooltips, ViewPlugin } from '@codemirror/view';
import classnames from 'classnames';
import { EditorView } from 'codemirror';
import type { MutableRefObject } from 'react';
import { useEffect, useRef } from 'react';
import { useUnmount } from 'react-use';
import { useEffect, useMemo, useRef } from 'react';
import { useMount, useUnmount } from 'react-use';
import { IconButton } from '../IconButton';
import './Editor.css';
import { baseExtensions, getLanguageExtension, multiLineExtensions } from './extensions';
import { singleLineExt } from './singleLine';
@@ -24,6 +25,7 @@ export interface _EditorProps {
onChange?: (value: string) => void;
onFocus?: () => void;
singleLine?: boolean;
format?: (v: string) => string;
}
export function _Editor({
@@ -38,6 +40,7 @@ export function _Editor({
onFocus,
className,
singleLine,
format,
}: _EditorProps) {
const cm = useRef<{ view: EditorView; languageCompartment: Compartment } | null>(null);
const wrapperRef = useRef<HTMLDivElement | null>(null);
@@ -109,18 +112,47 @@ export function _Editor({
syncGutterBg({ parent: wrapperRef.current, className });
}, [className]);
const cmContainer = useMemo(
() => (
<div
ref={wrapperRef}
dangerouslySetInnerHTML={{ __html: '' }}
className={classnames(
className,
'cm-wrapper text-base bg-gray-50',
heightMode === 'auto' ? 'cm-auto-height' : 'cm-full-height',
singleLine ? 'cm-singleline' : 'cm-multiline',
readOnly && 'cm-readonly',
)}
/>
),
[],
);
if (singleLine) {
return cmContainer;
}
return (
<div
ref={wrapperRef}
dangerouslySetInnerHTML={{ __html: '' }}
className={classnames(
className,
'cm-wrapper text-base bg-gray-50',
heightMode === 'auto' ? 'cm-auto-height' : 'cm-full-height',
singleLine ? 'cm-singleline' : 'cm-multiline',
readOnly && 'cm-readonly',
<div className="group relative h-full w-full">
{cmContainer}
{format && (
<IconButton
size="sm"
title="Re-format"
icon="magicWand"
className="absolute bottom-2 right-0 transition-opacity opacity-0 group-hover:opacity-70"
onClick={() => {
if (cm.current === null) return;
const { doc } = cm.current.view.state;
const insert = format(doc.toString());
// Update editor and blur because the cursor will reset anyway
cm.current.view.dispatch({ changes: { from: 0, to: doc.length, insert } });
cm.current.view.contentDOM.blur();
}}
/>
)}
/>
</div>
);
}

View File

@@ -22,6 +22,7 @@ import {
TriangleRightIcon,
UpdateIcon,
RowsIcon,
MagicWandIcon,
} from '@radix-ui/react-icons';
import classnames from 'classnames';
@@ -48,6 +49,7 @@ const icons = {
triangleLeft: TriangleLeftIcon,
triangleRight: TriangleRightIcon,
update: UpdateIcon,
magicWand: MagicWandIcon,
x: Cross2Icon,
};
@@ -66,8 +68,8 @@ export function Icon({ icon, spin, size = 'md', className }: IconProps) {
className,
'text-inherit',
size === 'md' && 'h-4 w-4',
size === 'sm' && 'h-3 w-3',
size === 'xs' && 'h-2 w-2',
size === 'sm' && 'h-3.5 w-3.5',
size === 'xs' && 'h-3 w-3',
spin && 'animate-spin',
)}
/>