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

@shopware-ag/storybook-addon-shopware

v1.0.0

Published

Shopware addon for Storybook

Downloads

1

Readme

Storybook addon for Shopware

The addon provides helpers and loaders to integrate the Shopware 6 administration with Storybook. It contains multiple parts - a loader, an addon panel and a renderer.

The loader is based on VueDocgenApi which is a toolkit to extract informations like events, slots, methods, properties etc. from Vue components. The loader itself transforms the JavaScript files from Shopware in export default to work together with VueDocgenApi.

The provided renderer allows to easily create stories in Storybook using Shopware components. It covers all the necessary parts to write efficent documentation without the need of any boilerplate code.

Last but not least the addon comes with an addon panel which displays the source code of all available Twig blocks inside a component. This way you'll find exactly the part of the code you want to override in your code to provide additional functionality.

The renderer

The renderer is the heart of the addon. It provides methods to create a default story, provide additional stories for the different variants of a component and allows to easily customize the template used for the story itself.

How to use the renderer

The renderer can easily be imported in your story using the following code snippet:

import { getRenderer } from '@shopware-ag/storybook-addon-shopware/renderer';

The function getRenderer accepts a configuration object for the component:

| Option | Description | Optional | |---|---|---| | title | Provides the name and the navigation structure of the component | ❌ | | component | Main Vue.js component for all story variants within the story file | ❌ | | additionalComponents | Additional Vue.js components which are used within the main Vue.js component. If the main component extends another component, please provide it here. | ✅ | | template | Template literal with the HTML markup to render the story. Default: <[component-name] v-bind="$props"></[component-name]> | ✅ | | figmaUrl | URL to a figma design which will be displayed in the Design tab | ✅ |

The method getRenderer returns an object with the following methods:

| Method | Description | Arguments | |--------|--------------|--- | getDefaultStory() | Provides the default story which is mandatory in Storybook. | none | getStory() | Provides the story which gets displayed to the user and shows of a certain variant / combination of properties of the component. | args - Preconfigured properties of the componenttemplate - a different template for the component. Useful to document slots and their behavior | | getTemplate() | Returns the configured template instance from the method getRenderer| none | | getCustomTemplate() | Helper method which provides a template instance to use as the second argument of the method getStory() | template - template literal of the template |

The following example shows the minimal set of arguments provided to method getRenderer():

import { getRenderer } from '@shopware-ag/storybook-addon-shopware/renderer';
import Icon from 'src/app/component/base/sw-icon';

const { getDefaultStory, getStory } = getRenderer({
    title: 'Basic / sw-icon',
    component: Icon,
});

Writing stories

First and foremost Storybook requires an export default with a default story. The default story needs to contain the title of the story, the necessary component as well as additional components if necessary. We can use the method getDefaultStory which is getting returned from getRenderer to provide the default story:

export default getDefaultStory();

Next up we can write the stories using the getStory method. The easiest way to use the method is export a named constant and provide the return value from getStory() as the value:

export const Default = getStory();

Usually this isn't quite enough, we would like to provide preconfigured properties which we can provide as the first argument of the method:

export const Default = getStory({
    name: 'default-chart-sales',
    color: '#4DC6E9',
});

Storybook recommends the use of UpperCamelCase for your story exports. For example VerticalTabs will be rendered as Virtual Tabs in the navigation structure.

Writing multiple stories

When we're writing multiple stories for a component we usually want to re-use configured properties of a previous story and just add new properties or modify existing properties here. This can be easiliy done using the rest operator in JavaScript.

export const Color = getStory({
    color: '#A092F0',
    firstName: 'John',
    lastName: 'Doe',
    size: '48px',
});

export const Square = getStory({ ...Color.args, ...{ variant: 'square' } });

export const Image = getStory({ ...Color.args,
...{
    imageUrl: 'https://randomuser.me/api/portraits/women/68.jpg',
} });

Using a custom template

Vue.js is heavily relying on slots for content distribution. Using the method getCustomTemplate() we can provide a custom template:

import { getRenderer } from '@shopware-ag/storybook-addon-shopware/renderer';

import Icon from 'src/app/component/base/sw-icon';
import Button from 'src/app/component/base/sw-button';
import EmptyState from 'src/app/component/base/sw-empty-state';

const { getDefaultStory, getStory, getCustomTemplate } = getRenderer({
    title: 'Basic / sw-empty-state',
    component: EmptyState,
    additionalComponents: [
        Icon,
        Button,
    ],
});

export default getDefaultStory();

export const Default = getStory({
    color: '#F88962',
    title: 'No experiment found',
    subline: `Lorem ipsum dolor sit amet, consectetur adipisicing elit. Atque consequatur consequuntur debitis dolore 
            dolorum earum exercitationem expedita ipsam iste iusto officia, officiis quae ratione recusandae reiciendis.
            Earum, ipsam, rerum? Earum.`,
    icon: 'default-object-lab-flask',
    emptyModule: true,
});

export const AdditionalActionButtons = getStory({ ...Default.args, ...{ color: '#57D9A3' } }, getCustomTemplate(`
    <sw-empty-state v-bind="$props">
        <template #actions>
            <sw-button>Click me!</sw-button>
        </template>    
    </sw-empty-state>
`));

Using automatic property bindings in template literals:

When you're writing a template to use within a story you can use the power of VueDocgenApi. Provide the markup the way you want and just make sure you're providing the automatic property bindings using v-bind like in the following example:

<sw-button v-bind="$props"></sw-button>

Providing additional controls which are not defined in a component

Additionally it's possible to provide additional controls for your story to customize the behavior of the component even more. In the following example we're providing an additional control called content which is filling the default slot of the sw-card component:

const { getDefaultStory, getStory } = getRenderer({
    title: 'Basic / sw-card',
    component: Card,
    additionalComponents: [
        Loader,
    ],
    template: `<sw-card v-bind="$props">{{ content }}</sw-card>`,
});

export default getDefaultStory();

export const CardWithTitle = getStory({
    title: 'Example card',
    content: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aliquam asperiores aut consectetur cum cumque'
});