-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathDemoController.tsx
More file actions
61 lines (50 loc) · 1.64 KB
/
DemoController.tsx
File metadata and controls
61 lines (50 loc) · 1.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'use client';
import * as React from 'react';
import { useRunner } from 'react-runner';
import { CodeControllerContext } from '@mui/internal-docs-infra/CodeControllerContext';
import type { ControlledCode } from '@mui/internal-docs-infra/CodeHighlighter/types';
import { useCodeExternals } from '@mui/internal-docs-infra/CodeExternalsContext';
function Runner({ code }: { code: string }) {
const externalsContext = useCodeExternals();
const scope = React.useMemo(() => {
let externals = externalsContext?.externals;
if (!externals) {
externals = { imports: { react: React } };
}
return { import: { ...externals } };
}, [externalsContext]);
const { element, error } = useRunner({ code, scope });
if (error) {
return <div>{error}</div>;
}
return element;
}
export function DemoController({ children }: { children: React.ReactNode }) {
// @focus-start @padding 1
const [code, setCode] = React.useState<ControlledCode | undefined>(undefined);
const components = React.useMemo(
() =>
code
? Object.keys(code).reduce(
(acc, cur) => {
const source = code[cur]?.source;
if (!source) {
return acc;
}
acc[cur] = <Runner code={source} />;
return acc;
},
{} as Record<string, React.ReactNode>,
)
: undefined,
[code],
);
const contextValue = React.useMemo(
() => ({ code, setCode, components }),
[code, setCode, components],
);
return (
<CodeControllerContext.Provider value={contextValue}>{children}</CodeControllerContext.Provider>
);
// @focus-end
}