Skip to content

Commit

Permalink
Upgrade Storybook, set up a11y addon, and wrap stories in an extra de…
Browse files Browse the repository at this point in the history
…corator that re-runs tests if an empty result is returned; associated config updates
  • Loading branch information
doubleedesign committed Aug 18, 2024
1 parent 82ab65c commit 3a421dd
Show file tree
Hide file tree
Showing 12 changed files with 3,116 additions and 4,125 deletions.
79 changes: 79 additions & 0 deletions .eslintrc.base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"root": true,
"env": {
"browser": true,
"es2020": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest"
},
"plugins": [
"@typescript-eslint",
"react-refresh"
],
"rules": {
"storybook/default-exports": "off",
"indent": ["error", "tab", {
"SwitchCase": 2,
"FunctionExpression": {
"parameters": 1,
"body": 1
},
"MemberExpression": 1,
"offsetTernaryExpressions": true
}],
"quotes": [
"warn",
"single"
],
"semi": [
"warn",
"always"
],
"brace-style": [1, "stroustrup", {
"allowSingleLine": false
}],
"object-curly-spacing": [
"error",
"always"
],
"space-in-parens": 0,
"array-bracket-spacing": 0,
"computed-property-spacing": "off",
"space-before-function-paren": "off",
"no-nested-ternary": "off",
"space-unary-ops": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": "warn",
"react-refresh/only-export-components": [
"warn",
{
"allowConstantExport": true
}
]
},
"overrides": [
{
"files": ["*.style.ts"],
"rules": {
"indent": ["warn", "tab", {
"SwitchCase": 1,
"FunctionExpression": {
"parameters": 1,
"body": 1
},
"MemberExpression": 1,
"offsetTernaryExpressions": true
}]
}
}
]
}
81 changes: 11 additions & 70 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,85 +1,26 @@
{
"root": true,
"root": false,
"env": {
"browser": true,
"es2020": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
"plugin:storybook/recommended"
".eslintrc.base.json"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest"
},
"plugins": [
"@typescript-eslint",
"react-refresh",
"project-structure"
],
"settings": {
"project-structure/config-path": "project-structure.json"
},
"ignorePatterns": [
"node_modules/",
"dist/",
"build/",
"storybook-static/",
".storybook"
],
"rules": {
"project-structure/file-structure": "error",
"storybook/default-exports": "off",
"indent": ["error", "tab", {
"SwitchCase": 2,
"FunctionExpression": {
"parameters": 1,
"body": 1
},
"MemberExpression": 1,
"offsetTernaryExpressions": true
}],
"quotes": [
"warn",
"single"
],
"semi": [
"warn",
"always"
],
"brace-style": [1, "stroustrup", {
"allowSingleLine": false
}],
"object-curly-spacing": [
"error",
"always"
],
"space-in-parens": 0,
"array-bracket-spacing": 0,
"computed-property-spacing": "off",
"space-before-function-paren": "off",
"no-nested-ternary": "off",
"space-unary-ops": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": "warn",
"react-refresh/only-export-components": [
"warn",
{
"allowConstantExport": true
}
]
},
"overrides": [
{
"files": ["*.style.ts"],
"rules": {
"indent": ["warn", "tab", {
"SwitchCase": 1,
"FunctionExpression": {
"parameters": 1,
"body": 1
},
"MemberExpression": 1,
"offsetTernaryExpressions": true
}]
}
}
]
"project-structure/file-structure": "error"
}
}
7 changes: 7 additions & 0 deletions .storybook/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"root": true,
"extends": [
"../.eslintrc.base.json",
"plugin:storybook/recommended"
]
}
38 changes: 38 additions & 0 deletions .storybook/decorators/a11y.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { addons } from '@storybook/preview-api';
import { STORY_RENDERED } from '@storybook/core-events';
import { ElementType, useCallback, useEffect } from 'react';
import { StoryContext } from '@storybook/react';

type MinimalContextData = {
story: string;
theme: string;
}
const A11Y_RESULT = 'storybook/a11y/result';
const A11Y_REQUEST = 'storybook/a11y/request';
const A11Y_RUNNING = 'storybook/a11y/running';
const A11Y_ERROR = 'storybook/a11y/error';
const A11Y_MANUAL = 'storybook/a11y/manual';
const A11Y_RUN = 'storybook/a11y/run';

export const WithA11yTests = (Story: ElementType, context: StoryContext) => {
const channel = addons.getChannel();

useEffect(() => {
// If the result comes back empty, re-run the tests
// This is a workaround for what seems to be a timing issue/race condition when changing the selected story
const checkAndHandleResult = (data: any) => {
if(data.passes.length === 0 && data.violations.length === 0 && data.incomplete.length === 0) {
channel.emit(A11Y_MANUAL, { storyId: context.id });
}
};

channel.on('storybook/a11y/result', checkAndHandleResult);

// Cleanup function that runs on unmount
return () => {
channel.off('storybook/a11y/result', checkAndHandleResult);
};
}, [channel, context.id]);

return <Story {...context} />;
};
2 changes: 2 additions & 0 deletions .storybook/decorators/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { WithTheme } from './theme';
export { WithA11yTests } from './a11y';
11 changes: 11 additions & 0 deletions .storybook/decorators/theme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ElementType } from 'react';
import { RedbackUiThemeProvider, themes } from '../../src';
import { StoryContext } from '@storybook/react';

export const WithTheme = (Story: ElementType, context: StoryContext) => {
return (
<RedbackUiThemeProvider theme={themes[context.globals.theme]}>
<Story />
</RedbackUiThemeProvider>
);
};
44 changes: 28 additions & 16 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,59 @@
import {type StorybookConfig } from '@storybook/react-vite';
import { mergeConfig } from "vite";
import { type StorybookConfig } from '@storybook/react-vite';
import { HttpProxy, mergeConfig } from 'vite';
import * as path from 'node:path';
import ServerOptions = HttpProxy.ServerOptions;

const isProduction = process.env.NODE_ENV === 'production';

const config: StorybookConfig = {
core: {
builder: '@storybook/builder-vite',
},
env: (config) => ({
...config,
STORYBOOK_BASE_URL: isProduction ? 'https://redback-operations.github.io/redback-ui' : 'http://localhost:6006',
}),
async viteFinal(config, { configType }) {
if (!config.optimizeDeps) {
config.optimizeDeps = { include: [] };
}
config.optimizeDeps.include.push('polished');

async viteFinal(config, { configType }) {
if(configType === 'PRODUCTION') {
config.server = mergeConfig(config.server, {
config.server = mergeConfig(<ServerOptions>config.server, {
mimeTypes: {
'ts': 'text/javascript'
}
});
}

return config;
return {
...config,
cacheDir: path.resolve(__dirname, '../node_modules/.cache/vite'),
optimizeDeps: {
...config.optimizeDeps,
include: [
...(config?.optimizeDeps?.include ?? []),
'polished',
'@storybook/addons',
'axe-core',
'@storybook/addon-a11y'
]
}
};
},
staticDirs: ['../public', {from: '../src/themes', to: 'themes'}],
staticDirs: ['../public', { from: '../src/themes', to: 'themes' }],
stories: ['../src/**/*.stories.@(ts|tsx)', '../docs/**/*.mdx'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-docs',
'storybook-dark-mode'
'@storybook/addon-a11y',
'storybook-dark-mode',
'@storybook/addon-mdx-gfm'
],
framework: {
name: '@storybook/react-vite',
options: {}
},
docs: {
autodocs: true,
defaultName: 'Docs',
defaultName: 'Docs'
},
typescript: {
reactDocgen: 'react-docgen-typescript'
}
};

export default config;
26 changes: 19 additions & 7 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Preview } from '@storybook/react';
import { Title, Subtitle, Description, Primary, Controls, Stories, DocsContainer, Unstyled } from '@storybook/blocks';
import { RedbackUiThemeProvider } from '../src/providers/RedbackUiThemeProvider/RedbackUiThemeProvider';
import { themes } from '../src/themes';
import { WithA11yTests, WithTheme } from './decorators';

const preview: Preview = {
globalTypes: {
Expand All @@ -19,17 +20,26 @@ const preview: Preview = {
},
},
decorators: [
(Story, context) => {
return (
<RedbackUiThemeProvider theme={themes[context.globals.theme]}>
<Story />
</RedbackUiThemeProvider>
);
}
WithTheme,
WithA11yTests,
],
parameters: {
layout: 'centered',
backgrounds: { disable: true },
a11y: {
element: '#storybook-root',
// axe-core configurationOptions (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#parameters-1)
config: {
// Rules to specifically turn on/off (these are not the only rules that will run, many are by default or associated with the tags in `options`)
// https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md
rules: [
{ id: 'color-contrast', enabled: true },
],
},
// axe-core optionsParameter (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter)
options: {
},
},
options: {
storySort: (a, b) => {
const pageOrder = ['About', 'Usage', 'Contributing'];
Expand Down Expand Up @@ -76,6 +86,8 @@ const preview: Preview = {
),
},
},

tags: ['autodocs']
};

export default preview;
Loading

0 comments on commit 3a421dd

Please sign in to comment.