Skip to content

Commit

Permalink
Merge pull request #400 from code-hike/fix-config-types
Browse files Browse the repository at this point in the history
Refactor component props
  • Loading branch information
pomber authored Jul 27, 2023
2 parents 6182f45 + 365c9fe commit 56f57d6
Show file tree
Hide file tree
Showing 24 changed files with 492 additions and 300 deletions.
2 changes: 1 addition & 1 deletion packages/mdx/dev/content/rows.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ console.log(7)

</CH.Code>

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

```js foo.js
console.log(2)
Expand Down
20 changes: 13 additions & 7 deletions packages/mdx/dev/content/test.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<CH.Scrollycoding rows={10} lineNumbers>

<CH.Code rows={3}>

```js
// mark(1)
function foobarloremipsumfoobarloremipsumsitametfoobarloremipsumfoobarloremipsumsitamet() {
// box[16:20] red
console.log("hover me")
// mark[9:12]
return 8
}
console.log(1)
```

</CH.Code>

Hello 1

</CH.Scrollycoding>


```terminal
❯ npm create astro -y
Expand Down Expand Up @@ -52,3 +57,4 @@ function foobarloremipsumfoobarloremipsumsitametfoobarloremipsumfoobarloremipsum
│ ◠ ◡ ◠ Good luck out there, astronaut! 🚀
╰─────╯
```

103 changes: 103 additions & 0 deletions packages/mdx/src/core/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import type { Theme } from "@code-hike/lighter"
import type { CodeStep } from "../smooth-code"

type TriggerPosition = `${number}px` | `${number}%`

export type RemarkConfig = {
// remark only
theme: Theme
autoImport?: boolean
skipLanguages: string[]
autoLink?: boolean
// path to the current file, internal use only
filepath?: string

// client config
lineNumbers?: boolean
showCopyButton?: boolean
staticMediaQuery?: string
triggerPosition?: TriggerPosition
}

// the config that is passed from remark to the client components
export type GlobalConfig = {
themeName: string
lineNumbers?: boolean
showCopyButton?: boolean
staticMediaQuery?: string
triggerPosition?: TriggerPosition

minZoom?: number
maxZoom?: number
horizontalCenter?: boolean
}

export function toGlobalConfig({
theme,
staticMediaQuery,
lineNumbers,
showCopyButton,
triggerPosition,
}: RemarkConfig): GlobalConfig {
return {
themeName:
typeof theme === "string" ? theme : theme.name,
staticMediaQuery,
lineNumbers,
showCopyButton,
triggerPosition,
}
}

export type CodeSettings = {
// from global config
lineNumbers?: boolean
showCopyButton?: boolean
staticMediaQuery?: string
themeName?: string
// scrollycoding only
triggerPosition?: TriggerPosition

showExpandButton?: boolean
/* not really the height, when this changes we measure everything again */
parentHeight?: any
minColumns?: number
minZoom?: number
maxZoom?: number
horizontalCenter?: boolean
rows?: number | "focus" | (number | "focus")[]
debug?: boolean
}

export type ElementProps = {
style?: React.CSSProperties
className?: string
}

export type CodeConfigProps = {
rows?: number | "focus" | (number | "focus")[]
showCopyButton?: boolean
showExpandButton?: boolean
lineNumbers?: boolean

minZoom?: number
maxZoom?: number
horizontalCenter?: boolean
}

type EditorPanel = {
tabs: string[]
active: string
heightRatio: number
}

export type EditorStep = {
files: CodeFile[]
northPanel: EditorPanel
southPanel?: EditorPanel
terminal?: string
}

export type CodeFile = CodeStep & {
name: string
}
144 changes: 77 additions & 67 deletions packages/mdx/src/mdx-client/code.tsx
Original file line number Diff line number Diff line change
@@ -1,118 +1,128 @@
import React from "react"
import { CodeConfig, CodeSpring } from "../smooth-code"
import { CodeSpring } from "../smooth-code"
import { EditorSpring, EditorStep } from "../mini-editor"
import {
EditorSpring,
EditorProps,
EditorStep,
} from "../mini-editor"
import { CodeHikeConfig } from "../remark/config"
CodeConfigProps,
ElementProps,
GlobalConfig,
} from "../core/types"

export function Code(
props: EditorProps & Partial<CodeHikeConfig>
) {
const [step, setStep] = React.useState(props)
type Props = {
editorStep: EditorStep
globalConfig: GlobalConfig
} & ElementProps &
CodeConfigProps

export function Code(props: Props) {
const { editorStep, globalConfig, ...codeConfigProps } =
props
const [step, setStep] = React.useState(editorStep)

function onTabClick(filename: string) {
const newStep = updateEditorStep(step, filename, null)
const newStep = updateEditorStep(
props.editorStep,
filename,
null
)
setStep({ ...step, ...newStep })
}

return <InnerCode {...step} onTabClick={onTabClick} />
return (
<InnerCode
editorStep={step}
onTabClick={onTabClick}
globalConfig={globalConfig}
codeConfigProps={codeConfigProps}
/>
)
}

// build the CodeConfig from props and props.codeConfig
export function mergeCodeConfig<T>(
props: Partial<CodeConfig> & {
codeConfig: Partial<CodeConfig>
} & T
) {
const {
lineNumbers,
showCopyButton,
showExpandButton,
minZoom,
maxZoom,
...rest
} = props
const codeConfig = {
...props.codeConfig,
maxZoom:
maxZoom == null ? props.codeConfig?.maxZoom : maxZoom,
minZoom:
minZoom == null ? props.codeConfig?.minZoom : minZoom,
horizontalCenter:
props.codeConfig?.horizontalCenter ??
props.horizontalCenter,
lineNumbers:
lineNumbers == null
? props.codeConfig?.lineNumbers
: lineNumbers,
showCopyButton:
showCopyButton == null
? props.codeConfig?.showCopyButton
: showCopyButton,
showExpandButton:
showExpandButton == null
? props.codeConfig?.showExpandButton
: showExpandButton,
rows: props.rows,
debug: props.debug ?? props.codeConfig?.debug,
}
return { ...rest, codeConfig }
type InnerCodeProps = {
onTabClick: (filename: string) => void
globalConfig: GlobalConfig
editorStep: EditorStep
codeConfigProps: CodeConfigProps & ElementProps
}

export function InnerCode({
onTabClick,
...props
}: EditorProps & {
onTabClick?: (filename: string) => void
} & Partial<CodeHikeConfig>) {
const { className, style, codeConfig, ...editorProps } =
mergeCodeConfig(props)
globalConfig,
editorStep,
codeConfigProps,
}: InnerCodeProps) {
const { className, style, ...config } = mergeCodeConfig(
globalConfig,
codeConfigProps
)

if (
!props.southPanel &&
props.files.length === 1 &&
!props.files[0].name
!editorStep.southPanel &&
editorStep.files.length === 1 &&
!editorStep.files[0].name
) {
return (
<div
className={`ch-codeblock not-prose ${
className || ""
}`}
data-ch-theme={props.codeConfig?.themeName}
data-ch-theme={globalConfig.themeName}
style={style}
>
<CodeSpring
className="ch-code"
config={codeConfig}
step={editorProps.files[0]}
config={config}
step={editorStep.files[0]}
/>
</div>
)
} else {
const frameProps = {
...editorProps?.frameProps,
// ...editorStep?.frameProps,
onTabClick,
}
return (
<div
className={`ch-codegroup not-prose ${
className || ""
}`}
data-ch-theme={props.codeConfig?.themeName}
data-ch-theme={globalConfig.themeName}
style={style}
>
<EditorSpring
{...editorProps}
{...editorStep}
frameProps={frameProps}
codeConfig={codeConfig}
codeConfig={config}
/>
</div>
)
}
}

export function mergeCodeConfig(
globalConfig: GlobalConfig,
local: CodeConfigProps & ElementProps
) {
const {
// ignore these
staticMediaQuery,
themeName,
triggerPosition,
// keep the rest
...global
} = globalConfig
return {
...global,
...local,
lineNumbers: local.lineNumbers ?? global.lineNumbers,
maxZoom: local.maxZoom ?? global.maxZoom,
minZoom: local.minZoom ?? global.minZoom,
horizontalCenter:
local.horizontalCenter ?? global.horizontalCenter,
showCopyButton:
local.showCopyButton ?? global.showCopyButton,
}
}

export function updateEditorStep(
step: EditorStep,
filename: string | undefined,
Expand Down
6 changes: 3 additions & 3 deletions packages/mdx/src/mdx-client/inline-code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ import { Code } from "../utils"

export function InlineCode({
className,
codeConfig,
globalConfig,
children,
code,
...rest
}: {
className: string
code: Code
children?: React.ReactNode
codeConfig: { themeName: string }
globalConfig: { themeName: string }
}) {
const { lines } = code
const allTokens = lines.flatMap(line => line.tokens)

return (
<span
data-ch-theme={codeConfig.themeName}
data-ch-theme={globalConfig.themeName}
className={
"ch-inline-code not-prose" +
(className ? " " + className : "")
Expand Down
Loading

0 comments on commit 56f57d6

Please sign in to comment.