How to Setup Storybook with Rails View Components in under 10 Minutes

alt text

Component driven design is one of the best things to come out of the ReactJS framework, and Storybook is an excellent way for a team to collaborate on new features while also conforming to a team style guide.

In a codebase, it’s easy for the different erb files to quickly become a mess when using a utility-style framework like Tailwind CSS. In no time at all, your app loses one of the essential elements of style.



Consistency.

View Components along with Storybook, can help solve this issue while also providing an excellent collaboration experience with your team members.

Why use Storybook with View Components

The main reason is that you can test edge cases with your design. For example, you might want to see what it looks like with different languages or different text when making a button.

  • Test edge cases with your design dynamically
  • Share your style guide with your team, including your managers, product managers and designers, so that they can iterate on it
  • Document use cases
  • Test components for accessibility issues.

If I have convinced you at all, feel free to follow along.

1. Set up a rails app (Optional)

Experienced Rails developers usually read this blog. I’m assuming that you are adding this to an existing app. 

If not, run the following command:

rails new Storybook

2. Install the necessary gems

To note. As of writing, there is no generator for the View Component Storybook gem, but I imagine there will be soon. Below is a summary of all the notes I took while investigating the gem. Hopefully, everything is there for you to get up and running to experience Storybook for yourself.

bundle add view_component
bundle add view_component_storybook

Add require "view_component/storybook/engine" to config/application.rb

# config/application.rb
require_relative 'boot'

require 'rails/all'
require "view_component/storybook/engine"
....

Add */*.stories.json to .gitignore

2. Configure Asset Hosts

If your view components depend on Javascript, CSS or other assets served by the Rails application, you will need to configure asset_hosts appropriately for your various environments. For local development, this is a simple as adding to config/development.rb:

Rails.application.configure do
config.action_controller.asset_host =  'http://localhost:3000'
end

Naturally, you can do the same for staging and production.

3. Install Storybook via yarn

  1. Add Storybook server as a dev dependency. The Storybook Controls addon isn’t needed but comes recommended.
    yarn add @storybook/server @storybook/addon-controls --dev
    
  2. Add an NPM script to your package.json to start your Storybook later.
    // package.json
    {
      "scripts": {
     "storybook": "start-storybook"
      }
    }
    
  3. Create a folder called .storybook. It is a dotfolder. From the command line, do the following:
    
 
mkdir .storybook

    
  4. Create a file called .storybook/main.js file to configure Storybook to find the JSON stories the gem creates. Also, configure the Controls addon:
    touch .storybook/main.js
    
    // .storybook/main.js
    module.exports = {
    stories: ['../test/components/**/*.stories.json'],
          //  stories: ['../spec/components/**/*.stories.json'], if using RSpec
          addons: [
            '@storybook/addon-controls',
          ],
    };


    
  5. Create the .storybook/preview.js file to configure Storybook with the Rails application URL to call for the HTML content of the stories
    touch .storybook/preview.js
    
    //.storybook/preview.js
    export const parameters = {
      server: {
    url: `http://localhost:3000/rails/stories`,
      },
    };
    

    4. Your First StoryBook Component

ViewComponent::Storybook::Stories provides a way to preview components in Storybook. Suppose our app has a ButtonComponent that takes a button_text parameter:

class ButtonComponent < ViewComponent::Base
  def initialize(button_text:)
    @button_text = button_text
  end
end

We can write a stories describing the ButtonComponent. 
So in spec/components/stories or test/components/stories, put in the following


class ButtonComponentStories < ViewComponent::Storybook::Stories
  story(:with_short_text) do
  constructor(title: "my title")
  end

  story(:with_long_text) do
  constructor(title: "my title")
  end
end

5. Generate Storybook JSON

Generate the Storybook JSON stories by running the rake task:

rake view_component_storybook:write_stories_json

Now you should be able to start the rails app and run the Storybook 
 rails s yarn storybook # in separate tab

Configuration (RSpec Only)

By Default ViewComponent::Storybook expects to find stories in the folder test/components/stories. This can be configured by setting stories_path in config/application.rb. For example if you’re using RSpec you might set the following configuration:

config.view_component_storybook.stories_path = Rails.root.join("spec/components/stories")

Gotcha’s

I had to add rack-cors gem and configure wildcard access for development.

  bundle add rack-cors

In config/development.rb, I added the following lines:

# config/development.rb
  config.action_controller.asset_host =  'http://localhost:5000'
  config.middleware.insert_before 0, Rack::Cors do
    allow do
      origins '*'
        resource '/rails/stories/*', :headers => :any, :methods => [:get]
      end
    end

Another Gotcha, I ran into. After you update the HTML for the component, you have to rerun the rake task.

Conclusion

There you have it. Hopefully, this has gotten you up and running in under 10 minutes. If not, feel free to reach out to me to see if I can help. Also, be sure to check out the docs. This gem is still under development and was even updated while I was writing this article.

Happy coding.






© 2021 William Kennedy, Inc. All rights reserved.