メインコンテンツへスキップ
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
はじめにWebReactSwiftUIJetpack ComposeFlutterReact Nativeプリセット自分のデザインシステムを作るAI エージェントと Tanrei を使うブランドデザイントークンデザインシステムとカスタマイズTheme Studioカラータイポグラフィアイコン形状エレベーションモーションインタラクション状態振る舞いレイアウトアクセシビリティ言葉カラートークンタイプスケールトークン形状トークンエレベーショントークンモーショントークン状態トークンスペースと寸法のトークンコンポーネントボタンメインアクションボタンセグメントボタンボタングループメニュー付きボタンツールバーコピーボタンチェックボックスラジオボタンスイッチチップメニュースライダースライダーフィールドカレンダーDateTimePickerフィールドグループラジオグループチェックボックスグループセレクトセレクトフィールドメニューバーファイルアップロードファイルピッカー 上級者向けドロップゾーンテキスト入力欄 上級者向けテキストフィールドチップフィールドフィールドコンボボックス 上級者向けコンボボックスフィールド数値入力欄 上級者向け数値フィールドカラー入力欄 上級者向けカラーフィールドワンタイムコード入力欄 上級者向けワンタイムコードフィールド埋め込みテキスト入力欄 上級者向けチャットコンポーザーカード区切り線モーダルレイヤー 上級者向けダイアログリストリスト行ボトムシートサイドシートカルーセルコードブロックテーブルポップオーバーステップアコーディオン説明リスト図アプリシェルページヘッダーツリービュータイムライン画像プレビューハンドルサイズ変更できる枠スクロールエリアバッジプログレスインジケーターメーターナンバーティッカーローディングインジケータースナックバーツールチップキーボードショートカットタグインラインコードコールアウトアバター空の状態タググループスケルトンファイル項目色見本マーキーテキストタブタブビューアプリバーナビゲーションバーナビゲーションドロワー検索リンクページネーション前後のリンクステッパーパンくずリスト目次リンクカードFAB メニューステータスTanrei の作り方コントリビューションライセンスと帰属
ホームコンポーネントチップ

チップ

行に並べて使う、ラベル付きの小さなコントロールです。提案されたアクションやどこかへのリンク、オンとオフを切り替える絞り込み、ユーザーが入力して取り除ける項目を表します。

content_copyMarkdown で表示
カテゴリ
選択
トークン
comp.chip
レベル
基礎
使用先
Chip field

概要

Web
tanrei-chip
schedule
SwiftUI
TanreiChip
schedule
Jetpack Compose
TanreiChip
schedule
Flutter
TanreiChip
schedule
React Native
Chip
schedule

生成元 docs/status/status.json, specs/chip.spec.json

種類

event

使い方

Web と React の例は現在の仕様に沿っています。SwiftUI、Compose、Flutter、React Native は追従待ちで、角の丸みが小さく、グリフも小さく、取り除くアクションが close のグリフで、destructiveRemove もリンクの形(href)も持たない以前の版のチップをまだ提供しています。これらの例は、追従するまでその版のものです。

<tanrei-chip label="カレンダーに追加"><span slot="icon">event</span></tanrei-chip>

<!-- href のあるアクションチップはリンクです。新しいタブで開くものは印を表示し、そのことを自分の言葉で伝えます。 -->
<tanrei-chip label="営業時間" href="/visit/hours/"></tanrei-chip>
<tanrei-chip label="経路" href="https://example.com/map" target="new" target-label="新しいタブで開きます"></tanrei-chip>

<!-- 絞り込みチップは自分の selected を切り替え、change を発火します。 -->
<tanrei-chip kind="filter" label="ベジタリアン"></tanrei-chip>

<!-- 入力チップは、remove-label を名前とする 2 つ目のボタンを持ちます。 -->
<tanrei-chip kind="input" label="山田 花子" remove-label="山田 花子を削除">
  <img slot="avatar" src="ada.jpg" alt="" />
</tanrei-chip>

<!-- 添付ファイルを取り除くと、そのファイルは失われます。取り除くアクションに破壊的な見た目を付けます。 -->
<tanrei-chip kind="input" label="report.pdf" remove-label="report.pdf を削除" destructive-remove></tanrei-chip>

<script type="module">
  import '@tanrei/web/components/chip';
  document.querySelector('[kind="filter"]').addEventListener('change', (e) => filter(e.detail.selected));
  // チップは DOM に残ります。取り除いて隣にフォーカスを移すのはページの役目です。
  document.querySelector('[kind="input"]').addEventListener('remove', (e) => removeRecipient(e.target));
</script>
import { Chip } from '@tanrei/react';

<Chip label="カレンダーに追加" onClick={addToCalendar}><span slot="icon">event</span></Chip>
<Chip label="営業時間" href="/visit/hours/" />
<Chip label="経路" href="https://example.com/map" target="new" targetLabel="新しいタブで開きます" />
<Chip kind="filter" selected={vegetarian} label="ベジタリアン" onChange={(e) => setVegetarian(e.detail.selected)} />
<Chip kind="input" label="山田 花子" removeLabel="山田 花子を削除" onRemove={() => removeRecipient(ada)} />
<Chip kind="input" label="report.pdf" removeLabel="report.pdf を削除" destructiveRemove onRemove={() => removeAttachment(report)} />
import Tanrei

// どのイニシャライザーを使うかで種類が決まります。
TanreiChip("カレンダーに追加", icon: "event", action: addToCalendar)
TanreiChip("ベジタリアン", isSelected: $vegetarian)
TanreiChip("山田 花子", removeLabel: "山田 花子を削除", action: openContact, onRemove: removeAda)
import io.github.chnotchy.tanrei.components.TanreiChip
import io.github.chnotchy.tanrei.primitives.TanreiText

// どのオーバーロードを使うかで種類が決まります。onClick だけならアクションチップです。
TanreiChip(onClick = ::addToCalendar, label = "カレンダーに追加", icon = { TanreiText("event") })

// selected と onSelectedChange を渡すと絞り込みチップになります。
TanreiChip(selected = vegetarian, onSelectedChange = { vegetarian = it }, label = "ベジタリアン")

// onClick と onRemove を渡すと入力チップになります。リストから取り除き、フォーカスを移すのは呼び出し側です。
TanreiChip(
    onClick = { openContact(ada) },
    onRemove = { recipients -= ada },
    label = "山田 花子",
    removeContentDescription = "山田 花子を削除",
    avatar = { ContactPhoto(ada) },
)
import 'package:tanrei/tanrei.dart';

// どのコンストラクターを使うかで種類が決まります。
TanreiChip(label: 'カレンダーに追加', icon: const Icon(AppSymbols.event), onPressed: addToCalendar);

TanreiChip.filter(
  label: 'ベジタリアン',
  selected: vegetarian,
  onSelected: (bool value) => setState(() => vegetarian = value),
);

TanreiChip.input(
  label: '山田 花子',
  removeSemanticLabel: '山田 花子を削除',
  avatar: Image.asset('ada.png', fit: BoxFit.cover),
  onDeleted: () => setState(() => recipients.remove(ada)), // フォーカスの移動も呼び出し側で
);
import { Chip } from '@tanrei/react-native';

<Chip label="カレンダーに追加" icon="event" onPress={addToCalendar} />
<Chip kind="filter" label="ベジタリアン" selected={vegetarian} onSelectedChange={setVegetarian} />
<Chip
  kind="input"
  label="山田 花子"
  avatar={{ uri: ada.photo }}
  removeAccessibilityLabel="山田 花子を削除"
  onRemove={() => removeRecipient(ada)}
/>

仕様

バリアント、サイズ、無効状態

eventeventevent

取り除くアクション:通常(既定)と破壊的。ホバーかフォーカスで違いが見えます

リンクのチップ:同じタブ、新しいタブ、無効

既定のシステムでは、どのチップも両端が半円のピル形で、文字を大きくして背が高くなってもピル形のままです。グリフは高さが許す限り大きく、medium では 24、small では 20 です。選択中の絞り込みチップのチェックはシステムのアイコンセットの check、取り除くグリフは cancel で、後者はいつも塗りつぶしで描きます。チップは独自の印を描かないので、別の印にしたいデザインシステムは別のアイコンセットを選びます。Outlined のチップの輪郭は、区切り線が引くのと同じ控えめな細い線です。

構成要素

構成要素

Web パッケージが描くフィクスチャ action-outlined の上に描いています。
パーツ 説明
1 container The shape that holds the chip's content and carries hover, focus and press of the chip itself.
2 outline · 任意 The border, drawn inside the container's edge. Transparent where the look has none (elevated, selected).
3 icon · 任意 Leading glyph of the system's icon set. A selected filter chip shows the glyph `check` in its place.
4 avatar · 任意 Leading image of an input chip (a person, a file), in place of the icon.
5 label Text that names the choice, action or item.
6 remove · 任意 An input chip's trailing remove action: the glyph `cancel` of the system's icon set, drawn filled, on a round container that carries its own hover, focus and press and sits concentric with the chip's round end: as far from the end as from the top and the bottom. A separate button for assistive technology. It takes the error color while it is hovered, focused or pressed only while destructiveRemove is true.
7 focus-ring Gap-then-ring indicator shown for keyboard focus, around the chip or around the remove action, whichever has focus.

寸法

寸法

長さ トークン 値(px)
container padding-inline-with-icon tanrei.comp.chip.container.padding-inline-with-icon.medium 8
container gap tanrei.comp.chip.container.gap.medium 8
container height tanrei.comp.chip.container.height.medium 32
icon size tanrei.comp.chip.icon.size.medium 24
Web パッケージが描くフィクスチャ action-outlined の上に描いています。

プロパティ

プロパティ 型 既定値 説明
kind action | filter | input "action" What the chip does. action: a button that performs or suggests something, or with href a link to it. filter: a two-state control, on or off. input: an item the user entered, which the user can remove. Kind decides the role and the parts, not the look.
variant outlined | elevated "outlined" Look. Outlined sits flat on a plain surface; elevated is raised for chips over media or a busy background. A design system may add values.
size small | medium "medium" Visual height (24 / 32). Small is for dense places, such as entered items inside a field or tags in a table row. The hit area always meets the minimum target. A design system may add values.
selected boolean false Whether a filter chip is on. Ignored unless kind is filter.
value string "" What a component that holds the selection of a set of filter chips names this chip by: the Tag group's value and values (TGR-17). Unique within the set. Not drawn and not exposed; the chip itself does nothing with it.
disabled boolean false Prevents interaction and removes the chip, and its remove action, from the focus order.
href string "" The destination of an action chip: an address as the platform's links take one (a URL; on the web a path or a fragment as well). Not empty, it makes the chip a link and not a button: the link role, activated by pointer, touch or Enter and not by Space, opened by the platform as its own links are, and drawn exactly as the action chip it would otherwise be (CHP-33, CHP-34). Ignored unless kind is action: a filter chip holds a state and an input chip a second action (CHP-37).
target same | new "same" Where the destination opens. same: where the person is — the same tab on the web, the app's own handling of the address elsewhere. new: a new context — a new tab or window on the web, outside the current screen elsewhere — which the chip marks with the glyph open_in_new after its label and says through targetLabel (CHP-35). Ignored without href.
targetLabel string "" What assistive technology reads after the link's name while target is new ("opens in a new tab"). Tanrei ships no words of its own, so the product gives them in its own language, as it gives a chip its removeLabel. Required while target is new; ignored otherwise.
label string "" The visible text and the accessible name.
removeLabel string "" The accessible name of an input chip's remove action. It should name the item ("Remove Ada Lovelace"), because the remove action is a separate element. Required when kind is input; ignored otherwise.
destructiveRemove boolean false Whether an input chip's remove action reads as destructive: at rest it looks as it does without the flag; while it is hovered, keyboard-focused or pressed its glyph and state layer take the error color. Set it where removing the item loses something that cannot be put back in a step (an attachment, a recipient already invited); leave it off where the person can put the item back in one step (an applied filter, a search term). It changes color only: the remove action's name, glyph, size and behaviour are the same either way. Ignored unless kind is input.
removable boolean true Whether an input chip draws its remove action. False for an entry that cannot be taken away now (a read-only field's): no remove action is drawn, so none stands there doing nothing. Ignored unless kind is input.

スロット

スロット 説明
icon Leading icon (a glyph of the system's icon set).
avatar Leading image of an input chip. Ignored for other kinds.

イベント

イベント 説明
click The chip itself was activated by pointer, touch, keyboard or assistive technology. Not emitted by the remove action. A link chip emits it before its destination opens; a product that takes the navigation itself (a client-side router) cancels it (CHP-34).
change A filter chip was activated; carries the new value of selected.
remove The user asked to remove an input chip, with its remove action or with Backspace or Delete. The chip does not remove itself.

状態

振る舞い

EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。

ID 要件
CHP-1 WHEN the user activates the chip by pointer, touch, Enter or Space — a link chip (CHP-33) by pointer, touch or Enter — THE chip SHALL emit click exactly once.
CHP-2 WHILE disabled is true THE chip SHALL NOT emit click, change or remove, SHALL NOT be focusable, nor its remove action, and SHALL expose the disabled state to assistive technology.
CHP-3 WHILE hovered, keyboard-focused or pressed THE chip SHALL render its container, outline, label, icon, elevation and opacity from the component tokens of the highest-precedence active state, with precedence pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state.
CHP-4 WHEN the chip receives keyboard focus THE chip SHALL show the focus ring without animation; focus gained by pointer or touch SHALL NOT show it.
CHP-5 WHERE the visual size is below the minimum target THE chip SHALL extend its hit area on both axes to sys.target.touch for touch input and sys.target.pointer for fine pointers, without changing its visual size; a platform that cannot tell the input type SHALL use sys.target.touch.
CHP-6 WHILE disabled is true THE chip SHALL render its container, outline, label, icon, remove action, elevation and opacity from the disabled component tokens of its variant and, for a filter chip, of its selection, and SHALL draw an avatar at sys.state.disabled-content-opacity.
CHP-7 WHEN variant or size names a value that the active design system does not have, or kind names a value this spec does not have, THE chip SHALL render and behave with the default value (kind action, and the default variant's or size's tokens), and in debug builds report the unknown value.
CHP-8 WHEN the chip is pressed by pointer, touch, Enter or Space THE chip SHALL show the pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner.
CHP-9 WHILE pressed THE chip SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; outline, label, icon, elevation, opacity and shape still come from the pressed tokens. Under none every part stays with the state under the press. The ripple grows over comp.chip.motion.feedback-duration with comp.chip.motion.state-easing, fades over the state duration of its size (comp.chip.motion.state-duration.small or .medium) with comp.chip.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced.
CHP-10 THE chip SHALL ease its container corners by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0) and show its keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
CHP-11 WHEN kind is filter and the user activates the chip THE chip SHALL emit click and then change with the opposite of selected, in that order (as a native checkbox does), and SHALL expose selected to assistive technology as pressed or not pressed; WHILE kind is not filter THE chip SHALL ignore selected and SHALL NOT expose a pressed state.
CHP-12 WHILE kind is filter and selected is true THE chip SHALL render its container, outline, label and icon from the selected parts of its variant (comp.chip.outlined.selected.container.color for outlined at rest, and so on); otherwise it SHALL render them from the variant's own parts (comp.chip.outlined.container.color, and so on).
CHP-13 WHILE kind is filter and selected is true THE chip SHALL show the glyph check of the system's icon set in the leading position, in place of its icon when it has one, and SHALL draw no mark of its own; WHEN selected changes THE chip SHALL show or hide the check, change its width with it, and change to or from the selected colors over comp.chip.motion.selection-duration with comp.chip.motion.selection-easing, and SHALL show the new condition at once where motion is reduced.
CHP-14 THE chip SHALL draw its icon, its check and its remove glyph at the icon size of its size (comp.chip.icon.size.medium for medium, and so on) and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max, the icon and the remove glyph with sys.icon.weight and the check with comp.chip.check.weight (not sys.icon.weight: the check is a control's own mark, drawn on the selected fill to tell on from off, as the checkbox's is, CHK-12), the weight changing the stroke of the glyph only and never its box; the icon and the check SHALL take the family and fill of its selection (sys.icon.family.selected and sys.icon.fill.selected only while kind is filter and selected is true; otherwise sys.icon.family.unselected and sys.icon.fill.unselected) and the icon color of its look (comp.chip.outlined.icon.color, comp.chip.outlined.selected.icon.color, and so on); the remove glyph SHALL always be drawn filled, with sys.icon.family.selected and sys.icon.fill.selected, in the glyph color of the parts CHP-20 and CHP-27 name (comp.chip.outlined.destructive-remove.icon.color or comp.chip.outlined.remove.icon.color, and so on).
CHP-15 WHERE kind is input and an avatar is given THE chip SHALL draw it in the leading position, in place of an icon, as an image of the avatar size of its size (comp.chip.avatar.size.medium for medium, and so on) clipped to comp.chip.avatar.shape and hidden from assistive technology; WHERE kind is not input THE chip SHALL ignore an avatar and report it in debug builds.
CHP-16 THE chip SHALL draw a container at least the height of its size (comp.chip.container.height.medium for medium, and so on) with corners comp.chip.container.shape, never larger than half the container's height (a pill where the value is sys.shape.corner.full, at any height the chip grows to), and an outline comp.chip.outline.width wide inside its edge, and lay out in one row its leading icon, check or avatar, its label and its remove glyph, separated by comp.chip.container.gap.medium (and so on); each end SHALL be padded by comp.chip.container.padding-inline-with-icon.medium where it holds an icon or the check, by comp.chip.container.padding-inline-with-avatar.medium where it holds an avatar, by comp.chip.container.padding-inline-with-remove.medium where it holds the remove glyph, and by comp.chip.container.padding-inline.medium where the label meets it, and the row's tallest item (the label's line, a glyph's box or the avatar) SHALL be padded at the top and bottom by at least comp.chip.container.padding-block.medium (and so on for each size). The remove action's round container takes no part in this layout (CHP-18); where it lies follows from it (CHP-32).
CHP-17 THE chip SHALL set its label on one line in the text style of its size (comp.chip.label.typescale.medium, and so on) and the label color of its look, truncating it with an ellipsis only when the layout gives the chip less width than the label needs, and SHALL grow in height with larger text; the full label SHALL remain the accessible name.
CHP-18 WHERE kind is input THE chip SHALL draw a remove action at its inline end: the glyph cancel of the system's icon set, centred on a round container of the remove size of its size (comp.chip.remove.container.size.medium, and so on) with corners comp.chip.remove.container.shape. The round container is larger than the glyph and SHALL NOT take part in the layout of CHP-16: it reaches into the gap before the glyph and the padding after it, as far as CHP-32 says, without changing the chip's size. THE chip SHALL draw no mark of its own for it, and SHALL expose it as a separate element with the button role, named by removeLabel, that is not a stop in the Tab order: it is reached by pointer, touch and assistive technology, and from the keyboard through the chip itself, on which Backspace or Delete removes (CHP-19). WHEN the remove action is activated by pointer, touch, assistive technology, Enter or Space THE chip SHALL emit remove exactly once and SHALL NOT emit click.
CHP-19 WHEN kind is input and the chip itself has keyboard focus and the user presses Backspace or Delete THE chip SHALL emit remove exactly once, and SHALL NOT answer the repeats of a key that is held down, so that one press asks for one removal. WHILE kind is input, removable is true and disabled is false THE chip SHALL expose to assistive technology, on the chip itself, that Delete and Backspace remove it (the platform's keyboard-shortcut property where it has one: on the web aria-keyshortcuts="Delete Backspace"), so that a person who does not see the remove action, and who no longer meets it by Tab (CHP-18), learns the key.
CHP-20 WHILE the remove action is hovered, keyboard-focused or pressed THE chip SHALL render the remove action's container and glyph from the remove parts of the remove action's own highest-precedence state (comp.chip.outlined.remove.container.color at rest, and so on; the destructive-remove parts instead while destructiveRemove is true, CHP-27), with the precedence of CHP-3, SHALL keep the chip's container, outline, label and icon at the chip's own state (the chip is not hovered or pressed while the pointer or press is on the remove action), SHALL show the focus ring around the remove action's round container rather than around the chip, and SHALL answer a press of it as CHP-8 and CHP-9 name, within that round container.
CHP-21 WHERE kind is input THE chip SHALL give the remove action a hit area of at least sys.target.touch for touch input and sys.target.pointer for fine pointers on both axes, around its glyph, reaching toward the label no further than the gap before the glyph and extending outward, beyond the chip's visual bounds, as far as it needs — never over the label; the rest of the chip's hit area SHALL activate the chip.
CHP-22 WHEN the chip emits remove THE chip SHALL NOT remove itself or move focus: the owner removes it and moves focus to a neighbouring chip, or to the field the chips belong to.
CHP-23 THE chip SHALL be one tab stop — an input chip too: its remove action is not a stop (CHP-18), and Backspace or Delete on the chip removes it (CHP-19) — unless the component that holds it gives its set one stop and the keys to reach each chip (the chip field, CHF-11; a tag group that holds a selection, TGR-20) — and SHALL NOT handle arrow keys; moving between chips with arrow keys, choosing one or several filter chips of a set, and wrapping or scrolling a row belong to the layout that holds the chips.
CHP-24 WHEN the elevation or the colors of the chip change between states THE chip SHALL animate the change over the state duration of its size (comp.chip.motion.state-duration.small or .medium) with comp.chip.motion.state-easing, and SHALL change them at once where motion is reduced.
CHP-25 WHEN the layout direction is right-to-left THE chip SHALL mirror the order of its content and apply its paddings by logical start and end, so that the remove action sits at the left, and SHALL grow a ripple from the point of contact as in left-to-right.
CHP-26 WHILE label is not empty THE chip SHALL expose it as its accessible name, over a name the product gives it on the element (aria-label or aria-labelledby); WHILE label is empty and the product gives the chip a name of its own on the element — aria-label, or aria-labelledby naming an element — THE chip SHALL expose that name as its accessible name; WHILE label is empty and the product gives it none THE chip SHALL still render, and in debug builds report that it has no accessible name; WHILE kind is input and removeLabel is empty THE chip SHALL report the same of its remove action.
CHP-27 WHILE kind is input and destructiveRemove is true THE chip SHALL render the remove action's round container and glyph from the destructive-remove parts of its variant in the remove action's own state (comp.chip.outlined.destructive-remove.container.color and comp.chip.outlined.destructive-remove.icon.color at rest, and so on), whose hovered, focused and pressed container mixes comp.chip.outlined.destructive-remove.state-layer.color and whose hovered, focused and pressed glyph takes the error color (in the default system both are the error role); at rest and while disabled the remove action SHALL look as it does with destructiveRemove false. WHILE destructiveRemove is false THE chip SHALL render the remove action from the remove parts (CHP-20). WHERE kind is not input THE chip SHALL ignore destructiveRemove.
CHP-28 THE chip SHALL NOT make color the only sign that removing is destructive: whatever destructiveRemove is, the remove action SHALL keep the button role, its accessible name removeLabel ("Remove Ada Lovelace"), the glyph cancel, its size and its hit area, and SHALL announce nothing more and nothing less to assistive technology.
CHP-29 THE chip SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the chip is shown THE chip SHALL draw itself for the new direction at once, without a motion of its own, keeping its selection and its focus.
CHP-30 WHERE the layout direction is right-to-left THE chip SHALL draw the glyph of its icon slot mirrored left to right exactly when the system's icon set marks that glyph's name as mirrored or the product forces mirroring for that use, and unmirrored when the product forbids it: the icon helper mirrors the glyph inside its own box, about the box's vertical centre line, changing neither its place, size, color and fill nor the order CHP-25 gives. THE chip SHALL NOT mirror a glyph itself, and SHALL NOT mirror content the product gives as an image or a view of its own rather than by a glyph's name. The check, remove and cancel glyphs the chip draws itself are not marked and are never mirrored.
CHP-31 THE chip SHALL lay out its label as text of its own direction, isolated from the text around it: each takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE chip SHALL still place the label and align its lines by the layout direction, not by the text's own, and SHALL cut a label that does not fit (CHP-17) at the end of its own direction, so that a left-to-right label in a right-to-left layout loses its right end and never its beginning.
CHP-32 WHERE kind is input THE chip SHALL center the remove action's round container on the remove glyph, on the chip's midline, so that it lies from the chip's inline end comp.chip.container.padding-inline-with-remove.medium less half of what comp.chip.remove.container.size.medium exceeds comp.chip.icon.size.medium by (and so on for each size), and never less than nothing; the default system's values SHALL make that distance the same as the round container's distance from the chip's top and from its bottom at the height of its size, so that the round container is inset equally on three sides, its center is the center of the chip's round end, and the two curves are concentric, as an avatar's and the round end's are at the other end. The hover, focus and press of the remove action (CHP-20) and its focus ring SHALL be drawn in that same place.
CHP-33 WHILE kind is action and href is not empty THE chip SHALL be a link and not a button: it SHALL expose the link role, named by label, with no pressed state; SHALL be the platform's own link to href (the web's anchor element; SwiftUI's Link; on Compose, Flutter and React Native an element with the platform's link semantics whose address is opened by the platform's opener), so that whatever the platform gives a link — on the web its context menu, opening in a new tab or window, copying and dragging its address, and the address shown before it is followed — is the platform's, and not the chip's to draw or to take over; and SHALL draw its container, outline, label, icon, elevation and opacity in every state from the same tokens as an action chip of its variant and size that has no destination, with no look of its own for a link and none for a destination already visited.
CHP-34 WHEN the user activates a link chip by pointer, touch or Enter THE chip SHALL emit click exactly once and then open href where target names, unless the product cancelled that click, in which case it SHALL open nothing: the product's own router has taken the navigation. It SHALL show the pressed state as CHP-8 and CHP-9 say and SHALL NOT hold the navigation back for sys.motion.duration.press-hold. THE chip SHALL NOT activate a link chip on Space, which on the web scrolls the page as it does on any link, and SHALL NOT show the pressed state for it; WHERE the platform gives its links other keys or gestures (on the web a modified or a middle click that opens a new tab, on Apple platforms a long press that previews) THE chip SHALL leave them to the platform.
CHP-35 WHILE the chip is a link and target is new THE chip SHALL open href in a new context — on the web a new tab or window that is given no handle to the page that opened it; on the other platforms outside the screen the person is on, as the platform's opener decides — and SHALL draw the glyph open_in_new of the system's icon set at its inline end, after the label, where CHP-16 lays out an input chip's remove glyph: comp.chip.container.gap.medium from the label, at comp.chip.icon.size.medium, with that end padded by comp.chip.container.padding-inline-with-icon.medium at the medium size (and each of its own size otherwise); in the icon color of its look and state (comp.chip.outlined.icon.color for outlined at rest, and so on); through the icon helper, which mirrors it in a right-to-left layout because the icon set marks its name; and hidden from assistive technology. WHILE target is new THE chip SHALL expose targetLabel as its description, read after its name and role, and WHILE targetLabel is empty SHALL still render and in debug builds report that a link that opens a new context does not say so. WHILE target is same THE chip SHALL draw no mark and SHALL ignore targetLabel.
CHP-36 WHILE kind is action and href is not empty and disabled is true THE chip SHALL NOT be a link that can be followed: it SHALL render as CHP-6 says, the mark of CHP-35 in the disabled icon color, SHALL expose the link role with the disabled state and no destination, SHALL NOT be focusable, SHALL NOT emit click, and SHALL open nothing by any means the platform gives a link (on the web the anchor carries no href, so there is no context menu entry, no drag and no new tab for it).
CHP-37 WHILE kind is filter or input THE chip SHALL ignore href, target and targetLabel and stay the chip its kind makes it, and in debug builds SHALL report that only an action chip can be a link: a control that holds a state, or that carries a second action, is not a destination. WHEN target names a value the chip does not define THE chip SHALL behave as same, and in debug builds report the unknown value. IF href is only white space, or names a script to run rather than a place to go (the web's javascript: scheme), or cannot be read as an address by the platform, THE chip SHALL be an action chip without a destination, and in the last two cases report it in debug builds.
CHP-38 WHILE kind is input and removable is false THE chip SHALL draw no remove action, SHALL have no stop for one and SHALL emit no remove, and SHALL keep the padding of a chip without one. WHILE kind is not input THE chip SHALL ignore removable.
CHP-39 WHEN a pointer or touch press lands on an input chip anywhere but on its remove action THE chip SHALL NOT let that press give the remove action focus: focus SHALL go where the platform puts it for a press on a button — to the chip itself where a pressed button takes focus, and nowhere in the chip where it takes none — so that the next Enter or Space activates the chip and never removes it. THE remove action SHALL still take focus when it is pressed itself or moved to by assistive technology or by the product, and the chip SHALL keep the Tab order of CHP-23.
CHP-40 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE chip SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role — an id reference by the elements it names in the host's tree or a tree around it, an error message as part of the description while the chip is invalid — except those the chip owns (aria-pressed, aria-disabled), which it SHALL move and not expose. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE chip SHALL take it off that element. WHEN the product sets an aria- attribute the chip owns THE chip SHALL report it in debug builds.

プラットフォーム別の名前対応

パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。

仕様 Web SwiftUI Jetpack Compose Flutter React Native
コンポーネント tanrei-chip TanreiChip TanreiChip TanreiChip Chip
kind · プロパティ kind isSelected / onRemove onSelectedChange / onRemove TanreiChip / TanreiChip.filter / TanreiChip.input kind
variant · プロパティ variant variant variant variant variant
size · プロパティ size size size size size
selected · プロパティ selected isSelected selected selected selected
value · プロパティ value value value value value
disabled · プロパティ disabled disabled enabled isEnabled disabled
href · プロパティ href destination href href href
target · プロパティ target target target target target
targetLabel · プロパティ targetLabel targetLabel targetLabel targetSemanticLabel targetLabel
label · プロパティ label title label label label
removeLabel · プロパティ removeLabel removeLabel removeContentDescription removeSemanticLabel removeAccessibilityLabel
destructiveRemove · プロパティ destructiveRemove destructiveRemove destructiveRemove destructiveRemove destructiveRemove
removable · プロパティ removable removable removable removable removable
click · イベント click action onClick onPressed onPress
change · イベント change isSelected onSelectedChange onSelected onSelectedChange
remove · イベント remove onRemove onRemove onDeleted onRemove
備考 removeLabel is reflected as the remove-label attribute. destructiveRemove is a boolean property that defaults to false, reflected as the destructive-remove attribute. The icon is the icon slot and the avatar the avatar slot. A filter chip switches its own selected and fires change, as a toggle Button does; remove is a custom event and the element stays in the DOM until the page removes it. With href an action chip's shadow root holds an <a> in place of its <button>, with the same classes, parts and listeners. The link form: href is the href attribute; target is the target attribute with the values same and new (the HTML spellings _self and _blank are read as those two; anything else is same and reported); targetLabel is the target-label attribute. Web-only, forwarded to the anchor and to nothing else: rel (to which new adds noopener) and download. Cancelling click (preventDefault()) cancels the navigation, which is how a client-side router takes it; a modified or a middle click is the browser's. A disabled link is the anchor without href, with role="link" and aria-disabled="true", as the navigation drawer's destination already is. Space is not handed to the press controller. element.click() follows the link. removable is a boolean property that defaults to true; its attribute is the inverse, not-removable, because an HTML boolean attribute cannot default to true. The remove action's <button> has tabindex="-1" (CHP-18): pressable by pointer and assistive technology, focusable by focus(), passed by Tab; while the chip removes, its own button or link carries aria-keyshortcuts="Delete Backspace" (CHP-19). A component that holds chips as a set and gives the set one stop (CHP-23, the chip field) takes each chip and its remove action out of the Tab order in the way the toolbar holds its Buttons. A mouse press anywhere on an input chip but its remove action takes the remove action's tabindex away until that press has placed focus (CHP-39): Safari on macOS gives a pressed <button> no focus and delegates the press to the first element with a tabindex in the shadow root, which would otherwise be the remove action. Kind is chosen by initializer: init(_:action:) is an action chip, init(_:isSelected:) (a Binding<Bool>) a filter chip, init(_:removeLabel:destructiveRemove:action:onRemove:) an input chip, with destructiveRemove defaulting to false. The remove action is a second Button placed beside the chip's own, never inside it, so VoiceOver reaches it as its own element. disabled follows .disabled(_:). The link form, not built on this platform yet: the initializer init(_:destination:), which takes a URL in place of action: (the filter and input initializers take none) draws the same control as a SwiftUI Link, so the address is opened by the environment's openURL — an app that routes addresses itself provides an OpenURLAction, which is how the navigation is cancelled — and VoiceOver reads the link trait. target: TanreiLinkTarget = .same and targetLabel (the accessibility hint) are parameters of that initializer alone. Not built on this platform yet: the remove action out of the focus order, with the keys of CHP-19 told to assistive technology — here it is still a second stop after the chip (CHP-18, CHP-19, CHP-23); removable, default true — an input chip that draws no remove action while it is false (CHP-38); and a holder that gives a set of chips one stop takes each chip's own stops away (CHP-23). Lagging behind CHP-14 (the check drawn at comp.chip.check.weight): its check is drawn at sys.icon.weight. Kind is chosen by overload: onClick alone is an action chip, selected + onSelectedChange a filter chip, onClick + onRemove an input chip. enabled is the inverse flag. The remove action is its own semantics node with Role.Button. The link form, not built on this platform yet: the action overload with href: String (the filter and input overloads take none) opens the address through LocalUriHandler.current after onClick; an app that routes addresses itself provides its own UriHandler. Compose has no link role for a clickable element (only link annotations inside text), so the node drops Role.Button and carries no role, and the README says so. target: TanreiLinkTarget = TanreiLinkTarget.Same; targetLabel is appended to the node's state description. Not built on this platform yet: the remove action out of the focus order, with the keys of CHP-19 told to assistive technology — here it is still a second stop after the chip (CHP-18, CHP-19, CHP-23); removable, default true — an input chip that draws no remove action while it is false (CHP-38); and a holder that gives a set of chips one stop takes each chip's own stops away (CHP-23). Lagging behind CHP-14 (the check drawn at comp.chip.check.weight): its check is drawn at sys.icon.weight. Kind is chosen by constructor: the default constructor is an action chip, .filter a filter chip, .input an input chip (Flutter's own FilterChip and InputChip names for the callbacks). isEnabled: false disables it, as Flutter's chips do. The remove action is its own Semantics node with the button flag. The link form, not built on this platform yet: the TanreiChip.link constructor (href is a Uri) has Semantics(link: true) with the address as its linkUrl. The package has no plugin dependency, so the address is opened by the nearest TanreiLinkOpener, an inherited widget the app provides once (calling url_launcher, or its own router); without one the control opens nothing and reports it in debug builds. target is a TanreiLinkTarget; targetSemanticLabel is the semantics hint. Not built on this platform yet: the remove action out of the focus order, with the keys of CHP-19 told to assistive technology — here it is still a second stop after the chip (CHP-18, CHP-19, CHP-23); removable, default true — an input chip that draws no remove action while it is false (CHP-38); and a holder that gives a set of chips one stop takes each chip's own stops away (CHP-23). Lagging behind CHP-14 (the check drawn at comp.chip.check.weight): its check is drawn at sys.icon.weight. The icon is the icon prop (a glyph name) and the avatar the avatar prop (an image source). The remove action is a second accessible Pressable with the button role, placed beside the chip's own rather than inside it, so a screen reader reaches it as its own element. The link form, not built on this platform yet: an action Chip with href has accessibilityRole="link" and opens the address with Linking.openURL after onPress, unless onPress called event.preventDefault(). target is "same" | "new"; targetLabel is the accessibilityHint. Not built on this platform yet: the remove action out of the focus order, with the keys of CHP-19 told to assistive technology — here it is still a second stop after the chip (CHP-18, CHP-19, CHP-23); removable, default true — an input chip that draws no remove action while it is false (CHP-38); and a holder that gives a set of chips one stop takes each chip's own stops away (CHP-23). Lagging behind CHP-14 (the check drawn at comp.chip.check.weight): its check is drawn at sys.icon.weight.

トークン

トークン 参照先 解決値(ライト)
--tanrei-comp-chip-avatar-shape sys.shape.corner.full 9999px
--tanrei-comp-chip-avatar-size-medium — 24px
--tanrei-comp-chip-avatar-size-small — 16px
--tanrei-comp-chip-check-weight sys.icon.mark.weight 500
--tanrei-comp-chip-container-gap-medium sys.space.space100 8px
--tanrei-comp-chip-container-gap-small sys.space.space50 4px
--tanrei-comp-chip-container-height-medium — 32px
--tanrei-comp-chip-container-height-small — 24px
--tanrei-comp-chip-container-padding-block-medium — 4px
--tanrei-comp-chip-container-padding-block-small sys.space.space25 2px
--tanrei-comp-chip-container-padding-inline-with-avatar-medium sys.space.space50 4px
--tanrei-comp-chip-container-padding-inline-with-avatar-small sys.space.space50 4px
--tanrei-comp-chip-container-padding-inline-with-icon-medium sys.space.space100 8px
--tanrei-comp-chip-container-padding-inline-with-icon-small sys.space.space75 6px
--tanrei-comp-chip-container-padding-inline-with-remove-medium sys.space.space50 4px
--tanrei-comp-chip-container-padding-inline-with-remove-small sys.space.space25 2px
--tanrei-comp-chip-container-padding-inline-medium sys.space.space200 16px
--tanrei-comp-chip-container-padding-inline-small sys.space.space100 8px
--tanrei-comp-chip-container-shape sys.shape.corner.full 9999px
--tanrei-comp-chip-disabled-opacity — 1
--tanrei-comp-chip-elevated-container-color sys.color.surface-container-lowest #ffffff
--tanrei-comp-chip-elevated-container-elevation sys.elevation.level2 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-chip-elevated-destructive-remove-container-color — #000000 · 0%
--tanrei-comp-chip-elevated-destructive-remove-icon-color comp.chip.elevated.remove.icon.color #4b4b4b
--tanrei-comp-chip-elevated-destructive-remove-state-layer-color sys.color.error #cd262f
--tanrei-comp-chip-elevated-disabled-container-color — #1b1b1b · 12%
--tanrei-comp-chip-elevated-disabled-container-elevation —
--tanrei-comp-chip-elevated-disabled-destructive-remove-container-color — #000000 · 0%
--tanrei-comp-chip-elevated-disabled-destructive-remove-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-destructive-remove-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-disabled-remove-container-color — #000000 · 0%
--tanrei-comp-chip-elevated-disabled-remove-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-remove-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-selected-container-color — #1b1b1b · 12%
--tanrei-comp-chip-elevated-disabled-selected-container-elevation —
--tanrei-comp-chip-elevated-disabled-selected-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-selected-label-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-disabled-selected-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-elevated-focused-container-color — #e8e8e8
--tanrei-comp-chip-elevated-focused-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-chip-elevated-focused-destructive-remove-container-color — #cd262f · 10%
--tanrei-comp-chip-elevated-focused-destructive-remove-icon-color — #cd262f
--tanrei-comp-chip-elevated-focused-destructive-remove-state-layer-color — #cd262f
--tanrei-comp-chip-elevated-focused-icon-color — #4b4b4b
--tanrei-comp-chip-elevated-focused-label-color — #1b1b1b
--tanrei-comp-chip-elevated-focused-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-focused-remove-container-color — #4b4b4b · 10%
--tanrei-comp-chip-elevated-focused-remove-icon-color — #4b4b4b
--tanrei-comp-chip-elevated-focused-remove-state-layer-color — #4b4b4b
--tanrei-comp-chip-elevated-focused-selected-container-color — #dadada
--tanrei-comp-chip-elevated-focused-selected-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-chip-elevated-focused-selected-icon-color — #262626
--tanrei-comp-chip-elevated-focused-selected-label-color — #262626
--tanrei-comp-chip-elevated-focused-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-focused-selected-state-layer-color — #262626
--tanrei-comp-chip-elevated-focused-state-layer-color — #1b1b1b
--tanrei-comp-chip-elevated-hovered-container-color — #ededed
--tanrei-comp-chip-elevated-hovered-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 4px 8px -4px rgb(0 0 0 / 0.04), 0px 16px 24px -8px rgb(0 0 0 / 0.06)
--tanrei-comp-chip-elevated-hovered-destructive-remove-container-color — #cd262f · 8%
--tanrei-comp-chip-elevated-hovered-destructive-remove-icon-color — #cd262f
--tanrei-comp-chip-elevated-hovered-destructive-remove-state-layer-color — #cd262f
--tanrei-comp-chip-elevated-hovered-icon-color — #4b4b4b
--tanrei-comp-chip-elevated-hovered-label-color — #1b1b1b
--tanrei-comp-chip-elevated-hovered-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-hovered-remove-container-color — #4b4b4b · 8%
--tanrei-comp-chip-elevated-hovered-remove-icon-color — #4b4b4b
--tanrei-comp-chip-elevated-hovered-remove-state-layer-color — #4b4b4b
--tanrei-comp-chip-elevated-hovered-selected-container-color — #dedede
--tanrei-comp-chip-elevated-hovered-selected-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 4px 8px -4px rgb(0 0 0 / 0.04), 0px 16px 24px -8px rgb(0 0 0 / 0.06)
--tanrei-comp-chip-elevated-hovered-selected-icon-color — #262626
--tanrei-comp-chip-elevated-hovered-selected-label-color — #262626
--tanrei-comp-chip-elevated-hovered-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-hovered-selected-state-layer-color — #262626
--tanrei-comp-chip-elevated-hovered-state-layer-color — #1b1b1b
--tanrei-comp-chip-elevated-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-chip-elevated-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-chip-elevated-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-pressed-container-color — #e8e8e8
--tanrei-comp-chip-elevated-pressed-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-chip-elevated-pressed-destructive-remove-container-color — #cd262f · 10%
--tanrei-comp-chip-elevated-pressed-destructive-remove-icon-color — #cd262f
--tanrei-comp-chip-elevated-pressed-destructive-remove-state-layer-color — #cd262f
--tanrei-comp-chip-elevated-pressed-icon-color — #4b4b4b
--tanrei-comp-chip-elevated-pressed-label-color — #1b1b1b
--tanrei-comp-chip-elevated-pressed-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-pressed-remove-container-color — #4b4b4b · 10%
--tanrei-comp-chip-elevated-pressed-remove-icon-color — #4b4b4b
--tanrei-comp-chip-elevated-pressed-remove-state-layer-color — #4b4b4b
--tanrei-comp-chip-elevated-pressed-selected-container-color — #dadada
--tanrei-comp-chip-elevated-pressed-selected-container-elevation — 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-chip-elevated-pressed-selected-icon-color — #262626
--tanrei-comp-chip-elevated-pressed-selected-label-color — #262626
--tanrei-comp-chip-elevated-pressed-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-pressed-selected-state-layer-color — #262626
--tanrei-comp-chip-elevated-pressed-state-layer-color — #1b1b1b
--tanrei-comp-chip-elevated-remove-container-color — #000000 · 0%
--tanrei-comp-chip-elevated-remove-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-chip-elevated-remove-state-layer-color comp.chip.elevated.remove.icon.color #4b4b4b
--tanrei-comp-chip-elevated-selected-container-color sys.color.secondary-container #eeeeee
--tanrei-comp-chip-elevated-selected-container-elevation sys.elevation.level2 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-chip-elevated-selected-icon-color sys.color.on-secondary-container #262626
--tanrei-comp-chip-elevated-selected-label-color sys.color.on-secondary-container #262626
--tanrei-comp-chip-elevated-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-elevated-selected-state-layer-color comp.chip.elevated.selected.label.color #262626
--tanrei-comp-chip-elevated-state-layer-color comp.chip.elevated.label.color #1b1b1b
--tanrei-comp-chip-focused-opacity — 1
--tanrei-comp-chip-hovered-opacity — 1
--tanrei-comp-chip-icon-size-medium sys.icon.medium 24px
--tanrei-comp-chip-icon-size-small sys.icon.small 20px
--tanrei-comp-chip-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-chip-motion-selection-duration sys.motion.role.selection.mark 250ms
--tanrei-comp-chip-motion-selection-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-chip-motion-state-duration-medium sys.motion.role.state.default 250ms
--tanrei-comp-chip-motion-state-duration-small sys.motion.role.state.compact 200ms
--tanrei-comp-chip-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-chip-outline-width sys.border.hairline 1px
--tanrei-comp-chip-outlined-container-color — #000000 · 0%
--tanrei-comp-chip-outlined-container-elevation sys.elevation.level0
--tanrei-comp-chip-outlined-destructive-remove-container-color — #000000 · 0%
--tanrei-comp-chip-outlined-destructive-remove-icon-color comp.chip.outlined.remove.icon.color #4b4b4b
--tanrei-comp-chip-outlined-destructive-remove-state-layer-color sys.color.error #cd262f
--tanrei-comp-chip-outlined-disabled-container-color — #000000 · 0%
--tanrei-comp-chip-outlined-disabled-container-elevation —
--tanrei-comp-chip-outlined-disabled-destructive-remove-container-color — #000000 · 0%
--tanrei-comp-chip-outlined-disabled-destructive-remove-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-destructive-remove-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-outline-color — #000000 · 8%
--tanrei-comp-chip-outlined-disabled-remove-container-color — #000000 · 0%
--tanrei-comp-chip-outlined-disabled-remove-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-remove-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-selected-container-color — #1b1b1b · 12%
--tanrei-comp-chip-outlined-disabled-selected-container-elevation —
--tanrei-comp-chip-outlined-disabled-selected-icon-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-selected-label-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-outlined-disabled-selected-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-chip-outlined-focused-container-color — #1b1b1b · 10%
--tanrei-comp-chip-outlined-focused-container-elevation —
--tanrei-comp-chip-outlined-focused-destructive-remove-container-color — #cd262f · 10%
--tanrei-comp-chip-outlined-focused-destructive-remove-icon-color — #cd262f
--tanrei-comp-chip-outlined-focused-destructive-remove-state-layer-color — #cd262f
--tanrei-comp-chip-outlined-focused-icon-color — #4b4b4b
--tanrei-comp-chip-outlined-focused-label-color — #1b1b1b
--tanrei-comp-chip-outlined-focused-outline-color — #000000 · 8%
--tanrei-comp-chip-outlined-focused-remove-container-color — #4b4b4b · 10%
--tanrei-comp-chip-outlined-focused-remove-icon-color — #4b4b4b
--tanrei-comp-chip-outlined-focused-remove-state-layer-color — #4b4b4b
--tanrei-comp-chip-outlined-focused-selected-container-color — #dadada
--tanrei-comp-chip-outlined-focused-selected-container-elevation —
--tanrei-comp-chip-outlined-focused-selected-icon-color — #262626
--tanrei-comp-chip-outlined-focused-selected-label-color — #262626
--tanrei-comp-chip-outlined-focused-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-outlined-focused-selected-state-layer-color — #262626
--tanrei-comp-chip-outlined-focused-state-layer-color — #1b1b1b
--tanrei-comp-chip-outlined-hovered-container-color — #1b1b1b · 8%
--tanrei-comp-chip-outlined-hovered-container-elevation —
--tanrei-comp-chip-outlined-hovered-destructive-remove-container-color — #cd262f · 8%
--tanrei-comp-chip-outlined-hovered-destructive-remove-icon-color — #cd262f
--tanrei-comp-chip-outlined-hovered-destructive-remove-state-layer-color — #cd262f
--tanrei-comp-chip-outlined-hovered-icon-color — #4b4b4b
--tanrei-comp-chip-outlined-hovered-label-color — #1b1b1b
--tanrei-comp-chip-outlined-hovered-outline-color — #000000 · 8%
--tanrei-comp-chip-outlined-hovered-remove-container-color — #4b4b4b · 8%
--tanrei-comp-chip-outlined-hovered-remove-icon-color — #4b4b4b
--tanrei-comp-chip-outlined-hovered-remove-state-layer-color — #4b4b4b
--tanrei-comp-chip-outlined-hovered-selected-container-color — #dedede
--tanrei-comp-chip-outlined-hovered-selected-container-elevation —
--tanrei-comp-chip-outlined-hovered-selected-icon-color — #262626
--tanrei-comp-chip-outlined-hovered-selected-label-color — #262626
--tanrei-comp-chip-outlined-hovered-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-outlined-hovered-selected-state-layer-color — #262626
--tanrei-comp-chip-outlined-hovered-state-layer-color — #1b1b1b
--tanrei-comp-chip-outlined-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-chip-outlined-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-chip-outlined-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-chip-outlined-pressed-container-color — #1b1b1b · 10%
--tanrei-comp-chip-outlined-pressed-container-elevation —
--tanrei-comp-chip-outlined-pressed-destructive-remove-container-color — #cd262f · 10%
--tanrei-comp-chip-outlined-pressed-destructive-remove-icon-color — #cd262f
--tanrei-comp-chip-outlined-pressed-destructive-remove-state-layer-color — #cd262f
--tanrei-comp-chip-outlined-pressed-icon-color — #4b4b4b
--tanrei-comp-chip-outlined-pressed-label-color — #1b1b1b
--tanrei-comp-chip-outlined-pressed-outline-color — #000000 · 8%
--tanrei-comp-chip-outlined-pressed-remove-container-color — #4b4b4b · 10%
--tanrei-comp-chip-outlined-pressed-remove-icon-color — #4b4b4b
--tanrei-comp-chip-outlined-pressed-remove-state-layer-color — #4b4b4b
--tanrei-comp-chip-outlined-pressed-selected-container-color — #dadada
--tanrei-comp-chip-outlined-pressed-selected-container-elevation —
--tanrei-comp-chip-outlined-pressed-selected-icon-color — #262626
--tanrei-comp-chip-outlined-pressed-selected-label-color — #262626
--tanrei-comp-chip-outlined-pressed-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-outlined-pressed-selected-state-layer-color — #262626
--tanrei-comp-chip-outlined-pressed-state-layer-color — #1b1b1b
--tanrei-comp-chip-outlined-remove-container-color — #000000 · 0%
--tanrei-comp-chip-outlined-remove-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-chip-outlined-remove-state-layer-color comp.chip.outlined.remove.icon.color #4b4b4b
--tanrei-comp-chip-outlined-selected-container-color sys.color.secondary-container #eeeeee
--tanrei-comp-chip-outlined-selected-container-elevation sys.elevation.level0
--tanrei-comp-chip-outlined-selected-icon-color sys.color.on-secondary-container #262626
--tanrei-comp-chip-outlined-selected-label-color sys.color.on-secondary-container #262626
--tanrei-comp-chip-outlined-selected-outline-color — #000000 · 0%
--tanrei-comp-chip-outlined-selected-state-layer-color comp.chip.outlined.selected.label.color #262626
--tanrei-comp-chip-outlined-state-layer-color comp.chip.outlined.label.color #1b1b1b
--tanrei-comp-chip-pressed-opacity — 1
--tanrei-comp-chip-remove-container-shape sys.shape.corner.full 9999px
--tanrei-comp-chip-remove-container-size-medium — 28px
--tanrei-comp-chip-remove-container-size-small — 24px
--tanrei-comp-chip-label-typescale-medium sys.typescale.label 500 14px/1.4286
--tanrei-comp-chip-label-typescale-small sys.typescale.label-small 500 12px/1.3333

フィクスチャ

基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。

生成元 specs/chip.spec.json, tokens/comp/chip.tokens.json, design/tokens/

ガイドライン

使う場面

関連する小さな選択肢を横に並べて見せるときに使います。リストの上の絞り込み、メッセージの下の返信候補、メールの宛先などです。10 個並べるにはボタンは重すぎ、チェックボックスはフォームの一部に見え、バッジやタグは押せません。

種類の選び方

kind は、チップが何をするか、つまりロールと構成要素を決めます。見た目は変わりません。

種類 何か 用途
Action(既定) ボタン。href があればリンク 日付の横の「カレンダーに追加」のような、内容に結び付いた補助アクション(assist)や、「いいですね」のような返信の提案(suggestion)。移動先があれば、関連するページへの近道。
Filter オンとオフを持つボタン リストの絞り込み。「ベジタリアン」「30 分以内」など。オンのときはチェックと選択時の色で示します。
Input ユーザーが入力した項目。取り除くアクションを持つ 宛先、タグ、検索語。アイコンの代わりにアバターも表示できます。

Material Design 3 にはチップが 4 系統あります。Tanrei では種類を 3 つにまとめています。assist と suggestion は、どちらもラベルと任意のアイコンを持つボタンなので、同じ action として扱います。提案のチップを控えめに見せたいデザインシステムは、専用のバリアントを追加します。

バリアントとサイズの選び方

バリアント 用途
Outlined(既定) 無地のサーフェスの上のチップ。輪郭は区切り線と同じ細い線で、チップを控えめに区切ります。意味を伝えるのはラベルです。
Elevated 写真や地図、込み入った背景の上。輪郭だけでは埋もれてしまう場所に使います。

たいていのチップは medium(32)にします。フィールドの中に並ぶ入力済みの項目や、表の上に並ぶ絞り込みなど、密度の高い場所では small(24)を使います。表の行の中に置く静的なラベルはタグです。どちらのサイズでも最小ターゲットは満たします。

チップ、タグ、バッジ

チップはコントロールです。押す、切り替える、取り除くといった操作を受け、フォーカスと状態を持ちます。タグは、ステータスやカテゴリーなど、1 つの項目に付ける静的なラベルで、ポインターには反応しません。バッジは、ほかの要素の角に付くドットや件数です。

  • 押す、選ぶ、取り除くものなら、チップを使います。
  • 付いている項目について何かを伝えるだけなら、タグを使います。
  • 何かの上に載る数字やドットなら、バッジを使います。

何もしないチップをラベルとして使わないでください。チップを無効にしてラベルの代わりにするのも避けます。

移動先のあるチップはリンク

移動先のあるコントロールはリンクです。押すとどこかへ移動するだけのアクションチップには href を指定します。チップはボタンではなく本物のリンクになり、Web ではアンカーになるので、新しいタブで開いたり、アドレスをコピーしたりできます。見た目はどの状態でもアクションチップとまったく同じで、訪問済みの状態はありません。

  • リンクのチップは Enter で移動します。Space では移動しません。Space はふつうのリンクと同じ働きをします。
  • 先に click が発火し、そのあとで移動先が開きます。クライアントサイドのルーターのように移動を自分で扱うなら、その click をキャンセルします。
  • target を new にすると、ラベルのあとに open_in_new のグリフを表示します。このとき targetLabel が必要です。名前のあとに読まれる言葉で、「新しいタブで開きます」などと書きます。Tanrei は言葉を同梱しません。
  • 無効なリンクのチップは移動できず、フォーカスの順序からも外れます。
  • リンクになれるのはアクションチップだけです。絞り込みチップは状態を持ち、入力チップは 2 つ目のアクションを持つので、どちらも href を無視し、デバッグビルドで報告します。

取り除くアクション

入力チップの末尾には、取り除くアクションがあります。塗りつぶしの cancel グリフを、それより少し大きい丸いコンテナに載せたもので、ホバー、フォーカス、押下の間はグリフの周りに輪として見えます。既定のシステムでは、丸いコンテナはチップの丸い端と同心で、端からの距離が上下からの距離と同じになります。丸いコンテナは自分の場所を取らないので、チップの幅も高さも変えません。取り除くアクションはチップとは別のボタンで、名前、ホバー・フォーカス・押下の状態、ヒット領域を自分で持ちます。ヒット領域は外側に向かって広がり、ラベルにはかかりません。このボタンを押すか、チップにフォーカスがある状態で Backspace か Delete を押すと、チップを取り除くよう求めます。チップは自分自身を取り除きません。 項目を取り除き、次のチップ、前のチップ、またはチップが属するフィールドへフォーカスを移すのは、利用者側のコードです。

取り除くアクションは、破壊的なアクションとして見せることができます(destructiveRemove。既定はオフです)。通常時の見た目はフラグがないときと同じで、ホバー、フォーカス、押下の間だけ、グリフとステートレイヤーがエラーの色になります。取り除くものの多くは、適用中の絞り込みや検索語のように、1 回の操作で元に戻せます。そのため、フラグを付けない限り、取り除くアクションは通常の見た目です。添付ファイルや招待済みの宛先のように、取り除くと 1 回の操作では戻せないものが失われる場所でフラグを付けます。Web では属性は destructive-remove です。このフラグが変えるのは色だけで、ほかの種類のチップでは無視されます。

読み取り専用のフィールドのエントリのように、いまは取り除けない入力チップは、取り除くアクションを描きません。removable を false にします。働かないアクションが残ることはなく、Backspace と Delete も何も求めず、チップの余白は取り除くアクションのないチップと同じになります。Web では、属性は反対の意味の not-removable です。ほかの種類のチップでは無視されます。

使われている場所は、チップフィールドです。エントリの 1 件ずつが、小さい入力チップです。チップフィールドでは、チップ全体で Tab が止まる場所を 1 つにし、専用のキーを用意して、求められたチップを取り除き、フォーカスを移します。Web では、チップをこのようにまとめるコンポーネントが、それぞれのチップに tabindex="-1" を設定します。チップと取り除くアクションは Tab の順序から外れますが、どちらもフォーカスは受け取れます。

推奨

  • ラベルは 1〜3 語程度に短くします。チップは 1 行のままで、レイアウトの幅が足りないときだけラベルを末尾で省略します。
  • 1 行に並べるチップのバリアントはそろえます。
  • 取り除くアクションのラベルには項目の名前を入れます。「削除」ではなく「山田 花子を削除」です。
  • 破壊的な見た目は、添付ファイルのように、取り除くと 1 回の操作では戻せないものが失われる場所にだけ付けます。絞り込みや検索語のように 1 回の操作で戻せる項目では、通常の見た目のままにします。
  • Web では、並べたチップをタググループに入れます。チップを折り返す行に並べ、チップの間に間隔を取り、全体を 1 つのリストとして伝えます。ほかのプラットフォームでは、またスクロールさせる並びでは、自分でレイアウトします。

非推奨

  • それだけで完結し、すぐに反映される設定に絞り込みチップを使わない。スイッチを使います。
  • 画面の主アクションにチップを使わない。ボタンかメインアクションボタンを使います。
  • アクションチップの click ハンドラーからページを移動しない。移動するチップには href を指定します。
  • 絞り込みの横に提案アクションを置くなど、1 行の中に種類を混ぜない。
  • 状態によって変わるラベルを絞り込みチップに付けない。状態は別に読み上げられます。

アクセシビリティ

ロール
button (link while an action chip has href)
ラベル付け
label is the chip's accessible name. An input chip's remove action is a separate button named by removeLabel, which names the item and the action ("Remove Ada Lovelace"), with or without destructiveRemove. The icon, the check, the cancel glyph and the avatar are decorative: a filter chip's state is announced from its pressed state, never from the check.
最小ターゲット
見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px

キーボード操作

キー 動作
Tab Moves focus to the chip. An input chip is one stop too: its remove action is not in the Tab order, and is reached by pointer, touch and assistive technology.
Enter / Space Activates the chip (a filter chip switches selected); on the remove action, removes the input chip. A link chip is activated by Enter alone: Space does what it does on any link (on the web it scrolls the page).
Backspace / Delete On a focused input chip, removes it (CHP-19). The chip tells assistive technology of these keys (on the web aria-keyshortcuts="Delete Backspace"), since its remove action is not met by Tab.

備考

  • A filter chip is a button with a pressed state (aria-pressed on the web, the selected trait on Apple platforms, a toggleable state on Android), as a toggle Button is, not a checkbox.
  • An input chip is two elements on every platform: the chip (role button) and its remove action (role button, named by removeLabel). On the web the remove action is a second `<button>` in the shadow root; on the other platforms it is its own accessibility element with its own hit area. It is one Tab stop: the remove action stays out of the Tab order, as the delete icon of MUI's Chip, the remove button of React Aria's TagGroup and the dismiss of Fluent's Tag do, and the keyboard removes the chip with Backspace or Delete on the chip itself, as a person who removes several entries in a row expects — one press each, without a second stop per chip to pass.
  • The chip does not group itself. A row of chips is laid out in wrapping lines, exposed as one list and given focus after a removal by the Tag group (TGR-1, TGR-7, TGR-9), or by the layout that holds the chips; one Tab stop with arrow keys, and single or multiple selection among filter chips, are a Tag group's that holds a selection (TGR-17 to TGR-21), or a Toolbar's.
  • destructiveRemove adds a color, never a meaning: the name removeLabel, the cancel glyph and the button role already say what the action does, so a person who cannot tell the error color from the resting one loses nothing (WCAG 1.4.1). The error glyph is a graphical object and keeps at least 3:1 against the chip's container in every scheme of the default system: the error role is held to 4.5:1 on every surface role by the token invariants, and the outlined chip shows a surface through its clear container while the elevated one is surface-container-lowest; under the state layer the lowest ratio is 3.98:1 (light scheme, on surface-container-highest, at the focus and pressed opacity).
  • The label does not wrap; at 200% text size the chip grows in height and the layout that holds a row lets it wrap to the next line or scroll.
  • How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.
  • In the default system the outline of an outlined chip is the hairline (the divider's color), far below 3:1 against the surface. That is within WCAG 1.4.11: the edge is not what identifies the chip. Its label is text held to 4.5:1, a selected filter chip is shown by its fill and its check, and focus by the focus ring. A product whose chips must show a 3:1 edge sets comp.chip.outlined.outline.color to sys.color.outline in a layer.
  • An action chip with a destination is a link: the link role, the platform's own link, Enter and not Space. A filter chip and an input chip take no destination. No visited state is drawn.
  • A link chip that opens a new context shows the open_in_new mark after its label and says so through targetLabel; the words are the product's.

生成元 specs/chip.spec.json, tokens/sys/measure.tokens.json

コンポーネントが担うこと

  • どのチップも、ボタンのロール、名前としてのラベル、無効状態を伝えます。アイコン、チェック、アバターは支援技術から隠します。
  • href のあるアクションチップは、同じ名前のまま、ボタンではなくリンクのロールを伝えます。新しいタブで開くリンクの印は支援技術から隠し、targetLabel をリンクの説明として、名前とロールのあとに読ませます。
  • 絞り込みチップは、トグルボタンと同じように、オンかどうかも伝えます(Web では押下状態、Apple のプラットフォームでは選択のトレイト、Android では切り替え可能な状態)。状態をチェックのグリフから読み上げることはありません。
  • 入力チップは 2 つの要素でできています。チップ本体と、取り除くアクションのラベルを名前とする独立したボタン、取り除くアクションです。ただし、フォーカスが止まるのはチップ本体の 1 か所だけです。Tab は取り除くアクションを飛ばし、取り除くアクションはポインター、タッチ、支援技術で押せます。チップ本体にフォーカスがあるときは、Backspace か Delete で取り除くよう求めます。そのことはチップが支援技術に伝えます(Web では aria-keyshortcuts で)。
  • Enter と Space でチップを実行し、取り除くアクションにフォーカスがあるときはそちらを実行します。リンクのチップは Enter だけで実行します。それぞれが自分のフォーカスインジケーターを、キーボードフォーカスのときだけ表示します。
  • チップのヒット領域は、どちらのサイズでも最小ターゲットを満たします。取り除くアクションも自分のヒット領域で最小ターゲットを満たし、ラベルにはかかりません。
  • 破壊的な見た目だけに頼ることはありません。destructiveRemove がオンでもオフでも、取り除くアクションのロール、名前、グリフ、大きさ、ヒット領域は変わらず、読み上げも増えません。何をするかは「山田 花子を削除」という名前が伝えます。
  • ラベルが省略されても、アクセシブルネームは全文のままです。文字を大きくすると、チップは縦に伸び、ピル形のままです。
  • 既定のシステムでは、Outlined のチップの輪郭は区切り線と同じ細い線で、サーフェスに対するコントラストは 3:1 に届きません。チップを見分ける手がかりは輪郭ではありません。ラベルは十分なコントラストのテキストで、選択中の絞り込みチップは塗りとチェックで、フォーカスはフォーカスリングで示します。3:1 の輪郭が必要なプロダクトは、レイヤで comp.chip.outlined.outline.color を sys.color.outline にします。
  • ラベルがない場合、入力チップに取り除くアクションのラベルがない場合、新しいタブで開くリンクに targetLabel がない場合、絞り込みチップや入力チップに移動先を指定した場合、未知の種類を指定した場合は、デバッグビルドで報告します。未知の種類はアクションチップとして描画され、動作します。

プラットフォームごとの既知の制約:

  • React Native:Backspace と Delete はキーイベントで受け取っていますが、iOS と Android で実際に届くかは実機でまだ確かめていません。いずれにしても、取り除くアクションには Tab で届きます。
  • React Native:VoiceOver と TalkBack がチップ本体と取り除くアクションを 2 つの要素としてこの順にたどるか、また取り除くアクションのヒット領域は、実機なしのテストでしか確かめていません。Android ではヒット領域が親ビューの外に出られないため、入力チップの並びの周りには余白を取ってください。
  • Flutter:取り除くアクションのヒット領域はチップの末尾より外まで届き、Flutter はその分だけ入力チップのレイアウト幅を広げます。そのため、入力チップを並べると間隔が少し広くなります。
  • Compose:取り除くアクションのヒット領域は、チップの幅を広げずにチップの末尾より外まで届きます。そのため、すぐ後ろに置いたチップと重なる部分では、後ろのチップが押されます。そこへのタッチ、プラットフォームのキー処理を通したキー操作、TalkBack は Robolectric 上でしか確かめておらず、実機ではまだ試していません。
  • SwiftUI:チップ本体での Backspace と Delete、チップ本体から取り除くアクションへの Tab は、部分ごとにはテストしていますが、通しではまだ動かしていません。押すとコントロールが薄くなるシステム(cupertino)では、取り除くグリフがチップより 1 フレーム遅れて薄くなります。
  • SwiftUI と Compose では、文字を大きくするとラベルは大きくなりますが、アイコン、チェック、取り除くグリフ、アバターは元の大きさのままです。ラベルに合わせて大きくすべきかは、まだ決まっていません。
  • 以前の版を提供している SwiftUI、Compose、Flutter、React Native では、入力チップの取り除くアクションがまだチップの次の 2 か所目のフォーカス位置で、Backspace と Delete で取り除けることも支援技術に伝えていません。追いついたときに、取り除くアクションをフォーカス順から外します。
  • Web は、チェックと取り除くグリフを、仕様が名前を挙げるアイコンセットの check と cancel で描きます(CHP-13、CHP-18)。以前の版を提供している SwiftUI、Compose、Flutter、React Native は、取り除くアクションをまだ close で描き(Flutter は Material Symbols のコードポイントで指定しています)、アイコンフォントがない場合、Compose と SwiftUI はチェックとバツを独自のベクターで描きます。それぞれ、追従した時点で cancel と check を名前で描き、独自のベクターは描かなくなります。

利用者側で行うこと

  • ユーザーが入力チップを取り除いたら、チップを取り除き、隣のチップかフィールドへフォーカスを移します。チップは求めるだけで、その後は何もしません。
  • 入力チップには、項目の名前を含む取り除くアクションのラベルを必ず付けます。「削除」とだけ読み上げられるボタンが並ぶと、どれがどの項目のものか区別できません。
  • 新しいタブやウィンドウで開くリンクのチップには、プロダクトの言語で targetLabel を付けます。
  • 絞り込みチップの並びには、何を絞り込むのかが分かる見出しかグループ名を付けます。
  • 矢印キーでチップ間を移動するなど、並び全体のキーボード操作が必要なら自分で用意します。各チップが扱うのは Tab、Enter、Space と、入力チップでの Backspace と Delete だけです。