Button

button要素の代替として操作や処理を実行するコンポーネントです。ユーザーに操作を促すとき、フォームを送信するとき、アクションを選択するときに使います。

使用上の注意

type=“button” について

SmartHR UIのButtonには意図しないsubmitを防ぐために、type="button"がついています。 そのため、form submitを使いたい場合は、必ずtype="submit"を明記してください。

種類

ボタンの優先度や役割に合わせた5種類のコンポーネントを総称して、Buttonコンポーネントとして定義しています。

Primary

Primaryボタンは、画面内で主要な操作をユーザーに示す役割を持ちます。

  • 1つの画面で、Primaryボタンは最大で1つまでにしてください。主要な操作が複数ある場合は、画面内の主要な操作が1つになるように情報設計と画面構成を見直してください。
  • ユーザーからの注目(視線)を集めることだけを目的に、Primaryボタンを使用しないでください。(参考:視線誘導

Secondary

Secondaryボタンは、画面内の通常の操作をユーザーに示す役割を持ちます。 SmartHR UIでは、variant propsのデフォルトはsecondaryです。

  • 1つの画面で使用できるSecondaryボタンの数に制限はありません。
  • ただしボタンが多すぎるとユーザーが迷う要因となります。情報設計と画面構成の見直しや、DropdownMenuButtonの利用などを検討してください。

Tertiary

Tertiaryボタンは、画面内の補助的な操作をユーザーに示す役割を持ちます。主にSecondaryボタンより重要度の低い操作に使います。

Tertiaryボタンは、背景色やボーダーがなく、テキストのみで表示されるため、操作できる要素だと気づきにくい場合があります。 単独で利用する場合は、prefix props または suffix props にアイコンを設定し、操作できる要素であることが視覚的に伝わりやすいようにしてください。

詳しくは、色以外の情報でもボタンであることを伝える を参照してください。

他の画面へ移動するリンクとして使いたい場合は、TextLinkを使ってください。

Danger

Dangerボタンは、ワンクッション必要な操作を行なうときに、ユーザーに注意を促す役割を持ちます。

  • 主に削除ダイアログで使用します。具体的な使用方法は、視覚的表現で目立ちにくくするを参照してください。
  • すべてのユーザーが色を見たり、理解できるわけではありません。警告を促す赤色(DANGER)に頼らず、ボタン配置のコンテキストやラベルテキストだけでもユーザーに伝わるように検討してください。

Text

Textボタンは、画面内の通常の操作をユーザーに示す役割を持ちます。

Secondaryボタンと役割は同じですが、Secondaryボタンの装飾(枠線)が過剰な場合に使います。例えば、次のような場合です。

  • コンポーネントに内包する場合
  • 多くのボタンを並べて表示する場合

Textボタンは、背景色やボーダーがなく、テキストのみで表示されるため、操作できる要素だと気づきにくい場合があります。 単独で利用する場合は、prefix props または suffix props にアイコンを設定し、操作できる要素であることが視覚的に伝わりやすいようにしてください。

詳しくは、色以外の情報でもボタンであることを伝える を参照してください。

AnchorButton

AnchorButtonは、リンク(a要素)をボタンのように装飾にするコンポーネントです。 アクションボタンとして表現したい場合は、Buttonを使用してください。

リンクを新規ウィンドウで開く場合には、テキストの右側に別タブで開くアイコン(OpenInNewTabIcon)が自動で配置されます。

レイアウト

ボタンサイズやアイコンの有無で、コンポーネント内のレイアウトにバリエーションがあります。「サイズ小かつアイコン付き(左)」のように組み合わせることもできます。

ボタンサイズ

2種類の大きさのボタンを使用できます。
SmartHR UIでは、サイズ(sizeprops)で指定できます。

種類表示例説明
通常通常のサイズです。
レイアウトの都合上、スペースを節約したいときに使うサイズです。

アイコンの有無

アイコンは、ボタンを押して実行される操作やUIを想起させる役割や、ボタンに視覚的なアクセントを与える役割を持ちます。

アイコン付きボタン

ラベルテキストの左右にアイコンを配置できます。
SmartHR UIでは、アイコン付き(左)はプレフィックス(prefixprops)に、アイコン付き(右)はサフィックス(suffixprops)にIconを指定することで表現できます。

アイコン付き(左)アイコン付き(右)の例と役割は以下の表を参考にしてください。

種類表示例アイコンの役割
アイコン付き(左)
ボタンを押したときに実行される操作を想起させるために使用します。同じ操作のボタンには、同じアイコンを指定してください。
アイコン付き(右)
ドロップダウンのように、ボタンを押したときに特定のUIが表示される場合に使用します。
(例:DropdownMenuButtonFilterDropdownSortDropdown
アイコン付きにする判断基準

アイコンを設定する判断は、以下を参考にしてください。

  • アイコンは左右どちらかにのみ指定してください。どちらにもアイコンをつけられそうな場合は、アイコン付き(右)(サフィックス)を優先し、アイコン付き(左)(プレフィックス)には指定しないでください。
  • 例外として、FilterDropdownSortDropdownのように、「操作を想起させる役割」と「特定のUIを表す役割」の両方をアイコンが担う必要があるときは、アイコン付き(右)(サフィックス)に「操作を想起させるアイコン」を指定する場合もあります。
アイコン付き(左)(プレフィックス)の判断基準

プレフィックスにアイコンを設定する判断は、以下を参考にしてください。

  • SmartHR上で頻出する操作に関しては、アイコンをつけることを推奨します。
  • レイアウトの都合でボタンの存在感を強調したい場合や、隣接するアイコン付きボタンと見た目を揃えたい場合など、必要性があればアイコンをつけることが可能です。
  • 一方で明確な必要性や理由がなければ、アイコンをつけることは極力避けてください。アイコンが多すぎると、ユーザーがアイコンの意味を理解することが難しくなり、開発者としてもアイコンを作成・選定するコストがかかります。

アイコンボタン

アイコンのみのボタンです。モバイルでの表示など、ラベルテキストを表示するレイアウト上の余裕がない場合に使います。 ラベルテキストがないため、アイコンには必ず代替テキストを含めてください。

状態

マウスオーバー

マウスポインタでボタンに触れている状態(hover状態)のスタイルです。 マウスオーバーを認知できるように、標準時の背景色にOVERLAYを重ねて表現します。

無効(disabled)

ボタンの操作ができない状態を表現したスタイルです。
無効状態のボタンはコントラストが低くユーザーを混乱させるため、できるだけ使わないようにしてください。

ユーザーはなぜ無効になっているのかわからないことがあります。権限による表示制御のデザインパターンを参考にして、そもそも無効ではなくボタン自体を非表示にしたり、無効状態の理由を付近に表示することを検討してください。

無効状態の理由を配置するスペースがどうしてもない場合、disabledReasonpropsで理由を表示することを検討します。

ライティング

ボタンラベルには動詞の終止形を使用する

アクセシビリティ

開発時の考慮点

色以外の情報でもボタンであることを伝える

TertiaryボタンやTextボタンは、主にテキスト色の違いによってボタンであることを表現しています。 そのため、色覚特性やロービジョンのユーザーには、テキスト色の違いだけでは、ボタンであることや操作できることが伝わりにくい場合があります。

操作できる要素だと気づきにくくなることで、ボタンを見逃したり、押したいボタンを見つけにくくなる可能性があります。 そのため、アイコンを追加し、色だけでなく形や見た目の違いからも、操作できる要素であることが伝わるようにしてください。

これにより、色覚特性やロービジョンのユーザーにも、ボタンを見つけやすくなり、操作しやすくなります。

良い実装例
悪い実装例

操作内容が伝わるラベルを使用する

ボタンには、押したときに何が実行されるのかがわかるラベルを設定してください。 ラベルは、簡潔でわかりやすく、アイコンや見た目だけに依存せず内容が伝わることが重要です。 操作内容が伝わるラベルを設定することで、スクリーンリーダーを使用するユーザーにもボタンの目的が伝わりやすくなり、誤操作の防止にもつながります。

詳しくは、ボタンラベルには動詞の終止形を使用する を参照してください。

アイコンボタンにはアクセシブルネームを設定する

アイコンボタンは、視覚的にはアイコンによって操作内容を伝えられますが、スクリーンリーダーを使用するユーザーには操作内容が伝わりません。 そのため、アイコンコンポーネントの alt props に操作内容を表すテキストを設定してください。設定したテキストはアクセシブルネームとして利用されます。

詳しくは、Iconコンポーネントのアクセシビリティを参照してください。

良い実装例
悪い実装例

アイコンボタンに代替テキストがない場合、スクリーンリーダーでは操作内容が伝わりません。また、代替テキストが曖昧な場合は、何を実行するボタンなのか判断できません。

関連ページ

モバイル

ボタンの大きさ

通常サイズのボタンを使う

モバイルでは基本的に通常サイズを使用してください。操作ミスが増えるためサイズ小のボタンを使うことは避けます。

レイアウトの都合上サイズ小のボタンにする必要がある場合、間隔を十分にあけてください。その場合、アイコンボタンとして使うことはなるべく避けてください

ボタンの幅

基本的にボタンはコンテンツ幅いっぱいに広げてください。

視線誘導やレイアウトを加味して調整が必要な場合、内包コンテンツに合わせた幅に調整できます。(Z型の視線移動を期待して設置するコンポーネントであるFloatAreaActionDialogなどでの利用を想定しています。)

Do

幅いっぱいに広げ、十分に操作領域を取る。

Do

視線誘導やレイアウトを加味して内包コンテンツに合わせた幅に調整する。

複数のボタンの並べ方

ボタンを並べる方向

基本的に垂直方向に並べることを推奨します。視線誘導やレイアウトを加味して調整が必要な場合、水平方向に並べることも可能です。

ボタンを並べる順番

PrimaryボタンとSecondaryボタンなど複数の操作を水平方向に並べる場合は、識字方向の後方にPrimaryボタンが来るようにレイアウトしてください。LTR(Left To Right)では、右側にPrimaryボタンを置きます。 垂直方向に並べる場合は、慣習にならい(TODO 要出典)Primaryボタンの下にSecondaryボタンを置きます。

実装例

Do

垂直方向に並べる場合はPrimaryボタンを上に置く。

Do

水平方向に並べる場合は後方にPrimaryボタンを置く。

使い方チェックリスト

Button
参照元:使用上の注意 > type="button" について 「使用上の注意 > type="button" について」の本文へ移動
  • Must
    form submit を使う場合は `type="submit"` を明記する
参照元:種類 > Primary 「種類 > Primary」の本文へ移動
  • Must
    1 つの画面で Primary ボタンは最大 1 つまでにする
    • 主要な操作が複数ある場合は、画面内の主要な操作が 1 つになるように情報設計と画面構成を見直す
  • Avoid
    ユーザーからの注目(視線)を集めることだけを目的に Primary ボタンを使用しない
参照元:種類 > Secondary 「種類 > Secondary」の本文へ移動
  • Should
    Secondary ボタンが多い場合は情報設計・画面構成の見直しや DropdownMenuButton の利用を検討する
参照元:種類 > Tertiary 「種類 > Tertiary」の本文へ移動
  • Must
    Tertiary ボタンを単独で利用する場合は prefix または suffix にアイコンを設定する
  • Must
    他の画面へ移動するリンクとして使いたい場合は TextLink を使う
  • Should
    Tertiary ボタンは Secondary ボタンより重要度の低い操作に使う
参照元:種類 > Danger 「種類 > Danger」の本文へ移動
  • Should
    Danger ボタンは主に削除ダイアログで使用する
  • Should
    警告色(DANGER)に頼らず、ボタン配置のコンテキストやラベルテキストだけでもユーザーに伝わるよう検討する
参照元:種類 > Text 「種類 > Text」の本文へ移動
  • Must
    Text ボタンを単独で使う場合は prefix または suffix にアイコンを設定する
  • Should
    Text ボタンは Secondary ボタンの装飾(枠線)が過剰な場合に使う
    • コンポーネントに内包する場合(例: DropdownMenuButton)
    • 多くのボタンを並べて表示する場合
参照元:種類 > AnchorButton 「種類 > AnchorButton」の本文へ移動
  • Must
    アクションボタンとして表現したい場合は Button を使用する
参照元:レイアウト > ボタンサイズ 「レイアウト > ボタンサイズ」の本文へ移動
  • Should
    レイアウトの都合上スペースを節約したいときはサイズ `小` を使う
参照元:レイアウト > アイコンの有無 > アイコン付きボタン 「レイアウト > アイコンの有無 > アイコン付きボタン」の本文へ移動
  • Must
    同じ操作のボタンには同じアイコンを指定する
  • Should
    アイコン付き(左)はボタンを押したときに実行される操作を想起させるために使用する
  • Should
    アイコン付き(右)はボタンを押したときに特定の UI が表示される場合に使用する
参照元:レイアウト > アイコンの有無 > アイコン付きボタン > `アイコン付き`にする判断基準 「レイアウト > アイコンの有無 > アイコン付きボタン > `アイコン付き`にする判断基準」の本文へ移動
  • Must
    アイコンは左右どちらかにのみ指定する
    • どちらにもアイコンをつけられそうな場合は、アイコン付き(右)(サフィックス)を優先し、アイコン付き(左)(プレフィックス)には指定しない
参照元:レイアウト > アイコンの有無 > アイコン付きボタン > `アイコン付き(左)`(プレフィックス)の判断基準 「レイアウト > アイコンの有無 > アイコン付きボタン > `アイコン付き(左)`(プレフィックス)の判断基準」の本文へ移動
  • Avoid
    明確な必要性や理由がなければ、アイコンをつけることは極力避ける
  • Should
    SmartHR 上で頻出する操作に関してはアイコンをつけるのを推奨する
参照元:レイアウト > アイコンの有無 > アイコンボタン 「レイアウト > アイコンの有無 > アイコンボタン」の本文へ移動
  • Must
    アイコンには必ず代替テキストを含める
  • Should
    アイコンのみのボタンは、ラベルテキストを表示するレイアウト上の余裕がない場合に使う
参照元:状態 > 無効(disabled) 「状態 > 無効(disabled)」の本文へ移動
  • Avoid
    無効状態のボタンはできるだけ使わない
    • そもそも無効ではなくボタン自体を非表示にしたり、無効状態の理由を付近に表示することを検討する
    • 無効状態の理由を配置するスペースがどうしてもない場合、`disabledReason` props で理由を表示することを検討する
参照元:ライティング 「ライティング」の本文へ移動
  • Must
    ボタンラベルには動詞の終止形を使用する
参照元:アクセシビリティ > 開発時の考慮点 > 色以外の情報でもボタンであることを伝える 「アクセシビリティ > 開発時の考慮点 > 色以外の情報でもボタンであることを伝える」の本文へ移動
  • Must
    Tertiary ボタンや Text ボタンにはアイコンを追加し、色だけでなく形や見た目の違いからも操作できる要素であることが伝わるようにする
参照元:アクセシビリティ > 開発時の考慮点 > アイコンボタンにはアクセシブルネームを設定する 「アクセシビリティ > 開発時の考慮点 > アイコンボタンにはアクセシブルネームを設定する」の本文へ移動
  • Must
    アイコンボタンはアイコンコンポーネントの `alt` props に操作内容を表すテキストを設定する
参照元:モバイル > ボタンの大きさ > 通常サイズのボタンを使う 「モバイル > ボタンの大きさ > 通常サイズのボタンを使う」の本文へ移動
  • Must
    レイアウトの都合上 `サイズ小` のボタンにする必要がある場合、間隔を十分にあける
    • その場合、アイコンボタンとして使うことはなるべく避ける
  • Avoid
    モバイルで `サイズ小` のボタンを使うことは避ける
  • Should
    モバイルでは基本的に `通常` サイズを使用する
参照元:モバイル > 複数のボタンの並べ方 > ボタンを並べる方向 「モバイル > 複数のボタンの並べ方 > ボタンを並べる方向」の本文へ移動
  • Should
    複数のボタンは基本的に垂直方向に並べる
参照元:モバイル > 複数のボタンの並べ方 > ボタンを並べる順番 「モバイル > 複数のボタンの並べ方 > ボタンを並べる順番」の本文へ移動
  • Must
    複数の操作を並べる場合は Primary ボタンの位置を一貫させる
    • 水平方向に並べる場合は、識字方向の後方に Primary ボタンが来るようにレイアウトする(LTR では右側)
    • 垂直方向に並べる場合は、Primary ボタンの下に Secondary ボタンを置く

Props

Button props

size
"S" "M"

ボタンの大きさ

disabledReason
{ icon?: FunctionComponent<{}>; message: ReactNode; }

無効な理由

prefix
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal

ボタン内の先頭に表示する内容。 通常は、アイコンを表示するために用いる。

suffix
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal

ボタン内の末尾に表示する内容。 通常は、アイコンを表示するために用いる。

wide
false true

true のとき、ボタンの width を 100% にする。

variant
"text" "primary" "secondary" "tertiary" "danger" "skeleton"

ボタンのスタイルの種類

loading
false true

処理が走ってるかどうか

AnchorButton props

size
"S" "M"

ボタンの大きさ

prefix
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal

ボタン内の先頭に表示する内容。 通常は、アイコンを表示するために用いる。

suffix
string number false true ReactElement<any, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal

ボタン内の末尾に表示する内容。 通常は、アイコンを表示するために用いる。

loading
false true

処理が走ってるかどうか

wide
false true

true のとき、ボタンの width を 100% にする。

elementAs
"symbol" "object" ComponentClass<any, any> FunctionComponent<any> "input" "a" "abbr" "address" "area" "article" "aside" "audio" "b" "base" "bdi" "bdo" "big" "blockquote" "body" "br" "button" "canvas" "caption" "center" "cite" "code" "col" "colgroup" "data" "datalist" "dd" "del" "details" "dfn" "dialog" "div" "dl" "dt" "em" "embed" "fieldset" "figcaption" "figure" "footer" "form" "h1" "h2" "h3" "h4" "h5" "h6" "head" "header" "hgroup" "hr" "html" "i" "iframe" "img" "ins" "kbd" "keygen" "label" "legend" "li" "link" "main" "map" "mark" "menu" "menuitem" "meta" "meter" "nav" "noindex" "noscript" "ol" "optgroup" "option" "output" "p" "param" "picture" "pre" "progress" "q" "rp" "rt" "ruby" "s" "samp" "search" "slot" "script" "section" "select" "small" "source" "span" "strong" "style" "sub" "summary" "sup" "table" "template" "tbody" "td" "textarea" "tfoot" "th" "thead" "time" "title" "tr" "track" "u" "ul" "var" "video" "wbr" "webview" "svg" "animate" "animateMotion" "animateTransform" "circle" "clipPath" "defs" "desc" "ellipse" "feBlend" "feColorMatrix" "feComponentTransfer" "feComposite" "feConvolveMatrix" "feDiffuseLighting" "feDisplacementMap" "feDistantLight" "feDropShadow" "feFlood" "feFuncA" "feFuncB" "feFuncG" "feFuncR" "feGaussianBlur" "feImage" "feMerge" "feMergeNode" "feMorphology" "feOffset" "fePointLight" "feSpecularLighting" "feSpotLight" "feTile" "feTurbulence" "filter" "foreignObject" "g" "image" "line" "linearGradient" "marker" "mask" "metadata" "mpath" "path" "pattern" "polygon" "polyline" "radialGradient" "rect" "set" "stop" "switch" "text" "textPath" "tspan" "use" "view"

next/linkなどのカスタムコンポーネントを指定します。指定がない場合はデフォルトで a タグが使用されます。

variant
"text" "primary" "secondary" "danger" "skeleton"
inactiveReason
{ icon?: FunctionComponent<{}>; message: ReactNode; }
ref
any

UnstyledButton props

Propsは設定されていません。

参考文献