@react-aria/virtualizer 4.0.3-nightly.5042 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -111,9 +111,13 @@ function $00ca8c0b29e3e07c$export$2ea0c4974da4731b(props, ref) {
111
111
  };
112
112
  // eslint-disable-next-line react-hooks/exhaustive-deps
113
113
  }, []);
114
+ let isUpdatingSize = (0, $kvIfm$react.useRef)(false);
114
115
  let updateSize = (0, $kvIfm$reactariautils.useEffectEvent)((flush)=>{
115
116
  let dom = ref.current;
116
- if (!dom) return;
117
+ if (!dom && !isUpdatingSize.current) return;
118
+ // Prevent reentrancy when resize observer fires, triggers re-layout that results in
119
+ // content size update, causing below layout effect to fire. This avoids infinite loops.
120
+ isUpdatingSize.current = true;
117
121
  let isTestEnv = false;
118
122
  let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');
119
123
  let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');
@@ -140,30 +144,24 @@ function $00ca8c0b29e3e07c$export$2ea0c4974da4731b(props, ref) {
140
144
  });
141
145
  }
142
146
  }
147
+ isUpdatingSize.current = false;
143
148
  });
144
- let didUpdateSize = (0, $kvIfm$react.useRef)(false);
149
+ // Update visible rect when the content size changes, in case scrollbars need to appear or disappear.
150
+ let lastContentSize = (0, $kvIfm$react.useRef)(null);
145
151
  (0, $kvIfm$reactariautils.useLayoutEffect)(()=>{
146
- // React doesn't allow flushSync inside effects, so queue a microtask.
147
- // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
148
- queueMicrotask(()=>{
149
- if (!didUpdateSize.current) {
150
- didUpdateSize.current = true;
151
- updateSize((0, $kvIfm$reactdom.flushSync));
152
- }
153
- });
154
- }, [
155
- updateSize
156
- ]);
157
- (0, $kvIfm$react.useEffect)(()=>{
158
- if (!didUpdateSize.current) {
159
- // If useEffect ran before the above microtask, we are in a synchronous render (e.g. act).
160
- // Update the size here so that you don't need to mock timers in tests.
161
- didUpdateSize.current = true;
162
- updateSize((fn)=>fn());
152
+ if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) {
153
+ // React doesn't allow flushSync inside effects, so queue a microtask.
154
+ // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
155
+ // If we are in an `act` environment, update immediately without a microtask so you don't need
156
+ // to mock timers in tests. In this case, the update is synchronous already.
157
+ // IS_REACT_ACT_ENVIRONMENT is used by React 18. Previous versions checked for the `jest` global.
158
+ // https://github.com/reactwg/react-18/discussions/102
159
+ // @ts-ignore
160
+ if (typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined') updateSize((fn)=>fn());
161
+ else queueMicrotask(()=>updateSize((0, $kvIfm$reactdom.flushSync)));
163
162
  }
164
- }, [
165
- updateSize
166
- ]);
163
+ lastContentSize.current = contentSize;
164
+ });
167
165
  let onResize = (0, $kvIfm$react.useCallback)(()=>{
168
166
  updateSize((0, $kvIfm$reactdom.flushSync));
169
167
  }, [
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/virtualizer/src/ScrollView.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// @ts-ignore\nimport {flushSync} from 'react-dom';\nimport {getScrollLeft} from './utils';\nimport React, {\n CSSProperties,\n ForwardedRef,\n HTMLAttributes,\n ReactNode,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n useState\n} from 'react';\nimport {Rect, Size} from '@react-stately/virtualizer';\nimport {useEffectEvent, useEvent, useLayoutEffect, useObjectRef, useResizeObserver} from '@react-aria/utils';\nimport {useLocale} from '@react-aria/i18n';\n\ninterface ScrollViewProps extends HTMLAttributes<HTMLElement> {\n contentSize: Size,\n onVisibleRectChange: (rect: Rect) => void,\n children?: ReactNode,\n innerStyle?: CSSProperties,\n onScrollStart?: () => void,\n onScrollEnd?: () => void,\n scrollDirection?: 'horizontal' | 'vertical' | 'both'\n}\n\nfunction ScrollView(props: ScrollViewProps, ref: ForwardedRef<HTMLDivElement | null>) {\n ref = useObjectRef(ref);\n let {scrollViewProps, contentProps} = useScrollView(props, ref);\n\n return (\n <div role=\"presentation\" {...scrollViewProps} ref={ref}>\n <div role=\"presentation\" {...contentProps}>\n {props.children}\n </div>\n </div>\n );\n}\n\nconst ScrollViewForwardRef = React.forwardRef(ScrollView);\nexport {ScrollViewForwardRef as ScrollView};\n\nexport function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement | null>) {\n let {\n contentSize,\n onVisibleRectChange,\n innerStyle,\n onScrollStart,\n onScrollEnd,\n scrollDirection = 'both',\n ...otherProps\n } = props;\n\n let state = useRef({\n scrollTop: 0,\n scrollLeft: 0,\n scrollEndTime: 0,\n scrollTimeout: null,\n width: 0,\n height: 0,\n isScrolling: false\n }).current;\n let {direction} = useLocale();\n\n let [isScrolling, setScrolling] = useState(false);\n let onScroll = useCallback((e) => {\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (props.onScroll) {\n props.onScroll(e);\n }\n\n flushSync(() => {\n let scrollTop = e.currentTarget.scrollTop;\n let scrollLeft = getScrollLeft(e.currentTarget, direction);\n\n // Prevent rubber band scrolling from shaking when scrolling out of bounds\n state.scrollTop = Math.max(0, Math.min(scrollTop, contentSize.height - state.height));\n state.scrollLeft = Math.max(0, Math.min(scrollLeft, contentSize.width - state.width));\n\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n\n if (!state.isScrolling) {\n state.isScrolling = true;\n setScrolling(true);\n\n // Pause typekit MutationObserver during scrolling.\n window.dispatchEvent(new Event('tk.disconnect-observer'));\n if (onScrollStart) {\n onScrollStart();\n }\n }\n\n // So we don't constantly call clearTimeout and setTimeout,\n // keep track of the current timeout time and only reschedule\n // the timer when it is getting close.\n let now = Date.now();\n if (state.scrollEndTime <= now + 50) {\n state.scrollEndTime = now + 300;\n\n clearTimeout(state.scrollTimeout);\n state.scrollTimeout = setTimeout(() => {\n state.isScrolling = false;\n setScrolling(false);\n state.scrollTimeout = null;\n\n window.dispatchEvent(new Event('tk.connect-observer'));\n if (onScrollEnd) {\n onScrollEnd();\n }\n }, 300);\n }\n });\n }, [props, direction, state, contentSize, onVisibleRectChange, onScrollStart, onScrollEnd]);\n\n // Attach event directly to ref so RAC Virtualizer doesn't need to send props upward.\n useEvent(ref, 'scroll', onScroll);\n\n // eslint-disable-next-line arrow-body-style\n useEffect(() => {\n return () => {\n clearTimeout(state.scrollTimeout);\n if (state.isScrolling) {\n window.dispatchEvent(new Event('tk.connect-observer'));\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n let updateSize = useEffectEvent((flush: typeof flushSync) => {\n let dom = ref.current;\n if (!dom) {\n return;\n }\n\n let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;\n let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');\n let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');\n let clientWidth = dom.clientWidth;\n let clientHeight = dom.clientHeight;\n let w = isTestEnv && !isClientWidthMocked ? Infinity : clientWidth;\n let h = isTestEnv && !isClientHeightMocked ? Infinity : clientHeight;\n\n if (state.width !== w || state.height !== h) {\n state.width = w;\n state.height = h;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, w, h));\n });\n\n // If the clientWidth or clientHeight changed, scrollbars appeared or disappeared as\n // a result of the layout update. In this case, re-layout again to account for the\n // adjusted space. In very specific cases this might result in the scrollbars disappearing\n // again, resulting in extra padding. We stop after a maximum of two layout passes to avoid\n // an infinite loop. This matches how browsers behavior with native CSS grid layout.\n if (!isTestEnv && clientWidth !== dom.clientWidth || clientHeight !== dom.clientHeight) {\n state.width = dom.clientWidth;\n state.height = dom.clientHeight;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n });\n }\n }\n });\n\n let didUpdateSize = useRef(false);\n useLayoutEffect(() => {\n // React doesn't allow flushSync inside effects, so queue a microtask.\n // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).\n queueMicrotask(() => {\n if (!didUpdateSize.current) {\n didUpdateSize.current = true;\n updateSize(flushSync);\n }\n });\n }, [updateSize]);\n useEffect(() => {\n if (!didUpdateSize.current) {\n // If useEffect ran before the above microtask, we are in a synchronous render (e.g. act).\n // Update the size here so that you don't need to mock timers in tests.\n didUpdateSize.current = true;\n updateSize(fn => fn());\n }\n }, [updateSize]);\n let onResize = useCallback(() => {\n updateSize(flushSync);\n }, [updateSize]);\n\n // Watch border-box instead of of content-box so that we don't go into\n // an infinite loop when scrollbars appear or disappear.\n useResizeObserver({ref, box: 'border-box', onResize});\n\n let style: React.CSSProperties = {\n // Reset padding so that relative positioning works correctly. Padding will be done in JS layout.\n padding: 0,\n ...otherProps.style\n };\n\n if (scrollDirection === 'horizontal') {\n style.overflowX = 'auto';\n style.overflowY = 'hidden';\n } else if (scrollDirection === 'vertical' || contentSize.width === state.width) {\n // Set overflow-x: hidden if content size is equal to the width of the scroll view.\n // This prevents horizontal scrollbars from flickering during resizing due to resize observer\n // firing slower than the frame rate, which may cause an infinite re-render loop.\n style.overflowY = 'auto';\n style.overflowX = 'hidden';\n } else {\n style.overflow = 'auto';\n }\n\n innerStyle = {\n width: Number.isFinite(contentSize.width) ? contentSize.width : undefined,\n height: Number.isFinite(contentSize.height) ? contentSize.height : undefined,\n pointerEvents: isScrolling ? 'none' : 'auto',\n position: 'relative',\n ...innerStyle\n };\n\n return {\n scrollViewProps: {\n ...otherProps,\n style\n },\n contentProps: {\n role: 'presentation',\n style: innerStyle\n }\n };\n}\n"],"names":[],"version":3,"file":"ScrollView.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/virtualizer/src/ScrollView.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// @ts-ignore\nimport {flushSync} from 'react-dom';\nimport {getScrollLeft} from './utils';\nimport React, {\n CSSProperties,\n ForwardedRef,\n HTMLAttributes,\n ReactNode,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n useState\n} from 'react';\nimport {Rect, Size} from '@react-stately/virtualizer';\nimport {useEffectEvent, useEvent, useLayoutEffect, useObjectRef, useResizeObserver} from '@react-aria/utils';\nimport {useLocale} from '@react-aria/i18n';\n\ninterface ScrollViewProps extends HTMLAttributes<HTMLElement> {\n contentSize: Size,\n onVisibleRectChange: (rect: Rect) => void,\n children?: ReactNode,\n innerStyle?: CSSProperties,\n onScrollStart?: () => void,\n onScrollEnd?: () => void,\n scrollDirection?: 'horizontal' | 'vertical' | 'both'\n}\n\nfunction ScrollView(props: ScrollViewProps, ref: ForwardedRef<HTMLDivElement | null>) {\n ref = useObjectRef(ref);\n let {scrollViewProps, contentProps} = useScrollView(props, ref);\n\n return (\n <div role=\"presentation\" {...scrollViewProps} ref={ref}>\n <div role=\"presentation\" {...contentProps}>\n {props.children}\n </div>\n </div>\n );\n}\n\nconst ScrollViewForwardRef = React.forwardRef(ScrollView);\nexport {ScrollViewForwardRef as ScrollView};\n\nexport function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement | null>) {\n let {\n contentSize,\n onVisibleRectChange,\n innerStyle,\n onScrollStart,\n onScrollEnd,\n scrollDirection = 'both',\n ...otherProps\n } = props;\n\n let state = useRef({\n scrollTop: 0,\n scrollLeft: 0,\n scrollEndTime: 0,\n scrollTimeout: null,\n width: 0,\n height: 0,\n isScrolling: false\n }).current;\n let {direction} = useLocale();\n\n let [isScrolling, setScrolling] = useState(false);\n let onScroll = useCallback((e) => {\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (props.onScroll) {\n props.onScroll(e);\n }\n\n flushSync(() => {\n let scrollTop = e.currentTarget.scrollTop;\n let scrollLeft = getScrollLeft(e.currentTarget, direction);\n\n // Prevent rubber band scrolling from shaking when scrolling out of bounds\n state.scrollTop = Math.max(0, Math.min(scrollTop, contentSize.height - state.height));\n state.scrollLeft = Math.max(0, Math.min(scrollLeft, contentSize.width - state.width));\n\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n\n if (!state.isScrolling) {\n state.isScrolling = true;\n setScrolling(true);\n\n // Pause typekit MutationObserver during scrolling.\n window.dispatchEvent(new Event('tk.disconnect-observer'));\n if (onScrollStart) {\n onScrollStart();\n }\n }\n\n // So we don't constantly call clearTimeout and setTimeout,\n // keep track of the current timeout time and only reschedule\n // the timer when it is getting close.\n let now = Date.now();\n if (state.scrollEndTime <= now + 50) {\n state.scrollEndTime = now + 300;\n\n clearTimeout(state.scrollTimeout);\n state.scrollTimeout = setTimeout(() => {\n state.isScrolling = false;\n setScrolling(false);\n state.scrollTimeout = null;\n\n window.dispatchEvent(new Event('tk.connect-observer'));\n if (onScrollEnd) {\n onScrollEnd();\n }\n }, 300);\n }\n });\n }, [props, direction, state, contentSize, onVisibleRectChange, onScrollStart, onScrollEnd]);\n\n // Attach event directly to ref so RAC Virtualizer doesn't need to send props upward.\n useEvent(ref, 'scroll', onScroll);\n\n // eslint-disable-next-line arrow-body-style\n useEffect(() => {\n return () => {\n clearTimeout(state.scrollTimeout);\n if (state.isScrolling) {\n window.dispatchEvent(new Event('tk.connect-observer'));\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n let isUpdatingSize = useRef(false);\n let updateSize = useEffectEvent((flush: typeof flushSync) => {\n let dom = ref.current;\n if (!dom && !isUpdatingSize.current) {\n return;\n }\n\n // Prevent reentrancy when resize observer fires, triggers re-layout that results in\n // content size update, causing below layout effect to fire. This avoids infinite loops.\n isUpdatingSize.current = true;\n\n let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;\n let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');\n let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');\n let clientWidth = dom.clientWidth;\n let clientHeight = dom.clientHeight;\n let w = isTestEnv && !isClientWidthMocked ? Infinity : clientWidth;\n let h = isTestEnv && !isClientHeightMocked ? Infinity : clientHeight;\n\n if (state.width !== w || state.height !== h) {\n state.width = w;\n state.height = h;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, w, h));\n });\n\n // If the clientWidth or clientHeight changed, scrollbars appeared or disappeared as\n // a result of the layout update. In this case, re-layout again to account for the\n // adjusted space. In very specific cases this might result in the scrollbars disappearing\n // again, resulting in extra padding. We stop after a maximum of two layout passes to avoid\n // an infinite loop. This matches how browsers behavior with native CSS grid layout.\n if (!isTestEnv && clientWidth !== dom.clientWidth || clientHeight !== dom.clientHeight) {\n state.width = dom.clientWidth;\n state.height = dom.clientHeight;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n });\n }\n }\n\n isUpdatingSize.current = false;\n });\n\n // Update visible rect when the content size changes, in case scrollbars need to appear or disappear.\n let lastContentSize = useRef<Size | null>(null);\n useLayoutEffect(() => {\n if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) {\n // React doesn't allow flushSync inside effects, so queue a microtask.\n // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).\n // If we are in an `act` environment, update immediately without a microtask so you don't need\n // to mock timers in tests. In this case, the update is synchronous already.\n // IS_REACT_ACT_ENVIRONMENT is used by React 18. Previous versions checked for the `jest` global.\n // https://github.com/reactwg/react-18/discussions/102\n // @ts-ignore\n if (typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined') {\n updateSize(fn => fn());\n } else {\n queueMicrotask(() => updateSize(flushSync));\n }\n }\n\n lastContentSize.current = contentSize;\n });\n\n let onResize = useCallback(() => {\n updateSize(flushSync);\n }, [updateSize]);\n\n // Watch border-box instead of of content-box so that we don't go into\n // an infinite loop when scrollbars appear or disappear.\n useResizeObserver({ref, box: 'border-box', onResize});\n\n let style: React.CSSProperties = {\n // Reset padding so that relative positioning works correctly. Padding will be done in JS layout.\n padding: 0,\n ...otherProps.style\n };\n\n if (scrollDirection === 'horizontal') {\n style.overflowX = 'auto';\n style.overflowY = 'hidden';\n } else if (scrollDirection === 'vertical' || contentSize.width === state.width) {\n // Set overflow-x: hidden if content size is equal to the width of the scroll view.\n // This prevents horizontal scrollbars from flickering during resizing due to resize observer\n // firing slower than the frame rate, which may cause an infinite re-render loop.\n style.overflowY = 'auto';\n style.overflowX = 'hidden';\n } else {\n style.overflow = 'auto';\n }\n\n innerStyle = {\n width: Number.isFinite(contentSize.width) ? contentSize.width : undefined,\n height: Number.isFinite(contentSize.height) ? contentSize.height : undefined,\n pointerEvents: isScrolling ? 'none' : 'auto',\n position: 'relative',\n ...innerStyle\n };\n\n return {\n scrollViewProps: {\n ...otherProps,\n style\n },\n contentProps: {\n role: 'presentation',\n style: innerStyle\n }\n };\n}\n"],"names":[],"version":3,"file":"ScrollView.main.js.map"}
@@ -100,9 +100,13 @@ function $44a6ee657928b002$export$2ea0c4974da4731b(props, ref) {
100
100
  };
101
101
  // eslint-disable-next-line react-hooks/exhaustive-deps
102
102
  }, []);
103
+ let isUpdatingSize = (0, $f9kpT$useRef)(false);
103
104
  let updateSize = (0, $f9kpT$useEffectEvent)((flush)=>{
104
105
  let dom = ref.current;
105
- if (!dom) return;
106
+ if (!dom && !isUpdatingSize.current) return;
107
+ // Prevent reentrancy when resize observer fires, triggers re-layout that results in
108
+ // content size update, causing below layout effect to fire. This avoids infinite loops.
109
+ isUpdatingSize.current = true;
106
110
  let isTestEnv = false;
107
111
  let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');
108
112
  let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');
@@ -129,30 +133,24 @@ function $44a6ee657928b002$export$2ea0c4974da4731b(props, ref) {
129
133
  });
130
134
  }
131
135
  }
136
+ isUpdatingSize.current = false;
132
137
  });
133
- let didUpdateSize = (0, $f9kpT$useRef)(false);
138
+ // Update visible rect when the content size changes, in case scrollbars need to appear or disappear.
139
+ let lastContentSize = (0, $f9kpT$useRef)(null);
134
140
  (0, $f9kpT$useLayoutEffect)(()=>{
135
- // React doesn't allow flushSync inside effects, so queue a microtask.
136
- // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
137
- queueMicrotask(()=>{
138
- if (!didUpdateSize.current) {
139
- didUpdateSize.current = true;
140
- updateSize((0, $f9kpT$flushSync));
141
- }
142
- });
143
- }, [
144
- updateSize
145
- ]);
146
- (0, $f9kpT$useEffect)(()=>{
147
- if (!didUpdateSize.current) {
148
- // If useEffect ran before the above microtask, we are in a synchronous render (e.g. act).
149
- // Update the size here so that you don't need to mock timers in tests.
150
- didUpdateSize.current = true;
151
- updateSize((fn)=>fn());
141
+ if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) {
142
+ // React doesn't allow flushSync inside effects, so queue a microtask.
143
+ // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
144
+ // If we are in an `act` environment, update immediately without a microtask so you don't need
145
+ // to mock timers in tests. In this case, the update is synchronous already.
146
+ // IS_REACT_ACT_ENVIRONMENT is used by React 18. Previous versions checked for the `jest` global.
147
+ // https://github.com/reactwg/react-18/discussions/102
148
+ // @ts-ignore
149
+ if (typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined') updateSize((fn)=>fn());
150
+ else queueMicrotask(()=>updateSize((0, $f9kpT$flushSync)));
152
151
  }
153
- }, [
154
- updateSize
155
- ]);
152
+ lastContentSize.current = contentSize;
153
+ });
156
154
  let onResize = (0, $f9kpT$useCallback)(()=>{
157
155
  updateSize((0, $f9kpT$flushSync));
158
156
  }, [
@@ -100,9 +100,13 @@ function $44a6ee657928b002$export$2ea0c4974da4731b(props, ref) {
100
100
  };
101
101
  // eslint-disable-next-line react-hooks/exhaustive-deps
102
102
  }, []);
103
+ let isUpdatingSize = (0, $f9kpT$useRef)(false);
103
104
  let updateSize = (0, $f9kpT$useEffectEvent)((flush)=>{
104
105
  let dom = ref.current;
105
- if (!dom) return;
106
+ if (!dom && !isUpdatingSize.current) return;
107
+ // Prevent reentrancy when resize observer fires, triggers re-layout that results in
108
+ // content size update, causing below layout effect to fire. This avoids infinite loops.
109
+ isUpdatingSize.current = true;
106
110
  let isTestEnv = false;
107
111
  let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');
108
112
  let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');
@@ -129,30 +133,24 @@ function $44a6ee657928b002$export$2ea0c4974da4731b(props, ref) {
129
133
  });
130
134
  }
131
135
  }
136
+ isUpdatingSize.current = false;
132
137
  });
133
- let didUpdateSize = (0, $f9kpT$useRef)(false);
138
+ // Update visible rect when the content size changes, in case scrollbars need to appear or disappear.
139
+ let lastContentSize = (0, $f9kpT$useRef)(null);
134
140
  (0, $f9kpT$useLayoutEffect)(()=>{
135
- // React doesn't allow flushSync inside effects, so queue a microtask.
136
- // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
137
- queueMicrotask(()=>{
138
- if (!didUpdateSize.current) {
139
- didUpdateSize.current = true;
140
- updateSize((0, $f9kpT$flushSync));
141
- }
142
- });
143
- }, [
144
- updateSize
145
- ]);
146
- (0, $f9kpT$useEffect)(()=>{
147
- if (!didUpdateSize.current) {
148
- // If useEffect ran before the above microtask, we are in a synchronous render (e.g. act).
149
- // Update the size here so that you don't need to mock timers in tests.
150
- didUpdateSize.current = true;
151
- updateSize((fn)=>fn());
141
+ if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) {
142
+ // React doesn't allow flushSync inside effects, so queue a microtask.
143
+ // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
144
+ // If we are in an `act` environment, update immediately without a microtask so you don't need
145
+ // to mock timers in tests. In this case, the update is synchronous already.
146
+ // IS_REACT_ACT_ENVIRONMENT is used by React 18. Previous versions checked for the `jest` global.
147
+ // https://github.com/reactwg/react-18/discussions/102
148
+ // @ts-ignore
149
+ if (typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined') updateSize((fn)=>fn());
150
+ else queueMicrotask(()=>updateSize((0, $f9kpT$flushSync)));
152
151
  }
153
- }, [
154
- updateSize
155
- ]);
152
+ lastContentSize.current = contentSize;
153
+ });
156
154
  let onResize = (0, $f9kpT$useCallback)(()=>{
157
155
  updateSize((0, $f9kpT$flushSync));
158
156
  }, [
@@ -1 +1 @@
1
- {"mappings":";;;;;;;AAAA;;;;;;;;;;CAUC,GAED,aAAa;;;;;;;AA4Bb,SAAS,iCAAW,KAAsB,EAAE,GAAwC;IAClF,MAAM,CAAA,GAAA,mBAAW,EAAE;IACnB,IAAI,mBAAC,eAAe,gBAAE,YAAY,EAAC,GAAG,0CAAc,OAAO;IAE3D,qBACE,gCAAC;QAAI,MAAK;QAAgB,GAAG,eAAe;QAAE,KAAK;qBACjD,gCAAC;QAAI,MAAK;QAAgB,GAAG,YAAY;OACtC,MAAM,QAAQ;AAIvB;AAEA,MAAM,yDAAuB,CAAA,GAAA,YAAI,EAAE,UAAU,CAAC;AAGvC,SAAS,0CAAc,KAAsB,EAAE,GAAkC;IACtF,IAAI,eACF,WAAW,uBACX,mBAAmB,cACnB,UAAU,iBACV,aAAa,eACb,WAAW,mBACX,kBAAkB,QAClB,GAAG,YACJ,GAAG;IAEJ,IAAI,QAAQ,CAAA,GAAA,aAAK,EAAE;QACjB,WAAW;QACX,YAAY;QACZ,eAAe;QACf,eAAe;QACf,OAAO;QACP,QAAQ;QACR,aAAa;IACf,GAAG,OAAO;IACV,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,gBAAQ;IAE1B,IAAI,CAAC,aAAa,aAAa,GAAG,CAAA,GAAA,eAAO,EAAE;IAC3C,IAAI,WAAW,CAAA,GAAA,kBAAU,EAAE,CAAC;QAC1B,IAAI,EAAE,MAAM,KAAK,EAAE,aAAa,EAC9B;QAGF,IAAI,MAAM,QAAQ,EAChB,MAAM,QAAQ,CAAC;QAGjB,CAAA,GAAA,gBAAQ,EAAE;YACR,IAAI,YAAY,EAAE,aAAa,CAAC,SAAS;YACzC,IAAI,aAAa,CAAA,GAAA,yCAAY,EAAE,EAAE,aAAa,EAAE;YAEhD,0EAA0E;YAC1E,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,YAAY,MAAM,GAAG,MAAM,MAAM;YACnF,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,YAAY,YAAY,KAAK,GAAG,MAAM,KAAK;YAEnF,oBAAoB,IAAI,CAAA,GAAA,WAAG,EAAE,MAAM,UAAU,EAAE,MAAM,SAAS,EAAE,MAAM,KAAK,EAAE,MAAM,MAAM;YAEzF,IAAI,CAAC,MAAM,WAAW,EAAE;gBACtB,MAAM,WAAW,GAAG;gBACpB,aAAa;gBAEb,mDAAmD;gBACnD,OAAO,aAAa,CAAC,IAAI,MAAM;gBAC/B,IAAI,eACF;YAEJ;YAEA,2DAA2D;YAC3D,6DAA6D;YAC7D,sCAAsC;YACtC,IAAI,MAAM,KAAK,GAAG;YAClB,IAAI,MAAM,aAAa,IAAI,MAAM,IAAI;gBACnC,MAAM,aAAa,GAAG,MAAM;gBAE5B,aAAa,MAAM,aAAa;gBAChC,MAAM,aAAa,GAAG,WAAW;oBAC/B,MAAM,WAAW,GAAG;oBACpB,aAAa;oBACb,MAAM,aAAa,GAAG;oBAEtB,OAAO,aAAa,CAAC,IAAI,MAAM;oBAC/B,IAAI,aACF;gBAEJ,GAAG;YACL;QACF;IACF,GAAG;QAAC;QAAO;QAAW;QAAO;QAAa;QAAqB;QAAe;KAAY;IAE1F,qFAAqF;IACrF,CAAA,GAAA,eAAO,EAAE,KAAK,UAAU;IAExB,4CAA4C;IAC5C,CAAA,GAAA,gBAAQ,EAAE;QACR,OAAO;YACL,aAAa,MAAM,aAAa;YAChC,IAAI,MAAM,WAAW,EACnB,OAAO,aAAa,CAAC,IAAI,MAAM;QAEnC;IACF,uDAAuD;IACvD,GAAG,EAAE;IAEL,IAAI,aAAa,CAAA,GAAA,qBAAa,EAAE,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO;QACrB,IAAI,CAAC,KACH;QAGF,IAAI,YAAY;QAChB,IAAI,sBAAsB,OAAO,mBAAmB,CAAC,OAAO,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC;QAC5F,IAAI,uBAAuB,OAAO,mBAAmB,CAAC,OAAO,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC;QAC7F,IAAI,cAAc,IAAI,WAAW;QACjC,IAAI,eAAe,IAAI,YAAY;QACnC,IAAI,IAAI,aAAa,CAAC,sBAAsB,WAAW;QACvD,IAAI,IAAI,aAAa,CAAC,uBAAuB,WAAW;QAExD,IAAI,MAAM,KAAK,KAAK,KAAK,MAAM,MAAM,KAAK,GAAG;YAC3C,MAAM,KAAK,GAAG;YACd,MAAM,MAAM,GAAG;YACf,MAAM;gBACJ,oBAAoB,IAAI,CAAA,GAAA,WAAG,EAAE,MAAM,UAAU,EAAE,MAAM,SAAS,EAAE,GAAG;YACrE;YAEA,oFAAoF;YACpF,kFAAkF;YAClF,0FAA0F;YAC1F,2FAA2F;YAC3F,oFAAoF;YACpF,IAAI,CAAC,aAAa,gBAAgB,IAAI,WAAW,IAAI,iBAAiB,IAAI,YAAY,EAAE;gBACtF,MAAM,KAAK,GAAG,IAAI,WAAW;gBAC7B,MAAM,MAAM,GAAG,IAAI,YAAY;gBAC/B,MAAM;oBACJ,oBAAoB,IAAI,CAAA,GAAA,WAAG,EAAE,MAAM,UAAU,EAAE,MAAM,SAAS,EAAE,MAAM,KAAK,EAAE,MAAM,MAAM;gBAC3F;YACF;QACF;IACF;IAEA,IAAI,gBAAgB,CAAA,GAAA,aAAK,EAAE;IAC3B,CAAA,GAAA,sBAAc,EAAE;QACd,sEAAsE;QACtE,4FAA4F;QAC5F,eAAe;YACb,IAAI,CAAC,cAAc,OAAO,EAAE;gBAC1B,cAAc,OAAO,GAAG;gBACxB,WAAW,CAAA,GAAA,gBAAQ;YACrB;QACF;IACF,GAAG;QAAC;KAAW;IACf,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,CAAC,cAAc,OAAO,EAAE;YAC1B,0FAA0F;YAC1F,uEAAuE;YACvE,cAAc,OAAO,GAAG;YACxB,WAAW,CAAA,KAAM;QACnB;IACF,GAAG;QAAC;KAAW;IACf,IAAI,WAAW,CAAA,GAAA,kBAAU,EAAE;QACzB,WAAW,CAAA,GAAA,gBAAQ;IACrB,GAAG;QAAC;KAAW;IAEf,sEAAsE;IACtE,wDAAwD;IACxD,CAAA,GAAA,wBAAgB,EAAE;aAAC;QAAK,KAAK;kBAAc;IAAQ;IAEnD,IAAI,QAA6B;QAC/B,iGAAiG;QACjG,SAAS;QACT,GAAG,WAAW,KAAK;IACrB;IAEA,IAAI,oBAAoB,cAAc;QACpC,MAAM,SAAS,GAAG;QAClB,MAAM,SAAS,GAAG;IACpB,OAAO,IAAI,oBAAoB,cAAc,YAAY,KAAK,KAAK,MAAM,KAAK,EAAE;QAC9E,mFAAmF;QACnF,6FAA6F;QAC7F,iFAAiF;QACjF,MAAM,SAAS,GAAG;QAClB,MAAM,SAAS,GAAG;IACpB,OACE,MAAM,QAAQ,GAAG;IAGnB,aAAa;QACX,OAAO,OAAO,QAAQ,CAAC,YAAY,KAAK,IAAI,YAAY,KAAK,GAAG;QAChE,QAAQ,OAAO,QAAQ,CAAC,YAAY,MAAM,IAAI,YAAY,MAAM,GAAG;QACnE,eAAe,cAAc,SAAS;QACtC,UAAU;QACV,GAAG,UAAU;IACf;IAEA,OAAO;QACL,iBAAiB;YACf,GAAG,UAAU;mBACb;QACF;QACA,cAAc;YACZ,MAAM;YACN,OAAO;QACT;IACF;AACF","sources":["packages/@react-aria/virtualizer/src/ScrollView.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// @ts-ignore\nimport {flushSync} from 'react-dom';\nimport {getScrollLeft} from './utils';\nimport React, {\n CSSProperties,\n ForwardedRef,\n HTMLAttributes,\n ReactNode,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n useState\n} from 'react';\nimport {Rect, Size} from '@react-stately/virtualizer';\nimport {useEffectEvent, useEvent, useLayoutEffect, useObjectRef, useResizeObserver} from '@react-aria/utils';\nimport {useLocale} from '@react-aria/i18n';\n\ninterface ScrollViewProps extends HTMLAttributes<HTMLElement> {\n contentSize: Size,\n onVisibleRectChange: (rect: Rect) => void,\n children?: ReactNode,\n innerStyle?: CSSProperties,\n onScrollStart?: () => void,\n onScrollEnd?: () => void,\n scrollDirection?: 'horizontal' | 'vertical' | 'both'\n}\n\nfunction ScrollView(props: ScrollViewProps, ref: ForwardedRef<HTMLDivElement | null>) {\n ref = useObjectRef(ref);\n let {scrollViewProps, contentProps} = useScrollView(props, ref);\n\n return (\n <div role=\"presentation\" {...scrollViewProps} ref={ref}>\n <div role=\"presentation\" {...contentProps}>\n {props.children}\n </div>\n </div>\n );\n}\n\nconst ScrollViewForwardRef = React.forwardRef(ScrollView);\nexport {ScrollViewForwardRef as ScrollView};\n\nexport function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement | null>) {\n let {\n contentSize,\n onVisibleRectChange,\n innerStyle,\n onScrollStart,\n onScrollEnd,\n scrollDirection = 'both',\n ...otherProps\n } = props;\n\n let state = useRef({\n scrollTop: 0,\n scrollLeft: 0,\n scrollEndTime: 0,\n scrollTimeout: null,\n width: 0,\n height: 0,\n isScrolling: false\n }).current;\n let {direction} = useLocale();\n\n let [isScrolling, setScrolling] = useState(false);\n let onScroll = useCallback((e) => {\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (props.onScroll) {\n props.onScroll(e);\n }\n\n flushSync(() => {\n let scrollTop = e.currentTarget.scrollTop;\n let scrollLeft = getScrollLeft(e.currentTarget, direction);\n\n // Prevent rubber band scrolling from shaking when scrolling out of bounds\n state.scrollTop = Math.max(0, Math.min(scrollTop, contentSize.height - state.height));\n state.scrollLeft = Math.max(0, Math.min(scrollLeft, contentSize.width - state.width));\n\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n\n if (!state.isScrolling) {\n state.isScrolling = true;\n setScrolling(true);\n\n // Pause typekit MutationObserver during scrolling.\n window.dispatchEvent(new Event('tk.disconnect-observer'));\n if (onScrollStart) {\n onScrollStart();\n }\n }\n\n // So we don't constantly call clearTimeout and setTimeout,\n // keep track of the current timeout time and only reschedule\n // the timer when it is getting close.\n let now = Date.now();\n if (state.scrollEndTime <= now + 50) {\n state.scrollEndTime = now + 300;\n\n clearTimeout(state.scrollTimeout);\n state.scrollTimeout = setTimeout(() => {\n state.isScrolling = false;\n setScrolling(false);\n state.scrollTimeout = null;\n\n window.dispatchEvent(new Event('tk.connect-observer'));\n if (onScrollEnd) {\n onScrollEnd();\n }\n }, 300);\n }\n });\n }, [props, direction, state, contentSize, onVisibleRectChange, onScrollStart, onScrollEnd]);\n\n // Attach event directly to ref so RAC Virtualizer doesn't need to send props upward.\n useEvent(ref, 'scroll', onScroll);\n\n // eslint-disable-next-line arrow-body-style\n useEffect(() => {\n return () => {\n clearTimeout(state.scrollTimeout);\n if (state.isScrolling) {\n window.dispatchEvent(new Event('tk.connect-observer'));\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n let updateSize = useEffectEvent((flush: typeof flushSync) => {\n let dom = ref.current;\n if (!dom) {\n return;\n }\n\n let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;\n let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');\n let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');\n let clientWidth = dom.clientWidth;\n let clientHeight = dom.clientHeight;\n let w = isTestEnv && !isClientWidthMocked ? Infinity : clientWidth;\n let h = isTestEnv && !isClientHeightMocked ? Infinity : clientHeight;\n\n if (state.width !== w || state.height !== h) {\n state.width = w;\n state.height = h;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, w, h));\n });\n\n // If the clientWidth or clientHeight changed, scrollbars appeared or disappeared as\n // a result of the layout update. In this case, re-layout again to account for the\n // adjusted space. In very specific cases this might result in the scrollbars disappearing\n // again, resulting in extra padding. We stop after a maximum of two layout passes to avoid\n // an infinite loop. This matches how browsers behavior with native CSS grid layout.\n if (!isTestEnv && clientWidth !== dom.clientWidth || clientHeight !== dom.clientHeight) {\n state.width = dom.clientWidth;\n state.height = dom.clientHeight;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n });\n }\n }\n });\n\n let didUpdateSize = useRef(false);\n useLayoutEffect(() => {\n // React doesn't allow flushSync inside effects, so queue a microtask.\n // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).\n queueMicrotask(() => {\n if (!didUpdateSize.current) {\n didUpdateSize.current = true;\n updateSize(flushSync);\n }\n });\n }, [updateSize]);\n useEffect(() => {\n if (!didUpdateSize.current) {\n // If useEffect ran before the above microtask, we are in a synchronous render (e.g. act).\n // Update the size here so that you don't need to mock timers in tests.\n didUpdateSize.current = true;\n updateSize(fn => fn());\n }\n }, [updateSize]);\n let onResize = useCallback(() => {\n updateSize(flushSync);\n }, [updateSize]);\n\n // Watch border-box instead of of content-box so that we don't go into\n // an infinite loop when scrollbars appear or disappear.\n useResizeObserver({ref, box: 'border-box', onResize});\n\n let style: React.CSSProperties = {\n // Reset padding so that relative positioning works correctly. Padding will be done in JS layout.\n padding: 0,\n ...otherProps.style\n };\n\n if (scrollDirection === 'horizontal') {\n style.overflowX = 'auto';\n style.overflowY = 'hidden';\n } else if (scrollDirection === 'vertical' || contentSize.width === state.width) {\n // Set overflow-x: hidden if content size is equal to the width of the scroll view.\n // This prevents horizontal scrollbars from flickering during resizing due to resize observer\n // firing slower than the frame rate, which may cause an infinite re-render loop.\n style.overflowY = 'auto';\n style.overflowX = 'hidden';\n } else {\n style.overflow = 'auto';\n }\n\n innerStyle = {\n width: Number.isFinite(contentSize.width) ? contentSize.width : undefined,\n height: Number.isFinite(contentSize.height) ? contentSize.height : undefined,\n pointerEvents: isScrolling ? 'none' : 'auto',\n position: 'relative',\n ...innerStyle\n };\n\n return {\n scrollViewProps: {\n ...otherProps,\n style\n },\n contentProps: {\n role: 'presentation',\n style: innerStyle\n }\n };\n}\n"],"names":[],"version":3,"file":"ScrollView.module.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/virtualizer/src/ScrollView.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// @ts-ignore\nimport {flushSync} from 'react-dom';\nimport {getScrollLeft} from './utils';\nimport React, {\n CSSProperties,\n ForwardedRef,\n HTMLAttributes,\n ReactNode,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n useState\n} from 'react';\nimport {Rect, Size} from '@react-stately/virtualizer';\nimport {useEffectEvent, useEvent, useLayoutEffect, useObjectRef, useResizeObserver} from '@react-aria/utils';\nimport {useLocale} from '@react-aria/i18n';\n\ninterface ScrollViewProps extends HTMLAttributes<HTMLElement> {\n contentSize: Size,\n onVisibleRectChange: (rect: Rect) => void,\n children?: ReactNode,\n innerStyle?: CSSProperties,\n onScrollStart?: () => void,\n onScrollEnd?: () => void,\n scrollDirection?: 'horizontal' | 'vertical' | 'both'\n}\n\nfunction ScrollView(props: ScrollViewProps, ref: ForwardedRef<HTMLDivElement | null>) {\n ref = useObjectRef(ref);\n let {scrollViewProps, contentProps} = useScrollView(props, ref);\n\n return (\n <div role=\"presentation\" {...scrollViewProps} ref={ref}>\n <div role=\"presentation\" {...contentProps}>\n {props.children}\n </div>\n </div>\n );\n}\n\nconst ScrollViewForwardRef = React.forwardRef(ScrollView);\nexport {ScrollViewForwardRef as ScrollView};\n\nexport function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement | null>) {\n let {\n contentSize,\n onVisibleRectChange,\n innerStyle,\n onScrollStart,\n onScrollEnd,\n scrollDirection = 'both',\n ...otherProps\n } = props;\n\n let state = useRef({\n scrollTop: 0,\n scrollLeft: 0,\n scrollEndTime: 0,\n scrollTimeout: null,\n width: 0,\n height: 0,\n isScrolling: false\n }).current;\n let {direction} = useLocale();\n\n let [isScrolling, setScrolling] = useState(false);\n let onScroll = useCallback((e) => {\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (props.onScroll) {\n props.onScroll(e);\n }\n\n flushSync(() => {\n let scrollTop = e.currentTarget.scrollTop;\n let scrollLeft = getScrollLeft(e.currentTarget, direction);\n\n // Prevent rubber band scrolling from shaking when scrolling out of bounds\n state.scrollTop = Math.max(0, Math.min(scrollTop, contentSize.height - state.height));\n state.scrollLeft = Math.max(0, Math.min(scrollLeft, contentSize.width - state.width));\n\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n\n if (!state.isScrolling) {\n state.isScrolling = true;\n setScrolling(true);\n\n // Pause typekit MutationObserver during scrolling.\n window.dispatchEvent(new Event('tk.disconnect-observer'));\n if (onScrollStart) {\n onScrollStart();\n }\n }\n\n // So we don't constantly call clearTimeout and setTimeout,\n // keep track of the current timeout time and only reschedule\n // the timer when it is getting close.\n let now = Date.now();\n if (state.scrollEndTime <= now + 50) {\n state.scrollEndTime = now + 300;\n\n clearTimeout(state.scrollTimeout);\n state.scrollTimeout = setTimeout(() => {\n state.isScrolling = false;\n setScrolling(false);\n state.scrollTimeout = null;\n\n window.dispatchEvent(new Event('tk.connect-observer'));\n if (onScrollEnd) {\n onScrollEnd();\n }\n }, 300);\n }\n });\n }, [props, direction, state, contentSize, onVisibleRectChange, onScrollStart, onScrollEnd]);\n\n // Attach event directly to ref so RAC Virtualizer doesn't need to send props upward.\n useEvent(ref, 'scroll', onScroll);\n\n // eslint-disable-next-line arrow-body-style\n useEffect(() => {\n return () => {\n clearTimeout(state.scrollTimeout);\n if (state.isScrolling) {\n window.dispatchEvent(new Event('tk.connect-observer'));\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n let isUpdatingSize = useRef(false);\n let updateSize = useEffectEvent((flush: typeof flushSync) => {\n let dom = ref.current;\n if (!dom && !isUpdatingSize.current) {\n return;\n }\n\n // Prevent reentrancy when resize observer fires, triggers re-layout that results in\n // content size update, causing below layout effect to fire. This avoids infinite loops.\n isUpdatingSize.current = true;\n\n let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;\n let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');\n let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');\n let clientWidth = dom.clientWidth;\n let clientHeight = dom.clientHeight;\n let w = isTestEnv && !isClientWidthMocked ? Infinity : clientWidth;\n let h = isTestEnv && !isClientHeightMocked ? Infinity : clientHeight;\n\n if (state.width !== w || state.height !== h) {\n state.width = w;\n state.height = h;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, w, h));\n });\n\n // If the clientWidth or clientHeight changed, scrollbars appeared or disappeared as\n // a result of the layout update. In this case, re-layout again to account for the\n // adjusted space. In very specific cases this might result in the scrollbars disappearing\n // again, resulting in extra padding. We stop after a maximum of two layout passes to avoid\n // an infinite loop. This matches how browsers behavior with native CSS grid layout.\n if (!isTestEnv && clientWidth !== dom.clientWidth || clientHeight !== dom.clientHeight) {\n state.width = dom.clientWidth;\n state.height = dom.clientHeight;\n flush(() => {\n onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height));\n });\n }\n }\n\n isUpdatingSize.current = false;\n });\n\n // Update visible rect when the content size changes, in case scrollbars need to appear or disappear.\n let lastContentSize = useRef<Size | null>(null);\n useLayoutEffect(() => {\n if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) {\n // React doesn't allow flushSync inside effects, so queue a microtask.\n // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).\n // If we are in an `act` environment, update immediately without a microtask so you don't need\n // to mock timers in tests. In this case, the update is synchronous already.\n // IS_REACT_ACT_ENVIRONMENT is used by React 18. Previous versions checked for the `jest` global.\n // https://github.com/reactwg/react-18/discussions/102\n // @ts-ignore\n if (typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined') {\n updateSize(fn => fn());\n } else {\n queueMicrotask(() => updateSize(flushSync));\n }\n }\n\n lastContentSize.current = contentSize;\n });\n\n let onResize = useCallback(() => {\n updateSize(flushSync);\n }, [updateSize]);\n\n // Watch border-box instead of of content-box so that we don't go into\n // an infinite loop when scrollbars appear or disappear.\n useResizeObserver({ref, box: 'border-box', onResize});\n\n let style: React.CSSProperties = {\n // Reset padding so that relative positioning works correctly. Padding will be done in JS layout.\n padding: 0,\n ...otherProps.style\n };\n\n if (scrollDirection === 'horizontal') {\n style.overflowX = 'auto';\n style.overflowY = 'hidden';\n } else if (scrollDirection === 'vertical' || contentSize.width === state.width) {\n // Set overflow-x: hidden if content size is equal to the width of the scroll view.\n // This prevents horizontal scrollbars from flickering during resizing due to resize observer\n // firing slower than the frame rate, which may cause an infinite re-render loop.\n style.overflowY = 'auto';\n style.overflowX = 'hidden';\n } else {\n style.overflow = 'auto';\n }\n\n innerStyle = {\n width: Number.isFinite(contentSize.width) ? contentSize.width : undefined,\n height: Number.isFinite(contentSize.height) ? contentSize.height : undefined,\n pointerEvents: isScrolling ? 'none' : 'auto',\n position: 'relative',\n ...innerStyle\n };\n\n return {\n scrollViewProps: {\n ...otherProps,\n style\n },\n contentProps: {\n role: 'presentation',\n style: innerStyle\n }\n };\n}\n"],"names":[],"version":3,"file":"ScrollView.module.js.map"}
@@ -27,7 +27,7 @@ $parcel$export(module.exports, "layoutInfoToStyle", () => $d6a26279cc31826b$expo
27
27
 
28
28
 
29
29
  function $d6a26279cc31826b$export$6796df8ba7398521(props) {
30
- let { className: className, layoutInfo: layoutInfo, virtualizer: virtualizer, parent: parent, children: children } = props;
30
+ let { style: style, className: className, layoutInfo: layoutInfo, virtualizer: virtualizer, parent: parent, children: children } = props;
31
31
  let { direction: direction } = (0, $eXWCF$reactariai18n.useLocale)();
32
32
  let ref = (0, $eXWCF$react.useRef)(undefined);
33
33
  (0, $7d70e069fceb2deb$exports.useVirtualizerItem)({
@@ -39,7 +39,10 @@ function $d6a26279cc31826b$export$6796df8ba7398521(props) {
39
39
  role: "presentation",
40
40
  ref: ref,
41
41
  className: className,
42
- style: $d6a26279cc31826b$export$1481e64fbe01b8b3(layoutInfo, direction, parent)
42
+ style: {
43
+ ...$d6a26279cc31826b$export$1481e64fbe01b8b3(layoutInfo, direction, parent),
44
+ ...style
45
+ }
43
46
  }, children);
44
47
  }
45
48
  let $d6a26279cc31826b$var$cache = new WeakMap();
@@ -54,8 +57,12 @@ function $d6a26279cc31826b$export$1481e64fbe01b8b3(layoutInfo, dir, parent) {
54
57
  if (cached.top === top && cached[xProperty] === x) return cached;
55
58
  }
56
59
  let rectStyles = {
57
- top: layoutInfo.rect.y - (parent ? parent.rect.y : 0),
58
- [xProperty]: layoutInfo.rect.x - (parent ? parent.rect.x : 0),
60
+ // TODO: For layoutInfos that are sticky that have parents with overflow visible, their "top" will be relative to the to the nearest scrolling container
61
+ // which WON'T be the parent since the parent has overflow visible. This means we shouldn't offset the height by the parent's position
62
+ // Not 100% about this change here since it is quite ambigious what the scrolling container maybe and how its top is positioned with respect to the
63
+ // calculated layoutInfo.y here
64
+ top: layoutInfo.rect.y - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.y : 0),
65
+ [xProperty]: layoutInfo.rect.x - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.x : 0),
59
66
  width: layoutInfo.rect.width,
60
67
  height: layoutInfo.rect.height
61
68
  };
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;AAcM,SAAS,0CAAgB,KAA2B;IACzD,IAAI,aAAC,SAAS,cAAE,UAAU,eAAE,WAAW,UAAE,MAAM,YAAE,QAAQ,EAAC,GAAG;IAC7D,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,8BAAQ;IAC1B,IAAI,MAAM,CAAA,GAAA,mBAAK,EAAE;IACjB,CAAA,GAAA,4CAAiB,EAAE;oBACjB;qBACA;aACA;IACF;IAEA,qBACE,0DAAC;QAAI,MAAK;QAAe,KAAK;QAAK,WAAW;QAAW,OAAO,0CAAkB,YAAY,WAAW;OACtG;AAGP;AAEA,IAAI,8BAAQ,IAAI;AACT,SAAS,0CAAkB,UAAsB,EAAE,GAAc,EAAE,MAA0B;IAClG,IAAI,YAAY,QAAQ,QAAQ,UAAU;IAC1C,IAAI,SAAS,4BAAM,GAAG,CAAC;IACvB,IAAI,UAAU,MAAM,CAAC,UAAU,IAAI,MAAM;QACvC,IAAI,CAAC,QACH,OAAO;QAGT,6CAA6C;QAC7C,IAAI,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QAC3C,IAAI,IAAI,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,GAAG,KAAK,OAAO,MAAM,CAAC,UAAU,KAAK,GAC9C,OAAO;IAEX;IAEA,IAAI,aAAa;QACf,KAAK,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,SAAS,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QACnD,CAAC,UAAU,EAAE,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,SAAS,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QAC3D,OAAO,WAAW,IAAI,CAAC,KAAK;QAC5B,QAAQ,WAAW,IAAI,CAAC,MAAM;IAChC;IAEA,sEAAsE;IACtE,OAAO,OAAO,CAAC,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM;QAC9C,IAAI,CAAC,OAAO,QAAQ,CAAC,QACnB,UAAU,CAAC,IAAI,GAAG;IAEtB;IAEA,IAAI,QAAuB;QACzB,UAAU,WAAW,QAAQ,GAAG,WAAW;QAC3C,qJAAqJ;QACrJ,SAAS,WAAW,QAAQ,GAAG,iBAAiB;QAChD,UAAU,WAAW,aAAa,GAAG,YAAY;QACjD,SAAS,WAAW,OAAO;QAC3B,QAAQ,WAAW,MAAM;QACzB,WAAW,WAAW,SAAS;QAC/B,SAAS;QACT,GAAG,UAAU;IACf;IAEA,4BAAM,GAAG,CAAC,YAAY;IACtB,OAAO;AACT","sources":["packages/@react-aria/virtualizer/src/VirtualizerItem.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Direction} from '@react-types/shared';\nimport {LayoutInfo} from '@react-stately/virtualizer';\nimport React, {CSSProperties, ReactNode, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useVirtualizerItem, VirtualizerItemOptions} from './useVirtualizerItem';\n\ninterface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {\n parent?: LayoutInfo | null,\n className?: string,\n children: ReactNode\n}\n\nexport function VirtualizerItem(props: VirtualizerItemProps) {\n let {className, layoutInfo, virtualizer, parent, children} = props;\n let {direction} = useLocale();\n let ref = useRef(undefined);\n useVirtualizerItem({\n layoutInfo,\n virtualizer,\n ref\n });\n\n return (\n <div role=\"presentation\" ref={ref} className={className} style={layoutInfoToStyle(layoutInfo, direction, parent)}>\n {children}\n </div>\n );\n}\n\nlet cache = new WeakMap();\nexport function layoutInfoToStyle(layoutInfo: LayoutInfo, dir: Direction, parent?: LayoutInfo | null): CSSProperties {\n let xProperty = dir === 'rtl' ? 'right' : 'left';\n let cached = cache.get(layoutInfo);\n if (cached && cached[xProperty] != null) {\n if (!parent) {\n return cached;\n }\n\n // Invalidate if the parent position changed.\n let top = layoutInfo.rect.y - parent.rect.y;\n let x = layoutInfo.rect.x - parent.rect.x;\n if (cached.top === top && cached[xProperty] === x) {\n return cached;\n }\n }\n\n let rectStyles = {\n top: layoutInfo.rect.y - (parent ? parent.rect.y : 0),\n [xProperty]: layoutInfo.rect.x - (parent ? parent.rect.x : 0),\n width: layoutInfo.rect.width,\n height: layoutInfo.rect.height\n };\n\n // Get rid of any non finite values since they aren't valid css values\n Object.entries(rectStyles).forEach(([key, value]) => {\n if (!Number.isFinite(value)) {\n rectStyles[key] = undefined;\n }\n });\n\n let style: CSSProperties = {\n position: layoutInfo.isSticky ? 'sticky' : 'absolute',\n // Sticky elements are positioned in normal document flow. Display inline-block so that they don't push other sticky columns onto the following rows.\n display: layoutInfo.isSticky ? 'inline-block' : undefined,\n overflow: layoutInfo.allowOverflow ? 'visible' : 'hidden',\n opacity: layoutInfo.opacity,\n zIndex: layoutInfo.zIndex,\n transform: layoutInfo.transform,\n contain: 'size layout style',\n ...rectStyles\n };\n\n cache.set(layoutInfo, style);\n return style;\n}\n"],"names":[],"version":3,"file":"VirtualizerItem.main.js.map"}
1
+ {"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;AAeM,SAAS,0CAAgB,KAA2B;IACzD,IAAI,SAAC,KAAK,aAAE,SAAS,cAAE,UAAU,eAAE,WAAW,UAAE,MAAM,YAAE,QAAQ,EAAC,GAAG;IACpE,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,8BAAQ;IAC1B,IAAI,MAAM,CAAA,GAAA,mBAAK,EAAE;IACjB,CAAA,GAAA,4CAAiB,EAAE;oBACjB;qBACA;aACA;IACF;IAEA,qBACE,0DAAC;QAAI,MAAK;QAAe,KAAK;QAAK,WAAW;QAAW,OAAO;YAAC,GAAG,0CAAkB,YAAY,WAAW,OAAO;YAAE,GAAG,KAAK;QAAA;OAC3H;AAGP;AAEA,IAAI,8BAAQ,IAAI;AACT,SAAS,0CAAkB,UAAsB,EAAE,GAAc,EAAE,MAA0B;IAClG,IAAI,YAAY,QAAQ,QAAQ,UAAU;IAC1C,IAAI,SAAS,4BAAM,GAAG,CAAC;IACvB,IAAI,UAAU,MAAM,CAAC,UAAU,IAAI,MAAM;QACvC,IAAI,CAAC,QACH,OAAO;QAGT,6CAA6C;QAC7C,IAAI,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QAC3C,IAAI,IAAI,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,GAAG,KAAK,OAAO,MAAM,CAAC,UAAU,KAAK,GAC9C,OAAO;IAEX;IAEA,IAAI,aAAa;QACf,wJAAwJ;QACxJ,sIAAsI;QACtI,mJAAmJ;QACnJ,+BAA+B;QAC/B,KAAK,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,UAAU,CAAE,CAAA,OAAO,aAAa,IAAI,WAAW,QAAQ,AAAD,IAAK,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QACrG,CAAC,UAAU,EAAE,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,UAAU,CAAE,CAAA,OAAO,aAAa,IAAI,WAAW,QAAQ,AAAD,IAAK,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QAC7G,OAAO,WAAW,IAAI,CAAC,KAAK;QAC5B,QAAQ,WAAW,IAAI,CAAC,MAAM;IAChC;IAEA,sEAAsE;IACtE,OAAO,OAAO,CAAC,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM;QAC9C,IAAI,CAAC,OAAO,QAAQ,CAAC,QACnB,UAAU,CAAC,IAAI,GAAG;IAEtB;IAEA,IAAI,QAAuB;QACzB,UAAU,WAAW,QAAQ,GAAG,WAAW;QAC3C,qJAAqJ;QACrJ,SAAS,WAAW,QAAQ,GAAG,iBAAiB;QAChD,UAAU,WAAW,aAAa,GAAG,YAAY;QACjD,SAAS,WAAW,OAAO;QAC3B,QAAQ,WAAW,MAAM;QACzB,WAAW,WAAW,SAAS;QAC/B,SAAS;QACT,GAAG,UAAU;IACf;IAEA,4BAAM,GAAG,CAAC,YAAY;IACtB,OAAO;AACT","sources":["packages/@react-aria/virtualizer/src/VirtualizerItem.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Direction} from '@react-types/shared';\nimport {LayoutInfo} from '@react-stately/virtualizer';\nimport React, {CSSProperties, ReactNode, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useVirtualizerItem, VirtualizerItemOptions} from './useVirtualizerItem';\n\ninterface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {\n parent?: LayoutInfo | null,\n style?: CSSProperties,\n className?: string,\n children: ReactNode\n}\n\nexport function VirtualizerItem(props: VirtualizerItemProps) {\n let {style, className, layoutInfo, virtualizer, parent, children} = props;\n let {direction} = useLocale();\n let ref = useRef(undefined);\n useVirtualizerItem({\n layoutInfo,\n virtualizer,\n ref\n });\n\n return (\n <div role=\"presentation\" ref={ref} className={className} style={{...layoutInfoToStyle(layoutInfo, direction, parent), ...style}}>\n {children}\n </div>\n );\n}\n\nlet cache = new WeakMap();\nexport function layoutInfoToStyle(layoutInfo: LayoutInfo, dir: Direction, parent?: LayoutInfo | null): CSSProperties {\n let xProperty = dir === 'rtl' ? 'right' : 'left';\n let cached = cache.get(layoutInfo);\n if (cached && cached[xProperty] != null) {\n if (!parent) {\n return cached;\n }\n\n // Invalidate if the parent position changed.\n let top = layoutInfo.rect.y - parent.rect.y;\n let x = layoutInfo.rect.x - parent.rect.x;\n if (cached.top === top && cached[xProperty] === x) {\n return cached;\n }\n }\n\n let rectStyles = {\n // TODO: For layoutInfos that are sticky that have parents with overflow visible, their \"top\" will be relative to the to the nearest scrolling container\n // which WON'T be the parent since the parent has overflow visible. This means we shouldn't offset the height by the parent's position\n // Not 100% about this change here since it is quite ambigious what the scrolling container maybe and how its top is positioned with respect to the\n // calculated layoutInfo.y here\n top: layoutInfo.rect.y - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.y : 0),\n [xProperty]: layoutInfo.rect.x - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.x : 0),\n width: layoutInfo.rect.width,\n height: layoutInfo.rect.height\n };\n\n // Get rid of any non finite values since they aren't valid css values\n Object.entries(rectStyles).forEach(([key, value]) => {\n if (!Number.isFinite(value)) {\n rectStyles[key] = undefined;\n }\n });\n\n let style: CSSProperties = {\n position: layoutInfo.isSticky ? 'sticky' : 'absolute',\n // Sticky elements are positioned in normal document flow. Display inline-block so that they don't push other sticky columns onto the following rows.\n display: layoutInfo.isSticky ? 'inline-block' : undefined,\n overflow: layoutInfo.allowOverflow ? 'visible' : 'hidden',\n opacity: layoutInfo.opacity,\n zIndex: layoutInfo.zIndex,\n transform: layoutInfo.transform,\n contain: 'size layout style',\n ...rectStyles\n };\n\n cache.set(layoutInfo, style);\n return style;\n}\n"],"names":[],"version":3,"file":"VirtualizerItem.main.js.map"}
@@ -16,7 +16,7 @@ import {useLocale as $ivH3G$useLocale} from "@react-aria/i18n";
16
16
 
17
17
 
18
18
  function $ccf8a0a04e4175ae$export$6796df8ba7398521(props) {
19
- let { className: className, layoutInfo: layoutInfo, virtualizer: virtualizer, parent: parent, children: children } = props;
19
+ let { style: style, className: className, layoutInfo: layoutInfo, virtualizer: virtualizer, parent: parent, children: children } = props;
20
20
  let { direction: direction } = (0, $ivH3G$useLocale)();
21
21
  let ref = (0, $ivH3G$useRef)(undefined);
22
22
  (0, $47736c1e63ba1c6d$export$1da781778207e0a2)({
@@ -28,7 +28,10 @@ function $ccf8a0a04e4175ae$export$6796df8ba7398521(props) {
28
28
  role: "presentation",
29
29
  ref: ref,
30
30
  className: className,
31
- style: $ccf8a0a04e4175ae$export$1481e64fbe01b8b3(layoutInfo, direction, parent)
31
+ style: {
32
+ ...$ccf8a0a04e4175ae$export$1481e64fbe01b8b3(layoutInfo, direction, parent),
33
+ ...style
34
+ }
32
35
  }, children);
33
36
  }
34
37
  let $ccf8a0a04e4175ae$var$cache = new WeakMap();
@@ -43,8 +46,12 @@ function $ccf8a0a04e4175ae$export$1481e64fbe01b8b3(layoutInfo, dir, parent) {
43
46
  if (cached.top === top && cached[xProperty] === x) return cached;
44
47
  }
45
48
  let rectStyles = {
46
- top: layoutInfo.rect.y - (parent ? parent.rect.y : 0),
47
- [xProperty]: layoutInfo.rect.x - (parent ? parent.rect.x : 0),
49
+ // TODO: For layoutInfos that are sticky that have parents with overflow visible, their "top" will be relative to the to the nearest scrolling container
50
+ // which WON'T be the parent since the parent has overflow visible. This means we shouldn't offset the height by the parent's position
51
+ // Not 100% about this change here since it is quite ambigious what the scrolling container maybe and how its top is positioned with respect to the
52
+ // calculated layoutInfo.y here
53
+ top: layoutInfo.rect.y - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.y : 0),
54
+ [xProperty]: layoutInfo.rect.x - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.x : 0),
48
55
  width: layoutInfo.rect.width,
49
56
  height: layoutInfo.rect.height
50
57
  };
@@ -16,7 +16,7 @@ import {useLocale as $ivH3G$useLocale} from "@react-aria/i18n";
16
16
 
17
17
 
18
18
  function $ccf8a0a04e4175ae$export$6796df8ba7398521(props) {
19
- let { className: className, layoutInfo: layoutInfo, virtualizer: virtualizer, parent: parent, children: children } = props;
19
+ let { style: style, className: className, layoutInfo: layoutInfo, virtualizer: virtualizer, parent: parent, children: children } = props;
20
20
  let { direction: direction } = (0, $ivH3G$useLocale)();
21
21
  let ref = (0, $ivH3G$useRef)(undefined);
22
22
  (0, $47736c1e63ba1c6d$export$1da781778207e0a2)({
@@ -28,7 +28,10 @@ function $ccf8a0a04e4175ae$export$6796df8ba7398521(props) {
28
28
  role: "presentation",
29
29
  ref: ref,
30
30
  className: className,
31
- style: $ccf8a0a04e4175ae$export$1481e64fbe01b8b3(layoutInfo, direction, parent)
31
+ style: {
32
+ ...$ccf8a0a04e4175ae$export$1481e64fbe01b8b3(layoutInfo, direction, parent),
33
+ ...style
34
+ }
32
35
  }, children);
33
36
  }
34
37
  let $ccf8a0a04e4175ae$var$cache = new WeakMap();
@@ -43,8 +46,12 @@ function $ccf8a0a04e4175ae$export$1481e64fbe01b8b3(layoutInfo, dir, parent) {
43
46
  if (cached.top === top && cached[xProperty] === x) return cached;
44
47
  }
45
48
  let rectStyles = {
46
- top: layoutInfo.rect.y - (parent ? parent.rect.y : 0),
47
- [xProperty]: layoutInfo.rect.x - (parent ? parent.rect.x : 0),
49
+ // TODO: For layoutInfos that are sticky that have parents with overflow visible, their "top" will be relative to the to the nearest scrolling container
50
+ // which WON'T be the parent since the parent has overflow visible. This means we shouldn't offset the height by the parent's position
51
+ // Not 100% about this change here since it is quite ambigious what the scrolling container maybe and how its top is positioned with respect to the
52
+ // calculated layoutInfo.y here
53
+ top: layoutInfo.rect.y - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.y : 0),
54
+ [xProperty]: layoutInfo.rect.x - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.x : 0),
48
55
  width: layoutInfo.rect.width,
49
56
  height: layoutInfo.rect.height
50
57
  };
@@ -1 +1 @@
1
- {"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AAcM,SAAS,0CAAgB,KAA2B;IACzD,IAAI,aAAC,SAAS,cAAE,UAAU,eAAE,WAAW,UAAE,MAAM,YAAE,QAAQ,EAAC,GAAG;IAC7D,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,gBAAQ;IAC1B,IAAI,MAAM,CAAA,GAAA,aAAK,EAAE;IACjB,CAAA,GAAA,yCAAiB,EAAE;oBACjB;qBACA;aACA;IACF;IAEA,qBACE,gCAAC;QAAI,MAAK;QAAe,KAAK;QAAK,WAAW;QAAW,OAAO,0CAAkB,YAAY,WAAW;OACtG;AAGP;AAEA,IAAI,8BAAQ,IAAI;AACT,SAAS,0CAAkB,UAAsB,EAAE,GAAc,EAAE,MAA0B;IAClG,IAAI,YAAY,QAAQ,QAAQ,UAAU;IAC1C,IAAI,SAAS,4BAAM,GAAG,CAAC;IACvB,IAAI,UAAU,MAAM,CAAC,UAAU,IAAI,MAAM;QACvC,IAAI,CAAC,QACH,OAAO;QAGT,6CAA6C;QAC7C,IAAI,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QAC3C,IAAI,IAAI,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,GAAG,KAAK,OAAO,MAAM,CAAC,UAAU,KAAK,GAC9C,OAAO;IAEX;IAEA,IAAI,aAAa;QACf,KAAK,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,SAAS,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QACnD,CAAC,UAAU,EAAE,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,SAAS,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QAC3D,OAAO,WAAW,IAAI,CAAC,KAAK;QAC5B,QAAQ,WAAW,IAAI,CAAC,MAAM;IAChC;IAEA,sEAAsE;IACtE,OAAO,OAAO,CAAC,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM;QAC9C,IAAI,CAAC,OAAO,QAAQ,CAAC,QACnB,UAAU,CAAC,IAAI,GAAG;IAEtB;IAEA,IAAI,QAAuB;QACzB,UAAU,WAAW,QAAQ,GAAG,WAAW;QAC3C,qJAAqJ;QACrJ,SAAS,WAAW,QAAQ,GAAG,iBAAiB;QAChD,UAAU,WAAW,aAAa,GAAG,YAAY;QACjD,SAAS,WAAW,OAAO;QAC3B,QAAQ,WAAW,MAAM;QACzB,WAAW,WAAW,SAAS;QAC/B,SAAS;QACT,GAAG,UAAU;IACf;IAEA,4BAAM,GAAG,CAAC,YAAY;IACtB,OAAO;AACT","sources":["packages/@react-aria/virtualizer/src/VirtualizerItem.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Direction} from '@react-types/shared';\nimport {LayoutInfo} from '@react-stately/virtualizer';\nimport React, {CSSProperties, ReactNode, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useVirtualizerItem, VirtualizerItemOptions} from './useVirtualizerItem';\n\ninterface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {\n parent?: LayoutInfo | null,\n className?: string,\n children: ReactNode\n}\n\nexport function VirtualizerItem(props: VirtualizerItemProps) {\n let {className, layoutInfo, virtualizer, parent, children} = props;\n let {direction} = useLocale();\n let ref = useRef(undefined);\n useVirtualizerItem({\n layoutInfo,\n virtualizer,\n ref\n });\n\n return (\n <div role=\"presentation\" ref={ref} className={className} style={layoutInfoToStyle(layoutInfo, direction, parent)}>\n {children}\n </div>\n );\n}\n\nlet cache = new WeakMap();\nexport function layoutInfoToStyle(layoutInfo: LayoutInfo, dir: Direction, parent?: LayoutInfo | null): CSSProperties {\n let xProperty = dir === 'rtl' ? 'right' : 'left';\n let cached = cache.get(layoutInfo);\n if (cached && cached[xProperty] != null) {\n if (!parent) {\n return cached;\n }\n\n // Invalidate if the parent position changed.\n let top = layoutInfo.rect.y - parent.rect.y;\n let x = layoutInfo.rect.x - parent.rect.x;\n if (cached.top === top && cached[xProperty] === x) {\n return cached;\n }\n }\n\n let rectStyles = {\n top: layoutInfo.rect.y - (parent ? parent.rect.y : 0),\n [xProperty]: layoutInfo.rect.x - (parent ? parent.rect.x : 0),\n width: layoutInfo.rect.width,\n height: layoutInfo.rect.height\n };\n\n // Get rid of any non finite values since they aren't valid css values\n Object.entries(rectStyles).forEach(([key, value]) => {\n if (!Number.isFinite(value)) {\n rectStyles[key] = undefined;\n }\n });\n\n let style: CSSProperties = {\n position: layoutInfo.isSticky ? 'sticky' : 'absolute',\n // Sticky elements are positioned in normal document flow. Display inline-block so that they don't push other sticky columns onto the following rows.\n display: layoutInfo.isSticky ? 'inline-block' : undefined,\n overflow: layoutInfo.allowOverflow ? 'visible' : 'hidden',\n opacity: layoutInfo.opacity,\n zIndex: layoutInfo.zIndex,\n transform: layoutInfo.transform,\n contain: 'size layout style',\n ...rectStyles\n };\n\n cache.set(layoutInfo, style);\n return style;\n}\n"],"names":[],"version":3,"file":"VirtualizerItem.module.js.map"}
1
+ {"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AAeM,SAAS,0CAAgB,KAA2B;IACzD,IAAI,SAAC,KAAK,aAAE,SAAS,cAAE,UAAU,eAAE,WAAW,UAAE,MAAM,YAAE,QAAQ,EAAC,GAAG;IACpE,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,gBAAQ;IAC1B,IAAI,MAAM,CAAA,GAAA,aAAK,EAAE;IACjB,CAAA,GAAA,yCAAiB,EAAE;oBACjB;qBACA;aACA;IACF;IAEA,qBACE,gCAAC;QAAI,MAAK;QAAe,KAAK;QAAK,WAAW;QAAW,OAAO;YAAC,GAAG,0CAAkB,YAAY,WAAW,OAAO;YAAE,GAAG,KAAK;QAAA;OAC3H;AAGP;AAEA,IAAI,8BAAQ,IAAI;AACT,SAAS,0CAAkB,UAAsB,EAAE,GAAc,EAAE,MAA0B;IAClG,IAAI,YAAY,QAAQ,QAAQ,UAAU;IAC1C,IAAI,SAAS,4BAAM,GAAG,CAAC;IACvB,IAAI,UAAU,MAAM,CAAC,UAAU,IAAI,MAAM;QACvC,IAAI,CAAC,QACH,OAAO;QAGT,6CAA6C;QAC7C,IAAI,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QAC3C,IAAI,IAAI,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,GAAG,KAAK,OAAO,MAAM,CAAC,UAAU,KAAK,GAC9C,OAAO;IAEX;IAEA,IAAI,aAAa;QACf,wJAAwJ;QACxJ,sIAAsI;QACtI,mJAAmJ;QACnJ,+BAA+B;QAC/B,KAAK,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,UAAU,CAAE,CAAA,OAAO,aAAa,IAAI,WAAW,QAAQ,AAAD,IAAK,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QACrG,CAAC,UAAU,EAAE,WAAW,IAAI,CAAC,CAAC,GAAI,CAAA,UAAU,CAAE,CAAA,OAAO,aAAa,IAAI,WAAW,QAAQ,AAAD,IAAK,OAAO,IAAI,CAAC,CAAC,GAAG,CAAA;QAC7G,OAAO,WAAW,IAAI,CAAC,KAAK;QAC5B,QAAQ,WAAW,IAAI,CAAC,MAAM;IAChC;IAEA,sEAAsE;IACtE,OAAO,OAAO,CAAC,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM;QAC9C,IAAI,CAAC,OAAO,QAAQ,CAAC,QACnB,UAAU,CAAC,IAAI,GAAG;IAEtB;IAEA,IAAI,QAAuB;QACzB,UAAU,WAAW,QAAQ,GAAG,WAAW;QAC3C,qJAAqJ;QACrJ,SAAS,WAAW,QAAQ,GAAG,iBAAiB;QAChD,UAAU,WAAW,aAAa,GAAG,YAAY;QACjD,SAAS,WAAW,OAAO;QAC3B,QAAQ,WAAW,MAAM;QACzB,WAAW,WAAW,SAAS;QAC/B,SAAS;QACT,GAAG,UAAU;IACf;IAEA,4BAAM,GAAG,CAAC,YAAY;IACtB,OAAO;AACT","sources":["packages/@react-aria/virtualizer/src/VirtualizerItem.tsx"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Direction} from '@react-types/shared';\nimport {LayoutInfo} from '@react-stately/virtualizer';\nimport React, {CSSProperties, ReactNode, useRef} from 'react';\nimport {useLocale} from '@react-aria/i18n';\nimport {useVirtualizerItem, VirtualizerItemOptions} from './useVirtualizerItem';\n\ninterface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {\n parent?: LayoutInfo | null,\n style?: CSSProperties,\n className?: string,\n children: ReactNode\n}\n\nexport function VirtualizerItem(props: VirtualizerItemProps) {\n let {style, className, layoutInfo, virtualizer, parent, children} = props;\n let {direction} = useLocale();\n let ref = useRef(undefined);\n useVirtualizerItem({\n layoutInfo,\n virtualizer,\n ref\n });\n\n return (\n <div role=\"presentation\" ref={ref} className={className} style={{...layoutInfoToStyle(layoutInfo, direction, parent), ...style}}>\n {children}\n </div>\n );\n}\n\nlet cache = new WeakMap();\nexport function layoutInfoToStyle(layoutInfo: LayoutInfo, dir: Direction, parent?: LayoutInfo | null): CSSProperties {\n let xProperty = dir === 'rtl' ? 'right' : 'left';\n let cached = cache.get(layoutInfo);\n if (cached && cached[xProperty] != null) {\n if (!parent) {\n return cached;\n }\n\n // Invalidate if the parent position changed.\n let top = layoutInfo.rect.y - parent.rect.y;\n let x = layoutInfo.rect.x - parent.rect.x;\n if (cached.top === top && cached[xProperty] === x) {\n return cached;\n }\n }\n\n let rectStyles = {\n // TODO: For layoutInfos that are sticky that have parents with overflow visible, their \"top\" will be relative to the to the nearest scrolling container\n // which WON'T be the parent since the parent has overflow visible. This means we shouldn't offset the height by the parent's position\n // Not 100% about this change here since it is quite ambigious what the scrolling container maybe and how its top is positioned with respect to the\n // calculated layoutInfo.y here\n top: layoutInfo.rect.y - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.y : 0),\n [xProperty]: layoutInfo.rect.x - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.x : 0),\n width: layoutInfo.rect.width,\n height: layoutInfo.rect.height\n };\n\n // Get rid of any non finite values since they aren't valid css values\n Object.entries(rectStyles).forEach(([key, value]) => {\n if (!Number.isFinite(value)) {\n rectStyles[key] = undefined;\n }\n });\n\n let style: CSSProperties = {\n position: layoutInfo.isSticky ? 'sticky' : 'absolute',\n // Sticky elements are positioned in normal document flow. Display inline-block so that they don't push other sticky columns onto the following rows.\n display: layoutInfo.isSticky ? 'inline-block' : undefined,\n overflow: layoutInfo.allowOverflow ? 'visible' : 'hidden',\n opacity: layoutInfo.opacity,\n zIndex: layoutInfo.zIndex,\n transform: layoutInfo.transform,\n contain: 'size layout style',\n ...rectStyles\n };\n\n cache.set(layoutInfo, style);\n return style;\n}\n"],"names":[],"version":3,"file":"VirtualizerItem.module.js.map"}
package/dist/types.d.ts CHANGED
@@ -313,6 +313,7 @@ export function useScrollView(props: ScrollViewProps, ref: _RefObject1<HTMLEleme
313
313
  };
314
314
  interface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {
315
315
  parent?: LayoutInfo | null;
316
+ style?: CSSProperties;
316
317
  className?: string;
317
318
  children: ReactNode;
318
319
  }
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/utils.ts","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/useVirtualizerItem.ts","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/ScrollView.tsx","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/VirtualizerItem.tsx","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/Virtualizer.tsx","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/index.ts","packages/@react-aria/virtualizer/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport type {RTLOffsetType} from './utils';\nexport type {VirtualizerItemOptions} from './useVirtualizerItem';\nexport {Virtualizer} from './Virtualizer';\nexport {useVirtualizerItem} from './useVirtualizerItem';\nexport {VirtualizerItem, layoutInfoToStyle} from './VirtualizerItem';\nexport {ScrollView, useScrollView} from './ScrollView';\nexport {getRTLOffsetType, getScrollLeft, setScrollLeft} from './utils';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/utils.ts","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/useVirtualizerItem.ts","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/ScrollView.tsx","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/VirtualizerItem.tsx","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/Virtualizer.tsx","packages/@react-aria/virtualizer/src/packages/@react-aria/virtualizer/src/index.ts","packages/@react-aria/virtualizer/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport type {RTLOffsetType} from './utils';\nexport type {VirtualizerItemOptions} from './useVirtualizerItem';\nexport {Virtualizer} from './Virtualizer';\nexport {useVirtualizerItem} from './useVirtualizerItem';\nexport {VirtualizerItem, layoutInfoToStyle} from './VirtualizerItem';\nexport {ScrollView, useScrollView} from './ScrollView';\nexport {getRTLOffsetType, getScrollLeft, setScrollLeft} from './utils';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-aria/virtualizer",
3
- "version": "4.0.3-nightly.5042+68403fe55",
3
+ "version": "4.0.4",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -22,11 +22,11 @@
22
22
  "url": "https://github.com/adobe/react-spectrum"
23
23
  },
24
24
  "dependencies": {
25
- "@react-aria/i18n": "3.0.0-nightly.3114+68403fe55",
26
- "@react-aria/interactions": "3.0.0-nightly.3114+68403fe55",
27
- "@react-aria/utils": "3.0.0-nightly.3114+68403fe55",
28
- "@react-stately/virtualizer": "4.0.3-nightly.5042+68403fe55",
29
- "@react-types/shared": "3.0.0-nightly.3114+68403fe55",
25
+ "@react-aria/i18n": "^3.12.3",
26
+ "@react-aria/interactions": "^3.22.4",
27
+ "@react-aria/utils": "^3.25.3",
28
+ "@react-stately/virtualizer": "^4.1.0",
29
+ "@react-types/shared": "^3.25.0",
30
30
  "@swc/helpers": "^0.5.0"
31
31
  },
32
32
  "peerDependencies": {
@@ -36,5 +36,5 @@
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  },
39
- "gitHead": "68403fe55489dce3de1b3094c957d598ad719861"
39
+ "gitHead": "8e0a28d188cdbdbd2b32296fa034b1b02ddde229"
40
40
  }
@@ -143,12 +143,17 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement
143
143
  // eslint-disable-next-line react-hooks/exhaustive-deps
144
144
  }, []);
145
145
 
146
+ let isUpdatingSize = useRef(false);
146
147
  let updateSize = useEffectEvent((flush: typeof flushSync) => {
147
148
  let dom = ref.current;
148
- if (!dom) {
149
+ if (!dom && !isUpdatingSize.current) {
149
150
  return;
150
151
  }
151
152
 
153
+ // Prevent reentrancy when resize observer fires, triggers re-layout that results in
154
+ // content size update, causing below layout effect to fire. This avoids infinite loops.
155
+ isUpdatingSize.current = true;
156
+
152
157
  let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;
153
158
  let isClientWidthMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientWidth');
154
159
  let isClientHeightMocked = Object.getOwnPropertyNames(window.HTMLElement.prototype).includes('clientHeight');
@@ -177,27 +182,31 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement
177
182
  });
178
183
  }
179
184
  }
185
+
186
+ isUpdatingSize.current = false;
180
187
  });
181
188
 
182
- let didUpdateSize = useRef(false);
189
+ // Update visible rect when the content size changes, in case scrollbars need to appear or disappear.
190
+ let lastContentSize = useRef<Size | null>(null);
183
191
  useLayoutEffect(() => {
184
- // React doesn't allow flushSync inside effects, so queue a microtask.
185
- // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
186
- queueMicrotask(() => {
187
- if (!didUpdateSize.current) {
188
- didUpdateSize.current = true;
189
- updateSize(flushSync);
192
+ if (!isUpdatingSize.current && (lastContentSize.current == null || !contentSize.equals(lastContentSize.current))) {
193
+ // React doesn't allow flushSync inside effects, so queue a microtask.
194
+ // We also need to wait until all refs are set (e.g. when passing a ref down from a parent).
195
+ // If we are in an `act` environment, update immediately without a microtask so you don't need
196
+ // to mock timers in tests. In this case, the update is synchronous already.
197
+ // IS_REACT_ACT_ENVIRONMENT is used by React 18. Previous versions checked for the `jest` global.
198
+ // https://github.com/reactwg/react-18/discussions/102
199
+ // @ts-ignore
200
+ if (typeof IS_REACT_ACT_ENVIRONMENT === 'boolean' ? IS_REACT_ACT_ENVIRONMENT : typeof jest !== 'undefined') {
201
+ updateSize(fn => fn());
202
+ } else {
203
+ queueMicrotask(() => updateSize(flushSync));
190
204
  }
191
- });
192
- }, [updateSize]);
193
- useEffect(() => {
194
- if (!didUpdateSize.current) {
195
- // If useEffect ran before the above microtask, we are in a synchronous render (e.g. act).
196
- // Update the size here so that you don't need to mock timers in tests.
197
- didUpdateSize.current = true;
198
- updateSize(fn => fn());
199
205
  }
200
- }, [updateSize]);
206
+
207
+ lastContentSize.current = contentSize;
208
+ });
209
+
201
210
  let onResize = useCallback(() => {
202
211
  updateSize(flushSync);
203
212
  }, [updateSize]);
@@ -18,12 +18,13 @@ import {useVirtualizerItem, VirtualizerItemOptions} from './useVirtualizerItem';
18
18
 
19
19
  interface VirtualizerItemProps extends Omit<VirtualizerItemOptions, 'ref'> {
20
20
  parent?: LayoutInfo | null,
21
+ style?: CSSProperties,
21
22
  className?: string,
22
23
  children: ReactNode
23
24
  }
24
25
 
25
26
  export function VirtualizerItem(props: VirtualizerItemProps) {
26
- let {className, layoutInfo, virtualizer, parent, children} = props;
27
+ let {style, className, layoutInfo, virtualizer, parent, children} = props;
27
28
  let {direction} = useLocale();
28
29
  let ref = useRef(undefined);
29
30
  useVirtualizerItem({
@@ -33,7 +34,7 @@ export function VirtualizerItem(props: VirtualizerItemProps) {
33
34
  });
34
35
 
35
36
  return (
36
- <div role="presentation" ref={ref} className={className} style={layoutInfoToStyle(layoutInfo, direction, parent)}>
37
+ <div role="presentation" ref={ref} className={className} style={{...layoutInfoToStyle(layoutInfo, direction, parent), ...style}}>
37
38
  {children}
38
39
  </div>
39
40
  );
@@ -57,8 +58,12 @@ export function layoutInfoToStyle(layoutInfo: LayoutInfo, dir: Direction, parent
57
58
  }
58
59
 
59
60
  let rectStyles = {
60
- top: layoutInfo.rect.y - (parent ? parent.rect.y : 0),
61
- [xProperty]: layoutInfo.rect.x - (parent ? parent.rect.x : 0),
61
+ // TODO: For layoutInfos that are sticky that have parents with overflow visible, their "top" will be relative to the to the nearest scrolling container
62
+ // which WON'T be the parent since the parent has overflow visible. This means we shouldn't offset the height by the parent's position
63
+ // Not 100% about this change here since it is quite ambigious what the scrolling container maybe and how its top is positioned with respect to the
64
+ // calculated layoutInfo.y here
65
+ top: layoutInfo.rect.y - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.y : 0),
66
+ [xProperty]: layoutInfo.rect.x - (parent && !(parent.allowOverflow && layoutInfo.isSticky) ? parent.rect.x : 0),
62
67
  width: layoutInfo.rect.width,
63
68
  height: layoutInfo.rect.height
64
69
  };