@react-aria/collections
Advanced tools
Comparing version 3.0.0-alpha.1 to 3.0.0-nightly.2986
375
dist/main.js
@@ -1,357 +0,36 @@ | ||
var _babelRuntimeHelpersExtends = $parcel$interopDefault(require("@babel/runtime/helpers/extends")); | ||
var $f20386e2aa690b4a$exports = require("./CollectionBuilder.main.js"); | ||
var $eaaf60978b89fc58$exports = require("./Hidden.main.js"); | ||
var $245f3f827bea6653$exports = require("./useCachedChildren.main.js"); | ||
var $499e2959ba1abacc$exports = require("./BaseCollection.main.js"); | ||
var _babelRuntimeHelpersObjectWithoutProperties = $parcel$interopDefault(require("@babel/runtime/helpers/objectWithoutProperties")); | ||
var _temp = require("@react-aria/utils"); | ||
var chain = _temp.chain; | ||
var focusWithoutScrolling = _temp.focusWithoutScrolling; | ||
var _react2 = require("react"); | ||
var _react = $parcel$interopDefault(_react2); | ||
var useRef = _react2.useRef; | ||
var useCallback = _react2.useCallback; | ||
var useLayoutEffect = _react2.useLayoutEffect; | ||
var useEffect = _react2.useEffect; | ||
var useState = _react2.useState; | ||
var _temp2 = require("@react-stately/collections"); | ||
var Size = _temp2.Size; | ||
var Rect = _temp2.Rect; | ||
var useCollectionState = _temp2.useCollectionState; | ||
var _babelRuntimeHelpersObjectSpread = $parcel$interopDefault(require("@babel/runtime/helpers/objectSpread2")); | ||
var _babelRuntimeHelpersSlicedToArray = $parcel$interopDefault(require("@babel/runtime/helpers/slicedToArray")); | ||
var flushSync = require("react-dom").flushSync; | ||
function $parcel$interopDefault(a) { | ||
return a && a.__esModule ? a.default : a; | ||
function $parcel$export(e, n, v, s) { | ||
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); | ||
} | ||
function useCollectionItem(options) { | ||
var _options$reusableView = options.reusableView, | ||
layoutInfo = _options$reusableView.layoutInfo, | ||
collectionManager = _options$reusableView.collectionManager, | ||
ref = options.ref; | ||
var updateSize = useCallback(function () { | ||
var size = $d4b7ca346532dc68037d455bd5$var$getSize(ref.current); | ||
collectionManager.updateItemSize(layoutInfo.key, size); | ||
}, [collectionManager, layoutInfo.key, ref]); | ||
useLayoutEffect(function () { | ||
if (layoutInfo.estimatedSize) { | ||
updateSize(); | ||
} | ||
}); | ||
return { | ||
updateSize: updateSize | ||
}; | ||
} | ||
$parcel$export(module.exports, "CollectionBuilder", () => $f20386e2aa690b4a$exports.CollectionBuilder); | ||
$parcel$export(module.exports, "Collection", () => $f20386e2aa690b4a$exports.Collection); | ||
$parcel$export(module.exports, "createLeafComponent", () => $f20386e2aa690b4a$exports.createLeafComponent); | ||
$parcel$export(module.exports, "createBranchComponent", () => $f20386e2aa690b4a$exports.createBranchComponent); | ||
$parcel$export(module.exports, "createHideableComponent", () => $eaaf60978b89fc58$exports.createHideableComponent); | ||
$parcel$export(module.exports, "useIsHidden", () => $eaaf60978b89fc58$exports.useIsHidden); | ||
$parcel$export(module.exports, "useCachedChildren", () => $245f3f827bea6653$exports.useCachedChildren); | ||
$parcel$export(module.exports, "BaseCollection", () => $499e2959ba1abacc$exports.BaseCollection); | ||
$parcel$export(module.exports, "NodeValue", () => $499e2959ba1abacc$exports.NodeValue); | ||
/* | ||
* Copyright 2024 Adobe. All rights reserved. | ||
* This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. You may obtain a copy | ||
* of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under | ||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
* OF ANY KIND, either express or implied. See the License for the specific language | ||
* governing permissions and limitations under the License. | ||
*/ | ||
exports.useCollectionItem = useCollectionItem; | ||
function $d4b7ca346532dc68037d455bd5$var$getSize(node) { | ||
return new Size(node.scrollWidth, node.scrollHeight); | ||
} | ||
function CollectionItem(props) { | ||
var reusableView = props.reusableView, | ||
parent = props.parent; | ||
var ref = useRef(); | ||
useCollectionItem({ | ||
reusableView: reusableView, | ||
ref: ref | ||
}); | ||
return (/*#__PURE__*/_react.createElement("div", { | ||
role: "presentation", | ||
ref: ref, | ||
style: layoutInfoToStyle(reusableView.layoutInfo, parent && parent.layoutInfo) | ||
}, reusableView.rendered) | ||
); | ||
} | ||
exports.CollectionItem = CollectionItem; | ||
function layoutInfoToStyle(layoutInfo, parent) { | ||
return { | ||
position: 'absolute', | ||
overflow: 'hidden', | ||
top: layoutInfo.rect.y - (parent ? parent.rect.y : 0), | ||
left: layoutInfo.rect.x - (parent ? parent.rect.x : 0), | ||
transition: 'all', | ||
WebkitTransition: 'all', | ||
WebkitTransitionDuration: 'inherit', | ||
transitionDuration: 'inherit', | ||
width: layoutInfo.rect.width + 'px', | ||
height: layoutInfo.rect.height + 'px', | ||
opacity: layoutInfo.opacity, | ||
zIndex: layoutInfo.zIndex, | ||
transform: layoutInfo.transform, | ||
contain: 'size layout style paint' | ||
}; | ||
} | ||
exports.layoutInfoToStyle = layoutInfoToStyle; | ||
function $bb7f3410d6ad6d6e4b89d1b5$var$ScrollView(props, ref) { | ||
var contentSize = props.contentSize, | ||
visibleRect = props.visibleRect, | ||
onVisibleRectChange = props.onVisibleRectChange, | ||
children = props.children, | ||
innerStyle = props.innerStyle, | ||
sizeToFit = props.sizeToFit, | ||
onScrollStart = props.onScrollStart, | ||
onScrollEnd = props.onScrollEnd, | ||
_props$scrollDirectio = props.scrollDirection, | ||
scrollDirection = _props$scrollDirectio === void 0 ? 'both' : _props$scrollDirectio, | ||
otherProps = _babelRuntimeHelpersObjectWithoutProperties(props, ["contentSize", "visibleRect", "onVisibleRectChange", "children", "innerStyle", "sizeToFit", "onScrollStart", "onScrollEnd", "scrollDirection"]); | ||
var defaultRef = useRef(); | ||
ref = ref || defaultRef; | ||
var state = useRef({ | ||
scrollTop: 0, | ||
scrollLeft: 0, | ||
scrollEndTime: 0, | ||
scrollTimeout: null, | ||
width: 0, | ||
height: 0 | ||
}).current; | ||
var _useState = useState(false), | ||
_useState2 = _babelRuntimeHelpersSlicedToArray(_useState, 2), | ||
isScrolling = _useState2[0], | ||
setScrolling = _useState2[1]; | ||
var onScroll = useCallback(function (e) { | ||
flushSync(function () { | ||
var _e$currentTarget = e.currentTarget, | ||
scrollTop = _e$currentTarget.scrollTop, | ||
scrollLeft = _e$currentTarget.scrollLeft, | ||
scrollHeight = _e$currentTarget.scrollHeight, | ||
scrollWidth = _e$currentTarget.scrollWidth, | ||
clientHeight = _e$currentTarget.clientHeight, | ||
clientWidth = _e$currentTarget.clientWidth; // Prevent rubber band scrolling from shaking when scrolling out of bounds | ||
state.scrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight)); | ||
state.scrollLeft = Math.max(0, Math.min(scrollLeft, scrollWidth - clientWidth)); | ||
onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height)); | ||
if (!isScrolling) { | ||
setScrolling(true); | ||
if (onScrollStart) { | ||
onScrollStart(); | ||
} | ||
} // So we don't constantly call clearTimeout and setTimeout, | ||
// keep track of the current timeout time and only reschedule | ||
// the timer when it is getting close. | ||
var now = Date.now(); | ||
if (state.scrollEndTime <= now + 50) { | ||
state.scrollEndTime = now + 300; | ||
clearTimeout(state.scrollTimeout); | ||
state.scrollTimeout = setTimeout(function () { | ||
setScrolling(false); | ||
state.scrollTimeout = null; | ||
if (onScrollEnd) { | ||
onScrollEnd(); | ||
} | ||
}, 300); | ||
} | ||
}); | ||
}, [isScrolling, onScrollEnd, onScrollStart, onVisibleRectChange, state.height, state.scrollEndTime, state.scrollLeft, state.scrollTimeout, state.scrollTop, state.width]); | ||
useEffect(function () { | ||
// TODO: resize observer | ||
// https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver | ||
var updateSize = function updateSize() { | ||
var dom = ref.current; | ||
if (!dom) { | ||
return; | ||
} | ||
var w = dom.clientWidth; | ||
var h = dom.clientHeight; | ||
if (sizeToFit && contentSize.width > 0 && contentSize.height > 0) { | ||
var _style = window.getComputedStyle(dom); | ||
if (sizeToFit === 'width') { | ||
w = contentSize.width; | ||
var maxWidth = parseInt(_style.maxWidth, 10); | ||
if (!isNaN(maxWidth)) { | ||
w = Math.min(maxWidth, w); | ||
} | ||
} else if (sizeToFit === 'height') { | ||
h = contentSize.height; | ||
var maxHeight = parseInt(_style.maxHeight, 10); | ||
if (!isNaN(maxHeight)) { | ||
h = Math.min(maxHeight, h); | ||
} | ||
} | ||
} | ||
if (state.width !== w || state.height !== h) { | ||
state.width = w; | ||
state.height = h; | ||
onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, w, h)); | ||
} | ||
}; | ||
updateSize(); | ||
window.addEventListener('resize', updateSize, false); | ||
return function () { | ||
window.removeEventListener('resize', updateSize, false); | ||
}; | ||
}, [onVisibleRectChange, ref, state.height, state.scrollLeft, state.scrollTop, state.width, sizeToFit, contentSize.width, contentSize.height]); | ||
useLayoutEffect(function () { | ||
var dom = ref.current; | ||
if (!dom) { | ||
return; | ||
} | ||
if (visibleRect.x !== state.scrollLeft) { | ||
state.scrollLeft = visibleRect.x; | ||
dom.scrollLeft = visibleRect.x; | ||
} | ||
if (visibleRect.y !== state.scrollTop) { | ||
state.scrollTop = visibleRect.y; | ||
dom.scrollTop = visibleRect.y; | ||
} | ||
}, [ref, state.scrollLeft, state.scrollTop, visibleRect.x, visibleRect.y]); | ||
var style = _babelRuntimeHelpersObjectSpread({}, otherProps.style, { | ||
position: 'relative', | ||
// Reset padding so that relative positioning works correctly. Padding will be done in JS layout. | ||
padding: 0 | ||
}); | ||
if (scrollDirection === 'horizontal') { | ||
style.overflowX = 'auto'; | ||
style.overflowY = 'hidden'; | ||
} else if (scrollDirection === 'vertical') { | ||
style.overflowY = 'auto'; | ||
style.overflowX = 'hidden'; | ||
} else { | ||
style.overflow = 'auto'; | ||
} | ||
return (/*#__PURE__*/_react.createElement("div", _babelRuntimeHelpersExtends({}, otherProps, { | ||
style: style, | ||
ref: ref, | ||
onScroll: onScroll | ||
}), /*#__PURE__*/_react.createElement("div", { | ||
role: "presentation", | ||
style: _babelRuntimeHelpersObjectSpread({ | ||
width: contentSize.width, | ||
height: contentSize.height, | ||
pointerEvents: isScrolling ? 'none' : 'auto' | ||
}, innerStyle) | ||
}, children)) | ||
); | ||
} | ||
var $bb7f3410d6ad6d6e4b89d1b5$export$ScrollView = _react.forwardRef($bb7f3410d6ad6d6e4b89d1b5$var$ScrollView); | ||
function $deafe93e304fe800e7ccd55076d5eed$var$CollectionView(props, ref) { | ||
var renderView = props.children, | ||
renderWrapper = props.renderWrapper, | ||
layout = props.layout, | ||
collection = props.collection, | ||
focusedKey = props.focusedKey, | ||
sizeToFit = props.sizeToFit, | ||
scrollDirection = props.scrollDirection, | ||
otherProps = _babelRuntimeHelpersObjectWithoutProperties(props, ["children", "renderWrapper", "layout", "collection", "focusedKey", "sizeToFit", "scrollDirection"]); | ||
var _useCollectionState = useCollectionState({ | ||
layout: layout, | ||
collection: collection, | ||
renderView: renderView, | ||
renderWrapper: renderWrapper || $deafe93e304fe800e7ccd55076d5eed$var$defaultRenderWrapper | ||
}), | ||
visibleViews = _useCollectionState.visibleViews, | ||
visibleRect = _useCollectionState.visibleRect, | ||
setVisibleRect = _useCollectionState.setVisibleRect, | ||
contentSize = _useCollectionState.contentSize, | ||
isAnimating = _useCollectionState.isAnimating, | ||
collectionManager = _useCollectionState.collectionManager, | ||
startScrolling = _useCollectionState.startScrolling, | ||
endScrolling = _useCollectionState.endScrolling; | ||
var fallbackRef = useRef(); | ||
ref = ref || fallbackRef; // Scroll to the focusedKey when it changes. Actually focusing the focusedKey | ||
// is up to the implementation using CollectionView since we don't have refs | ||
// to all of the item DOM nodes. | ||
useEffect(function () { | ||
if (focusedKey) { | ||
collectionManager.scrollToItem(focusedKey, 0); | ||
} | ||
}, [focusedKey, collectionManager]); | ||
var isFocusWithin = useRef(false); | ||
var onFocus = useCallback(function (e) { | ||
// If the focused item is scrolled out of view and is not in the DOM, the CollectionView | ||
// will have tabIndex={0}. When tabbing in from outside, scroll the focused item into view. | ||
// We only want to do this if the CollectionView itself is receiving focus, not a child | ||
// element, and we aren't moving focus to the CollectionView from within (see below). | ||
if (e.target === ref.current && !isFocusWithin.current) { | ||
collectionManager.scrollToItem(focusedKey, 0); | ||
} | ||
isFocusWithin.current = e.target !== ref.current; | ||
}, [ref, collectionManager, focusedKey]); | ||
var onBlur = useCallback(function (e) { | ||
isFocusWithin.current = ref.current.contains(e.relatedTarget); | ||
}, [ref]); // When the focused item is scrolled out of view and is removed from the DOM, | ||
// move focus to the collection view as a whole if focus was within before. | ||
var focusedView = collectionManager.getItemView(focusedKey); | ||
useEffect(function () { | ||
if (focusedKey && !focusedView && isFocusWithin.current && document.activeElement !== ref.current) { | ||
focusWithoutScrolling(ref.current); | ||
} | ||
}); | ||
return (/*#__PURE__*/_react.createElement($bb7f3410d6ad6d6e4b89d1b5$export$ScrollView, _babelRuntimeHelpersExtends({}, otherProps, { | ||
tabIndex: focusedView ? -1 : 0, | ||
ref: ref, | ||
onFocus: chain(otherProps.onFocus, onFocus), | ||
onBlur: chain(otherProps.onBlur, onBlur), | ||
innerStyle: isAnimating ? { | ||
transition: "none ".concat(collectionManager.transitionDuration, "ms") | ||
} : undefined, | ||
contentSize: contentSize, | ||
visibleRect: visibleRect, | ||
onVisibleRectChange: setVisibleRect, | ||
onScrollStart: startScrolling, | ||
onScrollEnd: endScrolling, | ||
sizeToFit: sizeToFit, | ||
scrollDirection: scrollDirection | ||
}), visibleViews) | ||
); | ||
} // forwardRef doesn't support generic parameters, so cast the result to the correct type | ||
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref | ||
var CollectionView = _react.forwardRef($deafe93e304fe800e7ccd55076d5eed$var$CollectionView); | ||
exports.CollectionView = CollectionView; | ||
function $deafe93e304fe800e7ccd55076d5eed$var$defaultRenderWrapper(parent, reusableView) { | ||
return (/*#__PURE__*/_react.createElement(CollectionItem, { | ||
key: reusableView.key, | ||
reusableView: reusableView, | ||
parent: parent | ||
}) | ||
); | ||
} | ||
//# sourceMappingURL=main.js.map |
@@ -1,324 +0,23 @@ | ||
import _babelRuntimeHelpersEsmExtends from "@babel/runtime/helpers/esm/extends"; | ||
import _babelRuntimeHelpersEsmObjectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; | ||
import { chain, focusWithoutScrolling } from "@react-aria/utils"; | ||
import _react, { useRef, useCallback, useLayoutEffect, useEffect, useState } from "react"; | ||
import { Size, Rect, useCollectionState } from "@react-stately/collections"; | ||
import _babelRuntimeHelpersEsmObjectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
import { flushSync } from "react-dom"; | ||
export function useCollectionItem(options) { | ||
let { | ||
reusableView: { | ||
layoutInfo, | ||
collectionManager | ||
}, | ||
ref | ||
} = options; | ||
let updateSize = useCallback(() => { | ||
let size = $e5e366cd21c786f9652cd90121bc5e$var$getSize(ref.current); | ||
collectionManager.updateItemSize(layoutInfo.key, size); | ||
}, [collectionManager, layoutInfo.key, ref]); | ||
useLayoutEffect(() => { | ||
if (layoutInfo.estimatedSize) { | ||
updateSize(); | ||
} | ||
}); | ||
return { | ||
updateSize | ||
}; | ||
} | ||
import {Collection as $e1995378a142960e$export$fb8073518f34e6ec, CollectionBuilder as $e1995378a142960e$export$bf788dd355e3a401, createBranchComponent as $e1995378a142960e$export$e953bb1cd0f19726, createLeafComponent as $e1995378a142960e$export$18af5c7a9e9b3664} from "./CollectionBuilder.module.js"; | ||
import {createHideableComponent as $f39a9eba43920ace$export$86427a43e3e48ebb, useIsHidden as $f39a9eba43920ace$export$b5d7cc18bb8d2b59} from "./Hidden.module.js"; | ||
import {useCachedChildren as $e948873055cbafe4$export$727c8fc270210f13} from "./useCachedChildren.module.js"; | ||
import {BaseCollection as $23b9f4fcf0fe224b$export$408d25a4e12db025, NodeValue as $23b9f4fcf0fe224b$export$f5d856d854e74713} from "./BaseCollection.module.js"; | ||
function $e5e366cd21c786f9652cd90121bc5e$var$getSize(node) { | ||
return new Size(node.scrollWidth, node.scrollHeight); | ||
} | ||
/* | ||
* Copyright 2024 Adobe. All rights reserved. | ||
* This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. You may obtain a copy | ||
* of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under | ||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
* OF ANY KIND, either express or implied. See the License for the specific language | ||
* governing permissions and limitations under the License. | ||
*/ | ||
export function CollectionItem(props) { | ||
let { | ||
reusableView, | ||
parent | ||
} = props; | ||
let ref = useRef(); | ||
useCollectionItem({ | ||
reusableView, | ||
ref | ||
}); | ||
return (/*#__PURE__*/_react.createElement("div", { | ||
role: "presentation", | ||
ref: ref, | ||
style: layoutInfoToStyle(reusableView.layoutInfo, parent && parent.layoutInfo) | ||
}, reusableView.rendered) | ||
); | ||
} | ||
export function layoutInfoToStyle(layoutInfo, parent) { | ||
return { | ||
position: 'absolute', | ||
overflow: 'hidden', | ||
top: layoutInfo.rect.y - (parent ? parent.rect.y : 0), | ||
left: layoutInfo.rect.x - (parent ? parent.rect.x : 0), | ||
transition: 'all', | ||
WebkitTransition: 'all', | ||
WebkitTransitionDuration: 'inherit', | ||
transitionDuration: 'inherit', | ||
width: layoutInfo.rect.width + 'px', | ||
height: layoutInfo.rect.height + 'px', | ||
opacity: layoutInfo.opacity, | ||
zIndex: layoutInfo.zIndex, | ||
transform: layoutInfo.transform, | ||
contain: 'size layout style paint' | ||
}; | ||
} | ||
function $f6363181241b7deb808b097c5c1c95$var$ScrollView(props, ref) { | ||
let { | ||
contentSize, | ||
visibleRect, | ||
onVisibleRectChange, | ||
children, | ||
innerStyle, | ||
sizeToFit, | ||
onScrollStart, | ||
onScrollEnd, | ||
scrollDirection = 'both' | ||
} = props, | ||
otherProps = _babelRuntimeHelpersEsmObjectWithoutProperties(props, ["contentSize", "visibleRect", "onVisibleRectChange", "children", "innerStyle", "sizeToFit", "onScrollStart", "onScrollEnd", "scrollDirection"]); | ||
let defaultRef = useRef(); | ||
ref = ref || defaultRef; | ||
let state = useRef({ | ||
scrollTop: 0, | ||
scrollLeft: 0, | ||
scrollEndTime: 0, | ||
scrollTimeout: null, | ||
width: 0, | ||
height: 0 | ||
}).current; | ||
let [isScrolling, setScrolling] = useState(false); | ||
let onScroll = useCallback(e => { | ||
flushSync(() => { | ||
let { | ||
scrollTop, | ||
scrollLeft, | ||
scrollHeight, | ||
scrollWidth, | ||
clientHeight, | ||
clientWidth | ||
} = e.currentTarget; // Prevent rubber band scrolling from shaking when scrolling out of bounds | ||
state.scrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight)); | ||
state.scrollLeft = Math.max(0, Math.min(scrollLeft, scrollWidth - clientWidth)); | ||
onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height)); | ||
if (!isScrolling) { | ||
setScrolling(true); | ||
if (onScrollStart) { | ||
onScrollStart(); | ||
} | ||
} // So we don't constantly call clearTimeout and setTimeout, | ||
// keep track of the current timeout time and only reschedule | ||
// the timer when it is getting close. | ||
let now = Date.now(); | ||
if (state.scrollEndTime <= now + 50) { | ||
state.scrollEndTime = now + 300; | ||
clearTimeout(state.scrollTimeout); | ||
state.scrollTimeout = setTimeout(() => { | ||
setScrolling(false); | ||
state.scrollTimeout = null; | ||
if (onScrollEnd) { | ||
onScrollEnd(); | ||
} | ||
}, 300); | ||
} | ||
}); | ||
}, [isScrolling, onScrollEnd, onScrollStart, onVisibleRectChange, state.height, state.scrollEndTime, state.scrollLeft, state.scrollTimeout, state.scrollTop, state.width]); | ||
useEffect(() => { | ||
// TODO: resize observer | ||
// https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver | ||
let updateSize = () => { | ||
let dom = ref.current; | ||
if (!dom) { | ||
return; | ||
} | ||
let w = dom.clientWidth; | ||
let h = dom.clientHeight; | ||
if (sizeToFit && contentSize.width > 0 && contentSize.height > 0) { | ||
let style = window.getComputedStyle(dom); | ||
if (sizeToFit === 'width') { | ||
w = contentSize.width; | ||
let maxWidth = parseInt(style.maxWidth, 10); | ||
if (!isNaN(maxWidth)) { | ||
w = Math.min(maxWidth, w); | ||
} | ||
} else if (sizeToFit === 'height') { | ||
h = contentSize.height; | ||
let maxHeight = parseInt(style.maxHeight, 10); | ||
if (!isNaN(maxHeight)) { | ||
h = Math.min(maxHeight, h); | ||
} | ||
} | ||
} | ||
if (state.width !== w || state.height !== h) { | ||
state.width = w; | ||
state.height = h; | ||
onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, w, h)); | ||
} | ||
}; | ||
updateSize(); | ||
window.addEventListener('resize', updateSize, false); | ||
return () => { | ||
window.removeEventListener('resize', updateSize, false); | ||
}; | ||
}, [onVisibleRectChange, ref, state.height, state.scrollLeft, state.scrollTop, state.width, sizeToFit, contentSize.width, contentSize.height]); | ||
useLayoutEffect(() => { | ||
let dom = ref.current; | ||
if (!dom) { | ||
return; | ||
} | ||
if (visibleRect.x !== state.scrollLeft) { | ||
state.scrollLeft = visibleRect.x; | ||
dom.scrollLeft = visibleRect.x; | ||
} | ||
if (visibleRect.y !== state.scrollTop) { | ||
state.scrollTop = visibleRect.y; | ||
dom.scrollTop = visibleRect.y; | ||
} | ||
}, [ref, state.scrollLeft, state.scrollTop, visibleRect.x, visibleRect.y]); | ||
let style = _babelRuntimeHelpersEsmObjectSpread({}, otherProps.style, { | ||
position: 'relative', | ||
// Reset padding so that relative positioning works correctly. Padding will be done in JS layout. | ||
padding: 0 | ||
}); | ||
if (scrollDirection === 'horizontal') { | ||
style.overflowX = 'auto'; | ||
style.overflowY = 'hidden'; | ||
} else if (scrollDirection === 'vertical') { | ||
style.overflowY = 'auto'; | ||
style.overflowX = 'hidden'; | ||
} else { | ||
style.overflow = 'auto'; | ||
} | ||
return (/*#__PURE__*/_react.createElement("div", _babelRuntimeHelpersEsmExtends({}, otherProps, { | ||
style: style, | ||
ref: ref, | ||
onScroll: onScroll | ||
}), /*#__PURE__*/_react.createElement("div", { | ||
role: "presentation", | ||
style: _babelRuntimeHelpersEsmObjectSpread({ | ||
width: contentSize.width, | ||
height: contentSize.height, | ||
pointerEvents: isScrolling ? 'none' : 'auto' | ||
}, innerStyle) | ||
}, children)) | ||
); | ||
} | ||
const $f6363181241b7deb808b097c5c1c95$export$ScrollView = _react.forwardRef($f6363181241b7deb808b097c5c1c95$var$ScrollView); | ||
function $ebc1e5916247e7181d0a82c4b9f2$var$CollectionView(props, ref) { | ||
let { | ||
children: renderView, | ||
renderWrapper, | ||
layout, | ||
collection, | ||
focusedKey, | ||
sizeToFit, | ||
scrollDirection | ||
} = props, | ||
otherProps = _babelRuntimeHelpersEsmObjectWithoutProperties(props, ["children", "renderWrapper", "layout", "collection", "focusedKey", "sizeToFit", "scrollDirection"]); | ||
let { | ||
visibleViews, | ||
visibleRect, | ||
setVisibleRect, | ||
contentSize, | ||
isAnimating, | ||
collectionManager, | ||
startScrolling, | ||
endScrolling | ||
} = useCollectionState({ | ||
layout, | ||
collection, | ||
renderView, | ||
renderWrapper: renderWrapper || $ebc1e5916247e7181d0a82c4b9f2$var$defaultRenderWrapper | ||
}); | ||
let fallbackRef = useRef(); | ||
ref = ref || fallbackRef; // Scroll to the focusedKey when it changes. Actually focusing the focusedKey | ||
// is up to the implementation using CollectionView since we don't have refs | ||
// to all of the item DOM nodes. | ||
useEffect(() => { | ||
if (focusedKey) { | ||
collectionManager.scrollToItem(focusedKey, 0); | ||
} | ||
}, [focusedKey, collectionManager]); | ||
let isFocusWithin = useRef(false); | ||
let onFocus = useCallback(e => { | ||
// If the focused item is scrolled out of view and is not in the DOM, the CollectionView | ||
// will have tabIndex={0}. When tabbing in from outside, scroll the focused item into view. | ||
// We only want to do this if the CollectionView itself is receiving focus, not a child | ||
// element, and we aren't moving focus to the CollectionView from within (see below). | ||
if (e.target === ref.current && !isFocusWithin.current) { | ||
collectionManager.scrollToItem(focusedKey, 0); | ||
} | ||
isFocusWithin.current = e.target !== ref.current; | ||
}, [ref, collectionManager, focusedKey]); | ||
let onBlur = useCallback(e => { | ||
isFocusWithin.current = ref.current.contains(e.relatedTarget); | ||
}, [ref]); // When the focused item is scrolled out of view and is removed from the DOM, | ||
// move focus to the collection view as a whole if focus was within before. | ||
let focusedView = collectionManager.getItemView(focusedKey); | ||
useEffect(() => { | ||
if (focusedKey && !focusedView && isFocusWithin.current && document.activeElement !== ref.current) { | ||
focusWithoutScrolling(ref.current); | ||
} | ||
}); | ||
return (/*#__PURE__*/_react.createElement($f6363181241b7deb808b097c5c1c95$export$ScrollView, _babelRuntimeHelpersEsmExtends({}, otherProps, { | ||
tabIndex: focusedView ? -1 : 0, | ||
ref: ref, | ||
onFocus: chain(otherProps.onFocus, onFocus), | ||
onBlur: chain(otherProps.onBlur, onBlur), | ||
innerStyle: isAnimating ? { | ||
transition: "none ".concat(collectionManager.transitionDuration, "ms") | ||
} : undefined, | ||
contentSize: contentSize, | ||
visibleRect: visibleRect, | ||
onVisibleRectChange: setVisibleRect, | ||
onScrollStart: startScrolling, | ||
onScrollEnd: endScrolling, | ||
sizeToFit: sizeToFit, | ||
scrollDirection: scrollDirection | ||
}), visibleViews) | ||
); | ||
} // forwardRef doesn't support generic parameters, so cast the result to the correct type | ||
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref | ||
export const CollectionView = _react.forwardRef($ebc1e5916247e7181d0a82c4b9f2$var$CollectionView); | ||
function $ebc1e5916247e7181d0a82c4b9f2$var$defaultRenderWrapper(parent, reusableView) { | ||
return (/*#__PURE__*/_react.createElement(CollectionItem, { | ||
key: reusableView.key, | ||
reusableView: reusableView, | ||
parent: parent | ||
}) | ||
); | ||
} | ||
export {$e1995378a142960e$export$bf788dd355e3a401 as CollectionBuilder, $e1995378a142960e$export$fb8073518f34e6ec as Collection, $e1995378a142960e$export$18af5c7a9e9b3664 as createLeafComponent, $e1995378a142960e$export$e953bb1cd0f19726 as createBranchComponent, $f39a9eba43920ace$export$86427a43e3e48ebb as createHideableComponent, $f39a9eba43920ace$export$b5d7cc18bb8d2b59 as useIsHidden, $e948873055cbafe4$export$727c8fc270210f13 as useCachedChildren, $23b9f4fcf0fe224b$export$408d25a4e12db025 as BaseCollection, $23b9f4fcf0fe224b$export$f5d856d854e74713 as NodeValue}; | ||
//# sourceMappingURL=module.js.map |
@@ -1,29 +0,86 @@ | ||
import { RefObject, CSSProperties, HTMLAttributes, Key, ReactElement } from "react"; | ||
import { ReusableView, LayoutInfo, Collection, Layout } from "@react-stately/collections"; | ||
interface CollectionItemOptions<T extends object, V, W> { | ||
reusableView: ReusableView<T, V>; | ||
ref: RefObject<HTMLElement>; | ||
import { Collection as _Collection1, Key, Node } from "@react-types/shared"; | ||
import React, { ReactElement, ReactNode, ForwardedRef, JSX } from "react"; | ||
/** An immutable object representing a Node in a Collection. */ | ||
export class NodeValue<T> implements Node<T> { | ||
readonly type: string; | ||
readonly key: Key; | ||
readonly value: T | null; | ||
readonly level: number; | ||
readonly hasChildNodes: boolean; | ||
readonly rendered: ReactNode; | ||
readonly textValue: string; | ||
readonly 'aria-label'?: string; | ||
readonly index: number; | ||
readonly parentKey: Key | null; | ||
readonly prevKey: Key | null; | ||
readonly nextKey: Key | null; | ||
readonly firstChildKey: Key | null; | ||
readonly lastChildKey: Key | null; | ||
readonly props: any; | ||
readonly render?: (node: Node<any>) => ReactElement; | ||
constructor(type: string, key: Key); | ||
get childNodes(): Iterable<Node<T>>; | ||
clone(): NodeValue<T>; | ||
} | ||
export function useCollectionItem<T extends object, V, W>(options: CollectionItemOptions<T, V, W>): { | ||
updateSize: () => void; | ||
}; | ||
interface CollectionItemProps<T extends object, V> { | ||
reusableView: ReusableView<T, V>; | ||
parent?: ReusableView<T, V>; | ||
/** | ||
* An immutable Collection implementation. Updates are only allowed | ||
* when it is not marked as frozen. This can be subclassed to implement | ||
* custom collection behaviors. | ||
*/ | ||
export class BaseCollection<T> implements _Collection1<Node<T>> { | ||
get size(): number; | ||
getKeys(): IterableIterator<Key>; | ||
[Symbol.iterator](): Generator<Node<T>, void, unknown>; | ||
getChildren(key: Key): Iterable<Node<T>>; | ||
getKeyBefore(key: Key): Key; | ||
getKeyAfter(key: Key): Key; | ||
getFirstKey(): Key; | ||
getLastKey(): Key; | ||
getItem(key: Key): Node<T> | null; | ||
at(): Node<T>; | ||
clone(): this; | ||
addNode(node: NodeValue<T>): void; | ||
removeNode(key: Key): void; | ||
commit(firstKey: Key | null, lastKey: Key | null, isSSR?: boolean): void; | ||
} | ||
export function CollectionItem<T extends object, V>(props: CollectionItemProps<T, V>): JSX.Element; | ||
export function layoutInfoToStyle(layoutInfo: LayoutInfo, parent?: LayoutInfo | null): CSSProperties; | ||
interface CollectionViewProps<T extends object, V> extends HTMLAttributes<HTMLElement> { | ||
children: (type: string, content: T) => V; | ||
renderWrapper?: (parent: ReusableView<T, V> | null, reusableView: ReusableView<T, V>, children: ReusableView<T, V>[], renderChildren: (views: ReusableView<T, V>[]) => ReactElement[]) => ReactElement; | ||
layout: Layout<T>; | ||
collection: Collection<T>; | ||
focusedKey?: Key; | ||
sizeToFit?: 'width' | 'height'; | ||
scrollDirection?: 'horizontal' | 'vertical' | 'both'; | ||
export interface CachedChildrenOptions<T> { | ||
/** Item objects in the collection. */ | ||
items?: Iterable<T>; | ||
/** The contents of the collection. */ | ||
children?: ReactNode | ((item: T) => ReactNode); | ||
/** Values that should invalidate the item cache when using dynamic collections. */ | ||
dependencies?: any[]; | ||
/** A scope to prepend to all child item ids to ensure they are unique. */ | ||
idScope?: Key; | ||
/** Whether to add `id` and `value` props to all child items. */ | ||
addIdAndValue?: boolean; | ||
} | ||
export const CollectionView: <T extends object, V>(props: CollectionViewProps<T, V> & { | ||
ref?: React.RefObject<HTMLDivElement>; | ||
}) => React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)>) | (new (props: any) => React.Component<any, any, any>)>; | ||
/** | ||
* Maps over a list of items and renders React elements for them. Each rendered item is | ||
* cached based on object identity, and React keys are generated from the `key` or `id` property. | ||
*/ | ||
export function useCachedChildren<T extends object>(props: CachedChildrenOptions<T>): ReactNode; | ||
/** Creates a component that forwards its ref and returns null if it is in a hidden subtree. */ | ||
export function createHideableComponent<T, P = {}>(fn: (props: P, ref: React.Ref<T>) => ReactNode | null): (props: P & React.RefAttributes<T>) => ReactNode | null; | ||
/** Returns whether the component is in a hidden subtree. */ | ||
export function useIsHidden(): boolean; | ||
export interface CollectionBuilderProps<C extends BaseCollection<object>> { | ||
content: ReactNode; | ||
children: (collection: C) => ReactNode; | ||
createCollection?: () => C; | ||
} | ||
/** | ||
* Builds a `Collection` from the children provided to the `content` prop, and passes it to the child render prop function. | ||
*/ | ||
export function CollectionBuilder<C extends BaseCollection<object>>(props: CollectionBuilderProps<C>): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | Iterable<React.ReactNode>> | JSX.Element; | ||
export function createLeafComponent<T extends object, P extends object, E extends Element>(type: string, render: (props: P, ref: ForwardedRef<E>) => ReactNode): (props: P & React.RefAttributes<T>) => ReactNode | null; | ||
export function createLeafComponent<T extends object, P extends object, E extends Element>(type: string, render: (props: P, ref: ForwardedRef<E>, node: Node<T>) => ReactNode): (props: P & React.RefAttributes<T>) => ReactNode | null; | ||
export function createBranchComponent<T extends object, P extends { | ||
children?: any; | ||
}, E extends Element>(type: string, render: (props: P, ref: ForwardedRef<E>, node: Node<T>) => ReactNode, useChildren?: (props: P) => ReactNode): (props: P & React.RefAttributes<E>) => React.ReactNode | null; | ||
export interface CollectionProps<T> extends CachedChildrenOptions<T> { | ||
} | ||
/** A Collection renders a list of items, automatically managing caching and keys. */ | ||
export function Collection<T extends object>(props: CollectionProps<T>): JSX.Element; | ||
//# sourceMappingURL=types.d.ts.map |
{ | ||
"name": "@react-aria/collections", | ||
"version": "3.0.0-alpha.1", | ||
"version": "3.0.0-nightly.2986+b940126e4", | ||
"description": "Spectrum UI components in React", | ||
@@ -9,5 +9,11 @@ "license": "Apache-2.0", | ||
"types": "dist/types.d.ts", | ||
"exports": { | ||
"types": "./dist/types.d.ts", | ||
"import": "./dist/import.mjs", | ||
"require": "./dist/main.js" | ||
}, | ||
"source": "src/index.ts", | ||
"files": [ | ||
"dist" | ||
"dist", | ||
"src" | ||
], | ||
@@ -17,13 +23,14 @@ "sideEffects": false, | ||
"type": "git", | ||
"url": "https://github.com/adobe-private/react-spectrum-v3" | ||
"url": "https://github.com/adobe/react-spectrum" | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.6.2", | ||
"@react-aria/utils": "^3.0.0-rc.2", | ||
"@react-stately/collections": "^3.0.0-alpha.1", | ||
"@react-types/shared": "^3.0.0-rc.2" | ||
"@react-aria/ssr": "3.9.5-nightly.4698+b940126e4", | ||
"@react-aria/utils": "3.0.0-nightly.2986+b940126e4", | ||
"@react-types/shared": "3.0.0-nightly.2986+b940126e4", | ||
"@swc/helpers": "^0.5.0", | ||
"use-sync-external-store": "^1.2.0" | ||
}, | ||
"peerDependencies": { | ||
"react": "^16.8.0", | ||
"react-dom": "^16.8.0" | ||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", | ||
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" | ||
}, | ||
@@ -33,3 +40,3 @@ "publishConfig": { | ||
}, | ||
"gitHead": "207e6ee9076905c96638a7f81a367758872e1410" | ||
"gitHead": "b940126e4d67a11d28b7c0b098eab23205598b6c" | ||
} |
# @react-aria/collections | ||
This package is part of [react-spectrum](https://github.com/adobe-private/react-spectrum-v3). See the repo for more details. | ||
This package is part of [react-spectrum](https://github.com/adobe/react-spectrum). See the repo for more details. |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 6 instances in 1 package
294622
41
3463
7
6
60
2
+ Added@swc/helpers@^0.5.0
+ Addedreact@19.0.0(transitive)
+ Addedreact-dom@19.0.0(transitive)
+ Addedscheduler@0.25.0(transitive)
+ Addeduse-sync-external-store@1.4.0(transitive)
- Removed@babel/runtime@^7.6.2
- Removed@babel/runtime@7.26.9(transitive)
- Removed@react-aria/ssr@3.9.7(transitive)
- Removed@react-aria/utils@3.27.0(transitive)
- Removed@react-stately/collections@3.12.1(transitive)
- Removed@react-stately/utils@3.10.5(transitive)
- Removed@react-types/shared@3.27.0(transitive)
- Removedclsx@2.1.1(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedloose-envify@1.4.0(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedprop-types@15.8.1(transitive)
- Removedreact@16.14.0(transitive)
- Removedreact-dom@16.14.0(transitive)
- Removedreact-is@16.13.1(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedscheduler@0.19.1(transitive)