@ergosign/storybook-addon-pseudo-states-vue
v0.0.1-alpha.61
Published
Storybook decorator to enable automatic generation and displaying of CSS pseudo states for components.
Downloads
82
Readme
Storybook Addon Pseudo States for Vue
This storybook addon allows you to automatically display pseudo states (and attribute states) of a component in Storybook's preview area.
Framework support
| Framework | Display States | Tool-Button to show/hide | | --------- | :------------: | :----------------------: | | Angular | + | + | | React | + | + | | Lit | + | + | | HTML | + | + | | Vue | + | + |
Getting started
First, add the addon to your project as a dev dependency:
npm install @ergosign/storybook-addon-pseudo-states-vue --save-dev
Next, enable it by adding it as an addon to .storybook/main.js
, e.g.
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@ergosign/storybook-addon-pseudo-states-vue',
],
};
Since there's no way to force an element to appear with a specific pseudo state, the addon relies on specific classes to simulate the state. The Styling section explains how to generate them.
Once that's done, you can add the decorator to a story, as explained in Usage.
Styling
The recommended approach is to generate classes from your pseudo state CSS rules automatically. The easiest way is to use the postcss-pseudo-classes PostCSS plugin.
npm i -D postcss-pseudo-classes
Then add it to your postcss.config.js
:
module.exports = {
plugins: [require('postcss-pseudo-classes')],
};
postcss-pseudo-classes
extracts all pseudo states from your styling and creates a class for each of them by adding a prefix, e.g. button:hover {}
becomes button.\:hover {}
. The default prefix is \:
, and storybook-addon-pseudo-states-vue
is configured to work with that configuration. If you need a different prefix, pass it to the plugin options:
module.exports = {
plugins: {
'postcss-pseudo-classes': {
prefix: 'pseudoclass--',
},
},
};
And update your story config accordingly (more on configuring stories below):
{
parameters: {
withPseudo: {
selector: "element",
prefix: "pseudoclass--"
},
},
};
If you're unsure about how to set up PostCSS, you can check out the Vue CLI or PostCSS docs.
Manually
Alternatively, you can code the pseudo state classes manually. The naming pattern is prefix
+ pseudostate
. With the default \:
prefix, it would look something like this:
.element {
// ...
&:hover,
&\:hover {
// hover styling
}
&:focus,
&\:focus {
// focus styling
}
}
Show/hide toolbar button
You can enable a toolbar button that toggles the pseudo states in the preview area. See framework support for information on which frameworks support this feature.
Enable the button by adding it to your .storybook/main.js
file:
module.exports = {
addons: ['@ergosign/storybook-addon-pseudo-states-vue'],
};
Usage
⚠️
withPseudo
should always come first in yourdecorators
array because it alters the template of the story.
General
Component Story Format (CSF, recommended)
import { withPseudo } from '@ergosign/storybook-addon-pseudo-states-vue';
const section = {
title: 'Button',
decorators: [withPseudo],
parameters: {
withPseudo: { selector: 'button' },
},
};
export default section;
export const Story = () => {
return {
component: ButtonComponent,
};
};
storyOf Format
import { withPseudo } from '@ergosign/storybook-addon-pseudo-states-vue';
storiesOf('Button', module)
.addDecorator(withPseudo)
.addParameters({
withPseudo: {
selector: 'button', // css selector of pseudo state's host element
pseudo: ['focus', 'hover', 'hover & focus', 'active'],
attributes: ['disabled', 'readonly', 'error'],
},
})
.add('Icon Button', () => <Button />);
There is a default configuration for selector
, pseudos
and attributes
. Thus, you can leave withPseudo
options empty.
With Vue
import { withPseudo } from '@ergosign/storybook-addon-pseudo-states-vue';
import { PseudoStateOrderDefault } from '@ergosign/storybook-addon-pseudo-states-vue/dist/share/types';
import SimpleButton from '../components/SimpleButton.vue';
export default {
title: 'Simple Button',
decorators: [withPseudo],
parameters: {
withPseudo: {
pseudo: PseudoStateOrderDefault,
attributes: ['disabled', { attr: 'appearance', value: 'primary' }],
},
},
argTypes: {
appearance: {
control: false,
},
},
};
const template = (args, { argTypes }) => ({
components: { SimpleButton },
props: Object.keys(argTypes),
template: '<simple-button :label="label" :disabled="disabled" />',
});
export const PseudoStates = template.bind({});
PseudoStates.args = {
label: 'Hello World',
disabled: false,
appearance: false,
};
Parameters & Types
See types.ts
Known limitations
- Vue 2.x support/not tested with Vue 3
- Broken in docs view