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.
- Overview
- Storybook Example Live
- Features of the Addon
- Why Choose SDC Storybook Over Alternatives?
- Quickstart Guide
- Configuration
- Setting Default Values
- Creating Experimental Stories
- Regular Storybook
- Configuration Options
- Dependencies
- Known Issues
- UI Patterns
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).
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.
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. - Custom and External Schema Definitions: Supports custom and external JSON schema definitions to validate components based on Drupal-specific configurations (e.g., UI Patterns, Experience Builder).
While solutions like SDC Styleguide and Drupal Storybook are valuable, the SDC Storybook addon offers distinct advantages:
- 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.
- 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.
- 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.
- 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.
- 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.
- Embed Drupal behaviors (like
Drupal.attachBehaviors()
) directly into Storybook previews, ensuring consistent component behavior between Storybook and production. - Supports
drupalSettings
andonce.js
, so components in Storybook behave identically to their Drupal counterparts.
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.
-
In theme or module or just empty directory (If package.json not yet exists):
npm init echo "node_modules/" >> .gitignore
-
Install dependencies:
npm i vite twig storybook-addon-sdc --save-dev
-
Initialize Storybook:
npx storybook@latest init --builder vite --type html --no-dev
-
Remove default storybook boilerplate stories (Optional):
rm -rf ./stories
-
Configure as described in Configuration.
-
Add components to the
components
directory (or copy from this repository). -
Start Storybook:
npm run storybook
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
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:
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:
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!'
The addon dynamically renders the components and stories as defined:
- Basic Args: The default
Basic.args
of theumami: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.
The community will have to decide what format the YAML stories should be.
All storybook functions work as usual and you can import SDC YAML into .stories.js
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 = {}
In addition to the standard configuration options, you can also specify customDefs and externalDefs to provide additional schema definitions. These options are optional and can be used to extend or override the default definitions.
The customDefs
option allows you to define custom schema definitions directly within your configuration. This can be object with custom definitions.
Example:
const options = {
sdcStorybookOptions: {
customDefs: {
'json-schema-definitions://experience_builder.module/column-width': {
title: 'Column Width',
type: 'integer',
enum: [25, 33, 50],
},
},
},
}
The externalDefs
option allows you to specify an array of paths to external definition files. These paths can be URLs to CDN-hosted files or local file paths.
Example:
const options = {
sdcStorybookOptions: {
externalDefs: [
'https://cdn.jsdelivr.net/gh/iberdinsky-skilld/[email protected]/drupal-defs/uiPatternsSchema.yml',
'https://example.com/path/to/definitions.yml',
'./local/path/to/definitions.yml',
],
},
}
When using externalDefs, the definitions will be fetched and registered automatically.
The validate
option enables schema validation for SDC components using the JSON Schema validator. By default, the validator checks the component configurations against the global schema located at:
$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
-
Global Schema Validation (Default): The addon uses the default global schema for validation. This schema is provided by Drupal and ensures that SDC components conform to the expected structure with the correct data types and properties.
-
Custom Component Schema: If a specific SDC component includes its own
$schema
field pointing to a custom schema, the validator will use that schema for validation instead of the global one. This allows for more flexibility and component-specific validation, especially when components have custom requirements. -
Validation Warnings: Validation errors or warnings are logged to the console, helping developers identify any issues with component configurations. Note: Validation will not break the rendering of the components. Even if a validation error occurs, the component will still appear in Storybook, and the warning will be logged for review.
To disable validation, set validate: false
:
const config = {
stories: ['../components/**/*.component.yml'],
addons: [
{
name: 'storybook-addon-sdc',
options: {
sdcStorybookOptions: {
validate: false, // Disable schema validation
},
},
},
],
}
- vite-plugin-twig-drupal: Loads Twig with Drupal functions.
- json-schema-faker: Generates mock data for missing props and
- JSON Schema validator
- The addon relies on Experimental indexers.
- Variants partially supported (Issue 3390712).
- Custom Twig filters and functions are not supported (UI Patterns TwigExtension).