ドロワー
stimeo--drawer
画面端からスライドインするモーダルパネル。data-state 同期と遷移後の hidden。
stimeo--drawer コントローラは、スライドオーバーのパネルとして WAI-ARIA の Dialog (Modal) パターンを実装する。フォーカストラップ・背景スクロールロック・背景の inert・フォーカス復帰という振る舞いは dialog と同じで、スライドに必要な状態同期が加わる。data-state(open/closed)をパネルとオーバーレイに同期して CSS がアニメーションでき、hidden は閉遷移の完了後にだけ付与して出のアニメーションを再生できる。placement Value は data-placement(left/right/top/bottom)として反映するのみで座標計算はしない。Escape とオーバーレイ(バックドロップ)クリックで閉じ、端の位置・スライド方向・曲線は利用側 CSS が持つ。
キーボード操作
| キー | 動作 |
|---|---|
| Esc | 閉じてフォーカスをトリガーへ戻す。 |
| Tab / Shift+Tab | パネル内でフォーカスを循環(トラップ)。 |
<%# Markup for the drawer (side panel) demo.
A modal panel that slides in from the right edge. In addition to focus move/trap,
Esc, background scroll lock, background inert, and returning focus to the trigger,
the library syncs data-state (open/closed) and applies hidden once the transition
finishes. Which edge it moves from and how (the slide) and the interpretation of
placement are expressed by the consumer's CSS (demo.css) reading data-placement /
data-state. %>
<div
class="drawer"
data-controller="stimeo--drawer"
data-stimeo--drawer-placement-value="right">
<button
type="button"
class="drawer__trigger"
data-stimeo--drawer-target="trigger"
data-action="click->stimeo--drawer#open">
<%= t("components.drawer.demo.open_button") %>
</button>
<%# Overlay (backdrop). Click to close. data-state stays in sync with the panel. %>
<div
class="drawer__overlay"
data-stimeo--drawer-target="overlay"
data-action="click->stimeo--drawer#closeOnBackdrop"
hidden>
<%# The role="dialog" + aria-modal panel. Starts closed / hidden. %>
<div
class="drawer__panel"
role="dialog"
aria-modal="true"
aria-labelledby="drawer-title"
data-stimeo--drawer-target="panel"
data-state="closed"
hidden>
<h3 id="drawer-title" class="drawer__title">
<%= t("components.drawer.demo.title") %>
</h3>
<p><%= t("components.drawer.demo.body") %></p>
<button type="button" class="drawer__close" data-action="click->stimeo--drawer#close">
<%= t("components.drawer.demo.close") %>
</button>
</div>
</div>
</div>
/*
* Presentation-only styles for the drawer demo.
* Stimeo UI itself ships behavior only (no CSS). Slide direction, distance, and the
* animation curve are the consumer's responsibility, expressed by reading the
* data-state (open/closed) and data-placement (left/right/top/bottom) the library syncs.
*/
.drawer__trigger,
.drawer__close {
padding: 0.5rem 1rem;
font: inherit;
cursor: pointer;
border: 1px solid var(--border-interactive);
border-radius: 0.375rem;
background: var(--surface-card);
}
/* Overlay: a full-screen semi-transparent backdrop that fades in/out. */
.drawer__overlay {
position: fixed;
inset: 0;
background: rgb(0 0 0 / 0.5);
opacity: 1;
transition: opacity 0.2s ease;
z-index: 50;
}
.drawer__overlay[data-state="closed"] {
opacity: 0;
}
/* Keep it fully removed while hidden is set (honor the library's hidden control). */
.drawer__overlay[hidden] {
display: none;
}
/* Panel: fixed to the right edge; data-state drives the slide transition. */
.drawer__panel {
position: fixed;
top: 0;
bottom: 0;
width: min(20rem, 80vw);
padding: 1.5rem;
background: var(--surface-card);
box-shadow: -8px 0 30px rgb(15 23 42 / 0.2);
transition: transform 0.25s ease;
overflow: auto;
}
.drawer__panel[hidden] {
display: none;
}
/* placement=right: enters/exits from the right edge; parks off-screen when closed. */
.drawer__panel[data-placement="right"] {
right: 0;
transform: translateX(0);
}
.drawer__panel[data-placement="right"][data-state="closed"] {
transform: translateX(100%);
}
.drawer__title {
margin: 0 0 0.5rem;
font-size: 1.125rem;
}
.drawer__close {
margin-top: 1.5rem;
}
このデモに固有の消費側 JS はありません(挙動はコントローラが担います)。
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。 共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--drawer"
ターゲット
| 名前 | 説明 | 属性 |
|---|---|---|
trigger
|
ドロワーを開くボタン。閉じるとフォーカスがここへ戻る。 | data-stimeo--drawer-target="trigger" |
overlay
|
パネルを包む背景。data-state を同期し、直接クリックするとドロワーを閉じる。 |
data-stimeo--drawer-target="overlay" |
panel
必須
|
スライドインする role="dialog" aria-modal のパネル。data-state/data-placement を持ち、退場遷移後にのみ非表示になる。 |
data-stimeo--drawer-target="panel" |
値(Values)
| 名前 | 説明 | 属性 |
|---|---|---|
placement
|
ドロワーが出てくる端。CSS 用に data-placement として反映する(既定 right)。 |
data-stimeo--drawer-placement-value |
open
|
ドロワーが開いているかどうか。開いた状態を反映・初期化する(既定 false)。 | data-stimeo--drawer-open-value |
アクション
| 名前 | 説明 | アクション |
|---|---|---|
close
|
data-state を closed にして退場スライドを開始し、遷移終了まで hidden とモーダル後始末を遅延する。 |
stimeo--drawer#close |
closeOnBackdrop
|
オーバーレイ自身(中身ではない)がクリックされたときのみ閉じる。 | stimeo--drawer#closeOnBackdrop |
open
|
パネル/オーバーレイを表示し、data-state を open にして入場スライドを再生、フォーカスを閉じ込めて背景スクロールをロックする。 |
stimeo--drawer#open |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
data-state |
パネル/オーバーレイ | open / closed。スライド遷移の起点。 |
hidden |
パネル/オーバーレイ | 閉遷移の完了後に付与(完全非表示)。 |
data-placement |
パネル | left / right / top / bottom。どの端から出すかの CSS 用フラグ。 |
inert |
背景の兄弟要素 | 開いている間、パネル外の要素へ付与。 |