0.13.1 • Published 12 months ago

anima-storybook-cli v0.13.1

Weekly downloads
-
License
MIT
Repository
github
Last release
12 months ago

Anima Storybook CLI is a command line tool that works in conjunction with the Anima Figma Plugin to transform Storybook stories into Figma components for a better design-development workflow.

Learn more about the motivations and benefits on our blog.

Table of Contents

Quick Start

You will be switching between Figma and your local Terminal!

  1. Figma: Install the Anima Plugin.
  2. Figma: Create a new Figma project. This is where all your sync'ed Storybook components will live.
  3. Figma: Run the Anima Plugin, go to the Storybook section and copy your unique Anima token.
  4. Terminal: Build your storybook instance, it's usually npm run build-storybook.
  5. Terminal: Run npx anima-storybook-cli sync -t <ANIMA_TOKEN_HERE>.
  6. Figma: Follow the remaining instructions in Figma and you can importing your Storybook components to Figma. 🎉

Setup

1. Installing the CLI

Run one of the following commands (of your preferred package manager) in the Storybook root folder:

npm install --save-dev anima-storybook-cli
yarn add -D anima-storybook-cli
pnpm add -D anima-storybook-cli

2. Add your unique Anima Token

Every Anima team has a unique Anima Token. You can retrieved your teams token through the Anima Figma Plugin under the Storybook section. If it's your first time using the plugin, you will find it on the first onboarding screen, however, you can also retrieve the token at any time from the dropdown menu.

The Anima Storybook CLI accepts the Anima Token using the -t flag:

anima-storybook sync -t <ANIMA_TOKEN_HERE>

For convenience we recommend you add your Anima token as an environment variable!

Adding an environment variable to your local environment

Create a .env file in the root of your Storybook project with the following contents:

#.env
STORYBOOK_ANIMA_TOKEN="PASTE_ANIMA_TOKEN_HERE"

in a CircleCI step (how to add environment variables in a circleCI)

in a GitHub Action step (how to add environment variables in GitHub Actions)

# .github/workflows/main.yml
env:
  STORYBOOK_ANIMA_TOKEN: ${{ secrets.STORYBOOK_ANIMA_TOKEN }}

Whitelist Anima's servers

  • api.animaapp.com (52.37.43.28, 52.32.9.31, 52.25.31.123, 52.32.62.176)
  • s3.animaapp.com (35.160.8.22)

Usage

[pkg manager] anima-storybook sync [options]

The Anima Storybook CLI syncronises a built instance of Storybook with the Anima Figma Plugin, generating Figma components from Storybook stories.

So it can be easily integrated with your Continuous Integration solution, and for your own personal convenience, building your Storybook before syncing it with Animas ensure that your always up to date.

We recommend adding the following script to your package.json

"scripts": {
  //...
  "sync": "npm run build-storybook && anima-storybook sync"
}

You then have a convenient command for syncronising:

npm run sync

Commands & Options

sync

Command to sync the storybook project to Anima team so that it can be then generated in Figma.

anima-storybook sync [option]

Options

OptionsShortDescriptionType
--token-tProvide Anima's token if it was not set as Environment variablestring
--directory-dTo specify the storybook build folder, otherwise it uses Storybook's default storybook-staticstring
--design-tokens               Provide a path of your Design Tokens file, i.e. ./design-tokens.jsonstring

Usage examples:

npx anima-storybook sync --token <anima_token> 
npx anima-storybook sync --directory <storybook_static_dir> #default is storybook-static
npx anima-storybook sync --design-tokens <path_to_design_tokens_file>

generate_tokens

Command to generate a design-tokens file from your framework theme file.

anima-storybook generate-tokens -f tailwind -c ./tailwind.config.cjs -o ./design-tokens.json

This command will generate design tokens colors based on your tailwind config by using theme.colors and theme.extend.colors

Options

OptionsShortDescriptionType
--framework-fProvide your framework name i.e. tailwindstring
--config-cProvide your framework config file i.e. ./tailwind.config.cjsstring
--output-oProvide an output path of your Design Tokens file, i.e. ./design-tokens.jsonstring

Alternative configuration

You can also create an anima.config.js file in your root directory, and save the configuration values like design tokens.

// anima.config.js
module.exports = {
  design_tokens: '<path to design tokens JSON file>', // "./design-tokens.json"
};

Writing better Storybook Stories

Anima uses Storybooks story controls to generate Figma component variants, so it's important to properly configure your stories.

We recommend writing your stories in the following way:

1. Specify ArgTypes to define the props of your component

Define a control type of select for props that have a number of values for example:

// Button.stories.js|jsx|ts|tsx

//...

export default {
  // ...
  argTypes: {
    // ...
    variant: {
      control: {
        type: 'select',
        options: ['primary', 'secondary', 'tertiary'],
      },
    },
  },
};

🚨 STORYBOOK BUG ALERT 🚨

The documented way to define a control type of boolean for a prop is:

// Button.stories.js|jsx|ts|tsx

//...

export default {
  // ...
  argTypes: {
    // ...
    disabled: {
      control: 'boolean',
    },
  },
};

We've discovered that this causes problems not only in our plugin but also in Storybook and we've logged an issue. To get the correct behaviour we recommend changing the definition to:

// Button.stories.js|jsx|ts|tsx

//...

export default {
  // ...
  argTypes: {
    // ...
    disabled: {
      type: 'boolean',
    },
  },
};

2. Use single story per component

Instead of creating a story for each variant of a component, it is preferable to create just one story and use the args property to define the default values of your props.

This will make it easier to find components to generate in Figma with the Anima plugin.

There are two ways to achieve this and both will have the same result:

2.1. Name your single story Default

// Button.stories.js|jsx|ts|tsx

import { Button } from './Button';

export default {
  title: 'Components/Button',
  component: Button,
  variant: {
      control: {
        type: 'select',
        options: ['primary', 'secondary', 'tertiary'],
      },
    },
};

export const Default = () => <Button {...args} />;

Default.args = {
  variant: 'primary',
  label: 'Button',
};

2.2. Use the single story hoisting feature from Storybook (more info here)

// Button.stories.js|jsx|ts|tsx

import { Button as Component } from './Button'; // import the Button component as a different name

export default {
  title: 'Components/Button',
  component: Component, // use the Button component as the component
  variant: {
      control: {
        type: 'select',
        options: ['primary', 'secondary', 'tertiary'],
      },
    },
};

// This is the only named export in the file, and it matches the component name
export const Button = () => <Component {...args} />;
Button.args = {
  variant: 'primary',
  label: 'Button',
};