npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

storybook-addon-sdc

v0.3.8

Published

Drupal Single Directory Components as stories

Downloads

2,653

Readme

Storybook SDC Addon

This addon streamlines the integration of Drupal Single Directory Components (SDC) into Storybook, allowing YAML-configured components (e.g., *.component.yml) to be dynamically loaded as stories in Storybook.

Demo GIF

Table of Contents


Overview

This Storybook addon makes it easy to integrate Drupal Single Directory Components (SDC) into Storybook using YAML configurations and Twig templates. It dynamically loads components, allowing you to quickly create and manage stories with minimal configuration.

It is still regular Storybook but now with the added option to import and manage Drupal Single Directory Components (SDC).

Storybook Example Live

You can view a live example of the SDC Addon in Storybook, hosted on GitHub Pages, showcasing components in the /components directory of that repository.

Features of the Addon

The SDC Storybook Addon simplifies the integration of Drupal Single Directory Components (SDC) into Storybook, offering several key features:

  • Vite Plugin Integration: Leverages the vite-plugin-twig-drupal plugin to seamlessly load and process Twig templates used in SDC components.
  • Dynamic Path Resolution: Utilizes namespaces to dynamically discover components within your project structure, eliminating the need for manual configuration.
  • Story Generation: Automatically creates stories based on the YAML configurations of your SDC components, streamlining the story creation process.
  • JSON Schema Support: Supports JSON Schema for props and slots, enabling the generation of mock data for missing values and ensuring data consistency.
  • Drupal Behavior Embedding: Allows you to directly embed Drupal behaviors like Drupal.attachBehaviors() into Storybook previews, ensuring components behave similarly to their Drupal counterparts.

Why Choose SDC Storybook Over Alternatives?

While solutions like SDC Styleguide and Drupal Storybook are valuable, the SDC Storybook addon offers distinct advantages:

1. Component Independence and Modularity

  • Following the BEM (Block Element Modifier) methodology, a component should work independently across environments.
  • The functionality of your component must not depend on the Drupal version, or the active Drupal theme — it should be portable to any system.

2. No Complex Drupal Setup Required

  • No need to install or configure Drupal dependencies for component development.
  • Work faster by developing frontend components in Storybook without running a heavy Drupal instance.

3. Simplifies DevOps and CI/CD Pipelines

  • Since components are isolated, testing and deployments are simplified.
  • You can avoid Drupal-specific configuration in CI pipelines, leading to more efficient and maintainable workflows.

4. Scalability and Flexibility with Faker.js and JSON Schema

  • Tools like Faker.js let you generate test data for components without needing real content.
  • JSON Schema defines component data clearly and consistently, helping maintain data integrity.

5. Industry-Standard Tool for Frontend Development

  • Storybook is widely adopted in frontend development, which makes onboarding easier, even for developers unfamiliar with Drupal.
  • JSON Schema enables work on components without deep Drupal knowledge, opening the project to a wider developer base.

6. Drupal-Specific Behavior Embedded in Components

  • Embed Drupal behaviors (like Drupal.attachBehaviors()) directly into Storybook previews, ensuring consistent component behavior between Storybook and production.
  • Supports drupalSettings and once.js, so components in Storybook behave identically to their Drupal counterparts.

7. Twig.js vs Drupal Twig

While using Drupal to render components offers tighter integration, there are strong reasons to continue using Twig.js in many scenarios:

  • Many Components Don’t Need Full Drupal Logic. Basic components (buttons, cards, lists) rely on simple HTML and CSS, not on complex template logic. For such components, Twig.js provides sufficient rendering without the need for full Drupal preprocessing.
  • Twig.js Works Well for Frontend-Focused Use Cases.
  • Styling and Behavior Mismatches Can Be Managed Separately in Drupal implelentation phase.

Quickstart Guide

  1. In theme or module or just empty directory (If package.json not yet exists):

    npm init
    echo "node_modules/" >> .gitignore
  2. Install dependencies:

    npm i vite twig storybook-addon-sdc --save-dev
  3. Initialize Storybook:

    npx storybook@latest init --builder vite --type html --no-dev
  4. Remove default storybook boilerplate stories (Optional):

    rm -rf ./stories
  5. Configure as described in Configuration.

  6. Add components to the components directory (or copy from this repository).

  7. Start Storybook:

    npm run storybook

Configuration

To configure the addon, update .storybook/main.js as shown below:

import { join } from 'node:path' // 1. Add path dependency.

const config = {
  stories: ['../components/**/*.component.yml'], // 2. Set components glob.
  addons: [
    {
      name: 'storybook-addon-sdc', // 3. Configure addon.
      options: {
        sdcStorybookOptions: {
          namespace: 'umami', // Your namespace.
        },
        vitePluginTwigDrupalOptions: {
          // vite-plugin-twig-drupal options.
          namespaces: {
            umami: join(__dirname, '../components'), // Your namespace and path to components.
          },
        },
        jsonSchemaFakerOptions: {}, // json-schema-faker options.
      },
    },
    // Any other addons.
    '@storybook/addon-essentials',
    '@chromatic-com/storybook',
    '@storybook/addon-interactions',
  ],
  framework: {
    name: '@storybook/html-vite',
    options: {},
  },
}
export default config

Setting Default Values

For json-schema-faker to generate reliable data, use default or examples in your SDC schema:

props:
  type: object
  properties:
    html_tag:
      type: string
      enum:
        - article
        - div
      default: article
slots:
  content:
    title: Content
    examples:
      - Hello! I'm card content

Refer to:

Creating Experimental Stories

The sdcStorybook configuration in the SDC YAML file provides a flexible way to define custom stories for your components. This feature allows you to use predefined props, custom slots, or even reuse stories defined elsewhere. Here's how it works:

Example Configuration

thirdPartySettings:
  sdcStorybook:
    stories:
      grid:
        props:
          label: Paragraph with grid
          extra_classes:
            - m-paragraph--grid
        slots:
          content:
            # 1. Basic Props and Slots
            # This card uses only the basic default props and slots defined in the component YAML.
            - type: component
              component: 'umami:card'

            # 2. Predefined Story
            # This card references an existing story (e.g., "Preview")
            # from the component YAML, which includes predefined props and slots.
            - type: component
              component: 'umami:card'
              story: Preview

            # 3. Custom Props and Slots
            # This card defines custom props to modify its behavior (e.g., setting
            # the HTML tag to 'div') and custom slots to override specific content.
            - type: component
              component: 'umami:card'
              props:
                html_tag: 'div' # Custom HTML tag for the card container
              slots:
                content: 'Hello from third grid card!'

Key Features

This configuration provides three distinct options for creating stories:

  1. Render Using Basic Args The first card in the grid example uses only its basic arguments (Basic.args). No additional configuration or props are required for this component.
- type: component
  component: 'umami:card'
  1. Reuse an Existing Story The second card uses the Preview story defined earlier. This is particularly useful for reusing pre-configured props and slots without redefining them in each story.
- type: component
  component: 'umami:card'
  story: Preview
  1. Define Custom Slots The third card defines a custom content slot. This allows you to override or enhance the default behavior of the component with specific content.
- type: component
  component: 'umami:card'
  props:
    html_tag: 'div'
  slots:
    content: 'Hello from third grid card!'

How It Works in Practice

The addon dynamically renders the components and stories as defined:

  • Basic Args: The default Basic.args of the umami:card component are used.
  • Existing Story: The Preview story is loaded, ensuring consistency across the Storybook environment.
  • Custom Slots and Props: Overrides the default slots and props behavior with unique content for that instance.

Why stories experimental?

The community will have to decide what format the YAML stories should be.

Regular storybook

All storybook functions work as usual and you can import SDC YAML into .stories.js

example

import header, {
  Preview as HeaderPreview,
} from '../components/header/header.component.yml'
import banner, {
  Preview as BannerPreview,
} from '../components/banner/banner.component.yml'

export default {
  title: 'Regular Storybook Page',
  render: () => {
    return `
      ${header.component({ ...HeaderPreview.args })}
      ${banner.component({ ...BannerPreview.args })}
    `
  },
  play: async ({ canvasElement }) => {
    Drupal.attachBehaviors(canvasElement, window.drupalSettings)
  },
}

export const Basic = {}

Dependencies

Known Issues

  • $ref: json-schema-definitions:// for SDC from Experience Builder is unsupported.
  • The addon relies on Experimental indexers.

UI Patterns