本文へ移動
uiify

Button

アイコンのみの表示にも対応する、バリエーションとサイズを備えたアクションボタン。

ブラウザー
Chrome 123+Firefox 121+Safari 17.5+
ティア
0
圧縮後のサイズ
340 B
強制レイアウトの上限
0 ms
axe の上限
0
SSR 対応
はい
公開された契約
テストハーネス

プレイグラウンド

デフォルト

セカンダリ

アウトライン

ゴースト

破壊的

リンク

読み込み中

使用例

Variants

Pick a variant by emphasis. The default is the filled primary action — use one per view. secondary is a tonal fill for supporting actions, outline a bordered one, ghost shows a surface only on hover, destructive marks irreversible actions and link reads as inline text.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button>Default</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="destructive">Destructive</Button>
      <Button variant="link">Link</Button>
    </>
  );
}

Sizes

sm is 32 px tall with 14 px text, md 44 px with 16 px and lg 56 px with 18 px. Omitting size gives md. Size and variant are independent, so every variant comes in every size.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
    </>
  );
}

With an icon

Put an icon next to the label as a child; the button spaces them 6 px apart. Mark decorative icons aria-hidden so the label stays the accessible name.

import { Button } from "@gunkin/uiify";

const plus = (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
  </svg>
);

export default function Example() {
  return (
    <>
      <Button>{plus}Create</Button>
      <Button variant="secondary">{plus}Create</Button>
      <Button variant="outline">{plus}Create</Button>
    </>
  );
}

Icon only

A button is never narrower than it is tall. The icon-sm, icon and icon-lg sizes drop the side padding, so a single icon sits in a 32, 44 or 56 px circle. There is no visible text, so always add an aria-label.

import { Button } from "@gunkin/uiify";

const plus = (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
  </svg>
);
const close = (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
  </svg>
);

export default function Example() {
  return (
    <>
      <Button size="icon-sm" aria-label="Create">{plus}</Button>
      <Button size="icon" aria-label="Create">{plus}</Button>
      <Button size="icon-lg" aria-label="Create">{plus}</Button>
      <Button variant="secondary" size="icon" aria-label="Create">{plus}</Button>
      <Button variant="outline" size="icon" aria-label="Create">{plus}</Button>
      <Button variant="ghost" size="icon" aria-label="Close">{close}</Button>
    </>
  );
}

Selected

selected marks the chosen item of a set or a toggle that is on, in any variant, with the primary fill. Pass selected={false} for the off state of a toggle so it is still announced as one. Toggle, Toggle group, Segmented control, Pagination and Toolbar use this same state.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button variant="outline" selected>Bold</Button>
      <Button variant="outline" selected={false}>Italic</Button>
      <Button variant="ghost" selected>Bold</Button>
      <Button variant="ghost" selected={false}>Italic</Button>
    </>
  );
}

Disabled

disabled sets the native attribute on a <button>: it leaves the tab order, ignores clicks and shows no hover or pressed state. On any other element it sets aria-disabled and blocks activation instead.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button disabled>Default</Button>
      <Button variant="secondary" disabled>Secondary</Button>
      <Button variant="outline" disabled>Outline</Button>
      <Button variant="destructive" disabled>Destructive</Button>
    </>
  );
}

API

Button

Prop型既定値説明
variant"secondary" | "outline" | "ghost" | "destructive" | "link"—data-variantに書き込む視覚的な強調度。省略すると、塗りつぶしの主要アクションになります。
size"sm" | "md" | "lg" | "icon-sm" | "icon" | "icon-lg"—data-sizeによる高さと余白(32、44、56 px、既定はmd)。アイコン用サイズは左右の余白をなくし、aria-labelが必要です。
selectedboolean—選択した項目や有効なトグルにdata-selectedを設定します。ネイティブの<button>には、他のARIA状態が指定されていなければaria-pressedも設定します。
disabledbooleanfalseボタンを無効にします。<button>ではネイティブ属性を使い、他の要素ではaria-disabledを設定して実行をブロックします。
type"button" | "submit" | "reset""button"描画する要素が<button>の場合にのみ適用する、ネイティブのボタン種別。フォーム内では"submit"を設定します。
asElementType"button"描画する要素またはコンポーネント。"a"やルーターのLinkなどを指定し、すべてのpropとrefを渡します。
renderReactElement | ((props, state) => ReactElement)—動作とアクセシビリティの接続を維持したまま、描画する要素を置き換えます。

キーボード

キー操作
Enter / Space実行
Tabフォーカス

アクセシビリティ

ネイティブの<button type="button">を描画します。ブラウザーがフォーカス、Enter、Spaceを提供し、誤ってフォームを送信することはありません。asやrenderでは指定した要素のロールを維持するため、アンカーはリンクのままです。disabledはボタンではネイティブ属性を使い、他の要素ではaria-disabledとtabindex="-1"を使います。selectedはaria-pressedになります。選択したリンクにはaria-currentが必要です。アイコンのみのボタンにはaria-labelが必要です。

スタイリングのフック

data-uiify-buttondata-disableddata-selecteddata-variantdata-size--uiify-button-wash (colour of the glow in the upper half)--uiify-button-rim (colour of the top edge highlight)