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.
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:
While solutions like SDC Styleguide and Drupal Storybook are valuable, the SDC Storybook addon offers distinct advantages:
Drupal.attachBehaviors()
) directly into Storybook previews, ensuring consistent component behavior between Storybook and production.drupalSettings
and once.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:
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!'
This configuration provides three distinct options for creating stories:
grid
example uses only its basic arguments (Basic.args
). No additional configuration or props are required for this component.- type: component
component: 'umami:card'
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
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!'
The addon dynamically renders the components and stories as defined:
Basic.args
of the umami:card
component are used.Preview
story is loaded, ensuring consistency across the Storybook environment.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 = {}
$ref: json-schema-definitions://
for SDC from Experience Builder is unsupported.