Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Better props support for mdx #174

Merged
merged 7 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Files and Folders

- `packages/mdx`: the npm package
- `packages/mdx/vite.config.js`: we only use vite for testing with vitest
- `packages/mdx/rollup.config.js`: rollup builds the thing we release to npm
- `packages/mdx/next.config.js`: we have a nextjs testing site, our poor man's storybook
- `packages/mdx/pages`: the pages for the nextjs test site
- `packages/mdx/dev`: code and content used by the nextjs test site
- `packages/mdx/src/remark`: the code that runs at build time when you compile an mdx file
- `examples`: a list of examples, most of them use the Code Hike version from `packages/mdx/dist`
- `examples/bundle-test`: this one is used by `.github/workflows/bundle-analysis.yml`
48 changes: 48 additions & 0 deletions packages/mdx/dev/content/passing-props.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
`<CH.Code lineNumbers showCopyButton={false} className="foobar">`

<CH.Code lineNumbers showCopyButton={false} className="foobar">

```js
console.log(1)
```

</CH.Code>

`<CH.Code lineNumbers={false} showCopyButton={true} className="foo">`

<CH.Code lineNumbers={false} showCopyButton={true} className="foo">

```js index.js
console.log(2)
```

```python foo.py
print(3)
```

---

```html index.html
<div>Hi</div>
```

</CH.Code>

`<CH.Code className="foobarbazbarbar" style={{border: "2px solid red", height: 160}}>`

<CH.Code className="foobarbazbarbar" style={{border: "2px solid red", height: 160}}>

```js index.js
console.log(2)
console.log(2)
console.log(2)
console.log(2)
console.log(2)
console.log(2)
console.log(2)
console.log(2)
console.log(2)
console.log(2)
```

</CH.Code>
2 changes: 1 addition & 1 deletion packages/mdx/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { remarkCodeHike } from "./mdx-plugin/plugin"
export { transform as remarkCodeHike } from "./remark/transform"

export { highlight } from "./highlighter"
53 changes: 45 additions & 8 deletions packages/mdx/src/mdx-client/code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import {
EditorProps,
EditorStep,
} from "../mini-editor"
import { CodeHikeConfig } from "remark/config"

export function Code(props: EditorProps) {
export function Code(
props: EditorProps & Partial<CodeHikeConfig>
) {
const [step, setStep] = React.useState(props)

function onTabClick(filename: string) {
Expand All @@ -22,29 +25,63 @@ export function InnerCode({
...props
}: EditorProps & {
onTabClick?: (filename: string) => void
}) {
} & Partial<CodeHikeConfig>) {
const {
lineNumbers,
showCopyButton,
className,
style,
...editorProps
} = props

const codeConfig = {
...props.codeConfig,
lineNumbers:
lineNumbers == null
? props.codeConfig?.lineNumbers
: lineNumbers,
showCopyButton:
showCopyButton == null
? props.codeConfig?.showCopyButton
: showCopyButton,
}

if (
!props.southPanel &&
props.files.length === 1 &&
!props.files[0].name
) {
return (
<div className="ch-codeblock not-prose">
<div
className={`ch-codeblock not-prose ${
className || ""
}`}
style={style}
>
<CodeSpring
className="ch-code"
config={props.codeConfig}
step={props.files[0]}
config={codeConfig}
step={editorProps.files[0]}
/>
</div>
)
} else {
const frameProps = {
...props?.frameProps,
...editorProps?.frameProps,
onTabClick,
}
return (
<div className="ch-codegroup not-prose">
<EditorSpring {...props} frameProps={frameProps} />
<div
className={`ch-codegroup not-prose ${
className || ""
}`}
style={style}
>
<EditorSpring
{...editorProps}
frameProps={frameProps}
codeConfig={codeConfig}
/>
</div>
)
}
Expand Down
19 changes: 0 additions & 19 deletions packages/mdx/src/mdx-plugin/ch-usage.ts

This file was deleted.

21 changes: 0 additions & 21 deletions packages/mdx/src/mdx-plugin/editor.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { highlight } from "../highlighter"
import { extractLinks } from "./links"
import {
visitAsync,
toJSX,
NodeInfo,
splitChildren,
CH_CODE_CONFIG_PLACEHOLDER,
} from "./unist-utils"
import { NodeInfo, splitChildren } from "./unist-utils"
import { CodeStep } from "../smooth-code"
import { EditorProps } from "../mini-editor"
import {
Expand All @@ -16,22 +10,7 @@ import {
} from "./annotations"
import { mergeFocus } from "../utils"
import { CodeNode, SuperNode } from "./nodes"

export async function transformCodeNodes(
tree: SuperNode,
{ theme }: { theme: any }
) {
await visitAsync(
tree,
"code",
async (node: CodeNode, index, parent) => {
await transformCode(
{ node, index, parent: parent! },
{ theme }
)
}
)
}
import { CodeHikeConfig } from "./config"

export function isEditorNode(node: SuperNode) {
return (
Expand All @@ -41,28 +20,9 @@ export function isEditorNode(node: SuperNode) {
)
}

async function transformCode(
nodeInfo: NodeInfo<CodeNode>,
config: { theme: any }
) {
toJSX(nodeInfo.node, {
name: "CH.Code",
props: await mapCode(nodeInfo, config),
})
}
export async function transformEditor(
nodeInfo: NodeInfo,
config: { theme: any }
) {
toJSX(nodeInfo.node, {
name: "CH.Code",
props: await mapEditor(nodeInfo, config),
})
}

export async function mapAnyCodeNode(
nodeInfo: NodeInfo,
config: { theme: any }
config: CodeHikeConfig
) {
const { node } = nodeInfo
if (node.type === "code") {
Expand All @@ -72,27 +32,28 @@ export async function mapAnyCodeNode(
}
}

type Props = Omit<EditorProps, "codeConfig">

async function mapCode(
nodeInfo: NodeInfo<CodeNode>,
config: { theme: any }
): Promise<EditorProps> {
config: CodeHikeConfig
): Promise<Props> {
const file = await mapFile(nodeInfo, config)
const props: EditorProps = {
const props: Props = {
northPanel: {
tabs: [file.name],
active: file.name,
heightRatio: 1,
},
files: [file],
codeConfig: CH_CODE_CONFIG_PLACEHOLDER,
}
return props
}

export async function mapEditor(
{ node }: NodeInfo,
config: { theme: any }
): Promise<EditorProps> {
config: CodeHikeConfig
): Promise<Props> {
const [northNodes, southNodes = []] = splitChildren(
node,
"thematicBreak"
Expand Down Expand Up @@ -139,14 +100,13 @@ export async function mapEditor(
}
: undefined,
files: allFiles as any,
codeConfig: CH_CODE_CONFIG_PLACEHOLDER,
}
return props
}

async function mapFile(
{ node, index, parent }: NodeInfo<CodeNode>,
config: { theme: any }
config: CodeHikeConfig
): Promise<CodeStep & FileOptions & { name: string }> {
const { theme } = config

Expand Down
20 changes: 20 additions & 0 deletions packages/mdx/src/remark/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export type CodeHikeConfig = {
theme: any
lineNumbers?: boolean
autoImport?: boolean
showCopyButton?: boolean
}

/**
* Add defaults and normalize config
*/
export function addConfigDefaults(
config: Partial<CodeHikeConfig> | undefined
): CodeHikeConfig {
// TODO warn when config looks weird
return {
...config,
theme: config?.theme || {},
autoImport: config?.autoImport === false ? false : true,
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { EditorStep } from "../mini-editor"
import { isEditorNode, mapAnyCodeNode } from "./code"
import { reduceSteps } from "./code-files-reducer"
import { CodeHikeConfig } from "./config"
import { SuperNode } from "./nodes"

// extract step info

export async function extractStepsInfo(
parent: SuperNode,
config: { theme: any },
config: CodeHikeConfig,
merge:
| "merge steps with header"
| "merge step with previous"
Expand All @@ -29,11 +30,10 @@ export async function extractStepsInfo(
steps[stepIndex] = steps[stepIndex] || { children: [] }
const step = steps[stepIndex]
if (!step.editorStep && isEditorNode(child)) {
const { codeConfig, ...editorStep } =
await mapAnyCodeNode(
{ node: child, parent, index: i },
config
)
const editorStep = await mapAnyCodeNode(
{ node: child, parent, index: i },
config
)

if (stepIndex === 0) {
// for the header props, keep it as it is
Expand Down
Loading