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

View File

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

View File

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

View File

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

View File

@@ -146,7 +146,6 @@ export function generateColorVariant(
lightnessMod > 0 lightnessMod > 0
? hsl[2] + (100 * whitePoint - hsl[2]) * lightnessMod ? hsl[2] + (100 * whitePoint - hsl[2]) * lightnessMod
: hsl[2] + hsl[2] * (1 - blackPoint) * lightnessMod; : hsl[2] + hsl[2] * (1 - blackPoint) * lightnessMod;
console.log('NEWL', color, newL);
return `hsl(${hsl[0]},${hsl[1]}%,${newL.toFixed(1)}%)`; return `hsl(${hsl[0]},${hsl[1]}%,${newL.toFixed(1)}%)`;
} }