react-aria
Version:
Spectrum UI components in React
1 lines • 17.5 kB
Source Map (JSON)
{"mappings":"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","sources":["packages/react-aria/src/collections/CollectionBuilder.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 {BaseCollection, CollectionNode} from './BaseCollection';\nimport {BaseNode, Document, ElementNode} from './Document';\nimport {CachedChildrenOptions, useCachedChildren} from './useCachedChildren';\nimport {createPortal} from 'react-dom';\nimport {FocusableContext} from '../interactions/useFocusable';\nimport {forwardRefType, Key, Node} from '@react-types/shared';\nimport {Hidden} from './Hidden';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n JSX,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {useIsSSR} from '../ssr/SSRProvider';\nimport {useSyncExternalStore as useSyncExternalStoreShim} from 'use-sync-external-store/shim/index.js';\n\nconst ShallowRenderContext = createContext(false);\nconst CollectionDocumentContext = createContext<Document<any, BaseCollection<any>> | null>(null);\n\nexport interface CollectionBuilderProps<C extends BaseCollection<any>> {\n content: ReactNode;\n children: (collection: C) => ReactNode;\n createCollection?: () => C;\n}\n\n/**\n * Builds a `Collection` from the children provided to the `content` prop, and passes it to the\n * child render prop function.\n */\nexport function CollectionBuilder<C extends BaseCollection<any>>(\n props: CollectionBuilderProps<C>\n): ReactElement {\n // If a document was provided above us, we're already in a hidden tree. Just render the content.\n let doc = useContext(CollectionDocumentContext);\n if (doc) {\n // The React types prior to 18 did not allow returning ReactNode from components\n // even though the actual implementation since React 16 did.\n // We must return ReactElement so that TS does not complain that <CollectionBuilder>\n // is not a valid JSX element with React 16 and 17 types.\n // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20544\n return props.content as ReactElement;\n }\n\n // Otherwise, render a hidden copy of the children so that we can build the collection before constructing the state.\n // This should always come before the real DOM content so we have built the collection by the time it renders during SSR.\n\n // This is fine. CollectionDocumentContext never changes after mounting.\n // eslint-disable-next-line react-hooks/rules-of-hooks\n let {collection, document} = useCollectionDocument(props.createCollection);\n return (\n <>\n <Hidden>\n <CollectionDocumentContext.Provider value={document}>\n {props.content}\n </CollectionDocumentContext.Provider>\n </Hidden>\n <CollectionInner render={props.children} collection={collection} />\n </>\n );\n}\n\nfunction CollectionInner({collection, render}) {\n return render(collection);\n}\n\ninterface CollectionDocumentResult<T, C extends BaseCollection<T>> {\n collection: C;\n document: Document<T, C>;\n}\n\n// React 16 and 17 don't support useSyncExternalStore natively, and the shim provided by React does not support getServerSnapshot.\n// This wrapper uses the shim, but additionally calls getServerSnapshot during SSR (according to SSRProvider).\nfunction useSyncExternalStoreFallback<C>(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => C,\n getServerSnapshot: () => C\n): C {\n let isSSR = useIsSSR();\n let isSSRRef = useRef(isSSR);\n // This is read immediately inside the wrapper, which also runs during render.\n // We just need a ref to avoid invalidating the callback itself, which\n // would cause React to re-run the callback more than necessary.\n // eslint-disable-next-line rsp-rules/pure-render\n isSSRRef.current = isSSR;\n\n let getSnapshotWrapper = useCallback(() => {\n return isSSRRef.current ? getServerSnapshot() : getSnapshot();\n }, [getSnapshot, getServerSnapshot]);\n return useSyncExternalStoreShim(subscribe, getSnapshotWrapper);\n}\n\nconst useSyncExternalStore =\n typeof React['useSyncExternalStore'] === 'function'\n ? React['useSyncExternalStore']\n : useSyncExternalStoreFallback;\n\nfunction useCollectionDocument<T extends object, C extends BaseCollection<T>>(\n createCollection?: () => C\n): CollectionDocumentResult<T, C> {\n // The document instance is mutable, and should never change between renders.\n // useSyncExternalStore is used to subscribe to updates, which vends immutable Collection objects.\n let [document] = useState(\n () => new Document<T, C>(createCollection?.() || (new BaseCollection() as C))\n );\n let subscribe = useCallback((fn: () => void) => document.subscribe(fn), [document]);\n let getSnapshot = useCallback(() => {\n let collection = document.getCollection();\n if (document.isSSR) {\n // After SSR is complete, reset the document to empty so it is ready for React to render the portal into.\n // We do this _after_ getting the collection above so that the collection still has content in it from SSR\n // during the current render, before React has finished the client render.\n document.resetAfterSSR();\n }\n return collection;\n }, [document]);\n let getServerSnapshot = useCallback(() => {\n document.isSSR = true;\n return document.getCollection();\n }, [document]);\n let collection = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n return {collection, document};\n}\n\nconst SSRContext = createContext<BaseNode<any> | null>(null);\n\nexport type CollectionNodeClass<T> = {\n new (key: Key): CollectionNode<T>;\n readonly type: string;\n};\n\nfunction createCollectionNodeClass(type: string): CollectionNodeClass<any> {\n let NodeClass = class extends CollectionNode<any> {\n static readonly type = type;\n };\n return NodeClass;\n}\n\nfunction useSSRCollectionNode<T extends Element>(\n CollectionNodeClass: CollectionNodeClass<T> | string,\n props: object,\n ref: ForwardedRef<T>,\n rendered?: any,\n children?: ReactNode,\n render?: (node: Node<any>) => ReactElement\n) {\n // To prevent breaking change, if CollectionNodeClass is a string, create a CollectionNodeClass using the string as the type\n if (typeof CollectionNodeClass === 'string') {\n CollectionNodeClass = createCollectionNodeClass(CollectionNodeClass);\n }\n\n // During SSR, portals are not supported, so the collection children will be wrapped in an SSRContext.\n // Since SSR occurs only once, we assume that the elements are rendered in order and never re-render.\n // Therefore we can create elements in our collection document during render so that they are in the\n // collection by the time we need to use the collection to render to the real DOM.\n // After hydration, we switch to client rendering using the portal.\n let itemRef = useCallback(\n (element: ElementNode<any> | null) => {\n element?.setProps(props, ref, CollectionNodeClass, rendered, render);\n },\n [props, ref, rendered, render, CollectionNodeClass]\n );\n let parentNode = useContext(SSRContext);\n if (parentNode) {\n // Guard against double rendering in strict mode.\n let element = parentNode.ownerDocument.nodesByProps.get(props);\n if (!element) {\n element = parentNode.ownerDocument.createElement(CollectionNodeClass.type);\n element.setProps(props, ref, CollectionNodeClass, rendered, render);\n parentNode.appendChild(element);\n parentNode.ownerDocument.updateCollection();\n parentNode.ownerDocument.nodesByProps.set(props, element);\n }\n\n return children ? <SSRContext.Provider value={element}>{children}</SSRContext.Provider> : null;\n }\n\n // @ts-ignore\n return <CollectionNodeClass.type ref={itemRef}>{children}</CollectionNodeClass.type>;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function createLeafComponent<T, P extends object, E extends Element>(\n CollectionNodeClass: CollectionNodeClass<any> | string,\n render: (props: P, ref: ForwardedRef<E>) => ReactElement | null\n): (props: P & React.RefAttributes<E>) => ReactElement | null;\nexport function createLeafComponent<T, P extends object, E extends Element>(\n CollectionNodeClass: CollectionNodeClass<any> | string,\n render: (props: P, ref: ForwardedRef<E>, node: Node<T>) => ReactElement | null\n): (props: P & React.RefAttributes<E>) => ReactElement | null;\nexport function createLeafComponent<P extends object, E extends Element>(\n CollectionNodeClass: CollectionNodeClass<any> | string,\n render: (props: P, ref: ForwardedRef<E>, node?: any) => ReactElement | null\n): (props: P & React.RefAttributes<any>) => ReactElement | null {\n let Component = ({node}) => render(node.props, node.props.ref, node);\n let Result = (forwardRef as forwardRefType)((props: P, ref: ForwardedRef<E>) => {\n let focusableProps = useContext(FocusableContext);\n let isShallow = useContext(ShallowRenderContext);\n if (!isShallow) {\n if (render.length >= 3) {\n throw new Error(render.name + ' cannot be rendered outside a collection.');\n }\n return render(props, ref);\n }\n\n return useSSRCollectionNode(\n CollectionNodeClass,\n props,\n ref,\n 'children' in props ? props.children : null,\n null,\n node => (\n // Forward FocusableContext to real DOM tree so tooltips work.\n <FocusableContext.Provider value={focusableProps}>\n <Component node={node} />\n </FocusableContext.Provider>\n )\n );\n });\n // @ts-ignore\n Result.displayName = render.name;\n return Result;\n}\n\nexport function createBranchComponent<T, P extends {children?: any}, E extends Element>(\n CollectionNodeClass: CollectionNodeClass<any> | string,\n render: (props: P, ref: ForwardedRef<E>, node: Node<T>) => ReactElement | null,\n useChildren: (props: P) => ReactNode = useCollectionChildren\n): (props: P & React.RefAttributes<E>) => ReactElement | null {\n let Component = ({node}) => render(node.props, node.props.ref, node);\n let Result = (forwardRef as forwardRefType)((props: P, ref: ForwardedRef<E>) => {\n let children = useChildren(props);\n return (\n useSSRCollectionNode(CollectionNodeClass, props, ref, null, children, node => (\n <Component node={node} />\n )) ?? <></>\n );\n });\n // @ts-ignore\n Result.displayName = render.name;\n return Result;\n}\n\nfunction useCollectionChildren<T>(options: CachedChildrenOptions<T>) {\n return useCachedChildren({...options, addIdAndValue: true});\n}\n\nexport interface CollectionProps<T> extends CachedChildrenOptions<T> {}\n\nconst CollectionContext = createContext<CachedChildrenOptions<unknown> | null>(null);\n\n/** A Collection renders a list of items, automatically managing caching and keys. */\nexport function Collection<T>(props: CollectionProps<T>): JSX.Element {\n let ctx = useContext(CollectionContext)!;\n let dependencies = (ctx?.dependencies || []).concat(props.dependencies);\n let idScope = props.idScope ?? ctx?.idScope;\n let children = useCollectionChildren({\n ...props,\n idScope,\n dependencies\n });\n\n let doc = useContext(CollectionDocumentContext);\n if (doc) {\n children = <CollectionRoot>{children}</CollectionRoot>;\n }\n\n // Propagate dependencies and idScope to child collections.\n ctx = useMemo(\n () => ({\n dependencies,\n idScope\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [idScope, ...dependencies]\n );\n\n return <CollectionContext.Provider value={ctx}>{children}</CollectionContext.Provider>;\n}\n\nfunction CollectionRoot({children}) {\n let doc = useContext(CollectionDocumentContext);\n let wrappedChildren = useMemo(\n () => (\n <CollectionDocumentContext.Provider value={null}>\n <ShallowRenderContext.Provider value>{children}</ShallowRenderContext.Provider>\n </CollectionDocumentContext.Provider>\n ),\n [children]\n );\n // During SSR, we render the content directly, and append nodes to the document during render.\n // The collection children return null so that nothing is actually rendered into the HTML.\n return useIsSSR() ? (\n <SSRContext.Provider value={doc}>{wrappedChildren}</SSRContext.Provider>\n ) : (\n createPortal(wrappedChildren, doc as unknown as Element)\n );\n}\n"],"names":[],"version":3,"file":"CollectionBuilder.cjs.map"}