doc/development/fe_guide/storybook.md
The Storybook for the gitlab-org/gitlab project is available on our GitLab Pages site.
Storybook dependencies and configuration are located under the storybook/ directory.
To build and launch Storybook locally, in the root directory of the gitlab project:
Install Storybook dependencies:
yarn storybook:install
Build the Storybook site:
yarn storybook:start
Test Storybook entries:
yarn storybook:dev:test
Discover more details about automated accessibility tests with Accessibility Storybook tests.
Stories can be added for any Vue component in the gitlab repository.
To add a story:
Create a new .stories.js file in the same directory as the Vue component.
The filename should have the same prefix as the Vue component.
vue_shared/
├─ components/
│ ├─ sidebar
│ | ├─ todo_toggle
│ | | ├─ todo_button.vue
│ │ | ├─ todo_button.stories.js
Stories should demonstrate each significantly different UI state related to the component's exposed props and events.
For instructions on how to write stories, refer to the official Storybook instructions
[!note] Specify the
titlefield of the story as the component's file path from thejavascripts/directory, without the/componentspart. For example, if the component is located atapp/assets/javascripts/vue_shared/components/sidebar/todo_toggle/todo_button.vue, specify the storytitleasvue_shared/sidebar/todo_toggle/todo_button. If the component is located in theee/directory, make sure to prefix the story's title withee/as well. This will ensure the Storybook navigation maps closely to our internal directory structure.
You can write stories for components that use either the GitLab REST or GraphQL APIs.
To add a story with API access:
Create a personal access token in your GitLab instance.
[!note] If you test against
gitlab.com, make sure to use a token withread_apiif possible and to make the token short-lived.
Create an .env file in the storybook directory. Use the storybook/.env.template file as
a starting point.
Set the API_ACCESS_TOKEN variable to the access token that you created.
Set the GITLAB_URL variable to the GitLab instance's domain URL, for example: http://gdk.test:3000.
Start or restart your storybook.
You can also use the GitLab API Access panel in the Storybook UI to set the GitLab instance URL and access token.
You should apply the withGitLabAPIAccess decorator to the stories that will consume GitLab APIs. This decorator
will display a badge indicating that the story won't work without providing the API access parameters:
import { withGitLabAPIAccess } from 'storybook_addons/gitlab_api_access';
import Api from '~/api';
import { ContentEditor } from './index';
export default {
component: ContentEditor,
title: 'ce/content_editor/content_editor',
decorators: [withGitLabAPIAccess],
};
The Storybook sets up ~/lib/utils/axios_utils in storybook/config/preview.js. Components that use the REST API
should work out of the box as long as you provide a valid GitLab instance URL and access token.
To write a story for a component that uses the GraphQL API, use the createVueApollo method provided in
the Story context.
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { withGitLabAPIAccess } from 'storybook_addons/gitlab_api_access';
import WorkspacesList from './list.vue';
Vue.use(VueApollo);
const Template = (_, { argTypes, createVueApollo }) => {
return {
components: { WorkspacesList },
apolloProvider: createVueApollo(),
provide: {
emptyStateSvgPath: '',
},
props: Object.keys(argTypes),
template: '<workspaces-list />',
};
};
export default {
component: WorkspacesList,
title: 'ee/workspaces/workspaces_list',
decorators: [withGitLabAPIAccess],
};
export const Default = Template.bind({});
Default.args = {};
To write a story for a component that requires access to a Vuex store, use the createVuexStore method provided in
the Story context.
import { withVuexStore } from 'storybook_addons/vuex_store';
import DurationChart from './duration-chart.vue';
const Template = (_, { argTypes, createVuexStore }) => {
return {
components: { DurationChart },
store: createVuexStore({
state: {},
getters: {},
modules: {},
}),
props: Object.keys(argTypes),
template: '<duration-chart />',
};
};
export default {
component: DurationChart,
title: 'ee/analytics/cycle_analytics/components/duration_chart',
decorators: [withVuexStore],
};
export const Default = Template.bind({});
Default.args = {};