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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add minimal storybook config #90

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ module.exports = {
es2021: true,
jest: true,
},
extends: ["plugin:react/recommended", "airbnb", "prettier"],
extends: [
"plugin:react/recommended",
"airbnb",
"prettier",
"plugin:storybook/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: {
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ yalc.lock
.swc/

stats.html

*storybook.log
61 changes: 61 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { StorybookConfig } from "@storybook/react-webpack5";
const path = require("path");

const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-webpack5-compiler-swc",
"@storybook/addon-onboarding",
"@storybook/addon-links",
"@storybook/addon-essentials",
"@chromatic-com/storybook",
"@storybook/addon-interactions",
"@storybook/addon-styling-webpack",
"@storybook/addon-themes",
{
name: "@storybook/addon-styling-webpack",

options: {
rules: [
{
test: /\.css$/,
sideEffects: true,
use: [
require.resolve("style-loader"),
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve("postcss-loader"),
options: {
implementation: require.resolve("postcss"),
},
},
],
},
],
},
},
],
framework: {
name: "@storybook/react-webpack5",
options: {},
},
webpackFinal: async (config, { configType }) => {
config.resolve.alias = {
...config.resolve.alias,
"#/components": path.resolve(__dirname, "../src/components"),
"#/lib": path.resolve(__dirname, "../src/lib"),
"#/hooks": path.resolve(__dirname, "../src/hooks"),
"#/locales": path.resolve(__dirname, "../src/locales"),
"#/types": path.resolve(__dirname, "../src/types"),
};

return config;
},
};

export default config;
51 changes: 51 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Preview } from "@storybook/react";
import "../src/storybook.css";
import "tailwindcss/tailwind.css";
import { withThemeByClassName } from "@storybook/addon-themes";
import { ThemeProvider } from "../src/components/ThemeToggle";
import { Toaster } from "../src/components/ui/Toaster";
import React from "react";
import { themes } from "@storybook/theming";
import { darkUIStorybook, lightUIStorybook, commonTheme } from "./themes";

const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
darkMode: {
classTarget: "html",
stylePreview: true,
darkClass: "dark",
lightClass: "light",
dark: { ...themes.dark, ...darkUIStorybook, ...commonTheme },
light: { ...themes.normal, ...lightUIStorybook, ...commonTheme },
current: "light",
},

controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export const decorators = [
(Story: React.FC) => (
<ThemeProvider>
<div className="max-h-screen">
<Toaster />
<Story />
</div>
</ThemeProvider>
),
withThemeByClassName({
themes: {
light: "light",
dark: "dark",
},
defaultTheme: "light",
}),
];

export default preview;
26 changes: 26 additions & 0 deletions .storybook/themes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const darkUIStorybook = {
colorPrimary: "hsl(210 40% 98%)",
colorSecondary: "hsl(217.2 32.6% 17.5%)",
appBg: "hsl(222.2 84% 4.9%)",
appContentBg: "hsl(222.2 84% 4.9%)",
appBorderColor: "hsl(217.2 32.6% 17.5%)",
appBorderRadius: ".4rem",
textColor: "hsl(210 40% 98%)",
textInverseColor: "hsl(217.2 32.6% 17.5%)",
barTextColor: "hsl(210 40% 98%)",
barSelectedColor: "hsl(210 40% 98%)",
barBg: "hsl(222.2 84% 4.9%)",
inputBg: "hsl(217.2 32.6% 17.5%)",
inputBorder: "hsl(217.2 32.6% 17.5%)",
inputTextColor: "hsl(210 40% 98%)",
inputBorderRadius: "0.4rem",
};

export const lightUIStorybook = {};

export const commonTheme = {
brandTitle: "Bleu UI",
brandUrl: "https://bleu.builders",
brandTarget: "_blank",
brandImage: "https://github.com/bleu.png",
};
22 changes: 19 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@bleu/ui",
"description": "",
"version": "0.1.128",
"version": "0.1.129",
"author": "",
"license": "",
"keywords": [],
Expand All @@ -25,7 +25,9 @@
"release": "yarn build && yarn release-it",
"link:self": "yarn yalc publish && yarn link",
"ts": "node node_modules/.bin/ts-node -r tsconfig-paths/register -O '{\"module\": \"commonjs\", \"moduleResolution\": \"classic\", \"resolveJsonModule\": false }' --transpile-only --project ./tsconfig.json",
"i18n:extract": "i18next src/**/*"
"i18n:extract": "i18next src/**/*",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"module": "dist/index.mjs",
"main": "./dist/index.js",
Expand Down Expand Up @@ -84,6 +86,7 @@
"node": ">=18.0.0"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.6.1",
"@commitlint/cli": "19.3.0",
"@commitlint/config-conventional": "19.2.2",
"@rollup/plugin-alias": "^5.1.0",
Expand All @@ -94,6 +97,17 @@
"@rollup/plugin-url": "^8.0.2",
"@ryansonshine/commitizen": "4.2.8",
"@ryansonshine/cz-conventional-changelog": "3.3.4",
"@storybook/addon-essentials": "^8.2.7",
"@storybook/addon-interactions": "^8.2.7",
"@storybook/addon-links": "^8.2.7",
"@storybook/addon-onboarding": "^8.2.7",
"@storybook/addon-styling-webpack": "^1.0.0",
"@storybook/addon-themes": "^8.2.8",
"@storybook/addon-webpack5-compiler-swc": "^1.0.5",
"@storybook/blocks": "^8.2.7",
"@storybook/react": "^8.2.7",
"@storybook/react-webpack5": "^8.2.7",
"@storybook/test": "^8.2.7",
"@svgr/rollup": "^8.1.0",
"@swc/core": "1.6.13",
"@testing-library/dom": "^10.3.1",
Expand Down Expand Up @@ -126,6 +140,7 @@
"eslint-plugin-react": "^7.34.3",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-sort-class-members": "^1.20.0",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-typescript-sort-keys": "3.2.0",
"eslint-plugin-unused-imports": "4.0.0",
"globals": "^15.8.0",
Expand All @@ -149,6 +164,7 @@
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-swc3": "^0.11.2",
"rollup-plugin-visualizer": "^5.12.0",
"storybook": "^8.2.7",
"style-loader": "^4.0.0",
"tailwindcss": "^3.4.4",
"tailwindcss-animate": "^1.0.7",
Expand Down Expand Up @@ -179,7 +195,7 @@
"trim-newlines": ">=3.0.1",
"yaml": ">=2.2.2"
},
"packageManager": "yarn@4.1.0",
"packageManager": "yarn@4.4.0",
"dependencies": {
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-alert-dialog": "^1.1.1",
Expand Down
41 changes: 41 additions & 0 deletions src/stories/Avatar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { Avatar, AvatarFallback, AvatarImage } from "../components/ui/Avatar";

// meta
const meta = {
title: "Components/Avatar",
render: () => (
<Avatar>
<AvatarImage src="https://github.com/bleu.png" alt="avatar" />
<AvatarFallback>Bleu Builders</AvatarFallback>
</Avatar>
),
tags: ["autodocs"],
parameters: {
layout: "centered",
},
} satisfies Meta<{}>;
Copy link

Choose a reason for hiding this comment

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

Avoid using {} as a type.

The use of {} as a type is discouraged because it means "any non-nullable value." Define a more specific type for better type safety.

-} satisfies Meta<{}>;
+} satisfies Meta<typeof Avatar>;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} satisfies Meta<{}>;
} satisfies Meta<typeof Avatar>;
Tools
Biome

[error] 18-18: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)


export default meta;

type Story = StoryObj<typeof meta>;

export const AvatarWithImage: Story = {
args: {},
render: () => (
<Avatar>
<AvatarImage src="https://github.com/bleu.png" alt="avatar" />
<AvatarFallback>Avatar</AvatarFallback>
</Avatar>
),
};
export const AvatarWithFallback: Story = {
args: {},
render: () => (
<Avatar>
<AvatarImage src="" alt="avatar" />
<AvatarFallback>bleu</AvatarFallback>
</Avatar>
),
};
105 changes: 105 additions & 0 deletions src/stories/Badge.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from "react";
import { Meta, StoryObj } from "@storybook/react";
import { Badge, BadgeProps } from "../components/ui/Badge";
// meta
const meta = {
title: "Components/Badge",
render: (args) => <Badge {...args}>{args.children}</Badge>,
tags: ["autodocs"],
args: {
color: "primary",
outline: "none",
size: "md",
children: "text",
},
argTypes: {
color: {
control: { type: "select" },
options: ["primary", "secondary", "success", "destructive", "pending"],
},
outline: {
control: { type: "select" },
options: ["none", "outline"],
},
size: {
control: { type: "select" },
options: ["xs", "sm", "md", "lg"],
},
},

parameters: {
layout: "centered",
},
} satisfies Meta<BadgeProps>;

export default meta;

type Story = StoryObj<typeof meta>;

// colors
export const Default: Story = {
args: {
color: "primary",
},
};
export const Secondary: Story = {
args: {
color: "secondary",
},
};

export const Destructive: Story = {
args: {
color: "destructive",
},
};

export const Pending: Story = {
args: {
color: "pending",
},
};

// sizes

export const Xs: Story = {
args: {
size: "xs",
},
};

export const Sm: Story = {
args: {
size: "sm",
},
};

export const Md: Story = {
args: {
size: "md",
},
};

export const Lg: Story = {
args: {
size: "lg",
},
};

// outline

export const OutlineBadge: Story = {
args: {
outline: "outline",
},
};

// link

export const LinkWithStyleBadge: Story = {
render: ({ color, outline, size, children }) => (
<Badge color={color} outline={outline} size={size}>
{children}
</Badge>
),
};
Loading