Giter Site home page Giter Site logo

hirohe / storybook-addon-jarle-monaco Goto Github PK

View Code? Open in Web Editor NEW
2.0 1.0 3.0 954 KB

storybook.js addon providing react-live preview and monaco-editor editing

Home Page: https://hirohe.github.io/jarle-monaco/?path=/story/example-liveedit-in-mdx--page

License: MIT License

JavaScript 21.13% CSS 2.64% TypeScript 76.24%
storybook jarle monaco-editor live-edit live-editor live-preview react storybook-addons

storybook-addon-jarle-monaco's Introduction

storybook-addon-jarle-monaco

version

provide a live-editing editor and preview as storybook addon, it uses jarle and monaco editor

you could change code in editor and see the result in preview

Example

yarn # install dependencies
yarn storybook # start storybook

Usage

npm i --save-dev storybook-addon-jarle-monaco
# or
yarn add -D storybook-addon-jarle-monaco

Registry the addon to storybook

module.exports = {
  // ...
  addons: [
    // ... other addons
    'storybook-addon-jarle-monaco',
  ],
}

Use in stories

image

// *.stories.jsx
import { generateLivePreviewStory } from 'storybook-addon-jarle-monaco'

// use generateLivePreviewStory HoC to generate live preview
export const LiveEdit = generateLivePreviewStory({
  code: `() => <Button primary label={foo} />`,
  scope: {
    Button,
    foo: 'bar',
  }
})

export const LiveEditUseLivePreview = () => (
  <LivePreview
    channel={addons.getChannel()}
    code={`<Button primary label={'hello'} />`}
    providerProps={{
      scope: {
        Button,
      }
    }}
  />
)

// use LivePreview alone, you need to set showEditor manually
LiveEditUseLivePreview.parameters = {
  liveEdit: {
    showEditor: true,
  }
}

Use in MDX

image

import { Meta } from '@storybook/addon-docs';
import { Button } from './Button';
import { Playground } from '@pupu/storybook-addon-jarle-monaco';

<Meta title="Example/LiveEdit in MDX" />

> Use `Playground` in *.stories.mdx file, it provides live preview and editor

### Button

<Playground
  code="<Button primary label={'hello'} />"
  providerProps={{
    scope: {
      Button,
    },
  }}
/>

Typescript typings resolve

Check the story AutoTypings.stories.mdx

image

image

With liveDecorator

  1. add liveDecorator as global decorator
import { liveDecorator } from 'storybook-addon-jarle-monaco'

// .storybook/preview.js
export const decorators = [
  liveDecorator
]
  1. usage in stories
// *.stories.jsx

// with liveDecorator will read the story's source code,
// so we can avoid writing live preview's code in plain text.
export const LiveEditWithLiveDecorator = () => <Button primary label="hello" />

// but you still need to provide scope or custom LivePreviewProps
LiveEditWithLiveDecorator.parameters = {
  liveEdit: {
    showEditor: true,
    withLiveDecorator: true,
    scope: {
      Button,
    }
  }
}

Config

Monaco files

this addon use @monaco-editor/react, by default monaco files are being downloaded from CDN, you can change the paths to use another CDN domain.

e.g.

import { loader } from '@monaco-editor/react'

loader.config({ paths: { vs: 'https://cdn.bootcdn.net/ajax/libs/monaco-editor/0.33.0/min/vs' } })

Story parameters

liveEdit config in story's parameters

property type default description
showEditor boolean false show the live edit panel or not
withLiveDecorator boolean false wrap the story with LivePreview decorator or not

Playground Component

property type default description
code string -- required, the code for live edit
autoTypings boolean false enable auto typings feature,if true, will set the language to typescript by default
defaultExpand boolean false expand the editor content
scope object -- prop of Jarle Preview, for global scope injection
providerProps ProviderProps -- props for Jarle Provider
resolveTypeDefinition (packageName: string) => Promise<string | null> | string | null -- provide custom type definitions for certain package
editorProps Partial<EditorProps> -- props for MonacoEditor
className string -- class for wrapper

you can add Jarle's Provider props in liveEdit, check the Jarle's docs for more information.

storybook-addon-jarle-monaco's People

Contributors

hirohe avatar

Stargazers

 avatar  avatar

Watchers

 avatar

storybook-addon-jarle-monaco's Issues

Stackoverflow when not using defaultExpanded

This is an amazing add-on! My docs have never looked better, and folks at my company are very excited about the idea of directly editing the components rather than fiddling with knobs. Truly amazing!

That being said, I've found an issue. It's not a show stopper, but it is awkward:

Problem:

If you have a mix of editors that require horizontal scrolling and editors that don't, and they are not expanded by default, then the editors crash with a stack overflow. It seems setScrollDimensions in some dependency is being called endlessly. This only appears to happen on initial page load. If I load up some editors that have no horizontal scrolling, and then shrink the screen down so that they do need it, they do not crash.

Reproduction Steps:

In your example repo I've modified the following files:

  • to the mdx live edit example, add a third playground that is just the first example again
  • in the components file for that mdx story, remove defaultExpanded from all the demos
  • in Demo2, remove all the line breaks so that the editor will require scrolling

Here are the files, for your copy/paste convenience.

// stories/MarkdownDemo.stories.mdx
import { Meta } from '@storybook/addon-docs';
import { Demo1, Demo2, Demo3 } from './markdown-demo';

<Meta title="Example/LiveEdit in MDX" />

<style>{`
.playground {
  margin-bottom: 24px;
}
`}</style>

### Basic
<Demo1 className="playground" />

---

### Import modules
<Demo2 className="playground" />

### A Third Example
<Demo1 className="playground" />
// stories/markdown-demo.jsx
import React from 'react'
import { Button } from './Button'
import { Playground } from '../src'
import Confetti from 'canvas-confetti'

export const Demo1 = ({ className }) => (
  <Playground
    className={className}
    code="<Button primary label={'hello'} />"
    providerProps={{
      scope: {
        Button,
      },
    }}
  />
)

export const Demo2 = ({ className }) => (
  <Playground
    className={className}
    code={`import Button from './Button';
import Confetti from 'canvas-confetti';

function cheer() {
  // left
  Confetti({ particleCount: 30, angle: 60, spread: 55, origin: { x: 0 } })

  // right
  Confetti({ particleCount: 30, angle: 120, spread: 55, origin: { x: 1 } })
}

() => <Button primary label={'Cheer !'} onClick={cheer} />
`}
    providerProps={{
      resolveImports: () => ({
        './Button': Button,
        'canvas-confetti': Confetti,
      }),
    }}
  />
)

export const Demo3 = ({ className }) => (
  <Playground
    className={className}
    code="<Button primary label={'hello'} />"
    providerProps={{
      scope: {
        Button,
      },
    }}
  />
)

Conclusion:

Like I said, a work-around exists. You can either use defaultExpanded (a bit verbose) or be careful to insert lots of line-breaks (a bit awkward). Otherwise, it is all-around a great tool. I will be happy to contribute a PR if you have an idea of how to fix this but don't have the time to implement it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.