Improve Bridge Flow types (#352)
* Updated local fork of react-window * Updated Fow 97 -> 103 * Lint ignore NPM dist * Improved Bridge Flow types
Brian Vaughn committed
Jul 20, 2019 at 14:08 UTC
4b34a77d290cf67ab0be51bf8edef0fe9787732b
46 files changed
+1066
-379
.eslintignore
+1
@@ -4,6 +4,7 @@ shells/browser/chrome/build
4
shells/browser/firefox/build
5
shells/browser/shared/build
6
shells/dev/dist
7
+packages/react-devtools-core/dist
8
vendor
9
*.js.snap
10
package.json
+2
-2
@@ -63,7 +63,7 @@
63
"test:chrome": "node ./shells/browser/chrome/test",
64
"test:firefox": "node ./shells/browser/firefox/test",
65
"test:standalone": "cd packages/react-devtools && yarn start",
66
- "typecheck": "flow check"
66
+ "typecheck": "flow check --show-all-errors"
67
},
68
"devEngines": {
69
"node": "10.x || 11.x"
@@ -119,7 +119,7 @@
119
"fbjs": "0.5.1",
120
"fbjs-scripts": "0.7.0",
121
"firefox-profile": "^1.0.2",
122
- "flow-bin": "^0.97.0",
122
+ "flow-bin": "^0.103.0",
123
"fs-extra": "^3.0.1",
124
"gh-pages": "^1.0.0",
125
"html2canvas": "^1.0.0-alpha.12",
packages/react-devtools-core/src/backend.js
+2
-1
@@ -8,6 +8,7 @@ import { __DEBUG__ } from 'src/constants';
8
import setupNativeStyleEditor from 'src/backend/NativeStyleEditor/setupNativeStyleEditor';
9
import { getDefaultComponentFilters } from 'src/utils';
10
11
+import type { BackendBridge } from 'src/bridge';
12
import type { ComponentFilter } from 'src/types';
13
import type { DevToolsHook } from 'src/backend/types';
14
import type { ResolveNativeStyle } from 'src/backend/NativeStyleEditor/setupNativeStyleEditor';
@@ -64,7 +65,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
65
return;
66
}
67
67
- let bridge: Bridge | null = null;
68
+ let bridge: BackendBridge | null = null;
69
70
const messageListeners = [];
71
const uri = 'ws://' + host + ':' + port;
packages/react-devtools-core/src/standalone.js
+4
-3
@@ -17,6 +17,7 @@ import DevTools from 'src/devtools/views/DevTools';
17
import launchEditor from './launchEditor';
18
import { __DEBUG__ } from 'src/constants';
19
20
+import type { FrontendBridge } from 'src/bridge';
21
import type { InspectedElement } from 'src/devtools/views/Components/types';
22
23
installHook(window);
@@ -46,7 +47,7 @@ function setStatusListener(value: StatusListener) {
47
return DevtoolsUI;
48
}
49
49
-let bridge: Bridge | null = null;
50
+let bridge: FrontendBridge | null = null;
51
let store: Store | null = null;
52
let root = null;
53
@@ -83,7 +84,7 @@ function reload() {
84
root = createRoot(node);
85
root.render(
86
createElement(DevTools, {
86
- bridge: ((bridge: any): Bridge),
87
+ bridge: ((bridge: any): FrontendBridge),
88
showTabBar: true,
89
store: ((store: any): Store),
90
warnIfLegacyBackendDetected: true,
@@ -166,7 +167,7 @@ function initialize(socket: WebSocket) {
167
}
168
},
169
});
169
- ((bridge: any): Bridge).addListener('shutdown', () => {
170
+ ((bridge: any): FrontendBridge).addListener('shutdown', () => {
171
socket.close();
172
});
173
shells/dev/app/SuspenseTree/index.js
+20
-20
@@ -1,17 +1,17 @@
1
// @flow
2
3
-import React, { Suspense, useState } from 'react';
3
+import React, { Fragment, Suspense, useState } from 'react';
4
5
function SuspenseTree() {
6
return (
7
- <>
7
+ <Fragment>
8
<h1>Suspense</h1>
9
<h4>Primary to Fallback Cycle</h4>
10
<PrimaryFallbackTest initialSuspend={false} />
11
<h4>Fallback to Primary Cycle</h4>
12
<PrimaryFallbackTest initialSuspend={true} />
13
<NestedSuspenseTest />
14
- </>
14
+ </Fragment>
15
);
16
}
17
@@ -20,7 +20,7 @@ function PrimaryFallbackTest({ initialSuspend }) {
20
const fallbackStep = useTestSequence('fallback', Fallback1, Fallback2);
21
const primaryStep = useTestSequence('primary', Primary1, Primary2);
22
return (
23
- <>
23
+ <Fragment>
24
<label>
25
<input
26
checked={suspend}
@@ -33,7 +33,7 @@ function PrimaryFallbackTest({ initialSuspend }) {
33
<Suspense fallback={fallbackStep}>
34
{suspend ? <Never /> : primaryStep}
35
</Suspense>
36
- </>
36
+ </Fragment>
37
);
38
}
39
@@ -45,32 +45,32 @@ function useTestSequence(label, T1, T2) {
45
</button>
46
);
47
let allSteps = [
48
- <>{next}</>,
49
- <>
48
+ <Fragment>{next}</Fragment>,
49
+ <Fragment>
50
{next} <T1 prop={step}>mount</T1>
51
- </>,
52
- <>
51
+ </Fragment>,
52
+ <Fragment>
53
{next} <T1 prop={step}>update</T1>
54
- </>,
55
- <>
54
+ </Fragment>,
55
+ <Fragment>
56
{next} <T2 prop={step}>several</T2> <T1 prop={step}>different</T1>{' '}
57
<T2 prop={step}>children</T2>
58
- </>,
59
- <>
58
+ </Fragment>,
59
+ <Fragment>
60
{next} <T2 prop={step}>goodbye</T2>
61
- </>,
61
+ </Fragment>,
62
];
63
return allSteps[step];
64
}
65
66
function NestedSuspenseTest() {
67
return (
68
- <>
68
+ <Fragment>
69
<h3>Nested Suspense</h3>
70
<Suspense fallback={<Fallback1>Loading outer</Fallback1>}>
71
<Parent />
72
</Suspense>
73
- </>
73
+ </Fragment>
74
);
75
}
76
@@ -118,19 +118,19 @@ function Never() {
118
throw new Promise(resolve => {});
119
}
120
121
-function Fallback1({ prop, ...rest }) {
121
+function Fallback1({ prop, ...rest }: any) {
122
return <span {...rest} />;
123
}
124
125
-function Fallback2({ prop, ...rest }) {
125
+function Fallback2({ prop, ...rest }: any) {
126
return <span {...rest} />;
127
}
128
129
-function Primary1({ prop, ...rest }) {
129
+function Primary1({ prop, ...rest }: any) {
130
return <span {...rest} />;
131
}
132
133
-function Primary2({ prop, ...rest }) {
133
+function Primary2({ prop, ...rest }: any) {
134
return <span {...rest} />;
135
}
136
src/__tests__/bridge-test.js
+5
-5
@@ -15,9 +15,9 @@ describe('Bridge', () => {
15
const bridge = new Bridge(wall);
16
17
// Check that we're wired up correctly.
18
- bridge.send('init');
18
+ bridge.send('reloadAppForProfiling');
19
jest.runAllTimers();
20
- expect(wall.send).toHaveBeenCalledWith('init', undefined, undefined);
20
+ expect(wall.send).toHaveBeenCalledWith('reloadAppForProfiling');
21
22
// Should flush pending messages and then shut down.
23
wall.send.mockClear();
@@ -25,9 +25,9 @@ describe('Bridge', () => {
25
bridge.send('update', '2');
26
bridge.shutdown();
27
jest.runAllTimers();
28
- expect(wall.send).toHaveBeenCalledWith('update', '1', undefined);
29
- expect(wall.send).toHaveBeenCalledWith('update', '2', undefined);
30
- expect(wall.send).toHaveBeenCalledWith('shutdown', undefined, undefined);
28
+ expect(wall.send).toHaveBeenCalledWith('update', '1');
29
+ expect(wall.send).toHaveBeenCalledWith('update', '2');
30
+ expect(wall.send).toHaveBeenCalledWith('shutdown');
31
32
// Verify that the Bridge doesn't send messages after shutdown.
33
spyOn(console, 'warn');
src/__tests__/inspectedElementContext-test.js
+2
-2
@@ -2,14 +2,14 @@
2
3
import typeof ReactTestRenderer from 'react-test-renderer';
4
import type { GetInspectedElementPath } from 'src/devtools/views/Components/InspectedElementContext';
5
-import type Bridge from 'src/bridge';
5
+import type { FrontendBridge } from 'src/bridge';
6
import type Store from 'src/devtools/store';
7
8
describe('InspectedElementContext', () => {
9
let React;
10
let ReactDOM;
11
let TestRenderer: ReactTestRenderer;
12
- let bridge: Bridge;
12
+ let bridge: FrontendBridge;
13
let store: Store;
14
let meta;
15
let utils;
src/__tests__/legacy/inspectElement-test.js
+2
-2
@@ -2,7 +2,7 @@
2
3
import type { InspectedElementPayload } from 'src/backend/types';
4
import type { DehydratedData } from 'src/devtools/views/Components/types';
5
-import type Bridge from 'src/bridge';
5
+import type { FrontendBridge } from 'src/bridge';
6
import type Store from 'src/devtools/store';
7
8
describe('InspectedElementContext', () => {
@@ -10,7 +10,7 @@ describe('InspectedElementContext', () => {
10
let ReactDOM;
11
let hydrate;
12
let meta;
13
- let bridge: Bridge;
13
+ let bridge: FrontendBridge;
14
let store: Store;
15
16
const act = (callback: Function) => {
src/__tests__/ownersListContext-test.js
+2
-2
@@ -2,14 +2,14 @@
2
3
import typeof ReactTestRenderer from 'react-test-renderer';
4
import type { Element } from 'src/devtools/views/Components/types';
5
-import type Bridge from 'src/bridge';
5
+import type { FrontendBridge } from 'src/bridge';
6
import type Store from 'src/devtools/store';
7
8
describe('OwnersListContext', () => {
9
let React;
10
let ReactDOM;
11
let TestRenderer: ReactTestRenderer;
12
- let bridge: Bridge;
12
+ let bridge: FrontendBridge;
13
let store: Store;
14
let utils;
15
src/__tests__/profilerContext-test.js
+2
-2
@@ -1,7 +1,7 @@
1
// @flow
2
3
import typeof ReactTestRenderer from 'react-test-renderer';
4
-import type Bridge from 'src/bridge';
4
+import type { FrontendBridge } from 'src/bridge';
5
import type { Context } from 'src/devtools/views/Profiler/ProfilerContext';
6
import type { DispatcherContext } from 'src/devtools/views/Components/TreeContext';
7
import type Store from 'src/devtools/store';
@@ -10,7 +10,7 @@ describe('ProfilerContext', () => {
10
let React;
11
let ReactDOM;
12
let TestRenderer: ReactTestRenderer;
13
- let bridge: Bridge;
13
+ let bridge: FrontendBridge;
14
let store: Store;
15
let utils;
16
src/__tests__/profilingCache-test.js
+2
-2
@@ -1,7 +1,7 @@
1
// @flow
2
3
import typeof ReactTestRenderer from 'react-test-renderer';
4
-import type Bridge from 'src/bridge';
4
+import type { FrontendBridge } from 'src/bridge';
5
import type Store from 'src/devtools/store';
6
7
describe('ProfilingCache', () => {
@@ -11,7 +11,7 @@ describe('ProfilingCache', () => {
11
let Scheduler;
12
let SchedulerTracing;
13
let TestRenderer: ReactTestRenderer;
14
- let bridge: Bridge;
14
+ let bridge: FrontendBridge;
15
let store: Store;
16
let utils;
17
src/__tests__/profilingCharts-test.js
+3
-3
@@ -29,7 +29,7 @@ describe('profiling charts', () => {
29
30
describe('flamegraph chart', () => {
31
it('should contain valid data', () => {
32
- const Parent = ({ count }) => {
32
+ const Parent = (_: {||}) => {
33
Scheduler.unstable_advanceTime(10);
34
return (
35
<React.Fragment>
@@ -105,7 +105,7 @@ describe('profiling charts', () => {
105
106
describe('ranked chart', () => {
107
it('should contain valid data', () => {
108
- const Parent = ({ count }) => {
108
+ const Parent = (_: {||}) => {
109
Scheduler.unstable_advanceTime(10);
110
return (
111
<React.Fragment>
@@ -177,7 +177,7 @@ describe('profiling charts', () => {
177
178
describe('interactions', () => {
179
it('should contain valid data', () => {
180
- const Parent = ({ count }) => {
180
+ const Parent = (_: {||}) => {
181
Scheduler.unstable_advanceTime(10);
182
return (
183
<React.Fragment>
src/__tests__/setupTests.js
+4
-2
@@ -1,5 +1,7 @@
1
// @flow
2
3
+import type { BackendBridge, FrontendBridge } from 'src/bridge';
4
+
5
const env = jasmine.getEnv();
6
env.beforeEach(() => {
7
// These files should be required (and re-reuired) before each test,
@@ -51,13 +53,13 @@ env.beforeEach(() => {
53
},
54
});
55
54
- const agent = new Agent(bridge);
56
+ const agent = new Agent(((bridge: any): BackendBridge));
57
58
const hook = global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
59
60
initBackend(hook, agent, global);
61
60
- const store = new Store(bridge);
62
+ const store = new Store(((bridge: any): FrontendBridge));
63
64
global.agent = agent;
65
global.bridge = bridge;
src/__tests__/storeComponentFilters-test.js
+2
-2
@@ -1,6 +1,6 @@
1
// @flow
2
3
-import type Bridge from 'src/bridge';
3
+import type { FrontendBridge } from 'src/bridge';
4
import type Store from 'src/devtools/store';
5
6
describe('Store component filters', () => {
@@ -8,7 +8,7 @@ describe('Store component filters', () => {
8
let ReactDOM;
9
let TestUtils;
10
let Types;
11
- let bridge: Bridge;
11
+ let bridge: FrontendBridge;
12
let store: Store;
13
let utils;
14
src/__tests__/treeContext-test.js
+2
-2
@@ -1,7 +1,7 @@
1
// @flow
2
3
import typeof ReactTestRenderer from 'react-test-renderer';
4
-import type Bridge from 'src/bridge';
4
+import type { FrontendBridge } from 'src/bridge';
5
import type Store from 'src/devtools/store';
6
import type {
7
DispatcherContext,
@@ -12,7 +12,7 @@ describe('TreeListContext', () => {
12
let React;
13
let ReactDOM;
14
let TestRenderer: ReactTestRenderer;
15
- let bridge: Bridge;
15
+ let bridge: FrontendBridge;
16
let store: Store;
17
let utils;
18
src/__tests__/utils.js
+2
-2
@@ -2,7 +2,7 @@
2
3
import typeof ReactTestRenderer from 'react-test-renderer';
4
5
-import type Bridge from 'src/bridge';
5
+import type { FrontendBridge } from 'src/bridge';
6
import type Store from 'src/devtools/store';
7
import type { ProfilingDataFrontend } from 'src/devtools/views/Profiler/types';
8
import type { ElementType } from 'src/types';
@@ -161,7 +161,7 @@ export function requireTestRenderer(): ReactTestRenderer {
161
}
162
}
163
164
-export function exportImportHelper(bridge: Bridge, store: Store): void {
164
+export function exportImportHelper(bridge: FrontendBridge, store: Store): void {
165
const { act } = require('./utils');
166
const {
167
prepareProfilingDataExport,
src/backend/NativeStyleEditor/setupNativeStyleEditor.js
+3
-3
@@ -1,16 +1,16 @@
1
// @flow
2
3
import Agent from 'src/backend/agent';
4
-import Bridge from 'src/bridge';
4
import resolveBoxStyle from './resolveBoxStyle';
5
6
+import type { BackendBridge } from 'src/bridge';
7
import type { RendererID } from '../types';
8
import type { StyleAndLayout } from './types';
9
10
export type ResolveNativeStyle = (stylesheetID: number) => ?Object;
11
12
export default function setupNativeStyleEditor(
13
- bridge: Bridge,
13
+ bridge: BackendBridge,
14
agent: Agent,
15
resolveNativeStyle: ResolveNativeStyle,
16
validAttributes?: $ReadOnlyArray<string> | null
@@ -81,7 +81,7 @@ const componentIDToStyleOverrides: Map<number, Object> = new Map();
81
82
function measureStyle(
83
agent: Agent,
84
- bridge: Bridge,
84
+ bridge: BackendBridge,
85
resolveNativeStyle: ResolveNativeStyle,
86
id: number,
87
rendererID: RendererID
src/backend/agent.js
+4
-4
@@ -2,7 +2,6 @@
2
3
import EventEmitter from 'events';
4
import throttle from 'lodash.throttle';
5
-import Bridge from 'src/bridge';
5
import {
6
SESSION_STORAGE_LAST_SELECTION_KEY,
7
SESSION_STORAGE_RELOAD_AND_PROFILE_KEY,
@@ -17,6 +16,7 @@ import {
16
import setupHighlighter from './views/Highlighter';
17
import { patch as patchConsole, unpatch as unpatchConsole } from './console';
18
19
+import type { BackendBridge } from 'src/bridge';
20
import type {
21
InstanceAndStyle,
22
NativeType,
@@ -81,14 +81,14 @@ export default class Agent extends EventEmitter<{|
81
showNativeHighlight: [NativeType],
82
shutdown: [],
83
|}> {
84
- _bridge: Bridge;
84
+ _bridge: BackendBridge;
85
_isProfiling: boolean = false;
86
_recordChangeDescriptions: boolean = false;
87
_rendererInterfaces: { [key: RendererID]: RendererInterface } = {};
88
_persistedSelection: PersistedSelection | null = null;
89
_persistedSelectionMatch: PathMatch | null = null;
90
91
- constructor(bridge: Bridge) {
91
+ constructor(bridge: BackendBridge) {
92
super();
93
94
if (
@@ -259,7 +259,7 @@ export default class Agent extends EventEmitter<{|
259
dataURL: string,
260
rootID: number,
261
|}) => {
262
- this._bridge.send('screenshotCaptured', { commitIndex, dataURL });
262
+ this._bridge.send('screenshotCaptured', { commitIndex, dataURL, rootID });
263
};
264
265
selectElement = ({ id, rendererID }: ElementAndRendererID) => {
src/backend/views/Highlighter/Overlay.js
+8
-5
@@ -11,6 +11,8 @@ type Rect = {
11
width: number,
12
};
13
14
+type Box = {| top: number, left: number, width: number, height: number |};
15
+
16
// Note that the Overlay components are not affected by the active Theme,
17
// because they highlight elements in the main Chrome window (outside of devtools).
18
// The colors below were chosen to roughly match those used by Chrome devtools.
@@ -21,7 +23,7 @@ class OverlayRect {
23
padding: HTMLElement;
24
content: HTMLElement;
25
24
- constructor(doc, container) {
26
+ constructor(doc: Document, container: HTMLElement) {
27
this.node = doc.createElement('div');
28
this.border = doc.createElement('div');
29
this.padding = doc.createElement('div');
@@ -51,7 +53,7 @@ class OverlayRect {
53
}
54
}
55
54
- update(box, dims) {
56
+ update(box: Rect, dims: any) {
57
boxWrap(dims, 'margin', this.node);
58
boxWrap(dims, 'border', this.border);
59
boxWrap(dims, 'padding', this.padding);
@@ -85,7 +87,7 @@ class OverlayTip {
87
nameSpan: HTMLElement;
88
dimSpan: HTMLElement;
89
88
- constructor(doc, container) {
90
+ constructor(doc: Document, container: HTMLElement) {
91
this.tip = doc.createElement('div');
92
assign(this.tip.style, {
93
display: 'flex',
@@ -126,13 +128,13 @@ class OverlayTip {
128
}
129
}
130
129
- updateText(name, width, height) {
131
+ updateText(name: string, width: number, height: number) {
132
this.nameSpan.textContent = name;
133
this.dimSpan.textContent =
134
Math.round(width) + 'px × ' + Math.round(height) + 'px';
135
}
136
135
- updatePosition(dims, bounds) {
137
+ updatePosition(dims: Box, bounds: Box) {
138
const tipRect = this.tip.getBoundingClientRect();
139
const tipPos = findTipPos(dims, bounds, {
140
width: tipRect.width,
@@ -247,6 +249,7 @@ export default class Overlay {
249
this.tipBoundsWindow.document.documentElement,
250
this.window
251
);
252
+
253
this.tip.updatePosition(
254
{
255
top: outerBox.top,
src/backend/views/Highlighter/index.js
+7
-3
@@ -2,11 +2,15 @@
2
3
import memoize from 'memoize-one';
4
import throttle from 'lodash.throttle';
5
-import Bridge from 'src/bridge';
5
import Agent from 'src/backend/agent';
6
import { hideOverlay, showOverlay } from './Highlighter';
7
9
-export default function setup(bridge: Bridge, agent: Agent): void {
8
+import type { BackendBridge } from 'src/bridge';
9
+
10
+export default function setupHighlighter(
11
+ bridge: BackendBridge,
12
+ agent: Agent
13
+): void {
14
bridge.addListener(
15
'clearNativeElementHighlight',
16
clearNativeElementHighlight
@@ -50,7 +54,7 @@ export default function setup(bridge: Bridge, agent: Agent): void {
54
rendererID,
55
scrollIntoView,
56
}: {
53
- displayName: string,
57
+ displayName: string | null,
58
hideAfterTimeout: boolean,
59
id: number,
60
openNativeElementsPanel: boolean,
src/bridge.js
+48
-27
@@ -22,7 +22,7 @@ type Message = {|
22
23
type HighlightElementInDOM = {|
24
...ElementAndRendererID,
25
- displayName: string,
25
+ displayName: string | null,
26
hideAfterTimeout: boolean,
27
openNativeElementsPanel: boolean,
28
scrollIntoView: boolean,
@@ -62,33 +62,48 @@ type NativeStyleEditor_SetValueParams = {|
62
value: string,
63
|};
64
65
-export default class Bridge extends EventEmitter<{|
65
+type BackendEvents = {|
66
+ captureScreenshot: [{| commitIndex: number, rootID: number |}],
67
+ inspectedElement: [InspectedElementPayload],
68
+ isBackendStorageAPISupported: [boolean],
69
+ operations: [Array<number>],
70
+ ownersList: [OwnersList],
71
+ overrideComponentFilters: [Array<ComponentFilter>],
72
+ profilingData: [ProfilingDataBackend],
73
+ profilingStatus: [boolean],
74
+ reloadAppForProfiling: [],
75
+ screenshotCaptured: [
76
+ {| commitIndex: number, dataURL: string, rootID: number |},
77
+ ],
78
+ selectFiber: [number],
79
+ shutdown: [],
80
+ stopInspectingNative: [boolean],
81
+ syncSelectionFromNativeElementsPanel: [],
82
+ syncSelectionToNativeElementsPanel: [],
83
+
84
+ // React Native style editor plug-in.
85
+ isNativeStyleEditorSupported: [
86
+ {| isSupported: boolean, validAttributes: ?$ReadOnlyArray<string> |},
87
+ ],
88
+ NativeStyleEditor_styleAndLayout: [StyleAndLayoutPayload],
89
+|};
90
+
91
+type FrontendEvents = {|
92
captureScreenshot: [{| commitIndex: number, rootID: number |}],
93
clearNativeElementHighlight: [],
94
getOwnersList: [ElementAndRendererID],
95
getProfilingData: [{| rendererID: RendererID |}],
96
getProfilingStatus: [],
97
highlightNativeElement: [HighlightElementInDOM],
72
- init: [],
98
inspectElement: [InspectElementParams],
74
- inspectedElement: [InspectedElementPayload],
75
- isBackendStorageAPISupported: [boolean],
99
logElementToConsole: [ElementAndRendererID],
77
- operations: [Array<number>],
78
- ownersList: [OwnersList],
79
- overrideComponentFilters: [Array<ComponentFilter>],
100
overrideContext: [OverrideValue],
101
overrideHookState: [OverrideHookState],
102
overrideProps: [OverrideValue],
103
overrideState: [OverrideValue],
104
overrideSuspense: [OverrideSuspense],
105
profilingData: [ProfilingDataBackend],
86
- profilingStatus: [boolean],
106
reloadAndProfile: [boolean],
88
- reloadAppForProfiling: [],
89
- screenshotCaptured: [
90
- {| commitIndex: number, dataURL: string, rootID: number |},
91
- ],
107
selectElement: [ElementAndRendererID],
108
selectFiber: [number],
109
shutdown: [],
@@ -96,20 +111,22 @@ export default class Bridge extends EventEmitter<{|
111
startProfiling: [boolean],
112
stopInspectingNative: [boolean],
113
stopProfiling: [],
99
- syncSelectionFromNativeElementsPanel: [],
100
- syncSelectionToNativeElementsPanel: [],
114
updateAppendComponentStack: [boolean],
115
updateComponentFilters: [Array<ComponentFilter>],
116
viewElementSource: [ElementAndRendererID],
117
118
// React Native style editor plug-in.
106
- isNativeStyleEditorSupported: [
107
- {| isSupported: boolean, validAttributes: $ReadOnlyArray<string> |},
108
- ],
119
NativeStyleEditor_measure: [ElementAndRendererID],
120
NativeStyleEditor_renameAttribute: [NativeStyleEditor_RenameAttributeParams],
121
NativeStyleEditor_setValue: [NativeStyleEditor_SetValueParams],
112
- NativeStyleEditor_styleAndLayout: [StyleAndLayoutPayload],
122
+|};
123
+
124
+class Bridge<
125
+ OutgoingEvents: Object,
126
+ IncomingEvents: Object
127
+> extends EventEmitter<{|
128
+ ...IncomingEvents,
129
+ ...OutgoingEvents,
130
|}> {
131
_isShutdown: boolean = false;
132
_messageQueue: Array<any> = [];
@@ -134,7 +151,10 @@ export default class Bridge extends EventEmitter<{|
151
return this._wall;
152
}
153
137
- send(event: string, payload: any, transferable?: Array<any>) {
154
+ send<EventName: $Keys<OutgoingEvents>>(
155
+ event: EventName,
156
+ ...payload: $ElementType<OutgoingEvents, EventName>
157
+ ) {
158
if (this._isShutdown) {
159
console.warn(
160
`Cannot send message "${event}" through a Bridge that has been shutdown.`
@@ -150,7 +170,7 @@ export default class Bridge extends EventEmitter<{|
170
// - if there *has* been a message flushed in the last BATCH_DURATION ms
171
// (or we're waiting for our setTimeout-0 to fire), then _timeoutID will
172
// be set, and we'll simply add to the queue and wait for that
153
- this._messageQueue.push(event, payload, transferable);
173
+ this._messageQueue.push(event, payload);
174
if (!this._timeoutID) {
175
this._timeoutID = setTimeout(this._flush, 0);
176
}
@@ -204,12 +224,8 @@ export default class Bridge extends EventEmitter<{|
224
this._timeoutID = null;
225
226
if (this._messageQueue.length) {
207
- for (let i = 0; i < this._messageQueue.length; i += 3) {
208
- this._wall.send(
209
- this._messageQueue[i],
210
- this._messageQueue[i + 1],
211
- this._messageQueue[i + 2]
212
- );
227
+ for (let i = 0; i < this._messageQueue.length; i += 2) {
228
+ this._wall.send(this._messageQueue[i], ...this._messageQueue[i + 1]);
229
}
230
this._messageQueue.length = 0;
231
@@ -220,3 +236,8 @@ export default class Bridge extends EventEmitter<{|
236
}
237
};
238
}
239
+
240
+export type BackendBridge = Bridge<BackendEvents, FrontendEvents>;
241
+export type FrontendBridge = Bridge<FrontendEvents, BackendEvents>;
242
+
243
+export default Bridge;
src/devtools/ProfilerStore.js
+7
-3
@@ -3,11 +3,11 @@
3
import EventEmitter from 'events';
4
import memoize from 'memoize-one';
5
import throttle from 'lodash.throttle';
6
-import Bridge from 'src/bridge';
6
import { prepareProfilingDataFrontendFromBackendAndStore } from './views/Profiler/utils';
7
import ProfilingCache from './ProfilingCache';
8
import Store from './store';
9
10
+import type { FrontendBridge } from 'src/bridge';
11
import type { ProfilingDataBackend } from 'src/backend/types';
12
import type {
13
CommitDataFrontend,
@@ -23,7 +23,7 @@ export default class ProfilerStore extends EventEmitter<{|
23
isProfiling: [],
24
profilingData: [],
25
|}> {
26
- _bridge: Bridge;
26
+ _bridge: FrontendBridge;
27
28
// Suspense cache for lazily calculating derived profiling data.
29
_cache: ProfilingCache;
@@ -79,7 +79,11 @@ export default class ProfilerStore extends EventEmitter<{|
79
80
_store: Store;
81
82
- constructor(bridge: Bridge, store: Store, defaultIsProfiling: boolean) {
82
+ constructor(
83
+ bridge: FrontendBridge,
84
+ store: Store,
85
+ defaultIsProfiling: boolean
86
+ ) {
87
super();
88
89
this._bridge = bridge;
src/devtools/index.js
+2
-2
@@ -1,6 +1,6 @@
1
// @flow
2
3
-import Bridge from 'src/bridge';
3
+import type { FrontendBridge } from 'src/bridge';
4
5
type Shell = {|
6
connect: (callback: Function) => void,
@@ -8,7 +8,7 @@ type Shell = {|
8
|};
9
10
export function initDevTools(shell: Shell) {
11
- shell.connect((bridge: Bridge) => {
11
+ shell.connect((bridge: FrontendBridge) => {
12
// TODO ...
13
});
14
}
src/devtools/store.js
+4
-4
@@ -2,7 +2,6 @@
2
3
import EventEmitter from 'events';
4
import { inspect } from 'util';
5
-import Bridge from 'src/bridge';
5
import {
6
TREE_OPERATION_ADD,
7
TREE_OPERATION_REMOVE,
@@ -24,6 +23,7 @@ import ProfilerStore from './ProfilerStore';
23
24
import type { Element } from './views/Components/types';
25
import type { ComponentFilter, ElementType } from '../types';
26
+import type { FrontendBridge } from 'src/bridge';
27
28
const debug = (methodName, ...args) => {
29
if (__DEBUG__) {
@@ -71,7 +71,7 @@ export default class Store extends EventEmitter<{|
71
supportsProfiling: [],
72
supportsReloadAndProfile: [],
73
|}> {
74
- _bridge: Bridge;
74
+ _bridge: FrontendBridge;
75
76
_captureScreenshots: boolean = false;
77
@@ -129,7 +129,7 @@ export default class Store extends EventEmitter<{|
129
// Used for windowing purposes.
130
_weightAcrossRoots: number = 0;
131
132
- constructor(bridge: Bridge, config?: Config) {
132
+ constructor(bridge: FrontendBridge, config?: Config) {
133
super();
134
135
if (__DEBUG__) {
@@ -701,7 +701,7 @@ export default class Store extends EventEmitter<{|
701
validAttributes,
702
}: {|
703
isSupported: boolean,
704
- validAttributes: $ReadOnlyArray<string>,
704
+ validAttributes: ?$ReadOnlyArray<string>,
705
|}) => {
706
this._isNativeStyleEditorSupported = isSupported;
707
this._nativeStyleEditorValidAttributes = validAttributes || null;
src/devtools/views/Components/HooksTree.js
+13
-11
@@ -221,17 +221,19 @@ function HookView({
221
if (canEditHooks && isStateEditable) {
222
overrideValueFn = (absolutePath: Array<string | number>, value: any) => {
223
const rendererID = store.getRendererIDForElement(id);
224
- bridge.send('overrideHookState', {
225
- id,
226
- hookID,
227
- // Hooks override function expects a relative path for the specified hook (id),
228
- // starting with its id within the (flat) hooks list structure.
229
- // This relative path does not include the fake tree structure DevTools uses for display,
230
- // so it's important that we remove that part of the path before sending the update.
231
- path: absolutePath.slice(path.length + 1),
232
- rendererID,
233
- value,
234
- });
224
+ if (rendererID !== null) {
225
+ bridge.send('overrideHookState', {
226
+ id,
227
+ hookID,
228
+ // Hooks override function expects a relative path for the specified hook (id),
229
+ // starting with its id within the (flat) hooks list structure.
230
+ // This relative path does not include the fake tree structure DevTools uses for display,
231
+ // so it's important that we remove that part of the path before sending the update.
232
+ path: absolutePath.slice(path.length + 1),
233
+ rendererID,
234
+ value,
235
+ });
236
+ }
237
};
238
}
239
src/devtools/views/Components/InspectedElementContext.js
+9
-3
@@ -85,7 +85,9 @@ function InspectedElementContextController({ children }: Props) {
85
const getInspectedElementPath = useCallback<GetInspectedElementPath>(
86
(id: number, path: Array<string | number>) => {
87
const rendererID = store.getRendererIDForElement(id);
88
- bridge.send('inspectElement', { id, path, rendererID });
88
+ if (rendererID !== null) {
89
+ bridge.send('inspectElement', { id, path, rendererID });
90
+ }
91
},
92
[bridge, store]
93
);
@@ -232,7 +234,9 @@ function InspectedElementContextController({ children }: Props) {
234
const sendRequest = () => {
235
timeoutID = null;
236
235
- bridge.send('inspectElement', { id: selectedElementID, rendererID });
237
+ if (rendererID !== null) {
238
+ bridge.send('inspectElement', { id: selectedElementID, rendererID });
239
+ }
240
};
241
242
// Send the initial inspection request.
@@ -240,7 +244,9 @@ function InspectedElementContextController({ children }: Props) {
244
sendRequest();
245
246
// Update the $r variable.
243
- bridge.send('selectElement', { id: selectedElementID, rendererID });
247
+ if (rendererID !== null) {
248
+ bridge.send('selectElement', { id: selectedElementID, rendererID });
249
+ }
250
251
const onInspectedElement = (data: InspectedElementPayload) => {
252
// If this is the element we requested, wait a little bit and then ask for another update.
src/devtools/views/Components/NativeStyleEditor/StyleEditor.js
+19
-13
@@ -25,22 +25,28 @@ export default function StyleEditor({ id, style }: Props) {
25
const store = useContext(StoreContext);
26
27
const changeAttribute = (oldName: string, newName: string, value: any) => {
28
- bridge.send('NativeStyleEditor_renameAttribute', {
29
- id,
30
- rendererID: store.getRendererIDForElement(id),
31
- oldName,
32
- newName,
33
- value,
34
- });
28
+ const rendererID = store.getRendererIDForElement(id);
29
+ if (rendererID !== null) {
30
+ bridge.send('NativeStyleEditor_renameAttribute', {
31
+ id,
32
+ rendererID,
33
+ oldName,
34
+ newName,
35
+ value,
36
+ });
37
+ }
38
};
39
40
const changeValue = (name: string, value: any) => {
38
- bridge.send('NativeStyleEditor_setValue', {
39
- id,
40
- rendererID: store.getRendererIDForElement(id),
41
- name,
42
- value,
43
- });
41
+ const rendererID = store.getRendererIDForElement(id);
42
+ if (rendererID !== null) {
43
+ bridge.send('NativeStyleEditor_setValue', {
44
+ id,
45
+ rendererID,
46
+ name,
47
+ value,
48
+ });
49
+ }
50
};
51
52
const keys = useMemo(() => Array.from(Object.keys(style)), [style]);
src/devtools/views/Components/NativeStyleEditor/context.js
+6
-4
@@ -136,10 +136,12 @@ function NativeStyleContextController({ children }: Props) {
136
const sendRequest = () => {
137
timeoutID = null;
138
139
- bridge.send('NativeStyleEditor_measure', {
140
- id: selectedElementID,
141
- rendererID,
142
- });
139
+ if (rendererID !== null) {
140
+ bridge.send('NativeStyleEditor_measure', {
141
+ id: selectedElementID,
142
+ rendererID,
143
+ });
144
+ }
145
};
146
147
// Send the initial measurement request.
src/devtools/views/Components/OwnersListContext.js
+3
-2
@@ -106,8 +106,9 @@ function OwnersListContextController({ children }: Props) {
106
useEffect(() => {
107
if (ownerID !== null) {
108
const rendererID = store.getRendererIDForElement(ownerID);
109
-
110
- bridge.send('getOwnersList', { id: ownerID, rendererID });
109
+ if (rendererID !== null) {
110
+ bridge.send('getOwnersList', { id: ownerID, rendererID });
111
+ }
112
}
113
114
return () => {};
src/devtools/views/Components/SelectedElement.js
+30
-10
@@ -140,12 +140,18 @@ export default function SelectedElement(_: Props) {
140
});
141
}
142
143
+ const rendererID = store.getRendererIDForElement(
144
+ nearestSuspenseElementID
145
+ );
146
+
147
// Toggle suspended
144
- bridge.send('overrideSuspense', {
145
- id: nearestSuspenseElementID,
146
- rendererID: store.getRendererIDForElement(nearestSuspenseElementID),
147
- forceFallback: !isSuspended,
148
- });
148
+ if (rendererID !== null) {
149
+ bridge.send('overrideSuspense', {
150
+ id: nearestSuspenseElementID,
151
+ rendererID,
152
+ forceFallback: !isSuspended,
153
+ });
154
+ }
155
}
156
}, [bridge, dispatch, element, isSuspended, modalDialogDispatch, store]);
157
@@ -280,15 +286,21 @@ function InspectedElementView({
286
if (type === ElementTypeClass) {
287
overrideContextFn = (path: Array<string | number>, value: any) => {
288
const rendererID = store.getRendererIDForElement(id);
283
- bridge.send('overrideContext', { id, path, rendererID, value });
289
+ if (rendererID !== null) {
290
+ bridge.send('overrideContext', { id, path, rendererID, value });
291
+ }
292
};
293
overridePropsFn = (path: Array<string | number>, value: any) => {
294
const rendererID = store.getRendererIDForElement(id);
287
- bridge.send('overrideProps', { id, path, rendererID, value });
295
+ if (rendererID !== null) {
296
+ bridge.send('overrideProps', { id, path, rendererID, value });
297
+ }
298
};
299
overrideStateFn = (path: Array<string | number>, value: any) => {
300
const rendererID = store.getRendererIDForElement(id);
291
- bridge.send('overrideState', { id, path, rendererID, value });
301
+ if (rendererID !== null) {
302
+ bridge.send('overrideState', { id, path, rendererID, value });
303
+ }
304
};
305
} else if (
306
(type === ElementTypeFunction ||
@@ -298,7 +310,9 @@ function InspectedElementView({
310
) {
311
overridePropsFn = (path: Array<string | number>, value: any) => {
312
const rendererID = store.getRendererIDForElement(id);
301
- bridge.send('overrideProps', { id, path, rendererID, value });
313
+ if (rendererID !== null) {
314
+ bridge.send('overrideProps', { id, path, rendererID, value });
315
+ }
316
};
317
} else if (type === ElementTypeSuspense && canToggleSuspense) {
318
overrideSuspenseFn = (path: Array<string | number>, value: boolean) => {
@@ -306,7 +320,13 @@ function InspectedElementView({
320
throw new Error('Unexpected path.');
321
}
322
const rendererID = store.getRendererIDForElement(id);
309
- bridge.send('overrideSuspense', { id, rendererID, forceFallback: value });
323
+ if (rendererID !== null) {
324
+ bridge.send('overrideSuspense', {
325
+ id,
326
+ rendererID,
327
+ forceFallback: value,
328
+ });
329
+ }
330
};
331
}
332
src/devtools/views/Components/Tree.js
+1
-1
@@ -192,7 +192,7 @@ export default function Tree(props: Props) {
192
(id: number) => {
193
const element = store.getElementByID(id);
194
const rendererID = store.getRendererIDForElement(id);
195
- if (element !== null) {
195
+ if (element !== null && rendererID !== null) {
196
bridge.send('highlightNativeElement', {
197
displayName: element.displayName,
198
hideAfterTimeout: false,
src/devtools/views/DevTools.js
+2
-2
@@ -6,7 +6,6 @@ import '@reach/menu-button/styles.css';
6
import '@reach/tooltip/styles.css';
7
8
import React, { useMemo, useState } from 'react';
9
-import Bridge from 'src/bridge';
9
import Store from '../store';
10
import { BridgeContext, StoreContext } from './context';
11
import Components from './Components/Components';
@@ -25,6 +24,7 @@ import styles from './DevTools.css';
24
import './root.css';
25
26
import type { InspectedElement } from 'src/devtools/views/Components/types';
27
+import type { FrontendBridge } from 'src/bridge';
28
29
export type BrowserTheme = 'dark' | 'light';
30
export type TabID = 'components' | 'profiler' | 'settings';
@@ -34,7 +34,7 @@ export type ViewElementSource = (
34
) => void;
35
36
export type Props = {|
37
- bridge: Bridge,
37
+ bridge: FrontendBridge,
38
browserTheme?: BrowserTheme,
39
defaultTab?: TabID,
40
showTabBar?: boolean,
src/devtools/views/context.js
+5
-3
@@ -1,11 +1,13 @@
1
// @flow
2
3
import { createContext } from 'react';
4
-import Bridge from 'src/bridge';
5
-
4
import Store from '../store';
5
8
-export const BridgeContext = createContext<Bridge>(((null: any): Bridge));
6
+import type { FrontendBridge } from 'src/bridge';
7
+
8
+export const BridgeContext = createContext<FrontendBridge>(
9
+ ((null: any): FrontendBridge)
10
+);
11
BridgeContext.displayName = 'BridgeContext';
12
13
export const StoreContext = createContext<Store>(((null: any): Store));
vendor/react-window/dist/index-dev.umd.js
new
+2
@@ -0,0 +1,2 @@
1
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e=e||self).ReactWindow={},e.React)}(this,function(e,t){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function n(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var i=function(e,t){return e.length===t.length&&e.every(function(e,r){return n=e,o=t[r],n===o;var n,o})};function a(e,t){var r;void 0===t&&(t=i);var n,o=[],a=!1;return function(){for(var i=arguments.length,l=new Array(i),s=0;s<i;s++)l[s]=arguments[s];return a&&r===this&&t(l,o)?n:(n=e.apply(this,l),a=!0,r=this,o=l,n)}}var l="object"==typeof performance&&"function"==typeof performance.now?function(){return performance.now()}:function(){return Date.now()};function s(e){cancelAnimationFrame(e.id)}function c(e,t){var r=l();var n={id:requestAnimationFrame(function o(){l()-r>=t?e.call(null):n.id=requestAnimationFrame(o)})};return n}var u=-1;var d=null;function f(e){if(void 0===e&&(e=!1),null===d||e){var t=document.createElement("div"),r=t.style;r.width="50px",r.height="50px",r.overflow="scroll",r.direction="rtl";var n=document.createElement("div"),o=n.style;return o.width="100px",o.height="100px",t.appendChild(n),document.body.appendChild(t),t.scrollLeft>0?d="positive-descending":(t.scrollLeft=1,d=0===t.scrollLeft?"negative":"positive-ascending"),document.body.removeChild(t),d}return d}var h=150,p=function(e){var t=e.columnIndex;e.data;return e.rowIndex+":"+t},m=null,v=null,g=null;function w(e){var i,l,d=e.getColumnOffset,m=e.getColumnStartIndexForOffset,v=e.getColumnStopIndexForStartIndex,g=e.getColumnWidth,w=e.getEstimatedTotalHeight,I=e.getEstimatedTotalWidth,M=e.getOffsetForColumnAndAlignment,y=e.getOffsetForRowAndAlignment,x=e.getRowHeight,C=e.getRowOffset,_=e.getRowStartIndexForOffset,b=e.getRowStopIndexForStartIndex,R=e.initInstanceProps,T=e.shouldResetStyleCacheOnItemSizeChange,z=e.validateProps;return l=i=function(e){function i(t){var r;return(r=e.call(this,t)||this)._instanceProps=R(r.props,o(o(r))),r._resetIsScrollingTimeoutId=null,r._outerRef=void 0,r.state={instance:o(o(r)),isScrolling:!1,horizontalScrollDirection:"forward",scrollLeft:"number"==typeof r.props.initialScrollLeft?r.props.initialScrollLeft:0,scrollTop:"number"==typeof r.props.initialScrollTop?r.props.initialScrollTop:0,scrollUpdateWasRequested:!1,verticalScrollDirection:"forward"},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(e,t,n,o,i,a,l,s){return r.props.onItemsRendered({overscanColumnStartIndex:e,overscanColumnStopIndex:t,overscanRowStartIndex:n,overscanRowStopIndex:o,visibleColumnStartIndex:i,visibleColumnStopIndex:a,visibleRowStartIndex:l,visibleRowStopIndex:s})}),r._callOnScroll=void 0,r._callOnScroll=a(function(e,t,n,o,i){return r.props.onScroll({horizontalScrollDirection:n,scrollLeft:e,scrollTop:t,verticalScrollDirection:o,scrollUpdateWasRequested:i})}),r._getItemStyle=void 0,r._getItemStyle=function(e,t){var n,o,i=r.props,a=i.columnWidth,l=i.direction,s=i.rowHeight,c=r._getItemStyleCache(T&&a,T&&l,T&&s),u=e+":"+t;c.hasOwnProperty(u)?n=c[u]:c[u]=((o={position:"absolute"})["rtl"===l?"right":"left"]=d(r.props,t,r._instanceProps),o.top=C(r.props,e,r._instanceProps),o.height=x(r.props,e,r._instanceProps),o.width=g(r.props,t,r._instanceProps),n=o);return n},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(e,t,r){return{}}),r._onScroll=function(e){var t=e.currentTarget,n=t.clientHeight,o=t.clientWidth,i=t.scrollLeft,a=t.scrollTop,l=t.scrollHeight,s=t.scrollWidth;r.setState(function(e){if(e.scrollLeft===i&&e.scrollTop===a)return null;var t=r.props.direction,c=i;if("rtl"===t)switch(f()){case"negative":c=-i;break;case"positive-descending":c=s-o-i}c=Math.max(0,Math.min(c,s-o));var u=Math.max(0,Math.min(a,l-n));return{isScrolling:!0,horizontalScrollDirection:e.scrollLeft<i?"forward":"backward",scrollLeft:c,scrollTop:u,verticalScrollDirection:e.scrollTop<a?"forward":"backward",scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(e){var t=r.props.outerRef;r._outerRef=e,"function"==typeof t?t(e):null!=t&&"object"==typeof t&&t.hasOwnProperty("current")&&(t.current=e)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,h)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1)})},r}n(i,e),i.getDerivedStateFromProps=function(e,t){return S(e,t),z(e),null};var l=i.prototype;return l.scrollTo=function(e){var t=e.scrollLeft,r=e.scrollTop;void 0!==t&&(t=Math.max(0,t)),void 0!==r&&(r=Math.max(0,r)),this.setState(function(e){return void 0===t&&(t=e.scrollLeft),void 0===r&&(r=e.scrollTop),e.scrollLeft===t&&e.scrollTop===r?null:{horizontalScrollDirection:e.scrollLeft<t?"forward":"backward",scrollLeft:t,scrollTop:r,scrollUpdateWasRequested:!0,verticalScrollDirection:e.scrollTop<r?"forward":"backward"}},this._resetIsScrollingDebounced)},l.scrollToItem=function(e){var t=e.align,r=void 0===t?"auto":t,n=e.columnIndex,o=e.rowIndex,i=this.props,a=i.columnCount,l=i.height,s=i.rowCount,c=i.width,d=this.state,f=d.scrollLeft,h=d.scrollTop,p=function(e){if(void 0===e&&(e=!1),-1===u||e){var t=document.createElement("div"),r=t.style;r.width="50px",r.height="50px",r.overflow="scroll",document.body.appendChild(t),u=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return u}();void 0!==n&&(n=Math.max(0,Math.min(n,a-1))),void 0!==o&&(o=Math.max(0,Math.min(o,s-1)));var m=w(this.props,this._instanceProps),v=I(this.props,this._instanceProps)>c?p:0,g=m>l?p:0;this.scrollTo({scrollLeft:void 0!==n?M(this.props,n,r,f,this._instanceProps,g):f,scrollTop:void 0!==o?y(this.props,o,r,h,this._instanceProps,v):h})},l.componentDidMount=function(){var e=this.props,t=e.initialScrollLeft,r=e.initialScrollTop;if(null!=this._outerRef){var n=this._outerRef;"number"==typeof t&&(n.scrollLeft=t),"number"==typeof r&&(n.scrollTop=r)}this._callPropsCallbacks()},l.componentDidUpdate=function(){var e=this.props.direction,t=this.state,r=t.scrollLeft,n=t.scrollTop;if(t.scrollUpdateWasRequested&&null!=this._outerRef){var o=this._outerRef;if("rtl"===e)switch(f()){case"negative":o.scrollLeft=-r;break;case"positive-ascending":o.scrollLeft=r;break;default:var i=o.clientWidth,a=o.scrollWidth;o.scrollLeft=a-i-r}else o.scrollLeft=Math.max(0,r);o.scrollTop=Math.max(0,n)}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var e=this.props,n=e.children,o=e.className,i=e.columnCount,a=e.direction,l=e.height,s=e.innerRef,c=e.innerElementType,u=e.innerTagName,d=e.itemData,f=e.itemKey,h=void 0===f?p:f,m=e.outerElementType,v=e.outerTagName,g=e.rowCount,S=e.style,M=e.useIsScrolling,y=e.width,x=this.state.isScrolling,C=this._getHorizontalRangeToRender(),_=C[0],b=C[1],R=this._getVerticalRangeToRender(),T=R[0],z=R[1],O=[];if(i>0&&g)for(var P=T;P<=z;P++)for(var W=_;W<=b;W++)O.push(t.createElement(n,{columnIndex:W,data:d,isScrolling:M?x:void 0,key:h({columnIndex:W,data:d,rowIndex:P}),rowIndex:P,style:this._getItemStyle(P,W)}));var E=w(this.props,this._instanceProps),A=I(this.props,this._instanceProps);return t.createElement(m||v||"div",{className:o,onScroll:this._onScroll,ref:this._outerRefSetter,style:r({position:"relative",height:l,width:y,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:a},S)},t.createElement(c||u||"div",{children:O,ref:s,style:{height:E,pointerEvents:x?"none":void 0,width:A}}))},l._callPropsCallbacks=function(){var e=this.props,t=e.columnCount,r=e.onItemsRendered,n=e.onScroll,o=e.rowCount;if("function"==typeof r&&t>0&&o>0){var i=this._getHorizontalRangeToRender(),a=i[0],l=i[1],s=i[2],c=i[3],u=this._getVerticalRangeToRender(),d=u[0],f=u[1],h=u[2],p=u[3];this._callOnItemsRendered(a,l,d,f,s,c,h,p)}if("function"==typeof n){var m=this.state,v=m.horizontalScrollDirection,g=m.scrollLeft,w=m.scrollTop,S=m.scrollUpdateWasRequested,I=m.verticalScrollDirection;this._callOnScroll(g,w,v,I,S)}},l._getHorizontalRangeToRender=function(){var e=this.props,t=e.columnCount,r=e.overscanColumnCount,n=e.overscanColumnsCount,o=e.overscanCount,i=e.rowCount,a=this.state,l=a.horizontalScrollDirection,s=a.isScrolling,c=a.scrollLeft,u=r||n||o||1;if(0===t||0===i)return[0,0,0,0];var d=m(this.props,c,this._instanceProps),f=v(this.props,d,c,this._instanceProps),h=s&&"backward"!==l?1:Math.max(1,u),p=s&&"forward"!==l?1:Math.max(1,u);return[Math.max(0,d-h),Math.max(0,Math.min(t-1,f+p)),d,f]},l._getVerticalRangeToRender=function(){var e=this.props,t=e.columnCount,r=e.overscanCount,n=e.overscanRowCount,o=e.overscanRowsCount,i=e.rowCount,a=this.state,l=a.isScrolling,s=a.verticalScrollDirection,c=a.scrollTop,u=n||o||r||1;if(0===t||0===i)return[0,0,0,0];var d=_(this.props,c,this._instanceProps),f=b(this.props,d,c,this._instanceProps),h=l&&"backward"!==s?1:Math.max(1,u),p=l&&"forward"!==s?1:Math.max(1,u);return[Math.max(0,d-h),Math.max(0,Math.min(i-1,f+p)),d,f]},i}(t.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,useIsScrolling:!1},l}"undefined"!=typeof window&&void 0!==window.WeakSet&&(m=new WeakSet,v=new WeakSet,g=new WeakSet);var S=function(e,t){var r=e.children,n=e.direction,o=e.height,i=e.innerTagName,a=e.outerTagName,l=e.overscanColumnsCount,s=e.overscanCount,c=e.overscanRowsCount,u=e.width,d=t.instance;if("number"==typeof s&&m&&!m.has(d)&&(m.add(d),console.warn("The overscanCount prop has been deprecated. Please use the overscanColumnCount and overscanRowCount props instead.")),"number"!=typeof l&&"number"!=typeof c||v&&!v.has(d)&&(v.add(d),console.warn("The overscanColumnsCount and overscanRowsCount props have been deprecated. Please use the overscanColumnCount and overscanRowCount props instead.")),null==i&&null==a||g&&!g.has(d)&&(g.add(d),console.warn("The innerTagName and outerTagName props have been deprecated. Please use the innerElementType and outerElementType props instead.")),null==r)throw Error('An invalid "children" prop has been specified. Value should be a React component. "'+(null===r?"null":typeof r)+'" was specified.');switch(n){case"ltr":case"rtl":break;default:throw Error('An invalid "direction" prop has been specified. Value should be either "ltr" or "rtl". "'+n+'" was specified.')}if("number"!=typeof u)throw Error('An invalid "width" prop has been specified. Grids must specify a number for width. "'+(null===u?"null":typeof u)+'" was specified.');if("number"!=typeof o)throw Error('An invalid "height" prop has been specified. Grids must specify a number for height. "'+(null===o?"null":typeof o)+'" was specified.')},I=function(e,t){var r=e.rowCount,n=t.rowMetadataMap,o=t.estimatedRowHeight,i=t.lastMeasuredRowIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=n[i];a=l.offset+l.size}return a+(r-i-1)*o},M=function(e,t){var r=e.columnCount,n=t.columnMetadataMap,o=t.estimatedColumnWidth,i=t.lastMeasuredColumnIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=n[i];a=l.offset+l.size}return a+(r-i-1)*o},y=function(e,t,r,n){var o,i,a;if("column"===e?(o=n.columnMetadataMap,i=t.columnWidth,a=n.lastMeasuredColumnIndex):(o=n.rowMetadataMap,i=t.rowHeight,a=n.lastMeasuredRowIndex),r>a){var l=0;if(a>=0){var s=o[a];l=s.offset+s.size}for(var c=a+1;c<=r;c++){var u=i(c);o[c]={offset:l,size:u},l+=u}"column"===e?n.lastMeasuredColumnIndex=r:n.lastMeasuredRowIndex=r}return o[r]},x=function(e,t,r,n){var o,i;return"column"===e?(o=r.columnMetadataMap,i=r.lastMeasuredColumnIndex):(o=r.rowMetadataMap,i=r.lastMeasuredRowIndex),(i>0?o[i].offset:0)>=n?C(e,t,r,i,0,n):_(e,t,r,Math.max(0,i),n)},C=function(e,t,r,n,o,i){for(;o<=n;){var a=o+Math.floor((n-o)/2),l=y(e,t,a,r).offset;if(l===i)return a;l<i?o=a+1:l>i&&(n=a-1)}return o>0?o-1:0},_=function(e,t,r,n,o){for(var i="column"===e?t.columnCount:t.rowCount,a=1;n<i&&y(e,t,n,r).offset<o;)n+=a,a*=2;return C(e,t,r,Math.min(n,i-1),Math.floor(n/2),o)},b=function(e,t,r,n,o,i,a){var l="column"===e?t.width:t.height,s=y(e,t,r,i),c="column"===e?M(t,i):I(t,i),u=Math.max(0,Math.min(c-l,s.offset)),d=Math.max(0,s.offset-l+a+s.size);switch("smart"===n&&(n=o>=d-l&&o<=u+l?"auto":"center"),n){case"start":return u;case"end":return d;case"center":return Math.round(d+(u-d)/2);case"auto":default:return o>=d&&o<=u?o:d>u?d:o<d?d:u}},R=w({getColumnOffset:function(e,t,r){return y("column",e,t,r).offset},getColumnStartIndexForOffset:function(e,t,r){return x("column",e,r,t)},getColumnStopIndexForStartIndex:function(e,t,r,n){for(var o=e.columnCount,i=e.width,a=y("column",e,t,n),l=r+i,s=a.offset+a.size,c=t;c<o-1&&s<l;)s+=y("column",e,++c,n).size;return c},getColumnWidth:function(e,t,r){return r.columnMetadataMap[t].size},getEstimatedTotalHeight:I,getEstimatedTotalWidth:M,getOffsetForColumnAndAlignment:function(e,t,r,n,o,i){return b("column",e,t,r,n,o,i)},getOffsetForRowAndAlignment:function(e,t,r,n,o,i){return b("row",e,t,r,n,o,i)},getRowOffset:function(e,t,r){return y("row",e,t,r).offset},getRowHeight:function(e,t,r){return r.rowMetadataMap[t].size},getRowStartIndexForOffset:function(e,t,r){return x("row",e,r,t)},getRowStopIndexForStartIndex:function(e,t,r,n){for(var o=e.rowCount,i=e.height,a=y("row",e,t,n),l=r+i,s=a.offset+a.size,c=t;c<o-1&&s<l;)s+=y("row",e,++c,n).size;return c},initInstanceProps:function(e,t){var r=e,n={columnMetadataMap:{},estimatedColumnWidth:r.estimatedColumnWidth||50,estimatedRowHeight:r.estimatedRowHeight||50,lastMeasuredColumnIndex:-1,lastMeasuredRowIndex:-1,rowMetadataMap:{}};return t.resetAfterColumnIndex=function(e,r){void 0===r&&(r=!0),t.resetAfterIndices({columnIndex:e,shouldForceUpdate:r})},t.resetAfterRowIndex=function(e,r){void 0===r&&(r=!0),t.resetAfterIndices({rowIndex:e,shouldForceUpdate:r})},t.resetAfterIndices=function(e){var r=e.columnIndex,o=e.rowIndex,i=e.shouldForceUpdate,a=void 0===i||i;"number"==typeof r&&(n.lastMeasuredColumnIndex=Math.min(n.lastMeasuredColumnIndex,r-1)),"number"==typeof o&&(n.lastMeasuredRowIndex=Math.min(n.lastMeasuredRowIndex,o-1)),t._getItemStyleCache(-1),a&&t.forceUpdate()},n},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(e){var t=e.columnWidth,r=e.rowHeight;if("function"!=typeof t)throw Error('An invalid "columnWidth" prop has been specified. Value should be a function. "'+(null===t?"null":typeof t)+'" was specified.');if("function"!=typeof r)throw Error('An invalid "rowHeight" prop has been specified. Value should be a function. "'+(null===r?"null":typeof r)+'" was specified.')}}),T=150,z=function(e,t){return e},O=null,P=null;function W(e){var i,l,u=e.getItemOffset,d=e.getEstimatedTotalSize,h=e.getItemSize,p=e.getOffsetForIndexAndAlignment,m=e.getStartIndexForOffset,v=e.getStopIndexForStartIndex,g=e.initInstanceProps,w=e.shouldResetStyleCacheOnItemSizeChange,S=e.validateProps;return l=i=function(e){function i(t){var r;return(r=e.call(this,t)||this)._instanceProps=g(r.props,o(o(r))),r._outerRef=void 0,r._resetIsScrollingTimeoutId=null,r.state={instance:o(o(r)),isScrolling:!1,scrollDirection:"forward",scrollOffset:"number"==typeof r.props.initialScrollOffset?r.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(e,t,n,o){return r.props.onItemsRendered({overscanStartIndex:e,overscanStopIndex:t,visibleStartIndex:n,visibleStopIndex:o})}),r._callOnScroll=void 0,r._callOnScroll=a(function(e,t,n){return r.props.onScroll({scrollDirection:e,scrollOffset:t,scrollUpdateWasRequested:n})}),r._getItemStyle=void 0,r._getItemStyle=function(e){var t,n=r.props,o=n.direction,i=n.itemSize,a=n.layout,l=r._getItemStyleCache(w&&i,w&&a,w&&o);if(l.hasOwnProperty(e))t=l[e];else{var s,c=u(r.props,e,r._instanceProps),d=h(r.props,e,r._instanceProps),f="horizontal"===o||"horizontal"===a;l[e]=((s={position:"absolute"})["rtl"===o?"right":"left"]=f?c:0,s.top=f?0:c,s.height=f?"100%":d,s.width=f?d:"100%",t=s)}return t},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(e,t,r){return{}}),r._onScrollHorizontal=function(e){var t=e.currentTarget,n=t.clientWidth,o=t.scrollLeft,i=t.scrollWidth;r.setState(function(e){if(e.scrollOffset===o)return null;var t=r.props.direction,a=o;if("rtl"===t)switch(f()){case"negative":a=-o;break;case"positive-descending":a=i-n-o}return a=Math.max(0,Math.min(a,i-n)),{isScrolling:!0,scrollDirection:e.scrollOffset<o?"forward":"backward",scrollOffset:a,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._onScrollVertical=function(e){var t=e.currentTarget,n=t.clientHeight,o=t.scrollHeight,i=t.scrollTop;r.setState(function(e){if(e.scrollOffset===i)return null;var t=Math.max(0,Math.min(i,o-n));return{isScrolling:!0,scrollDirection:e.scrollOffset<t?"forward":"backward",scrollOffset:t,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(e){var t=r.props.outerRef;r._outerRef=e,"function"==typeof t?t(e):null!=t&&"object"==typeof t&&t.hasOwnProperty("current")&&(t.current=e)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,T)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1,null)})},r}n(i,e),i.getDerivedStateFromProps=function(e,t){return E(e,t),S(e),null};var l=i.prototype;return l.scrollTo=function(e){e=Math.max(0,e),this.setState(function(t){return t.scrollOffset===e?null:{scrollDirection:t.scrollOffset<e?"forward":"backward",scrollOffset:e,scrollUpdateWasRequested:!0}},this._resetIsScrollingDebounced)},l.scrollToItem=function(e,t){void 0===t&&(t="auto");var r=this.props.itemCount,n=this.state.scrollOffset;e=Math.max(0,Math.min(e,r-1)),this.scrollTo(p(this.props,e,t,n,this._instanceProps))},l.componentDidMount=function(){var e=this.props,t=e.direction,r=e.initialScrollOffset,n=e.layout;if("number"==typeof r&&null!=this._outerRef){var o=this._outerRef;"horizontal"===t||"horizontal"===n?o.scrollLeft=r:o.scrollTop=r}this._callPropsCallbacks()},l.componentDidUpdate=function(){var e=this.props,t=e.direction,r=e.layout,n=this.state,o=n.scrollOffset;if(n.scrollUpdateWasRequested&&null!=this._outerRef){var i=this._outerRef;if("horizontal"===t||"horizontal"===r)if("rtl"===t)switch(f()){case"negative":i.scrollLeft=-o;break;case"positive-ascending":i.scrollLeft=o;break;default:var a=i.clientWidth,l=i.scrollWidth;i.scrollLeft=l-a-o}else i.scrollLeft=o;else i.scrollTop=o}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var e=this.props,n=e.children,o=e.className,i=e.direction,a=e.height,l=e.innerRef,s=e.innerElementType,c=e.innerTagName,u=e.itemCount,f=e.itemData,h=e.itemKey,p=void 0===h?z:h,m=e.layout,v=e.outerElementType,g=e.outerTagName,w=e.style,S=e.useIsScrolling,I=e.width,M=this.state.isScrolling,y="horizontal"===i||"horizontal"===m,x=y?this._onScrollHorizontal:this._onScrollVertical,C=this._getRangeToRender(),_=C[0],b=C[1],R=[];if(u>0)for(var T=_;T<=b;T++)R.push(t.createElement(n,{data:f,key:p(T,f),index:T,isScrolling:S?M:void 0,style:this._getItemStyle(T)}));var O=d(this.props,this._instanceProps);return t.createElement(v||g||"div",{className:o,onScroll:x,ref:this._outerRefSetter,style:r({position:"relative",height:a,width:I,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:i},w)},t.createElement(s||c||"div",{children:R,ref:l,style:{height:y?"100%":O,pointerEvents:M?"none":void 0,width:y?O:"100%"}}))},l._callPropsCallbacks=function(){if("function"==typeof this.props.onItemsRendered&&this.props.itemCount>0){var e=this._getRangeToRender(),t=e[0],r=e[1],n=e[2],o=e[3];this._callOnItemsRendered(t,r,n,o)}if("function"==typeof this.props.onScroll){var i=this.state,a=i.scrollDirection,l=i.scrollOffset,s=i.scrollUpdateWasRequested;this._callOnScroll(a,l,s)}},l._getRangeToRender=function(){var e=this.props,t=e.itemCount,r=e.overscanCount,n=this.state,o=n.isScrolling,i=n.scrollDirection,a=n.scrollOffset;if(0===t)return[0,0,0,0];var l=m(this.props,a,this._instanceProps),s=v(this.props,l,a,this._instanceProps),c=o&&"backward"!==i?1:Math.max(1,r),u=o&&"forward"!==i?1:Math.max(1,r);return[Math.max(0,l-c),Math.max(0,Math.min(t-1,s+u)),l,s]},i}(t.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,layout:"vertical",overscanCount:2,useIsScrolling:!1},l}"undefined"!=typeof window&&void 0!==window.WeakSet&&(O=new WeakSet,P=new WeakSet);var E=function(e,t){var r=e.children,n=e.direction,o=e.height,i=e.layout,a=e.innerTagName,l=e.outerTagName,s=e.width,c=t.instance;null==a&&null==l||P&&!P.has(c)&&(P.add(c),console.warn("The innerTagName and outerTagName props have been deprecated. Please use the innerElementType and outerElementType props instead."));var u="horizontal"===n||"horizontal"===i;switch(n){case"horizontal":case"vertical":O&&!O.has(c)&&(O.add(c),console.warn('The direction prop should be either "ltr" (default) or "rtl". Please use the layout prop to specify "vertical" (default) or "horizontal" orientation.'));break;case"ltr":case"rtl":break;default:throw Error('An invalid "direction" prop has been specified. Value should be either "ltr" or "rtl". "'+n+'" was specified.')}switch(i){case"horizontal":case"vertical":break;default:throw Error('An invalid "layout" prop has been specified. Value should be either "horizontal" or "vertical". "'+i+'" was specified.')}if(null==r)throw Error('An invalid "children" prop has been specified. Value should be a React component. "'+(null===r?"null":typeof r)+'" was specified.');if(u&&"number"!=typeof s)throw Error('An invalid "width" prop has been specified. Horizontal lists must specify a number for width. "'+(null===s?"null":typeof s)+'" was specified.');if(!u&&"number"!=typeof o)throw Error('An invalid "height" prop has been specified. Vertical lists must specify a number for height. "'+(null===o?"null":typeof o)+'" was specified.')},A=function(e,t,r){var n=e.itemSize,o=r.itemMetadataMap,i=r.lastMeasuredIndex;if(t>i){var a=0;if(i>=0){var l=o[i];a=l.offset+l.size}for(var s=i+1;s<=t;s++){var c=n(s);o[s]={offset:a,size:c},a+=c}r.lastMeasuredIndex=t}return o[t]},k=function(e,t,r,n,o){for(;n<=r;){var i=n+Math.floor((r-n)/2),a=A(e,i,t).offset;if(a===o)return i;a<o?n=i+1:a>o&&(r=i-1)}return n>0?n-1:0},D=function(e,t,r,n){for(var o=e.itemCount,i=1;r<o&&A(e,r,t).offset<n;)r+=i,i*=2;return k(e,t,Math.min(r,o-1),Math.floor(r/2),n)},F=function(e,t){var r=e.itemCount,n=t.itemMetadataMap,o=t.estimatedItemSize,i=t.lastMeasuredIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=n[i];a=l.offset+l.size}return a+(r-i-1)*o},L=W({getItemOffset:function(e,t,r){return A(e,t,r).offset},getItemSize:function(e,t,r){return r.itemMetadataMap[t].size},getEstimatedTotalSize:F,getOffsetForIndexAndAlignment:function(e,t,r,n,o){var i=e.direction,a=e.height,l=e.layout,s=e.width,c="horizontal"===i||"horizontal"===l?s:a,u=A(e,t,o),d=F(e,o),f=Math.max(0,Math.min(d-c,u.offset)),h=Math.max(0,u.offset-c+u.size);switch("smart"===r&&(r=n>=h-c&&n<=f+c?"auto":"center"),r){case"start":return f;case"end":return h;case"center":return Math.round(h+(f-h)/2);case"auto":default:return n>=h&&n<=f?n:n<h?h:f}},getStartIndexForOffset:function(e,t,r){return function(e,t,r){var n=t.itemMetadataMap,o=t.lastMeasuredIndex;return(o>0?n[o].offset:0)>=r?k(e,t,o,0,r):D(e,t,Math.max(0,o),r)}(e,r,t)},getStopIndexForStartIndex:function(e,t,r,n){for(var o=e.direction,i=e.height,a=e.itemCount,l=e.layout,s=e.width,c="horizontal"===o||"horizontal"===l?s:i,u=A(e,t,n),d=r+c,f=u.offset+u.size,h=t;h<a-1&&f<d;)f+=A(e,++h,n).size;return h},initInstanceProps:function(e,t){var r={itemMetadataMap:{},estimatedItemSize:e.estimatedItemSize||50,lastMeasuredIndex:-1};return t.resetAfterIndex=function(e,n){void 0===n&&(n=!0),r.lastMeasuredIndex=Math.min(r.lastMeasuredIndex,e-1),t._getItemStyleCache(-1),n&&t.forceUpdate()},r},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(e){var t=e.itemSize;if("function"!=typeof t)throw Error('An invalid "itemSize" prop has been specified. Value should be a function. "'+(null===t?"null":typeof t)+'" was specified.')}}),H=w({getColumnOffset:function(e,t){return t*e.columnWidth},getColumnWidth:function(e,t){return e.columnWidth},getRowOffset:function(e,t){return t*e.rowHeight},getRowHeight:function(e,t){return e.rowHeight},getEstimatedTotalHeight:function(e){var t=e.rowCount;return e.rowHeight*t},getEstimatedTotalWidth:function(e){var t=e.columnCount;return e.columnWidth*t},getOffsetForColumnAndAlignment:function(e,t,r,n,o,i){var a=e.columnCount,l=e.columnWidth,s=e.width,c=Math.max(0,a*l-s),u=Math.min(c,t*l),d=Math.max(0,t*l-s+i+l);switch("smart"===r&&(r=n>=d-s&&n<=u+s?"auto":"center"),r){case"start":return u;case"end":return d;case"center":var f=Math.round(d+(u-d)/2);return f<Math.ceil(s/2)?0:f>c+Math.floor(s/2)?c:f;case"auto":default:return n>=d&&n<=u?n:d>u?d:n<d?d:u}},getOffsetForRowAndAlignment:function(e,t,r,n,o,i){var a=e.rowHeight,l=e.height,s=e.rowCount,c=Math.max(0,s*a-l),u=Math.min(c,t*a),d=Math.max(0,t*a-l+i+a);switch("smart"===r&&(r=n>=d-l&&n<=u+l?"auto":"center"),r){case"start":return u;case"end":return d;case"center":var f=Math.round(d+(u-d)/2);return f<Math.ceil(l/2)?0:f>c+Math.floor(l/2)?c:f;case"auto":default:return n>=d&&n<=u?n:d>u?d:n<d?d:u}},getColumnStartIndexForOffset:function(e,t){var r=e.columnWidth,n=e.columnCount;return Math.max(0,Math.min(n-1,Math.floor(t/r)))},getColumnStopIndexForStartIndex:function(e,t,r){var n=e.columnWidth,o=e.columnCount,i=e.width,a=t*n,l=Math.ceil((i+r-a)/n);return Math.max(0,Math.min(o-1,t+l-1))},getRowStartIndexForOffset:function(e,t){var r=e.rowHeight,n=e.rowCount;return Math.max(0,Math.min(n-1,Math.floor(t/r)))},getRowStopIndexForStartIndex:function(e,t,r){var n=e.rowHeight,o=e.rowCount,i=e.height,a=t*n,l=Math.ceil((i+r-a)/n);return Math.max(0,Math.min(o-1,t+l-1))},initInstanceProps:function(e){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(e){var t=e.columnWidth,r=e.rowHeight;if("number"!=typeof t)throw Error('An invalid "columnWidth" prop has been specified. Value should be a number. "'+(null===t?"null":typeof t)+'" was specified.');if("number"!=typeof r)throw Error('An invalid "rowHeight" prop has been specified. Value should be a number. "'+(null===r?"null":typeof r)+'" was specified.')}}),U=W({getItemOffset:function(e,t){return t*e.itemSize},getItemSize:function(e,t){return e.itemSize},getEstimatedTotalSize:function(e){var t=e.itemCount;return e.itemSize*t},getOffsetForIndexAndAlignment:function(e,t,r,n){var o=e.direction,i=e.height,a=e.itemCount,l=e.itemSize,s=e.layout,c=e.width,u="horizontal"===o||"horizontal"===s?c:i,d=Math.max(0,a*l-u),f=Math.min(d,t*l),h=Math.max(0,t*l-u+l);switch("smart"===r&&(r=n>=h-u&&n<=f+u?"auto":"center"),r){case"start":return f;case"end":return h;case"center":var p=Math.round(h+(f-h)/2);return p<Math.ceil(u/2)?0:p>d+Math.floor(u/2)?d:p;case"auto":default:return n>=h&&n<=f?n:n<h?h:f}},getStartIndexForOffset:function(e,t){var r=e.itemCount,n=e.itemSize;return Math.max(0,Math.min(r-1,Math.floor(t/n)))},getStopIndexForStartIndex:function(e,t,r){var n=e.direction,o=e.height,i=e.itemCount,a=e.itemSize,l=e.layout,s=e.width,c=t*a,u="horizontal"===n||"horizontal"===l?s:o,d=Math.ceil((u+r-c)/a);return Math.max(0,Math.min(i-1,t+d-1))},initInstanceProps:function(e){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(e){var t=e.itemSize;if("number"!=typeof t)throw Error('An invalid "itemSize" prop has been specified. Value should be a number. "'+(null===t?"null":typeof t)+'" was specified.')}});function V(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}function q(e,t){for(var r in e)if(!(r in t))return!0;for(var n in t)if(e[n]!==t[n])return!0;return!1}function N(e,t){var r=e.style,n=V(e,["style"]),o=t.style,i=V(t,["style"]);return!q(r,o)&&!q(n,i)}e.VariableSizeGrid=R,e.VariableSizeList=L,e.FixedSizeGrid=H,e.FixedSizeList=U,e.areEqual=N,e.shouldComponentUpdate=function(e,t){return!N(this.props,e)||q(this.state,t)},Object.defineProperty(e,"__esModule",{value:!0})});
2
+//# sourceMappingURL=index-dev.umd.js.map
vendor/react-window/dist/index-prod.umd.js
new
+2
@@ -0,0 +1,2 @@
1
+!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((t=t||self).ReactWindow={},t.React)}(this,function(t,e){"use strict";function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t}).apply(this,arguments)}function o(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e}function n(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}var i=function(t,e){return t.length===e.length&&t.every(function(t,r){return o=t,n=e[r],o===n;var o,n})};function a(t,e){var r;void 0===e&&(e=i);var o,n=[],a=!1;return function(){for(var i=arguments.length,l=new Array(i),s=0;s<i;s++)l[s]=arguments[s];return a&&r===this&&e(l,n)?o:(o=t.apply(this,l),a=!0,r=this,n=l,o)}}var l="object"==typeof performance&&"function"==typeof performance.now?function(){return performance.now()}:function(){return Date.now()};function s(t){cancelAnimationFrame(t.id)}function c(t,e){var r=l();var o={id:requestAnimationFrame(function n(){l()-r>=e?t.call(null):o.id=requestAnimationFrame(n)})};return o}var u=-1;var f=null;function d(t){if(void 0===t&&(t=!1),null===f||t){var e=document.createElement("div"),r=e.style;r.width="50px",r.height="50px",r.overflow="scroll",r.direction="rtl";var o=document.createElement("div"),n=o.style;return n.width="100px",n.height="100px",e.appendChild(o),document.body.appendChild(e),e.scrollLeft>0?f="positive-descending":(e.scrollLeft=1,f=0===e.scrollLeft?"negative":"positive-ascending"),document.body.removeChild(e),f}return f}var h=150,m=function(t){var e=t.columnIndex;t.data;return t.rowIndex+":"+e};function p(t){var i,l,f=t.getColumnOffset,p=t.getColumnStartIndexForOffset,v=t.getColumnStopIndexForStartIndex,S=t.getColumnWidth,I=t.getEstimatedTotalHeight,w=t.getEstimatedTotalWidth,M=t.getOffsetForColumnAndAlignment,x=t.getOffsetForRowAndAlignment,_=t.getRowHeight,C=t.getRowOffset,R=t.getRowStartIndexForOffset,y=t.getRowStopIndexForStartIndex,T=t.initInstanceProps,O=t.shouldResetStyleCacheOnItemSizeChange,z=t.validateProps;return l=i=function(t){function i(e){var r;return(r=t.call(this,e)||this)._instanceProps=T(r.props,n(n(r))),r._resetIsScrollingTimeoutId=null,r._outerRef=void 0,r.state={instance:n(n(r)),isScrolling:!1,horizontalScrollDirection:"forward",scrollLeft:"number"==typeof r.props.initialScrollLeft?r.props.initialScrollLeft:0,scrollTop:"number"==typeof r.props.initialScrollTop?r.props.initialScrollTop:0,scrollUpdateWasRequested:!1,verticalScrollDirection:"forward"},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(t,e,o,n,i,a,l,s){return r.props.onItemsRendered({overscanColumnStartIndex:t,overscanColumnStopIndex:e,overscanRowStartIndex:o,overscanRowStopIndex:n,visibleColumnStartIndex:i,visibleColumnStopIndex:a,visibleRowStartIndex:l,visibleRowStopIndex:s})}),r._callOnScroll=void 0,r._callOnScroll=a(function(t,e,o,n,i){return r.props.onScroll({horizontalScrollDirection:o,scrollLeft:t,scrollTop:e,verticalScrollDirection:n,scrollUpdateWasRequested:i})}),r._getItemStyle=void 0,r._getItemStyle=function(t,e){var o,n,i=r.props,a=i.columnWidth,l=i.direction,s=i.rowHeight,c=r._getItemStyleCache(O&&a,O&&l,O&&s),u=t+":"+e;c.hasOwnProperty(u)?o=c[u]:c[u]=((n={position:"absolute"})["rtl"===l?"right":"left"]=f(r.props,e,r._instanceProps),n.top=C(r.props,t,r._instanceProps),n.height=_(r.props,t,r._instanceProps),n.width=S(r.props,e,r._instanceProps),o=n);return o},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(t,e,r){return{}}),r._onScroll=function(t){var e=t.currentTarget,o=e.clientHeight,n=e.clientWidth,i=e.scrollLeft,a=e.scrollTop,l=e.scrollHeight,s=e.scrollWidth;r.setState(function(t){if(t.scrollLeft===i&&t.scrollTop===a)return null;var e=r.props.direction,c=i;if("rtl"===e)switch(d()){case"negative":c=-i;break;case"positive-descending":c=s-n-i}c=Math.max(0,Math.min(c,s-n));var u=Math.max(0,Math.min(a,l-o));return{isScrolling:!0,horizontalScrollDirection:t.scrollLeft<i?"forward":"backward",scrollLeft:c,scrollTop:u,verticalScrollDirection:t.scrollTop<a?"forward":"backward",scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(t){var e=r.props.outerRef;r._outerRef=t,"function"==typeof e?e(t):null!=e&&"object"==typeof e&&e.hasOwnProperty("current")&&(e.current=t)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,h)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1)})},r}o(i,t),i.getDerivedStateFromProps=function(t,e){return g(t,e),z(t),null};var l=i.prototype;return l.scrollTo=function(t){var e=t.scrollLeft,r=t.scrollTop;void 0!==e&&(e=Math.max(0,e)),void 0!==r&&(r=Math.max(0,r)),this.setState(function(t){return void 0===e&&(e=t.scrollLeft),void 0===r&&(r=t.scrollTop),t.scrollLeft===e&&t.scrollTop===r?null:{horizontalScrollDirection:t.scrollLeft<e?"forward":"backward",scrollLeft:e,scrollTop:r,scrollUpdateWasRequested:!0,verticalScrollDirection:t.scrollTop<r?"forward":"backward"}},this._resetIsScrollingDebounced)},l.scrollToItem=function(t){var e=t.align,r=void 0===e?"auto":e,o=t.columnIndex,n=t.rowIndex,i=this.props,a=i.columnCount,l=i.height,s=i.rowCount,c=i.width,f=this.state,d=f.scrollLeft,h=f.scrollTop,m=function(t){if(void 0===t&&(t=!1),-1===u||t){var e=document.createElement("div"),r=e.style;r.width="50px",r.height="50px",r.overflow="scroll",document.body.appendChild(e),u=e.offsetWidth-e.clientWidth,document.body.removeChild(e)}return u}();void 0!==o&&(o=Math.max(0,Math.min(o,a-1))),void 0!==n&&(n=Math.max(0,Math.min(n,s-1)));var p=I(this.props,this._instanceProps),g=w(this.props,this._instanceProps)>c?m:0,v=p>l?m:0;this.scrollTo({scrollLeft:void 0!==o?M(this.props,o,r,d,this._instanceProps,v):d,scrollTop:void 0!==n?x(this.props,n,r,h,this._instanceProps,g):h})},l.componentDidMount=function(){var t=this.props,e=t.initialScrollLeft,r=t.initialScrollTop;if(null!=this._outerRef){var o=this._outerRef;"number"==typeof e&&(o.scrollLeft=e),"number"==typeof r&&(o.scrollTop=r)}this._callPropsCallbacks()},l.componentDidUpdate=function(){var t=this.props.direction,e=this.state,r=e.scrollLeft,o=e.scrollTop;if(e.scrollUpdateWasRequested&&null!=this._outerRef){var n=this._outerRef;if("rtl"===t)switch(d()){case"negative":n.scrollLeft=-r;break;case"positive-ascending":n.scrollLeft=r;break;default:var i=n.clientWidth,a=n.scrollWidth;n.scrollLeft=a-i-r}else n.scrollLeft=Math.max(0,r);n.scrollTop=Math.max(0,o)}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var t=this.props,o=t.children,n=t.className,i=t.columnCount,a=t.direction,l=t.height,s=t.innerRef,c=t.innerElementType,u=t.innerTagName,f=t.itemData,d=t.itemKey,h=void 0===d?m:d,p=t.outerElementType,g=t.outerTagName,v=t.rowCount,S=t.style,M=t.useIsScrolling,x=t.width,_=this.state.isScrolling,C=this._getHorizontalRangeToRender(),R=C[0],y=C[1],T=this._getVerticalRangeToRender(),O=T[0],z=T[1],b=[];if(i>0&&v)for(var P=O;P<=z;P++)for(var W=R;W<=y;W++)b.push(e.createElement(o,{columnIndex:W,data:f,isScrolling:M?_:void 0,key:h({columnIndex:W,data:f,rowIndex:P}),rowIndex:P,style:this._getItemStyle(P,W)}));var D=I(this.props,this._instanceProps),F=w(this.props,this._instanceProps);return e.createElement(p||g||"div",{className:n,onScroll:this._onScroll,ref:this._outerRefSetter,style:r({position:"relative",height:l,width:x,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:a},S)},e.createElement(c||u||"div",{children:b,ref:s,style:{height:D,pointerEvents:_?"none":void 0,width:F}}))},l._callPropsCallbacks=function(){var t=this.props,e=t.columnCount,r=t.onItemsRendered,o=t.onScroll,n=t.rowCount;if("function"==typeof r&&e>0&&n>0){var i=this._getHorizontalRangeToRender(),a=i[0],l=i[1],s=i[2],c=i[3],u=this._getVerticalRangeToRender(),f=u[0],d=u[1],h=u[2],m=u[3];this._callOnItemsRendered(a,l,f,d,s,c,h,m)}if("function"==typeof o){var p=this.state,g=p.horizontalScrollDirection,v=p.scrollLeft,S=p.scrollTop,I=p.scrollUpdateWasRequested,w=p.verticalScrollDirection;this._callOnScroll(v,S,g,w,I)}},l._getHorizontalRangeToRender=function(){var t=this.props,e=t.columnCount,r=t.overscanColumnCount,o=t.overscanColumnsCount,n=t.overscanCount,i=t.rowCount,a=this.state,l=a.horizontalScrollDirection,s=a.isScrolling,c=a.scrollLeft,u=r||o||n||1;if(0===e||0===i)return[0,0,0,0];var f=p(this.props,c,this._instanceProps),d=v(this.props,f,c,this._instanceProps),h=s&&"backward"!==l?1:Math.max(1,u),m=s&&"forward"!==l?1:Math.max(1,u);return[Math.max(0,f-h),Math.max(0,Math.min(e-1,d+m)),f,d]},l._getVerticalRangeToRender=function(){var t=this.props,e=t.columnCount,r=t.overscanCount,o=t.overscanRowCount,n=t.overscanRowsCount,i=t.rowCount,a=this.state,l=a.isScrolling,s=a.verticalScrollDirection,c=a.scrollTop,u=o||n||r||1;if(0===e||0===i)return[0,0,0,0];var f=R(this.props,c,this._instanceProps),d=y(this.props,f,c,this._instanceProps),h=l&&"backward"!==s?1:Math.max(1,u),m=l&&"forward"!==s?1:Math.max(1,u);return[Math.max(0,f-h),Math.max(0,Math.min(i-1,d+m)),f,d]},i}(e.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,useIsScrolling:!1},l}var g=function(t,e){t.children,t.direction,t.height,t.innerTagName,t.outerTagName,t.overscanColumnsCount,t.overscanCount,t.overscanRowsCount,t.width,e.instance},v=function(t,e){var r=t.rowCount,o=e.rowMetadataMap,n=e.estimatedRowHeight,i=e.lastMeasuredRowIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=o[i];a=l.offset+l.size}return a+(r-i-1)*n},S=function(t,e){var r=t.columnCount,o=e.columnMetadataMap,n=e.estimatedColumnWidth,i=e.lastMeasuredColumnIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=o[i];a=l.offset+l.size}return a+(r-i-1)*n},I=function(t,e,r,o){var n,i,a;if("column"===t?(n=o.columnMetadataMap,i=e.columnWidth,a=o.lastMeasuredColumnIndex):(n=o.rowMetadataMap,i=e.rowHeight,a=o.lastMeasuredRowIndex),r>a){var l=0;if(a>=0){var s=n[a];l=s.offset+s.size}for(var c=a+1;c<=r;c++){var u=i(c);n[c]={offset:l,size:u},l+=u}"column"===t?o.lastMeasuredColumnIndex=r:o.lastMeasuredRowIndex=r}return n[r]},w=function(t,e,r,o){var n,i;return"column"===t?(n=r.columnMetadataMap,i=r.lastMeasuredColumnIndex):(n=r.rowMetadataMap,i=r.lastMeasuredRowIndex),(i>0?n[i].offset:0)>=o?M(t,e,r,i,0,o):x(t,e,r,Math.max(0,i),o)},M=function(t,e,r,o,n,i){for(;n<=o;){var a=n+Math.floor((o-n)/2),l=I(t,e,a,r).offset;if(l===i)return a;l<i?n=a+1:l>i&&(o=a-1)}return n>0?n-1:0},x=function(t,e,r,o,n){for(var i="column"===t?e.columnCount:e.rowCount,a=1;o<i&&I(t,e,o,r).offset<n;)o+=a,a*=2;return M(t,e,r,Math.min(o,i-1),Math.floor(o/2),n)},_=function(t,e,r,o,n,i,a){var l="column"===t?e.width:e.height,s=I(t,e,r,i),c="column"===t?S(e,i):v(e,i),u=Math.max(0,Math.min(c-l,s.offset)),f=Math.max(0,s.offset-l+a+s.size);switch("smart"===o&&(o=n>=f-l&&n<=u+l?"auto":"center"),o){case"start":return u;case"end":return f;case"center":return Math.round(f+(u-f)/2);case"auto":default:return n>=f&&n<=u?n:f>u?f:n<f?f:u}},C=p({getColumnOffset:function(t,e,r){return I("column",t,e,r).offset},getColumnStartIndexForOffset:function(t,e,r){return w("column",t,r,e)},getColumnStopIndexForStartIndex:function(t,e,r,o){for(var n=t.columnCount,i=t.width,a=I("column",t,e,o),l=r+i,s=a.offset+a.size,c=e;c<n-1&&s<l;)s+=I("column",t,++c,o).size;return c},getColumnWidth:function(t,e,r){return r.columnMetadataMap[e].size},getEstimatedTotalHeight:v,getEstimatedTotalWidth:S,getOffsetForColumnAndAlignment:function(t,e,r,o,n,i){return _("column",t,e,r,o,n,i)},getOffsetForRowAndAlignment:function(t,e,r,o,n,i){return _("row",t,e,r,o,n,i)},getRowOffset:function(t,e,r){return I("row",t,e,r).offset},getRowHeight:function(t,e,r){return r.rowMetadataMap[e].size},getRowStartIndexForOffset:function(t,e,r){return w("row",t,r,e)},getRowStopIndexForStartIndex:function(t,e,r,o){for(var n=t.rowCount,i=t.height,a=I("row",t,e,o),l=r+i,s=a.offset+a.size,c=e;c<n-1&&s<l;)s+=I("row",t,++c,o).size;return c},initInstanceProps:function(t,e){var r=t,o={columnMetadataMap:{},estimatedColumnWidth:r.estimatedColumnWidth||50,estimatedRowHeight:r.estimatedRowHeight||50,lastMeasuredColumnIndex:-1,lastMeasuredRowIndex:-1,rowMetadataMap:{}};return e.resetAfterColumnIndex=function(t,r){void 0===r&&(r=!0),e.resetAfterIndices({columnIndex:t,shouldForceUpdate:r})},e.resetAfterRowIndex=function(t,r){void 0===r&&(r=!0),e.resetAfterIndices({rowIndex:t,shouldForceUpdate:r})},e.resetAfterIndices=function(t){var r=t.columnIndex,n=t.rowIndex,i=t.shouldForceUpdate,a=void 0===i||i;"number"==typeof r&&(o.lastMeasuredColumnIndex=Math.min(o.lastMeasuredColumnIndex,r-1)),"number"==typeof n&&(o.lastMeasuredRowIndex=Math.min(o.lastMeasuredRowIndex,n-1)),e._getItemStyleCache(-1),a&&e.forceUpdate()},o},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(t){t.columnWidth,t.rowHeight}}),R=150,y=function(t,e){return t};function T(t){var i,l,u=t.getItemOffset,f=t.getEstimatedTotalSize,h=t.getItemSize,m=t.getOffsetForIndexAndAlignment,p=t.getStartIndexForOffset,g=t.getStopIndexForStartIndex,v=t.initInstanceProps,S=t.shouldResetStyleCacheOnItemSizeChange,I=t.validateProps;return l=i=function(t){function i(e){var r;return(r=t.call(this,e)||this)._instanceProps=v(r.props,n(n(r))),r._outerRef=void 0,r._resetIsScrollingTimeoutId=null,r.state={instance:n(n(r)),isScrolling:!1,scrollDirection:"forward",scrollOffset:"number"==typeof r.props.initialScrollOffset?r.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},r._callOnItemsRendered=void 0,r._callOnItemsRendered=a(function(t,e,o,n){return r.props.onItemsRendered({overscanStartIndex:t,overscanStopIndex:e,visibleStartIndex:o,visibleStopIndex:n})}),r._callOnScroll=void 0,r._callOnScroll=a(function(t,e,o){return r.props.onScroll({scrollDirection:t,scrollOffset:e,scrollUpdateWasRequested:o})}),r._getItemStyle=void 0,r._getItemStyle=function(t){var e,o=r.props,n=o.direction,i=o.itemSize,a=o.layout,l=r._getItemStyleCache(S&&i,S&&a,S&&n);if(l.hasOwnProperty(t))e=l[t];else{var s,c=u(r.props,t,r._instanceProps),f=h(r.props,t,r._instanceProps),d="horizontal"===n||"horizontal"===a;l[t]=((s={position:"absolute"})["rtl"===n?"right":"left"]=d?c:0,s.top=d?0:c,s.height=d?"100%":f,s.width=d?f:"100%",e=s)}return e},r._getItemStyleCache=void 0,r._getItemStyleCache=a(function(t,e,r){return{}}),r._onScrollHorizontal=function(t){var e=t.currentTarget,o=e.clientWidth,n=e.scrollLeft,i=e.scrollWidth;r.setState(function(t){if(t.scrollOffset===n)return null;var e=r.props.direction,a=n;if("rtl"===e)switch(d()){case"negative":a=-n;break;case"positive-descending":a=i-o-n}return a=Math.max(0,Math.min(a,i-o)),{isScrolling:!0,scrollDirection:t.scrollOffset<n?"forward":"backward",scrollOffset:a,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._onScrollVertical=function(t){var e=t.currentTarget,o=e.clientHeight,n=e.scrollHeight,i=e.scrollTop;r.setState(function(t){if(t.scrollOffset===i)return null;var e=Math.max(0,Math.min(i,n-o));return{isScrolling:!0,scrollDirection:t.scrollOffset<e?"forward":"backward",scrollOffset:e,scrollUpdateWasRequested:!1}},r._resetIsScrollingDebounced)},r._outerRefSetter=function(t){var e=r.props.outerRef;r._outerRef=t,"function"==typeof e?e(t):null!=e&&"object"==typeof e&&e.hasOwnProperty("current")&&(e.current=t)},r._resetIsScrollingDebounced=function(){null!==r._resetIsScrollingTimeoutId&&s(r._resetIsScrollingTimeoutId),r._resetIsScrollingTimeoutId=c(r._resetIsScrolling,R)},r._resetIsScrolling=function(){r._resetIsScrollingTimeoutId=null,r.setState({isScrolling:!1},function(){r._getItemStyleCache(-1,null)})},r}o(i,t),i.getDerivedStateFromProps=function(t,e){return O(t,e),I(t),null};var l=i.prototype;return l.scrollTo=function(t){t=Math.max(0,t),this.setState(function(e){return e.scrollOffset===t?null:{scrollDirection:e.scrollOffset<t?"forward":"backward",scrollOffset:t,scrollUpdateWasRequested:!0}},this._resetIsScrollingDebounced)},l.scrollToItem=function(t,e){void 0===e&&(e="auto");var r=this.props.itemCount,o=this.state.scrollOffset;t=Math.max(0,Math.min(t,r-1)),this.scrollTo(m(this.props,t,e,o,this._instanceProps))},l.componentDidMount=function(){var t=this.props,e=t.direction,r=t.initialScrollOffset,o=t.layout;if("number"==typeof r&&null!=this._outerRef){var n=this._outerRef;"horizontal"===e||"horizontal"===o?n.scrollLeft=r:n.scrollTop=r}this._callPropsCallbacks()},l.componentDidUpdate=function(){var t=this.props,e=t.direction,r=t.layout,o=this.state,n=o.scrollOffset;if(o.scrollUpdateWasRequested&&null!=this._outerRef){var i=this._outerRef;if("horizontal"===e||"horizontal"===r)if("rtl"===e)switch(d()){case"negative":i.scrollLeft=-n;break;case"positive-ascending":i.scrollLeft=n;break;default:var a=i.clientWidth,l=i.scrollWidth;i.scrollLeft=l-a-n}else i.scrollLeft=n;else i.scrollTop=n}this._callPropsCallbacks()},l.componentWillUnmount=function(){null!==this._resetIsScrollingTimeoutId&&s(this._resetIsScrollingTimeoutId)},l.render=function(){var t=this.props,o=t.children,n=t.className,i=t.direction,a=t.height,l=t.innerRef,s=t.innerElementType,c=t.innerTagName,u=t.itemCount,d=t.itemData,h=t.itemKey,m=void 0===h?y:h,p=t.layout,g=t.outerElementType,v=t.outerTagName,S=t.style,I=t.useIsScrolling,w=t.width,M=this.state.isScrolling,x="horizontal"===i||"horizontal"===p,_=x?this._onScrollHorizontal:this._onScrollVertical,C=this._getRangeToRender(),R=C[0],T=C[1],O=[];if(u>0)for(var z=R;z<=T;z++)O.push(e.createElement(o,{data:d,key:m(z,d),index:z,isScrolling:I?M:void 0,style:this._getItemStyle(z)}));var b=f(this.props,this._instanceProps);return e.createElement(g||v||"div",{className:n,onScroll:_,ref:this._outerRefSetter,style:r({position:"relative",height:a,width:w,overflow:"auto",WebkitOverflowScrolling:"touch",willChange:"transform",direction:i},S)},e.createElement(s||c||"div",{children:O,ref:l,style:{height:x?"100%":b,pointerEvents:M?"none":void 0,width:x?b:"100%"}}))},l._callPropsCallbacks=function(){if("function"==typeof this.props.onItemsRendered&&this.props.itemCount>0){var t=this._getRangeToRender(),e=t[0],r=t[1],o=t[2],n=t[3];this._callOnItemsRendered(e,r,o,n)}if("function"==typeof this.props.onScroll){var i=this.state,a=i.scrollDirection,l=i.scrollOffset,s=i.scrollUpdateWasRequested;this._callOnScroll(a,l,s)}},l._getRangeToRender=function(){var t=this.props,e=t.itemCount,r=t.overscanCount,o=this.state,n=o.isScrolling,i=o.scrollDirection,a=o.scrollOffset;if(0===e)return[0,0,0,0];var l=p(this.props,a,this._instanceProps),s=g(this.props,l,a,this._instanceProps),c=n&&"backward"!==i?1:Math.max(1,r),u=n&&"forward"!==i?1:Math.max(1,r);return[Math.max(0,l-c),Math.max(0,Math.min(e-1,s+u)),l,s]},i}(e.PureComponent),i.defaultProps={direction:"ltr",itemData:void 0,layout:"vertical",overscanCount:2,useIsScrolling:!1},l}var O=function(t,e){t.children,t.direction,t.height,t.layout,t.innerTagName,t.outerTagName,t.width,e.instance},z=function(t,e,r){var o=t.itemSize,n=r.itemMetadataMap,i=r.lastMeasuredIndex;if(e>i){var a=0;if(i>=0){var l=n[i];a=l.offset+l.size}for(var s=i+1;s<=e;s++){var c=o(s);n[s]={offset:a,size:c},a+=c}r.lastMeasuredIndex=e}return n[e]},b=function(t,e,r,o,n){for(;o<=r;){var i=o+Math.floor((r-o)/2),a=z(t,i,e).offset;if(a===n)return i;a<n?o=i+1:a>n&&(r=i-1)}return o>0?o-1:0},P=function(t,e,r,o){for(var n=t.itemCount,i=1;r<n&&z(t,r,e).offset<o;)r+=i,i*=2;return b(t,e,Math.min(r,n-1),Math.floor(r/2),o)},W=function(t,e){var r=t.itemCount,o=e.itemMetadataMap,n=e.estimatedItemSize,i=e.lastMeasuredIndex,a=0;if(i>=r&&(i=r-1),i>=0){var l=o[i];a=l.offset+l.size}return a+(r-i-1)*n},D=T({getItemOffset:function(t,e,r){return z(t,e,r).offset},getItemSize:function(t,e,r){return r.itemMetadataMap[e].size},getEstimatedTotalSize:W,getOffsetForIndexAndAlignment:function(t,e,r,o,n){var i=t.direction,a=t.height,l=t.layout,s=t.width,c="horizontal"===i||"horizontal"===l?s:a,u=z(t,e,n),f=W(t,n),d=Math.max(0,Math.min(f-c,u.offset)),h=Math.max(0,u.offset-c+u.size);switch("smart"===r&&(r=o>=h-c&&o<=d+c?"auto":"center"),r){case"start":return d;case"end":return h;case"center":return Math.round(h+(d-h)/2);case"auto":default:return o>=h&&o<=d?o:o<h?h:d}},getStartIndexForOffset:function(t,e,r){return function(t,e,r){var o=e.itemMetadataMap,n=e.lastMeasuredIndex;return(n>0?o[n].offset:0)>=r?b(t,e,n,0,r):P(t,e,Math.max(0,n),r)}(t,r,e)},getStopIndexForStartIndex:function(t,e,r,o){for(var n=t.direction,i=t.height,a=t.itemCount,l=t.layout,s=t.width,c="horizontal"===n||"horizontal"===l?s:i,u=z(t,e,o),f=r+c,d=u.offset+u.size,h=e;h<a-1&&d<f;)d+=z(t,++h,o).size;return h},initInstanceProps:function(t,e){var r={itemMetadataMap:{},estimatedItemSize:t.estimatedItemSize||50,lastMeasuredIndex:-1};return e.resetAfterIndex=function(t,o){void 0===o&&(o=!0),r.lastMeasuredIndex=Math.min(r.lastMeasuredIndex,t-1),e._getItemStyleCache(-1),o&&e.forceUpdate()},r},shouldResetStyleCacheOnItemSizeChange:!1,validateProps:function(t){t.itemSize}}),F=p({getColumnOffset:function(t,e){return e*t.columnWidth},getColumnWidth:function(t,e){return t.columnWidth},getRowOffset:function(t,e){return e*t.rowHeight},getRowHeight:function(t,e){return t.rowHeight},getEstimatedTotalHeight:function(t){var e=t.rowCount;return t.rowHeight*e},getEstimatedTotalWidth:function(t){var e=t.columnCount;return t.columnWidth*e},getOffsetForColumnAndAlignment:function(t,e,r,o,n,i){var a=t.columnCount,l=t.columnWidth,s=t.width,c=Math.max(0,a*l-s),u=Math.min(c,e*l),f=Math.max(0,e*l-s+i+l);switch("smart"===r&&(r=o>=f-s&&o<=u+s?"auto":"center"),r){case"start":return u;case"end":return f;case"center":var d=Math.round(f+(u-f)/2);return d<Math.ceil(s/2)?0:d>c+Math.floor(s/2)?c:d;case"auto":default:return o>=f&&o<=u?o:f>u?f:o<f?f:u}},getOffsetForRowAndAlignment:function(t,e,r,o,n,i){var a=t.rowHeight,l=t.height,s=t.rowCount,c=Math.max(0,s*a-l),u=Math.min(c,e*a),f=Math.max(0,e*a-l+i+a);switch("smart"===r&&(r=o>=f-l&&o<=u+l?"auto":"center"),r){case"start":return u;case"end":return f;case"center":var d=Math.round(f+(u-f)/2);return d<Math.ceil(l/2)?0:d>c+Math.floor(l/2)?c:d;case"auto":default:return o>=f&&o<=u?o:f>u?f:o<f?f:u}},getColumnStartIndexForOffset:function(t,e){var r=t.columnWidth,o=t.columnCount;return Math.max(0,Math.min(o-1,Math.floor(e/r)))},getColumnStopIndexForStartIndex:function(t,e,r){var o=t.columnWidth,n=t.columnCount,i=t.width,a=e*o,l=Math.ceil((i+r-a)/o);return Math.max(0,Math.min(n-1,e+l-1))},getRowStartIndexForOffset:function(t,e){var r=t.rowHeight,o=t.rowCount;return Math.max(0,Math.min(o-1,Math.floor(e/r)))},getRowStopIndexForStartIndex:function(t,e,r){var o=t.rowHeight,n=t.rowCount,i=t.height,a=e*o,l=Math.ceil((i+r-a)/o);return Math.max(0,Math.min(n-1,e+l-1))},initInstanceProps:function(t){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(t){t.columnWidth,t.rowHeight}}),L=T({getItemOffset:function(t,e){return e*t.itemSize},getItemSize:function(t,e){return t.itemSize},getEstimatedTotalSize:function(t){var e=t.itemCount;return t.itemSize*e},getOffsetForIndexAndAlignment:function(t,e,r,o){var n=t.direction,i=t.height,a=t.itemCount,l=t.itemSize,s=t.layout,c=t.width,u="horizontal"===n||"horizontal"===s?c:i,f=Math.max(0,a*l-u),d=Math.min(f,e*l),h=Math.max(0,e*l-u+l);switch("smart"===r&&(r=o>=h-u&&o<=d+u?"auto":"center"),r){case"start":return d;case"end":return h;case"center":var m=Math.round(h+(d-h)/2);return m<Math.ceil(u/2)?0:m>f+Math.floor(u/2)?f:m;case"auto":default:return o>=h&&o<=d?o:o<h?h:d}},getStartIndexForOffset:function(t,e){var r=t.itemCount,o=t.itemSize;return Math.max(0,Math.min(r-1,Math.floor(e/o)))},getStopIndexForStartIndex:function(t,e,r){var o=t.direction,n=t.height,i=t.itemCount,a=t.itemSize,l=t.layout,s=t.width,c=e*a,u="horizontal"===o||"horizontal"===l?s:n,f=Math.ceil((u+r-c)/a);return Math.max(0,Math.min(i-1,e+f-1))},initInstanceProps:function(t){},shouldResetStyleCacheOnItemSizeChange:!0,validateProps:function(t){t.itemSize}});function A(t,e){if(null==t)return{};var r,o,n={},i=Object.keys(t);for(o=0;o<i.length;o++)r=i[o],e.indexOf(r)>=0||(n[r]=t[r]);return n}function H(t,e){for(var r in t)if(!(r in e))return!0;for(var o in e)if(t[o]!==e[o])return!0;return!1}function k(t,e){var r=t.style,o=A(t,["style"]),n=e.style,i=A(e,["style"]);return!H(r,n)&&!H(o,i)}t.VariableSizeGrid=C,t.VariableSizeList=D,t.FixedSizeGrid=F,t.FixedSizeList=L,t.areEqual=k,t.shouldComponentUpdate=function(t,e){return!k(this.props,t)||H(this.state,e)},Object.defineProperty(t,"__esModule",{value:!0})});
2
+//# sourceMappingURL=index-prod.umd.js.map
vendor/react-window/dist/index.cjs.js
+247
-62
@@ -59,6 +59,50 @@ function getScrollbarSize(recalculate) {
59
60
return size;
61
}
62
+var cachedRTLResult = null; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
63
+// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
64
+// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
65
+// The safest way to check this is to intentionally set a negative offset,
66
+// and then verify that the subsequent "scroll" event matches the negative offset.
67
+// If it does not match, then we can assume a non-standard RTL scroll implementation.
68
+
69
+function getRTLOffsetType(recalculate) {
70
+ if (recalculate === void 0) {
71
+ recalculate = false;
72
+ }
73
+
74
+ if (cachedRTLResult === null || recalculate) {
75
+ var outerDiv = document.createElement('div');
76
+ var outerStyle = outerDiv.style;
77
+ outerStyle.width = '50px';
78
+ outerStyle.height = '50px';
79
+ outerStyle.overflow = 'scroll';
80
+ outerStyle.direction = 'rtl';
81
+ var innerDiv = document.createElement('div');
82
+ var innerStyle = innerDiv.style;
83
+ innerStyle.width = '100px';
84
+ innerStyle.height = '100px';
85
+ outerDiv.appendChild(innerDiv);
86
+ document.body.appendChild(outerDiv);
87
+
88
+ if (outerDiv.scrollLeft > 0) {
89
+ cachedRTLResult = 'positive-descending';
90
+ } else {
91
+ outerDiv.scrollLeft = 1;
92
+
93
+ if (outerDiv.scrollLeft === 0) {
94
+ cachedRTLResult = 'negative';
95
+ } else {
96
+ cachedRTLResult = 'positive-ascending';
97
+ }
98
+ }
99
+
100
+ document.body.removeChild(outerDiv);
101
+ return cachedRTLResult;
102
+ }
103
+
104
+ return cachedRTLResult;
105
+}
106
107
var IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
108
@@ -72,6 +116,7 @@ var defaultItemKey = function defaultItemKey(_ref) {
116
117
118
var devWarningsOverscanCount = null;
119
+var devWarningsOverscanRowsColumnsCount = null;
120
var devWarningsTagName = null;
121
122
if (process.env.NODE_ENV !== 'production') {
@@ -79,6 +124,9 @@ if (process.env.NODE_ENV !== 'production') {
124
devWarningsOverscanCount =
125
/*#__PURE__*/
126
new WeakSet();
127
+ devWarningsOverscanRowsColumnsCount =
128
+ /*#__PURE__*/
129
+ new WeakSet();
130
devWarningsTagName =
131
/*#__PURE__*/
132
new WeakSet();
@@ -183,9 +231,11 @@ function createGridComponent(_ref2) {
231
232
_this._onScroll = function (event) {
233
var _event$currentTarget = event.currentTarget,
234
+ clientHeight = _event$currentTarget.clientHeight,
235
clientWidth = _event$currentTarget.clientWidth,
236
scrollLeft = _event$currentTarget.scrollLeft,
237
scrollTop = _event$currentTarget.scrollTop,
238
+ scrollHeight = _event$currentTarget.scrollHeight,
239
scrollWidth = _event$currentTarget.scrollWidth;
240
241
_this.setState(function (prevState) {
@@ -196,25 +246,33 @@ function createGridComponent(_ref2) {
246
return null;
247
}
248
199
- var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
200
- // Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
201
- // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
249
+ var direction = _this.props.direction; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
250
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
251
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
252
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
253
254
var calculatedScrollLeft = scrollLeft;
255
256
if (direction === 'rtl') {
206
- if (scrollLeft <= 0) {
207
- calculatedScrollLeft = -scrollLeft;
208
- } else {
209
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
257
+ switch (getRTLOffsetType()) {
258
+ case 'negative':
259
+ calculatedScrollLeft = -scrollLeft;
260
+ break;
261
+
262
+ case 'positive-descending':
263
+ calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
264
+ break;
265
}
211
- }
266
+ } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
267
+
268
269
+ calculatedScrollLeft = Math.max(0, Math.min(calculatedScrollLeft, scrollWidth - clientWidth));
270
+ var calculatedScrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
271
return {
272
isScrolling: true,
273
horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
274
scrollLeft: calculatedScrollLeft,
217
- scrollTop: scrollTop,
275
+ scrollTop: calculatedScrollTop,
276
verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
277
scrollUpdateWasRequested: false
278
};
@@ -339,26 +397,55 @@ function createGridComponent(_ref2) {
397
initialScrollLeft = _this$props3.initialScrollLeft,
398
initialScrollTop = _this$props3.initialScrollTop;
399
342
- if (typeof initialScrollLeft === 'number' && this._outerRef != null) {
343
- this._outerRef.scrollLeft = initialScrollLeft;
344
- }
400
+ if (this._outerRef != null) {
401
+ var outerRef = this._outerRef;
402
+
403
+ if (typeof initialScrollLeft === 'number') {
404
+ outerRef.scrollLeft = initialScrollLeft;
405
+ }
406
346
- if (typeof initialScrollTop === 'number' && this._outerRef != null) {
347
- this._outerRef.scrollTop = initialScrollTop;
407
+ if (typeof initialScrollTop === 'number') {
408
+ outerRef.scrollTop = initialScrollTop;
409
+ }
410
}
411
412
this._callPropsCallbacks();
413
};
414
415
_proto.componentDidUpdate = function componentDidUpdate() {
416
+ var direction = this.props.direction;
417
var _this$state2 = this.state,
418
scrollLeft = _this$state2.scrollLeft,
419
scrollTop = _this$state2.scrollTop,
420
scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
421
359
- if (scrollUpdateWasRequested && this._outerRef !== null) {
360
- this._outerRef.scrollLeft = scrollLeft;
361
- this._outerRef.scrollTop = scrollTop;
422
+ if (scrollUpdateWasRequested && this._outerRef != null) {
423
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
424
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
425
+ // So we need to determine which browser behavior we're dealing with, and mimic it.
426
+ var outerRef = this._outerRef;
427
+
428
+ if (direction === 'rtl') {
429
+ switch (getRTLOffsetType()) {
430
+ case 'negative':
431
+ outerRef.scrollLeft = -scrollLeft;
432
+ break;
433
+
434
+ case 'positive-ascending':
435
+ outerRef.scrollLeft = scrollLeft;
436
+ break;
437
+
438
+ default:
439
+ var clientWidth = outerRef.clientWidth,
440
+ scrollWidth = outerRef.scrollWidth;
441
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
442
+ break;
443
+ }
444
+ } else {
445
+ outerRef.scrollLeft = Math.max(0, scrollLeft);
446
+ }
447
+
448
+ outerRef.scrollTop = Math.max(0, scrollTop);
449
}
450
451
this._callPropsCallbacks();
@@ -442,7 +529,7 @@ function createGridComponent(_ref2) {
529
ref: innerRef,
530
style: {
531
height: estimatedTotalHeight,
445
- pointerEvents: isScrolling ? 'none' : '',
532
+ pointerEvents: isScrolling ? 'none' : undefined,
533
width: estimatedTotalWidth
534
}
535
}));
@@ -492,6 +579,7 @@ function createGridComponent(_ref2) {
579
_proto._getHorizontalRangeToRender = function _getHorizontalRangeToRender() {
580
var _this$props6 = this.props,
581
columnCount = _this$props6.columnCount,
582
+ overscanColumnCount = _this$props6.overscanColumnCount,
583
overscanColumnsCount = _this$props6.overscanColumnsCount,
584
overscanCount = _this$props6.overscanCount,
585
rowCount = _this$props6.rowCount;
@@ -499,7 +587,7 @@ function createGridComponent(_ref2) {
587
horizontalScrollDirection = _this$state4.horizontalScrollDirection,
588
isScrolling = _this$state4.isScrolling,
589
scrollLeft = _this$state4.scrollLeft;
502
- var overscanCountResolved = overscanColumnsCount || overscanCount || 1;
590
+ var overscanCountResolved = overscanColumnCount || overscanColumnsCount || overscanCount || 1;
591
592
if (columnCount === 0 || rowCount === 0) {
593
return [0, 0, 0, 0];
@@ -518,13 +606,14 @@ function createGridComponent(_ref2) {
606
var _this$props7 = this.props,
607
columnCount = _this$props7.columnCount,
608
overscanCount = _this$props7.overscanCount,
609
+ overscanRowCount = _this$props7.overscanRowCount,
610
overscanRowsCount = _this$props7.overscanRowsCount,
611
rowCount = _this$props7.rowCount;
612
var _this$state5 = this.state,
613
isScrolling = _this$state5.isScrolling,
614
verticalScrollDirection = _this$state5.verticalScrollDirection,
615
scrollTop = _this$state5.scrollTop;
527
- var overscanCountResolved = overscanRowsCount || overscanCount || 1;
616
+ var overscanCountResolved = overscanRowCount || overscanRowsCount || overscanCount || 1;
617
618
if (columnCount === 0 || rowCount === 0) {
619
return [0, 0, 0, 0];
@@ -553,7 +642,9 @@ var validateSharedProps = function validateSharedProps(_ref5, _ref6) {
642
height = _ref5.height,
643
innerTagName = _ref5.innerTagName,
644
outerTagName = _ref5.outerTagName,
645
+ overscanColumnsCount = _ref5.overscanColumnsCount,
646
overscanCount = _ref5.overscanCount,
647
+ overscanRowsCount = _ref5.overscanRowsCount,
648
width = _ref5.width;
649
var instance = _ref6.instance;
650
@@ -561,7 +652,14 @@ var validateSharedProps = function validateSharedProps(_ref5, _ref6) {
652
if (typeof overscanCount === 'number') {
653
if (devWarningsOverscanCount && !devWarningsOverscanCount.has(instance)) {
654
devWarningsOverscanCount.add(instance);
564
- console.warn('The overscanCount prop has been deprecated. ' + 'Please use the overscanColumnsCount and overscanRowsCount props instead.');
655
+ console.warn('The overscanCount prop has been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
656
+ }
657
+ }
658
+
659
+ if (typeof overscanColumnsCount === 'number' || typeof overscanRowsCount === 'number') {
660
+ if (devWarningsOverscanRowsColumnsCount && !devWarningsOverscanRowsColumnsCount.has(instance)) {
661
+ devWarningsOverscanRowsColumnsCount.add(instance);
662
+ console.warn('The overscanColumnsCount and overscanRowsCount props have been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
663
}
664
}
665
@@ -770,7 +868,11 @@ var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemT
868
default:
869
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
870
return scrollOffset;
773
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
871
+ } else if (minOffset > maxOffset) {
872
+ // Because we only take into account the scrollbar size when calculating minOffset
873
+ // this value can be larger than maxOffset when at the end of the list
874
+ return minOffset;
875
+ } else if (scrollOffset < minOffset) {
876
return minOffset;
877
} else {
878
return maxOffset;
@@ -1037,20 +1139,27 @@ function createListComponent(_ref) {
1139
return null;
1140
}
1141
1040
- var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
1041
- // Chrome does not seem to adhere; its scrolLeft values are positive (measured relative to the left).
1042
- // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
1043
-
1142
+ var direction = _this.props.direction;
1143
var scrollOffset = scrollLeft;
1144
1145
if (direction === 'rtl') {
1047
- if (scrollLeft <= 0) {
1048
- scrollOffset = -scrollOffset;
1049
- } else {
1050
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
1146
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1147
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1148
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
1149
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
1150
+ switch (getRTLOffsetType()) {
1151
+ case 'negative':
1152
+ scrollOffset = -scrollLeft;
1153
+ break;
1154
+
1155
+ case 'positive-descending':
1156
+ scrollOffset = scrollWidth - clientWidth - scrollLeft;
1157
+ break;
1158
}
1052
- }
1159
+ } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1160
+
1161
1162
+ scrollOffset = Math.max(0, Math.min(scrollOffset, scrollWidth - clientWidth));
1163
return {
1164
isScrolling: true,
1165
scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
@@ -1061,7 +1170,10 @@ function createListComponent(_ref) {
1170
};
1171
1172
_this._onScrollVertical = function (event) {
1064
- var scrollTop = event.currentTarget.scrollTop;
1173
+ var _event$currentTarget2 = event.currentTarget,
1174
+ clientHeight = _event$currentTarget2.clientHeight,
1175
+ scrollHeight = _event$currentTarget2.scrollHeight,
1176
+ scrollTop = _event$currentTarget2.scrollTop;
1177
1178
_this.setState(function (prevState) {
1179
if (prevState.scrollOffset === scrollTop) {
@@ -1069,12 +1181,14 @@ function createListComponent(_ref) {
1181
// In which case we don't need to trigger another render,
1182
// And we don't want to update state.isScrolling.
1183
return null;
1072
- }
1184
+ } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1185
1186
+
1187
+ var scrollOffset = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
1188
return {
1189
isScrolling: true,
1076
- scrollDirection: prevState.scrollOffset < scrollTop ? 'forward' : 'backward',
1077
- scrollOffset: scrollTop,
1190
+ scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
1191
+ scrollOffset: scrollOffset,
1192
scrollUpdateWasRequested: false
1193
};
1194
}, _this._resetIsScrollingDebounced);
@@ -1154,12 +1268,13 @@ function createListComponent(_ref) {
1268
initialScrollOffset = _this$props2.initialScrollOffset,
1269
layout = _this$props2.layout;
1270
1157
- if (typeof initialScrollOffset === 'number' && this._outerRef !== null) {
1158
- // TODO Deprecate direction "horizontal"
1271
+ if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
1272
+ var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1273
+
1274
if (direction === 'horizontal' || layout === 'horizontal') {
1160
- this._outerRef.scrollLeft = initialScrollOffset;
1275
+ outerRef.scrollLeft = initialScrollOffset;
1276
} else {
1162
- this._outerRef.scrollTop = initialScrollOffset;
1277
+ outerRef.scrollTop = initialScrollOffset;
1278
}
1279
}
1280
@@ -1174,12 +1289,34 @@ function createListComponent(_ref) {
1289
scrollOffset = _this$state.scrollOffset,
1290
scrollUpdateWasRequested = _this$state.scrollUpdateWasRequested;
1291
1177
- if (scrollUpdateWasRequested && this._outerRef !== null) {
1178
- // TODO Deprecate direction "horizontal"
1292
+ if (scrollUpdateWasRequested && this._outerRef != null) {
1293
+ var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1294
+
1295
if (direction === 'horizontal' || layout === 'horizontal') {
1180
- this._outerRef.scrollLeft = scrollOffset;
1296
+ if (direction === 'rtl') {
1297
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1298
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1299
+ // So we need to determine which browser behavior we're dealing with, and mimic it.
1300
+ switch (getRTLOffsetType()) {
1301
+ case 'negative':
1302
+ outerRef.scrollLeft = -scrollOffset;
1303
+ break;
1304
+
1305
+ case 'positive-ascending':
1306
+ outerRef.scrollLeft = scrollOffset;
1307
+ break;
1308
+
1309
+ default:
1310
+ var clientWidth = outerRef.clientWidth,
1311
+ scrollWidth = outerRef.scrollWidth;
1312
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
1313
+ break;
1314
+ }
1315
+ } else {
1316
+ outerRef.scrollLeft = scrollOffset;
1317
+ }
1318
} else {
1182
- this._outerRef.scrollTop = scrollOffset;
1319
+ outerRef.scrollTop = scrollOffset;
1320
}
1321
}
1322
@@ -1255,7 +1392,7 @@ function createListComponent(_ref) {
1392
ref: innerRef,
1393
style: {
1394
height: isHorizontal ? '100%' : estimatedTotalSize,
1258
- pointerEvents: isScrolling ? 'none' : '',
1395
+ pointerEvents: isScrolling ? 'none' : undefined,
1396
width: isHorizontal ? estimatedTotalSize : '100%'
1397
}
1398
}));
@@ -1537,7 +1674,7 @@ createListComponent({
1674
default:
1675
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1676
return scrollOffset;
1540
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
1677
+ } else if (scrollOffset < minOffset) {
1678
return minOffset;
1679
} else {
1680
return maxOffset;
@@ -1642,7 +1779,8 @@ createGridComponent({
1779
var columnCount = _ref7.columnCount,
1780
columnWidth = _ref7.columnWidth,
1781
width = _ref7.width;
1645
- var maxOffset = Math.max(0, Math.min(columnCount * columnWidth - width, columnIndex * columnWidth));
1782
+ var lastColumnOffset = Math.max(0, columnCount * columnWidth - width);
1783
+ var maxOffset = Math.min(lastColumnOffset, columnIndex * columnWidth);
1784
var minOffset = Math.max(0, columnIndex * columnWidth - width + scrollbarSize + columnWidth);
1785
1786
if (align === 'smart') {
@@ -1661,13 +1799,27 @@ createGridComponent({
1799
return minOffset;
1800
1801
case 'center':
1664
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1802
+ // "Centered" offset is usually the average of the min and max.
1803
+ // But near the edges of the list, this doesn't hold true.
1804
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1805
+
1806
+ if (middleOffset < Math.ceil(width / 2)) {
1807
+ return 0; // near the beginning
1808
+ } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
1809
+ return lastColumnOffset; // near the end
1810
+ } else {
1811
+ return middleOffset;
1812
+ }
1813
1814
case 'auto':
1815
default:
1816
if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
1817
return scrollLeft;
1670
- } else if (scrollLeft - minOffset < maxOffset - scrollLeft) {
1818
+ } else if (minOffset > maxOffset) {
1819
+ // Because we only take into account the scrollbar size when calculating minOffset
1820
+ // this value can be larger than maxOffset when at the end of the list
1821
+ return minOffset;
1822
+ } else if (scrollLeft < minOffset) {
1823
return minOffset;
1824
} else {
1825
return maxOffset;
@@ -1679,7 +1831,8 @@ createGridComponent({
1831
var rowHeight = _ref8.rowHeight,
1832
height = _ref8.height,
1833
rowCount = _ref8.rowCount;
1682
- var maxOffset = Math.max(0, Math.min(rowCount * rowHeight - height, rowIndex * rowHeight));
1834
+ var lastRowOffset = Math.max(0, rowCount * rowHeight - height);
1835
+ var maxOffset = Math.min(lastRowOffset, rowIndex * rowHeight);
1836
var minOffset = Math.max(0, rowIndex * rowHeight - height + scrollbarSize + rowHeight);
1837
1838
if (align === 'smart') {
@@ -1698,13 +1851,27 @@ createGridComponent({
1851
return minOffset;
1852
1853
case 'center':
1701
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1854
+ // "Centered" offset is usually the average of the min and max.
1855
+ // But near the edges of the list, this doesn't hold true.
1856
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1857
+
1858
+ if (middleOffset < Math.ceil(height / 2)) {
1859
+ return 0; // near the beginning
1860
+ } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
1861
+ return lastRowOffset; // near the end
1862
+ } else {
1863
+ return middleOffset;
1864
+ }
1865
1866
case 'auto':
1867
default:
1868
if (scrollTop >= minOffset && scrollTop <= maxOffset) {
1869
return scrollTop;
1707
- } else if (scrollTop - minOffset < maxOffset - scrollTop) {
1870
+ } else if (minOffset > maxOffset) {
1871
+ // Because we only take into account the scrollbar size when calculating minOffset
1872
+ // this value can be larger than maxOffset when at the end of the list
1873
+ return minOffset;
1874
+ } else if (scrollTop < minOffset) {
1875
return minOffset;
1876
} else {
1877
return maxOffset;
@@ -1722,7 +1889,9 @@ createGridComponent({
1889
columnCount = _ref10.columnCount,
1890
width = _ref10.width;
1891
var left = startIndex * columnWidth;
1725
- return Math.max(0, Math.min(columnCount - 1, startIndex + Math.floor((width + (scrollLeft - left)) / columnWidth)));
1892
+ var numVisibleColumns = Math.ceil((width + scrollLeft - left) / columnWidth);
1893
+ return Math.max(0, Math.min(columnCount - 1, startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
1894
+ ));
1895
},
1896
getRowStartIndexForOffset: function getRowStartIndexForOffset(_ref11, scrollTop) {
1897
var rowHeight = _ref11.rowHeight,
@@ -1733,8 +1902,10 @@ createGridComponent({
1902
var rowHeight = _ref12.rowHeight,
1903
rowCount = _ref12.rowCount,
1904
height = _ref12.height;
1736
- var left = startIndex * rowHeight;
1737
- return Math.max(0, Math.min(rowCount - 1, startIndex + Math.floor((height + (scrollTop - left)) / rowHeight)));
1905
+ var top = startIndex * rowHeight;
1906
+ var numVisibleRows = Math.ceil((height + scrollTop - top) / rowHeight);
1907
+ return Math.max(0, Math.min(rowCount - 1, startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
1908
+ ));
1909
},
1910
initInstanceProps: function initInstanceProps(props) {// Noop
1911
},
@@ -1759,13 +1930,11 @@ var FixedSizeList =
1930
/*#__PURE__*/
1931
createListComponent({
1932
getItemOffset: function getItemOffset(_ref, index) {
1762
- var itemSize = _ref.itemSize,
1763
- size = _ref.size;
1933
+ var itemSize = _ref.itemSize;
1934
return index * itemSize;
1935
},
1936
getItemSize: function getItemSize(_ref2, index) {
1767
- var itemSize = _ref2.itemSize,
1768
- size = _ref2.size;
1937
+ var itemSize = _ref2.itemSize;
1938
return itemSize;
1939
},
1940
getEstimatedTotalSize: function getEstimatedTotalSize(_ref3) {
@@ -1783,7 +1952,8 @@ createListComponent({
1952
// TODO Deprecate direction "horizontal"
1953
var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1954
var size = isHorizontal ? width : height;
1786
- var maxOffset = Math.max(0, Math.min(itemCount * itemSize - size, index * itemSize));
1955
+ var lastItemOffset = Math.max(0, itemCount * itemSize - size);
1956
+ var maxOffset = Math.min(lastItemOffset, index * itemSize);
1957
var minOffset = Math.max(0, index * itemSize - size + itemSize);
1958
1959
if (align === 'smart') {
@@ -1802,13 +1972,25 @@ createListComponent({
1972
return minOffset;
1973
1974
case 'center':
1805
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1975
+ {
1976
+ // "Centered" offset is usually the average of the min and max.
1977
+ // But near the edges of the list, this doesn't hold true.
1978
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1979
+
1980
+ if (middleOffset < Math.ceil(size / 2)) {
1981
+ return 0; // near the beginning
1982
+ } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
1983
+ return lastItemOffset; // near the end
1984
+ } else {
1985
+ return middleOffset;
1986
+ }
1987
+ }
1988
1989
case 'auto':
1990
default:
1991
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1992
return scrollOffset;
1811
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
1993
+ } else if (scrollOffset < minOffset) {
1994
return minOffset;
1995
} else {
1996
return maxOffset;
@@ -1832,7 +2014,9 @@ createListComponent({
2014
var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
2015
var offset = startIndex * itemSize;
2016
var size = isHorizontal ? width : height;
1835
- return Math.max(0, Math.min(itemCount - 1, startIndex + Math.floor((size + (scrollOffset - offset)) / itemSize)));
2017
+ var numVisibleItems = Math.ceil((size + scrollOffset - offset) / itemSize);
2018
+ return Math.max(0, Math.min(itemCount - 1, startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
2019
+ ));
2020
},
2021
initInstanceProps: function initInstanceProps(props) {// Noop
2022
},
@@ -1892,3 +2076,4 @@ exports.FixedSizeGrid = FixedSizeGrid;
2076
exports.FixedSizeList = FixedSizeList;
2077
exports.areEqual = areEqual;
2078
exports.shouldComponentUpdate = shouldComponentUpdate;
2079
+//# sourceMappingURL=index.cjs.js.map
vendor/react-window/dist/index.esm.js
+251
-66
@@ -54,6 +54,50 @@ function getScrollbarSize(recalculate) {
54
55
return size;
56
}
57
+var cachedRTLResult = null; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
58
+// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
59
+// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
60
+// The safest way to check this is to intentionally set a negative offset,
61
+// and then verify that the subsequent "scroll" event matches the negative offset.
62
+// If it does not match, then we can assume a non-standard RTL scroll implementation.
63
+
64
+function getRTLOffsetType(recalculate) {
65
+ if (recalculate === void 0) {
66
+ recalculate = false;
67
+ }
68
+
69
+ if (cachedRTLResult === null || recalculate) {
70
+ var outerDiv = document.createElement('div');
71
+ var outerStyle = outerDiv.style;
72
+ outerStyle.width = '50px';
73
+ outerStyle.height = '50px';
74
+ outerStyle.overflow = 'scroll';
75
+ outerStyle.direction = 'rtl';
76
+ var innerDiv = document.createElement('div');
77
+ var innerStyle = innerDiv.style;
78
+ innerStyle.width = '100px';
79
+ innerStyle.height = '100px';
80
+ outerDiv.appendChild(innerDiv);
81
+ document.body.appendChild(outerDiv);
82
+
83
+ if (outerDiv.scrollLeft > 0) {
84
+ cachedRTLResult = 'positive-descending';
85
+ } else {
86
+ outerDiv.scrollLeft = 1;
87
+
88
+ if (outerDiv.scrollLeft === 0) {
89
+ cachedRTLResult = 'negative';
90
+ } else {
91
+ cachedRTLResult = 'positive-ascending';
92
+ }
93
+ }
94
+
95
+ document.body.removeChild(outerDiv);
96
+ return cachedRTLResult;
97
+ }
98
+
99
+ return cachedRTLResult;
100
+}
101
102
var IS_SCROLLING_DEBOUNCE_INTERVAL = 150;
103
@@ -67,6 +111,7 @@ var defaultItemKey = function defaultItemKey(_ref) {
111
112
113
var devWarningsOverscanCount = null;
114
+var devWarningsOverscanRowsColumnsCount = null;
115
var devWarningsTagName = null;
116
117
if (process.env.NODE_ENV !== 'production') {
@@ -74,6 +119,9 @@ if (process.env.NODE_ENV !== 'production') {
119
devWarningsOverscanCount =
120
/*#__PURE__*/
121
new WeakSet();
122
+ devWarningsOverscanRowsColumnsCount =
123
+ /*#__PURE__*/
124
+ new WeakSet();
125
devWarningsTagName =
126
/*#__PURE__*/
127
new WeakSet();
@@ -178,9 +226,11 @@ function createGridComponent(_ref2) {
226
227
_this._onScroll = function (event) {
228
var _event$currentTarget = event.currentTarget,
229
+ clientHeight = _event$currentTarget.clientHeight,
230
clientWidth = _event$currentTarget.clientWidth,
231
scrollLeft = _event$currentTarget.scrollLeft,
232
scrollTop = _event$currentTarget.scrollTop,
233
+ scrollHeight = _event$currentTarget.scrollHeight,
234
scrollWidth = _event$currentTarget.scrollWidth;
235
236
// Force flush sync for scroll updates to reduce visual checkerboarding.
@@ -193,25 +243,33 @@ function createGridComponent(_ref2) {
243
return null;
244
}
245
196
- var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
197
- // Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
198
- // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
246
+ var direction = _this.props.direction; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
247
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
248
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
249
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
250
251
var calculatedScrollLeft = scrollLeft;
252
253
if (direction === 'rtl') {
203
- if (scrollLeft <= 0) {
204
- calculatedScrollLeft = -scrollLeft;
205
- } else {
206
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
254
+ switch (getRTLOffsetType()) {
255
+ case 'negative':
256
+ calculatedScrollLeft = -scrollLeft;
257
+ break;
258
+
259
+ case 'positive-descending':
260
+ calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
261
+ break;
262
}
208
- }
263
+ } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
264
+
265
266
+ calculatedScrollLeft = Math.max(0, Math.min(calculatedScrollLeft, scrollWidth - clientWidth));
267
+ var calculatedScrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
268
return {
269
isScrolling: true,
270
horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
271
scrollLeft: calculatedScrollLeft,
214
- scrollTop: scrollTop,
272
+ scrollTop: calculatedScrollTop,
273
verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
274
scrollUpdateWasRequested: false
275
};
@@ -337,26 +395,55 @@ function createGridComponent(_ref2) {
395
initialScrollLeft = _this$props3.initialScrollLeft,
396
initialScrollTop = _this$props3.initialScrollTop;
397
340
- if (typeof initialScrollLeft === 'number' && this._outerRef != null) {
341
- this._outerRef.scrollLeft = initialScrollLeft;
342
- }
398
+ if (this._outerRef != null) {
399
+ var outerRef = this._outerRef;
400
344
- if (typeof initialScrollTop === 'number' && this._outerRef != null) {
345
- this._outerRef.scrollTop = initialScrollTop;
401
+ if (typeof initialScrollLeft === 'number') {
402
+ outerRef.scrollLeft = initialScrollLeft;
403
+ }
404
+
405
+ if (typeof initialScrollTop === 'number') {
406
+ outerRef.scrollTop = initialScrollTop;
407
+ }
408
}
409
410
this._callPropsCallbacks();
411
};
412
413
_proto.componentDidUpdate = function componentDidUpdate() {
414
+ var direction = this.props.direction;
415
var _this$state2 = this.state,
416
scrollLeft = _this$state2.scrollLeft,
417
scrollTop = _this$state2.scrollTop,
418
scrollUpdateWasRequested = _this$state2.scrollUpdateWasRequested;
419
357
- if (scrollUpdateWasRequested && this._outerRef !== null) {
358
- this._outerRef.scrollLeft = scrollLeft;
359
- this._outerRef.scrollTop = scrollTop;
420
+ if (scrollUpdateWasRequested && this._outerRef != null) {
421
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
422
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
423
+ // So we need to determine which browser behavior we're dealing with, and mimic it.
424
+ var outerRef = this._outerRef;
425
+
426
+ if (direction === 'rtl') {
427
+ switch (getRTLOffsetType()) {
428
+ case 'negative':
429
+ outerRef.scrollLeft = -scrollLeft;
430
+ break;
431
+
432
+ case 'positive-ascending':
433
+ outerRef.scrollLeft = scrollLeft;
434
+ break;
435
+
436
+ default:
437
+ var clientWidth = outerRef.clientWidth,
438
+ scrollWidth = outerRef.scrollWidth;
439
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
440
+ break;
441
+ }
442
+ } else {
443
+ outerRef.scrollLeft = Math.max(0, scrollLeft);
444
+ }
445
+
446
+ outerRef.scrollTop = Math.max(0, scrollTop);
447
}
448
449
this._callPropsCallbacks();
@@ -440,7 +527,7 @@ function createGridComponent(_ref2) {
527
ref: innerRef,
528
style: {
529
height: estimatedTotalHeight,
443
- pointerEvents: isScrolling ? 'none' : '',
530
+ pointerEvents: isScrolling ? 'none' : undefined,
531
width: estimatedTotalWidth
532
}
533
}));
@@ -490,6 +577,7 @@ function createGridComponent(_ref2) {
577
_proto._getHorizontalRangeToRender = function _getHorizontalRangeToRender() {
578
var _this$props6 = this.props,
579
columnCount = _this$props6.columnCount,
580
+ overscanColumnCount = _this$props6.overscanColumnCount,
581
overscanColumnsCount = _this$props6.overscanColumnsCount,
582
overscanCount = _this$props6.overscanCount,
583
rowCount = _this$props6.rowCount;
@@ -497,7 +585,7 @@ function createGridComponent(_ref2) {
585
horizontalScrollDirection = _this$state4.horizontalScrollDirection,
586
isScrolling = _this$state4.isScrolling,
587
scrollLeft = _this$state4.scrollLeft;
500
- var overscanCountResolved = overscanColumnsCount || overscanCount || 1;
588
+ var overscanCountResolved = overscanColumnCount || overscanColumnsCount || overscanCount || 1;
589
590
if (columnCount === 0 || rowCount === 0) {
591
return [0, 0, 0, 0];
@@ -516,13 +604,14 @@ function createGridComponent(_ref2) {
604
var _this$props7 = this.props,
605
columnCount = _this$props7.columnCount,
606
overscanCount = _this$props7.overscanCount,
607
+ overscanRowCount = _this$props7.overscanRowCount,
608
overscanRowsCount = _this$props7.overscanRowsCount,
609
rowCount = _this$props7.rowCount;
610
var _this$state5 = this.state,
611
isScrolling = _this$state5.isScrolling,
612
verticalScrollDirection = _this$state5.verticalScrollDirection,
613
scrollTop = _this$state5.scrollTop;
525
- var overscanCountResolved = overscanRowsCount || overscanCount || 1;
614
+ var overscanCountResolved = overscanRowCount || overscanRowsCount || overscanCount || 1;
615
616
if (columnCount === 0 || rowCount === 0) {
617
return [0, 0, 0, 0];
@@ -551,7 +640,9 @@ var validateSharedProps = function validateSharedProps(_ref5, _ref6) {
640
height = _ref5.height,
641
innerTagName = _ref5.innerTagName,
642
outerTagName = _ref5.outerTagName,
643
+ overscanColumnsCount = _ref5.overscanColumnsCount,
644
overscanCount = _ref5.overscanCount,
645
+ overscanRowsCount = _ref5.overscanRowsCount,
646
width = _ref5.width;
647
var instance = _ref6.instance;
648
@@ -559,7 +650,14 @@ var validateSharedProps = function validateSharedProps(_ref5, _ref6) {
650
if (typeof overscanCount === 'number') {
651
if (devWarningsOverscanCount && !devWarningsOverscanCount.has(instance)) {
652
devWarningsOverscanCount.add(instance);
562
- console.warn('The overscanCount prop has been deprecated. ' + 'Please use the overscanColumnsCount and overscanRowsCount props instead.');
653
+ console.warn('The overscanCount prop has been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
654
+ }
655
+ }
656
+
657
+ if (typeof overscanColumnsCount === 'number' || typeof overscanRowsCount === 'number') {
658
+ if (devWarningsOverscanRowsColumnsCount && !devWarningsOverscanRowsColumnsCount.has(instance)) {
659
+ devWarningsOverscanRowsColumnsCount.add(instance);
660
+ console.warn('The overscanColumnsCount and overscanRowsCount props have been deprecated. ' + 'Please use the overscanColumnCount and overscanRowCount props instead.');
661
}
662
}
663
@@ -768,7 +866,11 @@ var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemT
866
default:
867
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
868
return scrollOffset;
771
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
869
+ } else if (minOffset > maxOffset) {
870
+ // Because we only take into account the scrollbar size when calculating minOffset
871
+ // this value can be larger than maxOffset when at the end of the list
872
+ return minOffset;
873
+ } else if (scrollOffset < minOffset) {
874
return minOffset;
875
} else {
876
return maxOffset;
@@ -1037,20 +1139,27 @@ function createListComponent(_ref) {
1139
return null;
1140
}
1141
1040
- var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
1041
- // Chrome does not seem to adhere; its scrolLeft values are positive (measured relative to the left).
1042
- // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
1043
-
1142
+ var direction = _this.props.direction;
1143
var scrollOffset = scrollLeft;
1144
1145
if (direction === 'rtl') {
1047
- if (scrollLeft <= 0) {
1048
- scrollOffset = -scrollOffset;
1049
- } else {
1050
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
1146
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1147
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1148
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
1149
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
1150
+ switch (getRTLOffsetType()) {
1151
+ case 'negative':
1152
+ scrollOffset = -scrollLeft;
1153
+ break;
1154
+
1155
+ case 'positive-descending':
1156
+ scrollOffset = scrollWidth - clientWidth - scrollLeft;
1157
+ break;
1158
}
1052
- }
1159
+ } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1160
1161
+
1162
+ scrollOffset = Math.max(0, Math.min(scrollOffset, scrollWidth - clientWidth));
1163
return {
1164
isScrolling: true,
1165
scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
@@ -1058,11 +1167,14 @@ function createListComponent(_ref) {
1167
scrollUpdateWasRequested: false
1168
};
1169
}, _this._resetIsScrollingDebounced);
1061
- });
1062
- };
1170
+ };
1171
+ });
1172
1173
_this._onScrollVertical = function (event) {
1065
- var scrollTop = event.currentTarget.scrollTop;
1174
+ var _event$currentTarget2 = event.currentTarget,
1175
+ clientHeight = _event$currentTarget2.clientHeight,
1176
+ scrollHeight = _event$currentTarget2.scrollHeight,
1177
+ scrollTop = _event$currentTarget2.scrollTop;
1178
1179
// Force flush sync for scroll updates to reduce visual checkerboarding.
1180
flushSync(() => {
@@ -1072,17 +1184,19 @@ function createListComponent(_ref) {
1184
// In which case we don't need to trigger another render,
1185
// And we don't want to update state.isScrolling.
1186
return null;
1075
- }
1187
+ } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1188
1189
+
1190
+ var scrollOffset = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight));
1191
return {
1192
isScrolling: true,
1079
- scrollDirection: prevState.scrollOffset < scrollTop ? 'forward' : 'backward',
1080
- scrollOffset: scrollTop,
1193
+ scrollDirection: prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
1194
+ scrollOffset: scrollOffset,
1195
scrollUpdateWasRequested: false
1196
};
1197
}, _this._resetIsScrollingDebounced);
1084
- });
1085
- };
1198
+ };
1199
+ });
1200
1201
_this._outerRefSetter = function (ref) {
1202
var outerRef = _this.props.outerRef;
@@ -1158,12 +1272,13 @@ function createListComponent(_ref) {
1272
initialScrollOffset = _this$props2.initialScrollOffset,
1273
layout = _this$props2.layout;
1274
1161
- if (typeof initialScrollOffset === 'number' && this._outerRef !== null) {
1162
- // TODO Deprecate direction "horizontal"
1275
+ if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
1276
+ var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1277
+
1278
if (direction === 'horizontal' || layout === 'horizontal') {
1164
- this._outerRef.scrollLeft = initialScrollOffset;
1279
+ outerRef.scrollLeft = initialScrollOffset;
1280
} else {
1166
- this._outerRef.scrollTop = initialScrollOffset;
1281
+ outerRef.scrollTop = initialScrollOffset;
1282
}
1283
}
1284
@@ -1178,12 +1293,34 @@ function createListComponent(_ref) {
1293
scrollOffset = _this$state.scrollOffset,
1294
scrollUpdateWasRequested = _this$state.scrollUpdateWasRequested;
1295
1181
- if (scrollUpdateWasRequested && this._outerRef !== null) {
1182
- // TODO Deprecate direction "horizontal"
1296
+ if (scrollUpdateWasRequested && this._outerRef != null) {
1297
+ var outerRef = this._outerRef; // TODO Deprecate direction "horizontal"
1298
+
1299
if (direction === 'horizontal' || layout === 'horizontal') {
1184
- this._outerRef.scrollLeft = scrollOffset;
1300
+ if (direction === 'rtl') {
1301
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1302
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1303
+ // So we need to determine which browser behavior we're dealing with, and mimic it.
1304
+ switch (getRTLOffsetType()) {
1305
+ case 'negative':
1306
+ outerRef.scrollLeft = -scrollOffset;
1307
+ break;
1308
+
1309
+ case 'positive-ascending':
1310
+ outerRef.scrollLeft = scrollOffset;
1311
+ break;
1312
+
1313
+ default:
1314
+ var clientWidth = outerRef.clientWidth,
1315
+ scrollWidth = outerRef.scrollWidth;
1316
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
1317
+ break;
1318
+ }
1319
+ } else {
1320
+ outerRef.scrollLeft = scrollOffset;
1321
+ }
1322
} else {
1186
- this._outerRef.scrollTop = scrollOffset;
1323
+ outerRef.scrollTop = scrollOffset;
1324
}
1325
}
1326
@@ -1259,7 +1396,7 @@ function createListComponent(_ref) {
1396
ref: innerRef,
1397
style: {
1398
height: isHorizontal ? '100%' : estimatedTotalSize,
1262
- pointerEvents: isScrolling ? 'none' : '',
1399
+ pointerEvents: isScrolling ? 'none' : undefined,
1400
width: isHorizontal ? estimatedTotalSize : '100%'
1401
}
1402
}));
@@ -1541,7 +1678,7 @@ createListComponent({
1678
default:
1679
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1680
return scrollOffset;
1544
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
1681
+ } else if (scrollOffset < minOffset) {
1682
return minOffset;
1683
} else {
1684
return maxOffset;
@@ -1646,7 +1783,8 @@ createGridComponent({
1783
var columnCount = _ref7.columnCount,
1784
columnWidth = _ref7.columnWidth,
1785
width = _ref7.width;
1649
- var maxOffset = Math.max(0, Math.min(columnCount * columnWidth - width, columnIndex * columnWidth));
1786
+ var lastColumnOffset = Math.max(0, columnCount * columnWidth - width);
1787
+ var maxOffset = Math.min(lastColumnOffset, columnIndex * columnWidth);
1788
var minOffset = Math.max(0, columnIndex * columnWidth - width + scrollbarSize + columnWidth);
1789
1790
if (align === 'smart') {
@@ -1665,13 +1803,27 @@ createGridComponent({
1803
return minOffset;
1804
1805
case 'center':
1668
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1806
+ // "Centered" offset is usually the average of the min and max.
1807
+ // But near the edges of the list, this doesn't hold true.
1808
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1809
+
1810
+ if (middleOffset < Math.ceil(width / 2)) {
1811
+ return 0; // near the beginning
1812
+ } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
1813
+ return lastColumnOffset; // near the end
1814
+ } else {
1815
+ return middleOffset;
1816
+ }
1817
1818
case 'auto':
1819
default:
1820
if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
1821
return scrollLeft;
1674
- } else if (scrollLeft - minOffset < maxOffset - scrollLeft) {
1822
+ } else if (minOffset > maxOffset) {
1823
+ // Because we only take into account the scrollbar size when calculating minOffset
1824
+ // this value can be larger than maxOffset when at the end of the list
1825
+ return minOffset;
1826
+ } else if (scrollLeft < minOffset) {
1827
return minOffset;
1828
} else {
1829
return maxOffset;
@@ -1683,7 +1835,8 @@ createGridComponent({
1835
var rowHeight = _ref8.rowHeight,
1836
height = _ref8.height,
1837
rowCount = _ref8.rowCount;
1686
- var maxOffset = Math.max(0, Math.min(rowCount * rowHeight - height, rowIndex * rowHeight));
1838
+ var lastRowOffset = Math.max(0, rowCount * rowHeight - height);
1839
+ var maxOffset = Math.min(lastRowOffset, rowIndex * rowHeight);
1840
var minOffset = Math.max(0, rowIndex * rowHeight - height + scrollbarSize + rowHeight);
1841
1842
if (align === 'smart') {
@@ -1702,13 +1855,27 @@ createGridComponent({
1855
return minOffset;
1856
1857
case 'center':
1705
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1858
+ // "Centered" offset is usually the average of the min and max.
1859
+ // But near the edges of the list, this doesn't hold true.
1860
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1861
+
1862
+ if (middleOffset < Math.ceil(height / 2)) {
1863
+ return 0; // near the beginning
1864
+ } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
1865
+ return lastRowOffset; // near the end
1866
+ } else {
1867
+ return middleOffset;
1868
+ }
1869
1870
case 'auto':
1871
default:
1872
if (scrollTop >= minOffset && scrollTop <= maxOffset) {
1873
return scrollTop;
1711
- } else if (scrollTop - minOffset < maxOffset - scrollTop) {
1874
+ } else if (minOffset > maxOffset) {
1875
+ // Because we only take into account the scrollbar size when calculating minOffset
1876
+ // this value can be larger than maxOffset when at the end of the list
1877
+ return minOffset;
1878
+ } else if (scrollTop < minOffset) {
1879
return minOffset;
1880
} else {
1881
return maxOffset;
@@ -1726,7 +1893,9 @@ createGridComponent({
1893
columnCount = _ref10.columnCount,
1894
width = _ref10.width;
1895
var left = startIndex * columnWidth;
1729
- return Math.max(0, Math.min(columnCount - 1, startIndex + Math.floor((width + (scrollLeft - left)) / columnWidth)));
1896
+ var numVisibleColumns = Math.ceil((width + scrollLeft - left) / columnWidth);
1897
+ return Math.max(0, Math.min(columnCount - 1, startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
1898
+ ));
1899
},
1900
getRowStartIndexForOffset: function getRowStartIndexForOffset(_ref11, scrollTop) {
1901
var rowHeight = _ref11.rowHeight,
@@ -1737,8 +1906,10 @@ createGridComponent({
1906
var rowHeight = _ref12.rowHeight,
1907
rowCount = _ref12.rowCount,
1908
height = _ref12.height;
1740
- var left = startIndex * rowHeight;
1741
- return Math.max(0, Math.min(rowCount - 1, startIndex + Math.floor((height + (scrollTop - left)) / rowHeight)));
1909
+ var top = startIndex * rowHeight;
1910
+ var numVisibleRows = Math.ceil((height + scrollTop - top) / rowHeight);
1911
+ return Math.max(0, Math.min(rowCount - 1, startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
1912
+ ));
1913
},
1914
initInstanceProps: function initInstanceProps(props) {// Noop
1915
},
@@ -1763,13 +1934,11 @@ var FixedSizeList =
1934
/*#__PURE__*/
1935
createListComponent({
1936
getItemOffset: function getItemOffset(_ref, index) {
1766
- var itemSize = _ref.itemSize,
1767
- size = _ref.size;
1937
+ var itemSize = _ref.itemSize;
1938
return index * itemSize;
1939
},
1940
getItemSize: function getItemSize(_ref2, index) {
1771
- var itemSize = _ref2.itemSize,
1772
- size = _ref2.size;
1941
+ var itemSize = _ref2.itemSize;
1942
return itemSize;
1943
},
1944
getEstimatedTotalSize: function getEstimatedTotalSize(_ref3) {
@@ -1787,7 +1956,8 @@ createListComponent({
1956
// TODO Deprecate direction "horizontal"
1957
var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1958
var size = isHorizontal ? width : height;
1790
- var maxOffset = Math.max(0, Math.min(itemCount * itemSize - size, index * itemSize));
1959
+ var lastItemOffset = Math.max(0, itemCount * itemSize - size);
1960
+ var maxOffset = Math.min(lastItemOffset, index * itemSize);
1961
var minOffset = Math.max(0, index * itemSize - size + itemSize);
1962
1963
if (align === 'smart') {
@@ -1806,13 +1976,25 @@ createListComponent({
1976
return minOffset;
1977
1978
case 'center':
1809
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1979
+ {
1980
+ // "Centered" offset is usually the average of the min and max.
1981
+ // But near the edges of the list, this doesn't hold true.
1982
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1983
+
1984
+ if (middleOffset < Math.ceil(size / 2)) {
1985
+ return 0; // near the beginning
1986
+ } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
1987
+ return lastItemOffset; // near the end
1988
+ } else {
1989
+ return middleOffset;
1990
+ }
1991
+ }
1992
1993
case 'auto':
1994
default:
1995
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1996
return scrollOffset;
1815
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
1997
+ } else if (scrollOffset < minOffset) {
1998
return minOffset;
1999
} else {
2000
return maxOffset;
@@ -1836,7 +2018,9 @@ createListComponent({
2018
var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
2019
var offset = startIndex * itemSize;
2020
var size = isHorizontal ? width : height;
1839
- return Math.max(0, Math.min(itemCount - 1, startIndex + Math.floor((size + (scrollOffset - offset)) / itemSize)));
2021
+ var numVisibleItems = Math.ceil((size + scrollOffset - offset) / itemSize);
2022
+ return Math.max(0, Math.min(itemCount - 1, startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
2023
+ ));
2024
},
2025
initInstanceProps: function initInstanceProps(props) {// Noop
2026
},
@@ -1891,3 +2075,4 @@ function shouldComponentUpdate(nextProps, nextState) {
2075
}
2076
2077
export { VariableSizeGrid, VariableSizeList, FixedSizeGrid, FixedSizeList, areEqual, shouldComponentUpdate };
2078
+//# sourceMappingURL=index.esm.js.map
vendor/react-window/package.json
+5
-3
@@ -1,6 +1,6 @@
1
{
2
"name": "react-window",
3
- "version": "1.8.0",
3
+ "version": "1.8.5",
4
"description":
5
"React components for efficiently rendering large, scrollable lists and tabular data",
6
"author":
@@ -91,7 +91,7 @@
91
"eslint-plugin-promise": "^3.7.0",
92
"eslint-plugin-react": "^7.7.0",
93
"eslint-plugin-standard": "^3.0.1",
94
- "flow-bin": "^0.80.0",
94
+ "flow-bin": "^0.103.0",
95
"gh-pages": "^1.1.0",
96
"lint-staged": "^7.0.5",
97
"prettier": "^1.12.1",
@@ -103,6 +103,8 @@
103
"rollup": "^1.4.1",
104
"rollup-plugin-babel": "^4.3.2",
105
"rollup-plugin-commonjs": "^9.2.1",
106
- "rollup-plugin-node-resolve": "^4.0.1"
106
+ "rollup-plugin-node-resolve": "^4.0.1",
107
+ "rollup-plugin-replace": "^2.2.0",
108
+ "rollup-plugin-terser": "^5.1.0"
109
}
110
}
vendor/react-window/src/FixedSizeGrid.js
+55
-21
@@ -31,12 +31,13 @@ const FixedSizeGrid = createGridComponent({
31
instanceProps: typeof undefined,
32
scrollbarSize: number
33
): number => {
34
- const maxOffset = Math.max(
34
+ const lastColumnOffset = Math.max(
35
0,
36
- Math.min(
37
- columnCount * ((columnWidth: any): number) - width,
38
- columnIndex * ((columnWidth: any): number)
39
- )
36
+ columnCount * ((columnWidth: any): number) - width
37
+ );
38
+ const maxOffset = Math.min(
39
+ lastColumnOffset,
40
+ columnIndex * ((columnWidth: any): number)
41
);
42
const minOffset = Math.max(
43
0,
@@ -60,12 +61,27 @@ const FixedSizeGrid = createGridComponent({
61
case 'end':
62
return minOffset;
63
case 'center':
63
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
64
+ // "Centered" offset is usually the average of the min and max.
65
+ // But near the edges of the list, this doesn't hold true.
66
+ const middleOffset = Math.round(
67
+ minOffset + (maxOffset - minOffset) / 2
68
+ );
69
+ if (middleOffset < Math.ceil(width / 2)) {
70
+ return 0; // near the beginning
71
+ } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
72
+ return lastColumnOffset; // near the end
73
+ } else {
74
+ return middleOffset;
75
+ }
76
case 'auto':
77
default:
78
if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
79
return scrollLeft;
68
- } else if (scrollLeft - minOffset < maxOffset - scrollLeft) {
80
+ } else if (minOffset > maxOffset) {
81
+ // Because we only take into account the scrollbar size when calculating minOffset
82
+ // this value can be larger than maxOffset when at the end of the list
83
+ return minOffset;
84
+ } else if (scrollLeft < minOffset) {
85
return minOffset;
86
} else {
87
return maxOffset;
@@ -81,12 +97,13 @@ const FixedSizeGrid = createGridComponent({
97
instanceProps: typeof undefined,
98
scrollbarSize: number
99
): number => {
84
- const maxOffset = Math.max(
100
+ const lastRowOffset = Math.max(
101
0,
86
- Math.min(
87
- rowCount * ((rowHeight: any): number) - height,
88
- rowIndex * ((rowHeight: any): number)
89
- )
102
+ rowCount * ((rowHeight: any): number) - height
103
+ );
104
+ const maxOffset = Math.min(
105
+ lastRowOffset,
106
+ rowIndex * ((rowHeight: any): number)
107
);
108
const minOffset = Math.max(
109
0,
@@ -110,12 +127,27 @@ const FixedSizeGrid = createGridComponent({
127
case 'end':
128
return minOffset;
129
case 'center':
113
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
130
+ // "Centered" offset is usually the average of the min and max.
131
+ // But near the edges of the list, this doesn't hold true.
132
+ const middleOffset = Math.round(
133
+ minOffset + (maxOffset - minOffset) / 2
134
+ );
135
+ if (middleOffset < Math.ceil(height / 2)) {
136
+ return 0; // near the beginning
137
+ } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
138
+ return lastRowOffset; // near the end
139
+ } else {
140
+ return middleOffset;
141
+ }
142
case 'auto':
143
default:
144
if (scrollTop >= minOffset && scrollTop <= maxOffset) {
145
return scrollTop;
118
- } else if (scrollTop - minOffset < maxOffset - scrollTop) {
146
+ } else if (minOffset > maxOffset) {
147
+ // Because we only take into account the scrollbar size when calculating minOffset
148
+ // this value can be larger than maxOffset when at the end of the list
149
+ return minOffset;
150
+ } else if (scrollTop < minOffset) {
151
return minOffset;
152
} else {
153
return maxOffset;
@@ -141,14 +173,14 @@ const FixedSizeGrid = createGridComponent({
173
scrollLeft: number
174
): number => {
175
const left = startIndex * ((columnWidth: any): number);
176
+ const numVisibleColumns = Math.ceil(
177
+ (width + scrollLeft - left) / ((columnWidth: any): number)
178
+ );
179
return Math.max(
180
0,
181
Math.min(
182
columnCount - 1,
148
- startIndex +
149
- Math.floor(
150
- (width + (scrollLeft - left)) / ((columnWidth: any): number)
151
- )
183
+ startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
184
)
185
);
186
},
@@ -167,13 +199,15 @@ const FixedSizeGrid = createGridComponent({
199
startIndex: number,
200
scrollTop: number
201
): number => {
170
- const left = startIndex * ((rowHeight: any): number);
202
+ const top = startIndex * ((rowHeight: any): number);
203
+ const numVisibleRows = Math.ceil(
204
+ (height + scrollTop - top) / ((rowHeight: any): number)
205
+ );
206
return Math.max(
207
0,
208
Math.min(
209
rowCount - 1,
175
- startIndex +
176
- Math.floor((height + (scrollTop - left)) / ((rowHeight: any): number))
210
+ startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
211
)
212
);
213
},
vendor/react-window/src/FixedSizeList.js
+27
-14
@@ -5,10 +5,10 @@ import createListComponent from './createListComponent';
5
import type { Props, ScrollToAlign } from './createListComponent';
6
7
const FixedSizeList = createListComponent({
8
- getItemOffset: ({ itemSize, size }: Props<any>, index: number): number =>
8
+ getItemOffset: ({ itemSize }: Props<any>, index: number): number =>
9
index * ((itemSize: any): number),
10
11
- getItemSize: ({ itemSize, size }: Props<any>, index: number): number =>
11
+ getItemSize: ({ itemSize }: Props<any>, index: number): number =>
12
((itemSize: any): number),
13
14
getEstimatedTotalSize: ({ itemCount, itemSize }: Props<any>) =>
@@ -23,12 +23,13 @@ const FixedSizeList = createListComponent({
23
// TODO Deprecate direction "horizontal"
24
const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
25
const size = (((isHorizontal ? width : height): any): number);
26
- const maxOffset = Math.max(
26
+ const lastItemOffset = Math.max(
27
0,
28
- Math.min(
29
- itemCount * ((itemSize: any): number) - size,
30
- index * ((itemSize: any): number)
31
- )
28
+ itemCount * ((itemSize: any): number) - size
29
+ );
30
+ const maxOffset = Math.min(
31
+ lastItemOffset,
32
+ index * ((itemSize: any): number)
33
);
34
const minOffset = Math.max(
35
0,
@@ -51,13 +52,25 @@ const FixedSizeList = createListComponent({
52
return maxOffset;
53
case 'end':
54
return minOffset;
54
- case 'center':
55
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
55
+ case 'center': {
56
+ // "Centered" offset is usually the average of the min and max.
57
+ // But near the edges of the list, this doesn't hold true.
58
+ const middleOffset = Math.round(
59
+ minOffset + (maxOffset - minOffset) / 2
60
+ );
61
+ if (middleOffset < Math.ceil(size / 2)) {
62
+ return 0; // near the beginning
63
+ } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
64
+ return lastItemOffset; // near the end
65
+ } else {
66
+ return middleOffset;
67
+ }
68
+ }
69
case 'auto':
70
default:
71
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
72
return scrollOffset;
60
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
73
+ } else if (scrollOffset < minOffset) {
74
return minOffset;
75
} else {
76
return maxOffset;
@@ -83,14 +96,14 @@ const FixedSizeList = createListComponent({
96
const isHorizontal = direction === 'horizontal' || layout === 'horizontal';
97
const offset = startIndex * ((itemSize: any): number);
98
const size = (((isHorizontal ? width : height): any): number);
99
+ const numVisibleItems = Math.ceil(
100
+ (size + scrollOffset - offset) / ((itemSize: any): number)
101
+ );
102
return Math.max(
103
0,
104
Math.min(
105
itemCount - 1,
90
- startIndex +
91
- Math.floor(
92
- (size + (scrollOffset - offset)) / ((itemSize: any): number)
93
- )
106
+ startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
107
)
108
);
109
},
vendor/react-window/src/VariableSizeGrid.js
+5
-1
@@ -274,7 +274,11 @@ const getOffsetForIndexAndAlignment = (
274
default:
275
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
276
return scrollOffset;
277
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
277
+ } else if (minOffset > maxOffset) {
278
+ // Because we only take into account the scrollbar size when calculating minOffset
279
+ // this value can be larger than maxOffset when at the end of the list
280
+ return minOffset;
281
+ } else if (scrollOffset < minOffset) {
282
return minOffset;
283
} else {
284
return maxOffset;
vendor/react-window/src/VariableSizeList.js
+1
-1
@@ -227,7 +227,7 @@ const VariableSizeList = createListComponent({
227
default:
228
if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
229
return scrollOffset;
230
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
230
+ } else if (scrollOffset < minOffset) {
231
return minOffset;
232
} else {
233
return maxOffset;
vendor/react-window/src/createGridComponent.js
+107
-25
@@ -3,7 +3,7 @@
3
import memoizeOne from 'memoize-one';
4
import { createElement, PureComponent } from 'react';
5
import { cancelTimeout, requestTimeout } from './timer';
6
-import { getScrollbarSize } from './domHelpers';
6
+import { getScrollbarSize, getRTLOffsetType } from './domHelpers';
7
8
import type { TimeoutID } from './timer';
9
@@ -46,6 +46,22 @@ type OnScrollCallback = ({
46
type ScrollEvent = SyntheticEvent<HTMLDivElement>;
47
type ItemStyleCache = { [key: string]: Object };
48
49
+type OuterProps = {|
50
+ children: React$Node,
51
+ className: string | void,
52
+ onScroll: ScrollEvent => void,
53
+ style: {
54
+ [string]: mixed,
55
+ },
56
+|};
57
+
58
+type InnerProps = {|
59
+ children: React$Node,
60
+ style: {
61
+ [string]: mixed,
62
+ },
63
+|};
64
+
65
export type Props<T> = {|
66
children: RenderComponent<T>,
67
className?: string,
@@ -56,7 +72,7 @@ export type Props<T> = {|
72
initialScrollLeft?: number,
73
initialScrollTop?: number,
74
innerRef?: any,
59
- innerElementType?: React$ElementType,
75
+ innerElementType?: string | React$AbstractComponent<InnerProps, any>,
76
innerTagName?: string, // deprecated
77
itemData: T,
78
itemKey?: (params: {|
@@ -67,11 +83,13 @@ export type Props<T> = {|
83
onItemsRendered?: OnItemsRenderedCallback,
84
onScroll?: OnScrollCallback,
85
outerRef?: any,
70
- outerElementType?: React$ElementType,
86
+ outerElementType?: string | React$AbstractComponent<OuterProps, any>,
87
outerTagName?: string, // deprecated
72
- overscanColumnsCount?: number,
88
+ overscanColumnCount?: number,
89
+ overscanColumnsCount?: number, // deprecated
90
overscanCount?: number, // deprecated
74
- overscanRowsCount?: number,
91
+ overscanRowCount?: number,
92
+ overscanRowsCount?: number, // deprecated
93
rowCount: number,
94
rowHeight: itemSize,
95
style?: Object,
@@ -130,10 +148,12 @@ const defaultItemKey = ({ columnIndex, data, rowIndex }) =>
148
// In DEV mode, this Set helps us only log a warning once per component instance.
149
// This avoids spamming the console every time a render happens.
150
let devWarningsOverscanCount = null;
151
+let devWarningsOverscanRowsColumnsCount = null;
152
let devWarningsTagName = null;
153
if (process.env.NODE_ENV !== 'production') {
154
if (typeof window !== 'undefined' && typeof window.WeakSet !== 'undefined') {
155
devWarningsOverscanCount = new WeakSet();
156
+ devWarningsOverscanRowsColumnsCount = new WeakSet();
157
devWarningsTagName = new WeakSet();
158
}
159
}
@@ -320,21 +340,47 @@ export default function createGridComponent({
340
341
componentDidMount() {
342
const { initialScrollLeft, initialScrollTop } = this.props;
323
- if (typeof initialScrollLeft === 'number' && this._outerRef != null) {
324
- ((this._outerRef: any): HTMLDivElement).scrollLeft = initialScrollLeft;
325
- }
326
- if (typeof initialScrollTop === 'number' && this._outerRef != null) {
327
- ((this._outerRef: any): HTMLDivElement).scrollTop = initialScrollTop;
343
+
344
+ if (this._outerRef != null) {
345
+ const outerRef = ((this._outerRef: any): HTMLElement);
346
+ if (typeof initialScrollLeft === 'number') {
347
+ outerRef.scrollLeft = initialScrollLeft;
348
+ }
349
+ if (typeof initialScrollTop === 'number') {
350
+ outerRef.scrollTop = initialScrollTop;
351
+ }
352
}
353
354
this._callPropsCallbacks();
355
}
356
357
componentDidUpdate() {
358
+ const { direction } = this.props;
359
const { scrollLeft, scrollTop, scrollUpdateWasRequested } = this.state;
335
- if (scrollUpdateWasRequested && this._outerRef !== null) {
336
- ((this._outerRef: any): HTMLDivElement).scrollLeft = scrollLeft;
337
- ((this._outerRef: any): HTMLDivElement).scrollTop = scrollTop;
360
+
361
+ if (scrollUpdateWasRequested && this._outerRef != null) {
362
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
363
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
364
+ // So we need to determine which browser behavior we're dealing with, and mimic it.
365
+ const outerRef = ((this._outerRef: any): HTMLElement);
366
+ if (direction === 'rtl') {
367
+ switch (getRTLOffsetType()) {
368
+ case 'negative':
369
+ outerRef.scrollLeft = -scrollLeft;
370
+ break;
371
+ case 'positive-ascending':
372
+ outerRef.scrollLeft = scrollLeft;
373
+ break;
374
+ default:
375
+ const { clientWidth, scrollWidth } = outerRef;
376
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
377
+ break;
378
+ }
379
+ } else {
380
+ outerRef.scrollLeft = Math.max(0, scrollLeft);
381
+ }
382
+
383
+ outerRef.scrollTop = Math.max(0, scrollTop);
384
}
385
386
this._callPropsCallbacks();
@@ -432,7 +478,7 @@ export default function createGridComponent({
478
ref: innerRef,
479
style: {
480
height: estimatedTotalHeight,
435
- pointerEvents: isScrolling ? 'none' : '',
481
+ pointerEvents: isScrolling ? 'none' : undefined,
482
width: estimatedTotalWidth,
483
},
484
})
@@ -586,6 +632,7 @@ export default function createGridComponent({
632
_getHorizontalRangeToRender(): [number, number, number, number] {
633
const {
634
columnCount,
635
+ overscanColumnCount,
636
overscanColumnsCount,
637
overscanCount,
638
rowCount,
@@ -593,7 +640,7 @@ export default function createGridComponent({
640
const { horizontalScrollDirection, isScrolling, scrollLeft } = this.state;
641
642
const overscanCountResolved: number =
596
- overscanColumnsCount || overscanCount || 1;
643
+ overscanColumnCount || overscanColumnsCount || overscanCount || 1;
644
645
if (columnCount === 0 || rowCount === 0) {
646
return [0, 0, 0, 0];
@@ -634,13 +681,14 @@ export default function createGridComponent({
681
const {
682
columnCount,
683
overscanCount,
684
+ overscanRowCount,
685
overscanRowsCount,
686
rowCount,
687
} = this.props;
688
const { isScrolling, verticalScrollDirection, scrollTop } = this.state;
689
690
const overscanCountResolved: number =
643
- overscanRowsCount || overscanCount || 1;
691
+ overscanRowCount || overscanRowsCount || overscanCount || 1;
692
693
if (columnCount === 0 || rowCount === 0) {
694
return [0, 0, 0, 0];
@@ -679,9 +727,11 @@ export default function createGridComponent({
727
728
_onScroll = (event: ScrollEvent): void => {
729
const {
730
+ clientHeight,
731
clientWidth,
732
scrollLeft,
733
scrollTop,
734
+ scrollHeight,
735
scrollWidth,
736
} = event.currentTarget;
737
this.setState(prevState => {
@@ -697,24 +747,38 @@ export default function createGridComponent({
747
748
const { direction } = this.props;
749
700
- // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
701
- // Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
702
- // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
750
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
751
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
752
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
753
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
754
let calculatedScrollLeft = scrollLeft;
755
if (direction === 'rtl') {
705
- if (scrollLeft <= 0) {
706
- calculatedScrollLeft = -scrollLeft;
707
- } else {
708
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
756
+ switch (getRTLOffsetType()) {
757
+ case 'negative':
758
+ calculatedScrollLeft = -scrollLeft;
759
+ break;
760
+ case 'positive-descending':
761
+ calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
762
+ break;
763
}
764
}
765
766
+ // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
767
+ calculatedScrollLeft = Math.max(
768
+ 0,
769
+ Math.min(calculatedScrollLeft, scrollWidth - clientWidth)
770
+ );
771
+ const calculatedScrollTop = Math.max(
772
+ 0,
773
+ Math.min(scrollTop, scrollHeight - clientHeight)
774
+ );
775
+
776
return {
777
isScrolling: true,
778
horizontalScrollDirection:
779
prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
780
scrollLeft: calculatedScrollLeft,
717
- scrollTop,
781
+ scrollTop: calculatedScrollTop,
782
verticalScrollDirection:
783
prevState.scrollTop < scrollTop ? 'forward' : 'backward',
784
scrollUpdateWasRequested: false,
@@ -768,7 +832,9 @@ const validateSharedProps = (
832
height,
833
innerTagName,
834
outerTagName,
835
+ overscanColumnsCount,
836
overscanCount,
837
+ overscanRowsCount,
838
width,
839
}: Props<any>,
840
{ instance }: State
@@ -779,7 +845,23 @@ const validateSharedProps = (
845
devWarningsOverscanCount.add(instance);
846
console.warn(
847
'The overscanCount prop has been deprecated. ' +
782
- 'Please use the overscanColumnsCount and overscanRowsCount props instead.'
848
+ 'Please use the overscanColumnCount and overscanRowCount props instead.'
849
+ );
850
+ }
851
+ }
852
+
853
+ if (
854
+ typeof overscanColumnsCount === 'number' ||
855
+ typeof overscanRowsCount === 'number'
856
+ ) {
857
+ if (
858
+ devWarningsOverscanRowsColumnsCount &&
859
+ !devWarningsOverscanRowsColumnsCount.has(instance)
860
+ ) {
861
+ devWarningsOverscanRowsColumnsCount.add(instance);
862
+ console.warn(
863
+ 'The overscanColumnsCount and overscanRowsCount props have been deprecated. ' +
864
+ 'Please use the overscanColumnCount and overscanRowCount props instead.'
865
);
866
}
867
}
vendor/react-window/src/createListComponent.js
+73
-21
@@ -3,6 +3,7 @@
3
import memoizeOne from 'memoize-one';
4
import { createElement, PureComponent } from 'react';
5
import { cancelTimeout, requestTimeout } from './timer';
6
+import { getRTLOffsetType } from './domHelpers';
7
8
import type { TimeoutID } from './timer';
9
@@ -38,6 +39,22 @@ type onScrollCallback = ({
39
type ScrollEvent = SyntheticEvent<HTMLDivElement>;
40
type ItemStyleCache = { [index: number]: Object };
41
42
+type OuterProps = {|
43
+ children: React$Node,
44
+ className: string | void,
45
+ onScroll: ScrollEvent => void,
46
+ style: {
47
+ [string]: mixed,
48
+ },
49
+|};
50
+
51
+type InnerProps = {|
52
+ children: React$Node,
53
+ style: {
54
+ [string]: mixed,
55
+ },
56
+|};
57
+
58
export type Props<T> = {|
59
children: RenderComponent<T>,
60
className?: string,
@@ -45,7 +62,7 @@ export type Props<T> = {|
62
height: number | string,
63
initialScrollOffset?: number,
64
innerRef?: any,
48
- innerElementType?: React$ElementType,
65
+ innerElementType?: string | React$AbstractComponent<InnerProps, any>,
66
innerTagName?: string, // deprecated
67
itemCount: number,
68
itemData: T,
@@ -55,7 +72,7 @@ export type Props<T> = {|
72
onItemsRendered?: onItemsRenderedCallback,
73
onScroll?: onScrollCallback,
74
outerRef?: any,
58
- outerElementType?: React$ElementType,
75
+ outerElementType?: string | React$AbstractComponent<OuterProps, any>,
76
outerTagName?: string, // deprecated
77
overscanCount: number,
78
style?: Object,
@@ -215,14 +232,13 @@ export default function createListComponent({
232
componentDidMount() {
233
const { direction, initialScrollOffset, layout } = this.props;
234
218
- if (typeof initialScrollOffset === 'number' && this._outerRef !== null) {
235
+ if (typeof initialScrollOffset === 'number' && this._outerRef != null) {
236
+ const outerRef = ((this._outerRef: any): HTMLElement);
237
// TODO Deprecate direction "horizontal"
238
if (direction === 'horizontal' || layout === 'horizontal') {
221
- ((this
222
- ._outerRef: any): HTMLDivElement).scrollLeft = initialScrollOffset;
239
+ outerRef.scrollLeft = initialScrollOffset;
240
} else {
224
- ((this
225
- ._outerRef: any): HTMLDivElement).scrollTop = initialScrollOffset;
241
+ outerRef.scrollTop = initialScrollOffset;
242
}
243
}
244
@@ -233,12 +249,32 @@ export default function createListComponent({
249
const { direction, layout } = this.props;
250
const { scrollOffset, scrollUpdateWasRequested } = this.state;
251
236
- if (scrollUpdateWasRequested && this._outerRef !== null) {
252
+ if (scrollUpdateWasRequested && this._outerRef != null) {
253
+ const outerRef = ((this._outerRef: any): HTMLElement);
254
+
255
// TODO Deprecate direction "horizontal"
256
if (direction === 'horizontal' || layout === 'horizontal') {
239
- ((this._outerRef: any): HTMLDivElement).scrollLeft = scrollOffset;
257
+ if (direction === 'rtl') {
258
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
259
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
260
+ // So we need to determine which browser behavior we're dealing with, and mimic it.
261
+ switch (getRTLOffsetType()) {
262
+ case 'negative':
263
+ outerRef.scrollLeft = -scrollOffset;
264
+ break;
265
+ case 'positive-ascending':
266
+ outerRef.scrollLeft = scrollOffset;
267
+ break;
268
+ default:
269
+ const { clientWidth, scrollWidth } = outerRef;
270
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
271
+ break;
272
+ }
273
+ } else {
274
+ outerRef.scrollLeft = scrollOffset;
275
+ }
276
} else {
241
- ((this._outerRef: any): HTMLDivElement).scrollTop = scrollOffset;
277
+ outerRef.scrollTop = scrollOffset;
278
}
279
}
280
@@ -326,7 +362,7 @@ export default function createListComponent({
362
ref: innerRef,
363
style: {
364
height: isHorizontal ? '100%' : estimatedTotalSize,
329
- pointerEvents: isScrolling ? 'none' : '',
365
+ pointerEvents: isScrolling ? 'none' : undefined,
366
width: isHorizontal ? estimatedTotalSize : '100%',
367
},
368
})
@@ -496,18 +532,28 @@ export default function createListComponent({
532
533
const { direction } = this.props;
534
499
- // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
500
- // Chrome does not seem to adhere; its scrolLeft values are positive (measured relative to the left).
501
- // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
535
let scrollOffset = scrollLeft;
536
if (direction === 'rtl') {
504
- if (scrollLeft <= 0) {
505
- scrollOffset = -scrollOffset;
506
- } else {
507
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
537
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
538
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
539
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
540
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
541
+ switch (getRTLOffsetType()) {
542
+ case 'negative':
543
+ scrollOffset = -scrollLeft;
544
+ break;
545
+ case 'positive-descending':
546
+ scrollOffset = scrollWidth - clientWidth - scrollLeft;
547
+ break;
548
}
549
}
550
551
+ // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
552
+ scrollOffset = Math.max(
553
+ 0,
554
+ Math.min(scrollOffset, scrollWidth - clientWidth)
555
+ );
556
+
557
return {
558
isScrolling: true,
559
scrollDirection:
@@ -519,7 +565,7 @@ export default function createListComponent({
565
};
566
567
_onScrollVertical = (event: ScrollEvent): void => {
522
- const { scrollTop } = event.currentTarget;
568
+ const { clientHeight, scrollHeight, scrollTop } = event.currentTarget;
569
this.setState(prevState => {
570
if (prevState.scrollOffset === scrollTop) {
571
// Scroll position may have been updated by cDM/cDU,
@@ -528,11 +574,17 @@ export default function createListComponent({
574
return null;
575
}
576
577
+ // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
578
+ const scrollOffset = Math.max(
579
+ 0,
580
+ Math.min(scrollTop, scrollHeight - clientHeight)
581
+ );
582
+
583
return {
584
isScrolling: true,
585
scrollDirection:
534
- prevState.scrollOffset < scrollTop ? 'forward' : 'backward',
535
- scrollOffset: scrollTop,
586
+ prevState.scrollOffset < scrollOffset ? 'forward' : 'backward',
587
+ scrollOffset,
588
scrollUpdateWasRequested: false,
589
};
590
}, this._resetIsScrollingDebounced);
vendor/react-window/src/domHelpers.js
+50
@@ -20,3 +20,53 @@ export function getScrollbarSize(recalculate?: boolean = false): number {
20
21
return size;
22
}
23
+
24
+export type RTLOffsetType =
25
+ | 'negative'
26
+ | 'positive-descending'
27
+ | 'positive-ascending';
28
+
29
+let cachedRTLResult: RTLOffsetType | null = null;
30
+
31
+// TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
32
+// Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
33
+// Safari's elastic bounce makes detecting this even more complicated wrt potential false positives.
34
+// The safest way to check this is to intentionally set a negative offset,
35
+// and then verify that the subsequent "scroll" event matches the negative offset.
36
+// If it does not match, then we can assume a non-standard RTL scroll implementation.
37
+export function getRTLOffsetType(recalculate?: boolean = false): RTLOffsetType {
38
+ if (cachedRTLResult === null || recalculate) {
39
+ const outerDiv = document.createElement('div');
40
+ const outerStyle = outerDiv.style;
41
+ outerStyle.width = '50px';
42
+ outerStyle.height = '50px';
43
+ outerStyle.overflow = 'scroll';
44
+ outerStyle.direction = 'rtl';
45
+
46
+ const innerDiv = document.createElement('div');
47
+ const innerStyle = innerDiv.style;
48
+ innerStyle.width = '100px';
49
+ innerStyle.height = '100px';
50
+
51
+ outerDiv.appendChild(innerDiv);
52
+
53
+ ((document.body: any): HTMLBodyElement).appendChild(outerDiv);
54
+
55
+ if (outerDiv.scrollLeft > 0) {
56
+ cachedRTLResult = 'positive-descending';
57
+ } else {
58
+ outerDiv.scrollLeft = 1;
59
+ if (outerDiv.scrollLeft === 0) {
60
+ cachedRTLResult = 'negative';
61
+ } else {
62
+ cachedRTLResult = 'positive-ascending';
63
+ }
64
+ }
65
+
66
+ ((document.body: any): HTMLBodyElement).removeChild(outerDiv);
67
+
68
+ return cachedRTLResult;
69
+ }
70
+
71
+ return cachedRTLResult;
72
+}
yarn.lock
+13
-13
@@ -766,9 +766,9 @@
766
regenerator-runtime "^0.12.0"
767
768
"@babel/runtime@^7.0.0":
769
- version "7.4.5"
770
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
771
- integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
769
+ version "7.5.5"
770
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
771
+ integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
772
dependencies:
773
regenerator-runtime "^0.13.2"
774
@@ -5522,10 +5522,10 @@ flatstr@^1.0.9:
5522
resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.9.tgz#0950d56fec02de1030c1311847ecd58c25690eb9"
5523
integrity sha512-qFlJnOBWDfIaunF54/lBqNKmXOI0HqNhu+mHkLmbaBXlS71PUd9OjFOdyevHt/aHoHB1+eW7eKHgRKOG5aHSpw==
5524
5525
-flow-bin@^0.97.0:
5526
- version "0.97.0"
5527
- resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.97.0.tgz#036ffcfc27503367a9d906ec9d843a0aa6f6bb83"
5528
- integrity sha512-jXjD05gkatLuC4+e28frH1hZoRwr1iASP6oJr61Q64+kR4kmzaS+AdFBhYgoYS5kpoe4UzwDebWK8ETQFNh00w==
5525
+flow-bin@^0.103.0:
5526
+ version "0.103.0"
5527
+ resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.103.0.tgz#7aec510d85e1c1b0f2b912bb988337d70035cb0f"
5528
+ integrity sha512-Y3yrnE5ICN1Kl/y10BwjA3JSuS+gt4jVPNyUNCZb0RqmkdssMrW8QNNysJYvhgAY/JBJH8Qv7NVUf11MiwfSlA==
5529
5530
fluent-syntax@0.10.0:
5531
version "0.10.0"
@@ -8250,9 +8250,9 @@ mem@^4.0.0:
8250
p-is-promise "^2.0.0"
8251
8252
"memoize-one@>=3.1.1 <6":
8253
- version "5.0.4"
8254
- resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.4.tgz#005928aced5c43d890a4dfab18ca908b0ec92cbc"
8255
- integrity sha512-P0z5IeAH6qHHGkJIXWw0xC2HNEgkx/9uWWBQw64FJj3/ol14VYdfVGWWr0fXfjhhv3TKVIqUq65os6O4GUNksA==
8253
+ version "5.0.5"
8254
+ resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e"
8255
+ integrity sha512-ey6EpYv0tEaIbM/nTDOpHciXUvd+ackQrJgEzBwemhZZIWZjcyodqEcrmqDy2BKRTM3a65kKBV4WtLXJDt26SQ==
8256
8257
memoize-one@^3.1.1:
8258
version "3.1.1"
@@ -10183,9 +10183,9 @@ regenerator-runtime@^0.12.0:
10183
integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
10184
10185
regenerator-runtime@^0.13.2:
10186
- version "0.13.2"
10187
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
10188
- integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
10186
+ version "0.13.3"
10187
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"
10188
+ integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==
10189
10190
regenerator-runtime@^0.9.5:
10191
version "0.9.6"