add storybook
This commit is contained in:
+15
-4
@@ -8,11 +8,22 @@
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:storybook/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"comma-dangle": 0,
|
||||
"max-len": ["error", { "code": 100 }],
|
||||
"max-len": [
|
||||
"error",
|
||||
{
|
||||
"code": 100
|
||||
}
|
||||
],
|
||||
"no-unused-vars": "off",
|
||||
"no-unexpected-multiline": "warn",
|
||||
"prefer-const": "warn",
|
||||
@@ -29,4 +40,4 @@
|
||||
"jest": true,
|
||||
"es6": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,3 +6,5 @@ bower_components/
|
||||
|
||||
build/*
|
||||
/demo/*
|
||||
|
||||
*storybook.log
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { StorybookConfig } from '@storybook/react-vite';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
"stories": [
|
||||
"../src/**/*.mdx",
|
||||
"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
|
||||
],
|
||||
"addons": [
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-onboarding",
|
||||
"@chromatic-com/storybook",
|
||||
"@storybook/experimental-addon-test"
|
||||
],
|
||||
"framework": {
|
||||
"name": "@storybook/react-vite",
|
||||
"options": {}
|
||||
}
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { Preview } from '@storybook/react'
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
@@ -0,0 +1,9 @@
|
||||
import { beforeAll } from 'vitest';
|
||||
import { setProjectAnnotations } from '@storybook/react';
|
||||
import * as projectAnnotations from './preview';
|
||||
|
||||
// This is an important step to apply the right configuration when testing your stories.
|
||||
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
|
||||
const project = setProjectAnnotations([projectAnnotations]);
|
||||
|
||||
beforeAll(project.beforeAll);
|
||||
+17
-1
@@ -13,7 +13,9 @@
|
||||
"gh": "yarn build:demo && gh-pages -d demo",
|
||||
"dev": "yarn eslint && yarn test",
|
||||
"test": "jest --silent ./src/**",
|
||||
"test:watch": "jest --watch ./src/**"
|
||||
"test:watch": "jest --watch ./src/**",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -32,20 +34,34 @@
|
||||
"chart.js": ">=3.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chromatic-com/storybook": "^3.2.5",
|
||||
"@storybook/addon-essentials": "^8.6.3",
|
||||
"@storybook/addon-onboarding": "^8.6.3",
|
||||
"@storybook/blocks": "^8.6.3",
|
||||
"@storybook/experimental-addon-test": "^8.6.3",
|
||||
"@storybook/react": "^8.6.3",
|
||||
"@storybook/react-vite": "^8.6.3",
|
||||
"@storybook/test": "^8.6.3",
|
||||
"@types/chart.js": "^2.9.41",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||
"@typescript-eslint/parser": "^7.4.0",
|
||||
"@vitest/browser": "^3.0.7",
|
||||
"@vitest/coverage-v8": "^3.0.7",
|
||||
"chart.js": "^4.4.6",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-storybook": "^0.11.3",
|
||||
"gh-pages": "^6.2.0",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"jest": "^29.7.0",
|
||||
"playwright": "^1.50.1",
|
||||
"prettier": "^3.3.3",
|
||||
"storybook": "^8.6.3",
|
||||
"terser-webpack-plugin": "^5.3.10",
|
||||
"ts-jest": "^29.2.5",
|
||||
"ts-loader": "^9.5.1",
|
||||
"typescript": "^5.6.3",
|
||||
"vitest": "^3.0.7",
|
||||
"webpack": "^5.96.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^5.1.0"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { fn } from "@storybook/test";
|
||||
|
||||
import { Button } from "./Button";
|
||||
|
||||
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
||||
const meta = {
|
||||
title: "Example/Button",
|
||||
component: Button,
|
||||
parameters: {
|
||||
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
|
||||
layout: "centered",
|
||||
},
|
||||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
|
||||
tags: ["autodocs"],
|
||||
// More on argTypes: https://storybook.js.org/docs/api/argtypes
|
||||
argTypes: {
|
||||
backgroundColor: { control: "color" },
|
||||
},
|
||||
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
|
||||
args: { onClick: fn() },
|
||||
} satisfies Meta<typeof Button>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
||||
export const Primary: Story = {
|
||||
args: {
|
||||
primary: true,
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const Secondary: Story = {
|
||||
args: {
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const Large: Story = {
|
||||
args: {
|
||||
size: "large",
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
|
||||
export const Small: Story = {
|
||||
args: {
|
||||
size: "small",
|
||||
label: "Button",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
|
||||
import './button.css';
|
||||
|
||||
export interface ButtonProps {
|
||||
/** Is this the principal call to action on the page? */
|
||||
primary?: boolean;
|
||||
/** What background color to use */
|
||||
backgroundColor?: string;
|
||||
/** How large should the button be? */
|
||||
size?: 'small' | 'medium' | 'large';
|
||||
/** Button contents */
|
||||
label: string;
|
||||
/** Optional click handler */
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
/** Primary UI component for user interaction */
|
||||
export const Button = ({
|
||||
primary = false,
|
||||
size = 'medium',
|
||||
backgroundColor,
|
||||
label,
|
||||
...props
|
||||
}: ButtonProps) => {
|
||||
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
|
||||
style={{ backgroundColor }}
|
||||
{...props}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Meta } from "@storybook/blocks";
|
||||
|
||||
export const RightArrow = () => (
|
||||
<svg
|
||||
viewBox="0 0 14 14"
|
||||
width="8px"
|
||||
height="14px"
|
||||
style={{
|
||||
marginLeft: "4px",
|
||||
display: "inline-block",
|
||||
shapeRendering: "inherit",
|
||||
verticalAlign: "middle",
|
||||
fill: "currentColor",
|
||||
"path fill": "currentColor",
|
||||
}}
|
||||
>
|
||||
<path d="m11.1 7.35-5.5 5.5a.5.5 0 0 1-.7-.7L10.04 7 4.9 1.85a.5.5 0 1 1 .7-.7l5.5 5.5c.2.2.2.5 0 .7Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
<Meta title="Configure your project" />
|
||||
|
||||
<div className="sb-container">
|
||||
<div className='sb-section-title'>
|
||||
# Configure your project
|
||||
|
||||
Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community.
|
||||
|
||||
</div>
|
||||
<div className="sb-section">
|
||||
<div className="sb-section-item">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
{`
|
||||
.sb-container {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
@@ -0,0 +1,30 @@
|
||||
.storybook-button {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
border-radius: 3em;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
.storybook-button--primary {
|
||||
background-color: #555ab9;
|
||||
color: white;
|
||||
}
|
||||
.storybook-button--secondary {
|
||||
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
|
||||
background-color: transparent;
|
||||
color: #333;
|
||||
}
|
||||
.storybook-button--small {
|
||||
padding: 10px 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.storybook-button--medium {
|
||||
padding: 11px 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.storybook-button--large {
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin';
|
||||
|
||||
const dirname =
|
||||
typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// More info at: https://storybook.js.org/docs/writing-tests/test-addon
|
||||
export default defineConfig({
|
||||
test: {
|
||||
workspace: [
|
||||
{
|
||||
extends: true,
|
||||
plugins: [
|
||||
// The plugin will run tests for the stories defined in your Storybook config
|
||||
// See options at: https://storybook.js.org/docs/writing-tests/test-addon#storybooktest
|
||||
storybookTest({ configDir: path.join(dirname, '.storybook') }),
|
||||
],
|
||||
test: {
|
||||
name: 'storybook',
|
||||
browser: {
|
||||
enabled: true,
|
||||
headless: true,
|
||||
name: 'chromium',
|
||||
provider: 'playwright'
|
||||
},
|
||||
setupFiles: ['.storybook/vitest.setup.ts'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user