Skip to content
Draft
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
2 changes: 1 addition & 1 deletion packages/spindle-ui/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ module.exports = {
name: '@storybook/react-webpack5',
},
typescript: {
reactDocgen: false,
reactDocgen: 'react-docgen-typescript',
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

reactDocgen を有効化すると、Button のように React.*HTMLAttributes を継承しているコンポーネントでは Props テーブルに HTML 属性が大量に出てしまい、Docs の可読性低下や Storybook 起動/ビルド時間の悪化につながりやすいです。reactDocgenTypescriptOptionspropFilternode_modules 由来の props を除外する等、抽出対象を絞る設定を追加するか、今回 Button のみが目的なら影響範囲を限定する方法を検討してください。

Suggested change
reactDocgen: 'react-docgen-typescript',
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
propFilter: (prop) => {
if (prop.parent && prop.parent.fileName) {
return !prop.parent.fileName.includes('node_modules');
}
return true;
},
},

Copilot uses AI. Check for mistakes.
},
};
28 changes: 27 additions & 1 deletion packages/spindle-ui/src/Button/Button.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Meta, Story, Source } from '@storybook/addon-docs/blocks';
import { Meta, Story, Source, ArgTypes, Description } from '@storybook/addon-docs/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# Button

<Description of={ButtonStories} />

<Source
language='javascript'
code={`
Expand All @@ -23,8 +25,14 @@ import '@openameba/spindle-ui/Button/Button.css';
code={`<link rel="stylesheet" href="https://unpkg.com/@openameba/spindle-ui/Button/Button.css">`}
/>

## Props

<ArgTypes of={ButtonStories} />

## Large

<Description of={ButtonStories.Large} />

<Story of={ButtonStories.Large} />

<Source
Expand All @@ -50,6 +58,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Large Full Width

<Description of={ButtonStories.LargeFullWidth} />

<Story of={ButtonStories.LargeFullWidth} />

<Source
Expand All @@ -75,6 +85,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Medium

<Description of={ButtonStories.Medium} />

<Story of={ButtonStories.Medium} />

<Source
Expand All @@ -100,6 +112,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Medium Full Width

<Description of={ButtonStories.MediumFullWidth} />

<Story of={ButtonStories.MediumFullWidth} />

<Source
Expand All @@ -125,6 +139,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Small

<Description of={ButtonStories.Small} />

<Story of={ButtonStories.Small} />

<Source
Expand All @@ -150,6 +166,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Small Full Width

<Description of={ButtonStories.SmallFullWidth} />

<Story of={ButtonStories.SmallFullWidth} />

<Source
Expand All @@ -175,6 +193,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Disabled

<Description of={ButtonStories.Disabled} />

<Story of={ButtonStories.Disabled} />

<Source
Expand All @@ -200,6 +220,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Disabled Full Width

<Description of={ButtonStories.DisabledFullWidth} />

<Story of={ButtonStories.DisabledFullWidth} />

<Source
Expand All @@ -225,6 +247,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## With Icon

<Description of={ButtonStories.WithIcon} />

<Story of={ButtonStories.WithIcon} />

<Source
Expand Down Expand Up @@ -252,6 +276,8 @@ import '@openameba/spindle-ui/Button/Button.css';

## Full Width With Icon

<Description of={ButtonStories.FullWidthWithIcon} />

<Story of={ButtonStories.FullWidthWithIcon} />

<Source
Expand Down
35 changes: 35 additions & 0 deletions packages/spindle-ui/src/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import { action } from 'storybook/actions';
import { ChevronDownBold, FileAdd, Link, PlusBold } from '../Icon';
import { Button } from './Button';

/**
* ユーザーのアクションを実行するためのボタンコンポーネント。
* contained, outlined, neutral, danger, lighted の5つのバリアントを持つ。
*/
const meta: Meta<typeof Button> = {
title: 'Button',
component: Button,
args: {
onClick: action('clicked'),
onMouseOver: action('mouse-over'),
Expand All @@ -15,6 +20,9 @@ const meta: Meta<typeof Button> = {
export default meta;
type Story = StoryObj<typeof meta>;

/**
* Large サイズのボタン。画面の主要アクションなど、視認性を高めたい場合に使用する。
*/
export const Large: Story = {
render: (args) => (
<>
Expand All @@ -37,6 +45,9 @@ export const Large: Story = {
),
};

/**
* Large サイズの全幅ボタン。モバイル画面下部の固定ボタンなどに使用する。
*/
export const LargeFullWidth: Story = {
render: (args) => (
<>
Expand All @@ -59,6 +70,9 @@ export const LargeFullWidth: Story = {
),
};

/**
* Medium サイズのボタン。もっとも汎用的なサイズ。
*/
export const Medium: Story = {
render: (args) => (
<>
Expand All @@ -81,6 +95,9 @@ export const Medium: Story = {
),
};

/**
* Medium サイズの全幅ボタン。
*/
export const MediumFullWidth: Story = {
render: (args) => (
<>
Expand All @@ -103,6 +120,9 @@ export const MediumFullWidth: Story = {
),
};

/**
* Small サイズのボタン。補助的なアクションやスペースが限られた箇所に使用する。
*/
export const Small: Story = {
render: (args) => (
<>
Expand All @@ -125,6 +145,9 @@ export const Small: Story = {
),
};

/**
* Small サイズの全幅ボタン。
*/
export const SmallFullWidth: Story = {
render: (args) => (
<>
Expand All @@ -147,6 +170,9 @@ export const SmallFullWidth: Story = {
),
};

/**
* 非活性状態のボタン。処理中やバリデーションエラー時など、操作を防ぎたい場合に使用する。
*/
export const Disabled: Story = {
render: (args) => (
<>
Expand All @@ -169,6 +195,9 @@ export const Disabled: Story = {
),
};

/**
* 非活性状態の全幅ボタン。
*/
export const DisabledFullWidth: Story = {
render: (args) => (
<>
Expand Down Expand Up @@ -221,6 +250,9 @@ export const DisabledFullWidth: Story = {
),
};

/**
* アイコン付きボタン。テキストだけでは伝わりにくいアクションの意味を補強する場合に使用する。
*/
export const WithIcon: Story = {
render: (args) => (
<>
Expand Down Expand Up @@ -264,6 +296,9 @@ export const WithIcon: Story = {
),
};

/**
* アイコン付き全幅ボタン。
*/
export const FullWidthWithIcon: Story = {
render: (args) => (
<>
Expand Down
5 changes: 5 additions & 0 deletions packages/spindle-ui/src/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ type Variant = 'contained' | 'outlined' | 'lighted' | 'neutral' | 'danger';
interface Props
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {
children?: React.ReactNode;
/** ボタンの横幅。fullWidth で親要素いっぱいに広がる */
layout?: Layout;
/** ボタンの大きさ */
size?: Size;
/** ボタンの見た目。アクションの重要度に応じて使い分ける */
variant?: Variant;
/** ボタンテキストの前後に表示するアイコン */
icon?: React.ReactNode;
/** アイコンの表示位置 */
iconPosition?: 'start' | 'end';
}

Expand Down
Loading