Skip to content
fandhe-frontendcore v0.4.3
GitHub

Message Scroller

fandhe-frontend-pre-styled-ui の message_scroller mod が提供するスタイル済み Message Scroller 部品です。AI チャット UI の会話ログを収めるスクロールコンテナで、Root / Viewport / Content / Anchor / Jump To Latest / Load More の 6 パーツ構成です。

viewport は overflow-y: auto によるネイティブスクロール(JS 不要)で、既定で高さ 24rem(--fandhe-message-scroller-height で上書き可能)を確保します。両端は mask-image による既定フェードを持ち、root が最下部に張り付いている(data-stuck="bottom")ときは末尾フェードを自動的に解除して最新メッセージを霞ませません。

root の data-stuck(bottom / free)・data-has-new(存在属性)、jump_to_latest の data-visible / hidden(2 択)、load_more の data-loading / data-disabled(存在属性)は headless 層が出力する data-* を CSS セレクタとして参照するだけで、class ベースの軸は持ちません。data-has-new が付いた root の jump-to-latest はアクセント色へ強調されます。load_more は loading が true のとき装飾的な spinner を children 先頭へ埋め込みます。

最下部追従・新着検知・履歴読み込み時の位置維持といったスクロール位置の計測・実行時更新はこの部品では実装しません(fandhe-frontend-wasm-full 側の配線が別イシューで担当します)。

関連 API: fandhe-frontend-pre-styled-ui API / fandhe-frontend-headless-ui API

Demo

会話ログを収めるスクロールコンテナ。data-stuck(bottom/free)・data-has-new・jump-to-latest の data-visible・load-more の data-loading/data-disabled は headless の data-* を参照するのみで class 軸は持ちません。1 例目は最下部に張り付いている既定状態(末尾フェード解除)、2 例目は手動スクロールで離脱し新着がある状態(jump-to-latest 強調・load-more 読み込み中)です。

How do I center a div?
Use display: flex and align-items: center.
New reply while you were scrolled up.

Features

  • root/viewport/content/anchor/jump-to-latest/load-more の 6 パーツで会話ログのスクロールコンテナを構造化する
  • MessageScrollerStuck(Bottom/Free)で data-stuck を切り替え、最下部に張り付いているときは viewport の末尾フェードを解除する(root[data-stuck="bottom"] > viewport の raw CSS 追記、message_scroller.rs モジュール doc「端フェードの採否」節参照)
  • has_new: bool で data-has-new 存在属性を切り替え、root[data-has-new] > jump-to-latest をアクセント色で強調する
  • jump_to_latest の visible: bool で data-visible / hidden の 2 択を切り替える(自動連動しない。hidden 時は UA 既定を display: none の明示規則で上書きする)
  • load_more の loading: bool で spinner_decorative を children 先頭へ埋め込み、disabled: bool でネイティブ disabled + data-disabled を切り替える(自動連動しない)
  • viewport は既定で mask-image による両端フェードを持つ(--fandhe-message-scroller-fade-start/-end を 0px へ上書きすれば片端無効化できる)
  • 最下部追従・新着検知・履歴読み込み時の位置維持等のスクロール計測はこの部品では実装しない(docs/policy/intentional-non-adoption.md §3.25 規則 1、message_scroller.rs モジュール doc「責務境界」節。実行時配線は fandhe-frontend-wasm-full、イシュー #2122)

Anatomy

root
  viewport
    load-more
    content
    anchor
  jump-to-latest

API Reference

Arguments

NameTypeDefaultDescription
stuckMessageScrollerStuckBottom最下部追従の状態(Bottom/Free)。data-stuck として出力され、Bottom のとき viewport の末尾フェードを解除する。
has_newboolfalsetrue の場合 data-has-new 存在属性を付与し、jump-to-latest をアクセント色で強調する(新着メッセージの表示のみ)。
viewport.label&str""非空のとき viewport へ role="region" + aria-label を出力する(空文字なら付与しない)。
jump_to_latest.visibleboolfalsetrue で data-visible 存在属性、false で hidden 存在属性を出力する(2 択、自動連動しない)。
load_more.loadingboolfalsetrue の場合 data-loading 存在属性を付与し、spinner_decorative を children 先頭へ埋め込む。
load_more.disabledboolfalsetrue の場合ネイティブ disabled + data-disabled 存在属性を付与する(loading とは自動連動しない)。

Data Attributes

PartAttributeObserved Values
jump-to-latestdata-visible(値なし)
load-moredata-disabled(値なし)
load-moredata-loading(値なし)
rootdata-has-new(値なし)
rootdata-stuckbottom, free

CSS Variables

VariableDefault
--fandhe-message-scroller-fade-end1.5rem
--fandhe-message-scroller-fade-start1.5rem
--fandhe-message-scroller-height24rem
--fandhe-message-scroller-thumb-bgvar(--fandhe-color-fg-subtle, var(--fandhe-color-border-emphasized, var(--fandhe-color-border)))

Examples

Default (stuck at bottom)

最下部に張り付いている既定状態です。jump-to-latest は hidden、末尾フェードは解除されています。

How do I center a div?
Use display: flex and align-items: center.

Scrolled up with new messages

手動スクロールで離脱し新着がある状態です。jump-to-latest が強調表示され、load-more は読み込み中です。

New reply while you were scrolled up.

Accessibility

Keyboard Interactions

KeyDescription
Arrow keys / Page Up / Page Downviewport は tabindex="0" を固定付与したネイティブスクロール領域であり、フォーカス時にブラウザ標準のスクロールキー操作を受け付ける(JS 不要)。

WAI-ARIA

AttributeDescription
tabindex="0" / role="region" + aria-label (viewport)viewport は tabindex="0" を固定付与し、label が非空のときのみ role="region" + aria-label を出力する(名前のない region を作らない)。
aria-hidden="true" (anchor)anchor は最下部センチネルであり aria-hidden="true" を固定付与する(fandhe-frontend-wasm-full がスクロール計測の観測対象にする、イシュー #2122)。
type="button" (jump-to-latest / load-more)両ボタンとも type="button" を固定付与する(フォーム内でも誤送信しない)。
(付与しない) aria-live / aria-busy / aria-posinset / aria-setsize通知・応答待ちの読み上げ、総数の伝達はいずれもアプリ固有の判断のため付与しない(headless message_scroller.rs モジュール doc「aria-live/aria-busy を付けない理由」「aria-posinset/aria-setsize を持たない理由」節参照)。