Convert Storybook stories into Sketch symbols.
Uses the amazing and experimental
html-sketchapp
. Only supports web.
Firstly, get Sketch and npm. Then either clone html-sketchapp
or download it as a zip, installing the included Sketch plugin called asketch2sketch.sketchplugin
:
Install story2sketch
:
npm i story2sketch -g
Now navigate to your Storybook 3.3 (or newer) project. You'll want to take full control of your Storybook webpack.config.js if you haven't already done so, adding:
module.exports = (storybookBaseConfig, configType) => {
const newConfig = {
...storybookBaseConfig
};
// Add this:
// Export bundles as libraries so we can access them on page scope.
newConfig.output.library = "[name]";
return newConfig;
}
Run story2sketch, pointing towards a Storybook iframe URL. See configuration for more options, or if you have a lot of stories.
story2sketch --url https://localhost:9001/iframe.html --output stories.asketch.json
Import the generated file into Sketch via Plugins > From *Almost* Sketch to Sketch
in Sketch menu bar.
Success!
As stated by react-sketchapp
, it's complicated to manage assets in a design system. Many teams building design systems or component libraries already produce Sketch files for distributing designs and use Storybook to prototype and present the developed components. It can become difficult to keep designs up to date with the latest components, with designers ever playing catchup. story2sketch
generates a Sketch file from your components via Storybook, so your Sketch designs always stay up to date.
You can configure story2sketch
using the API via the CLI, configuring your package.json
or adding a story2sketch.config.js
file.
Simply call story2sketch
with options from the API.
$ story2sketch --stories all --output dist/great-ui.asketch.json
Add the following to your package.json:
{
"story2sketch": {
"stories": "all",
"output": "dist/great-ui.asketch.json"
}
}
Create a file called story2sketch.config.js
on the root of your project:
module.exports = {
output: "dist/great-ui.asketch.json",
stories: "all"
}
Parameter | Explanation | Input Type | Default |
---|---|---|---|
--output |
Specifies the filename for the generated asketch.json file. | string | "dist/stories.asketch.json" |
--input |
The location of Storybook's generated iframe.html. Use this over --url if possible for performance. |
string | "dist/iframe.html" |
--url |
Storybook iframe URL. Will end in iframe.html . Prefer --input for performance if possible. |
string | "http://localhost:9001/iframe.html" |
--stories |
Stories to extract from Storybook. You should probably override the default. | object/string | "all" |
--concurrency |
Number of headless Chrome tabs to run in parallel. Drastically impacts performance. | integer | 4 |
--symbolGutter |
Gutter to place between symbols in Sketch. | integer | 100 |
--narrowViewport |
Narrow viewport dimensions | object | { width: 320, height: 1200 } |
--standardViewport |
Standard viewport dimensions | object | { width: 1920, height: 1200 } |
--querySelector |
Query selector to select your node on each page. Uses document.querySelectorAll . |
string | "*" |
--verbose |
Verbose logging output. | boolean | false |
module.exports = {
output: "dist/great-ui.asketch.json",
input: "dist/iframe.html",
concurrency: 2,
symbolGutter: 200,
narrowViewport: { width: 320, height: 1200 },
standardViewport: { width: 1920, height: 1200 },
pageTitle: "great-ui",
stories: [
{
kind: "Buttons/Button",
stories: [
{
name: "Button"
}
]
},
{
kind: "Buttons/ButtonGroup",
stories: [
{
name: "Default",
displayName: "Horizontal"
},
{
name: "Vertical"
}
]
},
{
kind: "Table",
stories: [
{
name: "Table"
}
]
}
]
}
Because this project is experimental, and so is it's core dependency. If your stuff looks bad, either it's not supported by html-sketchapp
yet (see support here), or you need to configure story2sketch.
react-sketchapp
only supports React Native, or forces you to use React Native component naming conventions. html-sketchapp
supports good ol' fashioned HTML, and doesn't care what web framework you're using.
Not yet, but we have plans to add support for multiple and custom adaptors.