Buttonコンポーネントは、ユーザーアクションを実行するためのクリック可能なUIコンポーネントです。複数のサイズ、バリアント、状態に対応し、アイコンの表示やポリモーフィックな要素としての使用が可能な柔軟なボタンコンポーネントを提供します。
import { Button } from '@zenkigen-inc/component-ui';
import type { ElementAs, AsProp, PolymorphicPropsWithoutRef } from '@zenkigen-inc/component-ui';import { Button } from '@zenkigen-inc/component-ui';
const MyComponent = () => {
const handleClick = () => {
console.log('ボタンがクリックされました');
};
return (
<Button
variant="fill"
size="medium"
onClick={handleClick}
>
ボタンラベル
</Button>
);
};なし(すべてオプション)
| プロパティ | 型 | デフォルト値 | 説明 |
|---|---|---|---|
size |
'small' | 'medium' | 'large' | 'x-large' |
'medium' |
ボタンのサイズ |
variant |
'fill' | 'fillDanger' | 'outline' | 'text' |
'fill' |
ボタンのスタイルバリエーション |
width |
CSSProperties['width'] |
- | ボタンの幅 |
isSelected |
boolean |
false |
選択状態の制御 |
isDisabled |
boolean |
undefined |
無効状態の制御 |
before |
ReactNode |
- | テキストの前に表示する要素 |
after |
ReactNode |
- | テキストの後に表示する要素 |
borderRadius |
CSSProperties['borderRadius'] |
- | ボタンの角丸設定 |
justifyContent |
'start' | 'center' |
'center' |
内容の配置方法 |
elementAs |
ElementType |
'button' |
レンダリングする要素の型 |
ComponentPropsWithoutRef<T> のすべてのプロパティが使用可能です(elementAsで指定された要素の属性)。
className は後方互換のため受け付けていますが、外部からスタイルを上書きする目的での使用は非推奨です。
スタイル変更は提供している props やテーマトークンで行ってください。
- 高さ:
h-6(24px) - パディング:
px-2.5 - タイポグラフィ:
typography-label14regular - アイコンサイズ:
small(推奨)
- 高さ:
h-8(32px) - パディング:
px-3 - タイポグラフィ:
typography-label14regular - アイコンサイズ:
small(推奨)
- 高さ:
h-10(40px) - パディング:
px-4 - 行の高さ:
leading-[24px] - タイポグラフィ:
typography-label16regular - アイコンサイズ:
medium(推奨)
- 高さ:
h-12(48px) - パディング:
px-4 - 行の高さ:
leading-[24px] - タイポグラフィ:
typography-label16regular - アイコンサイズ:
medium(推奨)
- 背景色:
bg-interactive01 - ボーダー:
border-interactive01 - テキスト色:
text-textOnColor - ホバー:
hover:bg-hover01 - アクティブ:
active:bg-active01
- 背景色:
bg-supportDanger - ボーダー:
border-supportDanger - テキスト色:
text-textOnColor - ホバー:
hover:bg-hoverDanger - アクティブ:
active:bg-activeDanger
- 背景色:
bg-uiBackground01 - ボーダー:
border-uiBorder02 - テキスト色:
text-interactive02 - ホバー:
hover:bg-hover02 - アクティブ:
active:bg-active02
- 背景色: 透明
- ボーダー: 透明
- テキスト色:
text-interactive02 - ホバー:
hover:bg-hover02 - アクティブ:
active:bg-active02
- 各バリアントのベース色が適用される
- ホバー・アクティブ状態のインタラクション有効
- 背景色:
bg-selectedUi - テキスト色:
text-interactive01 - ボーダー:
border-transparent(fill/fillDanger)またはborder-interactive01(outline/text) - アイコン色:
fill-interactive01 - ホバー時のテキスト・アイコン色:
text-textOnColor、fill-iconOnColor(fill/fillDangerのみ)
- ポインターイベント:
pointer-events-none - 背景色:
bg-disabled01(fill/fillDanger)またはbg-uiBackground01(outline/text) - テキスト色:
text-disabled01 - ボーダー:
border-disabled01(fill/fillDanger)またはborder-uiBorder01(outline/text)
<Button
variant="fill"
size="medium"
onClick={() => console.log('クリック')}
>
ボタンラベル
</Button>import { Icon } from '@zenkigen-inc/component-ui';
// アイコンが前にある場合
<Button
variant="fill"
before={<Icon name="add" size="small" />}
>
追加
</Button>
// アイコンが後にある場合
<Button
variant="outline"
after={<Icon name="arrow-right" size="small" />}
>
次へ
</Button>
// 両方にアイコンがある場合
<Button
variant="text"
before={<Icon name="edit" size="small" />}
after={<Icon name="arrow-right" size="small" />}
>
編集して次へ
</Button>const [isSelected, setIsSelected] = useState(false);
<Button
variant="fill"
isSelected={isSelected}
onClick={() => setIsSelected(!isSelected)}
>
選択可能なボタン
</Button><Button
variant="fill"
isDisabled={true}
>
無効なボタン
</Button><Button
variant="fill"
width={200}
borderRadius="9999px"
justifyContent="start"
>
カスタムボタン
</Button>// リンクとして使用
<Button
elementAs="a"
href="/path"
variant="outline"
>
リンクボタン
</Button>
// フォーム送信ボタン
<Button
elementAs="button"
type="submit"
variant="fill"
>
送信
</Button>- 標準的な
<button>要素のすべてのアクセシビリティ機能を継承 disabled属性が適切に設定される- フォーカス管理が適切に実装されている(
focusVisibleによる視覚的フィードバック) - キーボードナビゲーションに対応
- 選択状態が視覚的に明確に表示される
- ポリモーフィック実装により、適切なセマンティック要素を使用可能
clsxを使用した動的クラス名の生成@zenkigen-inc/component-themeのbuttonColorsとfocusVisibleを使用- ポリモーフィック実装により任意の要素としてレンダリング可能
a要素の場合はinline-flexクラスが自動適用- デフォルトの角丸は
rounded-button(borderRadiusが未指定の場合)
Buttonコンポーネントは以下の2つのコンポーネントで構成されています:
Button: 公開API用のコンポーネント(outlineDangerバリアントは含まない)InternalButton: 内部実装用のコンポーネント(outlineDangerバリアントを含む)
// 公開API用の型(outlineDangerは含まない)
type PublicProps<T extends ElementAs> = BaseProps<T> & {
variant?: 'fill' | 'fillDanger' | 'outline' | 'text';
};
// 内部実装用の型(outlineDanger variantを含む)
type InternalProps<T extends ElementAs> = BaseProps<T> & {
variant?: 'fill' | 'fillDanger' | 'outline' | 'text' | 'outlineDanger';
};createButton関数により、両方のコンポーネントで共通の実装ロジックが使用されています:
const createButton = <T extends ElementAs = 'button'>(props: InternalProps<T>) => {
// 共通の実装ロジック
};Buttonコンポーネントはポリモーフィックな実装により、elementAsプロパティで指定された要素としてレンダリングされます。
// デフォルトはbutton要素
<Button>通常のボタン</Button>
// a要素としてレンダリング
<Button elementAs="a" href="/path">リンクボタン</Button>
// div要素としてレンダリング
<Button elementAs="div" role="button">カスタムボタン</Button>ポリモーフィック実装により、elementAsで指定された要素の属性が型安全に提供されます。
// ✅ 正しい使用
<Button elementAs="a" href="/path">リンク</Button>
<Button elementAs="button" type="submit">送信</Button>
// ❌ コンパイルエラー
<Button elementAs="div" href="/path">エラー</Button>- アイコンの使用:
beforeとafterプロパティには@zenkigen-inc/component-iconsのIconコンポーネントを使用してください - ポリモーフィック使用時:
elementAsで指定した要素に適切な属性を設定してください(例:a要素の場合はhref属性) - アクセシビリティ: カスタム要素を使用する場合は、適切な
role属性やaria-*属性を設定してください - 選択状態の視覚的フィードバック:
isSelectedがtrueの場合、outlineとtextバリアントでは選択状態のスタイルが適用されます - 内部実装の使用:
InternalButtonコンポーネントは内部実装用であり、通常の使用ではButtonコンポーネントを使用してください - outlineDangerバリアント:
outlineDangerバリアントはInternalButtonでのみ利用可能で、公開APIでは提供されていません - classNameの扱い: 外部から
classNameを渡してスタイルを変更することは後方互換のため許容していますが非推奨です。 propsやテーマ設定でスタイルを調整してください
Buttonコンポーネントのスタイルは@zenkigen-inc/component-themeのbuttonColors設定に基づいています。カスタマイズする場合は、テーマ設定を変更することで一括でスタイルを調整できます。
特に以下の要素がカスタマイズ可能:
buttonColors- 各バリアントと状態の色設定focusVisible- フォーカス時の視覚的フィードバック- タイポグラフィトークンによる文字スタイル
| 日付 | 内容 | 担当者 |
|---|---|---|
| 2026-04-06 | x-large サイズバリアントを追加 |
- |
| 2025-11-26 15:53 JST | classNameプロパティの非推奨化を明記 |
- |
| 2025-10-29 10:28 JST | 内部実装の詳細を追加、InternalButtonコンポーネントとoutlineDangerバリアントの説明を追加 | - |
| 2025-10-29 10:16 JST | 新規作成 | - |