包详细信息

playroom

seek-oss328.6kMIT0.44.0

Design with code, powered by your own component library

自述文件

Playroom Playroom

npm Build Status


Playroom Demo

Simultaneously design across a variety of themes and screen sizes, powered by JSX and your own component library.

Playroom allows you to create a zero-install code-oriented design environment, built into a standalone bundle that can be deployed alongside your existing design system documentation.

  • Iterate on your designs in the final medium.
  • Create quick mock-ups and interactive prototypes with real code.
  • Exercise and evaluate the flexibility of your design system.
  • Share your work with others by simply copying the URL.

Demos

Braid Design System (Themed)

Bumbag

Overdrive

Cubes (Themed)

Mesh Design System (Themed)

Mística Design System (Themed)

Shopify Polaris

Agriculture Design System

Send us a PR if you'd like to be in this list!

Getting Started

$ npm install --save-dev playroom

Add the following scripts to your package.json:

{
  "scripts": {
    "playroom:start": "playroom start",
    "playroom:build": "playroom build"
  }
}

Add a playroom.config.js file to the root of your project:

module.exports = {
  components: './src/components',
  outputPath: './dist/playroom',

  // Optional:
  title: 'My Awesome Library',
  themes: './src/themes',
  snippets: './playroom/snippets.js',
  frameComponent: './playroom/FrameComponent.js',
  scope: './playroom/useScope.js',
  widths: [320, 768, 1024],
  port: 9000,
  openBrowser: true,
  paramType: 'search', // default is 'hash'
  exampleCode: `
    <Button>
      Hello World!
    </Button>
  `,
  baseUrl: '/playroom/',
  webpackConfig: () => ({
    // Custom webpack config goes here...
  }),
  iframeSandbox: 'allow-scripts',
  defaultVisibleWidths: [
    // subset of widths to display on first load
  ],
  defaultVisibleThemes: [
    // subset of themes to display on first load
  ],
};

Note: port and openBrowser options will be set to 9000 and true (respectively) by default whenever they are omitted from the config above.

Your components file is expected to export a single object or a series of named exports. For example:

export { default as Text } from '../Text'; // Re-exporting a default export
export { Button } from '../Button'; // Re-exporting a named export
// etc...

The iframeSandbox option can be used to set the sandbox attribute on Playroom's iframe. A minimum of allow-scripts is required for Playroom to work.

Now that your project is configured, you can start a local development server:

$ npm run playroom:start

To build your assets for production:

$ npm run playroom:build

Snippets

Playroom allows you to quickly insert predefined snippets of code, providing live previews across themes and viewports as you navigate the list. These snippets can be configured via a snippets file that looks like this:

export default [
  {
    group: 'Button',
    name: 'Strong',
    code: `
      <Button weight="strong">
        Button
      </Button>
    `,
  },
  // etc...
];

Custom Frame Component

If your components need to be nested within custom provider components, you can provide a custom React component file via the frameComponent option, which is a path to a file that exports a component. For example, if your component library has multiple themes:

import React from 'react';
import { ThemeProvider } from '../path/to/your/theming-system';

export default function FrameComponent({ theme, children }) {
  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}

Custom Scope

You can provide extra variables within the scope of your JSX via the scope option, which is a path to a file that exports a useScope Hook that returns a scope object. For example, if you wanted to expose a context-based theme variable to consumers of your Playroom:

// scope.js

import { useTheme } from '../path/to/your/theming-system';

export default function useScope() {
  return {
    theme: useTheme(),
  };
}

Embedded CSS Formatting

CSS authored inside style tags with a jsx attribute will be formatted as CSS. This takes advantage of prettier's embedded language formatting capabilities.

For example:

<style jsx>
  {`
    .foo {
      color: red;
    }
  `}
</style>

Theme Support

If your component library has multiple themes, you can customise Playroom to render every theme simultaneously via the themes configuration option.

Similar to your components file, your themes file is expected to export a single object or a series of named exports. For example:

export { themeA } from './themeA';
export { themeB } from './themeB';
// etc...

TypeScript Support

If a tsconfig.json file is present in your project, static prop types are parsed using react-docgen-typescript to provide better autocompletion in the Playroom editor.

[!NOTE] By default, all .ts and .tsx files in the current working directory are included, excluding node_modules.

If you need to customise this behaviour, you set the typeScriptFiles property in your playroom.config.js. This property accepts an array of tinyglobby-compatible globs.

module.exports = {
  // ...
  typeScriptFiles: ['src/components/**/*.{ts,tsx}', '!**/node_modules'],
};

If you need to customise the parser options, you can set the reactDocgenTypescriptConfig property in your playroom.config.js.

For example:

module.exports = {
  // ...
  reactDocgenTypescriptConfig: {
    propFilter: (prop, component) => {
      // ...
    },
  },
};

ESM Support

Playroom supports loading ESM configuration files. By default, Playroom will look for a playroom config file with either a .js, .mjs or .cjs file extension.

Storybook Integration

If you are interested in integrating Playroom into Storybook, check out storybook-addon-playroom.

Browser Support

Playroom is built to work on the latest stable versions of all major browsers. Some features may not work as expected in older browsers.

License

MIT.

更新日志

playroom

0.44.0

Minor Changes

  • #417 03d145d Thanks @michaeltaranto! - Improved handling of rendering errors

    Errors occurring during render no longer replace the frame contents with a red error message. Instead, the error is caught and overlaid on top of the last successful render result (when possible).

  • #414 e69f698 Thanks @felixhabib! - Improve snippets search ranking algorithm. Results are now sorted primarily by the group property over the name property, making it easier to see related snippets together.

    Replace fuzzy dependency with fuse.js to enable result sorting.

  • #410 6b5eaa3 Thanks @felixhabib! - Refactor layout.

    Improve the code editor show/hide animation. Prevent code contents from being searchable when the editor is hidden.

Patch Changes

  • #421 6fd2aab Thanks @askoufis! - Playroom's utility API is now bundled for both ESM and CJS

    EXAMPLE USAGE:

    // ESM import
    import { createUrl } from 'playroom';
    
    // CJS require
    const { createUrl } = require('playroom');
  • #424 8795fde Thanks @michaeltaranto! - Use clsx consistently for building class lists

    Remove classnames in favor of clsx for building class lists in the Playroom codebase.

  • #423 4640ca1 Thanks @michaeltaranto! - Preview: Improve accessibility of loading screen

  • #418 1d59ba3 Thanks @felixhabib! - Migrate some internal files from Javascript to Typescript.

0.43.1

Patch Changes

  • #408 059e9c7 Thanks @askoufis! - CLI: Only require modules that are relevant to the CLI command being executed

0.43.0

Minor Changes

  • #402 6f30915 Thanks @felixhabib! - Add 'Fit to window' frame width option

    Introduces a width option that dynamically sizes to use the maximum available frame space. This option will be available in addition to the existing supplied or default widths.

Patch Changes

  • #402 6f30915 Thanks @felixhabib! - Fix styling issue, ensuring frame names and shadows show at a dimmed opacity except on hover

0.42.0

Minor Changes

  • #397 15a44bb Thanks @askoufis! - Replace fast-glob dependency with tinyglobby, removing 6 transitive dependencies

    BREAKING CHANGE:

    While tinyglobby aims to mimic fast-glob's behaviour, not all behavior is guaranteed to be the same. The typescriptFiles property in your playroom config is the only property that is affected by this change. Please ensure any custom globs are functioning as expected.

0.41.0

Minor Changes

  • #396 3ceb0af Thanks @askoufis! - Drop support for React 17

    BREAKING CHANGE: React 17 is no longer supported. Playroom now requires React 18 or later.

Patch Changes

  • #396 3ceb0af Thanks @askoufis! - Loosen @types/react and @types/react-dom dependencies to include ^18.0.0

  • #393 199c1e0 Thanks @askoufis! - Use the URL hash for passing params to each playroom iframe even when paramType: 'search' is configured

    This change prevents a full React re-render from occurring whenever code is changed in a playroom in projects that configure paramType: 'search', resulting in a much smoother prototyping experience.

0.40.0

Minor Changes

  • b8f89d2: Set default colour scheme to 'system'.
  • 16ec1e7: Update react and react-dom peer dependency ranges to include ^19
  • 857feab: Remove keybinding for copying Playroom link to clipboard.
  • fab7863: Drop support for browser versions that do not support the IntersectionObserver API

    Playroom no longer provides a polyfill for IntersectionObserver.

Patch Changes

  • 4412ef1: Ensure favicon is displayed on Preview links.
  • 6095dc4: Replace polished dependency with CSS relative color syntax and color-mix
  • 16ec1e7: Remove react-use dependency
  • 67006f0: Fix bug in "Wrap selection in tag" command that caused the start cursor to sometimes be in the wrong position when selecting an empty line.
  • fb14616: Restrict playroom's Vanilla Extract plugin to only process playroom's .css.ts files
  • 719c957: Remove lodash dependency

0.39.1

Patch Changes

  • dbf3310: Update re-resizable dependency.

    Fix issue where resizable handles were stacked below the editor panel and could not be selected.

0.39.0

Minor Changes

  • d902e17: Save editor height and width preferences as a percentage of the viewport size, rather than a fixed pixel value. This prevents the editor from obscuring preview panels when toggling the browser tools on/off or resizing the window.
  • 7aaa6d0: Save the state of the editor visibility to the Playroom URL.

    This allows you to share a Playroom link with the editor either open or closed on load.

  • ee73b75: Update snippets behaviour to instantly navigate and scroll to the currently selected snippet. This eliminates sluggish feeling caused by smooth scroll.

Patch Changes

  • c5d5808: Fixes a bug that was causing erroneous snippet previews and broken preview updates when moving the cursor in the snippets panel while the snippets panel was closing.

0.38.1

Patch Changes

  • a62002d: Apply title from url on page load

    Previously the document title would only update when the frames panel is open. The title is now correctly reflected from the url on page load.

  • cf0fa9e: start: Disable webpack error overlay

    Prevent the default webpack dev server error overlay from blocking the preview frames in start mode. Playroom handles its own errors, and this would block the preview frames and need to be dismissed manually.

0.38.0

Minor Changes

  • 7df36e3: Improve frame filtering UX.

    • Allow users to select all checkboxes in a frame filter section, rather than automatically unselecting all checkboxes when all are selected.
    • Rename the "Show all" button to "Clear" to reinforce the filtering pattern.
  • 384810e: Use CSS gap and grid for layout spacing in Playroom UI.

Patch Changes

  • a0724d2: Fixes a bug in the side panel exit animation that was causing the contents to vanish abruptly
  • 934a017: Exclude irrelevant files from published package
  • 92a0039: Fix Playroom UI icon centering
  • 422a259: Remove data-testid attributes from UI elements

0.37.1

Patch Changes

  • 2b6d5c5: Update lz-string to 1.5.0, and removed unnecessary @types/lz-string

0.37.0

Minor Changes

  • 94c75f8: Add "Find", "Find and replace", and "Jump to line" functionality.

    Keybindings for these new commands are:

    • Cmd + F / Ctrl + F - Find
    • Cmd + Option + F / Ctrl + Alt + F - Find and replace
    • Cmd + G / Ctrl + G - Jump to line

Patch Changes

  • 71f694a: Fix issue with "Toggle comment" command commenting certain code outside JSX tags with incorrect syntax.

0.36.0

Minor Changes

  • c3f0373: Drop support for Node versions <18.12.0
  • 90edcc8: Add keybinding for copying Playroom link to clipboard with <kbd>⌘</kbd> + <kbd>⇧</kbd> + <kbd>C</kbd> (or, on Windows, <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>C</kbd>).
  • c99cc30: Add keybinding to toggle comment syntax for the current selection.

    Pressing <kbd>Cmd</kbd> + <kbd>/</kbd> (or, on Windows, <kbd>Ctrl</kbd> + <kbd>/</kbd>) will toggle comment syntax for the currently selected text. If no text is selected, the line the cursor is on will toggle comment syntax.

Patch Changes

  • dd95719: Add 'Insert snippet' shortcut to 'Keyboard Shortcuts' list in settings panel for better discoverability.
  • cad1ded: Remove dependency on current-git-branch package
  • 0215bb4: Replace query-string dependency with URLSearchParams
  • 6ad5895: Update shortcut format for Windows users for consistency with standard styling.
  • cb3c427: In the Settings Panel, sort keyboard shortcuts order by most frequently and widely used. Related shortcuts are grouped together.
  • b1766c2: Move Title setting from Settings Panel to Frame Panel to group current playroom settings together and improve discoverability.

    Now, all settings that affect the current playroom tab live in the Frame Panel. Settings affecting all playroom tabs live in the Settings Panel.

  • 41e8cfa: Fix an issue where new Playroom tabs without a set title would load a recently used title.

  • 134c5a4: Upgrade webpack-dev-server to v5
  • c3f0373: Update dependencies
  • f88a4e6: Fix async import of playroom config on Windows

0.35.0

Minor Changes

  • ad60e01: Add support for specifying default subsets of themes and screen widths via the config.

    Example usage

    // playroom.config.js
    module.exports = {
      ...,
      defaultVisibleWidths: [
        // subset of widths to display on first load
      ],
      defaultVisibleThemes: [
        // subset of themes to display on first load
      ],
    }
  • f45dd04: Add ability to customise tab titles via a "Title" section in the settings panel.

Patch Changes

  • f491105: Fix bug in "Wrap selection in tag" command that caused the start cursor to occasionally be placed in the wrong postion.

0.34.2

Patch Changes

  • 88bd204: Fix playroom build by making favicon path relative to webpack config

0.34.1

Patch Changes

  • e3b820b: Add favicon to Playroom site.
  • 4fb69cb: Improve affordance of error marker detail

0.34.0

Minor Changes

  • 1c8ae6b: Use smaller React pragmas to reduce the payload sent to iframes
  • c4b639c: Replace @babel/standalone with sucrase for JSX compilation

Patch Changes

  • 1c8ae6b: Highlight the correct error location when code has syntax errors

0.33.0

Minor Changes

  • 2d3571b: Add support for loading mjs config files

    Consumers should now be able to write their configuration files using ES modules. By default Playroom will look for playroom.config.js with either a .js, .mjs or .cjs file extension.

0.32.1

Patch Changes

  • a044864: Allow overriding Webpack module rules

    Consumers may have complex Webpack configurations that can clash with Playroom's. In this case, it's useful to be able to override the module rules that Playroom defines. For example, overriding loaders defined for CSS files:

    // playroom.config.js
    module.exports = {
      webpackConfig: () => ({
        module: {
          rules: [
            // use your own CSS loaders
            { test: /\.css$/, use: ['style-loader', 'css-loader'] },
          ],
        },
      }),
    };

0.32.0

Minor Changes

  • 720d542: Drop support for React 16. Consumers are encouraged to upgrade to React 17+, which is a drop-in replacement.
  • 720d542: Support TypeScript 5.0+

0.31.0

Minor Changes

  • 8ce01ff: Add keyboard shortcuts legend to the settings panel, to help with discoverability.
  • 8ce01ff: Adds keybinding for wrapping the current selection in a tag.

    Pressing <kbd><kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>,</kbd></kbd> (or, on Windows, <kbd><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>,</kbd></kbd>) will wrap the currently selected text in an empty fragment that is ready to be typed in.

    Works for single cursors (doesn't wrap anything), single line selections, multi-line selections, and multiple cursors.

0.30.0

Minor Changes

  • b247e88: Adds multi-cursor support.

    The keyboard shortcuts added in the previous version (swap/duplicate line up/down) now support multiple cursors being on screen. "Select next occurrence" and "add cursor up/down" have also been implemented.

    | Keybinding | Action | | -------------------------------------------------------------- | ----------------------- | | <kbd><kbd>Alt</kbd> + <kbd>Up</kbd></kbd> | Swap line up | | <kbd><kbd>Alt</kbd> + <kbd>Down</kbd></kbd> | Swap line down | | <kbd><kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>Up</kbd></kbd> | Duplicate line up | | <kbd><kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>Down</kbd></kbd> | Duplicate line down | | <kbd><kbd>Cmd</kbd> + <kbd>Alt</kbd> + <kbd>Up</kbd></kbd> | Add cursor to prev line | | <kbd><kbd>Cmd</kbd> + <kbd>Alt</kbd> + <kbd>Down</kbd></kbd> | Add cursor to next line | | <kbd><kbd>Cmd</kbd> + <kbd>D</kbd></kbd> | Select next occurrence |

0.29.0

Minor Changes

  • 9fc8c0d: Adds VSCode-style keybindings for move line up/down and copy line up/down. Works for selections as well as single lines.

    See the VSCode keyboard shortcut reference for details (Mac/Windows).

0.28.2

Patch Changes

  • 8030325: Update all dependencies
  • 8030325: Fix error message on gutter marker tooltip

    Playroom wraps the code in a Fragment to compile it and then removes it from the error message displayed as a tooltip on the gutter marker if it fails to compile.

    The logic has been improved to remove the first occurence of an opening <React.Fragment> and the last occurence of </React.Fragment>.

    Errors should no longer incorrectly have a stray closing fragment:

    "unknown: Expected corresponding JSX closing tag for <Boxerror>. (3:0)
    
       1 | <Boxerror>
       2 |   ...
    -> 3 | </Box></React.Fragment>
    +> 3 | </Box>
         | ^"
  • cbcf1cf: Update dependencies (and move to pnpm internally)