react-live#LiveProvider JavaScript Examples

The following examples show how to use react-live#LiveProvider. 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: index.js    From basis with MIT License 6 votes vote down vote up
function Preview() {
  const [code, setCode] = useState(null);
  const noInline = useMemo(() => getReactLiveNoInline(code), [code]);

  useEffect(() => {
    setCode(getPreviewCodeFromUrl());
  }, []);

  if (code === null) {
    return null;
  }

  return (
    <LiveProvider code={code} noInline={noInline} scope={scope}>
      <ComponentPreview
        iframeTitle="Preview"
        iframeStyle={{
          height: "100vh",
        }}
        hasBodyMargin={false}
      />
    </LiveProvider>
  );
}
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: ComponentContainer.js    From basis with MIT License 4 votes vote down vote up
function ComponentContainer(props) {
  const { code, noInline = false, scope, hasBodyMargin, bg } = props;
  const theme = useTheme();
  const spaceBetween = parseInt(theme.space[11], 10);
  const spaceAroundIframe = parseInt(theme.space[5], 10);
  const borderWidthPx = theme.borderWidths[0];
  const borderWidth = parseInt(borderWidthPx, 10);
  const minWidth = 50 + 2 * spaceAroundIframe + borderWidth;
  const initialWidth = useMemo(() => {
    if (!props.width || typeof props.width === "string") {
      const initialWidthPx =
        theme.breakpoints[props.width || "xs"] || props.width;

      return parseInt(initialWidthPx, 10) + 2 * spaceAroundIframe;
    }

    return props.width + 2 * spaceAroundIframe;
  }, [props.width, theme.breakpoints, spaceAroundIframe]);
  const [resizeWidth, setResizeWidth] = useState(
    initialWidth - 2 * spaceAroundIframe
  );
  const [width, setWidth] = useState(initialWidth + borderWidth);

  return (
    <div css={{ display: "flex", flexGrow: 1, overflowY: "auto" }}>
      <LiveProvider
        code={code}
        scope={scope}
        noInline={noInline}
        theme={reactLiveEditorTheme}
      >
        <div>
          <Resizable
            style={{
              flexShrink: 0,
              marginRight: spaceBetween,
              borderRight: `${borderWidthPx} solid ${theme.colors.grey.t10}`,
            }}
            enable={rightOnly}
            minWidth={minWidth}
            size={{
              width,
              height: "100%",
            }}
            onResizeStop={(_e, _direction, _ref, d) => {
              setWidth(width + d.width);
            }}
            onResize={(_e, _direction, _ref, d) => {
              setResizeWidth(
                width + d.width - 2 * spaceAroundIframe - borderWidth
              );
            }}
          >
            <div
              css={{
                position: "absolute",
                right: 0,
                top: 0,
                backgroundColor: theme.colors.grey.t10,
                fontSize: theme.fontSizes[0],
                padding: `0 ${theme.space[1]}`,
              }}
            >
              {resizeWidth}px
            </div>
            <div
              css={{
                height: "100%",
                boxSizing: "border-box",
                padding: spaceAroundIframe,
                backgroundColor: theme.getColor(bg),
                overflowY: "auto",
              }}
            >
              <ComponentPreview hasBodyMargin={hasBodyMargin} bg={bg} />
            </div>
          </Resizable>
        </div>
        <div css={{ flexGrow: 1, overflowY: "auto" }}>
          <ComponentCode code={code} />
          <LiveError />
        </div>
      </LiveProvider>
    </div>
  );
}
Example #8
Source File: message.js    From basis with MIT License 4 votes vote down vote up
function KitchenSinkMessage() {
  return (
    <KitchenSinkLayout name="Message">
      {BACKGROUNDS.map((bg) => (
        <Container
          padding="6"
          bg={bg === "white" ? "grey.t05" : "white"}
          key={bg}
        >
          <Grid rowsGap="4">
            <Message
              severity="info-or-minor"
              bg={bg}
              callToAction={
                <Link appearance="secondary-button" href="#" newTab>
                  Link
                </Link>
              }
            >
              We can help you ease the financial stress of COVID-19.{" "}
              <Link href="https://www.latitudefinancial.com.au/covid-19" newTab>
                Find out how.
              </Link>
            </Message>
            <Message
              severity="info-or-minor"
              bg={bg}
              callToAction={<Button variant="secondary">Button</Button>}
            >
              We can help you ease the financial stress of COVID-19.{" "}
              <Link href="https://www.latitudefinancial.com.au/covid-19" newTab>
                Find out how.
              </Link>
            </Message>
          </Grid>
        </Container>
      ))}
      <Container padding="6">
        <Message
          severity="info-or-minor"
          bg="highlight.pink.t100"
          callToAction={<Button variant="secondary">Dismiss</Button>}
          hasBreakpointWidth-sm
        >
          We can help you ease the financial stress of COVID-19.{" "}
          <Link href="https://www.latitudefinancial.com.au/covid-19" newTab>
            Find out how.
          </Link>
        </Message>
      </Container>
      <Container margin="6" width="240" bg="grey.t05">
        <Message severity="info-or-minor" padding="0">
          We can help you ease the financial stress of COVID-19.{" "}
          <Link href="https://www.latitudefinancial.com.au/covid-19" newTab>
            Find out how.
          </Link>
        </Message>
      </Container>
      <Container width="600" height="2272">
        <LiveProvider
          code={`
            Message.BACKGROUNDS.map((bg) => (
              <Container
                padding="6"
                bg={bg === "white" ? "grey.t05" : "white"}
                key={bg}
              >
                <Message
                  severity="info-or-minor"
                  bg={bg}
                  callToAction={
                    <Link appearance="secondary-button" href="#" newTab>
                      Link
                    </Link>
                  }
                >
                  Your minimum monthly payment (including any overdue and overlimit amount) 
                  will be debited if it is greater than your fixed amount.<br /><br />
                  Your statement closing balance will be debited if it is lower than your fixed amount.
                </Message>
              </Container>
            ))
          `}
          scope={scope}
        >
          <ComponentPreview hasBodyMargin={false} />
        </LiveProvider>
      </Container>
      <Container width="400">
        {SEVERITIES.map((severity) => (
          <Container padding="6" key={severity}>
            <Message
              severity={severity}
              bg="secondary.pink.t30"
              title="Something went wrong"
            >
              We are sorry, we cannot fulfill your request. Please contact
              Latitude for more information.
            </Message>
          </Container>
        ))}
      </Container>
    </KitchenSinkLayout>
  );
}
Example #9
Source File: sticky.js    From basis with MIT License 4 votes vote down vote up
function KitchenSinkSticky() {
  const code = `
    function FirstSticky() {
      return (
        <Placeholder
          label="First Sticky"
          height="24"
          height-xs="80"
          height-md="120"
          height-xl="40"
        />
      );
    }
    
    FirstSticky.ID = "FirstSticky";
    FirstSticky.HEIGHT_MAP = {
      default: 24,
      xs: 80,
      md: 120,
      xl: 40
    };
    
    function SecondSticky() {
      return (
        <Placeholder
          label="Second Sticky"
          height="80"
          height-sm="32"
          height-md="56"
        />
      );
    }
    
    SecondSticky.ID = "SecondSticky";
    SecondSticky.HEIGHT_MAP = {
      default: 80,
      sm: 32,
      md: 56
    };
    
    function ThirdSticky() {
      return <Placeholder label="Third Sticky" height="60" height-lg="80" />;
    }
    
    ThirdSticky.ID = "ThirdSticky";
    ThirdSticky.HEIGHT_MAP = {
      default: 60,
      lg: 80
    };

    function App() {
      return (
        <Sticky>
          <Sticky.Item>
            <FirstSticky />
          </Sticky.Item>
          <Sticky.Item>
            <SecondSticky />
          </Sticky.Item>
          <Container margin="6">
            <Text>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
              eiusmod tempor incididunt ut labore et dolore magna aliqua. Id
              interdum velit laoreet id donec ultrices tincidunt. Feugiat sed
              lectus vestibulum mattis ullamcorper velit. Nullam ac tortor vitae
              purus faucibus ornare suspendisse sed. Auctor eu augue ut lectus
              arcu bibendum at varius vel.
            </Text>
          </Container>
          <Sticky.Item>
            <ThirdSticky />
          </Sticky.Item>
          <Container margin="6">
            <Text>
              Enim blandit volutpat maecenas volutpat. Vitae semper quis lectus
              nulla at. Tempor orci dapibus ultrices in iaculis nunc sed augue
              lacus. Ullamcorper a lacus vestibulum sed arcu non odio. Facilisis
              leo vel fringilla est ullamcorper eget nulla facilisi. Habitasse
              platea dictumst quisque sagittis purus sit amet. Leo integer
              malesuada nunc vel risus commodo viverra maecenas accumsan. Commodo
              quis imperdiet massa tincidunt nunc pulvinar sapien. Consectetur
              purus ut faucibus pulvinar elementum. Sed arcu non odio euismod
              lacinia. Faucibus interdum posuere lorem ipsum dolor sit amet. Eget
              felis eget nunc lobortis. Urna nunc id cursus metus aliquam eleifend
              mi in. Quisque egestas diam in arcu cursus. Nulla facilisi nullam
              vehicula ipsum a arcu cursus vitae. Non nisi est sit amet. Ornare
              arcu odio ut sem nulla pharetra diam sit amet. Molestie ac feugiat
              sed lectus vestibulum mattis ullamcorper velit.
            </Text>
          </Container>
          <Container margin="6">
            <Text>
              Diam vulputate ut pharetra sit amet aliquam. Nisi scelerisque eu
              ultrices vitae auctor eu augue ut lectus. Auctor urna nunc id cursus
              metus aliquam eleifend. Elementum sagittis vitae et leo. Ac turpis
              egestas integer eget aliquet. Sollicitudin nibh sit amet commodo
              nulla facilisi nullam. Magna sit amet purus gravida quis. Est ante
              in nibh mauris cursus mattis. Ac odio tempor orci dapibus ultrices
              in iaculis nunc. Aenean vel elit scelerisque mauris.
            </Text>
          </Container>
          <Container margin="6">
            <Text>
              Sem et tortor consequat id porta nibh. Mus mauris vitae ultricies
              leo integer. Pellentesque adipiscing commodo elit at imperdiet dui
              accumsan sit amet. Commodo viverra maecenas accumsan lacus vel
              facilisis volutpat est velit. Lorem donec massa sapien faucibus.
              Enim nec dui nunc mattis enim ut tellus. Blandit cursus risus at
              ultrices mi. Quis enim lobortis scelerisque fermentum dui faucibus.
              Eget sit amet tellus cras adipiscing enim eu turpis egestas. Pretium
              lectus quam id leo in vitae turpis massa.
            </Text>
          </Container>
          <Container margin="6">
            <Text>
              Habitant morbi tristique senectus et netus et malesuada fames ac.
              Quisque id diam vel quam elementum pulvinar etiam non. Lorem ipsum
              dolor sit amet consectetur adipiscing. Cum sociis natoque penatibus
              et magnis dis. Nisi quis eleifend quam adipiscing. Faucibus a
              pellentesque sit amet porttitor eget dolor morbi. At quis risus sed
              vulputate odio. Ante metus dictum at tempor commodo ullamcorper a.
              In eu mi bibendum neque egestas congue quisque. Mauris in aliquam
              sem fringilla. Dui faucibus in ornare quam viverra orci. Netus et
              malesuada fames ac turpis egestas. Diam sollicitudin tempor id eu
              nisl nunc.
            </Text>
          </Container>
        </Sticky>
      );
    }

    render(<App />);
  `;
  return (
    <KitchenSinkLayout name="Sticky">
      <Container bg="grey.t05" padding="6 0">
        <Container width="320" height="600" margin="0 auto" bg="white">
          <LiveProvider code={code} scope={scope} noInline>
            <ComponentPreview hasBodyMargin={false} />
          </LiveProvider>
        </Container>
      </Container>

      <Container bg="grey.t05" padding="6 0">
        <Container width="376" height="600" margin="0 auto" bg="white">
          <LiveProvider code={code} scope={scope} noInline>
            <ComponentPreview hasBodyMargin={false} />
          </LiveProvider>
        </Container>
      </Container>

      <Container bg="grey.t05" padding="6 0">
        <Container width="576" height="600" margin="0 auto" bg="white">
          <LiveProvider code={code} scope={scope} noInline>
            <ComponentPreview hasBodyMargin={false} />
          </LiveProvider>
        </Container>
      </Container>

      <Container bg="grey.t05" padding="6 0">
        <Container width="768" height="600" margin="0 auto" bg="white">
          <LiveProvider code={code} scope={scope} noInline>
            <ComponentPreview hasBodyMargin={false} />
          </LiveProvider>
        </Container>
      </Container>

      <Container bg="grey.t05" padding="6 0">
        <Container width="992" height="600" margin="0 auto" bg="white">
          <LiveProvider code={code} scope={scope} noInline>
            <ComponentPreview hasBodyMargin={false} />
          </LiveProvider>
        </Container>
      </Container>

      <Container bg="grey.t05" padding="6 0">
        <Container width="1200" height="600" margin="0 auto" bg="white">
          <LiveProvider code={code} scope={scope} noInline>
            <ComponentPreview hasBodyMargin={false} />
          </LiveProvider>
        </Container>
      </Container>
    </KitchenSinkLayout>
  );
}
Example #10
Source File: index.js    From basis with MIT License 4 votes vote down vote up
function Playground() {
  const theme = useTheme();
  const [code, setCode] = useRecoilState(codeState);
  const debouncedCode = useDebounce(code, 500);
  const liveProviderProps = useMemo(
    () => ({
      code: debouncedCode,
      noInline: getReactLiveNoInline(debouncedCode),
    }),
    [debouncedCode]
  );
  const [screens, setScreens] = useRecoilState(screensState);
  const initialCodePanelHeight = useLocalStorageValue(
    LOCAL_STORAGE_CODE_PANEL_HEIGHT_KEY,
    "40vh"
  );
  const [codePanelHeight, setCodePanelHeight] = useState(null);
  const codePanelHeightOnResizeStart = useRef();
  const onCodePanelResizeStop = () => {
    try {
      localStorage &&
        localStorage.setItem(
          LOCAL_STORAGE_CODE_PANEL_HEIGHT_KEY,
          JSON.stringify(codePanelHeight)
        );
    } catch (error) {
      console.error(`Saving in localStorage failed: ${error.message}`);
    }
  };

  useEffect(() => {
    if (initialCodePanelHeight !== null) {
      setCodePanelHeight(initialCodePanelHeight);
    }
  }, [initialCodePanelHeight]);

  useEffect(() => {
    const dataFromUrl = getPlaygroundDataFromUrl();
    const initialCode = dataFromUrl.code ?? defaultCode;
    const initialScreens =
      dataFromUrl.settings?.screens ?? Object.entries(theme.breakpoints);

    setCode(initialCode);
    setScreens(
      initialScreens.map(([bp, width]) => ({
        id: bp,
        name: bp,
        width: parseInt(width, 10),
      }))
    );
  }, [theme, setCode, setScreens]);

  if (codePanelHeight === null) {
    return null;
  }

  return (
    <LiveProvider
      {...liveProviderProps}
      transformCode={annotateCodeForPlayground}
      scope={allDesignSystem}
      theme={reactLiveEditorTheme}
    >
      <Grid height="100vh" rows={`1fr ${codePanelHeight}`}>
        <Grid.Item>
          <Container height="100%" bg="grey.t03" overflow="auto">
            <div
              css={{
                display: "flex",
                boxSizing: "border-box",
                padding: theme.space[8],
                width: "min-content", // Without it, right padding is not visible. See also: https://stackoverflow.com/q/10054870/247243
                height: "100%",
              }}
            >
              {screens.map(
                ({ id, name, width, document, componentsLocation }, index) => (
                  <div
                    css={{
                      display: "flex",
                      marginLeft: index === 0 ? null : theme.space[8],
                    }}
                    key={id}
                  >
                    <PlaygroundScreen
                      id={id}
                      name={name}
                      width={width}
                      document={document}
                      componentsLocation={componentsLocation}
                    />
                  </div>
                )
              )}
            </div>
          </Container>
        </Grid.Item>
        {codePanelHeight !== null && (
          <Grid.Item>
            <Resizable
              size={{ height: codePanelHeight }}
              onResizeStart={() => {
                codePanelHeightOnResizeStart.current = codePanelHeight;
              }}
              onResize={(e, direction, ref, d) => {
                setCodePanelHeight(
                  heightToVh(
                    vhToHeight(codePanelHeightOnResizeStart.current) + d.height
                  )
                );
              }}
              onResizeStop={onCodePanelResizeStop}
              minHeight="10vh"
              maxHeight="90vh"
              enable={{
                top: true,
                right: false,
                bottom: false,
                left: false,
                topRight: false,
                bottomRight: false,
                bottomLeft: false,
                topLeft: false,
              }}
            >
              <PlaygroundCodePanel />
            </Resizable>
          </Grid.Item>
        )}
      </Grid>
    </LiveProvider>
  );
}
Example #11
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 #12
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 #13
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 #14
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 #15
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>
  );
}