Skip to content

Commit 9b3a67b

Browse files
authored
Merge pull request #174 from code-hike/config-props
Better props support for mdx
2 parents e46411d + 3347302 commit 9b3a67b

26 files changed

+338
-300
lines changed

contributing.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Files and Folders
2+
3+
- `packages/mdx`: the npm package
4+
- `packages/mdx/vite.config.js`: we only use vite for testing with vitest
5+
- `packages/mdx/rollup.config.js`: rollup builds the thing we release to npm
6+
- `packages/mdx/next.config.js`: we have a nextjs testing site, our poor man's storybook
7+
- `packages/mdx/pages`: the pages for the nextjs test site
8+
- `packages/mdx/dev`: code and content used by the nextjs test site
9+
- `packages/mdx/src/remark`: the code that runs at build time when you compile an mdx file
10+
- `examples`: a list of examples, most of them use the Code Hike version from `packages/mdx/dist`
11+
- `examples/bundle-test`: this one is used by `.github/workflows/bundle-analysis.yml`
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
`<CH.Code lineNumbers showCopyButton={false} className="foobar">`
2+
3+
<CH.Code lineNumbers showCopyButton={false} className="foobar">
4+
5+
```js
6+
console.log(1)
7+
```
8+
9+
</CH.Code>
10+
11+
`<CH.Code lineNumbers={false} showCopyButton={true} className="foo">`
12+
13+
<CH.Code lineNumbers={false} showCopyButton={true} className="foo">
14+
15+
```js index.js
16+
console.log(2)
17+
```
18+
19+
```python foo.py
20+
print(3)
21+
```
22+
23+
---
24+
25+
```html index.html
26+
<div>Hi</div>
27+
```
28+
29+
</CH.Code>
30+
31+
`<CH.Code className="foobarbazbarbar" style={{border: "2px solid red", height: 160}}>`
32+
33+
<CH.Code className="foobarbazbarbar" style={{border: "2px solid red", height: 160}}>
34+
35+
```js index.js
36+
console.log(2)
37+
console.log(2)
38+
console.log(2)
39+
console.log(2)
40+
console.log(2)
41+
console.log(2)
42+
console.log(2)
43+
console.log(2)
44+
console.log(2)
45+
console.log(2)
46+
```
47+
48+
</CH.Code>

packages/mdx/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export { remarkCodeHike } from "./mdx-plugin/plugin"
1+
export { transform as remarkCodeHike } from "./remark/transform"
22

33
export { highlight } from "./highlighter"

packages/mdx/src/mdx-client/code.tsx

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import {
55
EditorProps,
66
EditorStep,
77
} from "../mini-editor"
8+
import { CodeHikeConfig } from "remark/config"
89

9-
export function Code(props: EditorProps) {
10+
export function Code(
11+
props: EditorProps & Partial<CodeHikeConfig>
12+
) {
1013
const [step, setStep] = React.useState(props)
1114

1215
function onTabClick(filename: string) {
@@ -22,29 +25,63 @@ export function InnerCode({
2225
...props
2326
}: EditorProps & {
2427
onTabClick?: (filename: string) => void
25-
}) {
28+
} & Partial<CodeHikeConfig>) {
29+
const {
30+
lineNumbers,
31+
showCopyButton,
32+
className,
33+
style,
34+
...editorProps
35+
} = props
36+
37+
const codeConfig = {
38+
...props.codeConfig,
39+
lineNumbers:
40+
lineNumbers == null
41+
? props.codeConfig?.lineNumbers
42+
: lineNumbers,
43+
showCopyButton:
44+
showCopyButton == null
45+
? props.codeConfig?.showCopyButton
46+
: showCopyButton,
47+
}
48+
2649
if (
2750
!props.southPanel &&
2851
props.files.length === 1 &&
2952
!props.files[0].name
3053
) {
3154
return (
32-
<div className="ch-codeblock not-prose">
55+
<div
56+
className={`ch-codeblock not-prose ${
57+
className || ""
58+
}`}
59+
style={style}
60+
>
3361
<CodeSpring
3462
className="ch-code"
35-
config={props.codeConfig}
36-
step={props.files[0]}
63+
config={codeConfig}
64+
step={editorProps.files[0]}
3765
/>
3866
</div>
3967
)
4068
} else {
4169
const frameProps = {
42-
...props?.frameProps,
70+
...editorProps?.frameProps,
4371
onTabClick,
4472
}
4573
return (
46-
<div className="ch-codegroup not-prose">
47-
<EditorSpring {...props} frameProps={frameProps} />
74+
<div
75+
className={`ch-codegroup not-prose ${
76+
className || ""
77+
}`}
78+
style={style}
79+
>
80+
<EditorSpring
81+
{...editorProps}
82+
frameProps={frameProps}
83+
codeConfig={codeConfig}
84+
/>
4885
</div>
4986
)
5087
}

packages/mdx/src/mdx-plugin/ch-usage.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

packages/mdx/src/mdx-plugin/editor.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

packages/mdx/src/mdx-plugin/code.ts renamed to packages/mdx/src/remark/code.ts

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import { highlight } from "../highlighter"
22
import { extractLinks } from "./links"
3-
import {
4-
visitAsync,
5-
toJSX,
6-
NodeInfo,
7-
splitChildren,
8-
CH_CODE_CONFIG_PLACEHOLDER,
9-
} from "./unist-utils"
3+
import { NodeInfo, splitChildren } from "./unist-utils"
104
import { CodeStep } from "../smooth-code"
115
import { EditorProps } from "../mini-editor"
126
import {
@@ -16,22 +10,7 @@ import {
1610
} from "./annotations"
1711
import { mergeFocus } from "../utils"
1812
import { CodeNode, SuperNode } from "./nodes"
19-
20-
export async function transformCodeNodes(
21-
tree: SuperNode,
22-
{ theme }: { theme: any }
23-
) {
24-
await visitAsync(
25-
tree,
26-
"code",
27-
async (node: CodeNode, index, parent) => {
28-
await transformCode(
29-
{ node, index, parent: parent! },
30-
{ theme }
31-
)
32-
}
33-
)
34-
}
13+
import { CodeHikeConfig } from "./config"
3514

3615
export function isEditorNode(node: SuperNode) {
3716
return (
@@ -41,28 +20,9 @@ export function isEditorNode(node: SuperNode) {
4120
)
4221
}
4322

44-
async function transformCode(
45-
nodeInfo: NodeInfo<CodeNode>,
46-
config: { theme: any }
47-
) {
48-
toJSX(nodeInfo.node, {
49-
name: "CH.Code",
50-
props: await mapCode(nodeInfo, config),
51-
})
52-
}
53-
export async function transformEditor(
54-
nodeInfo: NodeInfo,
55-
config: { theme: any }
56-
) {
57-
toJSX(nodeInfo.node, {
58-
name: "CH.Code",
59-
props: await mapEditor(nodeInfo, config),
60-
})
61-
}
62-
6323
export async function mapAnyCodeNode(
6424
nodeInfo: NodeInfo,
65-
config: { theme: any }
25+
config: CodeHikeConfig
6626
) {
6727
const { node } = nodeInfo
6828
if (node.type === "code") {
@@ -72,27 +32,28 @@ export async function mapAnyCodeNode(
7232
}
7333
}
7434

35+
type Props = Omit<EditorProps, "codeConfig">
36+
7537
async function mapCode(
7638
nodeInfo: NodeInfo<CodeNode>,
77-
config: { theme: any }
78-
): Promise<EditorProps> {
39+
config: CodeHikeConfig
40+
): Promise<Props> {
7941
const file = await mapFile(nodeInfo, config)
80-
const props: EditorProps = {
42+
const props: Props = {
8143
northPanel: {
8244
tabs: [file.name],
8345
active: file.name,
8446
heightRatio: 1,
8547
},
8648
files: [file],
87-
codeConfig: CH_CODE_CONFIG_PLACEHOLDER,
8849
}
8950
return props
9051
}
9152

9253
export async function mapEditor(
9354
{ node }: NodeInfo,
94-
config: { theme: any }
95-
): Promise<EditorProps> {
55+
config: CodeHikeConfig
56+
): Promise<Props> {
9657
const [northNodes, southNodes = []] = splitChildren(
9758
node,
9859
"thematicBreak"
@@ -139,14 +100,13 @@ export async function mapEditor(
139100
}
140101
: undefined,
141102
files: allFiles as any,
142-
codeConfig: CH_CODE_CONFIG_PLACEHOLDER,
143103
}
144104
return props
145105
}
146106

147107
async function mapFile(
148108
{ node, index, parent }: NodeInfo<CodeNode>,
149-
config: { theme: any }
109+
config: CodeHikeConfig
150110
): Promise<CodeStep & FileOptions & { name: string }> {
151111
const { theme } = config
152112

packages/mdx/src/remark/config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export type CodeHikeConfig = {
2+
theme: any
3+
lineNumbers?: boolean
4+
autoImport?: boolean
5+
showCopyButton?: boolean
6+
}
7+
8+
/**
9+
* Add defaults and normalize config
10+
*/
11+
export function addConfigDefaults(
12+
config: Partial<CodeHikeConfig> | undefined
13+
): CodeHikeConfig {
14+
// TODO warn when config looks weird
15+
return {
16+
...config,
17+
theme: config?.theme || {},
18+
autoImport: config?.autoImport === false ? false : true,
19+
}
20+
}

packages/mdx/src/mdx-plugin/steps.tsx renamed to packages/mdx/src/remark/steps.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { EditorStep } from "../mini-editor"
22
import { isEditorNode, mapAnyCodeNode } from "./code"
33
import { reduceSteps } from "./code-files-reducer"
4+
import { CodeHikeConfig } from "./config"
45
import { SuperNode } from "./nodes"
56

67
// extract step info
78

89
export async function extractStepsInfo(
910
parent: SuperNode,
10-
config: { theme: any },
11+
config: CodeHikeConfig,
1112
merge:
1213
| "merge steps with header"
1314
| "merge step with previous"
@@ -29,11 +30,10 @@ export async function extractStepsInfo(
2930
steps[stepIndex] = steps[stepIndex] || { children: [] }
3031
const step = steps[stepIndex]
3132
if (!step.editorStep && isEditorNode(child)) {
32-
const { codeConfig, ...editorStep } =
33-
await mapAnyCodeNode(
34-
{ node: child, parent, index: i },
35-
config
36-
)
33+
const editorStep = await mapAnyCodeNode(
34+
{ node: child, parent, index: i },
35+
config
36+
)
3737

3838
if (stepIndex === 0) {
3939
// for the header props, keep it as it is

0 commit comments

Comments
 (0)