@samitouri / QOS-React-2 / commits / 4b34a77d29

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"