0.0.2 • Published 5 years ago

react-codepen-prefill-embed v0.0.2

Weekly downloads
33
License
MIT
Repository
-
Last release
5 years ago

React CodPen Prefill Embed

An unofficial, TypeScript-powered React wrapper around CodePen's very-official Prefill Embed API.

Is this for me?

From CodePen's docs:

Here's why Prefill Embeds are useful: say you have a blog or documentation site displaying important bits of code within <pre><code> tags. Perhaps you need to show a bit of HTML, CSS, or JavaScript.

...

CodePen Prefill Embeds are designed to render that code for you in a safe and isolated environment to help your users see, understand, and play with it more easily.

This wrapper might be a good fit for you if you're already using React to power something like a blog (maybe with Gatsby or Next.js) and don't wanna fuss about things like escaping markup.

Installation

From your favorite package registry

  • yarn add react-codepen-prefill-embed
  • npm install --save react-codepen-prefill-embed
import {
  PrefillEmbed,
  PrefillLang,
  useCodePenEmbed,
  stripIndent
} = from 'react-codepen-prefill-embed`;
// ...

From a CDN

<!--
  React and ReactDOMServer (yep, even in the browser)
  are required. You probably want regular ol' ReactDOM too.
-->
<script src="https://unpkg.com/react@16.8/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8/umd/react-dom-server.browser.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.8/umd/react-dom.browser.production.min.js"></script>

<!--
  If you're not using the `useCodePenEmbed` hook documented below
  you'll also need CodePen's API script
-->
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

<script src="https://unpkg.com/react-codepen-prefill-embed@latest/dist/umd/index.js"></script>
<script>
  const {
    PrefillEmbed,
    PrefillLang,
    useCodePenEmbed,
    stripIndent,
  } = ReactCodePenPrefillEmbed;
  // ...
</script>

Use on CodePen

Here's a template that has all the scripts loaded for you.

Usage example

const App = () => {
  useCodePenEmbed();
  return (
    <PrefillEmbed
      className="codepen"
      penTitle="My sweet demo"
      embedHeight="400"
      themeId="31205"
      editable
      description="Renders a barebones React component"
      tags={['react', 'react-docs-demo']}
      htmlClasses={['loading', 'no-js']}
      head={
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      }
      scripts={[
        'https://unpkg.com/react@16.8.6/umd/react.development.js',
        'https://unpkg.com/react-dom@16.8.6/umd/react-dom.development.js',
      ]}
      stylesheets={['https://unpkg.com/normalize.css@8.0.1/normalize.css']}
    >
      <PrefillLang lang="html">
        {stripIndent`
            <div id="root"></div>
        `}
      </PrefillLang>
      <PrefillLang lang="scss">
        {stripIndent`
            $bg: #eee;
            body {
              background: $bg; 
            }
        `}
      </PrefillLang>
      <PrefillLang lang="babel">
        {stripIndent`
          const App = () => <h1>Hello</h1>;
          ReactDOM.render(
            <App/>,
            document.getElementById('root')
          );
        `}
      </PrefillLang>
    </PrefillEmbed>
  );
};

Components

<PrefillEmbed>

The root of your embed. This is where you set Pen-specific settings like description or theme.

Props

Type annotations here if you prefer. Any props not listed will be passed to the wrapping <div> element. All <PrefillEmbed> props are optional.

Related to the Pen:
PropTypeDefaultDescription
penTitlestring--Title of your Pen
descriptionstring--Description of your Pen
tagsarray--Tags for your Pen. Max 5.
htmlClassesarray--Classes to add to the html element of your Pen
stylesheetsarray--Stylesheets to include as external resources
scriptsarray--Scripts to include as external resources
headnode--Content for the <head> of the document
prefillDataobject--Any additional keys/values you want passed to data-prefill
Related to the embed:
PropTypeDefaultDescription
embedHeightstring--Height of the generated iframe
themeIdstring--Theme id to use in the embed
editableboolfalseWhether or not the embed should be editable
defaultTabsarray'result'Default open tab(s)
classNamestring'codepen'Class for the wrapping <div>. If you change this, you'll be responsible for invoking the prefill API

<PrefillLang>

Used as children of <PrefillEmbed>— your HTML, CSS, and JS tabs.

Props

lang is the only prop, everything else is passed to the wrapping <pre> element.

PropTypeDefaultRequiredDescription
langstring--⚠️What kinda code is it? Support table below
Supported languages

HTML: html, slim, haml, markdown, pug

JS: js, babel, typescript, coffeescript, livescript

CSS: css, scss, sass, less, stylus

Hooks and Utilities

usePrefillEmbed

A hook to load CodePen's prefill API. This may be useful if you don't want to deal with adding a CDN-only script to your build process, but isn't recommended in the browser.

The script is loaded from https://static.codepen.io/assets/embed/ei.js and is async by default.

Options

OptionTypeDefaultDescription
asyncbooleantrueLoad the script with the async attribute
srcOverridestring--Override the source of the loaded script

stripIndent

Multi-line strings are easiest to work with in template literals. This can cause headaches when dealing with indented JSX code, however— consider this:

<App>
  <PrefillEmbed>
    <PrefillLang lang="html">
      {`
        <div>
          <span>Hello</span>
        </div>
      `}
    </PrefillLang>
  <PrefillEmbed>
</App>

Which will yield the following markup in your Pen:

        <div>
          <span>Hello</span>
        </div>

In order for whitespace to look normal you'd need to do something like this:

<App>
  <PrefillEmbed>
    <PrefillLang lang="html">
{`<div>
  <span>Hello</span>
</div>`}
    </PrefillLang>
  <PrefillEmbed>
</App>

And that's a bummer. Instead, you can use the provided template tag to strip leading indents and leading/trailing newlines.

Whitespace to strip is determined based on the first line of text after removing a leading newline. Tabs or spaces should both be fine so long as you're consistent.

<App>
  <PrefillEmbed>
    <PrefillLang lang="html">
      {stripIndent`
        <div>
          <span>Hello</span>
        </div>
      `}
    </PrefillLang>
  <PrefillEmbed>
</App>

...would become:

<div>
  <span>Hello</span>
</div>
0.0.2

5 years ago

0.0.1

5 years ago