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

アコーディオン

行を押すと、その場でコンテンツを表示したり隠したりします。項目が 1 つなら単独のディスクロージャーで、複数なら、それぞれが独立して開くか、一度に 1 つだけ開くセットです。

content_copyMarkdown で表示
カテゴリ
コンテインメント
トークン
comp.accordion
レベル
基礎

概要

Web
tanrei-accordion
schedule
SwiftUI
TanreiAccordion
radio_button_unchecked
Jetpack Compose
TanreiAccordion
radio_button_unchecked
Flutter
TanreiAccordion
radio_button_unchecked
React Native
Accordion
radio_button_unchecked

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

ヘルプページの質問:Outlined で、項目が 1 つ開いた状態

デザイントークンとは何ですか? 名前を付けたデザイン上の決定です。色、サイズ、時間などがあります。コンポーネントはトークンを読み、値を直接書くことはありません。

どのプラットフォームに対応していますか? Web Components、SwiftUI、Jetpack Compose、Flutter、React Native です。どれも同じ 1 組のトークンと仕様から作られます。

見た目を変えるにはどうすればよいですか? レイヤを使います。ダイヤルと、プロダクトに必要な場合は個別のトークンを設定するファイルです。

アコーディオンは、ページの一部を行の下に折りたたみ、その行で表示したり隠したりします。ヘルプページの回答、設定画面のセクション、フォームの詳細設定などです。項目が 1 つだけならディスクロージャーで、これも同じコンポーネントです。ナビゲーションドロワーの中で開く行き先のグループは、ドロワー自身のグループです。1 つの場所のビューを切り替えるものは、タブです。

Web では、プロダクト側のネイティブの <details> 要素を <tanrei-accordion> で囲みます。この要素はシャドウルートを持ちません。そのため各項目は、スクリプトが動く前から開閉でき、フォーカスを受け取り、展開状態を伝え、閉じているコンテンツをページの中に保ちます。ほかのプラットフォームはまだ実装していません。

使い方

<link rel="stylesheet" href="@tanrei/web/icons.css" />
<link rel="stylesheet" href="@tanrei/web/accordion.css" />

<tanrei-accordion variant="outlined">
  <details open>
    <summary>
      <span class="tanrei-icon" aria-hidden="true">palette</span>
      色
      <span data-supporting-text>ロール、パレット、6 つのスキーム</span>
      <span data-trailing-text>48 ロール</span>
    </summary>
    <p>コンポーネントが読む色は、すべてロールです。</p>
  </details>
  <details>
    <summary>書体</summary>
    <p>スタックは、テキスト用に 1 つ、コード用に 1 つです。</p>
  </details>
</tanrei-accordion>

<script type="module">
  import '@tanrei/web/components/accordion';
</script>
import { Accordion } from '@tanrei/react';
import '@tanrei/web/icons.css';
import '@tanrei/web/accordion.css';

<Accordion density="compact" exclusive>
  {sections.map((section) => (
    <details key={section.id} onToggle={(event) => track(section.id, event.currentTarget.open)}>
      <summary>
        {section.name}
        <span data-trailing-text>{section.count}</span>
      </summary>
      {section.content}
    </details>
  ))}
</Accordion>

@tanrei/web/accordion.css は、スクリプトが動く前に、見た目のすべてとすべての状態を描きます。要素自身も同じスタイルシートをページに加えるので、スクリプトだけを読み込んだページでも、少し遅れてアコーディオンが描かれます。シェブロンと項目のアイコンはアイコンセットのグリフなので、@tanrei/web/icons.css とアイコンフォントが必要です。

書くもの

パーツ Web での書き方
項目 <details>。open は、この要素自身の属性でありプロパティです。
ヘッダー 項目の最初に置く <summary>。全体が 1 つのボタンです。
ラベル <summary> のテキスト。
見出しにするラベル、インラインのコンテンツを含むラベル テキストの代わりに置く 1 つの要素。<summary><h3>請求</h3></summary> や <summary><span><code>tokens.css</code> を使う</span></summary> のように書きます。
補足テキスト <summary> の中の、data-supporting-text を付けた要素。
末尾のテキスト <summary> の中の、data-trailing-text を付けた要素。
アイコン <summary> の最初に置く <span class="tanrei-icon" aria-hidden="true">。中にグリフの名前を書きます。
コンテンツ <summary> より後ろのすべて。テキスト、利用者側のブロック、任意のコンポーネント、別のアコーディオンを置けます。
無効な項目 <summary aria-disabled="true" tabindex="-1">。
項目のイベント 項目自身の toggle。バブリングはしません。event.newState は "open" か "closed" です。

ブラウザーは、open が変わるたびに toggle を送ります。利用者側のコードが変えたときも、解析したばかりの <details open> をブラウザーが開いたときも同じです。open を自分で設定するコードは、設定した状態と照らし合わせて、自分の変更かどうかを見分けます。

Markdown

Markdown レンダラーは、<details> を HTML としてそのまま通します。ソースの中で 1 つまたは複数の <details> を <tanrei-accordion> で囲むか、テーブルのページがテーブルについて示しているように、ビルド時に囲みます。

仕様

compact で、2 行目と末尾の値がある場合:パネルの中の折りたたみ

テキスト本文、ラベル、見出しInter, Noto Sans JP フォントスタックを、優先する順に並べたものです。

コードコードブロックとインラインコードRoboto Mono フォントスタックを、優先する順に並べたものです。

継承したルール12 12 個のルールを、これより下のレイヤから継承しています。

一度に開くのは 1 つだけで、項目ごとに縁がある場合

色 ロール、パレット、6 つのスキーム。

通知 メール、プッシュ通知、週に 1 回のまとめ。

アカウント 名前、住所、パスワード。

構成要素

パーツ 説明
1 accordion The column that holds the items. It draws nothing of its own in the plain look and adds no space around the items; in the outlined look with a line between the items it carries the one edge around them all. It has no role and no name.
2 item One header and the content it shows and hides (an item of the item kind). Open or closed by itself; in the outlined look with a gap between the items it carries an edge of its own.
3 container An item's header: the row across the item's width that opens and closes it. One button. It carries hover, focus and press and is the hit area; it has no fill at rest in the default system.
4 icon · 任意 A glyph of the system's icon set at the start of the header, by name. Decorative, and the same open and closed.
5 label The item's name and the header's accessible name. Plain text unless the product gives a heading; it wraps and is never cut.
6 supporting-text · 任意 A line under the label that says what the item holds, quieter than the label. It wraps.
7 trailing-text · 任意 A short value before the chevron, readable without opening the item: a count, the present value of what the item holds. One line.
8 chevron The icon set's expand_more at the end of the header, turned half a turn while the item is open: the only mark of open and closed. Hidden from assistive technology, which is given the state in words.
9 content What the item shows while open, under its header and inset to the header's first part: the product's content, from one sentence to fields, a table or another accordion. Not drawn, not focusable and not exposed while the item is closed, and still part of the document where the platform has one.
10 outline · 任意 The outlined look's edge: one hairline with rounded corners around the whole accordion, or around each item where the items are parted by a gap.
11 divider · 任意 A hairline across the accordion between two items, where the items are ruled by a line.
12 focus-ring Gap-then-ring indicator shown for keyboard focus of a header, drawn inside the header's row.

プロパティ

プロパティ 型 既定値 説明
variant plain | outlined "plain" How the accordion stands on its surface. plain: rows on the surface, with nothing around them; for content in the flow of a page or a panel. outlined: bounded by one hairline with rounded corners; for a set that should read as one block among others, and on a surface where rows alone would be lost. A design system may add values.
density regular | compact "regular" How much room a header takes, in a table's words. regular (a 56 header with a 16 label in the default system) is for a page a person reads: the questions of a help page, the sections of a long form. compact (a 48 header with a 14 label, a navigation drawer row's) is for a panel among controls: settings, an inspector, a card. A design system may add values.
separation auto | divider | gap "auto" How an item is told from the item next to it. divider: one hairline between them; in the outlined look the items share one edge. gap: empty space and no line; in the outlined look each item has an edge of its own. Auto takes comp.accordion.separation, the design system's answer (divider in the default system).
exclusive boolean false Whether opening an item closes the one that was open, so that at most one item of this accordion is open. False, the default, lets every item open and close by itself: a reader may compare two answers, and nothing moves that they did not touch. True is for items that exclude each other (the steps of one choice). An open item can always be closed again, leaving none open.

アイテム

このコンポーネントが繰り返すアイテムの種類です。フィクスチャはアイテムを順に並べ、各プラットフォームはそれぞれの流儀で種類ごとに名前を付けます。

item

One header and the content it shows and hides. The fixture's content is the text of its content.

プロパティ 型 既定値 説明
label string "" Its name, drawn in its header and used as the header's accessible name. Plain text, never a heading; the label slot takes its place where the product needs a heading of its own level or inline content. Required unless the label slot is filled.
supportingText string "" A line under the label that says what the item holds ("Email, push and the weekly digest"), read as the header's description. Empty draws the label alone.
trailingText string "" A short value before the chevron that can be read without opening the item: a count, the present value. One line; read after the supporting text as the header's description.
icon string "" The name of a glyph in the system's icon set, drawn at the start of the header. Decorative.
open boolean false Whether its content is shown under its header. Set by the product for an item that starts open; the web sets it itself when the user opens or closes the item, and a controlled platform leaves it to the caller.
disabled boolean false Makes its header unavailable: it keeps its place and its open, draws its disabled look, cannot be toggled and leaves the focus order. The content of an open disabled item stays shown and as usable as the product made it.
スロット 説明
label The product's own label content in place of the label prop: text with inline content (a code span, a tag), or a heading of the level the page's outline needs. The accordion draws it in the label's style and changes neither its role nor its level. No control.
default The content: text, or the product's own blocks (paragraphs, fields, a table, any component, another accordion). The accordion insets it and gives it no style.
イベント 説明
toggle The item opened or closed: by the user from its header, by the accordion closing it for another (exclusive), or by the platform's search finding text in it; carries its new open state. Emitted exactly once per change, when the change begins.
仕様 Web SwiftUI Jetpack Compose Flutter React Native
アイテム details TanreiAccordionItem TanreiAccordionItem TanreiAccordionItem AccordionItem
label · プロパティ summary title label label label
supportingText · プロパティ data-supporting-text supportingText supportingText supportingText supportingText
trailingText · プロパティ data-trailing-text trailingText trailingText trailingText trailingText
icon · プロパティ tanrei-icon icon icon icon icon
open · プロパティ open isExpanded expanded expanded open
disabled · プロパティ aria-disabled disabled enabled enabled disabled
toggle · イベント toggle isExpanded onExpandedChange onExpansionChanged onToggle
備考 A native <details> whose first child is its <summary>. The summary's content is the label (the label slot): text, inline content, or a heading (<summary><h3>…</h3></summary>, which HTML allows). Inside the summary, an element with data-supporting-text holds the supporting text and one with data-trailing-text the trailing text; a .tanrei-icon element first in the summary is the icon. open is the element's own attribute and property, and toggle its own event (not bubbling; event.newState is open or closed), which the browser also sends when the product changes open — a product that sets open itself tells its own changes by the state it set. A disabled item is written <summary aria-disabled="true" tabindex="-1">: the stylesheet draws it and takes the pointer from it, tabindex takes it from the focus order, and the script refuses what is left. TanreiAccordionItem(_ title: String, supportingText: String = "", trailingText: String = "", icon: String? = nil, isExpanded: Binding<Bool>) { content }, as SwiftUI's DisclosureGroup binds its state and as TanreiNavigationDrawerGroup does; toggling writes the binding. A second initializer takes the label as a @ViewBuilder (the label slot; .accessibilityAddTraits(.isHeader) is the product's). disabled follows .disabled(_:). TanreiAccordionItem(label, expanded, onExpandedChange, supportingText = "", trailingText = "", icon = null, enabled = true, labelContent = null) { content }, the names of TanreiNavigationDrawerGroup; the header has Modifier.semantics { expand() / collapse() } and the expanded state. enabled is the inverse flag; labelContent is the label slot. TanreiAccordionItem(label:, supportingText: '', trailingText: '', icon:, expanded:, onExpansionChanged:, enabled: true, labelWidget:, child:), controlled, with the callback name of TanreiNavigationDrawerGroup; the header carries Semantics(button: true, expanded:). labelWidget is the label slot. <AccordionItem label="…" open={…} onToggle={…}>…</AccordionItem>, with the names of NavigationDrawerGroup; controlled when open is given, and defaultOpen otherwise. The label slot is the labelContent prop; the content is children. The header sets accessibilityRole="button" and accessibilityState={{ expanded, disabled }}.

状態

振る舞い

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

ID 要件
ACC-1 THE accordion SHALL lay out its items in one column, in the order given, each as wide as the accordion, and the accordion as wide as the layout it is placed in gives it: in a page, in a card, in a dialog, in a panel and in another item's content alike, with its start edge on the start edge of what is around it. It SHALL bring no outer space of its own (PRS-15: the space between it and its neighbours is its container's), SHALL have no minimum width, no maximum width and no height of its own, and SHALL NOT scroll: it is as tall as its headers and its open content, and content that cannot shrink scrolls inside its own box. An accordion of one item is a single disclosure and SHALL differ in nothing from an item of a set.
ACC-2 THE accordion SHALL draw each item as a header and, WHILE the item is open, its content below the header (ACC-8). A header is one row across the item's whole width, at least as high as its density gives (comp.accordion.container.height.regular for regular and comp.accordion.container.height.compact for compact) and growing with its text, padded at its start and end by comp.accordion.container.padding-inline.regular for regular and comp.accordion.container.padding-inline.compact for compact and above its first line and below its last by comp.accordion.container.padding-block.regular for regular and comp.accordion.container.padding-block.compact for compact. Inside it SHALL lay out, from the start: the icon, where the item has one (ACC-5); the text, a column that takes the remaining width and holds the label (ACC-3) and under it the supporting text (ACC-4); the trailing text, where it has one (ACC-4); and the chevron (ACC-6); with comp.accordion.container.gap between each two of them. THE accordion SHALL centre the icon, the trailing text and the chevron on the label's first line and keep them there however tall the text grows, and any height a header has beyond its text SHALL be shared equally above and below it.
ACC-3 THE accordion SHALL draw an item's label in the text style of its density (comp.accordion.label.typescale.regular for regular and comp.accordion.label.typescale.compact for compact) and the label color of its variant (comp.accordion.plain.label.color for plain, comp.accordion.outlined.label.color for outlined); the label SHALL wrap and SHALL never be cut. WHERE the item's label slot holds content THE accordion SHALL draw that content in the label's place, style and color instead of the label, and SHALL change neither its role nor its level: a label given as text is plain text and never a heading, and a label the product gives as a heading stays a heading of the level the product gave it, drawn as every other label is. The label slot SHALL hold text, inline content or a heading and no control: IF it holds a link, a button or a field THE accordion SHALL still render it and in debug builds report that a header is one button and holds no other. THE accordion SHALL set the label's letter-spacing by the script of its text, as every title is set (PRS-20): no negative letter-spacing WHERE its language is Chinese, Japanese or Korean, and none WHERE its script joins its letters or stacks marks on them.
ACC-4 WHILE an item's supportingText is not empty THE accordion SHALL draw it under the label, in the text style of its density (comp.accordion.supporting-text.typescale.regular for regular and comp.accordion.supporting-text.typescale.compact for compact) and the supporting-text color of its variant (comp.accordion.plain.supporting-text.color, comp.accordion.outlined.supporting-text.color); it SHALL wrap and SHALL never be cut, and the header SHALL grow to hold it. WHILE an item's trailingText is not empty THE accordion SHALL draw it on one line between the text and the chevron, in the text style of its density (comp.accordion.trailing-text.typescale.regular for regular and comp.accordion.trailing-text.typescale.compact for compact) and the trailing-text color of its variant (comp.accordion.plain.trailing-text.color, comp.accordion.outlined.trailing-text.color); it SHALL NOT wrap, and WHILE it would take more than half of the header's inner width it SHALL be cut at the end of its own direction with an ellipsis, so that the label always keeps at least half.
ACC-5 WHILE an item's icon is not empty THE accordion SHALL draw that glyph of the system's icon set at the start of the header, in a box of comp.accordion.icon.size.regular for regular and comp.accordion.icon.size.compact for compact, in the icon color of its variant (comp.accordion.plain.icon.color, comp.accordion.outlined.icon.color), with sys.icon.family.unselected and sys.icon.fill.unselected, sys.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max, and SHALL keep it from assistive technology. WHILE icon is empty THE accordion SHALL draw no glyph and keep no room for one: the label starts at the start padding. The icon SHALL be the same glyph whether the item is open or closed.
ACC-6 THE accordion SHALL draw a chevron at the end of every header: the icon set's expand_more in a box of comp.accordion.chevron.size.regular for regular and comp.accordion.chevron.size.compact for compact, in the chevron color of its variant (comp.accordion.plain.chevron.color, comp.accordion.outlined.chevron.color), drawn as ACC-5 draws a glyph, turned half a turn WHILE the item is open, and kept from assistive technology, which is given the item's state in words (ACC-24). The chevron SHALL be the only thing about a header that shows whether its item is open: the header's container, label, texts and icon SHALL be the same open and closed. A disabled item SHALL keep its chevron.
ACC-7 THE accordion SHALL draw an item's open as the state of that item alone: WHILE open is true its content is shown under its header, and WHILE open is false its content is not drawn, takes no space, cannot take focus and is not exposed to assistive technology. WHEN the accordion first appears it SHALL draw every item as its open says, in its first frame, without the motion of ACC-13 and without emitting toggle. A closed item's content SHALL stay what it was: on a platform that keeps what it does not draw (the web, where the content stays in the document, a field in it keeps its value and is still sent with its form) THE accordion SHALL NOT remove, rebuild or reset it when the item closes or opens; on a platform that builds only what is drawn, the content is built again when the item opens, and state that must outlive a close is the product's to hold.
ACC-8 WHILE an item is open THE accordion SHALL draw the content of its default slot under its header, inset at its start and end by the header's inline padding (comp.accordion.container.padding-inline.regular for regular and comp.accordion.container.padding-inline.compact for compact), so that it starts under the first part of the header, with no space above it and comp.accordion.content.padding-block-end.regular for regular and comp.accordion.content.padding-block-end.compact for compact below it. The content is the product's: THE accordion SHALL give it no text style and no color, which it takes from where the accordion stands, SHALL add no style to anything inside a component placed in it (PRS-16), and SHALL neither cut it nor limit its height. The content SHALL be held whole by the item: a margin of its first or last part is space inside the content, under the header and above the space below the content, and SHALL NOT reach out of the item. WHILE the item is open it is one target (ACC-36), and its hovered, focused and pressed states are the whole item's: THE accordion SHALL draw the container color of that state under the content as under the header (ACC-17) and SHALL give the content the state's opacity, and SHALL change nothing else about it — not its box, its text style or its color.
ACC-9 WHILE variant is plain THE accordion SHALL draw no edge and no fill of its own: its headers are rows on the surface it stands on, in the colors of the plain look (comp.accordion.plain.container.color and the plain tokens ACC-3 to ACC-6 name). WHILE variant is outlined THE accordion SHALL draw an edge comp.accordion.outline.width wide in comp.accordion.outline.color with corners comp.accordion.outline.shape, inside the size of what it bounds and without moving anything in it — around the whole accordion WHILE its separation is divider, and around each item WHILE it is gap (ACC-10) — SHALL clip the headers' containers, their state layers and the content to that edge's corners, and SHALL draw its headers in the colors of the outlined look (comp.accordion.outlined.container.color and the outlined tokens ACC-3 to ACC-6 name). The variant SHALL change the edge and these colors and nothing else.
ACC-10 THE accordion SHALL tell an item from the item next to it as its separation names: WHILE separation is auto, as comp.accordion.separation names, which follows sys.behavior.separation unless a design system sets it apart; WHILE separation is divider or gap, as that value names, whatever the tokens say. WHILE it is divider THE accordion SHALL draw one line of comp.accordion.divider.thickness in comp.accordion.divider.color across its whole width between every two items that follow each other, under the first one's content WHILE that item is open and under its header WHILE it is closed, without adding to an item's height, and SHALL draw no line above the first item or below the last. WHILE it is gap it SHALL leave comp.accordion.item.gap of empty space between every two items that follow each other, SHALL draw no such line, and SHALL leave no such space above the first item or below the last. WHEN separation, or the token it follows, changes THE accordion SHALL draw the other form at once, without animation, keeping every item's open; WHEN separation names a value the accordion does not define it SHALL treat it as auto and in debug builds report the unknown value. A platform that cannot draw a choice SHALL fall back to the first value, divider, and state that in its README.
ACC-11 WHEN the user activates the header of an item that is not disabled by pointer, touch, Enter or Space THE accordion SHALL emit that item's toggle exactly once with its new open state, and on the web SHALL set the item's open itself (a controlled platform leaves it to the caller). WHEN focus is on the header of a closed item and the user presses the arrow key toward the end of the line (Right in a left-to-right layout) THE accordion SHALL open the item in the same way, and on the header of an open item the arrow key toward the start SHALL close it; the arrow key that would do neither, and every other key, SHALL be left to the platform. THE accordion SHALL NOT move focus from one header to another by an arrow key: every header is a stop of its own in the focus order, as a navigation drawer's group rows are. Activating a header SHALL NOT move focus, and focus SHALL stay on the header while its item opens and closes.
ACC-12 WHILE exclusive is true THE accordion SHALL keep at most one of its own items open: WHEN an item opens, by the user's act, by the product setting its open or by ACC-16, THE accordion SHALL close the item that was open, emitting that item's toggle exactly once with false and on the web setting its open itself (a controlled platform leaves it to the caller), in the same motion as the one that opens (ACC-13). An open item SHALL still close by its own header, leaving none open. The items of an accordion placed inside an item's content SHALL NOT count: each accordion keeps its own. WHEN the accordion first appears, or exclusive becomes true, with more than one item open THE accordion SHALL draw the first of them in order open and the others closed, on the web setting their open itself, and in debug builds report that an exclusive accordion was given several open items. WHILE exclusive is false every item SHALL open and close by itself.
ACC-13 WHEN an item's open changes THE accordion SHALL reveal or hide its content from the header downward, the item growing or shrinking in height and everything after it moving with its lower edge, and SHALL turn the chevron, over comp.accordion.motion.disclosure-duration with comp.accordion.motion.disclosure-easing, at once where motion is reduced. The content SHALL be laid out once, at the width and height it has when shown, and the motion SHALL only change how much of it is seen: its lines SHALL NOT wrap again, its parts SHALL NOT be resized and nothing in it SHALL be measured again from frame to frame. The item's height SHALL go from its height at rest before the change to its height at rest after it with no jump at the start or at the end, whatever margins the content's first and last parts have. Content that is being hidden SHALL stay drawn until the motion ends and SHALL leave the focus order and assistive technology when the motion begins. WHEN open changes again before the motion ends THE accordion SHALL go on from where the motion is toward the new state, without a jump. toggle SHALL be emitted when the change begins, not when the motion ends.
ACC-14 WHEN items open and close in answer to the user's act on a header THE accordion SHALL keep that header where it is in the view, as far as the scrolling of what holds it allows, and move only what follows it: IF another item above it closes at the same time (ACC-12) THE accordion SHALL hold the activated header's place while the content above it goes, so that the row under the pointer or the finger does not move away from it. It SHALL NOT scroll for any other reason: an item that opens SHALL NOT be scrolled into view, and its content MAY reach below the view's edge.
ACC-15 WHEN an item closes while keyboard focus is inside its content THE accordion SHALL move focus to that item's header or, WHILE the item is disabled, leave focus to the platform's default; WHEN it closes while focus is elsewhere it SHALL NOT move focus.
ACC-16 WHERE the platform can search the text of what is shown and reports a match that lies in content it does not draw, or goes to a place inside such content (on the web, the browser's find-in-page and a link to a fragment of the page), WHEN the match or the place is inside a closed item THE accordion SHALL open that item, and every closed item of an accordion that holds it, at once and without the motion of ACC-13, SHALL emit each one's toggle exactly once with true, SHALL apply ACC-12 to each, and SHALL leave bringing the match into view to the platform; it SHALL do so for a disabled item too, whose header is unavailable and whose content is still part of the page. On a platform that has no such search or cannot report such a match, a closed item's content is not found, and THE accordion SHALL NOT open anything for it.
ACC-17 WHILE an item's header is hovered, keyboard-focused or pressed THE accordion SHALL render that header's container, label, supporting text, trailing text, icon, chevron and opacity from the component tokens of its variant in the highest-precedence active state, with precedence pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state. Hover and press over any part of the header's row SHALL answer on the whole container. WHILE the item is open THE accordion SHALL draw these states on the whole item, which is one target (ACC-36): the item's container — under the header and the content, to the item's edges — takes the state's container color and the header's parts its colors, whether the pointer is over the header or over the content where a press would close the item (ACC-36); over a descendant of the content that takes a press itself, the item SHALL show no hovered state of its own. The edge and the lines SHALL NOT change under a pointer, a press or focus.
ACC-18 WHEN an item's header receives keyboard focus THE accordion SHALL show the focus ring inside the header's container, following comp.accordion.container.shape, while the item is closed, and WHILE it is open around the whole item, which is one target (ACC-36) — inside the item's edge, around the header and the content together, following the item's corners (the outlined look's at the set's corners, none elsewhere) — so that neither a neighbouring item, an outlined edge nor a scrolling ancestor cuts it, without animation; focus gained by pointer or touch SHALL NOT show it.
ACC-19 WHERE a header is lower than the minimum target THE accordion SHALL make its container at least sys.target.touch tall for touch input and sys.target.pointer tall for fine pointers, because rows that touch cannot extend a hit area over each other; a platform that cannot tell the input type SHALL use sys.target.touch. The whole row, from the item's start edge to its end edge, its paddings, icon, texts and chevron included, SHALL be the header's hit area; WHILE the item is open, its content, down to the item's lower edge, SHALL be part of the item's hit area too: the open item is one target, as ACC-36 says.
ACC-20 WHILE an item's disabled is true THE accordion SHALL render its header's container, label, supporting text, trailing text, icon, chevron and opacity from the disabled component tokens of its variant, SHALL NOT emit its toggle for a press, a key or a touch, SHALL NOT make its header focusable and SHALL expose the header as disabled. The item SHALL keep its place and its open: a disabled item that is open still shows its content, which stays as usable as the product made it, and the product MAY still set its open. A header that draws no fill at rest SHALL draw none while disabled.
ACC-21 WHEN an item's header is pressed by pointer, touch, Enter or Space THE accordion SHALL show its pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner.
ACC-22 WHILE an item's header is pressed THE accordion 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, clipped to the container, from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole header 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; label, supporting text, trailing text, icon, chevron and opacity still come from the pressed tokens. Under none every part stays with the state under the press. WHILE the item is open the press is the whole item's (ACC-36), by its header or its content: overlay paints the pressed container color on the whole item, ripple grows the layer over the whole item from the point of contact (from the item's center for a key), and the pressed opacity applies to the content as to the header. The ripple grows over comp.accordion.motion.feedback-duration with comp.accordion.motion.state-easing, fades over comp.accordion.motion.state-duration with comp.accordion.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced.
ACC-23 THE accordion SHALL ease its headers' container corners and the outlined look's 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 a header's keyboard focus as sys.behavior.focus-style names (ring or glow), around the header while its item is closed and around the whole item while it is open (ACC-18); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
ACC-24 THE accordion SHALL expose each item's header as one button named by its label (the text of the label slot's content where the product gave one), described by its supporting text and then its trailing text, with its expanded or collapsed state, the disabled state where it applies, and its icon and chevron hidden; and SHALL expose an open item's content after its header in reading order, as the content it is. On the web the header is the summary of a details element, which the browser exposes as a button with the expanded state; on Apple platforms a button whose value is expanded or collapsed, as a disclosure group reads; on Android the expanded state with the expand and collapse actions; in Flutter the expanded semantics flag; in React Native accessibilityState.expanded. THE accordion SHALL NOT make an item's content a landmark or a named region, and the accordion itself SHALL have no role and no name: a page with several items would otherwise list each of them among its regions. WHILE an item's label is empty and its label slot holds nothing THE accordion SHALL still render it, and in debug builds report that its header has no accessible name.
ACC-25 WHEN an item opens or closes THE accordion SHALL let the header's changed state be the only thing assistive technology is told: it SHALL announce nothing itself, SHALL have no live region, and SHALL NOT move keyboard or screen-reader focus into the content.
ACC-26 WHILE the text size is enlarged THE accordion SHALL grow its label, its supporting text and its trailing text with it, keep its paddings and gaps, wrap the label and the supporting text, and grow each header in height; it SHALL keep the icon's and the chevron's boxes at their token sizes, both still centred on the label's first line (ACC-2), SHALL cut nothing but a trailing text as ACC-4 says, SHALL set no fixed height, SHALL lose no content when the reader raises line height, paragraph spacing, letter spacing or word spacing, and SHALL need no horizontal scrolling at a width of 320 points with text at 200 %.
ACC-27 WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE accordion SHALL draw the outlined look's edge and the lines of ACC-10 in the platform's text color; its labels, texts, icons and chevrons in that text color; a disabled header in the platform's color for disabled text; and a header's hover, press and focus in the platform's own colors for a button and for focus, with the focus ring still inside the header. Open and closed SHALL still be told apart by the chevron's turn, which no color carries.
ACC-28 WHERE the layout direction is right-to-left THE accordion SHALL mirror the order of a header's parts and apply its paddings by logical start and end: the icon at the right, the text after it, the trailing text and the chevron at the left; the content SHALL be inset by the same paddings. The arrow keys of ACC-11 SHALL follow the direction: Left opens and Right closes. The chevron's half turn SHALL be the same in both directions: a glyph that points down and then up has no mirrored form. A ripple SHALL still grow from the point of contact.
ACC-29 THE accordion 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 accordion is shown THE accordion SHALL draw itself for the new direction at once, without a motion of its own, keeping every item's open and its focus.
ACC-30 WHERE the layout direction is right-to-left THE accordion SHALL draw an item's icon 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 and color nor the order ACC-28 gives. THE accordion 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 chevron (expand_more, ACC-6) is not marked and is never mirrored.
ACC-31 THE accordion SHALL lay out an item's label, its supporting text and its trailing text each 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 name, a number with its unit and a version keep their own order in a right-to-left layout and reorder nothing beside them; THE accordion SHALL still place each and align its lines by the layout direction, not by the text's own, and SHALL cut a trailing text that does not fit (ACC-4) at the end of its own direction.
ACC-32 WHERE an item's content holds another accordion THE accordion SHALL treat it as content like any other: the inner accordion is laid out inside the item's inset (ACC-8), which is what shows its depth; it has its own variant, density, separation and exclusive; its headers answer the keys of ACC-11 for its own items only; and WHEN the outer item closes and opens again the inner items SHALL be as their open said. IF accordions nest more than three levels deep THE accordion SHALL still render them, and in debug builds report the depth.
ACC-33 WHILE the system's icon set cannot yet draw a glyph of the accordion (its font is still loading) THE accordion SHALL draw nothing in that glyph's place, never the glyph's name as text, SHALL keep the glyph's box, and SHALL draw the glyph once the set can; a header SHALL open and close its item all the same.
ACC-34 WHEN variant or density names a value that the active design system does not have THE accordion SHALL render with the default value (the default variant's or density's tokens), and in debug builds report the unknown value.
ACC-35 IF the accordion has no items THE accordion SHALL draw nothing, take no space and expose nothing. IF an item has no content THE accordion SHALL still render its header, which opens onto nothing but the space under the content (ACC-8), and in debug builds report that the item shows and hides nothing.
ACC-36 WHEN the content of an open item is pressed and released with the primary mouse button, a touch or a pen, without the pointer moving further than the platform's touch slop between the two, THE accordion SHALL close that item exactly as a press on its header does: one toggle with false, the motion of ACC-13 and the header kept where it is as ACC-14 says, with exclusive (ACC-12) closing nothing else. The item's whole frame is its hit area while it is open: the content from the item's start edge to its end edge and down to its lower edge, the space under the content (ACC-8) included, the way a whole card answers a press while the controls inside it keep their own. THE accordion SHALL NOT close the item IF the press lands on or inside something that answers a press itself — a link, a button, a field, a select, a label, a summary, an editable element, an element with a tab index, an element with a widget role, a custom element that takes focus, or an element to which the product gave the pointer cursor where the item's own is not (the pointer the item shows for itself does not count) — which keeps its own behaviour; IF the release ends a text selection, that is, the selection is not empty and lies in the item once the press is released; IF the pointer moved further than the slop (a drag, a scroll); IF a modifier key (Control, Command, Shift, Alt or Option) is held or a button other than the primary is used; IF the press is the second or a later press of a multiple click; WHILE the item is disabled (ACC-20); or IF the press lands inside an item of an accordion nested in the content: such a press belongs to the innermost item, so a press in a nested open item's content closes that item only, and a nested header toggles its own item only. For a pointer the open item is one target, as a whole clickable card is, and not a header and a content styled alike: WHILE a fine pointer is over the item where a press would toggle or close it — its header, or its content outside a descendant that takes a press itself — THE accordion SHALL show the hovered state on the whole item (ACC-17) and the pointer cursor; a press SHALL show the pressed state on the whole item (ACC-21, ACC-22); keyboard focus on the header SHALL be shown around the whole item (ACC-18). WHILE the pointer is over a descendant that takes a press itself, that descendant SHALL keep its own cursor, hover and press, and the item SHALL show neither its hovered state nor the pointer cursor. The content SHALL get no role, no name, no focus stop and no announcement: the header stays the one button with the expanded state, and the keyboard and assistive technology reach the item through it alone (ACC-11, ACC-24). WHERE the platform's content answers no press (on the web, without the element's script) the content SHALL show neither the pointer cursor nor a state.

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

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

仕様 Web SwiftUI Jetpack Compose Flutter React Native
コンポーネント tanrei-accordion TanreiAccordion TanreiAccordion TanreiAccordion Accordion
variant · プロパティ variant variant variant variant variant
density · プロパティ density density density density density
separation · プロパティ separation separation separation separation separation
exclusive · プロパティ exclusive isExclusive exclusive exclusive exclusive
備考 Form: <tanrei-accordion> is a custom element with **no shadow root**, around the product's own native <details> elements in the light DOM — <tanrei-accordion variant="outlined"><details open><summary>Colors</summary><p>…</p></details><details>…</details></tanrei-accordion>. The browser's disclosure is kept whole: it opens and closes without script, a summary is focusable and answers Enter and Space, it is exposed with its expanded state, its closed content stays in the document, find-in-page and a fragment link open it where the browser does that for a details element (ACC-16; in a browser that does not, the script listens for beforematch and hashchange where they exist, and otherwise closed content is not found, as in every details element there), and exclusive is the name attribute, which the element writes on its own <details> children with a name of its own (a nested accordion gets another, ACC-12); markup that must be exclusive without script writes name itself. Everything drawn comes from one stylesheet, @tanrei/web/accordion.css, whose selectors start at tanrei-accordion and are wrapped in :where(); it styles the page before the element is defined and without script (an element that is not yet defined is still an element), and the element adopts the same sheet into the root it is connected to, so it also works inside another component's shadow root. Props are attributes of the wrapper: variant, density, separation, exclusive. The summary is a grid (icon, text, trailing text, chevron); the browser's own marker is removed (list-style: none and the ::-webkit-details-marker rule) and the chevron is the summary's ::after in the icon font (expand_more), rotated under details[open]. The content's inset is padding on the <details> with the summary pulled back out by a negative inline margin, so no wrapper is needed around the product's content. The stylesheet alone gives the default system's whole look and every state: hover, :focus-visible with the ring as an inset outline, :active with the press-hold as a delayed transition back, the disabled look from summary[aria-disabled="true"], forced colors, and the separation through a style query on the component token's custom property with the separation attribute over it. The content's box is the details element's own ::details-content, a block formatting context (display: flow-root): the margins of the content's first and last parts stay inside it, at rest and at every height of the motion, so the height the motion starts and ends at is the height at rest (ACC-8, ACC-13). Motion (ACC-13) is CSS where the browser can move a height to auto (::details-content with block-size from 0 to calc-size(auto, size), overflow: clip, and content-visibility transitioned discretely so that closing content stays drawn until the end); elsewhere the script measures the content's height once, before the first frame, and the stylesheet moves the box between 0 and that height; where the browser has no ::details-content the item opens at once, and so it does where motion is reduced. The script reads layout from frame to frame only for an item turned back in the first half of its motion on the script's path, whose height goes on with no event to tell its end: it reads the item's height once a frame until it stands still. The package's script, where it is loaded, adds what a stylesheet cannot: the shared press primitive on the summary (ripple and dim, ACC-22), the arrow keys of ACC-11, the name of exclusive, holding the activated header's place where the browser's scroll anchoring does not (ACC-14), moving focus to the summary when an item closes around it (ACC-15), refusing a disabled summary's click, closing an open item when its content is pressed (ACC-36), and every debug report. ACC-36 is the script's alone: before the element is defined, and without script, only the summary toggles its item, and the content shows no pointer cursor and no state (they would promise a press nothing answers). Once the element is defined an open item is drawn as one target by accordion.css: the <details> paints the container color of its state (at rest the look's container color, no fill in every shipped system), the summary paints none and is not a positioning container, so its focus ring (::before, with the outer stroke as the item's own outline) and its ripple are laid out on the whole item, under the header and the content; the content's box (::details-content) takes the state's opacity. The element writes data-tanrei-hit on the item a mouse or a pen is over where a press would toggle or close it (from pointerover, by the same rule as a press), which draws it hovered and gives it cursor: pointer; over a control in the content the attribute is off, so the control's own cursor and states show and the item's none. To tell a box the product gave the pointer cursor from the content inheriting the item's, the element sets the item's cursor aside (data-tanrei-reading) while it reads the pressed element's. A press in the content is the summary's press primitive (data-pressed on the summary), drawn on the whole item, and ends when the pointer leaves the item or moves past the slop. Where the browser has no ::details-content the content's opacity is not changed. The element listens for pointerdown, pointermove and click on itself; a click closes the item when it follows a press with the primary button (any touch or pen) in that same item's content, the pointer has not moved more than 8 CSS pixels (the touch slop the sheets and the tabs use, the web naming none of its own), no modifier key is held, event.detail is 1, the document's selection is collapsed or outside the item, the innermost <details> on the event's composed path is the item itself, and nothing on that path between the target and the item is a link, a button, a field, a select, a textarea, a label, a summary, editable, a [tabindex], an element with a widget role, a custom element that delegates focus or takes it, or (the element pressed) drawn with cursor: pointer while the item, its own pointer set aside, is not. The click is decided a task after it is dispatched, so that a handler of the product's on the content is heard first: a click it cancelled (preventDefault()) closes nothing. It then sets the item's open to false, so the browser sends toggle and the motion, focus and exclusive rules run as for a press on the summary. Nothing is written into the content and no style is added to anything in it. Inside .tanrei-prose the element is an island by its tag name (PRS-16); the product makes an item's long-form content prose by its own <div class="tanrei-prose" data-measure="false">. Markdown: a renderer passes <details> through as HTML; the product wraps one or several in <tanrei-accordion>. React: Accordion and AccordionItem render the same elements. TanreiAccordion(variant:, density:, separation:, isExclusive:) { TanreiAccordionItem(…) { … } … }. The header is a button whose accessibility value is expanded or collapsed. An exclusive accordion writes false to the binding of the item it closes. Closed content is not in the view tree; state that must outlive a close is the product's (ACC-7). There is no search of the screen's text to answer (ACC-16). TanreiAccordion(variant, density, separation, exclusive) { TanreiAccordionItem(…) { … } }, items in a scope of the accordion. Controlled: an exclusive accordion calls onExpandedChange(false) on the item it closes. Closed content leaves the composition; rememberSaveable in the content keeps what the product wants kept (ACC-7). TanreiAccordion(variant:, density:, separation:, exclusive:, children: [TanreiAccordionItem(…)]). An exclusive accordion calls onExpansionChanged(false) on the item it closes. A closed item's child is not built; a PageStorageKey or the product's own state keeps what must be kept (ACC-7). <Accordion variant="outlined" exclusive> with AccordionItem children. An exclusive accordion calls onToggle(false) on the item it closes. Closed content is not mounted. Follows the app's direction where an ancestor's is not known.

トークン

トークン 参照先 解決値(ライト)
--tanrei-comp-accordion-chevron-size-compact sys.icon.small 20px
--tanrei-comp-accordion-chevron-size-regular sys.icon.medium 24px
--tanrei-comp-accordion-container-gap sys.space.space150 12px
--tanrei-comp-accordion-container-height-compact — 48px
--tanrei-comp-accordion-container-height-regular — 56px
--tanrei-comp-accordion-container-padding-block-compact — 12px
--tanrei-comp-accordion-container-padding-block-regular — 16px
--tanrei-comp-accordion-container-padding-inline-compact sys.space.space150 12px
--tanrei-comp-accordion-container-padding-inline-regular sys.space.space200 16px
--tanrei-comp-accordion-container-shape sys.shape.corner.none 0px
--tanrei-comp-accordion-content-padding-block-end-compact sys.space.space150 12px
--tanrei-comp-accordion-content-padding-block-end-regular sys.space.space200 16px
--tanrei-comp-accordion-disabled-opacity — 1
--tanrei-comp-accordion-divider-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-accordion-divider-thickness sys.border.hairline 1px
--tanrei-comp-accordion-focused-opacity — 1
--tanrei-comp-accordion-hovered-opacity — 1
--tanrei-comp-accordion-icon-size-compact sys.icon.small 20px
--tanrei-comp-accordion-icon-size-regular sys.icon.medium 24px
--tanrei-comp-accordion-item-gap sys.space.space100 8px
--tanrei-comp-accordion-motion-disclosure-duration sys.motion.role.disclosure 400ms
--tanrei-comp-accordion-motion-disclosure-easing sys.motion.easing.spatial cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-accordion-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-accordion-motion-state-duration sys.motion.role.state.large 250ms
--tanrei-comp-accordion-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-accordion-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-accordion-outline-shape sys.shape.corner.medium 8px
--tanrei-comp-accordion-outline-width sys.border.hairline 1px
--tanrei-comp-accordion-outlined-chevron-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-outlined-container-color comp.accordion.plain.container.color #000000 · 0%
--tanrei-comp-accordion-outlined-disabled-chevron-color — #1b1b1b · 38%
--tanrei-comp-accordion-outlined-disabled-container-color — #000000 · 0%
--tanrei-comp-accordion-outlined-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-accordion-outlined-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-accordion-outlined-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-accordion-outlined-disabled-supporting-text-color — #1b1b1b · 38%
--tanrei-comp-accordion-outlined-disabled-trailing-text-color — #1b1b1b · 38%
--tanrei-comp-accordion-outlined-focused-chevron-color — #4b4b4b
--tanrei-comp-accordion-outlined-focused-container-color — #1b1b1b · 10%
--tanrei-comp-accordion-outlined-focused-icon-color — #4b4b4b
--tanrei-comp-accordion-outlined-focused-label-color — #1b1b1b
--tanrei-comp-accordion-outlined-focused-state-layer-color — #1b1b1b
--tanrei-comp-accordion-outlined-focused-supporting-text-color — #4b4b4b
--tanrei-comp-accordion-outlined-focused-trailing-text-color — #4b4b4b
--tanrei-comp-accordion-outlined-hovered-chevron-color — #4b4b4b
--tanrei-comp-accordion-outlined-hovered-container-color — #1b1b1b · 8%
--tanrei-comp-accordion-outlined-hovered-icon-color — #4b4b4b
--tanrei-comp-accordion-outlined-hovered-label-color — #1b1b1b
--tanrei-comp-accordion-outlined-hovered-state-layer-color — #1b1b1b
--tanrei-comp-accordion-outlined-hovered-supporting-text-color — #4b4b4b
--tanrei-comp-accordion-outlined-hovered-trailing-text-color — #4b4b4b
--tanrei-comp-accordion-outlined-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-outlined-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-accordion-outlined-pressed-chevron-color — #4b4b4b
--tanrei-comp-accordion-outlined-pressed-container-color — #1b1b1b · 10%
--tanrei-comp-accordion-outlined-pressed-icon-color — #4b4b4b
--tanrei-comp-accordion-outlined-pressed-label-color — #1b1b1b
--tanrei-comp-accordion-outlined-pressed-state-layer-color — #1b1b1b
--tanrei-comp-accordion-outlined-pressed-supporting-text-color — #4b4b4b
--tanrei-comp-accordion-outlined-pressed-trailing-text-color — #4b4b4b
--tanrei-comp-accordion-outlined-state-layer-color comp.accordion.outlined.label.color #1b1b1b
--tanrei-comp-accordion-outlined-supporting-text-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-outlined-trailing-text-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-plain-chevron-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-plain-container-color — #000000 · 0%
--tanrei-comp-accordion-plain-disabled-chevron-color — #1b1b1b · 38%
--tanrei-comp-accordion-plain-disabled-container-color — #000000 · 0%
--tanrei-comp-accordion-plain-disabled-icon-color — #1b1b1b · 38%
--tanrei-comp-accordion-plain-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-accordion-plain-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-accordion-plain-disabled-supporting-text-color — #1b1b1b · 38%
--tanrei-comp-accordion-plain-disabled-trailing-text-color — #1b1b1b · 38%
--tanrei-comp-accordion-plain-focused-chevron-color — #4b4b4b
--tanrei-comp-accordion-plain-focused-container-color — #1b1b1b · 10%
--tanrei-comp-accordion-plain-focused-icon-color — #4b4b4b
--tanrei-comp-accordion-plain-focused-label-color — #1b1b1b
--tanrei-comp-accordion-plain-focused-state-layer-color — #1b1b1b
--tanrei-comp-accordion-plain-focused-supporting-text-color — #4b4b4b
--tanrei-comp-accordion-plain-focused-trailing-text-color — #4b4b4b
--tanrei-comp-accordion-plain-hovered-chevron-color — #4b4b4b
--tanrei-comp-accordion-plain-hovered-container-color — #1b1b1b · 8%
--tanrei-comp-accordion-plain-hovered-icon-color — #4b4b4b
--tanrei-comp-accordion-plain-hovered-label-color — #1b1b1b
--tanrei-comp-accordion-plain-hovered-state-layer-color — #1b1b1b
--tanrei-comp-accordion-plain-hovered-supporting-text-color — #4b4b4b
--tanrei-comp-accordion-plain-hovered-trailing-text-color — #4b4b4b
--tanrei-comp-accordion-plain-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-plain-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-accordion-plain-pressed-chevron-color — #4b4b4b
--tanrei-comp-accordion-plain-pressed-container-color — #1b1b1b · 10%
--tanrei-comp-accordion-plain-pressed-icon-color — #4b4b4b
--tanrei-comp-accordion-plain-pressed-label-color — #1b1b1b
--tanrei-comp-accordion-plain-pressed-state-layer-color — #1b1b1b
--tanrei-comp-accordion-plain-pressed-supporting-text-color — #4b4b4b
--tanrei-comp-accordion-plain-pressed-trailing-text-color — #4b4b4b
--tanrei-comp-accordion-plain-state-layer-color comp.accordion.plain.label.color #1b1b1b
--tanrei-comp-accordion-plain-supporting-text-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-plain-trailing-text-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-accordion-pressed-opacity — 1
--tanrei-comp-accordion-separation sys.behavior.separation 0
--tanrei-comp-accordion-label-typescale-compact sys.typescale.label 500 14px/1.4286
--tanrei-comp-accordion-label-typescale-regular sys.typescale.heading-5 500 16px/1.5
--tanrei-comp-accordion-supporting-text-typescale-compact sys.typescale.body-small 400 13px/1.5385
--tanrei-comp-accordion-supporting-text-typescale-regular sys.typescale.body 400 14px/1.5714
--tanrei-comp-accordion-trailing-text-typescale-compact sys.typescale.body-small 400 13px/1.5385
--tanrei-comp-accordion-trailing-text-typescale-regular sys.typescale.body 400 14px/1.5714

フィクスチャ

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

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

ガイドライン

アコーディオンにするかどうか

閉じているコンテンツは、読むのに 1 回押す手間がかかり、ひと目では見えません。一部の人にしか必要のないものを折りたたみ、ほとんどの人が目当てにしているものは開いたままにします。フォームの必須のフィールドやエラーを、閉じた項目の中に隠さないでください。

2 つの見た目

variant 描き方 用途
plain(既定) サーフェスの上に行を並べ、周りには何も描きません。 ページやパネルの流れの中に置くコンテンツ。
outlined 角を丸めた細い線で囲みます。 ほかのブロックと並べて、ひとまとまりに見せたいセット。

どちらの見た目も、操作していないときは何も塗りません。項目が開いている間も、ヘッダーの色は変わりません。開いていることを示すのは、シェブロンだけです。

密度

density 1 行のヘッダーの高さ ラベル 用途
regular(既定) 56 文字サイズ 16 / 行の高さ 24、太さは medium 利用者が読むページ:質問や、長いフォームのセクション。
compact 48 14 / 20、太さは medium コントロールの間に置くパネル:設定、インスペクター、カード。

ヘッダーはテキストに合わせて高くなります。compact のヘッダーは、ナビゲーションドロワーの行と同じ高さ、同じテキストスタイル、同じシェブロンです。

項目の区切り方

separation plain outlined
auto(既定) デザインシステムが選んだもの。既定のシステムでは細い線です。 同じです。
divider 項目の間に細い線を引きます。最初の項目の上と最後の項目の下には引きません。 セット全体を 1 つの縁で囲み、項目の間に細い線を引きます。
gap 余白だけで、線は引きません。 項目ごとに縁で囲みます。

一度に 1 つだけ開く

exclusive を付けると、ある項目が開いたときに、それまで開いていた項目が閉じます。1 つの選択を進めていく手順のように、互いに両立しない項目に使います。ページを短くするために使うものではありません。2 つの回答を並べて読みたい人が、そうできなくなります。上の項目が閉じる間も、押されたヘッダーは画面の同じ位置にとどまります。

Web では、exclusive は <details> の name 属性にあたり、要素がそれぞれの項目に書き込みます。スクリプトがなくても一度に 1 つだけ開くようにしたいマークアップでは、それぞれの項目に同じ name を自分で書きます。

推奨

  • ラベルはプレーンテキストで書きます。ページのアウトラインのためにその行を見出しにする必要があるときは、適切なレベルの見出しをラベルにします。
  • 補足テキストで、項目の中に何があるかを伝えます。開かなくても、開くかどうかを決められます。
  • 末尾のテキストは、件数や現在の値に使います。1 行に収め、収まらないときはラベルより先に切り詰められます。
  • 項目に属するアクションは、その項目のコンテンツの中に置きます。

非推奨

  • ヘッダーにリンク、ボタン、スイッチを置かない。ヘッダーは全体が 1 つのボタンです。
  • どの項目が開いているかを、色や太さで示さない。
  • アコーディオンを 3 階層より深く入れ子にしない。
  • 中のフィールドが invalid の状態だからといって、読み手に何も伝えずに項目を開かない。フォームが受け付けられなかったときは、最初のエラーがある項目を開いてから、そのフィールドにフォーカスを移します。

アクセシビリティ

ロール
button
ラベル付け
Each header is a button named by its label (or by the text of the label slot's content), described by its supporting text and then its trailing text, with the expanded or collapsed state; its icon and chevron are hidden. A label given as text is plain text; a heading in the label slot keeps its level. An open item's content follows its header in reading order and has no role or name of its own. The accordion has no role and no name.
最小ターゲット
見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px

キーボード操作

キー 動作
Tab / Shift+Tab Moves focus to each header that is not disabled, in order, and through the focusable content of each open item after its header. Every header is its own stop; the accordion is not one.
Enter / Space On a header, opens or closes its item. Focus stays on the header.
Right arrow / Left arrow (mirrored in right-to-left layouts) On the header of a closed item, the arrow toward the end of the line opens it; on the header of an open item, the arrow toward the start closes it. Elsewhere the keys are the platform's. As on a navigation drawer's group row.
Up arrow / Down arrow / Home / End Nothing of the accordion's: they scroll the page as they do anywhere. Focus does not rove between headers.

備考

  • An accordion is a set of disclosures, not a tree and not tabs: a header is a button with an expanded state that shows or hides what follows it, and every header stays its own tab stop. This is the model of a navigation drawer's groups, on purpose: a group in a drawer and an item in content answer the same keys in the same way, and a person learns it once. One tab stop with roving arrow keys would make a long page of content behave like a single widget and take the arrow keys from the page.
  • WCAG 1.3.1 (info and relationships): the accordion does not decide whether a label is a heading. Most labels are names of a fold in a panel and should stay text. Where the items are the sections of a page that people navigate by heading (the questions of a help page), the product gives a heading of the right level in the label slot. Some assistive technology reads a heading inside a button as the button's name only; where the outline must not depend on that, the product puts the heading before a single-item accordion instead.
  • The content is not a region. Naming every item's content as a landmark fills the list of regions with entries a person did not ask for; six items make six regions. A product whose single disclosure is a main part of its page may give its own content element the region role and the label's name.
  • Closed content costs a press to read and cannot be seen at a glance. Do not close what most people need, do not hide a form's required fields or its errors in a closed item, and when a form is refused, open the item that holds the first error before moving focus to the field: the accordion does not open an item because something inside it is invalid.
  • exclusive moves the page: opening one item closes another, and what the reader was looking at goes. The accordion keeps the activated header where it is (ACC-14), which removes the worst of it; even so, keep exclusive for items that exclude each other. A person who wants two answers side by side cannot have them.
  • Where the platform's own search can reach closed content (the web's find-in-page), a match opens the item (ACC-16), so closing content does not hide it from someone who looks for its words. Native platforms have no such search: there, text in a closed item is found only by the product's own search, which sets the item's open.
  • A header holds no control (ACC-3). A switch, a menu button or a link beside the label would be a control inside a button: unreachable or ambiguous for assistive technology, and a press on it would also toggle the item. An action that belongs to an item goes into its content, or beside the accordion.
  • WCAG 2.5.8 (target size): a header is the whole row and at least the touch target high in both densities; rows that touch do not share or extend hit areas (ACC-19).
  • WCAG 2.1.1 (keyboard) and 4.1.2 (name, role, value): closing an item by a press on its open content (ACC-36) is a convenience for a pointer only. The header is the one control, reached by the keyboard and named with its expanded state; the content gains no role, no focus stop and no announcement, so nothing is offered to a pointer that the keyboard and assistive technology do not already have through the header. An open item is one target, as a whole clickable card is (the maintainers' decision, 2026-10-13): the region that answers a press is the region that looks it — the pointer cursor over it, the hovered and pressed states drawn on the whole item, and keyboard focus ringed around the whole item, so that hover, press and focus all show the same one target, never a header and a content styled alike. This follows the clickable-card practice: the whole card is the target's area while the controls inside it keep their own press (Bootstrap, "Stretched link"), and the pointer cursor is set by the script, since without it the style would deceive (Inclusive Components, "Cards") — without the script the content shows no pointer and no state. Where the pointer is over a control in the content, that control is the target: it keeps its own cursor and states and the item shows none, as a nested button in a card answers alone. WCAG 2.4.7, 2.4.11 and 2.4.13 (focus visible, not obscured, appearance): the ring around an open item is the system's focus ring of the same widths and colors, inside the item's edge and drawn over its content, so nothing in the item, no neighbouring item, outlined edge or scrolling ancestor covers or cuts it, and it encloses a larger area than the header's. What a press must not be is kept from the same practice: a press that ends a text selection, or that is a drag, is not taken (that card pattern tells a selection by the press's length; the accordion tells it by the selection itself and by the slop).
  • WCAG 1.4.1 (use of color): open and closed are told by the chevron's turn and by the expanded state, never by color; the header keeps its colors when open. Disabled is told by the faded header and by the disabled state.
  • WCAG 1.4.3 and 1.4.11 (contrast) in the default system: the label is on-surface and the supporting text, trailing text, icon and chevron are on-surface-variant, on the surface the accordion stands on; each is held to 4.5:1 on every surface role by the token invariants. The edge and the lines are decorative: every header is told as a button by its chevron and its states.
  • Forced colors (ACC-27): the edge and the lines take the text color and the states the platform's own; nothing about open and closed rested on a color.
  • Web: the items are the product's own `<details>` elements with a `<summary>` each, in the document, inside `<tanrei-accordion>`. They open and close, keep their place in the tab order, are found by search in the page and are read, translated and printed as the page's content before any script runs and without it; what the script adds is listed in the platform notes. Before the element is defined, and without script, the stylesheet already draws the whole look, so nothing moves when the element is upgraded.
  • 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.

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

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

  • それぞれのヘッダーは、<details> 要素の <summary> です。展開状態を持つ 1 つのボタンで、フォーカスの順序の中に自分の止まる位置を持ちます。Enter と Space で開閉します。レイアウトの方向に合わせて、行の終わりを向いた矢印キーは閉じている項目を開き、行の始まりを向いた矢印キーは開いている項目を閉じます。上下の矢印キー、Home、End の働きはページのままです。
  • ヘッダーの名前はラベルです。要素は、補足テキスト、末尾のテキストの順に、ヘッダーの説明にします。スクリプトがなければ、3 つともこの順で名前として読み上げられます。
  • アイコンとシェブロンは、支援技術から隠されます。
  • コンテンツはリージョンではなく、開閉のときに何も読み上げません。支援技術に伝わるのは、ボタンの状態が変わったことだけです。
  • 閉じているコンテンツは、描かれず、フォーカスもできず、支援技術にも伝わりませんが、文書の中には残ります。その中のフィールドは値を保ち、フォームと一緒に送信されます。
  • 閉じている項目の中の場所へのリンクをたどると、その項目が開きます。ブラウザーがページ内検索のために <details> 要素を開く場合は、ページ内検索でも同じように開きます。
  • 開いている項目は、カード全体が押せるのと同じく、全体で 1 つのターゲットです。コンテンツのどこを押しても、ヘッダーを押したときと同じように項目が閉じます。ポインターを重ねると、ヘッダーとコンテンツを合わせた項目全体がホバーと押下の状態になり、カーソルはポインターになります。キーボードでヘッダーにフォーカスすると、フォーカスリングは項目全体を囲みます。コンテンツの中のリンク、ボタン、フィールドなど、自分で押下を受けるものはそれぞれの押下、カーソル、状態を保ち、その上にポインターがある間は項目は状態を示しません。テキストの選択、ドラッグ、修飾キーを押しながらの押下、入れ子のアコーディオンの項目の中での押下では閉じません(入れ子の項目のコンテンツを押すと、その項目だけが閉じます)。キーボードと支援技術はこれまでどおりヘッダーを使い、コンテンツにはロールもフォーカスの止まる位置も付きません。これにはスクリプトが必要です。スクリプトがないときは、ヘッダーだけが項目を開閉し、コンテンツにはポインターも状態も表示されません。
  • 項目が開いても、フォーカスは動きません。フォーカスが中にある項目が閉じたときは、フォーカスはその項目のヘッダーに移ります。
  • フォーカスリングは、項目が閉じているときはヘッダーの行の内側に、開いているときは項目の縁の内側にヘッダーとコンテンツをまとめて囲むように描くので、何にも切り取られません。
  • 高さは、ディスクロージャーのモーションで変わります。動きを減らす設定では、瞬時に切り替わります。
  • どちらの密度でも、高さはタッチターゲット以上です。
  • テキストを 200% にすると、ラベルは折り返し、ヘッダーは高くなり、シェブロンは 1 行目にとどまります。
  • 強制カラーモードでは、縁と線はテキストの色に、無効なヘッダーは無効なテキストの色になります。
  • 名前のないヘッダー、ラベルの中のコントロール、コンテンツのない項目、未知の値、3 階層を超える入れ子は、デバッグビルドで報告します。

利用者側で行うこと

  • ラベルを見出しにするかどうかを決めます。ほとんどのラベルは、パネルの中の折りたたみに付けた名前なので、テキストのままにします。利用者が見出しを頼りにたどるヘルプページの質問は、見出しにします。
  • ラベルにした見出しは、ボタンの中にあります。そのため支援技術によっては、ボタンの名前だけを読み上げ、見出しの一覧には出しません。アウトラインをそれに左右されたくないときは、代わりに、項目が 1 つだけのアコーディオンの前に見出しを置きます。
  • 無効な項目には、aria-disabled="true" と tabindex="-1" の両方を付けます。tabindex がなければ要素が補いますが、それはスクリプトが動いた後です。
  • ラベル、補足テキスト、末尾のテキストが、ページとは逆の方向の文字で書かれることがある場合は、ラベルを <span> で囲みます。そうすると、要素で囲んだそれぞれのテキストが自身の方向を保ちます。要素で囲んでいないラベルは、ページの方向で配置されます。