@aiquants/virtualscroll 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +5 -1
- package/dist/VirtualScroll.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +222 -215
- package/package.json +1 -1
- package/src/VirtualScroll.tsx +25 -3
package/package.json
CHANGED
package/src/VirtualScroll.tsx
CHANGED
|
@@ -1723,9 +1723,27 @@ const VirtualScrollInner = <T,>(
|
|
|
1723
1723
|
}, [contentSize, renderingEndIndex, renderingStartIndex, resolvedInsets.top, scheduleRangeEffect, scrollPosition, visibleEndIndex, visibleStartIndex])
|
|
1724
1724
|
|
|
1725
1725
|
/**
|
|
1726
|
-
*
|
|
1726
|
+
* Renders the auto-hiding Top/Bottom pill overlay, neutralized while hidden.
|
|
1727
1727
|
*
|
|
1728
|
-
*
|
|
1728
|
+
* 自動非表示の Top/Bottom ピルのオーバーレイを描画し、非表示中は無効化する処理。
|
|
1729
|
+
*
|
|
1730
|
+
* ❗ 非表示は `opacity: 0` で表現するため、要素は DOM に残り続ける (フェードのために
|
|
1731
|
+
* アンマウントしない)。`opacity` はフォーカス可能性に影響せず、CSS の `pointer-events: none`
|
|
1732
|
+
* はポインタ操作しか止めないため、無効化しないと**キーボード操作者は一覧を通過するたびに
|
|
1733
|
+
* 「何も見えないのにフォーカスが止まる」箇所を必ず 1 つ踏む**。しかもフォーカスリング
|
|
1734
|
+
* (`:focus-visible`) は `opacity: 0` の要素に描かれるため見えず、そこで Enter/Space を押すと
|
|
1735
|
+
* 一覧が先頭または末尾へ飛ぶ (`pointer-events: none` はキーボードからの活性化を素通しする)。
|
|
1736
|
+
*
|
|
1737
|
+
* 無効化は焦点・支援技術・ポインタの 3 軸を 2 層で塞ぐ:
|
|
1738
|
+
*
|
|
1739
|
+
* 1. オーバーレイの `inert`: 焦点・ヒットテスト・アクセシビリティツリー露出を一括で外す
|
|
1740
|
+
* (この 1 属性が本質的な修正。React 19 は真偽値プロップとして扱い、false では属性を出さない)。
|
|
1741
|
+
* 2. ピルの `tabIndex`: `inert` 未実装のブラウザ (Firefox 112 未満など) でもタブ順から外れる
|
|
1742
|
+
* ようにする下限。`inert` と同じ `isVisible` から導出するため両者が食い違うことはない。
|
|
1743
|
+
*
|
|
1744
|
+
* ポインタ軸の下限は CSS 側の `.aqvs-scroll-to-edge-overlay[data-visible="false"]
|
|
1745
|
+
* .aqvs-scroll-to-edge-button { pointer-events: none }` が担う (配布 CSS 未読込のホストでは
|
|
1746
|
+
* `inert` が、`inert` 未実装のブラウザでは CSS が、互いの穴を埋める)。
|
|
1729
1747
|
*/
|
|
1730
1748
|
const renderOverlay = useCallback(() => {
|
|
1731
1749
|
if (!enableScrollToTopBottomButtons) {
|
|
@@ -1736,12 +1754,14 @@ const VirtualScrollInner = <T,>(
|
|
|
1736
1754
|
const isTop = scrollDirection === "up"
|
|
1737
1755
|
|
|
1738
1756
|
return (
|
|
1739
|
-
<div className="aqvs-scroll-to-edge-overlay" data-visible={isVisible}>
|
|
1757
|
+
<div className="aqvs-scroll-to-edge-overlay" data-visible={isVisible} inert={!isVisible}>
|
|
1740
1758
|
{isTop ? (
|
|
1741
1759
|
<div className="aqvs-scroll-to-edge-button-container aqvs-scroll-to-edge-button-container-top">
|
|
1742
1760
|
<button
|
|
1743
1761
|
type="button"
|
|
1744
1762
|
className="aqvs-scroll-to-edge-button"
|
|
1763
|
+
// 非表示中はタブ順から外す (inert 未実装ブラウザ向けの下限)
|
|
1764
|
+
tabIndex={isVisible ? 0 : -1}
|
|
1745
1765
|
onClick={(e) => {
|
|
1746
1766
|
e.stopPropagation()
|
|
1747
1767
|
isProgrammaticScrollRef.current = true
|
|
@@ -1756,6 +1776,8 @@ const VirtualScrollInner = <T,>(
|
|
|
1756
1776
|
<button
|
|
1757
1777
|
type="button"
|
|
1758
1778
|
className="aqvs-scroll-to-edge-button"
|
|
1779
|
+
// 非表示中はタブ順から外す (inert 未実装ブラウザ向けの下限)
|
|
1780
|
+
tabIndex={isVisible ? 0 : -1}
|
|
1759
1781
|
onClick={(e) => {
|
|
1760
1782
|
e.stopPropagation()
|
|
1761
1783
|
isProgrammaticScrollRef.current = true
|