📄 Playground¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 1 |
| 📦 Imports | 33 |
| 💠 JSX Elements | 23 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/website/src/components/Playground.tsx
📦 Imports¶
| Name | Source |
|---|---|
ImperativePanelHandle |
react-resizable-panels |
useWindowSize |
@docusaurus/theme-common |
clsx |
clsx |
useCallback |
react |
useEffect |
react |
useMemo |
react |
useRef |
react |
useState |
react |
React |
react |
Panel |
react-resizable-panels |
PanelGroup |
react-resizable-panels |
PanelResizeHandle |
react-resizable-panels |
UpdateModel |
./linter/types |
ErrorGroup |
./types |
RuleDetails |
./types |
SelectedRange |
./types |
TabType |
./types |
ASTViewer |
./ast/ASTViewer |
ConfigEslint |
./config/ConfigEslint |
ConfigTypeScript |
./config/ConfigTypeScript |
EditorEmbed |
./editor/EditorEmbed |
LoadingEditor |
./editor/LoadingEditor |
ErrorsViewer |
./ErrorsViewer |
ErrorViewer |
./ErrorsViewer |
ESQueryFilter |
./ESQueryFilter |
useHashState |
./hooks/useHashState |
EditorTabs |
./layout/EditorTabs |
Loader |
./layout/Loader |
defaultConfig |
./options |
detailTabs |
./options |
OptionsSelector |
./OptionsSelector |
styles |
./Playground.module.css |
TypesDetails |
./typeDetails/TypesDetails |
JSX Elements¶
| Component | Type | Props | Children |
|---|---|---|---|
div |
element | className={styles.codeContainer} | |
PanelGroup |
component | autoSaveId="playground-size", className={styles.panelGroup}, direction={windo... | |
Panel |
component | className={styles.PanelColumn}, collapsible={true}, defaultSize={windowSize =... | |
div |
element | className={styles.playgroundMenu} | |
OptionsSelector |
component | setState={setState}, state={state}, tsVersions={tsVersions} | none |
PanelResizeHandle |
component | className={styles.PanelResizeHandle}, style={windowSize === 'mobile' ? { disp... | none |
Panel |
component | className={styles.PanelColumn}, collapsible={true}, id="playgroundEditor" | {isLoading && |
Loader |
component | none | none |
EditorTabs |
component | active={activeTab}, change={setTab}, showModal={onVisualEditor}, showVisualEd... | none |
ActiveVisualEditor |
component | className={styles.tabCode}, config={state[activeTab]}, onChange={setState}, r... | none |
div |
element | className={clsx( styles.tabCode, ActiveVisualEditor && styles.hidden, )}, key... | |
EditorEmbed |
component | none | none |
LoadingEditor |
component | activeTab={activeTab}, onASTChange={setAstModel}, onChange={setState}, onLoad... | none |
PanelResizeHandle |
component | className={styles.PanelResizeHandle} | none |
Panel |
component | className={styles.PanelColumn}, collapsible={true}, id="playgroundInfo" | , |
div |
element | none | |
EditorTabs |
component | active={state.showAST ?? false}, additionalTabsInfo={{ Errors: markers[active... | none |
ESQueryFilter |
component | defaultValue={state.esQuery?.filter}, onChange={(filter, selector) => setStat... | none |
div |
element | className={styles.playgroundInfoContainer} | {state.showAST === 'es' && esQueryError ? ( <ErrorViewer title="Invalid Selec... |
ErrorViewer |
component | title="Invalid Selector", type="warning", value={esQueryError} | none |
TypesDetails |
component | cursorPosition={position}, onHoverNode={setSelectedRange}, typeChecker={astMo... | none |
ASTViewer |
component | cursorPosition={position}, enableScrolling={state.scroll}, filter={ state.sho... | none |
ErrorsViewer |
component | value={markers[activeTab]} | none |
Functions¶
Playground(): React.JSX.Element¶
Returns: React.JSX.Element
Calls:
useWindowSize (from @docusaurus/theme-common)useHashState (from ./hooks/useHashState)useState (from react)useRef (from react)useMemo (from react)Math.roundparseFloatgetComputedStyleuseCallback (from react)setRuleNamessetTSVersionsetIsLoadingsetVisualTSConfigsetVisualEslintRcuseEffect (from react)playgroundMenuRef.current?.collapseplaygroundMenuRef.current?.expandclsx (from clsx)markers[activeTab].reducesetState
Code
function Playground(): React.JSX.Element {
const windowSize = useWindowSize();
const [state, setState] = useHashState(defaultConfig);
const [astModel, setAstModel] = useState<UpdateModel>();
const [markers, setMarkers] = useState<Record<TabType, ErrorGroup[]>>({
code: [],
eslintrc: [],
tsconfig: [],
});
const [ruleNames, setRuleNames] = useState<RuleDetails[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [tsVersions, setTSVersion] = useState<readonly string[]>([]);
const [selectedRange, setSelectedRange] = useState<SelectedRange>();
const [position, setPosition] = useState<number>();
const [activeTab, setTab] = useState<TabType>('code');
const [esQueryError, setEsQueryError] = useState<Error>();
const [visualEslintRc, setVisualEslintRc] = useState(false);
const [visualTSConfig, setVisualTSConfig] = useState(false);
const playgroundMenuRef = useRef<ImperativePanelHandle>(null);
const optionsSize = useMemo(
() =>
Math.round(
(parseFloat(getComputedStyle(document.documentElement).fontSize) *
2000) /
innerWidth,
),
[],
);
const onLoaded = useCallback(
(ruleNames: RuleDetails[], tsVersions: readonly string[]) => {
setRuleNames(ruleNames);
setTSVersion(tsVersions);
setIsLoading(false);
},
[],
);
const ActiveVisualEditor =
!isLoading &&
{
code: undefined,
eslintrc: visualEslintRc && ConfigEslint,
tsconfig: visualTSConfig && ConfigTypeScript,
}[activeTab];
const onVisualEditor = useCallback((tab: TabType) => {
if (tab === 'tsconfig') {
setVisualTSConfig(val => !val);
} else if (tab === 'eslintrc') {
setVisualEslintRc(val => !val);
}
}, []);
useEffect(() => {
if (windowSize === 'mobile') {
playgroundMenuRef.current?.collapse();
} else if (windowSize === 'desktop') {
playgroundMenuRef.current?.expand();
}
}, [windowSize]);
return (
<div className={styles.codeContainer}>
<PanelGroup
autoSaveId="playground-size"
className={styles.panelGroup}
direction={windowSize === 'mobile' ? 'vertical' : 'horizontal'}
>
<Panel
className={styles.PanelColumn}
collapsible={true}
defaultSize={windowSize === 'mobile' ? 0 : optionsSize}
id="playgroundMenu"
ref={playgroundMenuRef}
>
<div className={styles.playgroundMenu}>
<OptionsSelector
setState={setState}
state={state}
tsVersions={tsVersions}
/>
</div>
</Panel>
<PanelResizeHandle
className={styles.PanelResizeHandle}
style={windowSize === 'mobile' ? { display: 'none' } : {}}
/>
<Panel
className={styles.PanelColumn}
collapsible={true}
id="playgroundEditor"
>
{isLoading && <Loader />}
<EditorTabs
active={activeTab}
change={setTab}
showModal={onVisualEditor}
showVisualEditor={activeTab !== 'code'}
tabs={['code', 'tsconfig', 'eslintrc']}
/>
{ActiveVisualEditor && (
<ActiveVisualEditor
className={styles.tabCode}
config={state[activeTab]}
onChange={setState}
ruleOptions={ruleNames}
/>
)}
<div
className={clsx(
styles.tabCode,
ActiveVisualEditor && styles.hidden,
)}
key="monacoEditor"
>
<EditorEmbed />
</div>
<LoadingEditor
{...state}
activeTab={activeTab}
onASTChange={setAstModel}
onChange={setState}
onLoaded={onLoaded}
onMarkersChange={setMarkers}
onSelect={setPosition}
selectedRange={selectedRange}
/>
</Panel>
<PanelResizeHandle className={styles.PanelResizeHandle} />
<Panel
className={styles.PanelColumn}
collapsible={true}
id="playgroundInfo"
>
<div>
<EditorTabs
active={state.showAST ?? false}
additionalTabsInfo={{
Errors:
markers[activeTab].reduce(
(prev, cur) => prev + cur.items.length,
0,
) || 0,
}}
change={showAST => setState({ showAST })}
tabs={detailTabs}
/>
{state.showAST === 'es' && (
<ESQueryFilter
defaultValue={state.esQuery?.filter}
onChange={(filter, selector) =>
setState({ esQuery: { filter, selector } })
}
onError={setEsQueryError}
/>
)}
</div>
<div className={styles.playgroundInfoContainer}>
{state.showAST === 'es' && esQueryError ? (
<ErrorViewer
title="Invalid Selector"
type="warning"
value={esQueryError}
/>
) : state.showAST && astModel ? (
state.showAST === 'types' && astModel.storedTsAST ? (
<TypesDetails
cursorPosition={position}
onHoverNode={setSelectedRange}
typeChecker={astModel.typeChecker}
value={astModel.storedTsAST}
/>
) : (
<ASTViewer
cursorPosition={position}
enableScrolling={state.scroll}
filter={
state.showAST === 'es' ? state.esQuery?.selector : undefined
}
key={state.showAST}
onHoverNode={setSelectedRange}
showTokens={state.showTokens}
value={
state.showAST === 'types'
? undefined
: astModel[
`stored${({ es: 'AST', scope: 'Scope', ts: 'TsAST' } as const)[state.showAST]}` as const
]
}
/>
)
) : (
<ErrorsViewer value={markers[activeTab]} />
)}
</div>
</Panel>
</PanelGroup>
</div>
);
}
Generated by Syntax Scribe