@aiquants/virtualscroll 3.6.1 → 3.7.1
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 +79 -0
- package/README.md +103 -11
- package/dist/ScrollBar.d.cts +17 -1
- package/dist/ScrollBar.d.ts +17 -1
- package/dist/ScrollBar.d.ts.map +1 -1
- package/dist/ScrollPane.d.cts +15 -0
- package/dist/ScrollPane.d.ts +15 -0
- package/dist/ScrollPane.d.ts.map +1 -1
- package/dist/TapScrollCircle.d.ts.map +1 -1
- package/dist/VirtualGrid.d.cts +17 -1
- package/dist/VirtualGrid.d.ts +17 -1
- package/dist/VirtualGrid.d.ts.map +1 -1
- package/dist/VirtualScroll.d.cts +24 -5
- package/dist/VirtualScroll.d.ts +24 -5
- package/dist/VirtualScroll.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2007 -1967
- package/dist/labels.d.cts +125 -0
- package/dist/labels.d.ts +126 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/pointerCapture.d.cts +68 -0
- package/dist/pointerCapture.d.ts +69 -0
- package/dist/pointerCapture.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/ScrollBar.tsx +41 -38
- package/src/ScrollPane.tsx +64 -18
- package/src/TapScrollCircle.tsx +35 -25
- package/src/VirtualGrid.tsx +23 -1
- package/src/VirtualScroll.tsx +39 -12
- package/src/index.ts +1 -0
- package/src/labels.ts +236 -0
- package/src/pointerCapture.ts +89 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module labels
|
|
3
|
+
* @description Built-in UI chrome label catalog of the package. Covers exactly the seven strings
|
|
4
|
+
* the components render on their own: the ScrollBar arrow aria-labels, the VirtualScroll
|
|
5
|
+
* scroll-to-edge pill texts and the empty-state text. Live-region wording stays consumer-owned
|
|
6
|
+
* (`liveRegion.format` / `liveRegion.buildMessage`) and is not part of this catalog. The default
|
|
7
|
+
* locale is `"en"`; `"ja"` is the second locale. No language negotiation happens here: hosts map
|
|
8
|
+
* `navigator.language` (or anything else) to a supported locale themselves.
|
|
9
|
+
*
|
|
10
|
+
* @description パッケージ内蔵の UI クローム文言カタログ。コンポーネント自身が描画する 7 文言
|
|
11
|
+
* (ScrollBar 矢印の aria-label、VirtualScroll の端スクロールピル文言、空状態文言) だけを対象とし、
|
|
12
|
+
* ライブリージョンの文言は利用側の所有 (`liveRegion.format` / `liveRegion.buildMessage`) で
|
|
13
|
+
* 本カタログの対象外。既定ロケールは `"en"`、第 2 ロケールは `"ja"`。言語ネゴシエーションは行わず、
|
|
14
|
+
* `navigator.language` 等から対応ロケールへの対応付けはホスト側の責務。
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Supported UI chrome locales, in declaration order. The first entry is NOT implicitly the
|
|
18
|
+
* default — the default lives only in {@link resolveVirtualScrollLocale}.
|
|
19
|
+
* 対応する UI クロームロケールの一覧 (宣言順)。先頭要素が暗黙の既定値になるわけではなく、
|
|
20
|
+
* 既定値は {@link resolveVirtualScrollLocale} にのみ存在。
|
|
21
|
+
*/
|
|
22
|
+
export declare const VIRTUAL_SCROLL_LOCALES: readonly ["en", "ja"];
|
|
23
|
+
/**
|
|
24
|
+
* A supported UI chrome locale (`"en"` | `"ja"`).
|
|
25
|
+
* 対応 UI クロームロケール (`"en"` | `"ja"`)。
|
|
26
|
+
*/
|
|
27
|
+
export type VirtualScrollLocale = (typeof VIRTUAL_SCROLL_LOCALES)[number];
|
|
28
|
+
/**
|
|
29
|
+
* The complete set of built-in chrome strings, one value per rendered surface.
|
|
30
|
+
* 内蔵クローム文言の完全な集合 (描画面ごとに 1 値)。
|
|
31
|
+
*/
|
|
32
|
+
export type VirtualScrollLabels = {
|
|
33
|
+
/**
|
|
34
|
+
* aria-label of the vertical ScrollBar start (up) arrow button.
|
|
35
|
+
* 縦 ScrollBar 始端 (上) 矢印ボタンの aria-label。
|
|
36
|
+
*/
|
|
37
|
+
readonly scrollUp: string;
|
|
38
|
+
/**
|
|
39
|
+
* aria-label of the vertical ScrollBar end (down) arrow button.
|
|
40
|
+
* 縦 ScrollBar 終端 (下) 矢印ボタンの aria-label。
|
|
41
|
+
*/
|
|
42
|
+
readonly scrollDown: string;
|
|
43
|
+
/**
|
|
44
|
+
* aria-label of the horizontal ScrollBar start (left) arrow button.
|
|
45
|
+
* 横 ScrollBar 始端 (左) 矢印ボタンの aria-label。
|
|
46
|
+
*/
|
|
47
|
+
readonly scrollLeft: string;
|
|
48
|
+
/**
|
|
49
|
+
* aria-label of the horizontal ScrollBar end (right) arrow button.
|
|
50
|
+
* 横 ScrollBar 終端 (右) 矢印ボタンの aria-label。
|
|
51
|
+
*/
|
|
52
|
+
readonly scrollRight: string;
|
|
53
|
+
/**
|
|
54
|
+
* Text of the VirtualScroll scroll-to-top pill, shown when
|
|
55
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` is on.
|
|
56
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` 有効時に表示される VirtualScroll 先頭移動ピルの文言。
|
|
57
|
+
*/
|
|
58
|
+
readonly scrollToTop: string;
|
|
59
|
+
/**
|
|
60
|
+
* Text of the VirtualScroll scroll-to-bottom pill, shown when
|
|
61
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` is on.
|
|
62
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` 有効時に表示される VirtualScroll 末尾移動ピルの文言。
|
|
63
|
+
*/
|
|
64
|
+
readonly scrollToBottom: string;
|
|
65
|
+
/**
|
|
66
|
+
* VirtualScroll empty-state text shown when `itemCount === 0`. VirtualGrid shows it too, for
|
|
67
|
+
* 0 rows, an all-frozen row set and degenerate bands (its embedded VirtualScroll gets 0 items).
|
|
68
|
+
* `itemCount === 0` 時の VirtualScroll 空状態文言。VirtualGrid も 0 行・全行固定・退化帯で表示
|
|
69
|
+
* (内蔵 VirtualScroll の項目数が 0 になるため)。
|
|
70
|
+
*/
|
|
71
|
+
readonly noItems: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Partial per-key overrides laid over the catalog of the chosen locale. An `undefined` value keeps
|
|
75
|
+
* the catalog value; any present value must be a string with non-whitespace content.
|
|
76
|
+
* 選択ロケールのカタログへ重ねるキー単位の部分上書き。`undefined` 値はカタログ値を維持し、
|
|
77
|
+
* 値を与える場合は空白以外の文字を含む文字列であることが必須。
|
|
78
|
+
*/
|
|
79
|
+
export type VirtualScrollLabelOverrides = {
|
|
80
|
+
readonly [K in keyof VirtualScrollLabels]?: VirtualScrollLabels[K];
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Every key of {@link VirtualScrollLabels}, in catalog order. This is the closed key set that
|
|
84
|
+
* overrides are validated against.
|
|
85
|
+
* {@link VirtualScrollLabels} の全キー (カタログ順)。上書き検証に用いる閉じたキー集合。
|
|
86
|
+
*/
|
|
87
|
+
export declare const VIRTUAL_SCROLL_LABEL_KEYS: readonly ["scrollUp", "scrollDown", "scrollLeft", "scrollRight", "scrollToTop", "scrollToBottom", "noItems"];
|
|
88
|
+
/**
|
|
89
|
+
* Frozen built-in catalogs per locale. `en` is the package's historical English wording.
|
|
90
|
+
* ロケールごとの凍結済み内蔵カタログ。`en` はパッケージ従来の英語文言。
|
|
91
|
+
*/
|
|
92
|
+
export declare const VIRTUAL_SCROLL_LABEL_CATALOGS: Readonly<Record<VirtualScrollLocale, VirtualScrollLabels>>;
|
|
93
|
+
/**
|
|
94
|
+
* Resolves the UI chrome locale. `undefined` (an absent prop) maps to the default `"en"`; a member
|
|
95
|
+
* of {@link VIRTUAL_SCROLL_LOCALES} is returned as-is. This is the single place the default lives.
|
|
96
|
+
* UI クロームロケールの解決。`undefined` (prop 未指定) は既定の `"en"`、
|
|
97
|
+
* {@link VIRTUAL_SCROLL_LOCALES} の要素はそのまま返却。既定値を持つ唯一の場所。
|
|
98
|
+
*
|
|
99
|
+
* @param locale - Requested locale, or `undefined` for the default / 要求ロケール (`undefined` で既定)
|
|
100
|
+
* @returns The resolved supported locale / 解決済みの対応ロケール
|
|
101
|
+
* @throws {RangeError} When `locale` is neither `undefined` nor a supported locale (`null`, `""`,
|
|
102
|
+
* `"EN"`, `"ja-JP"`, `"fr"`, numbers, ...) — no language negotiation /
|
|
103
|
+
* `undefined` でも対応ロケールでもない場合 (`null`、`""`、`"EN"`、`"ja-JP"`、`"fr"`、数値など)。言語ネゴシエーションなし
|
|
104
|
+
*/
|
|
105
|
+
export declare const resolveVirtualScrollLocale: (locale: VirtualScrollLocale | undefined) => VirtualScrollLocale;
|
|
106
|
+
/**
|
|
107
|
+
* Resolves the effective labels: the catalog of the resolved locale overlaid by `overrides`.
|
|
108
|
+
* Returns the frozen catalog itself (same identity) when `overrides` is `undefined`, otherwise a
|
|
109
|
+
* new frozen object. Inputs are never mutated.
|
|
110
|
+
* 実効ラベルの解決。解決済みロケールのカタログへ `overrides` を重ねた結果。`overrides` が
|
|
111
|
+
* `undefined` なら凍結カタログそのもの (同一参照)、それ以外は新しい凍結オブジェクトを返却。入力は不変。
|
|
112
|
+
*
|
|
113
|
+
* @param locale - Requested locale, or `undefined` for the default / 要求ロケール (`undefined` で既定)
|
|
114
|
+
* @param overrides - Per-key overrides, or `undefined` for none / キー単位の上書き (`undefined` で上書きなし)
|
|
115
|
+
* @returns The resolved, frozen labels / 解決済みの凍結ラベル
|
|
116
|
+
* @throws {RangeError} When the locale is unsupported, `overrides` is `null` or not an object,
|
|
117
|
+
* `overrides` is not a plain object (its prototype is neither `Object.prototype` nor `null`, e.g.
|
|
118
|
+
* an array or a class instance), an own key is not a label key, or a present own value is not a
|
|
119
|
+
* string with non-whitespace content. Only own properties are read /
|
|
120
|
+
* ロケールが非対応、`overrides` が `null` または非オブジェクト、`overrides` が素のオブジェクトでない
|
|
121
|
+
* (プロトタイプが `Object.prototype` でも `null` でもない。配列やクラスインスタンスなど)、自身のキーが
|
|
122
|
+
* ラベルキー外、または与えられた自身の値が空白以外の文字を含む文字列でない場合。読むのは自身の
|
|
123
|
+
* プロパティのみ
|
|
124
|
+
*/
|
|
125
|
+
export declare const resolveVirtualScrollLabels: (locale: VirtualScrollLocale | undefined, overrides: VirtualScrollLabelOverrides | undefined) => VirtualScrollLabels;
|
package/dist/labels.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module labels
|
|
3
|
+
* @description Built-in UI chrome label catalog of the package. Covers exactly the seven strings
|
|
4
|
+
* the components render on their own: the ScrollBar arrow aria-labels, the VirtualScroll
|
|
5
|
+
* scroll-to-edge pill texts and the empty-state text. Live-region wording stays consumer-owned
|
|
6
|
+
* (`liveRegion.format` / `liveRegion.buildMessage`) and is not part of this catalog. The default
|
|
7
|
+
* locale is `"en"`; `"ja"` is the second locale. No language negotiation happens here: hosts map
|
|
8
|
+
* `navigator.language` (or anything else) to a supported locale themselves.
|
|
9
|
+
*
|
|
10
|
+
* @description パッケージ内蔵の UI クローム文言カタログ。コンポーネント自身が描画する 7 文言
|
|
11
|
+
* (ScrollBar 矢印の aria-label、VirtualScroll の端スクロールピル文言、空状態文言) だけを対象とし、
|
|
12
|
+
* ライブリージョンの文言は利用側の所有 (`liveRegion.format` / `liveRegion.buildMessage`) で
|
|
13
|
+
* 本カタログの対象外。既定ロケールは `"en"`、第 2 ロケールは `"ja"`。言語ネゴシエーションは行わず、
|
|
14
|
+
* `navigator.language` 等から対応ロケールへの対応付けはホスト側の責務。
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Supported UI chrome locales, in declaration order. The first entry is NOT implicitly the
|
|
18
|
+
* default — the default lives only in {@link resolveVirtualScrollLocale}.
|
|
19
|
+
* 対応する UI クロームロケールの一覧 (宣言順)。先頭要素が暗黙の既定値になるわけではなく、
|
|
20
|
+
* 既定値は {@link resolveVirtualScrollLocale} にのみ存在。
|
|
21
|
+
*/
|
|
22
|
+
export declare const VIRTUAL_SCROLL_LOCALES: readonly ["en", "ja"];
|
|
23
|
+
/**
|
|
24
|
+
* A supported UI chrome locale (`"en"` | `"ja"`).
|
|
25
|
+
* 対応 UI クロームロケール (`"en"` | `"ja"`)。
|
|
26
|
+
*/
|
|
27
|
+
export type VirtualScrollLocale = (typeof VIRTUAL_SCROLL_LOCALES)[number];
|
|
28
|
+
/**
|
|
29
|
+
* The complete set of built-in chrome strings, one value per rendered surface.
|
|
30
|
+
* 内蔵クローム文言の完全な集合 (描画面ごとに 1 値)。
|
|
31
|
+
*/
|
|
32
|
+
export type VirtualScrollLabels = {
|
|
33
|
+
/**
|
|
34
|
+
* aria-label of the vertical ScrollBar start (up) arrow button.
|
|
35
|
+
* 縦 ScrollBar 始端 (上) 矢印ボタンの aria-label。
|
|
36
|
+
*/
|
|
37
|
+
readonly scrollUp: string;
|
|
38
|
+
/**
|
|
39
|
+
* aria-label of the vertical ScrollBar end (down) arrow button.
|
|
40
|
+
* 縦 ScrollBar 終端 (下) 矢印ボタンの aria-label。
|
|
41
|
+
*/
|
|
42
|
+
readonly scrollDown: string;
|
|
43
|
+
/**
|
|
44
|
+
* aria-label of the horizontal ScrollBar start (left) arrow button.
|
|
45
|
+
* 横 ScrollBar 始端 (左) 矢印ボタンの aria-label。
|
|
46
|
+
*/
|
|
47
|
+
readonly scrollLeft: string;
|
|
48
|
+
/**
|
|
49
|
+
* aria-label of the horizontal ScrollBar end (right) arrow button.
|
|
50
|
+
* 横 ScrollBar 終端 (右) 矢印ボタンの aria-label。
|
|
51
|
+
*/
|
|
52
|
+
readonly scrollRight: string;
|
|
53
|
+
/**
|
|
54
|
+
* Text of the VirtualScroll scroll-to-top pill, shown when
|
|
55
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` is on.
|
|
56
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` 有効時に表示される VirtualScroll 先頭移動ピルの文言。
|
|
57
|
+
*/
|
|
58
|
+
readonly scrollToTop: string;
|
|
59
|
+
/**
|
|
60
|
+
* Text of the VirtualScroll scroll-to-bottom pill, shown when
|
|
61
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` is on.
|
|
62
|
+
* `scrollBarOptions.enableScrollToTopBottomButtons` 有効時に表示される VirtualScroll 末尾移動ピルの文言。
|
|
63
|
+
*/
|
|
64
|
+
readonly scrollToBottom: string;
|
|
65
|
+
/**
|
|
66
|
+
* VirtualScroll empty-state text shown when `itemCount === 0`. VirtualGrid shows it too, for
|
|
67
|
+
* 0 rows, an all-frozen row set and degenerate bands (its embedded VirtualScroll gets 0 items).
|
|
68
|
+
* `itemCount === 0` 時の VirtualScroll 空状態文言。VirtualGrid も 0 行・全行固定・退化帯で表示
|
|
69
|
+
* (内蔵 VirtualScroll の項目数が 0 になるため)。
|
|
70
|
+
*/
|
|
71
|
+
readonly noItems: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Partial per-key overrides laid over the catalog of the chosen locale. An `undefined` value keeps
|
|
75
|
+
* the catalog value; any present value must be a string with non-whitespace content.
|
|
76
|
+
* 選択ロケールのカタログへ重ねるキー単位の部分上書き。`undefined` 値はカタログ値を維持し、
|
|
77
|
+
* 値を与える場合は空白以外の文字を含む文字列であることが必須。
|
|
78
|
+
*/
|
|
79
|
+
export type VirtualScrollLabelOverrides = {
|
|
80
|
+
readonly [K in keyof VirtualScrollLabels]?: VirtualScrollLabels[K];
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Every key of {@link VirtualScrollLabels}, in catalog order. This is the closed key set that
|
|
84
|
+
* overrides are validated against.
|
|
85
|
+
* {@link VirtualScrollLabels} の全キー (カタログ順)。上書き検証に用いる閉じたキー集合。
|
|
86
|
+
*/
|
|
87
|
+
export declare const VIRTUAL_SCROLL_LABEL_KEYS: readonly ["scrollUp", "scrollDown", "scrollLeft", "scrollRight", "scrollToTop", "scrollToBottom", "noItems"];
|
|
88
|
+
/**
|
|
89
|
+
* Frozen built-in catalogs per locale. `en` is the package's historical English wording.
|
|
90
|
+
* ロケールごとの凍結済み内蔵カタログ。`en` はパッケージ従来の英語文言。
|
|
91
|
+
*/
|
|
92
|
+
export declare const VIRTUAL_SCROLL_LABEL_CATALOGS: Readonly<Record<VirtualScrollLocale, VirtualScrollLabels>>;
|
|
93
|
+
/**
|
|
94
|
+
* Resolves the UI chrome locale. `undefined` (an absent prop) maps to the default `"en"`; a member
|
|
95
|
+
* of {@link VIRTUAL_SCROLL_LOCALES} is returned as-is. This is the single place the default lives.
|
|
96
|
+
* UI クロームロケールの解決。`undefined` (prop 未指定) は既定の `"en"`、
|
|
97
|
+
* {@link VIRTUAL_SCROLL_LOCALES} の要素はそのまま返却。既定値を持つ唯一の場所。
|
|
98
|
+
*
|
|
99
|
+
* @param locale - Requested locale, or `undefined` for the default / 要求ロケール (`undefined` で既定)
|
|
100
|
+
* @returns The resolved supported locale / 解決済みの対応ロケール
|
|
101
|
+
* @throws {RangeError} When `locale` is neither `undefined` nor a supported locale (`null`, `""`,
|
|
102
|
+
* `"EN"`, `"ja-JP"`, `"fr"`, numbers, ...) — no language negotiation /
|
|
103
|
+
* `undefined` でも対応ロケールでもない場合 (`null`、`""`、`"EN"`、`"ja-JP"`、`"fr"`、数値など)。言語ネゴシエーションなし
|
|
104
|
+
*/
|
|
105
|
+
export declare const resolveVirtualScrollLocale: (locale: VirtualScrollLocale | undefined) => VirtualScrollLocale;
|
|
106
|
+
/**
|
|
107
|
+
* Resolves the effective labels: the catalog of the resolved locale overlaid by `overrides`.
|
|
108
|
+
* Returns the frozen catalog itself (same identity) when `overrides` is `undefined`, otherwise a
|
|
109
|
+
* new frozen object. Inputs are never mutated.
|
|
110
|
+
* 実効ラベルの解決。解決済みロケールのカタログへ `overrides` を重ねた結果。`overrides` が
|
|
111
|
+
* `undefined` なら凍結カタログそのもの (同一参照)、それ以外は新しい凍結オブジェクトを返却。入力は不変。
|
|
112
|
+
*
|
|
113
|
+
* @param locale - Requested locale, or `undefined` for the default / 要求ロケール (`undefined` で既定)
|
|
114
|
+
* @param overrides - Per-key overrides, or `undefined` for none / キー単位の上書き (`undefined` で上書きなし)
|
|
115
|
+
* @returns The resolved, frozen labels / 解決済みの凍結ラベル
|
|
116
|
+
* @throws {RangeError} When the locale is unsupported, `overrides` is `null` or not an object,
|
|
117
|
+
* `overrides` is not a plain object (its prototype is neither `Object.prototype` nor `null`, e.g.
|
|
118
|
+
* an array or a class instance), an own key is not a label key, or a present own value is not a
|
|
119
|
+
* string with non-whitespace content. Only own properties are read /
|
|
120
|
+
* ロケールが非対応、`overrides` が `null` または非オブジェクト、`overrides` が素のオブジェクトでない
|
|
121
|
+
* (プロトタイプが `Object.prototype` でも `null` でもない。配列やクラスインスタンスなど)、自身のキーが
|
|
122
|
+
* ラベルキー外、または与えられた自身の値が空白以外の文字を含む文字列でない場合。読むのは自身の
|
|
123
|
+
* プロパティのみ
|
|
124
|
+
*/
|
|
125
|
+
export declare const resolveVirtualScrollLabels: (locale: VirtualScrollLocale | undefined, overrides: VirtualScrollLabelOverrides | undefined) => VirtualScrollLabels;
|
|
126
|
+
//# sourceMappingURL=labels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../src/labels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,uBAAwB,CAAA;AAE3D;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAC9B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,mBAAmB,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC;CAAE,CAAA;AAEhH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,8GAAgK,CAAA;AAMtM;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAmBnG,CAAA;AAiCF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,mBAAmB,GAAG,SAAS,KAAG,mBASpF,CAAA;AAWD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,mBAAmB,GAAG,SAAS,EAAE,WAAW,2BAA2B,GAAG,SAAS,KAAG,mBAiCxI,CAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module pointerCapture
|
|
3
|
+
* @description The single capability rule for the Pointer Capture API, shared by every pointer interaction in this package.
|
|
4
|
+
*
|
|
5
|
+
* @description 本パッケージのすべてのポインタ操作が共有する、Pointer Capture API の唯一の能力判定モジュール。
|
|
6
|
+
*
|
|
7
|
+
* `ScrollPane` (コンテンツのドラッグスクロール)・`ScrollBar` (サム / トラックのドラッグ)・
|
|
8
|
+
* `TapScrollCircle` (タップスクロールサークル) は、キャプチャの取得・解放・保持確認を
|
|
9
|
+
* 必ずここを通して行う。要素の `setPointerCapture` / `releasePointerCapture` /
|
|
10
|
+
* `hasPointerCapture` を直接呼んではならない。
|
|
11
|
+
*
|
|
12
|
+
* ❗ **3 つのメソッドが揃っている要素だけを「対応」とみなす。** jsdom (React のテストの既定環境) は
|
|
13
|
+
* このどれも実装しないため、直接呼ぶと利用側の `user.click` 1 回で `TypeError` になる。
|
|
14
|
+
* 一部だけを実装する環境で「取得はしたが解放も確認もできない」状態を作らないよう、判定は 1 本にしてある。
|
|
15
|
+
*
|
|
16
|
+
* 非対応の要素ではキャプチャ無しで操作を続ける (縮退)。コンテンツ領域とサムのドラッグは
|
|
17
|
+
* `window` / `document` のリスナーが追従を受け持つため動き続け、トラックとタップサークルは
|
|
18
|
+
* ポインタが要素上にある間だけ追従する。失われるのは、ウインドウ外や iframe 上で離したときの
|
|
19
|
+
* 終端イベントの受信と、`lostpointercapture` による強制解放の検知である。
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Outcome of a pointer capture request.
|
|
23
|
+
* ポインタキャプチャ要求の結果。
|
|
24
|
+
*
|
|
25
|
+
* - `"captured"`: The element now holds the capture. / 要素がキャプチャを保持した。
|
|
26
|
+
* - `"unsupported"`: The element does not implement the Pointer Capture API; nothing was attempted. / 要素が API を実装しておらず、要求自体を行っていない。
|
|
27
|
+
* - `"inactive-pointer"`: The UA rejected the pointer as inactive (`NotFoundError`). / ポインタが非アクティブとして拒否された (`NotFoundError`)。
|
|
28
|
+
* - `"rejected"`: The UA rejected the request for any other reason. / それ以外の理由で拒否された。
|
|
29
|
+
*/
|
|
30
|
+
export type PointerCaptureResult = "captured" | "unsupported" | "inactive-pointer" | "rejected";
|
|
31
|
+
/**
|
|
32
|
+
* Reports whether the element implements the whole Pointer Capture API.
|
|
33
|
+
* 要素が Pointer Capture API (取得・解放・保持確認の 3 メソッド) をすべて実装しているかの判定処理。
|
|
34
|
+
*
|
|
35
|
+
* @param element The element to inspect. 判定対象の要素。
|
|
36
|
+
* @returns True when set / release / has are all callable. 3 メソッドがすべて呼び出し可能な場合に true。
|
|
37
|
+
*/
|
|
38
|
+
export declare const supportsPointerCapture: (element: Element) => boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Reports whether the element holds (or has a pending) capture of the pointer.
|
|
41
|
+
* 要素が指定ポインタのキャプチャを保持 (または保留) しているかの判定処理。
|
|
42
|
+
*
|
|
43
|
+
* @param element The element to inspect. 判定対象の要素。
|
|
44
|
+
* @param pointerId The pointer to look up. 対象のポインタ ID。
|
|
45
|
+
* @returns True when the capture is held; always false when the API is unsupported. 保持している場合に true。API 非対応の要素では常に false。
|
|
46
|
+
*/
|
|
47
|
+
export declare const isPointerCaptured: (element: Element, pointerId: number) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Requests capture of the pointer for the element and classifies the outcome without throwing.
|
|
50
|
+
* 要素へ指定ポインタのキャプチャを要求し、例外を投げずに結果を分類する処理。
|
|
51
|
+
*
|
|
52
|
+
* @param element The element that should receive the capture. キャプチャを受け取る要素。
|
|
53
|
+
* @param pointerId The pointer to capture. キャプチャするポインタ ID。
|
|
54
|
+
* @returns The classified outcome of the request. 要求結果の分類。
|
|
55
|
+
*/
|
|
56
|
+
export declare const capturePointer: (element: Element, pointerId: number) => PointerCaptureResult;
|
|
57
|
+
/**
|
|
58
|
+
* Releases the element's capture of the pointer when it holds one; does nothing otherwise.
|
|
59
|
+
* 要素が指定ポインタのキャプチャを保持していれば解放し、保持していなければ何もしない処理。
|
|
60
|
+
*
|
|
61
|
+
* 呼び出し側が状態を確定させてから呼ぶこと。`lostpointercapture` を同期発火するブラウザでは、
|
|
62
|
+
* この呼び出しの最中に喪失ハンドラーが走る。
|
|
63
|
+
*
|
|
64
|
+
* @param element The element that may hold the capture. キャプチャを保持している可能性のある要素。
|
|
65
|
+
* @param pointerId The pointer to release. 解放するポインタ ID。
|
|
66
|
+
* @returns Nothing. なし。
|
|
67
|
+
*/
|
|
68
|
+
export declare const releaseCapturedPointer: (element: Element, pointerId: number) => void;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module pointerCapture
|
|
3
|
+
* @description The single capability rule for the Pointer Capture API, shared by every pointer interaction in this package.
|
|
4
|
+
*
|
|
5
|
+
* @description 本パッケージのすべてのポインタ操作が共有する、Pointer Capture API の唯一の能力判定モジュール。
|
|
6
|
+
*
|
|
7
|
+
* `ScrollPane` (コンテンツのドラッグスクロール)・`ScrollBar` (サム / トラックのドラッグ)・
|
|
8
|
+
* `TapScrollCircle` (タップスクロールサークル) は、キャプチャの取得・解放・保持確認を
|
|
9
|
+
* 必ずここを通して行う。要素の `setPointerCapture` / `releasePointerCapture` /
|
|
10
|
+
* `hasPointerCapture` を直接呼んではならない。
|
|
11
|
+
*
|
|
12
|
+
* ❗ **3 つのメソッドが揃っている要素だけを「対応」とみなす。** jsdom (React のテストの既定環境) は
|
|
13
|
+
* このどれも実装しないため、直接呼ぶと利用側の `user.click` 1 回で `TypeError` になる。
|
|
14
|
+
* 一部だけを実装する環境で「取得はしたが解放も確認もできない」状態を作らないよう、判定は 1 本にしてある。
|
|
15
|
+
*
|
|
16
|
+
* 非対応の要素ではキャプチャ無しで操作を続ける (縮退)。コンテンツ領域とサムのドラッグは
|
|
17
|
+
* `window` / `document` のリスナーが追従を受け持つため動き続け、トラックとタップサークルは
|
|
18
|
+
* ポインタが要素上にある間だけ追従する。失われるのは、ウインドウ外や iframe 上で離したときの
|
|
19
|
+
* 終端イベントの受信と、`lostpointercapture` による強制解放の検知である。
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Outcome of a pointer capture request.
|
|
23
|
+
* ポインタキャプチャ要求の結果。
|
|
24
|
+
*
|
|
25
|
+
* - `"captured"`: The element now holds the capture. / 要素がキャプチャを保持した。
|
|
26
|
+
* - `"unsupported"`: The element does not implement the Pointer Capture API; nothing was attempted. / 要素が API を実装しておらず、要求自体を行っていない。
|
|
27
|
+
* - `"inactive-pointer"`: The UA rejected the pointer as inactive (`NotFoundError`). / ポインタが非アクティブとして拒否された (`NotFoundError`)。
|
|
28
|
+
* - `"rejected"`: The UA rejected the request for any other reason. / それ以外の理由で拒否された。
|
|
29
|
+
*/
|
|
30
|
+
export type PointerCaptureResult = "captured" | "unsupported" | "inactive-pointer" | "rejected";
|
|
31
|
+
/**
|
|
32
|
+
* Reports whether the element implements the whole Pointer Capture API.
|
|
33
|
+
* 要素が Pointer Capture API (取得・解放・保持確認の 3 メソッド) をすべて実装しているかの判定処理。
|
|
34
|
+
*
|
|
35
|
+
* @param element The element to inspect. 判定対象の要素。
|
|
36
|
+
* @returns True when set / release / has are all callable. 3 メソッドがすべて呼び出し可能な場合に true。
|
|
37
|
+
*/
|
|
38
|
+
export declare const supportsPointerCapture: (element: Element) => boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Reports whether the element holds (or has a pending) capture of the pointer.
|
|
41
|
+
* 要素が指定ポインタのキャプチャを保持 (または保留) しているかの判定処理。
|
|
42
|
+
*
|
|
43
|
+
* @param element The element to inspect. 判定対象の要素。
|
|
44
|
+
* @param pointerId The pointer to look up. 対象のポインタ ID。
|
|
45
|
+
* @returns True when the capture is held; always false when the API is unsupported. 保持している場合に true。API 非対応の要素では常に false。
|
|
46
|
+
*/
|
|
47
|
+
export declare const isPointerCaptured: (element: Element, pointerId: number) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Requests capture of the pointer for the element and classifies the outcome without throwing.
|
|
50
|
+
* 要素へ指定ポインタのキャプチャを要求し、例外を投げずに結果を分類する処理。
|
|
51
|
+
*
|
|
52
|
+
* @param element The element that should receive the capture. キャプチャを受け取る要素。
|
|
53
|
+
* @param pointerId The pointer to capture. キャプチャするポインタ ID。
|
|
54
|
+
* @returns The classified outcome of the request. 要求結果の分類。
|
|
55
|
+
*/
|
|
56
|
+
export declare const capturePointer: (element: Element, pointerId: number) => PointerCaptureResult;
|
|
57
|
+
/**
|
|
58
|
+
* Releases the element's capture of the pointer when it holds one; does nothing otherwise.
|
|
59
|
+
* 要素が指定ポインタのキャプチャを保持していれば解放し、保持していなければ何もしない処理。
|
|
60
|
+
*
|
|
61
|
+
* 呼び出し側が状態を確定させてから呼ぶこと。`lostpointercapture` を同期発火するブラウザでは、
|
|
62
|
+
* この呼び出しの最中に喪失ハンドラーが走る。
|
|
63
|
+
*
|
|
64
|
+
* @param element The element that may hold the capture. キャプチャを保持している可能性のある要素。
|
|
65
|
+
* @param pointerId The pointer to release. 解放するポインタ ID。
|
|
66
|
+
* @returns Nothing. なし。
|
|
67
|
+
*/
|
|
68
|
+
export declare const releaseCapturedPointer: (element: Element, pointerId: number) => void;
|
|
69
|
+
//# sourceMappingURL=pointerCapture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pointerCapture.d.ts","sourceRoot":"","sources":["../src/pointerCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,aAAa,GAAG,kBAAkB,GAAG,UAAU,CAAA;AAE/F;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,OAAO,KAAG,OAAoK,CAAA;AAE9N;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,OAAO,EAAE,WAAW,MAAM,KAAG,OAAkF,CAAA;AAE1J;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,OAAO,EAAE,WAAW,MAAM,KAAG,oBAYpE,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,OAAO,EAAE,WAAW,MAAM,KAAG,IAI5E,CAAA"}
|
package/package.json
CHANGED
package/src/ScrollBar.tsx
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import type { CSSProperties, ReactNode } from "react"
|
|
7
7
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
|
|
8
8
|
import { twMerge } from "tailwind-merge"
|
|
9
|
+
import { resolveVirtualScrollLabels, type VirtualScrollLabelOverrides, type VirtualScrollLocale } from "./labels.ts"
|
|
9
10
|
import { Logger } from "./logger.ts"
|
|
11
|
+
import { capturePointer, releaseCapturedPointer } from "./pointerCapture.ts"
|
|
10
12
|
import { TapScrollCircle, type TapScrollCircleDragState, type TapScrollCircleHandle, type TapScrollCircleRenderProps } from "./TapScrollCircle.tsx"
|
|
11
13
|
import { getAxisScale, minmax } from "./utils.ts"
|
|
12
14
|
|
|
@@ -21,7 +23,6 @@ type OrientationConfig = {
|
|
|
21
23
|
positionKey: "left" | "top"
|
|
22
24
|
selectDelta: (deltaX: number, deltaY: number) => number
|
|
23
25
|
getPointerCoordinate: (point: { clientX: number; clientY: number }) => number
|
|
24
|
-
arrowLabels: [string, string]
|
|
25
26
|
arrowIcons: [string, string]
|
|
26
27
|
directionClass: string
|
|
27
28
|
orientation: "vertical" | "horizontal"
|
|
@@ -193,6 +194,21 @@ export type ScrollBarProps = {
|
|
|
193
194
|
visibleStartIndex?: number
|
|
194
195
|
/** The index of the last visible item. / 最後の可視アイテムのインデックス。 */
|
|
195
196
|
visibleEndIndex?: number
|
|
197
|
+
/**
|
|
198
|
+
* UI chrome locale of the built-in arrow aria-labels (default `"en"`). An unsupported value
|
|
199
|
+
* throws a RangeError at render; no language negotiation happens.
|
|
200
|
+
* 内蔵矢印 aria-label の UI クロームロケール (既定 `"en"`)。非対応値は描画時に RangeError、
|
|
201
|
+
* 言語ネゴシエーションなし。
|
|
202
|
+
*/
|
|
203
|
+
locale?: VirtualScrollLocale
|
|
204
|
+
/**
|
|
205
|
+
* Per-key overrides laid over the catalog of `locale`. This bar reads `scrollUp` / `scrollDown`
|
|
206
|
+
* (vertical) or `scrollLeft` / `scrollRight` (horizontal); unknown keys and blank values throw a
|
|
207
|
+
* RangeError at render.
|
|
208
|
+
* `locale` のカタログへ重ねるキー単位の上書き。本バーが読むのは縦なら `scrollUp` / `scrollDown`、
|
|
209
|
+
* 横なら `scrollLeft` / `scrollRight`。未知キーと空白値は描画時に RangeError。
|
|
210
|
+
*/
|
|
211
|
+
labels?: VirtualScrollLabelOverrides
|
|
196
212
|
}
|
|
197
213
|
|
|
198
214
|
/** The minimum size of the scrollbar thumb. / スクロールバーのつまみの最小サイズ。 */
|
|
@@ -255,7 +271,6 @@ const createOrientationConfig = (horizontal: boolean): OrientationConfig => {
|
|
|
255
271
|
positionKey: "left",
|
|
256
272
|
selectDelta: (deltaX: number, _deltaY: number) => deltaX,
|
|
257
273
|
getPointerCoordinate: ({ clientX }) => clientX,
|
|
258
|
-
arrowLabels: ["Scroll left", "Scroll right"],
|
|
259
274
|
arrowIcons: ["◀", "▶"],
|
|
260
275
|
directionClass: "aqvs-scrollbar-horizontal",
|
|
261
276
|
orientation: "horizontal",
|
|
@@ -268,7 +283,6 @@ const createOrientationConfig = (horizontal: boolean): OrientationConfig => {
|
|
|
268
283
|
positionKey: "top",
|
|
269
284
|
selectDelta: (_deltaX: number, deltaY: number) => deltaY,
|
|
270
285
|
getPointerCoordinate: ({ clientY }) => clientY,
|
|
271
|
-
arrowLabels: ["Scroll up", "Scroll down"],
|
|
272
286
|
arrowIcons: ["▲", "▼"],
|
|
273
287
|
directionClass: "aqvs-scrollbar-vertical",
|
|
274
288
|
orientation: "vertical",
|
|
@@ -608,6 +622,8 @@ export const ScrollBar = ({
|
|
|
608
622
|
renderThumbOverlay,
|
|
609
623
|
visibleStartIndex,
|
|
610
624
|
visibleEndIndex,
|
|
625
|
+
locale,
|
|
626
|
+
labels,
|
|
611
627
|
}: ScrollBarProps) => {
|
|
612
628
|
const [isDragging, setIsDragging] = useState(false)
|
|
613
629
|
const [isThumbHovered, setIsThumbHovered] = useState(false)
|
|
@@ -635,6 +651,8 @@ export const ScrollBar = ({
|
|
|
635
651
|
const autoScrollDirectionRef = useRef<0 | 1 | -1>(0)
|
|
636
652
|
const resolvedTapScrollOptions = useMemo<ResolvedTapScrollCircleOptions>(() => resolveTapScrollCircleOptions(tapScrollCircleOptions, itemCount), [itemCount, tapScrollCircleOptions])
|
|
637
653
|
const orientationConfig = useMemo(() => createOrientationConfig(horizontal), [horizontal])
|
|
654
|
+
const resolvedLabels = useMemo(() => resolveVirtualScrollLabels(locale, labels), [locale, labels])
|
|
655
|
+
const arrowLabels = horizontal ? ([resolvedLabels.scrollLeft, resolvedLabels.scrollRight] as const) : ([resolvedLabels.scrollUp, resolvedLabels.scrollDown] as const)
|
|
638
656
|
const {
|
|
639
657
|
enabled: tapCircleEnabled,
|
|
640
658
|
size: tapCircleSize,
|
|
@@ -661,7 +679,7 @@ export const ScrollBar = ({
|
|
|
661
679
|
onScroll,
|
|
662
680
|
scrollPosition,
|
|
663
681
|
})
|
|
664
|
-
const { mainSizeKey, crossSizeKey, positionKey, selectDelta, getPointerCoordinate,
|
|
682
|
+
const { mainSizeKey, crossSizeKey, positionKey, selectDelta, getPointerCoordinate, arrowIcons, directionClass, orientation } = orientationConfig
|
|
665
683
|
const effectiveTapMaxDistance = Math.max(tapCircleMaxDistance, 1)
|
|
666
684
|
// 表示領域に対するコンテンツの比率
|
|
667
685
|
const scrollRatio = viewportSize / contentSize
|
|
@@ -1119,10 +1137,10 @@ export const ScrollBar = ({
|
|
|
1119
1137
|
|
|
1120
1138
|
/**
|
|
1121
1139
|
* Pointer up handler for thumb dragging.
|
|
1122
|
-
* Cleans up drag state and visual feedback.
|
|
1140
|
+
* Cleans up drag state and visual feedback, releasing the capture only when the press acquired one.
|
|
1123
1141
|
*
|
|
1124
1142
|
* つまみドラッグ用のポインタ上げハンドラー。
|
|
1125
|
-
*
|
|
1143
|
+
* ドラッグ状態と視覚的フィードバックをクリーンアップし、押下時にキャプチャを取得できていた場合だけ解放します。
|
|
1126
1144
|
*/
|
|
1127
1145
|
const handleThumbPointerUp = useCallback(
|
|
1128
1146
|
(event: PointerEvent) => {
|
|
@@ -1135,9 +1153,8 @@ export const ScrollBar = ({
|
|
|
1135
1153
|
document.removeEventListener("pointerup", handleThumbPointerUp)
|
|
1136
1154
|
document.removeEventListener("pointercancel", handleThumbPointerUp)
|
|
1137
1155
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
captureTarget.releasePointerCapture(event.pointerId)
|
|
1156
|
+
if (state.captureTarget !== null) {
|
|
1157
|
+
releaseCapturedPointer(state.captureTarget, event.pointerId)
|
|
1141
1158
|
}
|
|
1142
1159
|
|
|
1143
1160
|
thumbDragStateRef.current = { pointerId: null, startThumbPosition: 0, startClientX: 0, startClientY: 0, scale: 1, captureTarget: null }
|
|
@@ -1210,8 +1227,10 @@ export const ScrollBar = ({
|
|
|
1210
1227
|
// スクロールバーのつまみをポインタイベントで処理
|
|
1211
1228
|
/**
|
|
1212
1229
|
* Handles pointer down interaction on the thumb.
|
|
1230
|
+
* Captures the pointer when the element supports it; otherwise the drag continues on the document listeners alone.
|
|
1213
1231
|
*
|
|
1214
1232
|
* つまみ押下時のインタラクションを処理。
|
|
1233
|
+
* 要素がキャプチャに対応していれば取得し、取得できなければ document のリスナーだけでドラッグを続ける。
|
|
1215
1234
|
*/
|
|
1216
1235
|
const handlePointerDownOnThumb = (event: React.PointerEvent<HTMLDivElement>) => {
|
|
1217
1236
|
if (!scrollBarVisible) {
|
|
@@ -1230,18 +1249,10 @@ export const ScrollBar = ({
|
|
|
1230
1249
|
|
|
1231
1250
|
// ポインターキャプチャを取得し、iframe/ウィンドウ外での pointerup 取りこぼしによる
|
|
1232
1251
|
// ドラッグ固着を防ぐ。キャプチャ後もイベントは document までバブリングするため既存の
|
|
1233
|
-
// document
|
|
1252
|
+
// document リスナはそのまま機能する。取得できなかったときは解放対象を持たない。
|
|
1234
1253
|
const element = event.currentTarget
|
|
1235
1254
|
const scale = getMainAxisScale(element)
|
|
1236
|
-
|
|
1237
|
-
if (element.setPointerCapture) {
|
|
1238
|
-
try {
|
|
1239
|
-
element.setPointerCapture(event.pointerId)
|
|
1240
|
-
captureTarget = element
|
|
1241
|
-
} catch {
|
|
1242
|
-
captureTarget = null
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1255
|
+
const captureTarget = capturePointer(element, event.pointerId) === "captured" ? element : null
|
|
1245
1256
|
|
|
1246
1257
|
thumbDragStateRef.current = {
|
|
1247
1258
|
pointerId: event.pointerId,
|
|
@@ -1265,8 +1276,10 @@ export const ScrollBar = ({
|
|
|
1265
1276
|
|
|
1266
1277
|
/**
|
|
1267
1278
|
* Handles pointer down interaction on the track.
|
|
1279
|
+
* Jumps to the pressed position and captures the pointer when the element supports it.
|
|
1268
1280
|
*
|
|
1269
1281
|
* トラック押下時のインタラクションを処理。
|
|
1282
|
+
* 押下位置へ移動し、要素がキャプチャに対応していれば取得する。
|
|
1270
1283
|
*/
|
|
1271
1284
|
const handlePointerDownOnTrack = (event: React.PointerEvent<HTMLDivElement>) => {
|
|
1272
1285
|
if (!scrollBarVisible) {
|
|
@@ -1294,15 +1307,9 @@ export const ScrollBar = ({
|
|
|
1294
1307
|
const initialPosition = translateToScrollPosition(startThumbPosition)
|
|
1295
1308
|
resolveScrollRequest(initialPosition)
|
|
1296
1309
|
|
|
1297
|
-
//
|
|
1298
|
-
//
|
|
1299
|
-
|
|
1300
|
-
try {
|
|
1301
|
-
element.setPointerCapture(event.pointerId)
|
|
1302
|
-
} catch {
|
|
1303
|
-
// キャプチャ取得失敗時はキャプチャなしで続行 (要素上の pointermove では追従する)。
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1310
|
+
// 取得できなくても (非アクティブ pointerId・API 非対応) ドラッグ状態の設定と preventDefault は続ける。
|
|
1311
|
+
// キャプチャ無しでも要素上の pointermove では追従する。
|
|
1312
|
+
capturePointer(element, event.pointerId)
|
|
1306
1313
|
|
|
1307
1314
|
trackDragStateRef.current = {
|
|
1308
1315
|
pointerId: event.pointerId,
|
|
@@ -1357,19 +1364,17 @@ export const ScrollBar = ({
|
|
|
1357
1364
|
|
|
1358
1365
|
/**
|
|
1359
1366
|
* Handles pointer up interaction on the track.
|
|
1367
|
+
* Releases the capture when held and ends the track drag.
|
|
1360
1368
|
*
|
|
1361
1369
|
* トラックドラッグ終了時の処理。
|
|
1370
|
+
* キャプチャを保持していれば解放し、トラックドラッグを終える。
|
|
1362
1371
|
*/
|
|
1363
1372
|
const handlePointerUpOnTrack = (event: React.PointerEvent<HTMLDivElement>) => {
|
|
1364
1373
|
if (trackDragStateRef.current.pointerId !== event.pointerId) {
|
|
1365
1374
|
return
|
|
1366
1375
|
}
|
|
1367
1376
|
|
|
1368
|
-
|
|
1369
|
-
const element = event.currentTarget
|
|
1370
|
-
if (element.hasPointerCapture?.(event.pointerId)) {
|
|
1371
|
-
element.releasePointerCapture(event.pointerId)
|
|
1372
|
-
}
|
|
1377
|
+
releaseCapturedPointer(event.currentTarget, event.pointerId)
|
|
1373
1378
|
|
|
1374
1379
|
resetTrackDragState()
|
|
1375
1380
|
|
|
@@ -1379,19 +1384,17 @@ export const ScrollBar = ({
|
|
|
1379
1384
|
|
|
1380
1385
|
/**
|
|
1381
1386
|
* Handles pointer cancel interaction on the track.
|
|
1387
|
+
* Releases the capture when held and discards the track drag.
|
|
1382
1388
|
*
|
|
1383
1389
|
* トラックドラッグキャンセル時の処理。
|
|
1390
|
+
* キャプチャを保持していれば解放し、トラックドラッグを破棄する。
|
|
1384
1391
|
*/
|
|
1385
1392
|
const handlePointerCancelOnTrack = (event: React.PointerEvent<HTMLDivElement>) => {
|
|
1386
1393
|
if (trackDragStateRef.current.pointerId !== event.pointerId) {
|
|
1387
1394
|
return
|
|
1388
1395
|
}
|
|
1389
1396
|
|
|
1390
|
-
|
|
1391
|
-
const element = event.currentTarget
|
|
1392
|
-
if (element.hasPointerCapture?.(event.pointerId)) {
|
|
1393
|
-
element.releasePointerCapture(event.pointerId)
|
|
1394
|
-
}
|
|
1397
|
+
releaseCapturedPointer(event.currentTarget, event.pointerId)
|
|
1395
1398
|
|
|
1396
1399
|
resetTrackDragState()
|
|
1397
1400
|
}
|