Skip to content

Commit c8f7b29

Browse files
committed
Split client and server code
1 parent 8889b5f commit c8f7b29

24 files changed

+373
-436
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import React from "react"
2+
import { CodeAnnotation } from "@code-hike/smooth-code"
3+
4+
export function Annotation() {
5+
return "error: code hike remark plugin not running or annotation isn't at the right place"
6+
}
7+
8+
export const annotationsMap: Record<
9+
string,
10+
CodeAnnotation["Component"]
11+
> = {
12+
box: Box,
13+
bg: Background,
14+
label: Label,
15+
link: CodeLink,
16+
}
17+
18+
function Box({
19+
children,
20+
data,
21+
theme,
22+
}: {
23+
data: any
24+
children: React.ReactNode
25+
theme: any
26+
}) {
27+
const border =
28+
typeof data === "string"
29+
? data
30+
: theme.tokenColors.find((tc: any) =>
31+
tc.scope?.includes("string")
32+
)?.settings?.foreground || "yellow"
33+
return (
34+
<span style={{ outline: `2px solid ${border}` }}>
35+
{children}
36+
</span>
37+
)
38+
}
39+
40+
function Background({
41+
children,
42+
data,
43+
style,
44+
theme,
45+
}: {
46+
data: string
47+
children: React.ReactNode
48+
style?: React.CSSProperties
49+
theme?: any
50+
}) {
51+
const bg =
52+
data ||
53+
(((theme as any).colors[
54+
"editor.lineHighlightBackground"
55+
] ||
56+
(theme as any).colors[
57+
"editor.selectionHighlightBackground"
58+
]) as string)
59+
return (
60+
<div
61+
style={{
62+
...style,
63+
background: bg,
64+
// cursor: "pointer",
65+
}}
66+
// onClick={_ => alert("clicked")}
67+
>
68+
{children}
69+
</div>
70+
)
71+
}
72+
73+
function Label({
74+
children,
75+
data,
76+
style,
77+
theme,
78+
}: {
79+
data: any
80+
children: React.ReactNode
81+
style?: React.CSSProperties
82+
theme?: any
83+
}) {
84+
const bg = ((theme as any).colors[
85+
"editor.lineHighlightBackground"
86+
] ||
87+
(theme as any).colors[
88+
"editor.selectionHighlightBackground"
89+
]) as string
90+
const [hover, setHover] = React.useState(false)
91+
92+
return (
93+
<div
94+
style={{
95+
...style,
96+
background: hover ? bg : undefined,
97+
}}
98+
onMouseEnter={() => setHover(true)}
99+
onMouseLeave={() => setHover(false)}
100+
>
101+
{children}
102+
<div
103+
style={{
104+
position: "absolute",
105+
right: 0,
106+
paddingRight: 16,
107+
display: hover ? "block" : "none",
108+
opacity: 0.7,
109+
}}
110+
>
111+
{data?.children || data}
112+
</div>
113+
</div>
114+
)
115+
}
116+
117+
function CodeLink({
118+
children,
119+
data,
120+
}: {
121+
data:
122+
| {
123+
url: string
124+
title: string | undefined
125+
}
126+
| string
127+
children: React.ReactNode
128+
}) {
129+
const url = (data as any)?.url || data
130+
const title = (data as any)?.title
131+
return (
132+
<a
133+
href={url}
134+
target="_blank"
135+
rel="noopener noreferrer"
136+
title={title}
137+
style={{
138+
textDecoration: "underline",
139+
textDecorationStyle: "dotted",
140+
color: "inherit",
141+
}}
142+
>
143+
{children}
144+
</a>
145+
)
146+
}

packages/mdx/src/client/code.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from "react"
2+
import { CodeSpring } from "@code-hike/smooth-code"
3+
import {
4+
EditorSpring,
5+
EditorProps,
6+
} from "@code-hike/mini-editor"
7+
8+
export function Code(props: EditorProps) {
9+
if (
10+
!props.southPanel &&
11+
props.files.length === 1 &&
12+
!props.files[0].name
13+
) {
14+
return (
15+
<CodeSpring
16+
className="ch-code"
17+
config={props.codeConfig}
18+
step={props.files[0]}
19+
/>
20+
)
21+
} else {
22+
return <EditorSpring {...props} />
23+
}
24+
}

packages/mdx/src/preview.tsx renamed to packages/mdx/src/client/preview.tsx

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,3 @@ function mergeFiles(
6666
})
6767
return result
6868
}
69-
70-
export async function getPresetConfig(
71-
attributes?: {
72-
name: string
73-
value: "string"
74-
}[]
75-
) {
76-
// todo add cache
77-
const presetAttribute = attributes?.find(
78-
(attr: any) => attr.name === "preset"
79-
)
80-
if (!presetAttribute) return undefined
81-
const url = presetAttribute.value
82-
const prefix = "https://codesandbox.io/s/"
83-
const csbid = url.slice(prefix.length)
84-
const configUrl = `https://codesandbox.io/api/v1/sandboxes/${csbid}/sandpack`
85-
const res = await fetch(configUrl)
86-
return await res.json()
87-
}
File renamed without changes.

packages/mdx/src/scrollycoding.tsx renamed to packages/mdx/src/client/scrollycoding.tsx

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
1-
import { visitAsync, toJSX } from "./unist-utils"
2-
import { Node, Parent } from "unist"
31
import React from "react"
42
import {
5-
EditorSpring,
63
EditorProps,
74
EditorStep,
85
} from "@code-hike/mini-editor"
9-
import { mapEditor, Code } from "./code"
10-
import { reduceSteps } from "./code-files-reducer"
11-
import { extractStepsInfo } from "./steps"
6+
import { Code } from "./code"
127
import {
138
Scroller,
149
Step as ScrollerStep,
1510
} from "@code-hike/scroller"
16-
import {
17-
Preview,
18-
PresetConfig,
19-
getPresetConfig,
20-
} from "./preview"
11+
import { Preview, PresetConfig } from "./preview"
2112

2213
export function Scrollycoding({
2314
children,
@@ -77,41 +68,3 @@ export function Scrollycoding({
7768
</section>
7869
)
7970
}
80-
81-
export async function transformScrollycodings(
82-
tree: Node,
83-
config: { theme: any }
84-
) {
85-
await visitAsync(
86-
tree,
87-
"mdxJsxFlowElement",
88-
async node => {
89-
if (node.name === "CH.Scrollycoding") {
90-
await transformScrollycoding(node, config)
91-
}
92-
}
93-
)
94-
}
95-
async function transformScrollycoding(
96-
node: Node,
97-
{ theme }: { theme: any }
98-
) {
99-
const editorSteps = await extractStepsInfo(
100-
node as Parent,
101-
{ theme },
102-
"merge step with previous"
103-
)
104-
105-
const presetConfig = await getPresetConfig(
106-
(node as any).attributes
107-
)
108-
109-
toJSX(node, {
110-
props: {
111-
codeConfig: { theme },
112-
editorSteps: editorSteps,
113-
presetConfig,
114-
},
115-
appendProps: true,
116-
})
117-
}

packages/mdx/src/section.tsx renamed to packages/mdx/src/client/section.tsx

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
1-
import visit from "unist-util-visit"
2-
import { Node, Parent } from "unist"
3-
import { highlight } from "@code-hike/highlighter"
4-
import { extractLinks } from "./links"
5-
import { visitAsync, toJSX } from "./unist-utils"
61
import React from "react"
7-
import {
8-
EditorSpring,
9-
EditorProps,
10-
} from "@code-hike/mini-editor"
11-
import {
12-
Code,
13-
mapEditor,
14-
isEditorNode,
15-
mapAnyCodeNode,
16-
} from "./code"
2+
import { EditorProps } from "@code-hike/mini-editor"
3+
import { Code } from "./code"
174

185
const SectionContext = React.createContext<{
196
props: EditorProps
@@ -130,66 +117,3 @@ export function SectionLink({
130117
/>
131118
)
132119
}
133-
134-
export async function transformSections(
135-
tree: Node,
136-
config: { theme: any }
137-
) {
138-
await visitAsync(
139-
tree,
140-
"mdxJsxFlowElement",
141-
async sectionNode => {
142-
if (sectionNode.name === "CH.Section") {
143-
await transformSection(sectionNode, config)
144-
}
145-
}
146-
)
147-
}
148-
149-
async function transformSection(
150-
node: Node,
151-
config: { theme: any }
152-
) {
153-
let props
154-
await visitAsync(
155-
node,
156-
["mdxJsxFlowElement", "code"],
157-
async (node, index, parent) => {
158-
if (isEditorNode(node)) {
159-
props = await mapAnyCodeNode(
160-
{ node, index, parent: parent! },
161-
config
162-
)
163-
toJSX(node, { name: "CH.SectionCode", props: {} })
164-
}
165-
}
166-
)
167-
168-
transformLinks(node)
169-
170-
if (props) {
171-
toJSX(node, { name: "CH.Section", props: props as any })
172-
} else {
173-
toJSX(node, { name: "div", props: {} })
174-
}
175-
}
176-
177-
function transformLinks(tree: Node) {
178-
visit(tree, "link", (linkNode: any) => {
179-
const url = decodeURI(linkNode["url"])
180-
if (url.startsWith("focus://")) {
181-
const [firstPart, secondPart] = decodeURI(url)
182-
.substr("focus://".length)
183-
.split("#")
184-
const hasFile = Boolean(secondPart)
185-
const props = hasFile
186-
? { file: firstPart, focus: secondPart, id: url }
187-
: { focus: firstPart, id: url }
188-
toJSX(linkNode, {
189-
type: "mdxJsxTextElement",
190-
name: "CH.SectionLink",
191-
props,
192-
})
193-
}
194-
})
195-
}
File renamed without changes.

0 commit comments

Comments
 (0)