@onekeyfe/react-native-native-list 3.0.113 → 3.0.115
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/android/build.gradle +1 -0
- package/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +8 -2
- package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +378 -88
- package/ios/NativeListCell.swift +2 -0
- package/ios/RNCNativeListView.swift +186 -35
- package/lib/module/web/NativeListWebEngine.js +104 -46
- package/lib/typescript/src/web/NativeListWebEngine.d.ts +11 -2
- package/package.json +4 -2
- package/src/web/NativeListWebEngine.ts +190 -89
|
@@ -8,7 +8,7 @@ import { acquireNativeListAvatar, canonicalNativeListAvatarUri } from "./NativeL
|
|
|
8
8
|
const SECTION_INDEX_CONTENT_INSET = 16;
|
|
9
9
|
const SECTION_INDEX_RAIL_WIDTH = 32;
|
|
10
10
|
const SECTION_INDEX_EDGE_PADDING = 8;
|
|
11
|
-
const
|
|
11
|
+
const SECTION_INDEX_LABEL_SPACING = 16;
|
|
12
12
|
const SECTION_INDEX_MIN_HEIGHT = 120;
|
|
13
13
|
const DEFAULT_VIEWPORT_WIDTH = 320;
|
|
14
14
|
const DEFAULT_VIEWPORT_HEIGHT = 640;
|
|
@@ -394,6 +394,17 @@ export function visibleWebLayoutItems(layout, offset, viewportLength, overscan =
|
|
|
394
394
|
}
|
|
395
395
|
return visible;
|
|
396
396
|
}
|
|
397
|
+
export function resolveWebCollapsiblePagerScrollMetrics(rawOffset, rawViewportLength, headerInset, stickyInset) {
|
|
398
|
+
const header = Math.max(0, headerInset);
|
|
399
|
+
const sticky = Math.max(0, stickyInset);
|
|
400
|
+
return {
|
|
401
|
+
offset: Math.max(0, rawOffset - header),
|
|
402
|
+
viewportLength: Math.max(0, rawViewportLength - sticky)
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
export function resolveWebCollapsiblePagerRawOffset(logicalOffset, headerInset) {
|
|
406
|
+
return Math.max(0, logicalOffset) + Math.max(0, headerInset);
|
|
407
|
+
}
|
|
397
408
|
export function webLayoutItemsForMount(layout, offset, viewportLength, virtualizationEnabled, overscan = 0) {
|
|
398
409
|
return virtualizationEnabled ? visibleWebLayoutItems(layout, offset, viewportLength, overscan) : layout.items;
|
|
399
410
|
}
|
|
@@ -493,6 +504,11 @@ export const WEB_LIST_CSS = `
|
|
|
493
504
|
.ok-native-list-subtitle-segments{display:flex;align-items:center;min-width:0;max-width:100%;height:20px}.ok-native-list-subtitle-segments>.ok-native-list-secondary{flex:0 1 auto;min-width:0}.ok-native-list-subtitle-dot{flex:0 0 4px;width:4px;height:4px;margin:0 6px;border-radius:50%;background:var(--nl-disabled)}.ok-native-list-wallet-row>.ok-native-list-flex{flex:0 1 auto;width:100%;align-items:center}.ok-native-list-wallet-badges{display:flex;gap:4px;justify-content:center;margin-top:4px;height:20px;max-width:100%}.ok-native-list-wallet-badges>.ok-native-list-badge{background:var(--nl-strong);color:var(--nl-secondary);font-size:12px;line-height:16px;height:20px;box-sizing:border-box;padding:2px 4px}.ok-native-list-visual-overlay{position:absolute;display:flex;align-items:center;justify-content:center;box-sizing:border-box;border-radius:50%;overflow:hidden;line-height:1;font-size:10px}.ok-native-list-visual-overlay img,.ok-native-list-visual-overlay svg{width:100%;height:100%;object-fit:contain}
|
|
494
505
|
.ok-native-list-row.ok-native-list-market-skeleton{padding:12px 20px;gap:0}.ok-native-list-skeleton-left{display:flex;align-items:center;gap:12px;flex:1}.ok-native-list-skeleton-text{display:flex;flex-direction:column;gap:4px}.ok-native-list-skeleton-right{display:flex;align-items:center;gap:8px}.ok-native-list-skeleton-mark{display:block;flex-shrink:0;border-radius:8px;animation:ok-native-list-skeleton 1.5s linear infinite alternate}@keyframes ok-native-list-skeleton{from{background-color:var(--nl-skeleton-base)}to{background-color:var(--nl-skeleton-highlight)}}.ok-native-list-market-spinner{display:block;width:20px;height:20px;flex-shrink:0;color:var(--nl-icon);animation:ok-native-list-spin .75s linear infinite}
|
|
495
506
|
@media (prefers-reduced-motion:reduce){.ok-native-list-index-preview,.ok-native-list-refresh{transition:none}.ok-native-list-spinner,.ok-native-list-market-spinner{animation:none}.ok-native-list-skeleton-mark{animation:none;background:var(--nl-skeleton-base)}}
|
|
507
|
+
.ok-native-list-footer{flex:0 0 auto;min-height:0}.ok-native-list-sticky{position:absolute;z-index:4;left:0;right:0;top:0;pointer-events:auto;box-shadow:0 1px 0 var(--nl-separator)}.ok-native-list-viewport-frame:has(>.ok-native-list-index-rail:not([hidden]))>.ok-native-list-viewport{scrollbar-width:none}.ok-native-list-viewport-frame:has(>.ok-native-list-index-rail:not([hidden]))>.ok-native-list-viewport::-webkit-scrollbar{display:none}.ok-native-list-index-rail{position:absolute;z-index:6;top:0;right:0;bottom:0;width:${SECTION_INDEX_RAIL_WIDTH}px;touch-action:none;cursor:pointer}.ok-native-list-index-rail[hidden]{display:none}.ok-native-list-index-button{appearance:none;position:absolute;left:15px;display:flex;width:14px;height:14px;align-items:center;justify-content:center;padding:0;transform:translateY(-50%);border:0;border-radius:7px;background:transparent;color:var(--nl-disabled);font-family:inherit;font-size:10px;font-weight:400;line-height:1;cursor:pointer}.ok-native-list-index-button[data-active="true"]{background:var(--nl-positive);color:var(--nl-inverse-text);font-weight:500}.ok-native-list-index-button:focus-visible{outline:2px solid var(--nl-positive);outline-offset:1px}
|
|
508
|
+
.ok-native-list-refresh{position:absolute;z-index:7;left:50%;top:8px;display:flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;background:var(--nl-inverse);color:var(--nl-inverse-text);font-size:12px;opacity:0;transform:translate(-50%,-16px);transition:opacity .15s ease,transform .15s ease;pointer-events:none}.ok-native-list-refresh[data-visible="true"]{opacity:1;transform:translate(-50%,0)}
|
|
509
|
+
.ok-native-list-warning{height:auto;display:flex;flex-direction:column;align-items:stretch;gap:4px;padding:14px 12px;border-top:1px solid;border-bottom:1px solid;box-sizing:border-box;cursor:default}.ok-native-list-warning-title,.ok-native-list-warning-message{font-size:14px;line-height:20px;white-space:normal;overflow-wrap:anywhere}.ok-native-list-warning-title{font-weight:500;color:var(--nl-primary)}.ok-native-list-warning-message{font-weight:400;color:var(--nl-secondary)}
|
|
510
|
+
.ok-native-list-subtitle-segments{display:flex;align-items:center;min-width:0;max-width:100%;height:20px}.ok-native-list-subtitle-segments>.ok-native-list-secondary{flex:0 1 auto;min-width:0}.ok-native-list-subtitle-dot{flex:0 0 4px;width:4px;height:4px;margin:0 6px;border-radius:50%;background:var(--nl-disabled)}.ok-native-list-wallet-row>.ok-native-list-flex{flex:0 1 auto;width:100%;align-items:center}.ok-native-list-wallet-badges{display:flex;gap:4px;justify-content:center;margin-top:4px;height:20px;max-width:100%}.ok-native-list-wallet-badges>.ok-native-list-badge{background:var(--nl-strong);color:var(--nl-secondary);font-size:12px;line-height:16px;height:20px;box-sizing:border-box;padding:2px 4px}.ok-native-list-visual-overlay{position:absolute;display:flex;align-items:center;justify-content:center;box-sizing:border-box;border-radius:50%;overflow:hidden;line-height:1;font-size:10px}.ok-native-list-visual-overlay img,.ok-native-list-visual-overlay svg{width:100%;height:100%;object-fit:contain}
|
|
511
|
+
@media (prefers-reduced-motion:reduce){.ok-native-list-refresh{transition:none}.ok-native-list-spinner{animation:none}}
|
|
496
512
|
/* OneKey patch: selector controls follow their original semantic colors and geometry. */
|
|
497
513
|
.ok-native-list-checkbox[data-selector="networkSelector"]{padding:0;border-radius:4px;border-color:var(--nl-checkbox-border,var(--nl-separator));background:var(--nl-checkbox-icon,var(--nl-inverse-text))}
|
|
498
514
|
.ok-native-list-checkbox[data-selector="networkSelector"]::after{display:none}
|
|
@@ -1900,8 +1916,6 @@ export class NativeListWebEngine {
|
|
|
1900
1916
|
this.indexRail.setAttribute('role', 'navigation');
|
|
1901
1917
|
this.indexRail.setAttribute('aria-label', 'Section index');
|
|
1902
1918
|
this.indexRail.hidden = true;
|
|
1903
|
-
this.indexPreview = createElement(this.document, 'div', 'ok-native-list-index-preview');
|
|
1904
|
-
this.indexPreview.setAttribute('aria-live', 'polite');
|
|
1905
1919
|
this.refreshIndicator = createElement(this.document, 'div', 'ok-native-list-refresh', 'Refreshing');
|
|
1906
1920
|
this.refreshIndicator.setAttribute('role', 'status');
|
|
1907
1921
|
this.reorderPreview = createElement(this.document, 'div', 'ok-native-list-reorder-preview');
|
|
@@ -1909,12 +1923,13 @@ export class NativeListWebEngine {
|
|
|
1909
1923
|
this.reorderPreview.setAttribute('aria-hidden', 'true');
|
|
1910
1924
|
this.document.body.appendChild(this.reorderPreview);
|
|
1911
1925
|
this.viewport.append(this.content);
|
|
1912
|
-
this.viewportFrame.append(this.viewport, this.sticky, this.indexRail, this.
|
|
1926
|
+
this.viewportFrame.append(this.viewport, this.sticky, this.indexRail, this.refreshIndicator);
|
|
1913
1927
|
this.root.append(style, this.viewportFrame, this.footer);
|
|
1914
1928
|
host.appendChild(this.root);
|
|
1915
1929
|
this.viewport.addEventListener('scroll', this.handleScroll, {
|
|
1916
1930
|
passive: true
|
|
1917
1931
|
});
|
|
1932
|
+
this.viewport.addEventListener('ok-collapsible-pager-insets-changed', this.handleCollapsiblePagerInsetsChanged);
|
|
1918
1933
|
this.root.addEventListener('click', this.handleClick);
|
|
1919
1934
|
this.root.addEventListener('pointerdown', this.handleMarketPointerDown);
|
|
1920
1935
|
this.root.addEventListener('pointermove', this.handleMarketPointerMove);
|
|
@@ -1941,6 +1956,8 @@ export class NativeListWebEngine {
|
|
|
1941
1956
|
this.viewport.addEventListener('touchcancel', this.handleReorderTouchCancel);
|
|
1942
1957
|
this.indexRail.addEventListener('pointerdown', this.handleIndexPointer);
|
|
1943
1958
|
this.indexRail.addEventListener('pointermove', this.handleIndexPointer);
|
|
1959
|
+
this.indexRail.addEventListener('pointerup', this.handleIndexPointerEnd);
|
|
1960
|
+
this.indexRail.addEventListener('pointercancel', this.handleIndexPointerEnd);
|
|
1944
1961
|
this.indexRail.addEventListener('click', this.handleIndexClick);
|
|
1945
1962
|
this.viewport.addEventListener('pointerdown', this.handlePullStart, {
|
|
1946
1963
|
passive: true
|
|
@@ -2117,11 +2134,11 @@ export class NativeListWebEngine {
|
|
|
2117
2134
|
this.invalidateActionAnchor('destroy');
|
|
2118
2135
|
this.destroyed = true;
|
|
2119
2136
|
if (this.frameHandle !== undefined) this.cancelFrame(this.frameHandle);
|
|
2120
|
-
if (this.previewTimer !== undefined) this.document.defaultView?.clearTimeout(this.previewTimer);
|
|
2121
2137
|
if (this.reorderMovementTimer !== undefined) this.document.defaultView?.clearTimeout(this.reorderMovementTimer);
|
|
2122
2138
|
this.resizeObserver?.disconnect();
|
|
2123
2139
|
this.document.defaultView?.removeEventListener('resize', this.handleWindowResize);
|
|
2124
2140
|
this.viewport.removeEventListener('scroll', this.handleScroll);
|
|
2141
|
+
this.viewport.removeEventListener('ok-collapsible-pager-insets-changed', this.handleCollapsiblePagerInsetsChanged);
|
|
2125
2142
|
this.root.removeEventListener('click', this.handleClick);
|
|
2126
2143
|
this.cancelMarketPointer();
|
|
2127
2144
|
this.root.removeEventListener('pointerdown', this.handleMarketPointerDown);
|
|
@@ -2141,6 +2158,8 @@ export class NativeListWebEngine {
|
|
|
2141
2158
|
this.viewport.removeEventListener('touchcancel', this.handleReorderTouchCancel);
|
|
2142
2159
|
this.indexRail.removeEventListener('pointerdown', this.handleIndexPointer);
|
|
2143
2160
|
this.indexRail.removeEventListener('pointermove', this.handleIndexPointer);
|
|
2161
|
+
this.indexRail.removeEventListener('pointerup', this.handleIndexPointerEnd);
|
|
2162
|
+
this.indexRail.removeEventListener('pointercancel', this.handleIndexPointerEnd);
|
|
2144
2163
|
this.indexRail.removeEventListener('click', this.handleIndexClick);
|
|
2145
2164
|
this.viewport.removeEventListener('pointerdown', this.handlePullStart);
|
|
2146
2165
|
this.viewport.removeEventListener('pointermove', this.handlePullMove);
|
|
@@ -2207,7 +2226,17 @@ export class NativeListWebEngine {
|
|
|
2207
2226
|
recomputeLayout = () => {
|
|
2208
2227
|
if (this.destroyed) return;
|
|
2209
2228
|
const viewportWidth = this.viewport.clientWidth;
|
|
2210
|
-
const viewportHeight = this.viewport.clientHeight;
|
|
2229
|
+
const viewportHeight = this.snapshot.layout.orientation === 'horizontal' ? this.viewport.clientHeight : this.verticalScrollMetrics().viewportLength;
|
|
2230
|
+
if (this.snapshot.layout.orientation !== 'horizontal') {
|
|
2231
|
+
const stickyInset = this.collapsiblePagerInsets().sticky;
|
|
2232
|
+
this.sticky.style.top = String(stickyInset) + 'px';
|
|
2233
|
+
this.indexRail.style.top = String(stickyInset) + 'px';
|
|
2234
|
+
this.refreshIndicator.style.top = String(stickyInset + 8) + 'px';
|
|
2235
|
+
} else {
|
|
2236
|
+
this.sticky.style.top = '0px';
|
|
2237
|
+
this.indexRail.style.top = '0px';
|
|
2238
|
+
this.refreshIndicator.style.top = '8px';
|
|
2239
|
+
}
|
|
2211
2240
|
if (this.lastViewportWidth >= 0 && (viewportWidth !== this.lastViewportWidth || viewportHeight !== this.lastViewportHeight)) {
|
|
2212
2241
|
this.invalidateActionAnchor('layout');
|
|
2213
2242
|
this.measuredWarningHeights.clear();
|
|
@@ -2225,7 +2254,7 @@ export class NativeListWebEngine {
|
|
|
2225
2254
|
this.layout = computeWebListLayout(measuredSnapshot, viewportWidth, viewportHeight, this.reorderCompactKey);
|
|
2226
2255
|
this.content.style.width = String(this.layout.contentWidth) + 'px';
|
|
2227
2256
|
this.content.style.height = String(this.layout.contentHeight) + 'px';
|
|
2228
|
-
this.renderSectionIndex(
|
|
2257
|
+
this.renderSectionIndex(this.viewport.clientHeight <= 0 ? DEFAULT_VIEWPORT_HEIGHT : Math.max(1, viewportHeight));
|
|
2229
2258
|
if (previousHorizontal !== this.layout.horizontal) {
|
|
2230
2259
|
this.viewport.scrollLeft = 0;
|
|
2231
2260
|
this.viewport.scrollTop = 0;
|
|
@@ -2434,19 +2463,30 @@ export class NativeListWebEngine {
|
|
|
2434
2463
|
sectionIndexVisibleEntryIndices(viewportHeight) {
|
|
2435
2464
|
const entryCount = this.sectionIndexEntries.length;
|
|
2436
2465
|
if (entryCount <= 1) return entryCount ? [0] : [];
|
|
2437
|
-
const
|
|
2438
|
-
|
|
2466
|
+
const {
|
|
2467
|
+
trackHeight
|
|
2468
|
+
} = this.sectionIndexMetrics(viewportHeight);
|
|
2469
|
+
const maxVisible = Math.max(1, Math.floor(trackHeight / SECTION_INDEX_LABEL_SPACING));
|
|
2439
2470
|
if (entryCount <= maxVisible) {
|
|
2440
2471
|
return Array.from({
|
|
2441
2472
|
length: entryCount
|
|
2442
2473
|
}, (_, index) => index);
|
|
2443
2474
|
}
|
|
2475
|
+
if (maxVisible === 1) return [0];
|
|
2444
2476
|
const result = new Set();
|
|
2445
2477
|
for (let slot = 0; slot < maxVisible; slot += 1) {
|
|
2446
2478
|
result.add(Math.round(slot * (entryCount - 1) / (maxVisible - 1)));
|
|
2447
2479
|
}
|
|
2448
2480
|
return [...result].sort((left, right) => left - right);
|
|
2449
2481
|
}
|
|
2482
|
+
sectionIndexMetrics(viewportHeight) {
|
|
2483
|
+
const availableHeight = Math.max(0, viewportHeight - SECTION_INDEX_EDGE_PADDING * 2);
|
|
2484
|
+
const trackHeight = Math.min(availableHeight, SECTION_INDEX_LABEL_SPACING * this.sectionIndexEntries.length);
|
|
2485
|
+
return {
|
|
2486
|
+
originY: (viewportHeight - trackHeight) / 2,
|
|
2487
|
+
trackHeight
|
|
2488
|
+
};
|
|
2489
|
+
}
|
|
2450
2490
|
renderSectionIndex(viewportHeight) {
|
|
2451
2491
|
this.indexRail.replaceChildren();
|
|
2452
2492
|
if (!sectionIndexEnabled(this.snapshot)) {
|
|
@@ -2465,8 +2505,11 @@ export class NativeListWebEngine {
|
|
|
2465
2505
|
}
|
|
2466
2506
|
const visibleEntryIndices = this.sectionIndexVisibleEntryIndices(viewportHeight);
|
|
2467
2507
|
setData(this.indexRail, 'compact', visibleEntryIndices.length < this.sectionIndexEntries.length);
|
|
2508
|
+
const metrics = this.sectionIndexMetrics(viewportHeight);
|
|
2509
|
+
const visibleTrackHeight = Math.min(metrics.trackHeight, SECTION_INDEX_LABEL_SPACING * visibleEntryIndices.length);
|
|
2510
|
+
const visibleOriginY = metrics.originY + (metrics.trackHeight - visibleTrackHeight) / 2;
|
|
2468
2511
|
const fragment = this.document.createDocumentFragment();
|
|
2469
|
-
visibleEntryIndices.forEach(entryIndex => {
|
|
2512
|
+
visibleEntryIndices.forEach((entryIndex, visibleIndex) => {
|
|
2470
2513
|
const entry = this.sectionIndexEntries[entryIndex];
|
|
2471
2514
|
if (!entry) return;
|
|
2472
2515
|
const button = createElement(this.document, 'button', 'ok-native-list-index-button', entry.title);
|
|
@@ -2475,8 +2518,7 @@ export class NativeListWebEngine {
|
|
|
2475
2518
|
setData(button, 'sectionEntryIndex', entryIndex);
|
|
2476
2519
|
setData(button, 'sectionPosition', entry.position);
|
|
2477
2520
|
setData(button, 'sectionKey', entry.key);
|
|
2478
|
-
|
|
2479
|
-
button.style.top = String(SECTION_INDEX_EDGE_PADDING + progress * (viewportHeight - SECTION_INDEX_EDGE_PADDING * 2)) + 'px';
|
|
2521
|
+
button.style.top = String(visibleOriginY + visibleTrackHeight * (visibleIndex + 0.5) / visibleEntryIndices.length) + 'px';
|
|
2480
2522
|
fragment.appendChild(button);
|
|
2481
2523
|
});
|
|
2482
2524
|
this.indexRail.appendChild(fragment);
|
|
@@ -2571,7 +2613,7 @@ export class NativeListWebEngine {
|
|
|
2571
2613
|
}
|
|
2572
2614
|
}
|
|
2573
2615
|
const next = this.layout.items[nextIndex];
|
|
2574
|
-
const translate = next ? Math.min(0, next.y - this.
|
|
2616
|
+
const translate = next ? Math.min(0, next.y - this.currentOffset() - item.height) : 0;
|
|
2575
2617
|
this.sticky.style.transform = 'translate3d(0,' + String(translate) + 'px,0)';
|
|
2576
2618
|
this.updateVisibleSelection();
|
|
2577
2619
|
}
|
|
@@ -2606,23 +2648,45 @@ export class NativeListWebEngine {
|
|
|
2606
2648
|
return viewportLength > 0 && this.layout.items.length > 0;
|
|
2607
2649
|
}
|
|
2608
2650
|
viewportLength() {
|
|
2609
|
-
|
|
2651
|
+
if (this.layout.horizontal) {
|
|
2652
|
+
return this.viewport.clientWidth || DEFAULT_VIEWPORT_WIDTH;
|
|
2653
|
+
}
|
|
2654
|
+
if (this.viewport.clientHeight <= 0) return DEFAULT_VIEWPORT_HEIGHT;
|
|
2655
|
+
return Math.max(1, this.verticalScrollMetrics().viewportLength);
|
|
2610
2656
|
}
|
|
2611
2657
|
contentLength() {
|
|
2612
2658
|
return this.layout.horizontal ? this.layout.contentWidth : this.layout.contentHeight;
|
|
2613
2659
|
}
|
|
2614
2660
|
currentOffset() {
|
|
2615
|
-
return this.layout.horizontal ? this.viewport.scrollLeft : this.
|
|
2661
|
+
return this.layout.horizontal ? this.viewport.scrollLeft : this.verticalScrollMetrics().offset;
|
|
2662
|
+
}
|
|
2663
|
+
collapsiblePagerInsets() {
|
|
2664
|
+
const readInset = name => {
|
|
2665
|
+
const parsed = Number.parseFloat(this.viewport.style.getPropertyValue(name));
|
|
2666
|
+
return Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
|
|
2667
|
+
};
|
|
2668
|
+
return {
|
|
2669
|
+
header: readInset('--ok-collapsible-pager-header-inset'),
|
|
2670
|
+
sticky: readInset('--ok-collapsible-pager-sticky-inset')
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
verticalScrollMetrics() {
|
|
2674
|
+
const insets = this.collapsiblePagerInsets();
|
|
2675
|
+
return resolveWebCollapsiblePagerScrollMetrics(this.viewport.scrollTop, this.viewport.clientHeight, insets.header, insets.sticky);
|
|
2616
2676
|
}
|
|
2677
|
+
handleCollapsiblePagerInsetsChanged = () => {
|
|
2678
|
+
this.recomputeLayout();
|
|
2679
|
+
};
|
|
2617
2680
|
scrollToAbsoluteOffset(offset, animated) {
|
|
2618
2681
|
const resolved = Math.min(Math.max(0, offset), Math.max(0, this.contentLength() - this.viewportLength()));
|
|
2682
|
+
const rawOffset = this.layout.horizontal ? resolved : resolveWebCollapsiblePagerRawOffset(resolved, this.collapsiblePagerInsets().header);
|
|
2619
2683
|
this.viewport.scrollTo(this.layout.horizontal ? {
|
|
2620
|
-
left:
|
|
2684
|
+
left: rawOffset,
|
|
2621
2685
|
top: 0,
|
|
2622
2686
|
behavior: animated ? 'smooth' : 'auto'
|
|
2623
2687
|
} : {
|
|
2624
2688
|
left: 0,
|
|
2625
|
-
top:
|
|
2689
|
+
top: rawOffset,
|
|
2626
2690
|
behavior: animated ? 'smooth' : 'auto'
|
|
2627
2691
|
});
|
|
2628
2692
|
this.scheduleFrame();
|
|
@@ -2959,50 +3023,42 @@ export class NativeListWebEngine {
|
|
|
2959
3023
|
const view = this.document.defaultView;
|
|
2960
3024
|
if (view?.cancelAnimationFrame) view.cancelAnimationFrame(handle);else view?.clearTimeout(handle);
|
|
2961
3025
|
}
|
|
2962
|
-
selectIndexPosition(position
|
|
3026
|
+
selectIndexPosition(position) {
|
|
3027
|
+
const activeKey = this.sectionIndexEntries.find(entry => entry.position === position)?.key;
|
|
3028
|
+
this.indexRail.querySelectorAll('[data-section-key]').forEach(button => setData(button, 'active', button.dataset.sectionKey === activeKey));
|
|
2963
3029
|
this.scrollToIndex(position, {
|
|
2964
3030
|
animated: false,
|
|
2965
3031
|
alignment: 'start',
|
|
2966
3032
|
viewPosition: 0,
|
|
2967
3033
|
viewOffset: 0
|
|
2968
3034
|
});
|
|
2969
|
-
const frame = this.viewportFrame.getBoundingClientRect();
|
|
2970
|
-
if (previewClientY !== undefined && frame.height > 0) {
|
|
2971
|
-
const previewY = Math.min(frame.height - 24, Math.max(24, previewClientY - frame.top));
|
|
2972
|
-
this.indexPreview.style.top = String(previewY) + 'px';
|
|
2973
|
-
} else {
|
|
2974
|
-
this.indexPreview.style.top = '50%';
|
|
2975
|
-
}
|
|
2976
|
-
this.indexPreview.textContent = title;
|
|
2977
|
-
setData(this.indexPreview, 'visible', true);
|
|
2978
|
-
if (this.previewTimer !== undefined) this.document.defaultView?.clearTimeout(this.previewTimer);
|
|
2979
|
-
this.previewTimer = this.document.defaultView?.setTimeout(() => {
|
|
2980
|
-
setData(this.indexPreview, 'visible', false);
|
|
2981
|
-
}, 180);
|
|
2982
3035
|
}
|
|
2983
3036
|
sectionIndexEntryAtEvent(event) {
|
|
2984
3037
|
const rail = this.indexRail.getBoundingClientRect();
|
|
2985
3038
|
if (this.sectionIndexEntries.length === 0 || rail.height <= 0) {
|
|
2986
3039
|
return undefined;
|
|
2987
3040
|
}
|
|
2988
|
-
const
|
|
2989
|
-
|
|
2990
|
-
const
|
|
2991
|
-
const
|
|
2992
|
-
return
|
|
2993
|
-
entry,
|
|
2994
|
-
previewClientY: event.clientY
|
|
2995
|
-
} : undefined;
|
|
3041
|
+
const metrics = this.sectionIndexMetrics(rail.height);
|
|
3042
|
+
if (metrics.trackHeight <= 0) return undefined;
|
|
3043
|
+
const progress = Math.min(1, Math.max(0, (event.clientY - rail.top - metrics.originY) / metrics.trackHeight));
|
|
3044
|
+
const entryIndex = Math.min(this.sectionIndexEntries.length - 1, Math.floor(progress * this.sectionIndexEntries.length));
|
|
3045
|
+
return this.sectionIndexEntries[entryIndex];
|
|
2996
3046
|
}
|
|
2997
3047
|
handleIndexPointer = event => {
|
|
2998
3048
|
if (event.type === 'pointermove' && event.buttons === 0) return;
|
|
2999
|
-
const
|
|
3000
|
-
if (!
|
|
3049
|
+
const entry = this.sectionIndexEntryAtEvent(event);
|
|
3050
|
+
if (!entry) return;
|
|
3001
3051
|
event.preventDefault();
|
|
3002
3052
|
if (event.type === 'pointerdown') {
|
|
3003
3053
|
this.indexRail.setPointerCapture?.(event.pointerId);
|
|
3004
3054
|
}
|
|
3005
|
-
this.selectIndexPosition(
|
|
3055
|
+
this.selectIndexPosition(entry.position);
|
|
3056
|
+
};
|
|
3057
|
+
handleIndexPointerEnd = event => {
|
|
3058
|
+
if (event.type === 'pointerup') {
|
|
3059
|
+
const entry = this.sectionIndexEntryAtEvent(event);
|
|
3060
|
+
if (entry) this.selectIndexPosition(entry.position);
|
|
3061
|
+
}
|
|
3006
3062
|
};
|
|
3007
3063
|
handleIndexClick = event => {
|
|
3008
3064
|
if ('detail' in event && typeof event.detail === 'number' && event.detail > 0) return;
|
|
@@ -3012,8 +3068,7 @@ export class NativeListWebEngine {
|
|
|
3012
3068
|
if (!button) return;
|
|
3013
3069
|
const entry = this.sectionIndexEntries[Number(button.dataset.sectionEntryIndex)];
|
|
3014
3070
|
if (!entry) return;
|
|
3015
|
-
|
|
3016
|
-
this.selectIndexPosition(entry.position, entry.title, rect.top + rect.height / 2);
|
|
3071
|
+
this.selectIndexPosition(entry.position);
|
|
3017
3072
|
};
|
|
3018
3073
|
handlePullStart = event => {
|
|
3019
3074
|
if (this.pointerReorder?.pointerId === event.pointerId || !this.snapshot.capabilities?.pullToRefresh || this.viewport.scrollTop > 0 || event.pointerType !== 'touch' && event.pointerType !== 'pen') return;
|
|
@@ -3168,7 +3223,9 @@ export class NativeListWebEngine {
|
|
|
3168
3223
|
setCurrentOffset(offset) {
|
|
3169
3224
|
const maximum = Math.max(0, this.contentLength() - this.viewportLength());
|
|
3170
3225
|
const next = Math.max(0, Math.min(maximum, offset));
|
|
3171
|
-
if (this.layout.horizontal) this.viewport.scrollLeft = next;else
|
|
3226
|
+
if (this.layout.horizontal) this.viewport.scrollLeft = next;else {
|
|
3227
|
+
this.viewport.scrollTop = resolveWebCollapsiblePagerRawOffset(next, this.collapsiblePagerInsets().header);
|
|
3228
|
+
}
|
|
3172
3229
|
this.scheduleFrame();
|
|
3173
3230
|
}
|
|
3174
3231
|
showReorderPreview(state) {
|
|
@@ -3219,8 +3276,9 @@ export class NativeListWebEngine {
|
|
|
3219
3276
|
}
|
|
3220
3277
|
this.reorderSettlingKey = state.sourceKey;
|
|
3221
3278
|
const viewportRect = this.viewport.getBoundingClientRect();
|
|
3279
|
+
const insets = this.collapsiblePagerInsets();
|
|
3222
3280
|
const left = viewportRect.left + destinationLayout.x - this.viewport.scrollLeft;
|
|
3223
|
-
const top = viewportRect.top + destinationLayout.y - this.viewport.scrollTop;
|
|
3281
|
+
const top = viewportRect.top + destinationLayout.y + insets.header + insets.sticky - this.viewport.scrollTop;
|
|
3224
3282
|
this.reorderPreview.getBoundingClientRect();
|
|
3225
3283
|
this.reorderPreview.style.transition = 'transform ' + String(REORDER_DROP_TRANSITION_MS) + 'ms ' + WEB_REORDER_ANIMATION.dropTimingFunction + ', box-shadow ' + String(REORDER_DROP_TRANSITION_MS) + 'ms ' + WEB_REORDER_ANIMATION.dropTimingFunction;
|
|
3226
3284
|
this.reorderPreview.style.boxShadow = 'none';
|
|
@@ -66,6 +66,12 @@ export declare function estimateWebRowHeight(row: RowModel, snapshot: NativeList
|
|
|
66
66
|
export declare function computeWebListLayout(snapshot: NativeListSnapshot, viewportWidth: number, viewportHeight: number, compactRowKey?: string): WebListLayout;
|
|
67
67
|
export declare function webWalletGroupReorderBadge(row: RowModel): string | undefined;
|
|
68
68
|
export declare function visibleWebLayoutItems(layout: WebListLayout, offset: number, viewportLength: number, overscan?: number): readonly WebLayoutItem[];
|
|
69
|
+
export type WebCollapsiblePagerScrollMetrics = Readonly<{
|
|
70
|
+
offset: number;
|
|
71
|
+
viewportLength: number;
|
|
72
|
+
}>;
|
|
73
|
+
export declare function resolveWebCollapsiblePagerScrollMetrics(rawOffset: number, rawViewportLength: number, headerInset: number, stickyInset: number): WebCollapsiblePagerScrollMetrics;
|
|
74
|
+
export declare function resolveWebCollapsiblePagerRawOffset(logicalOffset: number, headerInset: number): number;
|
|
69
75
|
export declare function webLayoutItemsForMount(layout: WebListLayout, offset: number, viewportLength: number, virtualizationEnabled: boolean, overscan?: number): readonly WebLayoutItem[];
|
|
70
76
|
export declare function webRowRenderSignature(row: RowModel): string;
|
|
71
77
|
export declare function isWebMarketQuotePatch(patch: RowPatch): boolean;
|
|
@@ -81,7 +87,6 @@ export declare class NativeListWebEngine {
|
|
|
81
87
|
private readonly footer;
|
|
82
88
|
private readonly sticky;
|
|
83
89
|
private readonly indexRail;
|
|
84
|
-
private readonly indexPreview;
|
|
85
90
|
private readonly refreshIndicator;
|
|
86
91
|
private readonly reorderPreview;
|
|
87
92
|
private readonly previousHostPosition;
|
|
@@ -101,7 +106,6 @@ export declare class NativeListWebEngine {
|
|
|
101
106
|
private avatarDirection;
|
|
102
107
|
private reachedGeneration;
|
|
103
108
|
private stickyKey;
|
|
104
|
-
private previewTimer;
|
|
105
109
|
private sectionIndexEntries;
|
|
106
110
|
private pointerReorder;
|
|
107
111
|
private keyboardReorder;
|
|
@@ -149,6 +153,7 @@ export declare class NativeListWebEngine {
|
|
|
149
153
|
private renderElement;
|
|
150
154
|
private renderFooter;
|
|
151
155
|
private sectionIndexVisibleEntryIndices;
|
|
156
|
+
private sectionIndexMetrics;
|
|
152
157
|
private renderSectionIndex;
|
|
153
158
|
private updateVisibleSelection;
|
|
154
159
|
private updateVisibleState;
|
|
@@ -160,6 +165,9 @@ export declare class NativeListWebEngine {
|
|
|
160
165
|
private viewportLength;
|
|
161
166
|
private contentLength;
|
|
162
167
|
private currentOffset;
|
|
168
|
+
private collapsiblePagerInsets;
|
|
169
|
+
private verticalScrollMetrics;
|
|
170
|
+
private handleCollapsiblePagerInsetsChanged;
|
|
163
171
|
private scrollToAbsoluteOffset;
|
|
164
172
|
private performPendingScroll;
|
|
165
173
|
private rowAtElement;
|
|
@@ -193,6 +201,7 @@ export declare class NativeListWebEngine {
|
|
|
193
201
|
private selectIndexPosition;
|
|
194
202
|
private sectionIndexEntryAtEvent;
|
|
195
203
|
private handleIndexPointer;
|
|
204
|
+
private handleIndexPointerEnd;
|
|
196
205
|
private handleIndexClick;
|
|
197
206
|
private handlePullStart;
|
|
198
207
|
private handlePullMove;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/react-native-native-list",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.115",
|
|
4
4
|
"description": "Template-driven native RecyclerView and UICollectionView for React Native",
|
|
5
5
|
"source": "./src/index.ts",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"eslint-config-prettier": "^10.1.8",
|
|
74
74
|
"eslint-plugin-prettier": "^5.5.4",
|
|
75
75
|
"jest": "^29.7.0",
|
|
76
|
+
"jsdom": "26.1.0",
|
|
76
77
|
"nitrogen": "0.37.0",
|
|
77
78
|
"prettier": "^2.8.8",
|
|
78
79
|
"react": "19.2.3",
|
|
@@ -82,7 +83,8 @@
|
|
|
82
83
|
"typescript": "^5.9.2"
|
|
83
84
|
},
|
|
84
85
|
"peerDependencies": {
|
|
85
|
-
"@onekeyfe/react-native-image": "3.0.
|
|
86
|
+
"@onekeyfe/react-native-image": "3.0.115",
|
|
87
|
+
"@onekeyfe/react-native-native-logger": "3.0.115",
|
|
86
88
|
"react": "*",
|
|
87
89
|
"react-native": "*",
|
|
88
90
|
"react-native-nitro-modules": "0.37.0"
|