Skip to content

Commit 56f57d6

Browse files
authored
Merge pull request #400 from code-hike/fix-config-types
Refactor component props
2 parents 6182f45 + 365c9fe commit 56f57d6

24 files changed

+492
-300
lines changed

packages/mdx/dev/content/rows.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ console.log(7)
6666

6767
</CH.Code>
6868

69-
<CH.Code rows={[2, "focus"]} lineNumbers >
69+
<CH.Code rows={[2, "focus"]} lineNumbers showExpandButton>
7070

7171
```js foo.js
7272
console.log(2)

packages/mdx/dev/content/test.mdx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
<CH.Scrollycoding rows={10} lineNumbers>
2+
3+
<CH.Code rows={3}>
4+
15
```js
2-
// mark(1)
3-
function foobarloremipsumfoobarloremipsumsitametfoobarloremipsumfoobarloremipsumsitamet() {
4-
// box[16:20] red
5-
console.log("hover me")
6-
// mark[9:12]
7-
return 8
8-
}
6+
console.log(1)
97
```
108

9+
</CH.Code>
10+
11+
Hello 1
12+
13+
</CH.Scrollycoding>
14+
15+
1116
```terminal
1217
❯ npm create astro -y
1318
@@ -52,3 +57,4 @@ function foobarloremipsumfoobarloremipsumsitametfoobarloremipsumfoobarloremipsum
5257
│ ◠ ◡ ◠ Good luck out there, astronaut! 🚀
5358
╰─────╯
5459
```
60+

packages/mdx/src/core/types.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import type { Theme } from "@code-hike/lighter"
2+
import type { CodeStep } from "../smooth-code"
3+
4+
type TriggerPosition = `${number}px` | `${number}%`
5+
6+
export type RemarkConfig = {
7+
// remark only
8+
theme: Theme
9+
autoImport?: boolean
10+
skipLanguages: string[]
11+
autoLink?: boolean
12+
// path to the current file, internal use only
13+
filepath?: string
14+
15+
// client config
16+
lineNumbers?: boolean
17+
showCopyButton?: boolean
18+
staticMediaQuery?: string
19+
triggerPosition?: TriggerPosition
20+
}
21+
22+
// the config that is passed from remark to the client components
23+
export type GlobalConfig = {
24+
themeName: string
25+
lineNumbers?: boolean
26+
showCopyButton?: boolean
27+
staticMediaQuery?: string
28+
triggerPosition?: TriggerPosition
29+
30+
minZoom?: number
31+
maxZoom?: number
32+
horizontalCenter?: boolean
33+
}
34+
35+
export function toGlobalConfig({
36+
theme,
37+
staticMediaQuery,
38+
lineNumbers,
39+
showCopyButton,
40+
triggerPosition,
41+
}: RemarkConfig): GlobalConfig {
42+
return {
43+
themeName:
44+
typeof theme === "string" ? theme : theme.name,
45+
staticMediaQuery,
46+
lineNumbers,
47+
showCopyButton,
48+
triggerPosition,
49+
}
50+
}
51+
52+
export type CodeSettings = {
53+
// from global config
54+
lineNumbers?: boolean
55+
showCopyButton?: boolean
56+
staticMediaQuery?: string
57+
themeName?: string
58+
// scrollycoding only
59+
triggerPosition?: TriggerPosition
60+
61+
showExpandButton?: boolean
62+
/* not really the height, when this changes we measure everything again */
63+
parentHeight?: any
64+
minColumns?: number
65+
minZoom?: number
66+
maxZoom?: number
67+
horizontalCenter?: boolean
68+
rows?: number | "focus" | (number | "focus")[]
69+
debug?: boolean
70+
}
71+
72+
export type ElementProps = {
73+
style?: React.CSSProperties
74+
className?: string
75+
}
76+
77+
export type CodeConfigProps = {
78+
rows?: number | "focus" | (number | "focus")[]
79+
showCopyButton?: boolean
80+
showExpandButton?: boolean
81+
lineNumbers?: boolean
82+
83+
minZoom?: number
84+
maxZoom?: number
85+
horizontalCenter?: boolean
86+
}
87+
88+
type EditorPanel = {
89+
tabs: string[]
90+
active: string
91+
heightRatio: number
92+
}
93+
94+
export type EditorStep = {
95+
files: CodeFile[]
96+
northPanel: EditorPanel
97+
southPanel?: EditorPanel
98+
terminal?: string
99+
}
100+
101+
export type CodeFile = CodeStep & {
102+
name: string
103+
}

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

Lines changed: 77 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,128 @@
11
import React from "react"
2-
import { CodeConfig, CodeSpring } from "../smooth-code"
2+
import { CodeSpring } from "../smooth-code"
3+
import { EditorSpring, EditorStep } from "../mini-editor"
34
import {
4-
EditorSpring,
5-
EditorProps,
6-
EditorStep,
7-
} from "../mini-editor"
8-
import { CodeHikeConfig } from "../remark/config"
5+
CodeConfigProps,
6+
ElementProps,
7+
GlobalConfig,
8+
} from "../core/types"
99

10-
export function Code(
11-
props: EditorProps & Partial<CodeHikeConfig>
12-
) {
13-
const [step, setStep] = React.useState(props)
10+
type Props = {
11+
editorStep: EditorStep
12+
globalConfig: GlobalConfig
13+
} & ElementProps &
14+
CodeConfigProps
15+
16+
export function Code(props: Props) {
17+
const { editorStep, globalConfig, ...codeConfigProps } =
18+
props
19+
const [step, setStep] = React.useState(editorStep)
1420

1521
function onTabClick(filename: string) {
16-
const newStep = updateEditorStep(step, filename, null)
22+
const newStep = updateEditorStep(
23+
props.editorStep,
24+
filename,
25+
null
26+
)
1727
setStep({ ...step, ...newStep })
1828
}
1929

20-
return <InnerCode {...step} onTabClick={onTabClick} />
30+
return (
31+
<InnerCode
32+
editorStep={step}
33+
onTabClick={onTabClick}
34+
globalConfig={globalConfig}
35+
codeConfigProps={codeConfigProps}
36+
/>
37+
)
2138
}
2239

23-
// build the CodeConfig from props and props.codeConfig
24-
export function mergeCodeConfig<T>(
25-
props: Partial<CodeConfig> & {
26-
codeConfig: Partial<CodeConfig>
27-
} & T
28-
) {
29-
const {
30-
lineNumbers,
31-
showCopyButton,
32-
showExpandButton,
33-
minZoom,
34-
maxZoom,
35-
...rest
36-
} = props
37-
const codeConfig = {
38-
...props.codeConfig,
39-
maxZoom:
40-
maxZoom == null ? props.codeConfig?.maxZoom : maxZoom,
41-
minZoom:
42-
minZoom == null ? props.codeConfig?.minZoom : minZoom,
43-
horizontalCenter:
44-
props.codeConfig?.horizontalCenter ??
45-
props.horizontalCenter,
46-
lineNumbers:
47-
lineNumbers == null
48-
? props.codeConfig?.lineNumbers
49-
: lineNumbers,
50-
showCopyButton:
51-
showCopyButton == null
52-
? props.codeConfig?.showCopyButton
53-
: showCopyButton,
54-
showExpandButton:
55-
showExpandButton == null
56-
? props.codeConfig?.showExpandButton
57-
: showExpandButton,
58-
rows: props.rows,
59-
debug: props.debug ?? props.codeConfig?.debug,
60-
}
61-
return { ...rest, codeConfig }
40+
type InnerCodeProps = {
41+
onTabClick: (filename: string) => void
42+
globalConfig: GlobalConfig
43+
editorStep: EditorStep
44+
codeConfigProps: CodeConfigProps & ElementProps
6245
}
6346

6447
export function InnerCode({
6548
onTabClick,
66-
...props
67-
}: EditorProps & {
68-
onTabClick?: (filename: string) => void
69-
} & Partial<CodeHikeConfig>) {
70-
const { className, style, codeConfig, ...editorProps } =
71-
mergeCodeConfig(props)
49+
globalConfig,
50+
editorStep,
51+
codeConfigProps,
52+
}: InnerCodeProps) {
53+
const { className, style, ...config } = mergeCodeConfig(
54+
globalConfig,
55+
codeConfigProps
56+
)
7257

7358
if (
74-
!props.southPanel &&
75-
props.files.length === 1 &&
76-
!props.files[0].name
59+
!editorStep.southPanel &&
60+
editorStep.files.length === 1 &&
61+
!editorStep.files[0].name
7762
) {
7863
return (
7964
<div
8065
className={`ch-codeblock not-prose ${
8166
className || ""
8267
}`}
83-
data-ch-theme={props.codeConfig?.themeName}
68+
data-ch-theme={globalConfig.themeName}
8469
style={style}
8570
>
8671
<CodeSpring
8772
className="ch-code"
88-
config={codeConfig}
89-
step={editorProps.files[0]}
73+
config={config}
74+
step={editorStep.files[0]}
9075
/>
9176
</div>
9277
)
9378
} else {
9479
const frameProps = {
95-
...editorProps?.frameProps,
80+
// ...editorStep?.frameProps,
9681
onTabClick,
9782
}
9883
return (
9984
<div
10085
className={`ch-codegroup not-prose ${
10186
className || ""
10287
}`}
103-
data-ch-theme={props.codeConfig?.themeName}
88+
data-ch-theme={globalConfig.themeName}
10489
style={style}
10590
>
10691
<EditorSpring
107-
{...editorProps}
92+
{...editorStep}
10893
frameProps={frameProps}
109-
codeConfig={codeConfig}
94+
codeConfig={config}
11095
/>
11196
</div>
11297
)
11398
}
11499
}
115100

101+
export function mergeCodeConfig(
102+
globalConfig: GlobalConfig,
103+
local: CodeConfigProps & ElementProps
104+
) {
105+
const {
106+
// ignore these
107+
staticMediaQuery,
108+
themeName,
109+
triggerPosition,
110+
// keep the rest
111+
...global
112+
} = globalConfig
113+
return {
114+
...global,
115+
...local,
116+
lineNumbers: local.lineNumbers ?? global.lineNumbers,
117+
maxZoom: local.maxZoom ?? global.maxZoom,
118+
minZoom: local.minZoom ?? global.minZoom,
119+
horizontalCenter:
120+
local.horizontalCenter ?? global.horizontalCenter,
121+
showCopyButton:
122+
local.showCopyButton ?? global.showCopyButton,
123+
}
124+
}
125+
116126
export function updateEditorStep(
117127
step: EditorStep,
118128
filename: string | undefined,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ import { Code } from "../utils"
33

44
export function InlineCode({
55
className,
6-
codeConfig,
6+
globalConfig,
77
children,
88
code,
99
...rest
1010
}: {
1111
className: string
1212
code: Code
1313
children?: React.ReactNode
14-
codeConfig: { themeName: string }
14+
globalConfig: { themeName: string }
1515
}) {
1616
const { lines } = code
1717
const allTokens = lines.flatMap(line => line.tokens)
1818

1919
return (
2020
<span
21-
data-ch-theme={codeConfig.themeName}
21+
data-ch-theme={globalConfig.themeName}
2222
className={
2323
"ch-inline-code not-prose" +
2424
(className ? " " + className : "")

0 commit comments

Comments
 (0)