react-live#LiveEditor JavaScript Examples

The following examples show how to use react-live#LiveEditor. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ComponentCode.js    From basis with MIT License 6 votes vote down vote up
function ComponentCode({ className, code }) {
  const theme = useTheme();

  return (
    <div
      className={className}
      css={{
        padding: `${theme.space[3]} ${theme.space[5]}`,
        "textarea:focus": {
          outline: "none",
        },
      }}
    >
      <LiveEditor />
      <CopyToClipboard text={code}>
        <button>Copy Code</button>
      </CopyToClipboard>
    </div>
  );
}
Example #2
Source File: LiveProvider.js    From cardano-documentation with MIT License 6 votes vote down vote up
ReactLiveProvider = ({ code }) => {
  return (
    <LiveProvider code={code}>
      <LiveEditor />
      <LiveError />
      <LivePreview />
    </LiveProvider>
  )
}
Example #3
Source File: LiveProvider.js    From learningHub with MIT License 6 votes vote down vote up
ReactLiveProvider = ({ code }) => {
  return (
    <LiveProvider code={code}>
      <LiveEditor />
      <LiveError />
      <LivePreview />
    </LiveProvider>
  );
}
Example #4
Source File: ExampleItem.js    From Lambda with MIT License 5 votes vote down vote up
render() {
    const { editorOpen } = this.state;
    const editorClassNames = classNames('live-editor', {
      'live-editor--visible': editorOpen,
    });
    const formId = `editorOpen${this.props.label.replace(' ', '_')}`;

    return (
      <div className="section">
        <h3 className="section__heading">
          {this.props.label}{' '}
          <label className="source-checkbox-label" htmlFor={formId}>
            <input
              type="checkbox"
              id={formId}
              name={formId}
              checked={editorOpen}
              onChange={this.handleEditSourceChange}
            />
            View source
          </label>
        </h3>
        {this.renderHint()}
        <LiveProvider
          scope={scope}
          code={this.props.code}
          theme={dracula}
          noInline
        >
          <LiveError />
          <div className="live-preview">
            <div className={editorClassNames}>
              <LiveEditor />
            </div>
            <LivePreview
              className="react-live-preview"
              style={{ dir: this.props.direction === 'rtl' ? 'rtl' : 'ltr' }}
            />
          </div>
        </LiveProvider>
      </div>
    );
  }
Example #5
Source File: index.js    From r3f-website with MIT License 5 votes vote down vote up
export default function CodeHighlight({
  children,
  className,
  live,
  title,
  lineNumbers,
}) {
  const [copied, setCopied] = useState(false);
  const codeString = children.trim();
  const language = className.replace(/language-/, "");

  if (live) {
    return (
      <LiveProvider
        code={codeString}
        noInline
        theme={theme}
        transformCode={(code) => `/** @jsx mdx */${code}`}
        scope={{ mdx, Canvas }}
      >
        <LiveWrapper>
          <StyledEditor>
            <LiveEditor />
          </StyledEditor>
          <LivePreview />
        </LiveWrapper>

        <LiveError />
      </LiveProvider>
    );
  }

  const handleClick = () => {
    setCopied(true);
    copyToClipboard(codeString);
  };

  return (
    <>
      {title && <PreHeader>{title}</PreHeader>}
      <div className="gatsby-highlight">
        <Highlight
          {...defaultProps}
          code={codeString}
          language={language}
          theme={theme}
        >
          {({
            className: blockClassName,
            style,
            tokens,
            getLineProps,
            getTokenProps,
          }) => (
            <Pre className={blockClassName} style={style} hasTitle={title}>
              <CopyCode onClick={handleClick}>
                {copied ? "Copied!" : "Copy"}
              </CopyCode>
              <code>
                {tokens.map((line, i) => (
                  <div {...getLineProps({ line, key: i })}>
                    {lineNumbers && <LineNo>{i + 1}</LineNo>}
                    {line.map((token, key) => (
                      <span {...getTokenProps({ token, key })} />
                    ))}
                  </div>
                ))}
              </code>
            </Pre>
          )}
        </Highlight>
      </div>
    </>
  );
}
Example #6
Source File: index.js    From gatsby-blog-mdx with MIT License 4 votes vote down vote up
Code = ({ codeString, language, metastring, ...props }) => {
  const [copyBtnText, setCopyBtnText] = useState("Copy")
  const [copyText, setCopyText] = useState("")
  const [loadingText, setLoadingText] = useState(false)

  // Set up texts to be copied on copy button
  useEffect(() => {
    let newStr = ""
    // Remove highlight comments
    let line = ""
    for (let i = 0; i < codeString.length; i++) {
      const c = codeString.charAt(i)
      if (c === "\n") {
        const result = removeHighlightComments(line)
        if (result) {
          newStr += result
          if (i !== codeString.length - 1) {
            newStr += "\n"
          }
        }
        line = ""
      } else {
        line += c
      }
    }
    // Last line
    const result = removeHighlightComments(line)
    if (result) newStr += result
    setCopyText(newStr)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // Set default language to text
  if (!language) language = "text"

  if (props["react-live"]) {
    return (
      <LiveProvider code={codeString} noInline={true} theme={undefined}>
        <LiveEditor className="live-highlight" style={undefined} />
        <LiveError className="live-error" />
        <LivePreview className="live-preview" />
      </LiveProvider>
    )
  }

  const handleCopy = () => {
    setCopyBtnText("Copied!")
    if (!loadingText) {
      setLoadingText(true)
      setTimeout(() => {
        setCopyBtnText("Copy")
        setLoadingText(false)
      }, 4000)
    }
  }

  const shouldHighlightLine = calculateLinesToHighlight(metastring)

  return (
    <Highlight
      {...defaultProps}
      code={codeString}
      language={language}
      theme={false}
    >
      {({ className, style, tokens, getLineProps, getTokenProps }) => {
        return (
          <div className="gatsby-highlight" data-language={language}>
            <div className="badge-btn-wrap">
              <div className={`language-badge language-badge-${language}`}>
                {language.toUpperCase()}
              </div>
              <CopyToClipboard text={copyText} onCopy={handleCopy}>
                <button className="btn-copy">{copyBtnText}</button>
              </CopyToClipboard>
            </div>
            <pre className={className} style={style}>
              {tokens.map((line, i) => {
                const lineProps = getLineProps({ line, key: i })
                const shouldExclude = highlightLine(line, lineProps, i)

                if (shouldHighlightLine(i)) {
                  addClassName(lineProps)
                }

                if (linesToHighlight.length > 0) {
                  if (linesToHighlight[0] === i) {
                    // Add class name & pop
                    addClassName(lineProps)
                    linesToHighlight.shift()
                  }
                }
                return !shouldExclude ? (
                  <div key={i} {...lineProps}>
                    {line.map((token, key) => (
                      <span {...getTokenProps({ token, key })} />
                    ))}
                  </div>
                ) : null
              })}
            </pre>
          </div>
        )
      }}
    </Highlight>
  )
}
Example #7
Source File: PlaygroundCodePanel.js    From basis with MIT License 4 votes vote down vote up
function PlaygroundCodePanel() {
  const theme = useTheme();
  const isCanary = useCanary();
  const [isInspectMode, setIsInspectMode] = useRecoilState(isInspectModeState);
  const [code, setCode] = useRecoilState(codeState);
  const [screens, setScreens] = useRecoilState(screensState);
  const [isSaved, setIsSaved] = useState(false);
  const [areSettingsOpen, setAreSettingsOpen] = useState(false);
  const settingsRef = useRef();
  const updateComponentsLocation = useCallback(() => {
    setScreens((screens) =>
      screens.map((screen) => ({
        ...screen,
        componentsLocation: getComponentsLocation(screen.document),
      }))
    );
  }, [setScreens]);

  useEffect(() => {
    if (isInspectMode) {
      updateComponentsLocation();
    }
  }, [isInspectMode, updateComponentsLocation]);

  return (
    <div
      css={{
        display: "flex",
        flexDirection: "column",
        height: "100%",
        boxSizing: "border-box",
        position: "relative",
      }}
    >
      <div
        css={{
          display: "flex",
          flexShrink: 0,
          padding: `${theme.space[2]} ${theme.space[8]}`,
          backgroundColor: theme.colors.grey.t05,
          borderTop: `${theme.borderWidths[0]} solid ${theme.colors.grey.t16}`,
          borderBottom: `${theme.borderWidths[0]} solid ${theme.colors.grey.t16}`,
        }}
      >
        <Stack direction="horizontal" gap="4">
          {isCanary && (
            <Button
              variant="icon"
              onClick={() => {
                setIsInspectMode((isInspectMode) => !isInspectMode);
              }}
            >
              <Icon
                name="select-object"
                size="24px"
                color={isInspectMode ? "highlight.blue.t100" : "grey.t75"}
                hoverColor={isInspectMode ? "highlight.blue.t100" : "black"}
              />
            </Button>
          )}
          <Button
            variant="secondary"
            width="88"
            onClick={() => {
              setCode(prettify(code));
            }}
          >
            Prettify
          </Button>
          <Button
            variant="secondary"
            width="88"
            disabled={isSaved}
            onClick={() => {
              navigate(
                getPlaygroundUrl({
                  code,
                  settings: {
                    screens: screens.map(({ name, width }) => [name, width]),
                  },
                })
              );

              setIsSaved(true);

              setTimeout(() => {
                setIsSaved(false);
              }, 1000);
            }}
          >
            {isSaved ? "Saved!" : "Save"}
          </Button>
          <Button
            variant="secondary"
            width="88"
            onClick={() => {
              const previewUrl = getPreviewUrl(code);

              window.open(previewUrl, "_blank");
            }}
          >
            Preview
          </Button>
        </Stack>
        <div css={{ flexShrink: 0, marginLeft: "auto" }}>
          <Button
            variant="secondary"
            width="88"
            onClick={() => {
              setAreSettingsOpen((areSettingsOpen) => !areSettingsOpen);
            }}
          >
            Settings
          </Button>
        </div>
      </div>
      <div
        css={{
          display: "flex",
          position: "relative",
          flexGrow: 1,
          minHeight: 0, // This ensures that, when there is a lot of code, this div isn't growing beyond what we want.
        }}
      >
        <div
          css={{
            padding: `${theme.space[4]} ${theme.space[8]}`,
            width: "100%",
            overflow: "auto",
            "textarea:focus": {
              outline: "none",
            },
          }}
        >
          <VisuallyHidden>
            <label htmlFor="code-editor">Code Editor</label>
          </VisuallyHidden>
          <LiveEditor
            textareaId="code-editor"
            padding={0}
            style={{ minHeight: "100%" }}
            onChange={setCode}
          />
        </div>
        {areSettingsOpen && (
          <div
            css={{
              position: "absolute",
              left: 0,
              top: 0,
              right: 0,
              bottom: 0,
              backgroundColor: "rgba(255, 255, 255, 0.7)",
            }}
            role="button"
            tabIndex="0"
            onKeyDown={(e) => {
              if (
                e.target === e.currentTarget &&
                (e.key === " " || e.key === "Enter")
              ) {
                setAreSettingsOpen(false);
              }
            }}
            onClick={(e) => {
              if (!settingsRef.current.contains(e.target)) {
                setAreSettingsOpen(false);
              }
            }}
          >
            <div
              css={{
                position: "absolute",
                top: 0,
                bottom: 0,
                right: 0,
                width: "320px",
                maxWidth: "100vw",
                boxSizing: "border-box",
                borderLeft: `${theme.borderWidths[0]} solid ${theme.colors.grey.t16}`,
              }}
              ref={settingsRef}
            >
              <PlaygroundSettings />
            </div>
          </div>
        )}
      </div>
      <PlaygroundCodeError />
    </div>
  );
}
Example #8
Source File: CodeEditor.js    From Lambda with MIT License 4 votes vote down vote up
render() {
    const {containerNodeID} = this.props;
    const {compiledES6, code, error, showBabelErrorMessage, showJSX} =
      this.state;

    let errorMessage;
    if (showBabelErrorMessage) {
      errorMessage = (
        <span>
          Babel could not be loaded.
          <br />
          <br />
          This can be caused by an ad blocker. If you're using one, consider
          adding reactjs.org to the whitelist so the live code examples will
          work.
        </span>
      );
    } else if (error != null) {
      errorMessage = error.message;
    }

    return (
      <LiveProvider code={showJSX ? code : compiledES6} mountStylesheet={false}>
        <div
          css={{
            [media.greaterThan('medium')]: {
              display: 'flex',
              alignItems: 'stretch',
              flexDirection: 'row',
            },

            [media.lessThan('small')]: {
              display: 'block',
            },
          }}
        >
          <div
            css={{
              flex: '0 0 70%',
              overflow: 'hidden',
              borderRadius: '10px 0 0 10px',

              [media.lessThan('medium')]: {
                borderRadius: '10px 10px 0 0',
              },
            }}
          >
            <div
              css={{
                padding: '0px 10px',
                background: colors.darker,
                color: colors.white,
              }}
            >
              <MetaTitle onDark={true}>
                Live JSX Editor
                <label
                  css={{
                    fontSize: 14,
                    float: 'right',
                    cursor: 'pointer',
                  }}
                >
                  <input
                    checked={this.state.showJSX}
                    onChange={(event) =>
                      this.setState({showJSX: event.target.checked})
                    }
                    type="checkbox"
                  />{' '}
                  JSX?
                </label>
              </MetaTitle>
            </div>
            <div
              css={{
                height: '100%',
                width: '100%',
                borderRadius: '0',
                maxHeight: '340px !important',
                marginTop: '0 !important',
                marginLeft: '0 !important',
                paddingLeft: '0 !important',
                marginRight: '0 !important',
                paddingRight: '0 !important',
                marginBottom: '0 !important',
                paddingBottom: '20px !important',
                [media.lessThan('medium')]: {
                  marginBottom: '0 !important',
                },

                '& pre.prism-code[contenteditable]': {
                  outline: 0,
                  overflow: 'auto',
                  marginRight: '0 !important',
                  marginBottom: '0 !important',
                },
              }}
              className="gatsby-highlight"
            >
              <LiveEditor ignoreTabKey={true} onChange={this._onChange} />
            </div>
          </div>
          {error && (
            <div
              css={{
                flex: '0 0 30%',
                overflow: 'hidden',
                border: `1px solid ${colors.error}`,
                borderRadius: '0 10px 10px 0',
                fontSize: 12,
                lineHeight: 1.5,

                [media.lessThan('medium')]: {
                  borderRadius: '0 0 10px 10px',
                },
              }}
            >
              <div
                css={{
                  padding: '0px 10px',
                  background: colors.error,
                  color: colors.white,
                }}
              >
                <MetaTitle
                  cssProps={{
                    color: colors.white,
                  }}
                >
                  Error
                </MetaTitle>
              </div>
              <pre
                css={{
                  whiteSpace: 'pre-wrap',
                  wordBreak: 'break-word',
                  color: colors.error,
                  padding: 10,
                }}
              >
                {errorMessage}
              </pre>
            </div>
          )}
          {!error && (
            <div
              css={{
                flex: '0 0 30%',
                overflow: 'hidden',
                border: `1px solid ${colors.divider}`,
                borderRadius: '0 10px 10px 0',

                [media.lessThan('medium')]: {
                  borderRadius: '0 0 10px 10px',
                },
              }}
            >
              <div
                css={{
                  padding: '0 10px',
                  backgroundColor: colors.divider,
                }}
              >
                <MetaTitle>Result</MetaTitle>
              </div>
              <div
                id={containerNodeID}
                css={{
                  padding: 10,
                  maxHeight: '340px !important',
                  overflow: 'auto',

                  '& input': {
                    width: '100%',
                    display: 'block',
                    border: '1px solid #ccc', // TODO
                    padding: 5,
                  },

                  '& button': {
                    marginTop: 10,
                    padding: '5px 10px',
                  },

                  '& label': {
                    display: 'block',
                    marginTop: 10,
                  },

                  '& textarea': {
                    width: '100%',
                    height: 60,
                    padding: 5,
                  },
                }}
              />
            </div>
          )}
        </div>
      </LiveProvider>
    );
  }
Example #9
Source File: index.js    From mds-docs with MIT License 4 votes vote down vote up
StoryComp = ({
  componentData,
  showArgsTable = true,
  htmlData,
  propData = {},
}) => {
  const testRef = useRef(null);
  const [zoom, setZoom] = useState(1);
  const [activeTab, setActiveTab] = React.useState(0);

  const [jsxCode, setJsxCode] = React.useState(
    getRawPreviewCode(componentData)
  );

  const html = beautifyHTML(htmlData,
    beautifyHTMLOptions
  );
  const [htmlCode, setHtmlCode] = useState(html);
  const [isExpanded, setIsExpanded] = useState(false);
  const [activeButton, setActiveButton] = useState('React');

  const renderHTMLTab = () => {
    return (
      <Tab label={<Button>HTML</Button>}>
        {renderCodeBlock(htmlCode)}
      </Tab>
    );
  };

  const renderCodeBlock = (val) => (
    <div>
      <style>
        {`pre {
        margin: 0;
        text-align: left;

      }`}
      </style>
      <SyntaxHighlighter
        language='javascript'
        style={vs2015}
        showLineNumbers={true}
      >
        {val}
      </SyntaxHighlighter>
    </div>
  );

  const copyCode = (val) =>
    navigator.clipboard.writeText(val);

  const CopyCode = (props) => {
    const { onClick } = props;
    return (
      <div className='ml-auto d-flex'>
        <img
          src={logo}
          className='codesandBox-icon mr-6 align-self-center'
          onClick={(e) => {
            e.preventDefault();
            openSandbox(jsxCode);
          }}
        />
        <Icon
          name='content_copy'
          size={20}
          appearance='white'
          onClick={onClick}
          className='align-self-center cursor-pointer'
        />
      </div>
    );
  };

  const handleZoomIn = () => {
    setZoom(zoom + 0.5);
  };

  const handleZoomOut = () => {
    setZoom(zoom - 0.5);
  };

  const showLiveEditorContent = () => {
    if (activeButton === 'React') {
      return (
        <div>
          <LiveEditor theme={vsDark} />
        </div>
      );
    } else {
      return renderCodeBlock(htmlCode);
    }
  };

  const imports = React.useMemo(() => ({ ...DS }), []);

  return (
    <>
      <div className='pt-8 pb-8 d-flex w-100 m-auto flex-column align-items-center'>
        <LiveProvider code={jsxCode} scope={imports}>
          <Card
            shadow='light'
            className='w-100 overflow-hidden'
          >
            <CardHeader>
              <div className='d-flex justify-content-end'>
                <Button
                  onClick={() => handleZoomIn()}
                  icon='zoom_in'
                  appearance='transparent'
                  largeIcon
                  className='transformation-button'
                ></Button>
                <Button
                  onClick={() => handleZoomOut()}
                  icon='zoom_out'
                  appearance='transparent'
                  largeIcon
                  className='transformation-button'
                ></Button>
              </div>
            </CardHeader>
            <CardBody className='d-flex flex-column align-items-center'>
              <div ref={testRef}>
                <LivePreview
                  className='p-8 live-preview'
                  style={{ zoom: zoom }}
                />
                <LiveError />
              </div>
              <div className='d-flex flex-row-reverse w-100 mb-6'>
                <Button
                  appearance='basic'
                  className='action-button'
                  onClick={() => setIsExpanded(!isExpanded)}
                >
                  {isExpanded ? 'Hide code' : 'Show code'}
                </Button>
              </div>
            </CardBody>
          </Card>

          {isExpanded && (
            <Card
              shadow='light'
              className='w-100 overflow-hidden mt-6 live-editor-card'
            >
              <div>
                <div className='d-flex px-4 pt-6'>
                  <Button
                    appearance='basic'
                    onClick={() => setActiveButton('React')}
                    selected={
                      activeButton === 'React'
                        ? true
                        : false
                    }
                    className='mr-3'
                  >
                    React
                  </Button>
                  <Button
                    appearance='basic'
                    onClick={() => setActiveButton('HTML')}
                    selected={
                      activeButton === 'HTML' ? true : false
                    }
                  >
                    HTML
                  </Button>
                  {activeButton === 'React' && (
                    <CopyCode
                      onClick={() => {
                        const editor =
                          document.querySelector(
                            '.npm__react-simple-code-editor__textarea'
                          );
                        if (editor) copyCode(editor.value);
                      }}
                    />
                  )}
                </div>
              </div>

              {showLiveEditorContent()}
            </Card>
          )}
        </LiveProvider>
        {showArgsTable && (
          <>
            <Heading className='mt-10 align-self-start'>
              Props
            </Heading>
            <ArgsTable rows={propData} />
          </>
        )}
      </div>
    </>
  );
}
Example #10
Source File: index.js    From usepandas with MIT License 4 votes vote down vote up
export default function CodeHighlight({
  codeString,
  className,
  live,
  highlight,
  title,
  lineNumbers,
}) {
  const [copied, setCopied] = useState(false);
  const language = className && className.replace(/language-/, "");

  const shouldHighlightLine = calculateLinesToHighlight(highlight);

  const handleClick = () => {
    setCopied(true);
    copyToClipboard(codeString);

    setTimeout(() => {
      setCopied(false);
    }, 4000);
  };

  if (live) {
    return (
      <LiveProvider
        code={codeString}
        noInline
        theme={theme}
        transformCode={(code) => `/** @jsx mdx */${code}`}
        scope={scope}
      >
        <LiveWrapper>
          <LivePreview />

          <StyledEditor>
            <CopyCode onClick={handleClick} disabled={copied} hasTitle>
              {copied ? "Copied!" : "Copy"}
            </CopyCode>

            <LiveEditor />
          </StyledEditor>

          <LiveError />
        </LiveWrapper>
      </LiveProvider>
    );
  }

  return (
    <>
      {title && <PreHeader>{title}</PreHeader>}
      <div className="gatsby-highlight">
        <Highlight
          {...defaultProps}
          code={codeString}
          language={language}
          theme={theme}
        >
          {({
            className: blockClassName,
            style,
            tokens,
            getLineProps,
            getTokenProps,
          }) => (
            <Pre
              className={blockClassName}
              style={style}
              hasTitle={title}
              hasLanguage={!!language}
            >
              <CopyCode
                onClick={handleClick}
                disabled={copied}
                hasTitle={title}
              >
                {copied ? "Copied!" : "Copy"}
              </CopyCode>
              <code>
                {tokens.map((line, index) => {
                  const lineProps = getLineProps({ line, key: index });

                  if (shouldHighlightLine(index)) {
                    lineProps.className = `${lineProps.className} highlight-line`;
                  }

                  return (
                    <div {...lineProps}>
                      {lineNumbers && <LineNo>{index + 1}</LineNo>}
                      {line.map((token, key) => (
                        <span {...getTokenProps({ token, key })} />
                      ))}
                    </div>
                  );
                })}
              </code>
            </Pre>
          )}
        </Highlight>
      </div>
    </>
  );
}
Example #11
Source File: playground.js    From r3f-website with MIT License 4 votes vote down vote up
Playground = () => {
  const [activeGeometry, setActiveGeometry] = useState(box);
  const [color, setColor] = useState("#ccc");
  const [numberOfGeometry, setNumberOfGeometry] = useState(1);
  const [picker, showPicker] = useState(false);
  const pickerButton = useRef();
  useClickOutside(pickerButton, () => showPicker(false));
  return (
    <section
      css={`
        padding: 60px 0;
      `}
    >
      <h2>Try it yourself</h2>
      <p
        css={`
          position: relative;
          display: flex;
          align-items: center;
        `}
      >
        I want to render a{" "}
        <select
          css={`
            margin: 0 5px;
          `}
          onChange={(e) => setActiveGeometry(e.target.value)}
          onBlur={(e) => setActiveGeometry(e.target.value)}
        >
          <option value={box}>Box</option>
          <option value={sphere}>Sphere</option>
          <option value={cone}>Cone</option>
          <option value={dodecahedron}>Dodecahedron</option>
        </select>{" "}
        in a{" "}
        <span
          ref={pickerButton}
          css={`
            display: inherit;
          `}
        >
          <button
            aria-label="Show color picker"
            onClick={() => showPicker((s) => !s)}
            css={`
              width: 23px;
              height: 23px;
              margin: 0 5px;
              background: ${color};
              border: 1px solid #ffffff;
            `}
          />
          {picker && (
            <ChromePicker
              css={`
                position: absolute;
                top: 40px;
                z-index: 99;
                left: 180px;
              `}
              color={color}
              onChange={(color) => setColor(color.hex)}
            />
          )}{" "}
        </span>
        color
      </p>
      I want to show{" "}
      <input
        aria-label="How many geometry to show"
        type="number"
        max="6"
        min="1"
        value={numberOfGeometry}
        onChange={(e) => setNumberOfGeometry(e.target.value)}
      ></input>{" "}
      geometry
      <LiveProvider
        theme={nightOwl}
        scope={scope}
        noInline
        code={code(activeGeometry, color, numberOfGeometry)}
      >
        <div
          css={`
            display: grid;
            grid-template-columns: 1fr 1fr;
            grid-gap: 40px;

            @media screen and (max-width: 900px) {
              grid-template-columns: 1fr;
            }
          `}
        >
          <LiveEditor
            css={`
              margin-top: 40px;
            `}
          />
          <div
            css={`
              height: 100%;
              > div {
                height: 100%;
                min-height: 400px;
              }
            `}
          >
            <LiveError />
            <LivePreview />
          </div>
        </div>
      </LiveProvider>
    </section>
  );
}
Example #12
Source File: CodeBlock.jsx    From tonic-ui with MIT License 4 votes vote down vote up
CodeBlock = ({
  /**
   * Do not evaluate and mount the inline code (Default: `false`).
   */
  noInline = false,

  /**
   * Disable editing on the `<LiveEditor />` (Default: `false`)
   */
  disabled = false,

  /**
   * Preview only (Default: `false`)
   */
  previewOnly = false,

  /**
   * Default is expand or collapse (Default: `false`)
   */
  expanded: defaultExpanded = false,

  className,
  children,
  ...props
}) => {
  const [, updateState] = useState();
  const forceUpdate = useCallback(() => updateState({}), []);
  const [colorMode] = useColorMode();
  const [editorCode, setEditorCode] = useState(children.trim());
  const {
    onCopy: copySource,
    hasCopied: hasCopiedSource,
  } = useClipboard(editorCode);
  const [isLiveEditorVisible, toggleLiveEditorVisibility] = reactHooks.useToggle(defaultExpanded);
  const resetDemo = () => {
    setEditorCode(children.trim());
    toggleLiveEditorVisibility(false);
    forceUpdate();
  };
  const handleLiveEditorChange = useCallback(newCode => {
    setEditorCode(newCode.trim());
  }, []);
  const language = className && className.replace(/language-/, '');

  noInline = boolean(noInline);

  if (disabled === undefined) {
    disabled = (language !== 'jsx');
  } else {
    disabled = (language !== 'jsx') || boolean(disabled);
  }

  const liveProviderProps = {
    theme: {
      dark: codeBlockDark,
      light: codeBlockLight,
    }[colorMode],
    language,
    noInline,
    disabled,
    code: editorCode,
    transformCode: code => code,
    scope: {
      ...reactComponents,
      ...reactLabComponents,
      ...reactHooks,
      ...thirdPartyComponents,
      Code,
      FontAwesomeIcon,
      InputTag,
      Lorem,
      SkeletonBody,
      SkeletonContent,
      Global, // from '@emotion/react'
      css, // from '@emotion/react'
      mdx, // from '@mdx-js/react'
      sx, // from '@tonic-ui/styled-system'
      tmicons, // from '@trendmicro/tmicon'
    },
    mountStylesheet: false,
    ...props,
  };

  if (previewOnly) {
    return (
      <LiveProvider {...liveProviderProps}>
        <LiveCodePreview style={liveCodePreviewStyle} />
      </LiveProvider>
    );
  }

  const isEditable = !disabled;

  if (!isEditable) {
    return (
      <LiveProvider {...liveProviderProps}>
        <LiveEditor
          style={liveEditorStyle}
          css={css`
            & > textarea { outline: 0; }
          `}
        />
      </LiveProvider>
    );
  }

  return (
    <LiveProvider {...liveProviderProps}>
      <LiveCodePreview style={liveCodePreviewStyle} />
      <Box display="flex" justifyContent="flex-end">
        <IconButton onClick={toggleLiveEditorVisibility}>
          <Tooltip label={isLiveEditorVisible ? 'Hide the source' : 'Show the source'}>
            <Icon icon="code" size={{ sm: '5x', md: '4x' }} />
          </Tooltip>
        </IconButton>
        <IconButton onClick={copySource}>
          <Tooltip label={hasCopiedSource ? 'Copied' : 'Copy the source'}>
            <Icon icon="file-copy-o" size={{ sm: '5x', md: '4x' }} />
          </Tooltip>
        </IconButton>
        <IconButton onClick={resetDemo}>
          <Tooltip label="Reset the demo">
            <Icon icon="redo" size={{ sm: '5x', md: '4x' }} />
          </Tooltip>
        </IconButton>
      </Box>
      <Fade in={isLiveEditorVisible}>
        <Collapse in={isLiveEditorVisible} unmountOnExit={true}>
          <LiveEditor
            onChange={handleLiveEditorChange}
            style={liveEditorStyle}
            css={css`
              & > textarea { outline: 0; }
            `}
          />
        </Collapse>
      </Fade>
      <LiveError style={liveErrorStyle} />
    </LiveProvider>
  );
}