-
-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathPlayground.tsx
More file actions
109 lines (93 loc) · 2.56 KB
/
Copy pathPlayground.tsx
File metadata and controls
109 lines (93 loc) · 2.56 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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { usePageData } from '@rspress/core/runtime';
// @ts-ignore Cannot find module _rspress_playground_imports
import getImport from '_rspress_playground_imports';
import React, {
type HTMLAttributes,
type ReactNode,
useCallback,
useState,
} from 'react';
import { Editor, Runner } from '../../dist/web/esm';
// inject by builder in cli/index.ts
declare global {
const __PLAYGROUND_DIRECTION__: Direction;
}
type Direction = 'horizontal' | 'vertical';
export interface PlaygroundProps extends HTMLAttributes<HTMLDivElement> {
code: string;
language: string;
direction?: Direction;
editorPosition?: 'left' | 'right';
renderChildren?: (
props: PlaygroundProps,
code: string,
direction: Direction,
) => ReactNode;
}
function useDirection(props: PlaygroundProps): Direction {
const { page } = usePageData();
const { frontmatter = {} } = page;
const { playgroundDirection } = frontmatter;
// from props
if (props.direction) {
return props.direction;
}
// from page frontmatter
if (playgroundDirection) {
return playgroundDirection as Direction;
}
// inject by config
try {
return __PLAYGROUND_DIRECTION__;
} catch (_e) {
// ignore
}
return 'horizontal';
}
export default function Playground(props: PlaygroundProps) {
const {
code: codeProp,
language,
className = '',
direction: directionProp,
editorPosition,
renderChildren,
...rest
} = props;
const direction = useDirection(props);
const [code, setCode] = useState(codeProp);
const handleCodeChange = useCallback((e?: string) => {
setCode(e || '');
}, []);
const useReverseLayout =
direction === 'horizontal' && editorPosition === 'left';
const monacoLanguage =
language === 'tsx' || language === 'ts' ? 'typescript' : 'javascript';
const classNames = [
'rspress-playground',
`rspress-playground-${direction}`,
`rspress-playground-reverse-${useReverseLayout ? 'y' : 'n'}`,
'rp-not-doc',
className,
]
.filter(Boolean)
.join(' ');
return (
<div className={classNames} {...rest}>
<Runner language={language} code={code} getImport={getImport} />
<Editor
value={code}
onChange={handleCodeChange}
language={monacoLanguage}
beforeMount={monaco => {
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: true,
noSyntaxValidation: true,
noSuggestionDiagnostics: true,
});
}}
/>
{renderChildren?.(props, code, direction)}
</div>
);
}