diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000000..00f1703c04 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,42 @@ +import sharedConfig from '../webpack/shared'; + +import type { StorybookConfig } from '@storybook/core-common'; + +const config: StorybookConfig = { + stories: [ + '../stories/**/*.stories.mdx', + '../stories/**/*.stories.@(js|jsx|ts|tsx)' + ], + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-interactions', + { + name: '@storybook/addon-postcss', + options: { + postcssLoaderOptions: { + implementation: require('postcss'), + }, + }, + }, + ], + framework: '@storybook/react', + core: { + builder: '@storybook/builder-webpack5', + }, + webpackFinal: async (config) => { + config.resolve!.alias = { + ...sharedConfig.resolve!.alias, + ...config.resolve!.alias, + }; + + config.resolve!.modules = [ + ...sharedConfig.resolve!.modules!, + ...config.resolve!.modules!, + ]; + + return config; + }, +}; + +export default config; \ No newline at end of file diff --git a/.storybook/preview.ts b/.storybook/preview.ts new file mode 100644 index 0000000000..c876c5abf9 --- /dev/null +++ b/.storybook/preview.ts @@ -0,0 +1,12 @@ +import '../app/styles/tailwind.css'; +import '../stories/theme.css'; + +export const parameters = { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +} \ No newline at end of file diff --git a/app/soapbox/components/ui/button/button.tsx b/app/soapbox/components/ui/button/button.tsx index 8847f9c58b..43805eee2b 100644 --- a/app/soapbox/components/ui/button/button.tsx +++ b/app/soapbox/components/ui/button/button.tsx @@ -100,4 +100,7 @@ const Button = React.forwardRef((props, ref): JSX.El return renderButton(); }); -export default Button; +export { + Button as default, + Button, +}; diff --git a/package.json b/package.json index 86290ccbf5..4ff197e2f2 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,9 @@ "lint": "${npm_execpath} run lint:js && ${npm_execpath} run lint:sass", "lint:js": "npx eslint --ext .js,.jsx,.cjs,.mjs,.ts,.tsx . --cache", "lint:sass": "npx stylelint app/styles/**/*.scss", - "prepare": "husky install" + "prepare": "husky install", + "storybook": "start-storybook -p 6006", + "build-storybook": "build-storybook" }, "license": "AGPL-3.0-or-later", "browserslist": [ @@ -194,6 +196,15 @@ "@gitbeaker/node": "^35.8.0", "@jedmao/redux-mock-store": "^3.0.5", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", + "@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/addon-postcss": "^2.0.0", + "@storybook/builder-webpack5": "^6.5.16", + "@storybook/manager-webpack5": "^6.5.16", + "@storybook/react": "^6.5.16", + "@storybook/testing-library": "^0.0.13", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "^14.0.3", diff --git a/stories/Button.stories.tsx b/stories/Button.stories.tsx new file mode 100644 index 0000000000..796d17e96a --- /dev/null +++ b/stories/Button.stories.tsx @@ -0,0 +1,48 @@ +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import React from 'react'; + +import { Button } from 'soapbox/components/ui'; + +// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +export default { + title: 'UI/Button', + component: Button, + // More on argTypes: https://storybook.js.org/docs/react/api/argtypes + argTypes: { + text: { type: 'string', defaultValue: 'Button' }, + theme: { defaultValue: 'primary' }, + size: { defaultValue: 'md' }, + disabled: { defaultValue: false }, + block: { defaultValue: false }, + children: { table: { disable: true } }, + className: { table: { disable: true } }, + type: { table: { disable: true } }, + to: { table: { disable: true } }, + icon: { table: { disable: true } }, + onClick: { table: { disable: true } }, + }, +} as ComponentMeta; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +const Template: ComponentStory = (args) =>