続きを読む
stimeo--read-more
CSS の行クランプを切り替え、収まっているときはトグルを隠す。
stimeo--read-more コントローラは Disclosure の慣行(aria-expanded)を借用し、 data-state で本文の省略表示と全文表示を切り替えます。省略(行クランプ)自体は利用側 CSS の責務で、コントローラはオーバーフロー検知を担います。本文が実際にはみ出していないときはトグルを hidden にし、判定はリサイズ時に再実行します。本文は折りたたみ中も DOM に残るため、支援技術からは常に全文が読めます。ライブラリは挙動のみを提供し、見た目はこの Playground が持ちます。
Stimeo は Ruby on Rails 向けのヘッドレス Stimulus UI フレームワークです。提供するのは挙動のみ——ロール・キーボード操作・ライブリージョン通知を備えたアクセシブルで属性駆動のコンポーネントを提供し、見た目はすべて利用側に委ねます。同梱 CSS もランタイム依存もありません。マークアップと見た目はあなたが用意し、Stimeo は正しくテストされたアクセシビリティの意味論をその下で提供します。
キーボード操作
| キー | 動作 |
|---|---|
| Enter / Space | 省略表示と全文表示を切り替える(ネイティブボタン)。 |
<%# Markup for the read-more demo.
The body is visually truncated with a CSS line clamp, and a toggle switches to the
full text. The library syncs aria-expanded / data-state and hides the toggle when
there is no overflow (so no needless button appears). The clamp itself lives in demo.css. %>
<div class="read-more" data-controller="stimeo--read-more">
<p
class="read-more__content"
id="read-more-demo-content"
data-state="collapsed"
data-stimeo--read-more-target="content">
<%= t("components.read_more.demo.body") %>
</p>
<button
class="read-more__trigger"
type="button"
aria-expanded="false"
aria-controls="read-more-demo-content"
hidden
data-stimeo--read-more-target="trigger"
data-action="click->stimeo--read-more#toggle">
<%= t("components.read_more.demo.trigger") %>
</button>
</div>
/*
* Presentation-only styles for the read-more demo.
* The visual truncation (line clamp) is applied only when data-state="collapsed".
* The library toggles the toggle's visibility (hidden) based on overflow detection.
*/
.read-more {
max-width: 32rem;
}
.read-more__content {
margin: 0 0 0.5rem;
line-height: 1.6;
}
/* Clamp to 3 lines while collapsed. Line-based, so it follows text zoom (WCAG 1.4.4). */
.read-more__content[data-state="collapsed"] {
display: -webkit-box;
-webkit-line-clamp: 3;
line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.read-more__content[data-state="expanded"] {
-webkit-line-clamp: none;
line-clamp: none;
}
.read-more__trigger {
padding: 0.25rem 0;
background: transparent;
border: 0;
font: inherit;
font-weight: 600;
color: var(--accent);
cursor: pointer;
}
.read-more__trigger::after {
content: "";
}
.read-more__trigger[aria-expanded="true"]::before {
content: "▲ ";
}
.read-more__trigger[aria-expanded="false"]::before {
content: "▼ ";
}
このデモに固有の消費側 JS はありません(挙動はコントローラが担います)。
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。 共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--read-more"
ターゲット
| 名前 | 説明 | 属性 |
|---|---|---|
content
必須
|
クランプされるテキスト要素。data-state(collapsed/expanded)が利用側の視覚的クランプを切り替える。 |
data-stimeo--read-more-target="content" |
trigger
必須
|
「続きを読む」ボタン。テキストが溢れない限り非表示。aria-expanded を持つ。 |
data-stimeo--read-more-target="trigger" |
値(Values)
| 名前 | 説明 | 属性 |
|---|---|---|
collapsed
|
connect 時に反映する初期の折りたたみ(クランプ)状態(既定 true)。 | data-stimeo--read-more-collapsed-value |
アクション
| 名前 | 説明 | アクション |
|---|---|---|
toggle
|
折りたたみ(クランプ)と展開を切り替え、オーバーフローを再判定する。 | stimeo--read-more#toggle |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
aria-expanded |
トリガー | 展開で "true"、折りたたみで "false"。 |
data-state |
中身 | "collapsed" / "expanded"。CSS の行クランプを制御。 |
hidden |
トリガー | 本文が収まっている(オーバーフロー無し)とき付与し、トグルを隠す。 |