/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import React, {
CSSProperties,
Suspense,
lazy,
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
} from 'react';
import {usePrismTheme} from '@docusaurus/theme-common';
import clsx from 'clsx';
import nullthrows from 'nullthrows';
import {LiveProvider, LiveEditor, LivePreview, LiveError} from 'react-live';
import EditorToolbar from './EditorToolbar';
import type {FlexStyle} from './FlexStyle';
import type {StyleNode} from './YogaViewer';
import styles from './Playground.module.css';
const defaultCode = `
`.trim();
export type Props = Readonly<{
code?: string;
height?: CSSProperties['height'];
autoFocus?: boolean;
}>;
export default function Playground({code, height, autoFocus}: Props) {
const prismTheme = usePrismTheme();
const playgroundRef = useRef(null);
const editorScrollRef = useRef(null);
const [isLoaded, setIsLoaded] = useState(false);
const [liveCode, setLiveCode] = useState(code ?? defaultCode);
const [scrollbarWidth, setScrollbarWidth] = useState(0);
const LivePreviewWrapper = useCallback(
(props: React.ComponentProps<'div'>) => {
useEffect(() => {
setIsLoaded(true);
}, []);
return ;
},
[],
);
useEffect(() => {
// TODO: This is hacky and relies on being called after some operation
// "react-live" does which itself can manipulate global focus
if (isLoaded && autoFocus) {
const codeElem = playgroundRef?.current?.querySelector('.prism-code');
const sel = window.getSelection();
if (codeElem?.clientHeight && sel != null) {
sel.selectAllChildren(codeElem);
sel.collapseToStart();
}
}
}, [isLoaded, autoFocus]);
useLayoutEffect(() => {
// The toolbar is positioned relative to the outside of the scrolling
// container so it stays in the same place when scrolling, but this means
// it isn't automatically adjusted for scrollbar width
if (editorScrollRef.current) {
setScrollbarWidth(
editorScrollRef.current.offsetWidth -
editorScrollRef.current.clientWidth,
);
}
});
const heightStyle = height
? ({'--yg-playground-height': height} as React.CSSProperties)
: undefined;
return (