npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

playground-typ

v1.2.3

Published

Interactive JavaScript sandbox

Downloads

3

Readme

Overview

This project provides a quick, visual way to experiment with JavaScript code. It's designed to be loaded as an iframe for easy inclusion in any webpage.

There are a variety of configuration options, including a React preset and a React Native preset.

I use this sandbox in my free educational guides:

Usage

The sandbox may be included on your site in one of two ways:

For legacy React Native-specific docs, see the v1 branch

As a React Component

If you're using React:

npm install --save javascript-playgrounds

# or

yarn add javascript-playgrounds

Then:

import Playground from 'javascript-playgrounds'

export default function App() {
  return <Playground style={{ width: 800, height: 500 }} />
}

This component is a wrapper around the iframe that handles encoding parameters for you. While it passes most props along to the iframe, it has a few extra props:

| Title | Description | Default | | --------------- | --------------------------------------------------------------------------------------------- | --------------------------------- | | style | The style of the div which wraps the iframe (the iframe has 100% width and height). | undefined | | className | The className of the div which wraps the iframe | undefined | | baseURL | Optionally, specify a custom url to load the player from. This url should not include a hash. | unpkg.com (see unpkg) |

As an iframe

If you're not using React, include the sandbox in an iframe.

<iframe
  width="880"
  height="425"
  frameborder="0"
  src="//unpkg.com/javascript-playgrounds@^1.0.0/public/index.html"
></iframe>

Configuration parameters should be passed as part of the hash string, after #data=. They should be JSON-encoded and then URI-encoded:

const parameters = { code: `console.log('Hello, world!')` }
const hashString = '#data=' + encodeURIComponent(JSON.stringify(parameters))

When used as an iframe, the easiest way to set the code parameter is to edit the code in the sandbox and copy and paste the url when you're done (the url updates automatically as you type).

For convenience, you may optionally pass the preset parameter in the url string directly, e.g. #preset=react&data=....

Parameters

The sandbox accepts the following props/parameters.

| Title | Description | Default | | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | | preset | This sets reasonable defaults for other parameters. Options are javascript, react, and react-native. Experimental options are html and python (make sure to lock down your javascript-playgrounds library version when using experimental presets). | 'javascript' | | title | An optional title for the editor pane. | '' | | code | The code to show/run in the player. | The sample app | | files | A map of { [filename]: code }. This will take precedence over code if given. | undefined | | entry | The filename of the file that runs first. This is only relevant when showing multiple files with the files parameter. Defaults to index.js, or index.tsx if TypeScript is enabled. | 'index.js' or 'index.tsx' | | initialTab | The filename of the tab to show by default. This is only relevant when showing multiple files with the files parameter. Defaults to the value of entry. | entry | | modules | An array of external modules to make available to the sandbox. Each object in the array should be an object containing a name and url. As a shorthand, pass a string name to load a module from unpkg (https://unpkg.com/${name}). More detail below. | [] | | css | An optional CSS string to apply within the workspace iframe. | '' | | styles | An map of inline style objects, applied to various elements to customize the style of the UI. Example: { header: { backgroundColor: 'red' } } | {} | | strings | A map of strings that appear in the UI. Example: { loading: 'Loading dependencies...' } | {} | | sharedEnvironment | This affects how the iframes share data with one another, mainly for the "playgrounds" feature. When true, iframes will pass JavaScript objects back and forth, while when false, they'll pass serialized JSON. | false | | detectDependencies | Should the player scan code files for imports and try to fetch them from unpkg? Only modules imported in the initial code are fetched (not those added while typing in the sandbox). | true | | fullscreen | Show a button to enable fullscreen editing (in most configurations of panes). Note that the iframe must have the allowfullscreen attribute for this to work. | false | | compiler | Settings for Babel | {} | | compiler.maxLoopIterations | Throw an error if a loop iterates more than a certain amount of times. Set to 0 to disable. | 1000 | | playground | Settings for playgrounds (inline widgets that display runtime values) | {} | | playground.enabled | Turn on playgrounds? | false | | playground.renderReactElements | Render React elements? If false, will print the React element object, e.g. { type, props, key }, rather than render it. | true | | playground.debounceDuration | How frequently widgets update. A little delay helps keep the UI feeling smoother. | 200 (milliseconds) | | typescript | TypeScript settings | {} | | typescript.enabled | Turn on TypeScript hover tooltip info? Defaults to false | false | | typescript.libs | An array of default libraries to include, e.g. 'dom' and 'es2015'. We don't include some newer/esoteric ones by default, to reduce download size. | See source code | | typescript.types | An array of additional type files to download. Each should be an object { name, url }. | [] | | workspaces | Add a tutorial-like sequence of sets of files, highlighting changes between each set. Each object in this array can contain: { title, description, workspace: { title, files, entry, initialTab } }. Properties in the workspace object will override those given as top level parameters. | [] | | panes | An array of UI panes to display. To display a pane without options, use a string. Otherwise, use an object with a type property. The available panes are: 'stack', 'editor', 'transpiler', 'player', 'workspaces', 'console'. Note that there must be a player pane for any code to run. For pane options, see below. | ['editor', 'player'] | | responsivePaneSets | An array of { maxWidth, panes } objects to show at different responsive breakpoints. The iframe will use the first set where the maxWidth is greater than the current window width. The top-level panes parameter has maxWidth: Infinity so that it's used by default if there's no matching set of panes. | [] | | targetOrigin | If passed, the sandbox will call parent.postMessage(JSON.stringify(data), targetOrigin) on code changes. | undefined |

Examples of loading modules:
  • To load a CommonJS require-style module, the name is the require(name) name, and the second is the source url. E.g. to load moment.js: set modules to the value [{ name: 'moment', url: 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js' }]
  • To load a component as a property on window, also pass a globalName, which will be the window property name (e.g. window.moment). E.g. to load moment.js this way: set modules to the value [{ name: 'moment', globalName: 'moment', url: 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js' }]

Pane options

All panes support the following options:

| Title | Description | Default | | ----------- | ------------------------------------------------------------------------------------------------------------------------- | ----------- | | style | The inline styles for this specific pane, merged with those passed in the top-level styles object if given. | undefined | | title | An optional title for this pane. If used on an 'editor' pane, this will override a top-level title, if one was given. | '' |

Each pane additionally supports pane-specific options. For more detail:

The player pane

Display the running app, optionally with the image of a phone around it.

| Title | Description | Default | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | platform | One of ios, android, or web. When web, no phone image is displayed. | 'ios' | | width | The width of the device. This has no effect if the platform is web. | 210px | | scale | Zoom the device screen. This has no effect if the platform is web. | 1 | | assetRoot | Specifies the root url for asset requires. E.g. to require http://localhost:8080/images/hello.png, you could set assetRoot to 'http://localhost:8080/' and write require('./images/hello.png') in your code. | '' | | css | An optional CSS string to apply within the player's iframe. | '' | | styleSheet | One of reset or none. When reset, the meyerweb CSS reset is applied to the player's iframe. | 'reset' | | statusBarHeight | Display a rectangle at the top of the phone screen, mimicking a status bar. | 0px | | statusBarColor | The color of the fake status bar. | 'black' | | prelude | JavaScript code that runs before the entry file. | '' | | modules | Pane-specific modules, in addition to those passed at the top level. | [] | | console | Display an embedded console in this pane. See the console options below. Additionally, the embedded version of the console has the following properties... | {} | | console.visible | Show the console? | false | | console.maximized | Show the console over the entire player? | false | | console.collapsible | Allow collapsing the console via a toggle button. | true |

The console pane

Show the output console.log, similar to the Chrome inspector. This can be a separate pane, or embedded in the player pane.

| Title | Description | Default | | ------------------------- | ---------------------------------------------------------- | ------- | | showFileName | Show the file name containing the console.log. | false | | showLineNumber | Show the line number of the console.log. | true | | renderReactElements | Render React elements, instead of displaying element JSON. | false |

The stack pane

A nested stack of panes.

| Title | Description | Default | | -------------- | ------------------------------------------------------------- | ------- | | children | An array of panes, just like the top level panes parameter. | [] |

The editor pane

None at the moment.

The transpiler pane

None at the moment.

The workspaces pane

None at the moment.

Hosting

This project contains static assets that run standalone in the browser. You don't need a server, unless you want to host the assets yourself.

unpkg

The recommended host is https://unpkg.com, which is a CDN that serves content from the npm registry. The examples in this README all point to:

<iframe
  width="880"
  height="425"
  frameborder="0"
  src="//unpkg.com/javascript-playgrounds@^1.0.0/public/index.html"
></iframe>

Note that unpkg resolves semver versions in the url

Examples

These examples were created by loading the demo page and running roughly the following JS in the console:

location.href.slice(0, location.href.indexOf('#')) +
  '#data=' +
  encodeURIComponent(
    JSON.stringify({
      title: 'Custom title',
      panes: [
        'editor',
        { type: 'player', platform: 'android', modules: ['moment'] },
      ],
    })
  )

Development

Run

yarn
yarn dev
# => localhost:8080

Build

yarn build

Contributing

Contributions are welcome, but if you're planning to add features, I recommend opening an issue describing the change first.

I maintain this project specifically for my educational guides, so if it's a feature I wouldn't use, I might not want to maintain it. It also may take me a little while to get to reviewing.

License

3-Clause BSD

https://opensource.org/licenses/BSD-3-Clause