Read-only editor

This commit is contained in:
Gregory Schier
2023-03-08 16:53:13 -08:00
parent 956a2ef5ce
commit c37cfaf0e4
5 changed files with 79 additions and 77 deletions

View File

@@ -1,83 +1,85 @@
.cm-wrapper {
@apply h-full;
}
.cm-editor {
@apply w-full block text-base;
.cm-editor {
@apply w-full block text-base;
* {
@apply cursor-text;
}
* {
@apply cursor-text;
}
&.cm-focused {
outline: none !important;
}
&.cm-focused {
outline: none !important;
}
.cm-line {
@apply text-gray-900 pl-1 pr-1.5;
}
.cm-selectionBackground {
@apply bg-gray-300;
}
.cm-placeholder {
@apply text-placeholder;
}
.cm-line {
@apply text-gray-900 pl-1 pr-1.5;
}
.cm-gutters {
@apply border-0 text-gray-500 text-opacity-30;
.cm-placeholder {
@apply text-placeholder;
}
.cm-gutterElement {
@apply cursor-default;
.cm-gutters {
@apply border-0 text-gray-500 text-opacity-30;
.cm-gutterElement {
@apply cursor-default;
}
}
&.cm-focused .cm-gutters {
@apply text-opacity-60;
}
.placeholder-widget {
@apply text-[0.9em] text-gray-800 dark:text-gray-1000 px-1 rounded cursor-default dark:shadow;
/* NOTE: Background and border are translucent so we can see text selection through it */
@apply bg-gray-300/40 border border-gray-300 border-opacity-40 hover:border-opacity-80;
/* Bring above on hover */
@apply hover:z-10 relative;
}
}
&.cm-focused .cm-gutters,
.cm-gutters:hover {
@apply text-opacity-60;
&.cm-singleline {
.cm-editor {
@apply h-full w-full;
}
.cm-scroller {
@apply font-mono flex text-[0.8rem];
align-items: center !important;
overflow: hidden !important;
}
.cm-line {
@apply px-0;
}
}
.placeholder-widget {
@apply text-[0.9em] text-gray-800 dark:text-gray-1000 px-1 rounded cursor-default dark:shadow;
&.cm-multiline {
&.cm-full-height {
@apply relative;
/* NOTE: Background and border are translucent so we can see text selection through it */
@apply bg-gray-300/40 border border-gray-300 border-opacity-40 hover:border-opacity-80;
/* Bring above on hover */
@apply hover:z-10 relative;
}
}
.cm-singleline {
.cm-editor {
@apply h-full w-full;
}
.cm-scroller {
@apply font-mono flex text-[0.8rem];
align-items: center !important;
overflow: hidden !important;
}
.cm-line {
@apply px-0;
}
}
.cm-multiline {
&.cm-full-height {
@apply relative;
.cm-editor {
@apply inset-0 absolute;
position: absolute !important;
}
}
.cm-editor {
@apply inset-0 absolute;
position: absolute !important;
@apply h-full;
}
}
.cm-editor {
@apply h-full;
}
.cm-scroller {
@apply font-mono text-[0.75rem];
.cm-scroller {
@apply font-mono text-[0.75rem];
}
}
}
@@ -115,20 +117,13 @@
@apply bg-transparent;
}
.cm-editor.cm-focused .cm-activeLineGutter {
@apply text-gray-800;
}
.cm-editor .cm-cursor {
@apply border-l-2 border-gray-800;
}
.cm-editor .cm-selectionBackground {
@apply bg-gray-200/70;
}
.cm-editor.cm-focused .cm-selectionBackground {
@apply bg-gray-200;
.cm-wrapper:not(.cm-readonly) .cm-editor {
&.cm-focused .cm-activeLineGutter {
@apply text-gray-800;
}
.cm-cursor {
@apply border-l-2 border-gray-800;
}
}
.cm-singleline .cm-editor {

View File

@@ -10,6 +10,7 @@ import { baseExtensions, getLanguageExtension, multiLineExtensions } from './ext
import { singleLineExt } from './singleLine';
export interface EditorProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
readOnly?: boolean;
heightMode?: 'auto' | 'full';
contentType?: string;
autoFocus?: boolean;
@@ -23,6 +24,7 @@ export interface EditorProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onCha
}
export default function Editor({
readOnly,
heightMode,
contentType,
autoFocus,
@@ -41,6 +43,7 @@ export default function Editor({
() =>
getExtensions({
container: ref.current,
readOnly,
placeholder,
singleLine,
onChange,
@@ -116,6 +119,7 @@ export default function Editor({
'cm-wrapper text-base bg-background',
heightMode === 'auto' ? 'cm-auto-height' : 'cm-full-height',
singleLine ? 'cm-singleline' : 'cm-multiline',
readOnly && 'cm-readonly',
)}
{...props}
/>
@@ -124,6 +128,7 @@ export default function Editor({
function getExtensions({
container,
readOnly,
singleLine,
placeholder,
onChange,
@@ -131,7 +136,7 @@ function getExtensions({
useTemplating,
}: Pick<
EditorProps,
'singleLine' | 'onChange' | 'contentType' | 'useTemplating' | 'placeholder'
'singleLine' | 'onChange' | 'contentType' | 'useTemplating' | 'placeholder' | 'readOnly'
> & { container: HTMLDivElement | null }) {
const ext = getLanguageExtension({ contentType, useTemplating });
@@ -148,6 +153,7 @@ function getExtensions({
...(singleLine ? [singleLineExt()] : []),
...(!singleLine ? [multiLineExtensions] : []),
...(ext ? [ext] : []),
...(readOnly ? [EditorState.readOnly.of(true)] : []),
...(placeholder ? [placeholderExt(placeholder)] : []),
...(singleLine

View File

@@ -34,6 +34,7 @@ import {
} from '@codemirror/view';
import { tags as t } from '@lezer/highlight';
import { debouncedAutocompletionDisplay } from './autocomplete';
import { readOnlyTransactionFilter } from './readOnlyTransactionFilter';
import { twig } from './twig/extension';
import { url } from './url/extension';

View File

@@ -130,6 +130,7 @@ export function ResponsePane({ requestId, className }: Props) {
</div>
) : response?.body ? (
<Editor
readOnly
className="bg-gray-50 dark:!bg-gray-100"
valueKey={`${contentType}:${response.updatedAt}`}
defaultValue={response?.body}