From 46662f34142e03b21d04eb903308d277feaafb5c Mon Sep 17 00:00:00 2001 From: Rodrigo Pombo Date: Wed, 19 Jul 2023 08:57:51 +0000 Subject: [PATCH 1/2] Rename configs --- packages/mdx/src/core/types.ts | 65 +++++++++++++++++++ packages/mdx/src/mdx-client/code.tsx | 14 ++-- packages/mdx/src/mdx-client/preview.tsx | 4 +- packages/mdx/src/mdx-client/scrollycoding.tsx | 5 +- packages/mdx/src/mini-editor/editor-shift.tsx | 19 +++--- .../mdx/src/mini-editor/editor-spring.tsx | 4 +- packages/mdx/src/mini-editor/editor-tween.tsx | 6 +- packages/mdx/src/remark/config.ts | 15 +---- packages/mdx/src/remark/transform.ts | 17 ++--- packages/mdx/src/smooth-code/code-spring.tsx | 9 +-- packages/mdx/src/smooth-code/code-tween.tsx | 21 +----- packages/mdx/src/smooth-code/index.tsx | 8 +-- 12 files changed, 106 insertions(+), 81 deletions(-) create mode 100644 packages/mdx/src/core/types.ts diff --git a/packages/mdx/src/core/types.ts b/packages/mdx/src/core/types.ts new file mode 100644 index 00000000..01247460 --- /dev/null +++ b/packages/mdx/src/core/types.ts @@ -0,0 +1,65 @@ +import type { Theme } from "@code-hike/lighter" + +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 +} + +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 +} diff --git a/packages/mdx/src/mdx-client/code.tsx b/packages/mdx/src/mdx-client/code.tsx index 2f0644d6..9998eab5 100644 --- a/packages/mdx/src/mdx-client/code.tsx +++ b/packages/mdx/src/mdx-client/code.tsx @@ -1,15 +1,13 @@ import React from "react" -import { CodeConfig, CodeSpring } from "../smooth-code" +import { CodeSpring } from "../smooth-code" import { EditorSpring, EditorProps, EditorStep, } from "../mini-editor" -import { CodeHikeConfig } from "../remark/config" +import { CodeSettings, GlobalConfig } from "../core/types" -export function Code( - props: EditorProps & Partial -) { +export function Code(props: EditorProps & GlobalConfig) { const [step, setStep] = React.useState(props) function onTabClick(filename: string) { @@ -22,8 +20,8 @@ export function Code( // build the CodeConfig from props and props.codeConfig export function mergeCodeConfig( - props: Partial & { - codeConfig: Partial + props: Partial & { + codeConfig: Partial } & T ) { const { @@ -66,7 +64,7 @@ export function InnerCode({ ...props }: EditorProps & { onTabClick?: (filename: string) => void -} & Partial) { +} & GlobalConfig) { const { className, style, codeConfig, ...editorProps } = mergeCodeConfig(props) diff --git a/packages/mdx/src/mdx-client/preview.tsx b/packages/mdx/src/mdx-client/preview.tsx index 28e55dfb..5c80dcea 100644 --- a/packages/mdx/src/mdx-client/preview.tsx +++ b/packages/mdx/src/mdx-client/preview.tsx @@ -6,7 +6,7 @@ import { SandboxInfo, } from "@codesandbox/sandpack-client" import { EditorStep } from "../mini-editor" -import { CodeConfig } from "../smooth-code" +import { CodeSettings } from "../core/types" export type PresetConfig = SandboxInfo export function Preview({ @@ -27,7 +27,7 @@ export function Preview({ show?: string style?: React.CSSProperties children?: React.ReactNode - codeConfig?: CodeConfig + codeConfig?: CodeSettings }) { const kids = presetConfig ? ( - codeConfig: CodeConfig + codeConfig: CodeSettings springConfig?: SpringConfig } & DivProps diff --git a/packages/mdx/src/mini-editor/editor-tween.tsx b/packages/mdx/src/mini-editor/editor-tween.tsx index dc98a4db..e8c82e07 100644 --- a/packages/mdx/src/mini-editor/editor-tween.tsx +++ b/packages/mdx/src/mini-editor/editor-tween.tsx @@ -5,10 +5,10 @@ import { } from "./editor-frame" import { TerminalPanel } from "./terminal-panel" import { useTransition, EditorStep } from "./editor-shift" -import { CodeConfig } from "../smooth-code" import { useLayoutEffect } from "../utils" import { CopyButton } from "smooth-code/copy-button" import { EditorExpandButton } from "mini-editor/expand-button" +import { CodeSettings } from "../core/types" export { EditorTransition, EditorTween } export type { EditorTransitionProps, EditorTweenProps } @@ -18,7 +18,7 @@ type EditorTransitionProps = { next?: EditorStep t: number backward: boolean - codeConfig: CodeConfig + codeConfig: CodeSettings } & Omit type DivProps = React.PropsWithoutRef< @@ -30,7 +30,7 @@ type EditorTweenProps = { next?: EditorStep t: number backward: boolean - codeConfig: CodeConfig + codeConfig: CodeSettings frameProps?: Partial } & DivProps diff --git a/packages/mdx/src/remark/config.ts b/packages/mdx/src/remark/config.ts index e23ddedf..ac0a99b8 100644 --- a/packages/mdx/src/remark/config.ts +++ b/packages/mdx/src/remark/config.ts @@ -1,17 +1,6 @@ -import { Theme } from "@code-hike/lighter" +import { RemarkConfig } from "../core/types" -export type CodeHikeConfig = { - theme: Theme - lineNumbers?: boolean - autoImport?: boolean - skipLanguages: string[] - showExpandButton?: boolean - showCopyButton?: boolean - autoLink?: boolean - staticMediaQuery?: string - // path to the current file, internal use only - filepath?: string -} +export type CodeHikeConfig = RemarkConfig /** * Add defaults and normalize config diff --git a/packages/mdx/src/remark/transform.ts b/packages/mdx/src/remark/transform.ts index 372e718d..3619f6fa 100644 --- a/packages/mdx/src/remark/transform.ts +++ b/packages/mdx/src/remark/transform.ts @@ -13,6 +13,7 @@ import { addConfigDefaults, CodeHikeConfig } from "./config" import type { Node } from "unist" import { getThemeColors } from "@code-hike/lighter" +import { toGlobalConfig } from "core/types" const transforms = [ transformPreviews, @@ -155,16 +156,12 @@ async function addConfig( config: CodeHikeConfig ) { const { theme } = config - const themeName = - typeof theme === "string" ? theme : theme.name - const style = await getStyle(theme, themeName) - const codeConfig = { - staticMediaQuery: config.staticMediaQuery, - lineNumbers: config.lineNumbers, - showCopyButton: config.showCopyButton, - themeName, - } + const globalConfig = toGlobalConfig(config) + const style = await getStyle( + theme, + globalConfig.themeName + ) tree.children.unshift({ type: "mdxJsxFlowElement", @@ -236,7 +233,7 @@ async function addConfig( type: "Identifier", name: CH_CODE_CONFIG_VAR_NAME, }, - init: valueToEstree(codeConfig), + init: valueToEstree(globalConfig), }, ], kind: "const", diff --git a/packages/mdx/src/smooth-code/code-spring.tsx b/packages/mdx/src/smooth-code/code-spring.tsx index 07d80325..eda99ef6 100644 --- a/packages/mdx/src/smooth-code/code-spring.tsx +++ b/packages/mdx/src/smooth-code/code-spring.tsx @@ -1,11 +1,8 @@ import React from "react" import { useSpring } from "use-spring" import { FullTween } from "../utils" -import { - CodeTween, - CodeConfig, - CodeStep, -} from "./code-tween" +import { CodeTween, CodeStep } from "./code-tween" +import { CodeSettings } from "../core/types" type SpringConfig = Parameters[1] @@ -27,7 +24,7 @@ export function CodeSpring({ ...htmlProps }: { step: CodeStep - config: CodeConfig & { spring?: SpringConfig } + config: CodeSettings & { spring?: SpringConfig } } & HTMLProps) { const { tween, t } = useStepSpring(step, config.spring) return ( diff --git a/packages/mdx/src/smooth-code/code-tween.tsx b/packages/mdx/src/smooth-code/code-tween.tsx index 7dce0165..61d701da 100644 --- a/packages/mdx/src/smooth-code/code-tween.tsx +++ b/packages/mdx/src/smooth-code/code-tween.tsx @@ -15,6 +15,7 @@ import { import { SmoothLines } from "./smooth-lines" import { CopyButton } from "./copy-button" import { CodeExpandButton } from "mini-editor/expand-button" +import { CodeSettings } from "../core/types" type HTMLProps = React.DetailedHTMLProps< React.HTMLAttributes, @@ -26,7 +27,7 @@ type TriggerPosition = `${number}px` | `${number}%` export type CodeTweenProps = { tween: FullTween progress: number - config: CodeConfig + config: CodeSettings } & HTMLProps export type CodeStep = { @@ -34,22 +35,6 @@ export type CodeStep = { focus: FocusString annotations?: CodeAnnotation[] } -export type CodeConfig = { - /* not really the height, when this changes we measure everything again */ - parentHeight?: any - minColumns?: number - minZoom?: number - maxZoom?: number - horizontalCenter?: boolean - lineNumbers?: boolean - showCopyButton?: boolean - showExpandButton?: boolean - staticMediaQuery?: string - rows?: number | "focus" | (number | "focus")[] - triggerPosition?: TriggerPosition - debug?: boolean - themeName?: string -} function useCodeShift({ tween, @@ -132,7 +117,7 @@ function AfterDimensions({ }: { dimensions: NonNullable stepInfo: CodeShift - config: CodeConfig + config: CodeSettings progress: number htmlProps: HTMLProps tween: FullTween diff --git a/packages/mdx/src/smooth-code/index.tsx b/packages/mdx/src/smooth-code/index.tsx index 8eaa6fb3..fc6b872a 100644 --- a/packages/mdx/src/smooth-code/index.tsx +++ b/packages/mdx/src/smooth-code/index.tsx @@ -1,10 +1,6 @@ -import { - CodeTween, - CodeStep, - CodeConfig, -} from "./code-tween" +import { CodeTween, CodeStep } from "./code-tween" import { CodeAnnotation } from "./partial-step-parser" import { CodeSpring } from "./code-spring" export { CodeTween, CodeSpring } -export type { CodeAnnotation, CodeStep, CodeConfig } +export type { CodeAnnotation, CodeStep } From c6c44ff677f2fdac95859078bf744ef7a7293290 Mon Sep 17 00:00:00 2001 From: Rodrigo Pombo Date: Sat, 22 Jul 2023 09:20:31 +0000 Subject: [PATCH 2/2] Refactor mdx-client props --- packages/mdx/dev/content/rows.mdx | 2 +- packages/mdx/dev/content/test.mdx | 18 ++- packages/mdx/src/core/types.ts | 38 +++++ packages/mdx/src/mdx-client/code.tsx | 140 ++++++++++-------- packages/mdx/src/mdx-client/inline-code.tsx | 6 +- packages/mdx/src/mdx-client/preview.tsx | 32 ++-- packages/mdx/src/mdx-client/scrollycoding.tsx | 115 +++++++++----- packages/mdx/src/mdx-client/section.tsx | 59 +++++--- packages/mdx/src/mdx-client/slideshow.tsx | 77 +++++----- packages/mdx/src/mdx-client/slots.tsx | 59 +++++--- packages/mdx/src/mdx-client/spotlight.tsx | 44 +++--- packages/mdx/src/remark/code.ts | 10 +- packages/mdx/src/remark/steps.tsx | 2 + packages/mdx/src/remark/transform.code.ts | 10 +- packages/mdx/src/remark/transform.section.ts | 3 +- packages/mdx/src/remark/transform.ts | 2 +- packages/mdx/src/remark/unist-utils.ts | 4 +- 17 files changed, 393 insertions(+), 228 deletions(-) diff --git a/packages/mdx/dev/content/rows.mdx b/packages/mdx/dev/content/rows.mdx index c78fe2bd..f60d306e 100644 --- a/packages/mdx/dev/content/rows.mdx +++ b/packages/mdx/dev/content/rows.mdx @@ -66,7 +66,7 @@ console.log(7) - + ```js foo.js console.log(2) diff --git a/packages/mdx/dev/content/test.mdx b/packages/mdx/dev/content/test.mdx index d2c33608..5eb7290a 100644 --- a/packages/mdx/dev/content/test.mdx +++ b/packages/mdx/dev/content/test.mdx @@ -1,9 +1,13 @@ + + + + ```js -// mark(1) -function foobarloremipsumfoobarloremipsumsitametfoobarloremipsumfoobarloremipsumsitamet() { - // box[16:20] red - console.log("hover me") - // mark[9:12] - return 8 -} +console.log(1) ``` + + + +Hello 1 + + diff --git a/packages/mdx/src/core/types.ts b/packages/mdx/src/core/types.ts index 01247460..6c2fe08e 100644 --- a/packages/mdx/src/core/types.ts +++ b/packages/mdx/src/core/types.ts @@ -1,4 +1,5 @@ import type { Theme } from "@code-hike/lighter" +import type { CodeStep } from "../smooth-code" type TriggerPosition = `${number}px` | `${number}%` @@ -25,6 +26,10 @@ export type GlobalConfig = { showCopyButton?: boolean staticMediaQuery?: string triggerPosition?: TriggerPosition + + minZoom?: number + maxZoom?: number + horizontalCenter?: boolean } export function toGlobalConfig({ @@ -63,3 +68,36 @@ export type CodeSettings = { 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 +} diff --git a/packages/mdx/src/mdx-client/code.tsx b/packages/mdx/src/mdx-client/code.tsx index 9998eab5..059fb86d 100644 --- a/packages/mdx/src/mdx-client/code.tsx +++ b/packages/mdx/src/mdx-client/code.tsx @@ -1,96 +1,83 @@ import React from "react" import { CodeSpring } from "../smooth-code" +import { EditorSpring, EditorStep } from "../mini-editor" import { - EditorSpring, - EditorProps, - EditorStep, -} from "../mini-editor" -import { CodeSettings, GlobalConfig } from "../core/types" + CodeConfigProps, + ElementProps, + GlobalConfig, +} from "../core/types" -export function Code(props: EditorProps & GlobalConfig) { - 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 + return ( + + ) } -// build the CodeConfig from props and props.codeConfig -export function mergeCodeConfig( - props: Partial & { - codeConfig: Partial - } & 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 -} & GlobalConfig) { - 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 (
) } else { const frameProps = { - ...editorProps?.frameProps, + // ...editorStep?.frameProps, onTabClick, } return ( @@ -98,19 +85,44 @@ export function InnerCode({ className={`ch-codegroup not-prose ${ className || "" }`} - data-ch-theme={props.codeConfig?.themeName} + data-ch-theme={globalConfig.themeName} style={style} > ) } } +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, diff --git a/packages/mdx/src/mdx-client/inline-code.tsx b/packages/mdx/src/mdx-client/inline-code.tsx index 714fd6e2..e0cca1a8 100644 --- a/packages/mdx/src/mdx-client/inline-code.tsx +++ b/packages/mdx/src/mdx-client/inline-code.tsx @@ -3,7 +3,7 @@ import { Code } from "../utils" export function InlineCode({ className, - codeConfig, + globalConfig, children, code, ...rest @@ -11,14 +11,14 @@ export function InlineCode({ className: string code: Code children?: React.ReactNode - codeConfig: { themeName: string } + globalConfig: { themeName: string } }) { const { lines } = code const allTokens = lines.flatMap(line => line.tokens) return ( {frameless ? ( kids diff --git a/packages/mdx/src/mdx-client/scrollycoding.tsx b/packages/mdx/src/mdx-client/scrollycoding.tsx index ef1be972..22a82cbb 100644 --- a/packages/mdx/src/mdx-client/scrollycoding.tsx +++ b/packages/mdx/src/mdx-client/scrollycoding.tsx @@ -7,23 +7,33 @@ import { LinkableSection } from "./section" import { extractPreviewSteps } from "./steps" import { Swap } from "./ssmq" import { StaticStepContext } from "./slots" -import { GlobalConfig } from "../core/types" +import { + CodeConfigProps, + ElementProps, + GlobalConfig, +} from "../core/types" type ScrollycodingProps = { + globalConfig: GlobalConfig + // data children: React.ReactNode editorSteps: EditorStep[] - codeConfig: GlobalConfig - start?: number presetConfig?: PresetConfig - className?: string - style?: React.CSSProperties hasPreviewSteps?: boolean -} + // custom props + staticMediaQuery?: string + start?: number + // more things like : rows, showCopyButton, showExpandButton, lineNumbers, staticMediaQuery +} & CodeConfigProps & + ElementProps -export function Scrollycoding(props) { +export function Scrollycoding(props: ScrollycodingProps) { + const staticMediaQuery = + props.staticMediaQuery ?? + props.globalConfig.staticMediaQuery return ( } > @@ -32,17 +42,30 @@ export function Scrollycoding(props) { } function StaticScrollycoding({ + globalConfig, + // data children, - hasPreviewSteps, editorSteps, - ...rest + presetConfig, + hasPreviewSteps, + // local config + staticMediaQuery, + start = 0, + // element props: + className, + style, + // code config props + ...codeConfigProps }: ScrollycodingProps) { const { stepsChildren, previewChildren } = extractPreviewSteps(children, hasPreviewSteps) return (
{stepsChildren.map((children, i) => ( {children} @@ -63,23 +88,33 @@ function StaticScrollycoding({ function StaticSection({ editorStep, previewStep, - allProps, children, + presetConfig, + codeConfigProps, + globalConfig, }: { editorStep: EditorStep previewStep: React.ReactNode children: React.ReactNode - allProps: any + presetConfig?: PresetConfig + codeConfigProps: CodeConfigProps + globalConfig: GlobalConfig }) { const [step, setStep] = React.useState({ - ...editorStep, - ...allProps, + editorStep, + previewStep, + presetConfig, + codeConfigProps, + selectedId: undefined, }) const resetFocus = () => setStep({ - ...editorStep, - ...allProps, + editorStep, + previewStep, + presetConfig, + codeConfigProps, + selectedId: undefined, }) const setFocus = ({ fileName, @@ -90,11 +125,15 @@ function StaticSection({ focus: string | null id: string }) => { - const newStep = updateEditorStep(step, fileName, focus) + const newEditorStep = updateEditorStep( + step.editorStep, + fileName, + focus + ) setStep({ ...step, - ...newStep, + editorStep: newEditorStep, selectedId: id, }) } @@ -102,10 +141,9 @@ function StaticSection({ return (
{stepsChildren.map((children, i) => (
{presetConfig ? ( ) : hasPreviewSteps ? ( ) : null}
diff --git a/packages/mdx/src/mdx-client/section.tsx b/packages/mdx/src/mdx-client/section.tsx index 280bede0..4327a268 100644 --- a/packages/mdx/src/mdx-client/section.tsx +++ b/packages/mdx/src/mdx-client/section.tsx @@ -1,32 +1,43 @@ import React from "react" -import { EditorProps } from "../mini-editor" import { InnerCode, updateEditorStep } from "./code" +import { + CodeConfigProps, + EditorStep, + ElementProps, + GlobalConfig, +} from "../core/types" const SectionContext = React.createContext<{ - props: EditorProps + codeConfigProps: CodeConfigProps + editorStep: EditorStep setFocus: (x: { fileName?: string focus: string | null id: string }) => void }>({ - props: null!, + codeConfigProps: {}, + editorStep: null!, setFocus: () => {}, }) +type SectionProps = { + globalConfig: GlobalConfig + children: React.ReactNode + editorStep: EditorStep +} & CodeConfigProps & + ElementProps + export function Section({ children, className, style, - ...props -}: { - children: React.ReactNode - className?: string - style?: React.CSSProperties -}) { - const [state, setState] = React.useState(props) + editorStep, + ...codeConfigProps +}: SectionProps) { + const [state, setState] = React.useState(editorStep) - const resetFocus = () => setState(props) + const resetFocus = () => setState(editorStep) const setFocus = ({ fileName, @@ -55,7 +66,8 @@ export function Section({ > @@ -70,18 +82,29 @@ export function Section({ ) } -export function SectionCode(innerProps) { - const { props, setFocus } = - React.useContext(SectionContext) +export function SectionCode({ + globalConfig, + ...codeConfigProps +}: { globalConfig: GlobalConfig } & CodeConfigProps & + ElementProps) { + const section = React.useContext(SectionContext) const onTabClick = (filename: string) => { - setFocus({ fileName: filename, focus: null, id: "" }) + section.setFocus({ + fileName: filename, + focus: null, + id: "", + }) } return ( ) diff --git a/packages/mdx/src/mdx-client/slideshow.tsx b/packages/mdx/src/mdx-client/slideshow.tsx index f3d24d2f..bb9fef4a 100644 --- a/packages/mdx/src/mdx-client/slideshow.tsx +++ b/packages/mdx/src/mdx-client/slideshow.tsx @@ -1,46 +1,56 @@ import React from "react" import { clamp, useInterval } from "utils" -import { EditorProps, EditorStep } from "../mini-editor" +import { EditorStep } from "../mini-editor" import { InnerCode, updateEditorStep } from "./code" import { Preview, PresetConfig } from "./preview" import { extractPreviewSteps } from "./steps" +import { + CodeConfigProps, + ElementProps, + GlobalConfig, +} from "../core/types" -type ChangeEvent = { - index: number +type SlideshowProps = { + globalConfig: GlobalConfig + // data + children: React.ReactNode + editorSteps: EditorStep[] + hasPreviewSteps?: boolean + presetConfig?: PresetConfig + // local config + autoFocus?: boolean + start?: number + onChange?: (e: { index: number }) => void + autoPlay?: number + loop?: boolean +} & CodeConfigProps & + ElementProps + +export function Slideshow(props: SlideshowProps) { + return } -export function Slideshow({ +function InnerSlideshow({ + globalConfig, + // data children, - className, - code, - codeConfig, editorSteps, - autoFocus, hasPreviewSteps, + presetConfig, + // local config: + autoFocus, + autoPlay, // Set the initial slide index start = 0, // Called when the slideshow state changes and returns the current state object onChange: onSlideshowChange = () => {}, - presetConfig, - style, - autoPlay, loop = false, - ...rest -}: { - children: React.ReactNode - className?: string - code?: EditorProps["codeConfig"] - codeConfig: EditorProps["codeConfig"] - editorSteps: EditorStep[] - hasPreviewSteps?: boolean - autoFocus?: boolean - start?: number - onChange?: (e: ChangeEvent) => void - presetConfig?: PresetConfig - style?: React.CSSProperties - autoPlay?: number - loop?: boolean -}) { + // element props: + className, + style, + // code config props: + ...codeConfigProps +}: SlideshowProps) { const { stepsChildren, previewChildren } = extractPreviewSteps(children, hasPreviewSteps) const withPreview = presetConfig || hasPreviewSteps @@ -97,16 +107,13 @@ export function Slideshow({ withPreview ? "ch-slideshow-with-preview" : "" } ${className || ""}`} style={style} - data-ch-theme={codeConfig.themeName} + data-ch-theme={globalConfig.themeName} >
{presetConfig ? ( @@ -114,11 +121,13 @@ export function Slideshow({ className="ch-slideshow-preview" files={tab.files} presetConfig={presetConfig} + globalConfig={globalConfig} /> ) : hasPreviewSteps ? ( ) : null}
diff --git a/packages/mdx/src/mdx-client/slots.tsx b/packages/mdx/src/mdx-client/slots.tsx index 8f64a8a6..246ab0ff 100644 --- a/packages/mdx/src/mdx-client/slots.tsx +++ b/packages/mdx/src/mdx-client/slots.tsx @@ -2,53 +2,74 @@ import React from "react" import { EditorStep } from "../mini-editor" import { InnerCode } from "./code" import { Preview } from "./preview" +import { + CodeConfigProps, + ElementProps, + GlobalConfig, +} from "../core/types" -export function CodeSlot() { +type CodeSlotProps = CodeConfigProps & ElementProps + +export function CodeSlot(localProps: CodeSlotProps) { const context = React.useContext(StaticStepContext) if (!context) { return null } - return -} - -function InnerCodeSlot({ editorStep, setFocus }) { + const { + editorStep, + codeConfigProps, + setFocus, + globalConfig, + } = context const onTabClick = (filename: string) => { setFocus({ fileName: filename, focus: null, id: "" }) } - const { preset, presetConfig, ...props } = editorStep - return + + return ( + + ) } -export function PreviewSlot() { + +export function PreviewSlot(localProps: any) { const context = React.useContext(StaticStepContext) if (!context) { return null } - return -} + const { + editorStep, + previewStep, + presetConfig, + globalConfig, + } = context -function InnerPreviewSlot({ - previewStep, - allProps, - editorStep, -}) { - const { preset, ...props } = allProps return ( ) } export const StaticStepContext = React.createContext<{ editorStep: EditorStep + globalConfig: GlobalConfig previewStep: React.ReactNode - allProps: any + presetConfig?: any + codeConfigProps: CodeConfigProps setFocus: (x: { fileName?: string focus: string | null diff --git a/packages/mdx/src/mdx-client/spotlight.tsx b/packages/mdx/src/mdx-client/spotlight.tsx index 029cbdcb..6f7048e5 100644 --- a/packages/mdx/src/mdx-client/spotlight.tsx +++ b/packages/mdx/src/mdx-client/spotlight.tsx @@ -1,29 +1,37 @@ import React from "react" -import { EditorProps, EditorStep } from "../mini-editor" +import { EditorStep } from "../mini-editor" import { InnerCode, updateEditorStep } from "./code" import { Preview, PresetConfig } from "./preview" import { extractPreviewSteps } from "./steps" +import { + CodeConfigProps, + ElementProps, + GlobalConfig, +} from "../core/types" + +type SpotlightProps = { + globalConfig: GlobalConfig + // data + children: React.ReactNode + editorSteps: EditorStep[] + presetConfig?: PresetConfig + hasPreviewSteps?: boolean + // local config + start?: number +} & CodeConfigProps & + ElementProps export function Spotlight({ children, editorSteps, - codeConfig, + globalConfig, start = 0, presetConfig, className, style, hasPreviewSteps, - ...rest -}: { - children: React.ReactNode - editorSteps: EditorStep[] - codeConfig: EditorProps["codeConfig"] - start?: number - presetConfig?: PresetConfig - className?: string - style?: React.CSSProperties - hasPreviewSteps?: boolean -}) { + ...codeConfigProps +}: SpotlightProps) { const { stepsChildren, previewChildren } = extractPreviewSteps(children, hasPreviewSteps) @@ -54,7 +62,7 @@ export function Spotlight({ withPreview ? "ch-spotlight-with-preview" : "" } ${className || ""}`} style={style} - data-ch-theme={codeConfig.themeName} + data-ch-theme={globalConfig.themeName} >
{headerElement?.props?.children ? ( @@ -82,9 +90,9 @@ export function Spotlight({
{presetConfig ? ( @@ -92,11 +100,13 @@ export function Spotlight({ className="ch-spotlight-preview" files={tab.files} presetConfig={presetConfig} + globalConfig={globalConfig} /> ) : hasPreviewSteps ? ( ) : null}
diff --git a/packages/mdx/src/remark/code.ts b/packages/mdx/src/remark/code.ts index 8b295062..d2fe4bd4 100644 --- a/packages/mdx/src/remark/code.ts +++ b/packages/mdx/src/remark/code.ts @@ -1,11 +1,11 @@ import { highlight } from "./lighter" import { NodeInfo, splitChildren } from "./unist-utils" import { CodeStep } from "../smooth-code" -import { EditorProps } from "../mini-editor" import { getAnnotationsFromMetastring } from "./annotations.metastring" import { CodeNode, SuperNode } from "./nodes" import { CodeHikeConfig } from "./config" import { splitCodeAndAnnotations } from "./annotations.comments" +import { EditorStep } from "../core/types" export function isEditorNode( node: SuperNode, @@ -34,14 +34,12 @@ export async function mapAnyCodeNode( } } -type Props = Omit - async function mapCode( nodeInfo: NodeInfo, config: CodeHikeConfig -): Promise { +): Promise { const file = await mapFile(nodeInfo, config) - const props: Props = { + const props: EditorStep = { northPanel: { tabs: [file.name], active: file.name, @@ -55,7 +53,7 @@ async function mapCode( export async function mapEditor( { node }: NodeInfo, config: CodeHikeConfig -): Promise { +): Promise { const [northNodes, southNodes = []] = splitChildren( node, "thematicBreak" diff --git a/packages/mdx/src/remark/steps.tsx b/packages/mdx/src/remark/steps.tsx index b3fe60db..8afc4acd 100644 --- a/packages/mdx/src/remark/steps.tsx +++ b/packages/mdx/src/remark/steps.tsx @@ -59,9 +59,11 @@ export async function extractStepsInfo( filter ) } + const node = child as any step.children.push({ type: "mdxJsxFlowElement", name: "CH.CodeSlot", + attributes: node.attributes, }) } else if ( child.type === "mdxJsxFlowElement" && diff --git a/packages/mdx/src/remark/transform.code.ts b/packages/mdx/src/remark/transform.code.ts index 7e0f7df5..8ae7cb8e 100644 --- a/packages/mdx/src/remark/transform.code.ts +++ b/packages/mdx/src/remark/transform.code.ts @@ -1,9 +1,5 @@ import { NodeInfo, toJSX, visitAsync } from "./unist-utils" -import { - isEditorNode, - mapAnyCodeNode, - mapEditor, -} from "./code" +import { isEditorNode, mapAnyCodeNode } from "./code" import { CodeNode, JsxNode, SuperNode } from "./nodes" import { CodeHikeConfig } from "./config" @@ -38,7 +34,9 @@ async function transformCode( ) { toJSX(nodeInfo.node, { name: "CH.Code", - props: await mapAnyCodeNode(nodeInfo, config), + props: { + editorStep: await mapAnyCodeNode(nodeInfo, config), + }, appendProps: true, addConfigProp: true, }) diff --git a/packages/mdx/src/remark/transform.section.ts b/packages/mdx/src/remark/transform.section.ts index 5e9d4035..2e14828f 100644 --- a/packages/mdx/src/remark/transform.section.ts +++ b/packages/mdx/src/remark/transform.section.ts @@ -35,6 +35,7 @@ async function transformSection( toJSX(editorNode, { name: "CH.SectionCode", appendProps: true, + addConfigProp: true, props: {}, }) } @@ -46,7 +47,7 @@ async function transformSection( if (props) { toJSX(node, { name: "CH.Section", - props: props as any, + props: { editorStep: props }, addConfigProp: true, appendProps: true, }) diff --git a/packages/mdx/src/remark/transform.ts b/packages/mdx/src/remark/transform.ts index 3619f6fa..612d9af7 100644 --- a/packages/mdx/src/remark/transform.ts +++ b/packages/mdx/src/remark/transform.ts @@ -146,7 +146,7 @@ async function getCSSVariables( } /** - * Creates a `chCodeConfig` variable node in the tree + * Creates a `chGlobalConfig` variable node in the tree * so that the components can access the config * * Also add a style tags with all the css variables with the theme colors diff --git a/packages/mdx/src/remark/unist-utils.ts b/packages/mdx/src/remark/unist-utils.ts index 0c087ced..2c7373f6 100644 --- a/packages/mdx/src/remark/unist-utils.ts +++ b/packages/mdx/src/remark/unist-utils.ts @@ -46,7 +46,7 @@ export async function visitAsync( await Promise.all(promises) } -export const CH_CODE_CONFIG_VAR_NAME = "chCodeConfig" +export const CH_CODE_CONFIG_VAR_NAME = "chGlobalConfig" /** * Transforms a node into a JSX Flow ELement (or another given type). @@ -89,7 +89,7 @@ export function toJSX( if (addConfigProp) { node.attributes.push( - toAttribute("codeConfig", CH_CODE_CONFIG_VAR_NAME, { + toAttribute("globalConfig", CH_CODE_CONFIG_VAR_NAME, { type: "Identifier", name: CH_CODE_CONFIG_VAR_NAME, })