ui(admin): too many changes, not enough commits

This commit is contained in:
Matthew Penner 2021-05-20 16:00:46 -06:00
parent bca2338863
commit 8aa9641ec2
44 changed files with 1955 additions and 334 deletions

View file

@ -0,0 +1,99 @@
import React, { useCallback, useState } from 'react';
import styled from 'styled-components/macro';
import tw, { TwStyle } from 'twin.macro';
import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets';
import { defaultKeymap, defaultTabBinding } from '@codemirror/commands';
import { commentKeymap } from '@codemirror/comment';
import { foldGutter, foldKeymap } from '@codemirror/fold';
import { lineNumbers, highlightActiveLineGutter } from '@codemirror/gutter';
import { defaultHighlightStyle } from '@codemirror/highlight';
import { history, historyKeymap } from '@codemirror/history';
import { indentOnInput, LezerLanguage } from '@codemirror/language';
import { lintKeymap } from '@codemirror/lint';
import { bracketMatching } from '@codemirror/matchbrackets';
import { rectangularSelection } from '@codemirror/rectangular-selection';
import { searchKeymap, highlightSelectionMatches } from '@codemirror/search';
import { Extension, EditorState } from '@codemirror/state';
import { StreamLanguage, StreamParser } from '@codemirror/stream-parser';
import { keymap, highlightSpecialChars, drawSelection, highlightActiveLine, EditorView } from '@codemirror/view';
import { ayuMirage } from '@/components/elements/EditorTheme';
const extensions: Extension = [
ayuMirage,
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter(),
drawSelection(),
EditorState.allowMultipleSelections.of(true),
indentOnInput(),
defaultHighlightStyle.fallback,
bracketMatching(),
closeBrackets(),
autocompletion(),
rectangularSelection(),
highlightActiveLine(),
highlightSelectionMatches(),
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...foldKeymap,
...commentKeymap,
...completionKeymap,
...lintKeymap,
defaultTabBinding,
]),
EditorState.tabSize.of(4),
];
const EditorContainer = styled.div<{ overrides?: TwStyle }>`
min-height: 12rem;
${tw`relative`};
& > div {
${props => props.overrides};
&.cm-focused {
outline: none;
}
}
`;
export interface Props {
className?: string;
overrides?: TwStyle;
mode: LezerLanguage | StreamParser<any>;
initialContent?: string;
}
export default ({ className, overrides, mode, initialContent }: Props) => {
const [ state ] = useState<EditorState>(EditorState.create({
doc: initialContent,
extensions: [ ...extensions, (mode instanceof LezerLanguage) ? mode : StreamLanguage.define(mode) ],
}));
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [ view, setView ] = useState<EditorView>();
const ref = useCallback((node) => {
if (!node) {
return;
}
const view = new EditorView({
state: state,
parent: node,
});
setView(view);
}, []);
return (
<EditorContainer className={className} overrides={overrides} ref={ref}/>
);
};

View file

@ -0,0 +1,144 @@
import { EditorView } from '@codemirror/view';
import { Extension } from '@codemirror/state';
import { HighlightStyle, tags as t } from '@codemirror/highlight';
const highlightBackground = 'transparent';
const background = '#1F2430';
const selection = '#34455A';
const cursor = '#FFCC66';
export const ayuMirageTheme = EditorView.theme({
'&': {
color: '#CBCCC6',
backgroundColor: background,
},
'.cm-content': {
caretColor: cursor,
},
'&.cm-focused .cm-cursor': { borderLeftColor: cursor },
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection': { backgroundColor: selection },
'.cm-panels': { backgroundColor: '#232834', color: '#CBCCC6' },
'.cm-panels.cm-panels-top': { borderBottom: '2px solid black' },
'.cm-panels.cm-panels-bottom': { borderTop: '2px solid black' },
'.cm-searchMatch': {
backgroundColor: '#72a1ff59',
outline: '1px solid #457dff',
},
'.cm-searchMatch.cm-searchMatch-selected': {
backgroundColor: '#6199ff2f',
},
'.cm-activeLine': { backgroundColor: highlightBackground },
'.cm-selectionMatch': { backgroundColor: '#aafe661a' },
'.cm-matchingBracket, .cm-nonmatchingBracket': {
backgroundColor: '#bad0f847',
outline: '1px solid #515a6b',
},
'.cm-gutters': {
backgroundColor: 'transparent',
color: '#FF3333',
border: 'none',
},
'.cm-gutterElement': {
color: 'rgba(61, 66, 77, 99)',
},
'.cm-activeLineGutter': {
backgroundColor: highlightBackground,
},
'.cm-foldPlaceholder': {
backgroundColor: 'transparent',
border: 'none',
color: '#ddd',
},
'.cm-tooltip': {
border: '1px solid #181a1f',
backgroundColor: '#232834',
},
'.cm-tooltip-autocomplete': {
'& > ul > li[aria-selected]': {
backgroundColor: highlightBackground,
color: '#CBCCC6',
},
},
}, { dark: true });
export const ayuMirageHighlightStyle = HighlightStyle.define([
{
tag: t.keyword,
color: '#FFA759',
},
{
tag: [ t.name, t.deleted, t.character, t.propertyName, t.macroName ],
color: '#5CCFE6',
},
{
tag: [ t.function(t.variableName), t.labelName ],
color: '#CBCCC6',
},
{
tag: [ t.color, t.constant(t.name), t.standard(t.name) ],
color: '#F29E74',
},
{
tag: [ t.definition(t.name), t.separator ],
color: '#CBCCC6B3',
},
{
tag: [ t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace ],
color: '#FFCC66',
},
{
tag: [ t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string) ],
color: '#5CCFE6',
},
{
tag: [ t.meta, t.comment ],
color: '#5C6773',
},
{
tag: t.strong,
fontWeight: 'bold',
},
{
tag: t.emphasis,
fontStyle: 'italic',
},
{
tag: t.strikethrough,
textDecoration: 'line-through',
},
{
tag: t.link,
color: '#FF3333',
textDecoration: 'underline',
},
{
tag: t.heading,
fontWeight: 'bold',
color: '#BAE67E',
},
{
tag: [ t.atom, t.bool, t.special(t.variableName) ],
color: '#5CCFE6',
},
{
tag: [ t.processingInstruction, t.string, t.inserted ],
color: '#BAE67E',
},
{
tag: t.invalid,
color: '#FF3333',
},
]);
export const ayuMirage: Extension = [ ayuMirageTheme, ayuMirageHighlightStyle ];

View file

@ -43,7 +43,7 @@ const inputStyle = css<Props>`
& + .input-help {
${tw`mt-1 text-xs`};
${props => props.hasError ? tw`text-red-200` : tw`text-neutral-200`};
${props => props.hasError ? tw`text-red-200` : tw`text-neutral-400`};
}
&:required, &:invalid {