Embedding Figma Files in Storybook
The best design and development teams imbue design and brand consistency across multiple products with design systems . When designers and developers collaborate on and regularly contribute to a design system, communication between designers and developers improves since a design system serves as a single source of truth for design guidelines, workflows and elements. By having a design system, everyone understands what set of colors, typography, components, etc. defines the brand and unifies the digital experience. A tool for building robust design systems is Figma . Unlike most other tools, Figma allows teams to work together on design systems in real-time. Design systems constantly evolve to meet users' growing expectations and/or adopt the latest UI/UX trends and patterns, so using a tool like Figma helps to organize, maintain and easily locate design elements. Plus, Figma provides an Inspect panel , which gives developers an easy way to extract CSS code from any design element. This close mapping to code makes developer handoff more seamless. Designers can edit styles and assets within the design system, and developers can view those changes immediately and quickly adapt them into the products. Pairing Figma with Storybook speeds up this process. With a single Storybook addon, storybook-addon-designs , a Figma design system (or any design system) gets directly embedded in the addon panel of the Storybook UI. Any updates made to the design system are synced to the Storybook addon, so developers don't have to switch back and forth between Figma and Storybook to implement these updates in code. They no longer need to ask for links to the updated parts of the design system. Below, I'm going to show you how to embed a Figma file in Storybook with the storybook-addon-designs addon. For this tutorial, we will recreate a button component from the Material 3 Design Kit with React and write stories that represent the different UI states this component supports (e.g., disabled). Material 3 Design Kit is a Figma community file for Google's open-source Material design system . Before proceeding further, duplicate this file to your Figma account's Draft folder and open it to ensure you have access to the design system. When you navigate to the "Components" page, you should see the buttons in the Figma canvas. To get started, create a new directory named figma-storybook and initialize it with a package.json file: Install React and React DOM as dependencies: Install Storybook via the Storybook CLI: Note : Storybook automatically has built-in TypeScript support, so any components written in TypeScript should work with Storybook with no additional configuration needed. To style the React component, install two packages of the Emotion library as dependencies: Within the root of this project's directory, create a src directory and move the stories directory to this directory. Then, delete the contents of the stories directory. Since we moved the stories directory, let's inform Storybook of the new location of this directory: ( .storybook/main.js ) Looking at the design system in Figma, the button's CSS styles can be copied from the Inspect panel. Using these CSS styles, let's implement the button as a React component. Within the src directory, create a components directory and add two files: Here, we will define the button types filled , outlined , text , elevated and tonal as button categories to avoid any confusion with HTML <button /> types ( button , submit and reset ). Each category comes with five unique visual states: enabled , hovered , focused , pressed and disabled . We can implement the hovered , focused and pressed states purely with CSS via the pseudo-classes :hover , :focus and :active respectively. enabled serves as the default state, and disabled can be controlled via the <button /> element's disabled attribute. Now, let's write the <Button /> component and its styles: ( src/components/Button.tsx ) ( src/components/Button.styles.tsx ) Note : The ::after pseudo-element emulates the ripple effect that's recognizable from Material Design UIs. When the user clicks or touches the button, the ripple spreads out in a circular motion from the point of interaction, like a ripple in water. The ripple gives visual feedback to the user that the element has been clicked or touched. For Storybook to load the button's font family "Roboto," let's wrap stories with a decorator that adds an Emotion <Global /> component for injecting global styles like CSS resets and font faces. In this case, the <Global /> component will import the "Roboto" font family from Google Fonts and make it available to all components rendered in stories. ( .storybook/preview.js ) Within the src/stories directory, let's create a Button.stories.tsx file: We will write two stories for the <Button /> component, one for the enabled default state and another for the disabled state. The story for the enabled state should render a button that's clickable and touchable. The story for the disabled state should render a button that's grayed out and not interactive. ( src/stories/Button.stories.tsx ) Run Storybook and check that the <Button /> component looks and behaves correctly. If a designer decides to change the color of the button in the design system, then you would have to launch Figma and open the design system in Figma before being able to see what the new color is and copy the new color from the Inspect panel. Let's improve this workflow by having the design system readily accessible in Storybook. To connect stories directly to Figma, install the storybook-addon-designs addon as a dev. dependency: Within the .storybook/main.js file, register the storybook-addon-designs addon. ( .storybook/main.js ) In Figma, right-click on the filled button with the text "Enabled" and copy its link. A link makes navigating large Figma files easier by referencing a specific element within the file. When visiting the link, Figma brings the referenced element to the forefront of the canvas and highlights it. Within the src/stories/Button.stories.tsx file, set a design parameter for the Enabled story via the parameters key, like so: Parameters define a story's metadata and determine which addons to apply to a story. In this case, the design parameter tells Storybook to apply the storybook-addon-designs addon to the Enabled story. The object set to design configures the storybook-addon-designs addon for the Enabled story. ( src/stories/Button.stories.tsx ) type specifies the type of resource (e.g., image for image, iframe for iframe, figma for Figma file, etc.) to embed in the addon panel. url specifies the URL of the resource. For the Enabled story, we specify the type as figma and the url as the link to the filled button with the text "Enabled" in the Figma file to embed a live view of the Figma file (zoomed into this button) in the addon panel. Save the changes and wait for the Storybook UI to reload. The view has a "Figma" label in the top-left corner, and the user can move around and zoom in (and out of) the Figma file. Since you have a different link for each component variant, let's repeat these same steps for the Disabled story. ( src/stories/Button.stories.tsx ) Currently, all you can do within the live view is move around and zoom in (and out of) the Figma file. To be able to inspect design tokens and extract CSS code from the live view, we must embed the Figma file with an enhanced spec viewed called Figspec . The storybook-addon-designs addon supports a figspec type, but it requires providing a Figma access token to Storybook so that the addon can tell the Figma API to render the Figma file using Figspec components. Let's generate a Figma access token by: Copy the Figma access token. Then, create a .env file within the root of the project directory and add an environment variable named STORYBOOK_FIGMA_ACCESS_TOKEN that's set to the copied token. ( .env ) Within the src/stories/Button.stories.tsx file, replace all instances of the figma type with the figspec type, like so: ( src/stories/Button.stories.tsx ) Restart Storybook so that the environment variable is loaded. When you click on the button in the live view, a panel with the button's CSS code appears. Note : You can click either the button's background or the button's text to get either's CSS code. If you change the background color of the button in the Figma file, then that change will automatically be seen in the live view. If you find yourself stuck at any point while working through this tutorial, then feel free to visit the main branch of this GitHub repository here for the code. Try integrating your Figma design systems into your project's Storybook UI. If you want to learn more advanced techniques with Storybook, then check out the Storybook for React Apps course by Yann Braga, a senior software engineer at Chromatic and a maintainer of Storybook: