react-aria
Version:
Spectrum UI components in React
232 lines (220 loc) • 13.7 kB
JavaScript
import {BaseCollection as $0c55dae31ace3277$export$408d25a4e12db025, CollectionNode as $0c55dae31ace3277$export$d68d59712b04d9d1} from "./BaseCollection.js";
import {Document as $b4d65d3a608b09a7$export$b34a105447964f9f} from "./Document.js";
import {useCachedChildren as $91ad91478b215293$export$727c8fc270210f13} from "./useCachedChildren.js";
import {FocusableContext as $088f27a386bc4a8f$export$f9762fab77588ecb} from "../interactions/useFocusable.js";
import {Hidden as $dd46fb4c3e047f13$export$8dc98ba7eadeaa56} from "./Hidden.js";
import {useIsSSR as $85138adc03e1f057$export$535bd6ca7f90a273} from "../ssr/SSRProvider.js";
import {createPortal as $87Tar$createPortal} from "react-dom";
import $87Tar$react, {createContext as $87Tar$createContext, useContext as $87Tar$useContext, useRef as $87Tar$useRef, useCallback as $87Tar$useCallback, useState as $87Tar$useState, forwardRef as $87Tar$forwardRef, useMemo as $87Tar$useMemo} from "react";
import {useSyncExternalStore as $87Tar$useSyncExternalStore} from "use-sync-external-store/shim/index.js";
/*
* 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.
*/
const $d0e72a6e56b3c41b$var$ShallowRenderContext = /*#__PURE__*/ (0, $87Tar$createContext)(false);
const $d0e72a6e56b3c41b$var$CollectionDocumentContext = /*#__PURE__*/ (0, $87Tar$createContext)(null);
function $d0e72a6e56b3c41b$export$bf788dd355e3a401(props) {
// If a document was provided above us, we're already in a hidden tree. Just render the content.
let doc = (0, $87Tar$useContext)($d0e72a6e56b3c41b$var$CollectionDocumentContext);
if (doc) // The React types prior to 18 did not allow returning ReactNode from components
// even though the actual implementation since React 16 did.
// We must return ReactElement so that TS does not complain that <CollectionBuilder>
// is not a valid JSX element with React 16 and 17 types.
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20544
return props.content;
// Otherwise, render a hidden copy of the children so that we can build the collection before constructing the state.
// This should always come before the real DOM content so we have built the collection by the time it renders during SSR.
// This is fine. CollectionDocumentContext never changes after mounting.
// eslint-disable-next-line react-hooks/rules-of-hooks
let { collection: collection, document: document } = $d0e72a6e56b3c41b$var$useCollectionDocument(props.createCollection);
return /*#__PURE__*/ (0, $87Tar$react).createElement((0, $87Tar$react).Fragment, null, /*#__PURE__*/ (0, $87Tar$react).createElement((0, $dd46fb4c3e047f13$export$8dc98ba7eadeaa56), null, /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$CollectionDocumentContext.Provider, {
value: document
}, props.content)), /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$CollectionInner, {
render: props.children,
collection: collection
}));
}
function $d0e72a6e56b3c41b$var$CollectionInner({ collection: collection, render: render }) {
return render(collection);
}
// React 16 and 17 don't support useSyncExternalStore natively, and the shim provided by React does not support getServerSnapshot.
// This wrapper uses the shim, but additionally calls getServerSnapshot during SSR (according to SSRProvider).
function $d0e72a6e56b3c41b$var$useSyncExternalStoreFallback(subscribe, getSnapshot, getServerSnapshot) {
let isSSR = (0, $85138adc03e1f057$export$535bd6ca7f90a273)();
let isSSRRef = (0, $87Tar$useRef)(isSSR);
// This is read immediately inside the wrapper, which also runs during render.
// We just need a ref to avoid invalidating the callback itself, which
// would cause React to re-run the callback more than necessary.
// eslint-disable-next-line rsp-rules/pure-render
isSSRRef.current = isSSR;
let getSnapshotWrapper = (0, $87Tar$useCallback)(()=>{
return isSSRRef.current ? getServerSnapshot() : getSnapshot();
}, [
getSnapshot,
getServerSnapshot
]);
return (0, $87Tar$useSyncExternalStore)(subscribe, getSnapshotWrapper);
}
const $d0e72a6e56b3c41b$var$useSyncExternalStore = typeof (0, $87Tar$react)['useSyncExternalStore'] === 'function' ? (0, $87Tar$react)['useSyncExternalStore'] : $d0e72a6e56b3c41b$var$useSyncExternalStoreFallback;
function $d0e72a6e56b3c41b$var$useCollectionDocument(createCollection) {
// The document instance is mutable, and should never change between renders.
// useSyncExternalStore is used to subscribe to updates, which vends immutable Collection objects.
let [document] = (0, $87Tar$useState)(()=>new (0, $b4d65d3a608b09a7$export$b34a105447964f9f)((createCollection === null || createCollection === void 0 ? void 0 : createCollection()) || new (0, $0c55dae31ace3277$export$408d25a4e12db025)()));
let subscribe = (0, $87Tar$useCallback)((fn)=>document.subscribe(fn), [
document
]);
let getSnapshot = (0, $87Tar$useCallback)(()=>{
let collection = document.getCollection();
if (document.isSSR) // After SSR is complete, reset the document to empty so it is ready for React to render the portal into.
// We do this _after_ getting the collection above so that the collection still has content in it from SSR
// during the current render, before React has finished the client render.
document.resetAfterSSR();
return collection;
}, [
document
]);
let getServerSnapshot = (0, $87Tar$useCallback)(()=>{
document.isSSR = true;
return document.getCollection();
}, [
document
]);
let collection = $d0e72a6e56b3c41b$var$useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
return {
collection: collection,
document: document
};
}
const $d0e72a6e56b3c41b$var$SSRContext = /*#__PURE__*/ (0, $87Tar$createContext)(null);
function $d0e72a6e56b3c41b$var$createCollectionNodeClass(type) {
var _class;
let NodeClass = (_class = class extends (0, $0c55dae31ace3277$export$d68d59712b04d9d1) {
}, _class.type = type, _class);
return NodeClass;
}
function $d0e72a6e56b3c41b$var$useSSRCollectionNode(CollectionNodeClass, props, ref, rendered, children, render) {
// To prevent breaking change, if CollectionNodeClass is a string, create a CollectionNodeClass using the string as the type
if (typeof CollectionNodeClass === 'string') CollectionNodeClass = $d0e72a6e56b3c41b$var$createCollectionNodeClass(CollectionNodeClass);
// During SSR, portals are not supported, so the collection children will be wrapped in an SSRContext.
// Since SSR occurs only once, we assume that the elements are rendered in order and never re-render.
// Therefore we can create elements in our collection document during render so that they are in the
// collection by the time we need to use the collection to render to the real DOM.
// After hydration, we switch to client rendering using the portal.
let itemRef = (0, $87Tar$useCallback)((element)=>{
element === null || element === void 0 ? void 0 : element.setProps(props, ref, CollectionNodeClass, rendered, render);
}, [
props,
ref,
rendered,
render,
CollectionNodeClass
]);
let parentNode = (0, $87Tar$useContext)($d0e72a6e56b3c41b$var$SSRContext);
if (parentNode) {
// Guard against double rendering in strict mode.
let element = parentNode.ownerDocument.nodesByProps.get(props);
if (!element) {
element = parentNode.ownerDocument.createElement(CollectionNodeClass.type);
element.setProps(props, ref, CollectionNodeClass, rendered, render);
parentNode.appendChild(element);
parentNode.ownerDocument.updateCollection();
parentNode.ownerDocument.nodesByProps.set(props, element);
}
return children ? /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$SSRContext.Provider, {
value: element
}, children) : null;
}
// @ts-ignore
return /*#__PURE__*/ (0, $87Tar$react).createElement(CollectionNodeClass.type, {
ref: itemRef
}, children);
}
function $d0e72a6e56b3c41b$export$18af5c7a9e9b3664(CollectionNodeClass, render) {
let Component = ({ node: node })=>render(node.props, node.props.ref, node);
let Result = (0, $87Tar$forwardRef)((props, ref)=>{
let focusableProps = (0, $87Tar$useContext)((0, $088f27a386bc4a8f$export$f9762fab77588ecb));
let isShallow = (0, $87Tar$useContext)($d0e72a6e56b3c41b$var$ShallowRenderContext);
if (!isShallow) {
if (render.length >= 3) throw new Error(render.name + ' cannot be rendered outside a collection.');
return render(props, ref);
}
return $d0e72a6e56b3c41b$var$useSSRCollectionNode(CollectionNodeClass, props, ref, 'children' in props ? props.children : null, null, (node)=>// Forward FocusableContext to real DOM tree so tooltips work.
/*#__PURE__*/ (0, $87Tar$react).createElement((0, $088f27a386bc4a8f$export$f9762fab77588ecb).Provider, {
value: focusableProps
}, /*#__PURE__*/ (0, $87Tar$react).createElement(Component, {
node: node
})));
});
// @ts-ignore
Result.displayName = render.name;
return Result;
}
function $d0e72a6e56b3c41b$export$e953bb1cd0f19726(CollectionNodeClass, render, useChildren = $d0e72a6e56b3c41b$var$useCollectionChildren) {
let Component = ({ node: node })=>render(node.props, node.props.ref, node);
let Result = (0, $87Tar$forwardRef)((props, ref)=>{
let children = useChildren(props);
var _useSSRCollectionNode;
return (_useSSRCollectionNode = $d0e72a6e56b3c41b$var$useSSRCollectionNode(CollectionNodeClass, props, ref, null, children, (node)=>/*#__PURE__*/ (0, $87Tar$react).createElement(Component, {
node: node
}))) !== null && _useSSRCollectionNode !== void 0 ? _useSSRCollectionNode : /*#__PURE__*/ (0, $87Tar$react).createElement((0, $87Tar$react).Fragment, null);
});
// @ts-ignore
Result.displayName = render.name;
return Result;
}
function $d0e72a6e56b3c41b$var$useCollectionChildren(options) {
return (0, $91ad91478b215293$export$727c8fc270210f13)({
...options,
addIdAndValue: true
});
}
const $d0e72a6e56b3c41b$var$CollectionContext = /*#__PURE__*/ (0, $87Tar$createContext)(null);
function $d0e72a6e56b3c41b$export$fb8073518f34e6ec(props) {
let ctx = (0, $87Tar$useContext)($d0e72a6e56b3c41b$var$CollectionContext);
let dependencies = ((ctx === null || ctx === void 0 ? void 0 : ctx.dependencies) || []).concat(props.dependencies);
var _props_idScope;
let idScope = (_props_idScope = props.idScope) !== null && _props_idScope !== void 0 ? _props_idScope : ctx === null || ctx === void 0 ? void 0 : ctx.idScope;
let children = $d0e72a6e56b3c41b$var$useCollectionChildren({
...props,
idScope: idScope,
dependencies: dependencies
});
let doc = (0, $87Tar$useContext)($d0e72a6e56b3c41b$var$CollectionDocumentContext);
if (doc) children = /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$CollectionRoot, null, children);
// Propagate dependencies and idScope to child collections.
ctx = (0, $87Tar$useMemo)(()=>({
dependencies: dependencies,
idScope: idScope
}), // eslint-disable-next-line react-hooks/exhaustive-deps
[
idScope,
...dependencies
]);
return /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$CollectionContext.Provider, {
value: ctx
}, children);
}
function $d0e72a6e56b3c41b$var$CollectionRoot({ children: children }) {
let doc = (0, $87Tar$useContext)($d0e72a6e56b3c41b$var$CollectionDocumentContext);
let wrappedChildren = (0, $87Tar$useMemo)(()=>/*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$CollectionDocumentContext.Provider, {
value: null
}, /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$ShallowRenderContext.Provider, {
value: true
}, children)), [
children
]);
// During SSR, we render the content directly, and append nodes to the document during render.
// The collection children return null so that nothing is actually rendered into the HTML.
return (0, $85138adc03e1f057$export$535bd6ca7f90a273)() ? /*#__PURE__*/ (0, $87Tar$react).createElement($d0e72a6e56b3c41b$var$SSRContext.Provider, {
value: doc
}, wrappedChildren) : /*#__PURE__*/ (0, $87Tar$createPortal)(wrappedChildren, doc);
}
export {$d0e72a6e56b3c41b$export$bf788dd355e3a401 as CollectionBuilder, $d0e72a6e56b3c41b$export$18af5c7a9e9b3664 as createLeafComponent, $d0e72a6e56b3c41b$export$e953bb1cd0f19726 as createBranchComponent, $d0e72a6e56b3c41b$export$fb8073518f34e6ec as Collection};
//# sourceMappingURL=CollectionBuilder.js.map