Skip to content

Commit c6568d8

Browse files
committed
color codemirrors properly
1 parent 744a6b1 commit c6568d8

File tree

8 files changed

+500
-55
lines changed

8 files changed

+500
-55
lines changed
File renamed without changes.

src/components/index-page/graphql-advantages/precision.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,19 @@ export function PrecisionFigure() {
9696
className="nextra-codeblocks flex w-full max-w-[100vw] bg-gradient-to-b from-transparent to-sec-lighter px-[14px] py-[30px] *:w-1/2 dark:to-sec-darker/25 max-[380px]:px-0 sm:max-w-[calc(100vw-32px)] xl:px-[46px] max-[380px]:[&_:is(.rounded-t-md,pre)]:rounded-none [&_pre]:!h-48"
9797
aria-hidden
9898
>
99-
<Pre data-filename="Query" className="p-4">
99+
<Pre data-filename="Query" className="p-4 text-[#6E7557]">
100100
{"{"}
101101
{"\n "}
102-
<span className="!text-pri-base dark:!text-pri-light">{"hero"}</span>
102+
<span className="!text-pri-base dark:!text-sec-light">{"hero"}</span>
103103
{" {"}
104-
<span className="!text-pri-base dark:!text-pri-light">
104+
<span className="!text-pri-base dark:!text-sec-light">
105105
{"\n name"}
106106
</span>
107107
{"\n height\n mass".split("").map((char, i) => (
108108
<span
109109
key={i}
110110
id={"ch" + i}
111-
className="hidden !text-pri-base dark:!text-pri-light"
111+
className="hidden !text-pri-base dark:!text-sec-light"
112112
>
113113
{char === "\n" ? <br /> : char}
114114
</span>
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import { EditorView } from "@codemirror/view"
2+
import { Extension } from "@codemirror/state"
3+
import { HighlightStyle, syntaxHighlighting } from "@codemirror/language"
4+
import { tags as t } from "@lezer/highlight"
5+
6+
/// The editor theme styles for One Dark using CSS custom properties.
7+
export const oneDarkTheme = EditorView.theme(
8+
{
9+
"&": {
10+
color: "var(--cm-foreground)",
11+
backgroundColor: "var(--cm-background)",
12+
},
13+
14+
".cm-content": {
15+
caretColor: "var(--cm-cursor)",
16+
},
17+
18+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--cm-cursor)" },
19+
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":
20+
{ backgroundColor: "var(--cm-selection)" },
21+
22+
".cm-panels": {
23+
backgroundColor: "var(--cm-background)",
24+
color: "var(--cm-foreground)",
25+
},
26+
".cm-panels.cm-panels-top": {
27+
borderBottom: "2px solid var(--cm-gutter-border)",
28+
},
29+
".cm-panels.cm-panels-bottom": {
30+
borderTop: "2px solid var(--cm-gutter-border)",
31+
},
32+
33+
".cm-searchMatch": {
34+
backgroundColor: "#72a1ff59",
35+
outline: "1px solid #457dff",
36+
},
37+
".cm-searchMatch.cm-searchMatch-selected": {
38+
backgroundColor: "#6199ff2f",
39+
},
40+
41+
".cm-activeLine": { backgroundColor: "rgba(255, 255, 255, 0.05)" },
42+
".cm-selectionMatch": { backgroundColor: "#aafe661a" },
43+
44+
"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket": {
45+
backgroundColor: "#bad0f847",
46+
},
47+
48+
".cm-gutters": {
49+
backgroundColor: "var(--cm-gutter-background)",
50+
color: "var(--cm-line-number)",
51+
border: "none",
52+
borderRight: "1px solid var(--cm-gutter-border)",
53+
},
54+
55+
".cm-activeLineGutter": {
56+
backgroundColor: "var(--cm-gutter-background)",
57+
},
58+
59+
".cm-foldPlaceholder": {
60+
backgroundColor: "transparent",
61+
border: "none",
62+
color: "#ddd",
63+
},
64+
65+
".cm-tooltip": {
66+
border: "none",
67+
backgroundColor: "var(--cm-hints-background)",
68+
color: "var(--cm-hints-foreground)",
69+
},
70+
".cm-tooltip .cm-tooltip-arrow:before": {
71+
borderTopColor: "transparent",
72+
borderBottomColor: "transparent",
73+
},
74+
".cm-tooltip .cm-tooltip-arrow:after": {
75+
borderTopColor: "var(--cm-hints-background)",
76+
borderBottomColor: "var(--cm-hints-background)",
77+
},
78+
".cm-tooltip-autocomplete": {
79+
"& > ul > li[aria-selected]": {
80+
backgroundColor: "var(--cm-hints-active-background)",
81+
color: "var(--cm-hints-active-foreground)",
82+
},
83+
},
84+
},
85+
{ dark: true },
86+
)
87+
88+
/// The highlighting style for code using CSS custom properties.
89+
export const oneDarkHighlightStyle = HighlightStyle.define([
90+
{ tag: t.keyword, class: "cm-keyword" },
91+
{
92+
tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
93+
class: "cm-def",
94+
},
95+
{ tag: [t.function(t.variableName), t.labelName], class: "cm-variable" },
96+
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], class: "cm-atom" },
97+
{ tag: [t.definition(t.name), t.separator], class: "cm-def" },
98+
{
99+
tag: [
100+
t.typeName,
101+
t.className,
102+
t.number,
103+
t.changed,
104+
t.annotation,
105+
t.modifier,
106+
t.self,
107+
t.namespace,
108+
],
109+
class: "cm-atom",
110+
},
111+
{
112+
tag: [
113+
t.operator,
114+
t.operatorKeyword,
115+
t.url,
116+
t.escape,
117+
t.regexp,
118+
t.link,
119+
t.special(t.string),
120+
],
121+
class: "cm-punctuation",
122+
},
123+
{ tag: [t.meta, t.comment], class: "cm-comment" },
124+
{ tag: t.strong, fontWeight: "bold" },
125+
{ tag: t.emphasis, fontStyle: "italic" },
126+
{ tag: t.strikethrough, textDecoration: "line-through" },
127+
{ tag: t.link, class: "cm-comment", textDecoration: "underline" },
128+
{ tag: t.heading, fontWeight: "bold", class: "cm-def" },
129+
{ tag: [t.atom, t.bool, t.special(t.variableName)], class: "cm-atom" },
130+
{ tag: [t.processingInstruction, t.string, t.inserted], class: "cm-string" },
131+
{ tag: t.invalid, class: "cm-invalidchar" },
132+
{
133+
tag: t.punctuation,
134+
class: "cm-punctuation",
135+
},
136+
])
137+
138+
/// Extension to enable the One Dark theme using CSS custom properties.
139+
export const oneDark: Extension = [
140+
oneDarkTheme,
141+
syntaxHighlighting(oneDarkHighlightStyle),
142+
]

src/components/marked/mini-graphiQL.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default class MiniGraphiQL extends Component<
6262
)
6363

6464
return (
65-
<div className="miniGraphiQL">
65+
<div className="flex text-sm *:w-1/2">
6666
{Object.keys(this.state.variableToType).length > 0 ? (
6767
<div className="hasVariables">
6868
{editor}
@@ -91,10 +91,10 @@ export default class MiniGraphiQL extends Component<
9191
this.setState({
9292
variableToType: getVariableToType(this.props.schema, this.state.query),
9393
})
94-
this._runQuery()
94+
this._runQuery({ manual: true })
9595
}
9696

97-
async _runQuery() {
97+
async _runQuery(options: { manual: boolean }) {
9898
this._editorQueryID++
9999
const queryID = this._editorQueryID
100100
try {
@@ -107,11 +107,17 @@ export default class MiniGraphiQL extends Component<
107107

108108
let resultToSerialize: any = result
109109
if (result.errors) {
110+
if (!options.manual) {
111+
// if the query was ran on edit, we display errors on the left side
112+
// so we can just return instead of showing the resulting error
113+
return
114+
}
115+
110116
// Convert errors to serializable format
111117
const serializedErrors = result.errors.map(error => ({
112118
message: error.message,
113119
locations: error.locations,
114-
path: error.path
120+
path: error.path,
115121
}))
116122
// Replace errors with serialized version for JSON.stringify
117123
resultToSerialize = { ...result, errors: serializedErrors }
@@ -129,6 +135,7 @@ export default class MiniGraphiQL extends Component<
129135

130136
_handleEditQuery(value: string) {
131137
this.setState({ query: value })
138+
void this._runQuery({ manual: false })
132139
}
133140

134141
_handleEditVariables(value: string) {

src/components/marked/query-editor.tsx

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@ import { Component } from "react"
22
import { EditorView, keymap } from "@codemirror/view"
33
import { EditorState } from "@codemirror/state"
44
import { history, historyKeymap, defaultKeymap } from "@codemirror/commands"
5-
import { syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language"
6-
import { autocompletion, completionKeymap } from "@codemirror/autocomplete"
5+
import { bracketMatching } from "@codemirror/language"
6+
import {
7+
autocompletion,
8+
closeBrackets,
9+
completionKeymap,
10+
} from "@codemirror/autocomplete"
711
import { graphql, updateSchema } from "cm6-graphql"
812
import { GraphQLSchema } from "graphql"
13+
import { oneDark } from "./codemirror-one-dark"
14+
import "./syntax-highlighting.css"
915

1016
interface QueryEditorProps {
1117
schema?: GraphQLSchema
1218
value?: string
1319
onEdit?: (value: string) => void
14-
onRunQuery?: () => void
1520
runQuery?: () => void
1621
onHintInformationRender?: (el: HTMLElement) => void
1722
}
@@ -54,38 +59,30 @@ export class QueryEditor extends Component<QueryEditorProps> {
5459
componentDidMount() {
5560
if (!this.domNode) return
5661

57-
// Create key bindings
5862
const runQueryBinding = keymap.of([
5963
{
6064
key: "Cmd-Enter",
61-
run: () => {
62-
if (this.props.onRunQuery) {
63-
this.props.onRunQuery()
64-
}
65-
return true
66-
},
65+
run: () => (this.props.runQuery?.(), true),
6766
},
6867
{
6968
key: "Ctrl-Enter",
70-
run: () => {
71-
if (this.props.onRunQuery) {
72-
this.props.onRunQuery()
73-
}
74-
return true
75-
},
69+
run: () => (this.props.runQuery?.(), true),
7670
},
7771
])
7872

79-
// Create editor state
8073
const state = EditorState.create({
8174
doc: this.props.value || "",
8275
extensions: [
8376
history(),
77+
closeBrackets(),
78+
bracketMatching(),
8479
keymap.of([...historyKeymap, ...completionKeymap, ...defaultKeymap]),
8580
runQueryBinding,
86-
syntaxHighlighting(defaultHighlightStyle),
87-
graphql(this.props.schema),
88-
autocompletion(),
81+
oneDark,
82+
graphql(this.props.schema, {}),
83+
autocompletion({
84+
icons: false,
85+
}),
8986
EditorView.updateListener.of(update => {
9087
if (update.docChanged && !this.ignoreChangeEvent) {
9188
this.cachedValue = update.state.doc.toString()
@@ -94,15 +91,6 @@ export class QueryEditor extends Component<QueryEditorProps> {
9491
}
9592
}
9693
}),
97-
EditorView.theme({
98-
".cm-editor": {
99-
fontSize: "inherit",
100-
fontFamily: "inherit",
101-
},
102-
".cm-focused": {
103-
outline: "none",
104-
},
105-
}),
10694
],
10795
})
10896

src/components/marked/result-viewer.tsx

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { Component } from "react"
22
import { EditorView } from "@codemirror/view"
33
import { EditorState } from "@codemirror/state"
44
import { json } from "@codemirror/lang-json"
5-
import { syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language"
5+
import { oneDark } from "./codemirror-one-dark"
6+
7+
import "./syntax-highlighting.css"
68

79
interface ResultViewerProps {
810
value?: string
@@ -28,21 +30,7 @@ export class ResultViewer extends Component<ResultViewerProps> {
2830
// Create read-only editor state for JSON results
2931
const state = EditorState.create({
3032
doc: this.props.value || "",
31-
extensions: [
32-
EditorState.readOnly.of(true),
33-
EditorView.editable.of(false),
34-
json(),
35-
syntaxHighlighting(defaultHighlightStyle),
36-
EditorView.theme({
37-
".cm-editor": {
38-
fontSize: "inherit",
39-
fontFamily: "inherit",
40-
},
41-
".cm-focused": {
42-
outline: "none",
43-
},
44-
}),
45-
],
33+
extensions: [EditorState.readOnly.of(true), json(), oneDark],
4634
})
4735

4836
// Create editor view

0 commit comments

Comments
 (0)