Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experience 8346: Add configuration for local instance of Storybook #8803

Merged
merged 1 commit into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend-react/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
"plugin:import/recommended",
"plugin:import/typescript",
"prettier",
"plugin:storybook/recommended",
],
plugins: ["testing-library", "unused-imports", "jest-dom", "prettier"],
env: {
Expand Down
22 changes: 22 additions & 0 deletions frontend-react/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = {
stories: [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)",
],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-a11y",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for later, but this might be a really nice package to see the states of different components without the need of dev tools: https://storybook.js.org/addons/storybook-addon-pseudo-states

],
framework: "@storybook/react",
core: {
builder: "@storybook/builder-webpack5",
},
refs: {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows for composition with other/external Storybooks. Everything's still going through network requests so browsing external stories won't be as snappy as our own, but it's still nice to have everything in one place.

trussworks: {
title: "Trussworks Storybook",
url: "https://trussworks.github.io/react-uswds/",
},
},
};
59 changes: 59 additions & 0 deletions frontend-react/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { initializeWorker, mswDecorator } from "msw-storybook-addon";
import { CacheProvider } from "rest-hooks";
import { BrowserRouter } from "react-router-dom";
import { HelmetProvider } from "react-helmet-async";
import MockDate from "mockdate";

import "../src/content/generated/global.out.css";

// mock all dates in stories to make sure we don't run into date-related inconsistencies
MockDate.set("2023-01-01");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This'd be especially useful if we start using snapshots with Chromatic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious how this will interact with faker.js if we end up using it but something to worry about later.


export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are included by default on installation, but they're useful!

color: /(background|color)$/i,
date: /Date$/,
},
},
options: {
storySort: {
method: "alphabetical",
order: [],
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the order should be yet since our component system is still in a limbo state.

},
},
};

initializeWorker();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSW isn't hooked up yet, but we might as well get it started 馃し


function withRestHooksCacheProvider(Story) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add an all-in-one HOC like we do in tests, but I figure the granularity might be good. Not really an issue either way, though!

return (
<CacheProvider>
<Story />
</CacheProvider>
);
}

function withRouter(Story) {
return (
<BrowserRouter>
<Story />
</BrowserRouter>
);
}

function withHelmet(Story) {
return (
<HelmetProvider>
<Story />
</HelmetProvider>
);
}

export const decorators = [
withHelmet,
withRouter,
withRestHooksCacheProvider,
mswDecorator,
];
22 changes: 21 additions & 1 deletion frontend-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@
"lint:eslint": "cross-env NODE_ENV=production eslint \"src/**/*.{js,ts,jsx,tsx}\"",
"lint:eslint:write": "cross-env NODE_ENV=production eslint --fix \"src/**/*.{js,ts,jsx,tsx}\"",
"yarn:show-outdated-packages": "yarn outdated",
"run-build-dir": "yarn build:localdev:csp && yarn global add serve && serve -s build"
"run-build-dir": "yarn build:localdev:csp && yarn global add serve && serve -s build",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"browserslist": {
"production": [
Expand All @@ -102,6 +104,20 @@
"@jest/globals": "^29.5.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@rest-hooks/test": "^7.3.1",
"@storybook/addon-a11y": "^6.5.16",
"@storybook/addon-actions": "^6.5.16",
"@storybook/addon-essentials": "^6.5.16",
"@storybook/addon-interactions": "^6.5.16",
"@storybook/addon-links": "^6.5.16",
"@storybook/addons": "^6.5.16",
"@storybook/api": "^6.5.16",
"@storybook/builder-webpack5": "^6.5.16",
"@storybook/components": "^6.5.16",
"@storybook/core-events": "^6.5.16",
"@storybook/manager-webpack5": "^6.5.16",
"@storybook/react": "^6.5.16",
"@storybook/testing-library": "^0.0.13",
"@storybook/theming": "^6.5.16",
"@svgr/webpack": "^6.5.1",
"@testing-library/cypress": "^9.0.0",
"@testing-library/dom": "^9.0.0",
Expand Down Expand Up @@ -147,6 +163,7 @@
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-jest-dom": "^4.0.3",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-storybook": "^0.6.11",
"eslint-plugin-testing-library": "^5.10.2",
"eslint-plugin-unused-imports": "2.0.0",
"eslint-webpack-plugin": "^4.0.0",
Expand All @@ -160,7 +177,9 @@
"jest-watch-typeahead": "^2.2.2",
"loader-utils": "3.2.1",
"mini-css-extract-plugin": "^2.7.5",
"mockdate": "^3.0.5",
"msw": "^1.1.0",
"msw-storybook-addon": "^1.8.0",
"npm-run-all": "^4.1.5",
"otplib": "^12.0.1",
"postcss": "^8.4.21",
Expand All @@ -181,6 +200,7 @@
"sass-loader": "^13.2.1",
"semver": "^7.3.8",
"source-map-loader": "^4.0.1",
"storybook-addon-react-router-v6": "^0.3.1",
"style-loader": "^3.3.1",
"tailwindcss": "^3.2.7",
"terser-webpack-plugin": "^5.3.6",
Expand Down
27 changes: 27 additions & 0 deletions frontend-react/src/components/StaticAlert.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { ComponentMeta, ComponentStory } from "@storybook/react";

import { StaticAlert, StaticAlertType } from "./StaticAlert";

export default {
title: "components/StaticAlert",
component: StaticAlert,
argTypes: {
type: {
control: {
type: "radio",
options: Object.values(StaticAlertType),
},
},
},
} as ComponentMeta<typeof StaticAlert>;

export const Default: ComponentStory<typeof StaticAlert> = (args) => (
<StaticAlert {...args} />
);
Default.args = {
type: StaticAlertType.Success,
heading: "StaticAlert Heading",
message: "This is the message of the StaticAlert",
children: "Children are optional! (Try clearing me out)",
};
50 changes: 50 additions & 0 deletions frontend-react/src/components/USLink.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react";
import { ComponentMeta, ComponentStory } from "@storybook/react";

import { USExtLink, USLink, USLinkButton } from "./USLink";

export default {
title: "components/USLink",
component: USLink,
} as ComponentMeta<typeof USLink>;

export const Default: ComponentStory<typeof USLink> = (args) => (
<USLink {...args} />
);
Default.args = {
className: "",
children: "This is a link",
};

export const Button: ComponentStory<typeof USLinkButton> = (args) => (
<USLinkButton {...args} />
);
Button.args = {
children: "This is a link styled as a button",
secondary: false,
base: false,
inverse: false,
unstyled: false,
};
Button.argTypes = {
accentStyle: {
control: {
type: "radio",
options: ["", "cool", "warm"],
},
},
size: {
control: {
type: "radio",
options: ["", "big"],
},
},
};

export const ExtLink: ComponentStory<typeof USExtLink> = (args) => (
<USExtLink {...args} />
);
ExtLink.args = {
className: "",
children: "This is an external link",
};