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

モーダルレイヤー

すべてのモーダルなサーフェスの下にあるレイヤーです。表示するものの背後のウィンドウを暗くし、そこにあるものをすべて操作不能にします。フォーカスを中へ移してとどめ、閉じたら返し、Escape、プラットフォームの「戻る」、暗い部分の押下で閉じるよう求めます。一度スタイルを変えれば、すべてのモーダルなサーフェスがそれに従います。

content_copyMarkdown で表示

上級者向け

ほとんどのプロダクトでは、このコンポーネントを部品として含むBottom sheet, DateTimePicker, Dialog, Image preview, Navigation drawer, Search, Side sheetを配置します。

カテゴリ
コンテインメント
トークン
comp.modal-layer
レベル
基礎

概要

Web
tanrei-modal-layer
clock_loader_40
SwiftUI
tanreiModalLayer
radio_button_unchecked
Jetpack Compose
TanreiModalLayer
radio_button_unchecked
Flutter
TanreiModalLayer
radio_button_unchecked
React Native
ModalLayer
radio_button_unchecked

生成元 docs/status/status.json, specs/modal-layer.spec.json

利用者側のカードを囲むモーダルレイヤー:ボタンで開きます

写真を書き出す

24 枚の写真を書き出す準備ができました。

完了

どのモーダルなサーフェスの下にも、同じレイヤーがあります。このレイヤーはサーフェスの背後のウィンドウを暗くし、ページがいったん脇に置かれたことを伝えます。そこにあるものはすべて操作不能にします。背後のものは押すことも、フォーカスすることも、スクリーンリーダーで読むこともできず、ページはスクロールしません。フォーカスをサーフェスの中へ移し、開いている間はそこにとどめ、閉じたら返します。そして、人が Escape を押したとき、プラットフォームの「戻る」を使ったとき、暗い部分を押したときに、閉じるよう求めます。

モーダルレイヤーは、このレイヤーを独立したコンポーネントにしたものです。ダイアログ、モーダルのときのサイドシートとボトムシート、モーダルのナビゲーションドロワー、画像プレビュー、モーダルの DateTimePicker、検索のモーダルな表示は、どれもこれで組み立てられています。どれも独自の決まりを持たず、このレイヤーの決まりに従います。

これは上級者向けのコンポーネントです。出会う場面は 2 つあります。

  • すべてのモーダルなサーフェスのスタイルを一度に変える。 レイヤーのトークン comp.modal-layer.* は、上に挙げた各コンポーネントのスクリムとモーションのトークンの参照先です。プロダクトのレイヤでこれを設定すると、すべてのモーダルなサーフェスがそろって変わります。変わるのは、暗くする色と不透明度、背後のぼかし、レイヤーが現れて消えるまでの時間です。
  • Tanrei にないモーダルなサーフェスを作る。 コマンドパレット、ウィンドウ全体を覆う画面、独自のビューアーなどです。サーフェスをレイヤーの中に入れれば、プロダクトのほかのモーダルなサーフェスと同じように振る舞います。

判断を求めるならダイアログを使います。パネルなら、モーダルのサイドシートかボトムシートを使います。これらは自分で名前を示し、アクションを配置し、出口を用意しています。

Web では <tanrei-modal-layer> です。ほかのプラットフォームはまだ実装していません。

使い方

レイヤーは制御コンポーネントです。表示するには open を設定します。人が閉じるよう求めると、理由(escape、back、scrim)を添えて close を発火し、開いたままでいます。open を false に戻すのは利用者側です。スクリーンリーダーが読み上げる名前として、label を指定します。

レイヤーが自分で描くのは暗い部分だけです。コンテンツは自分の色、形状、パディングを保ち、レイヤーはそれを本来の大きさのままウィンドウの中央に置きます。別の場所に置くときは、プラットフォームの手段を使います(Web では ::part(container))。

<tanrei-button id="open-palette" variant="text">コマンド</tanrei-button>

<tanrei-modal-layer label="コマンド">
  <div class="palette">
    <!-- autofocus で最初のフォーカスを示します。ないときは、フォーカスはレイヤーのコンテナへ移ります。 -->
    <input autofocus aria-label="コマンドを検索">
    <ul>…</ul>
  </div>
</tanrei-modal-layer>

<style>
  /* コンテナは利用者側で配置します。ここではウィンドウの上寄りに置いています。 */
  tanrei-modal-layer::part(container) { margin-block-start: 15vh; }
</style>

<script type="module">
  import '@tanrei/web/components/modal-layer';
  const layer = document.querySelector('tanrei-modal-layer');
  document.querySelector('#open-palette').addEventListener('click', () => (layer.open = true));
  // Escape、戻る操作、暗い部分の押下。レイヤーが自分で閉じることはありません。
  layer.addEventListener('close', (event) => {
    console.log(event.detail.reason); // 'escape'、'back'、'scrim' のいずれか
    layer.open = false;
  });
</script>
// 上級者向けのコンポーネント(ほかのコンポーネントの部品)は、advanced のエントリーから読み込みます。
import { ModalLayer } from '@tanrei/react/advanced';

<ModalLayer open={open} label="コマンド" onClose={() => setOpen(false)}>
  <CommandPalette />
</ModalLayer>

まだ実装していません。予定している形はビューのモディファイアー .tanreiModalLayer(isPresented:, accessibilityLabel:, onClose:) { … } です。

まだ実装していません。予定している形は TanreiModalLayer(visible, onCloseRequest, contentDescription) { … } です。

まだ実装していません。予定している形は TanreiModalLayer(open:, onClose:, semanticLabel:, child: …) です。

まだ実装していません。予定している形は <ModalLayer visible onClose accessibilityLabel>…</ModalLayer> です。

すべてのモーダルなサーフェスのスタイルを変える

プロダクトがレイヤのファイルでレイヤーのトークンを設定すると、すべてのモーダルなサーフェスがそれに従います。

{
  "tokens": {
    "tanrei.comp.modal-layer.scrim.color": { "$value": "{tanrei.sys.color.scrim}" },
    "tanrei.comp.modal-layer.scrim.blur": { "$value": { "value": 8, "unit": "px" }, "reason": "モーダルなサーフェスの背後をすりガラスのように見せます。" }
  }
}

暗い部分の不透明度は、その色のアルファです。明るくしたり暗くしたりするには、色か、システムの scrim ロールを変えます。1 つのサーフェスだけを変えたいときは、代わりにそのサーフェス自身のトークン(comp.dialog.scrim.color、comp.dialog.motion.enter-duration)を設定します。設定するまでは、レイヤーのトークンを参照しています。

仕様

構成要素

パーツ 説明
1 scrim · 任意 The dim over the whole window behind the container, to every edge and under every system inset. It blocks presses and, while the layer is dismissible, a press on it asks the layer to close. Not drawn while scrim is false.
2 container The box the content is in, placed in the window's safe area. It draws nothing of its own — no color, edge, shadow, shape or padding — takes focus when nothing in the content is marked for it, and is the modal dialog assistive technology reads.

プロパティ

プロパティ 型 既定値 説明
open boolean false Whether the layer is presented. The product opens it, and closes it in answer to close (or from its content's own controls); on SwiftUI, where it is a binding, the layer writes false itself.
dismissible boolean true Whether Escape, the platform's back and a press on the scrim ask the layer to close (MDL-6). Set it to false only when the person must finish with one of the content's own controls, and give the content one.
scrim boolean true Whether the layer dims what lies behind its container. False for content that covers the whole window with a fill of its own (a full-window preview): the layer then draws nothing behind it and still blocks everything there (MDL-2).
label string "" Names the container for assistive technology ("Export photos"): the modal dialog's name. Never drawn. Required.

スロット

スロット 説明
default The content: the surface the product presents modally (a panel, a card, a view over the whole window). The layer places its container (MDL-11) and draws, styles and sizes nothing of the content. A fixture's content string is plain text.

イベント

イベント 説明
close The layer asks to be closed: Escape, the platform's back or a press on the scrim. Carries which of these it was, named escape, back or scrim (in the platform's casing). Emitted only while dismissible is true.

状態

振る舞い

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

ID 要件
MDL-1 WHEN open becomes true THE modal layer SHALL present its container above everything in its window — every region, every overlay not opened from inside it (MDL-9) and every modal layer opened before it (MDL-8) — and, WHILE scrim is true, SHALL draw its scrim over the whole window behind the container, to every edge and under every system inset, filled with comp.modal-layer.scrim.color (its alpha is the dim) and, WHILE comp.modal-layer.scrim.blur is above 0, with what lies behind it blurred by a Gaussian blur of that radius (the radius of CSS's blur()); WHERE the platform cannot blur what lies behind a window it SHALL draw the color alone. WHILE scrim is false it SHALL draw nothing behind the container and SHALL still block what is behind as MDL-2 says. A component built from the modal layer draws the scrim from its own scrim tokens, which alias these two (comp.dialog.scrim.color and comp.dialog.scrim.blur, and so on).
MDL-2 WHILE open is true THE modal layer SHALL make everything outside its container inert — not focusable, not pressable, hidden from assistive technology — and SHALL keep the content behind it from scrolling without moving it (where a scroll bar takes room, that room stays while the scroll is held), so that a press, a scroll or a key anywhere outside the container reaches nothing behind it; WHEN it closes THE modal layer SHALL restore what is behind to what it was before: its scroll position, and what was focusable, pressable and exposed.
MDL-3 WHEN open changes from false to true, and WHEN the layer is mounted with open true, THE modal layer SHALL move focus to the element in its content that the product marked for initial focus (the platform's own mark, named in the platform notes) or, without one, to the element the component built from it names (the navigation drawer's selected destination, NVD-19) or else to its container, so that assistive technology reads its name first and the next Tab reaches the first focusable element. Focus SHALL move when the layer opens, not when its motion ends.
MDL-4 WHILE open is true THE modal layer SHALL keep focus inside its container: Tab from the last focusable element in it SHALL move to the first, Shift+Tab from the first (or from the container itself) SHALL move to the last, the container SHALL keep focus WHILE nothing in it is focusable, and screen-reader navigation SHALL NOT leave it.
MDL-5 WHEN the layer closes THE modal layer SHALL return focus to the element that had it when the layer opened or, where that element no longer exists, cannot take focus or is inert, to the platform's default for a closed overlay; focus SHALL move when the layer closes, not when its motion ends.
MDL-6 WHILE dismissible is true and open is true, WHEN the user presses Escape, uses the platform's back (Android's back gesture or button, the iOS accessibility escape gesture) or presses the scrim — a press that starts and ends outside the container — THE modal layer SHALL emit close exactly once with the reason escape, back or scrim, and SHALL stay open until open becomes false: the product sets it from close (through the binding where open is one, SwiftUI), unless the component built from the modal layer closes itself as its own spec says (DLG-5, NVD-20). Escape SHALL reach the layer only after everything inside its container has heard it: a key an element inside takes (a field clearing its text, a menu closing) SHALL NOT also ask the layer to close. WHILE dismissible is false THE modal layer SHALL ignore these inputs and emit nothing, and a press on the scrim SHALL still reach nothing behind it.
MDL-7 WHEN the layer opens THE modal layer SHALL fade its scrim and its container in from transparent over comp.modal-layer.motion.enter-duration with comp.modal-layer.motion.enter-easing, and WHEN it closes SHALL fade both out over comp.modal-layer.motion.exit-duration with comp.modal-layer.motion.exit-easing, keeping them drawn until the fade ends. A component built from the modal layer SHALL fade the scrim in step with its own surface, over its own enter and exit motion, and moves its surface as its own spec says (a dialog grows, a sheet slides). The enter and exit tokens of a surface that takes the modal role (a dialog, a modal picker, an image preview) alias these four, so that one value sets the tempo of every such surface of a product; a sheet (a bottom sheet, a side sheet, a modal navigation drawer) takes the sheet role (tanrei.sys.motion.role.appear.sheet.enter and .exit) instead, so that one value sets the tempo of every sheet. WHERE motion is reduced THE modal layer SHALL fade without moving or growing anything, or SHALL appear and disappear at once WHERE the component built from it says so or on a platform whose reduced-motion setting removes every animation (Android's).
MDL-8 WHEN a modal layer opens while another is open THE modal layer SHALL stack above it with its own scrim, make the first one inert with the rest of the window, and WHEN it closes return focus to the element inside the first one that had it; Escape, the platform's back and a press on the scrim SHALL reach only the topmost layer.
MDL-9 WHEN an overlay that is not modal opens from an element inside the container — a menu, a tooltip, a popover, a select's list, a docked picker — THE modal layer SHALL let it be presented above the layer and operated while the rest of the window is inert, and SHALL NOT count a press inside it as a press on the scrim: the overlay belongs to the layer as POP-25 says.
MDL-10 THE modal layer SHALL expose its container as a modal dialog named by label, everything outside it being hidden (MDL-2); a component built from it names the dialog by its own headline or label and may expose it as an alert dialog (DLG-14). WHILE label is empty THE modal layer SHALL still open, and in debug builds SHALL report that it has no accessible name.
MDL-11 THE modal layer SHALL draw nothing of its own but the scrim: its container has no color, edge, shadow, shape or padding and hands its content no color or text style, so that plain text given as content takes what the window around it gives. It SHALL lay the container out at the size of its content, centred in the window's safe area and above the on-screen keyboard while one is shown, and never larger than that area, the content scrolling inside it where it is larger; the product places or sizes the container otherwise in the platform's own way (named in the platform notes). A component built from the modal layer places and draws its own surface (DLG-7, SSH-7, BSH-6, IMP-1).
MDL-12 THE modal layer SHALL take its layout direction from where it is used and SHALL have no direction setting of its own; it SHALL mirror nothing itself, and its content follows the direction.
MDL-13 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 modal layer 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 its dialog (MDL-10) — an id reference by the elements it names in the host's tree or a tree around it, a description after its own. WHILE label is not empty it is the dialog's name, over a name given so; WHILE label is empty, a name given so is the dialog's name and SHALL NOT be reported as having none in debug builds. 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 modal layer SHALL take it off that element.

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

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

仕様 Web SwiftUI Jetpack Compose Flutter React Native
コンポーネント tanrei-modal-layer tanreiModalLayer TanreiModalLayer TanreiModalLayer ModalLayer
open · プロパティ open isPresented visible open visible
dismissible · プロパティ closedby dismissible dismissible dismissible dismissible
scrim · プロパティ scrim scrim scrim scrim scrim
label · プロパティ label accessibilityLabel contentDescription semanticLabel accessibilityLabel
close · イベント close onClose onCloseRequest onClose onClose
備考 dismissible is HTML's own closedby attribute, as on <tanrei-dialog> and <tanrei-bottom-sheet>: any (the default) or none. scrim is a boolean property that defaults to true; its attribute is the inverse no-scrim (an HTML boolean attribute cannot default to true). close is a CustomEvent whose detail.reason is escape, scrim or back (back when the native cancel arrives without an Escape key, as Android's back gesture sends it); the product sets open to false from it. The content is the default slot. The container is a native <dialog> in the shadow root opened with showModal(), in the top layer over ::backdrop, the scrim (backdrop-filter blurs what is behind it); it is the container part, which a product places or sizes with ::part(container) (MDL-11). The fade out (MDL-7) keeps the closed <dialog> in the top layer in every browser, as it does every Tanrei modal overlay: closing closes the modal <dialog> at once (focus goes back, nothing is inert any more) and shows it as a manual popover, inert and taking no pointer, marked data-tanrei-leaving, until its fade and its scrim's have finished. The autofocus attribute on a slotted element marks initial focus. Debug builds (import.meta.env.DEV or the package's dev export) report an empty label (MDL-10). Snapshot harness: a 640 × 640 viewport with a surface page, the layer opened by open; the screenshot is the viewport. Planned: a view modifier, as .sheet is: .tanreiModalLayer(isPresented: Binding<Bool>, dismissible:, scrim:, accessibilityLabel:, onClose:, content:), presented as tanreiDialog is (on iOS .fullScreenCover with a clear presentation background and the system transition off; Tanrei draws the scrim and the fade; on macOS an overlay of the modified view with the modal trait). Closing writes false to isPresented and then calls onClose with the reason. Initial focus is .defaultFocus; Escape is .onKeyPress(.escape) and the escape gesture .accessibilityAction(.escape). The blur is a material behind the scrim where the radius is above 0. The container is placed with the content's own frame and alignment. Planned: TanreiModalLayer(visible, onCloseRequest: (TanreiModalLayerCloseReason) -> Unit, dismissible, scrim, contentDescription, content), drawn in a Dialog window of its own (as TanreiDialog and the modal sheets are) with the window's own dim off and usePlatformDefaultWidth = false; the window traps focus, answers back and hides what is behind from TalkBack. The blur is the window's blur-behind radius on Android 12 and later, and none before (MDL-1). The caller sets visible to false from onCloseRequest. The container is placed with a Modifier on the content. Planned: TanreiModalLayer(open:, onClose:, dismissible:, scrim:, semanticLabel:, child:), a controlled overlay in the Overlay over the page with a ModalBarrier drawn in the layer's color and a BackdropFilter for the blur, a FocusScope that traps focus, BlockSemantics behind it and a PopScope for back. The container is placed with the child's own Align. Planned: <ModalLayer visible onClose dismissible scrim accessibilityLabel>{content}</ModalLayer>, presented in a transparent Modal with animationType="none", statusBarTranslucent and navigationBarTranslucent; onRequestClose (Android's back, and Escape on a hardware keyboard) is close with the reason back or escape. React Native cannot blur what is behind a window without a native module of its own, so the scrim is the color alone (MDL-1). The container is placed with the content's own style.

トークン

トークン 参照先 解決値(ライト)
--tanrei-comp-modal-layer-motion-enter-duration sys.motion.role.appear.modal.enter 350ms
--tanrei-comp-modal-layer-motion-enter-easing sys.motion.easing.enter cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-modal-layer-motion-exit-duration sys.motion.role.appear.modal.exit 300ms
--tanrei-comp-modal-layer-motion-exit-easing sys.motion.easing.exit cubic-bezier(0.3, 0, 1, 1)
--tanrei-comp-modal-layer-scrim-blur — 0px
--tanrei-comp-modal-layer-scrim-color sys.color.scrim #000000 · 40%

フィクスチャ

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

生成元 specs/modal-layer.spec.json, tokens/comp/modal-layer.tokens.json, design/tokens/

ガイドライン

レイヤーが担うことと、利用者側に任せること

レイヤー 利用者側のコンテンツ
背後のウィンドウを端から端まで暗くします(scrim をオフにすると何も描きません)。 自分の色、形状、影、パディング。レイヤーはどれも加えません。
背後のすべてを操作不能にし、ページがスクロールしないようにします。 ウィンドウより高いときの、自分のスクロール。
フォーカスを中へ移してとどめ、閉じたら返します。 最初にフォーカスを受け取る要素があれば、その印。
Escape、プラットフォームの「戻る」、暗い部分の押下で閉じるよう求めます。 閉じる、キャンセル、完了のボタンなど、自分の出口。
コンテナを、コンテンツの大きさのままウィンドウの中央に置きます。 中央でないなら、代わりに置く場所。

暗くしないとき

暗い背景の上のビューアーのように、コンテンツが自分の塗りでウィンドウ全体を覆うときは、scrim をオフにします。暗くするものが残っていないからです。それでもレイヤーは背後のすべてをふさぎ、コンテンツの外を押せば閉じるよう求めます。

推奨

  • label でレイヤーに名前を付けます。フォーカスが中へ移ると、スクリーンリーダーがそれを読み上げます。
  • 目に見える出口をコンテンツに入れます。Escape を知らない人もいますし、「戻る」はどのデバイスにもあるわけではありません。
  • プロダクトのモーダルなサーフェスは comp.modal-layer.* で変えます。そうすれば、そろったままになります。

非推奨

  • むき出しのレイヤーでダイアログやシートを作らない。見出し、アクション、その配置をすでに備えたダイアログやシートを使います。
  • コンテンツに出口がないのに dismissible をオフにしない。人が抜け出す手段がなくなります。
  • ページをふさぐべきでないものに使わない。ポップオーバー、メニュー、スナックバーなら、ページを使える状態のまま残せます。

アクセシビリティ

ロール
dialog
ラベル付け
The container is a modal dialog named by label; everything outside it is hidden from assistive technology while the layer is open. The scrim is not exposed. A component built from the modal layer names the dialog by its own headline or label, and the dialog may be an alert dialog.
最小ターゲット
見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px

キーボード操作

キー 動作
Tab / Shift+Tab Move focus through the focusable elements in the container, wrapping from the last to the first and back; focus never leaves the layer.
Escape Asks the layer to close (close, reason escape) while dismissible is true; with stacked layers, only the topmost. A key an element inside takes first goes no further.

備考

  • The modal layer is what every modal surface of Tanrei has in common: the dialog, the modal side sheet, the modal bottom sheet, the modal navigation drawer, the image preview, the modal date-time picker and the search's modal views are each built from it and cite its rules. Restyle their scrim and their tempo once, through comp.modal-layer.*.
  • Use it alone for a modal surface Tanrei does not have — a command palette, a takeover over the whole window, a viewer of your own. For a decision use the Dialog; for a panel, the modal side sheet or bottom sheet: they already hold focus, name themselves and place their actions.
  • Give the content a way out of its own (a Close, Cancel or Done button). Escape, back and the scrim are not found by everyone, and with dismissible false they do nothing.
  • The layer has no target of its own; what the product puts in it meets the minimum target itself.
  • Inert, focus moved in, kept and given back: the WAI-ARIA Authoring Practices' modal dialog pattern and HTML's modal dialog. The web presents the container with a modal <dialog> element (showModal gives the top layer and inertness); the other platforms present it in a window or a route of its own with the system's dim switched off, so that every platform draws the layer's own scrim.

生成元 specs/modal-layer.spec.json, tokens/sys/measure.tokens.json

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

  • コンテナは、label を名前とするモーダルなダイアログです。開いている間、その外側のものはすべて支援技術から隠れます。
  • レイヤーが開くと、最初から開いた状態で書かれていても、フォーカスが中へ移ります。移る先は印を付けた要素、なければコンテナなので、まず名前が読み上げられます。
  • Tab と Shift+Tab はレイヤーの中で折り返します。フォーカスが背後のページに届くことはありません。
  • 閉じると、フォーカスは元の場所へ戻ります。その要素がなくなっていれば、プラットフォームが置く場所へ移ります。
  • Escape で閉じるよう求めるのは、中のものすべてが Escape を受け取った後だけです。Escape でテキストを消すフィールドや、閉じるメニューがあれば、レイヤーは開いたままです。
  • 別のレイヤーの中から開いたレイヤーは、その上に重なります。Escape、「戻る」、暗い部分の押下に応えるのは一番上のものだけです。

利用者側で行うこと

  • サーフェスが何のためのものかを伝える label を指定します。
  • フォームや検索フィールドがサーフェスの目的なら、最初にフォーカスする要素に印を付けます。
  • コンテンツを閉じる目に見えるコントロールを用意します。そのコントロールがない限り、dismissible はオンのままにします。