Skip to content

Commit fe79931

Browse files
committed
Update codemirror styles
1 parent 5e3a31e commit fe79931

File tree

15 files changed

+179
-159
lines changed

15 files changed

+179
-159
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"@types/codemirror": "5.60.16",
9494
"@types/hast": "3.0.4",
9595
"@types/node": "^22.10.5",
96-
"@types/react": "^18.3.18",
96+
"@types/react": "^18.3.23",
9797
"@types/rss": "0.0.32",
9898
"@types/string-similarity": "^4.0.2",
9999
"@typescript-eslint/eslint-plugin": "7.18.0",
@@ -111,7 +111,7 @@
111111
"remark-lint-first-heading-level": "3.1.2",
112112
"remark-lint-heading-increment": "3.1.2",
113113
"tsx": "^4.19.4",
114-
"typescript": "^5.8.3"
114+
"typescript": "^5.9.2"
115115
},
116116
"browserslist": [
117117
"chrome >0 and last 2.5 years",

pnpm-lock.yaml

Lines changed: 59 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1+
import { Pre, PreProps } from "../../components/pre"
12
import { getMdxHeadings } from "./get-mdx-headings"
23
import { MdxLink } from "./mdx-link"
34

5+
const MdxPre = (props: PreProps) => {
6+
return (
7+
<Pre
8+
{...props}
9+
containerClassName="[&:not(:first-child)]:_mt-6 bg-white dark:bg-neu-800/[.025]"
10+
className="!rounded-none"
11+
/>
12+
)
13+
}
14+
415
export const mdxComponents = {
516
a: MdxLink,
17+
pre: MdxPre,
618
...getMdxHeadings(),
719
}

src/_design-system/syntax/dark.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "k-colorable dark, based on GitHub Dark",
2+
"name": "k-colorable dark",
33
"type": "dark",
44
"semanticHighlighting": true,
55
"colors": {
@@ -191,7 +191,7 @@
191191
{
192192
"scope": ["comment", "punctuation.definition.comment", "string.comment"],
193193
"settings": {
194-
"foreground": "#6a737d"
194+
"foreground": "#737373"
195195
}
196196
},
197197
{

src/components/interactive-code-block/codemirror-one-dark.tsx renamed to src/components/interactive-code-block/codemirror-theme.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { Extension } from "@codemirror/state"
33
import { HighlightStyle, syntaxHighlighting } from "@codemirror/language"
44
import { tags as t } from "@lezer/highlight"
55

6-
/// The editor theme styles for One Dark using CSS custom properties.
7-
export const oneDarkTheme = EditorView.theme({
6+
export const editorTheme = EditorView.theme({
87
"&": {
98
color: "var(--cm-foreground)",
109
backgroundColor: "var(--cm-background)",
@@ -82,8 +81,7 @@ export const oneDarkTheme = EditorView.theme({
8281
},
8382
})
8483

85-
/// The highlighting style for code using CSS custom properties.
86-
export const oneDarkHighlightStyle = HighlightStyle.define([
84+
export const syntaxTheme = HighlightStyle.define([
8785
{ tag: t.keyword, class: "cm-keyword" },
8886
{
8987
tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
@@ -132,8 +130,7 @@ export const oneDarkHighlightStyle = HighlightStyle.define([
132130
},
133131
])
134132

135-
/// Extension to enable the One Dark theme using CSS custom properties.
136-
export const oneDark: Extension = [
137-
oneDarkTheme,
138-
syntaxHighlighting(oneDarkHighlightStyle),
133+
export const codeMirrorThemeExtension: Extension = [
134+
editorTheme,
135+
syntaxHighlighting(syntaxTheme),
139136
]
Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,5 @@
11
import dynamic from "next/dynamic"
2-
import { StarWarsSchema } from "./swapi-schema"
3-
import { UsersSchema } from "./users-schema"
42

5-
const SCHEMA_MAP = {
6-
StarWars: StarWarsSchema,
7-
Users: UsersSchema,
8-
} as const
9-
10-
type SchemaKey = keyof typeof SCHEMA_MAP
11-
12-
type Metadata = {
13-
graphiql?: boolean
14-
variables?: unknown
15-
schema?: SchemaKey
16-
}
17-
18-
const MiniGraphiQL = dynamic(() => import("./mini-graphiQL"), { ssr: true })
19-
20-
export function Marked({ children }: { children: string }) {
21-
const codeMatch = children.match(/```graphql\s*\n([\s\S]*?)```/)
22-
const blockContent = codeMatch?.[1]
23-
const [firstLine, ...rest] = (blockContent || "").split("\n")
24-
25-
const metaMatch = firstLine.match(/^\s*#\s*({.*})\s*$/)?.[1] ?? "{}"
26-
const meta = JSON.parse(metaMatch) as Metadata
27-
28-
const query = rest.join("\n")
29-
const variables = meta.variables
30-
? JSON.stringify(meta.variables, null, 2)
31-
: ""
32-
const schema = SCHEMA_MAP[meta.schema ?? "StarWars"]
33-
34-
return <MiniGraphiQL schema={schema} query={query} variables={variables} />
35-
}
3+
export const InteractiveCodeBlock = dynamic(() => import("./mini-graphiQL"), {
4+
ssr: true,
5+
})

src/components/interactive-code-block/mini-graphiQL.tsx

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import { QueryEditor } from "./query-editor"
1414
import { VariableEditor } from "./variable-editor"
1515
import { ResultViewer } from "./result-viewer"
1616
import { getVariableToType } from "./get-variable-to-type"
17+
import { StarWarsSchema } from "./swapi-schema"
18+
import { UsersSchema } from "./users-schema"
19+
import { CodeBlockLabel } from "@/components/pre/code-block-label"
1720

1821
export type MiniGraphiQLProps = {
19-
schema: GraphQLSchema
20-
query: string
21-
variables: string
22-
rootValue?: any
22+
children: string
2323
}
2424

2525
interface MiniGraphiQLState {
@@ -29,6 +29,19 @@ interface MiniGraphiQLState {
2929
variableToType: Record<string, string>
3030
}
3131

32+
const SCHEMA_MAP = {
33+
StarWars: StarWarsSchema,
34+
Users: UsersSchema,
35+
} as const
36+
37+
type SchemaKey = keyof typeof SCHEMA_MAP
38+
39+
type Metadata = {
40+
graphiql?: boolean
41+
variables?: unknown
42+
schema?: SchemaKey
43+
}
44+
3245
export default class MiniGraphiQL extends Component<
3346
MiniGraphiQLProps,
3447
MiniGraphiQLState
@@ -37,46 +50,77 @@ export default class MiniGraphiQL extends Component<
3750

3851
_editorQueryID = 0
3952

53+
schema: GraphQLSchema
54+
4055
constructor(props: MiniGraphiQLProps) {
4156
super(props)
42-
const query = props.query.replace(/^\s+/, "")
4357

44-
// Initialize state
58+
const codeMatch = this.props.children.match(/```graphql\s*\n([\s\S]*?)```/)
59+
const blockContent = codeMatch?.[1]
60+
const [firstLine, ...rest] = (blockContent || "").split("\n")
61+
62+
const metaMatch = firstLine.match(/^\s*#\s*({.*})\s*$/)?.[1] ?? "{}"
63+
const meta = JSON.parse(metaMatch) as Metadata
64+
65+
const query = rest.join("\n").replace(/^\s+/, "")
66+
const variables = meta.variables
67+
? JSON.stringify(meta.variables, null, 2)
68+
: ""
69+
this.schema = SCHEMA_MAP[meta.schema ?? "StarWars"]
70+
4571
this.state = {
4672
query: query,
47-
variables: props.variables,
73+
variables: variables,
4874
response: null,
49-
variableToType: getVariableToType(props.schema, query),
75+
variableToType: getVariableToType(this.schema, query),
5076
}
5177
}
5278

5379
render() {
5480
const editor = (
55-
<QueryEditor
56-
key="query-editor"
57-
schema={this.props.schema}
58-
value={this.state.query}
59-
onEdit={this._handleEditQuery.bind(this)}
60-
runQuery={this._runQueryFromEditor.bind(this)}
61-
/>
81+
<div className="flex flex-col">
82+
<CodeBlockLabel
83+
text="Operation"
84+
className="border-b border-neu-200 bg-[--cm-background] dark:border-neu-50"
85+
/>
86+
<QueryEditor
87+
key="query-editor"
88+
schema={this.schema}
89+
value={this.state.query}
90+
onEdit={this._handleEditQuery.bind(this)}
91+
runQuery={this._runQueryFromEditor.bind(this)}
92+
/>
93+
</div>
6294
)
6395

6496
return (
6597
<div className="[&:not(:first-child)]:_mt-6 grid grid-cols-2 border border-neu-200 text-sm dark:border-neu-50">
6698
{Object.keys(this.state.variableToType).length > 0 ? (
67-
<div className="hasVariables">
99+
<div className="hasVariables flex flex-col">
68100
{editor}
69-
<VariableEditor
70-
value={this.state.variables}
71-
variableToType={this.state.variableToType}
72-
onEdit={this._handleEditVariables.bind(this)}
73-
onRunQuery={this._runQuery.bind(this)}
74-
/>
101+
<div className="flex flex-col border-neu-200 dark:border-neu-50">
102+
<CodeBlockLabel
103+
text="Variables"
104+
className="border-b border-neu-200 bg-[--cm-background] dark:border-neu-50"
105+
/>
106+
<VariableEditor
107+
value={this.state.variables}
108+
variableToType={this.state.variableToType}
109+
onEdit={this._handleEditVariables.bind(this)}
110+
onRunQuery={() => void this._runQuery.bind(this)}
111+
/>
112+
</div>
75113
</div>
76114
) : (
77115
editor
78116
)}
79-
<ResultViewer value={this.state.response || undefined} />
117+
<div className="flex flex-col border-l border-neu-200 dark:border-neu-50">
118+
<CodeBlockLabel
119+
text="Response"
120+
className="border-b border-neu-200 bg-[--cm-background] dark:border-neu-50"
121+
/>
122+
<ResultViewer value={this.state.response || undefined} />
123+
</div>
80124
</div>
81125
)
82126
}
@@ -89,7 +133,7 @@ export default class MiniGraphiQL extends Component<
89133

90134
_runQueryFromEditor() {
91135
this.setState({
92-
variableToType: getVariableToType(this.props.schema, this.state.query),
136+
variableToType: getVariableToType(this.schema, this.state.query),
93137
})
94138
this._runQuery({ manual: true })
95139
}
@@ -99,10 +143,9 @@ export default class MiniGraphiQL extends Component<
99143
const queryID = this._editorQueryID
100144
try {
101145
const result = await graphql({
102-
schema: this.props.schema,
146+
schema: this.schema,
103147
source: this.state.query,
104148
variableValues: JSON.parse(this.state.variables || "{}"),
105-
rootValue: this.props.rootValue,
106149
})
107150

108151
let resultToSerialize: any = result

src/components/interactive-code-block/query-editor.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "@codemirror/autocomplete"
1111
import { graphql, updateSchema } from "cm6-graphql"
1212
import { GraphQLSchema } from "graphql"
13-
import { oneDark } from "./codemirror-one-dark"
13+
import { codeMirrorThemeExtension } from "./codemirror-theme"
1414
import "./syntax-highlighting.css"
1515

1616
interface QueryEditorProps {
@@ -78,7 +78,7 @@ export class QueryEditor extends Component<QueryEditorProps> {
7878
bracketMatching(),
7979
keymap.of([...historyKeymap, ...completionKeymap, ...defaultKeymap]),
8080
runQueryBinding,
81-
oneDark,
81+
codeMirrorThemeExtension,
8282
graphql(this.props.schema, {}),
8383
autocompletion({
8484
icons: false,
@@ -144,9 +144,7 @@ export class QueryEditor extends Component<QueryEditorProps> {
144144
ref={e => {
145145
this.domNode = e
146146
}}
147-
>
148-
<span className="editor-name rounded-tl">Operation</span>
149-
</div>
147+
/>
150148
)
151149
}
152150
}

src/components/interactive-code-block/result-viewer.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { EditorView } from "@codemirror/view"
33
import { EditorState } from "@codemirror/state"
44
// todo: perhaps custom grammar to match the shiki highlighting?
55
import { json } from "@codemirror/lang-json"
6-
import { oneDark } from "./codemirror-one-dark"
6+
import { codeMirrorThemeExtension } from "./codemirror-theme"
77

88
import "./syntax-highlighting.css"
99

@@ -31,7 +31,11 @@ export class ResultViewer extends Component<ResultViewerProps> {
3131
// Create read-only editor state for JSON results
3232
const state = EditorState.create({
3333
doc: this.props.value || "",
34-
extensions: [EditorState.readOnly.of(true), json(), oneDark],
34+
extensions: [
35+
EditorState.readOnly.of(true),
36+
json(),
37+
codeMirrorThemeExtension,
38+
],
3539
})
3640

3741
// Create editor view
@@ -71,9 +75,7 @@ export class ResultViewer extends Component<ResultViewerProps> {
7175
ref={e => {
7276
this.domNode = e
7377
}}
74-
>
75-
<span className="editor-name rounded-tr">Response</span>
76-
</div>
78+
/>
7779
)
7880
}
7981
}

src/components/interactive-code-block/syntax-highlighting.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
.dark {
3131
/* Dark theme colors (matching Shiki dark.json) */
32-
--cm-comment: #6a737d;
32+
--cm-comment: #737373;
3333
--cm-punctuation: #6e7557;
3434
--cm-keyword: #c2f653;
3535
--cm-def: #dbf6a2;
@@ -45,11 +45,11 @@
4545
--cm-atom: #79b8ff;
4646

4747
/* Editor UI colors - dark theme */
48-
--cm-background: #000;
48+
--cm-background: hsl(var(--color-neu-800) / 0.025);
4949
--cm-foreground: #cfd3c5;
5050
--cm-gutter-background: #1f2425;
5151
--cm-gutter-border: #1b1f20;
52-
--cm-line-number: #6a737d;
52+
--cm-line-number: #737373;
5353
--cm-cursor: #c8e1ff;
5454
--cm-selection: #3392ff44;
5555
--cm-hints-foreground: #e1e4e8;

0 commit comments

Comments
 (0)