@depup/react-aria-components 1.21.1-depup.0 → 1.22.0-depup.0
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.
- package/README.md +4 -3
- package/Sheet/package.json +5 -0
- package/changes.json +6 -2
- package/dist/exports/Sheet.cjs +30 -0
- package/dist/exports/Sheet.cjs.map +1 -0
- package/dist/exports/Sheet.js +21 -0
- package/dist/exports/Sheet.js.map +1 -0
- package/dist/exports/Sheet.mjs +21 -0
- package/dist/exports/Sheet.mjs.map +1 -0
- package/dist/exports/TokenField.cjs +1 -0
- package/dist/exports/TokenField.cjs.map +1 -1
- package/dist/exports/TokenField.js +2 -2
- package/dist/exports/TokenField.js.map +1 -1
- package/dist/exports/TokenField.mjs +2 -2
- package/dist/exports/TokenField.mjs.map +1 -1
- package/dist/exports/index.cjs +7 -0
- package/dist/exports/index.cjs.map +1 -1
- package/dist/exports/index.js +3 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/index.mjs +3 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/private/Breadcrumbs.cjs +1 -1
- package/dist/private/Breadcrumbs.cjs.map +1 -1
- package/dist/private/Breadcrumbs.js +1 -1
- package/dist/private/Breadcrumbs.js.map +1 -1
- package/dist/private/Breadcrumbs.mjs +1 -1
- package/dist/private/Breadcrumbs.mjs.map +1 -1
- package/dist/private/Modal.cjs +56 -11
- package/dist/private/Modal.cjs.map +1 -1
- package/dist/private/Modal.js +61 -14
- package/dist/private/Modal.js.map +1 -1
- package/dist/private/Modal.mjs +58 -14
- package/dist/private/Modal.mjs.map +1 -1
- package/dist/private/NavigationTree.cjs.map +1 -1
- package/dist/private/NavigationTree.js.map +1 -1
- package/dist/private/NavigationTree.mjs.map +1 -1
- package/dist/private/Popover.cjs +10 -2
- package/dist/private/Popover.cjs.map +1 -1
- package/dist/private/Popover.js +10 -2
- package/dist/private/Popover.js.map +1 -1
- package/dist/private/Popover.mjs +10 -2
- package/dist/private/Popover.mjs.map +1 -1
- package/dist/private/Sheet.cjs +827 -0
- package/dist/private/Sheet.cjs.map +1 -0
- package/dist/private/Sheet.js +820 -0
- package/dist/private/Sheet.js.map +1 -0
- package/dist/private/Sheet.mjs +814 -0
- package/dist/private/Sheet.mjs.map +1 -0
- package/dist/types/exports/Sheet.d.ts +3 -0
- package/dist/types/exports/TokenField.d.ts +2 -2
- package/dist/types/exports/index.d.ts +2 -0
- package/dist/types/src/Modal.d.ts +28 -1
- package/dist/types/src/NavigationTree.d.ts +1 -1
- package/dist/types/src/Sheet.d.ts +149 -0
- package/package.json +13 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;;AA6CM,MAAM,0DACX,CAAA,GAAA,0BAAY,EAA0D;AAUxE,MAAM,oEAAgC,CAAA,GAAA,0BAAY,EAAsC,CAAC;AAgBzF,MAAM,oEAAgC,CAAA,GAAA,0BAAY,EAAsC,CAAC;AAElF,MAAM,0DAAiC,CAAA,GAAA,0BAAY,EAAgC;IACxF,mBAAmB;AACrB;AA2CO,MAAM,4CAA+B,AAAd,WAAW,GAAI,CAAA,GAAA,uBAAS,EAAqB,SAAS,eAElF,KAA6B,EAAE,GAAiC;IAChE,CAAC,OAAO,IAAI,GAAG,CAAA,GAAA,yCAAc,EAAE,OAAO,KAAK;IAC3C,IAAI,aAAC,SAAS,SAAE,KAAK,YAAE,QAAQ,iBAAE,aAAa,EAAE,GAAG,MAAK,GAAG;IAC3D,IAAI,iBAAiB,CAAA,GAAA,mBAAK,EAAsB;IAChD,IAAI,UAAU,CAAA,GAAA,yCAAW,EAAE;IAC3B,IAAI,UAAU,CAAA,GAAA,oBAAM,EAAE,IAAO,CAAA;2BAAC;4BAAe;qBAAgB;QAAO,CAAA,GAAI;QAAC;QAAe;KAAQ;IAEhG,qBACE,0DAAC,oDAA8B,QAAQ;QAAC,OAAO;qBAC7C,0DAAC,CAAA,GAAA,8BAAG;QACD,GAAG,IAAI;QACR,KAAK;QACL,WAAW,aAAa;QACxB,OAAO;QACP,eAAc;QACd,4BAA2B;OAC1B;AAIT;AAiDO,MAAM,4CAAmC,AAAd,WAAW,GAAI,CAAA,GAAA,uBAAS,EACxD,SAAS,mBACP,KAAiC,EACjC,GAAiC;IAEjC,IAAI,QACF,IAAI,YACJ,QAAQ,UACR,MAAM,OACN,GAAG,YACH,QAAQ,QACR,IAAI,kBACJ,cAAc,iBACd,aAAa,aACb,SAAS,SACT,KAAK,UACL,MAAM,EACN,GAAG,MACJ,GAAG;IACJ,IAAI,iBAAC,aAAa,WAAE,OAAO,EAAC,GAAG,CAAA,GAAA,uBAAS,EAAE;IAC1C,IAAI,UAAU,QAAQ,QAAQ,KAAK,MAAM,GAAG;IAC5C,IAAI,YAAY,WAAW,SAAS;IACpC,IAAI,CAAC,eAAe,eAAe,GAAG,CAAA,GAAA,qBAAO,EAAE;IAC/C,qFAAqF;IACrF,IAAI,qBAAqB,CACvB,cAC0D,CAAA;YAC1D,GAAG,WAAW;uBACd;YACA,mBAAmB,4CAAsB,YAAY,EAAE,EAAE,YAAY,KAAK,EAAE;YAC5E,gBACE,YAAY,cAAc,IAAK,YAAY,oBAAoB,IAAI;QACvE,CAAA;IAEA,IAAI,SAAS,CAAA,GAAA,yCAAW,EAAE;IAC1B,CAAA,GAAA,sBAAQ,EAAE;QACR,IAAI,aAAa,OAAO,OAAO,EAAE;YAC/B,IAAI,eAAe,CAAA,GAAA,2DAAc,EAAE,OAAO,OAAO,EAAE;YACnD,8FAA8F;YAC9F,8FAA8F;YAC9F,uEAAuE;YACvE,IAAI,WAAW,SAAS;YACxB,IAAI,YAAY,CAAA,GAAA,8DAAW,EAAE,UAAU,eACrC,CAAA,GAAA,yDAAa,EAAE,cAAc,OAAO,OAAO,EAAE;gBAAC,OAAO;YAAQ;QAEjE;IACF,GAAG;QAAC;QAAW;QAAQ;KAAQ;IAE/B,qBACE,0DAAC,oDAA8B,QAAQ;QACrC,OAAO;kBACL;sBACA;oBACA;iBACA;sBACA;kBACA;4BACA;2BACA;uBACA;2BACA;4BACA;QACF;qBACA,0DAAC,CAAA,GAAA,kCAAO;QACL,GAAG,IAAI;QACR,KAAK;QACL,MAAM;QACN,WAAW,UAAU,UAAU;QAC/B,uBAAA;QACA,gBAAc,aAAa;QAC3B,WACE,OAAO,cAAc,aACjB,CAAA,cAAe,UAAU,mBAAmB,gBAC3C,aAAa;QAEpB,OACE,OAAO,UAAU,aACb,CAAA,cAAe,MAAM,mBAAmB,gBACxC;QAEN,QAAQ,CAAC,UAAU;YACjB,IAAI,SAAS,mBAAmB;YAChC,IAAI,EAAC,UAAU,WAAW,EAAE,GAAG,SAAQ,GAAG;YAC1C,IAAI,YAAY;gBACd,sBAAsB,OAAO,cAAc,IAAI;gBAC/C,yBAAyB,OAAO,iBAAiB,IAAI;YACvD;YACA,IAAI,wBACF,0DAAC,0CAA+B,QAAQ;gBACtC,OAAO;oBAAC,mBAAmB,OAAO,iBAAiB;gBAAA;eAClD;YAGL,OAAO,OAAO,WAAW,aACvB,OAAO;gBAAC,GAAG,OAAO;gBAAE,GAAG,SAAS;gBAAE,UAAU;YAAO,GAAG,wBAEtD,0DAAC,CAAA,GAAA,6BAAE,EAAE,GAAG;gBAAE,GAAG,OAAO;gBAAG,GAAG,SAAS;eAChC;QAGP;;AAIR;AAaF,sEAAsE;AACtE,SAAS,sCAAgB,UAAqC,EAAE,KAAa;IAC3E,KAAK,IAAI,OAAO,WAAW,OAAO,GAAI;QACpC,IAAI,WAAW,OAAO,CAAC,MAAM,OAAO,SAAS,OAC3C,OAAO;IAEX;IACA,OAAO;AACT;AAEA,kGAAkG;AAClG,kGAAkG;AAClG,gEAAgE;AAChE,SAAS,wCACP,UAAqC,EACrC,YAAsB,EACtB,GAAQ;IAER,IAAI,SAAS;IACb,IAAI,OAAO,WAAW,OAAO,CAAC;IAC9B,MAAO,MAAM,aAAa,KAAM;QAC9B,IAAI,SAAS,WAAW,OAAO,CAAC,KAAK,SAAS;QAC9C,IAAI,QAAQ,SAAS,UAAU,CAAC,aAAa,GAAG,CAAC,KAAK,SAAS,GAC7D,SAAS,KAAK,SAAS;QAEzB,OAAO;IACT;IACA,OAAO;AACT;AAEA,8FAA8F;AAC9F,kGAAkG;AAClG,SAAS,wCAAkB,SAAC,KAAK,EAA8B;IAC7D,IAAI,iBAAC,aAAa,kBAAE,cAAc,EAAC,GAAG,CAAA,GAAA,uBAAS,EAAE;IACjD,IAAI,cAAC,UAAU,oBAAE,gBAAgB,gBAAE,YAAY,EAAC,GAAG;IACnD,CAAA,GAAA,sBAAQ,EAAE;QACR,IACE,iBAAiB,QACjB,kBAAkB,QAClB,eAAe,OAAO,KAAK,eAE3B;QAEF,IAAI,MAAM,sCAAgB,YAAY;QACtC,IAAI,OAAO,MAAM;YACf,MAAM,wCAAkB,YAAY,cAAc;YAClD,eAAe,OAAO,GAAG;YACzB,iBAAiB,aAAa,CAAC;QACjC;IACF,GAAG;QAAC;QAAe;QAAY;QAAc;QAAgB;KAAiB;AAChF;AAEA,iEAAiE;AACjE,IAAI,+CAAyB,IAAI;AAKjC,sFAAsF;AACtF,SAAS,2CAAqB,KAAyB,EAAE,aAAqB;IAC5E,IAAI,cAAC,UAAU,EAAC,GAAG;IACnB,IAAI,SAAS,6CAAuB,GAAG,CAAC;IACxC,IAAI,UAAU,OAAO,SAAS,KAAK,eACjC,OAAO,OAAO,SAAS;IAEzB,IAAI,WAAW,sCAAgB,YAAY;IAC3C,IAAI,YAAY,IAAI;IACpB,IAAI,OAAO,YAAY,OAAO,WAAW,OAAO,CAAC,YAAY;IAC7D,MAAO,MAAM,aAAa,QAAQ,CAAC,UAAU,GAAG,CAAC,KAAK,SAAS,EAAG;QAChE,UAAU,GAAG,CAAC,KAAK,SAAS;QAC5B,OAAO,WAAW,OAAO,CAAC,KAAK,SAAS;IAC1C;IACA,6CAAuB,GAAG,CAAC,YAAY;QAAC,WAAW;mBAAe;IAAS;IAC3E,OAAO;AACT;AAEA,4EAA4E;AAC5E,SAAS,4CACP,EAAmB,EACnB,KAAyB,EACzB,aAAwC;IAExC,IAAI,MAAM,QAAQ,iBAAiB,QAAQ,CAAC,OAC1C,OAAO;IAET,OAAO,2CAAqB,OAAO,eAAe,GAAG,CAAC;AACxD;AAEO,SAAS,0CAA0B,KAAqC;IAC7E,IAAI,UAAU,CAAA,GAAA,uBAAS,EAAE;IACzB,qBACE,0DAAC,CAAA,GAAA,yCAAc,GAAM,OAClB,CAAC,gCACA,0DAAC;YACC,iBAAiB;YACjB,SAAS;YACT,UAAU,MAAM,QAAQ;;AAKlC;AAQA,SAAS,qDAA+B,KAA0C;IAChF,IAAI,mBAAC,eAAe,WAAE,OAAO,YAAE,QAAQ,EAAC,GAAG;IAC3C,IAAI,aAAC,SAAS,iBAAE,aAAa,kBAAE,cAAc,EAAE,GAAG,WAAU,GAAG;IAC/D,IAAI,SAAC,KAAK,kBAAE,cAAc,wBAAE,oBAAoB,MAAE,EAAE,iBAAE,aAAa,EAAC,GAAG;IACvE,IAAI,qBAAC,iBAAiB,EAAC,GAAG,CAAA,GAAA,uBAAS,EAAE;IAErC,wCAAkB;eAAC;IAAK;IAExB,iGAAiG;IACjG,8EAA8E;IAC9E,IAAI,mBAAmB,kBAAmB,wBAAwB,CAAC,CAAC;IACpE,IAAI,SAA0F;QAC5F,GAAG,eAAe;QAClB,WAAW,CAAC,CAAC;2BACb;QACA,gBAAgB;IAClB;IACA,IAAI,iBAAiB,OAAO,aAAa,aAAa,SAAS,UAAU;IACzE,gFAAgF;IAChF,IAAI,mBAAmB;QACrB,GAAG,SAAS;QACZ,gBAAgB,YAAY,SAAS;QACrC,eAAe;QACf,SAAS,UAAU,IAAI,IAAI,QAAQ,gBAAgB,IAAM,MAAM,SAAS,CAAC,MAAM;IACjF;IACA,qBAAO,0DAAC,CAAA,GAAA,kCAAO;QAAE,QAAQ;YAAC;gBAAC,CAAA,GAAA,qCAAU;gBAAG;aAAiB;SAAC;OAAG;AAC/D;AAOO,SAAS,0CACd,KAAoC;IAEpC,qBACE,0DAAC,CAAA,GAAA,qCAAU;QAAE,WAAU;QAAoC,GAAG,KAAK;OAChE,MAAM,QAAQ;AAGrB;AAOO,SAAS,0CAAqB,KAAgC;IACnE,qBACE,0DAAC,CAAA,GAAA,oCAAS;QAAE,WAAU;QAAmC,GAAG,KAAK;OAC9D,MAAM,QAAQ;AAGrB","sources":["packages/react-aria-components/src/NavigationTree.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 {\n ChildrenOrFunction,\n ClassNameOrFunction,\n ContextValue,\n dom,\n Provider,\n StyleRenderProps,\n useContextProps\n} from './utils';\nimport {Collection, forwardRefType, Key, Node, RouterOptions} from '@react-types/shared';\nimport {getScrollParent} from 'react-aria/private/utils/getScrollParent';\nimport {LinkContext} from './Link';\nimport {nodeContains} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n ReactNode,\n RefObject,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {scrollIntoView} from 'react-aria/private/utils/scrollIntoView';\nimport {\n Tree,\n TreeHeader,\n TreeHeaderProps,\n TreeItem,\n TreeItemContent,\n TreeItemContentRenderProps,\n TreeItemProps,\n TreeItemRenderProps,\n TreeProps,\n TreeRenderProps,\n TreeSection,\n TreeSectionProps\n} from './Tree';\nimport {TreeState} from 'react-stately/useTreeState';\nimport {useObjectRef} from 'react-aria/useObjectRef';\n\nexport const NavigationTreeContext =\n createContext<ContextValue<NavigationTreeProps<any>, HTMLDivElement>>(null);\n\ninterface InternalNavigationTreeContextValue {\n /** The route that is currently selected. */\n selectedRoute?: string | null;\n /** The last route the focused key was synced to; dedupes the focus sync across items. */\n syncedRouteRef?: RefObject<string | undefined>;\n /** The NavigationTree's root element, used to keep current-route scrolling inside the tree. */\n treeRef?: RefObject<HTMLDivElement | null>;\n}\nconst InternalNavigationTreeContext = createContext<InternalNavigationTreeContextValue>({});\n\ninterface NavigationTreeItemLinkContextValue {\n href?: string;\n hrefLang?: string;\n target?: string;\n rel?: string;\n download?: string | boolean;\n ping?: string;\n referrerPolicy?: ReferrerPolicy;\n routerOptions?: RouterOptions;\n isCurrent?: boolean;\n // Whether the item's link (as opposed to another focusable child such as a button) is focused.\n isLinkFocused?: boolean;\n setLinkFocused?: (isFocused: boolean) => void;\n}\nconst NavigationTreeItemLinkContext = createContext<NavigationTreeItemLinkContextValue>({});\n\nexport const NavigationTreeItemStateContext = createContext<{isCurrentAncestor: boolean}>({\n isCurrentAncestor: false\n});\n\nexport interface NavigationTreeRenderProps extends Pick<\n TreeRenderProps,\n 'isEmpty' | 'isFocused' | 'isFocusVisible' | 'state'\n> {}\n\nexport interface NavigationTreeProps<T>\n extends\n Omit<\n TreeProps<T>,\n | 'selectionMode'\n | 'selectionBehavior'\n | 'selectedKeys'\n | 'defaultSelectedKeys'\n | 'onSelectionChange'\n | 'disallowEmptySelection'\n | 'disabledBehavior'\n | 'keyboardNavigationBehavior'\n | 'escapeKeyBehavior'\n | 'shouldSelectOnPressUp'\n | 'dragAndDropHooks'\n | 'renderEmptyState'\n | 'onAction'\n | 'className'\n | 'style'\n | 'render'\n >,\n StyleRenderProps<NavigationTreeRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTree'\n */\n className?: ClassNameOrFunction<NavigationTreeRenderProps>;\n /** The route that is currently selected, matched against each item's `href`. */\n selectedRoute?: string | null;\n}\n\n/**\n * A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.\n */\nexport const NavigationTree = /*#__PURE__*/ (forwardRef as forwardRefType)(function NavigationTree<\n T\n>(props: NavigationTreeProps<T>, ref: ForwardedRef<HTMLDivElement>) {\n [props, ref] = useContextProps(props, ref, NavigationTreeContext);\n let {className, style, children, selectedRoute, ...rest} = props;\n let syncedRouteRef = useRef<string | undefined>(undefined);\n let treeRef = useObjectRef(ref);\n let context = useMemo(() => ({selectedRoute, syncedRouteRef, treeRef}), [selectedRoute, treeRef]);\n\n return (\n <InternalNavigationTreeContext.Provider value={context}>\n <Tree\n {...rest}\n ref={treeRef}\n className={className ?? 'react-aria-NavigationTree'}\n style={style}\n selectionMode=\"none\"\n keyboardNavigationBehavior=\"tab\">\n {children}\n </Tree>\n </InternalNavigationTreeContext.Provider>\n );\n});\n\nexport interface NavigationTreeItemRenderProps extends TreeItemRenderProps {\n /**\n * Whether this item is the current route (its `href` matches the NavigationTree's\n * `selectedRoute`).\n *\n * @selector [data-current]\n */\n isCurrent: boolean;\n /**\n * Whether this item is an ancestor of the current-route item (at any level, regardless of whether\n * it is expanded or collapsed).\n *\n * @selector [data-current-ancestor]\n */\n isCurrentAncestor: boolean;\n}\n\nexport interface NavigationTreeItemProps<T = object>\n extends\n Omit<\n TreeItemProps<T>,\n | 'className'\n | 'style'\n | 'render'\n | 'onAction'\n | 'allowsArrowNavigation'\n | 'focusMode'\n | 'value'\n >,\n StyleRenderProps<NavigationTreeItemRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTreeItem'\n */\n className?: ClassNameOrFunction<NavigationTreeItemRenderProps>;\n /**\n * The content of the side nav item along with any nested children. Supports static nested side\n * nav items or use of a Collection to dynamically render nested side nav items.\n */\n children: ReactNode;\n}\n\n/**\n * A NavigationTreeItem represents an individual item in a NavigationTree.\n */\nexport const NavigationTreeItem = /*#__PURE__*/ (forwardRef as forwardRefType)(\n function NavigationTreeItem<T extends object>(\n props: NavigationTreeItemProps<T>,\n ref: ForwardedRef<HTMLDivElement>\n ) {\n let {\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n className,\n style,\n render,\n ...rest\n } = props;\n let {selectedRoute, treeRef} = useContext(InternalNavigationTreeContext);\n let hasLink = href != null && href.length > 0;\n let isCurrent = hasLink && href === selectedRoute;\n let [isLinkFocused, setLinkFocused] = useState(false);\n // Additional render props NavigationTreeItem adds to what TreeItem already provides.\n let getItemRenderProps = <R extends TreeItemRenderProps>(\n renderProps: R\n ): R & {isCurrent: boolean; isCurrentAncestor: boolean} => ({\n ...renderProps,\n isCurrent,\n isCurrentAncestor: hasSelectedDescendant(renderProps.id, renderProps.state, selectedRoute),\n isFocusVisible:\n renderProps.isFocusVisible || (renderProps.isFocusVisibleWithin && isLinkFocused)\n });\n\n let objRef = useObjectRef(ref);\n useEffect(() => {\n if (isCurrent && objRef.current) {\n let scrollParent = getScrollParent(objRef.current, true) as HTMLElement;\n // Only scroll the tree's own scroll container into view — never an outer ancestor such as the\n // page. When the tree isn't its own scroll container the nearest scroll parent is outside the\n // tree, so we skip rather than hijack the surrounding scroll position.\n let treeRoot = treeRef?.current;\n if (treeRoot && nodeContains(treeRoot, scrollParent)) {\n scrollIntoView(scrollParent, objRef.current, {block: 'center'});\n }\n }\n }, [isCurrent, objRef, treeRef]);\n\n return (\n <NavigationTreeItemLinkContext.Provider\n value={{\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n isCurrent,\n isLinkFocused,\n setLinkFocused\n }}>\n <TreeItem\n {...rest}\n ref={objRef}\n href={href}\n focusMode={hasLink ? 'child' : undefined}\n allowsArrowNavigation\n data-current={isCurrent || undefined}\n className={\n typeof className === 'function'\n ? renderProps => className(getItemRenderProps(renderProps))\n : (className ?? 'react-aria-NavigationTreeItem')\n }\n style={\n typeof style === 'function'\n ? renderProps => style(getItemRenderProps(renderProps))\n : style\n }\n render={(domProps, renderProps) => {\n let values = getItemRenderProps(renderProps);\n let {children: rowChildren, ...domRest} = domProps;\n let dataProps = {\n 'data-focus-visible': values.isFocusVisible || undefined,\n 'data-current-ancestor': values.isCurrentAncestor || undefined\n };\n let content = (\n <NavigationTreeItemStateContext.Provider\n value={{isCurrentAncestor: values.isCurrentAncestor}}>\n {rowChildren}\n </NavigationTreeItemStateContext.Provider>\n );\n return typeof render === 'function' ? (\n render({...domRest, ...dataProps, children: content}, values)\n ) : (\n <dom.div {...domRest} {...dataProps}>\n {content}\n </dom.div>\n );\n }}\n />\n </NavigationTreeItemLinkContext.Provider>\n );\n }\n);\n\nexport interface NavigationTreeItemContentRenderProps extends NavigationTreeItemRenderProps {}\n\nexport interface NavigationTreeItemContentProps {\n /**\n * The children of the component. A function may be provided to alter the children based on\n * component state.\n */\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\n// The collection key of the item whose href matches `route`, or null.\nfunction findKeyForRoute(collection: Collection<Node<unknown>>, route: string): Key | null {\n for (let key of collection.getKeys()) {\n if (collection.getItem(key)?.props?.href === route) {\n return key;\n }\n }\n return null;\n}\n\n// Walks up from `key` to the closest ancestor that is actually rendered (all ancestors expanded).\n// Returns `key` unchanged when already visible. A collapsed ancestor hides everything beneath it,\n// so the highest collapsed ancestor is the closest visible row.\nfunction closestVisibleKey(\n collection: Collection<Node<unknown>>,\n expandedKeys: Set<Key>,\n key: Key\n): Key {\n let target = key;\n let node = collection.getItem(key);\n while (node?.parentKey != null) {\n let parent = collection.getItem(node.parentKey);\n if (parent?.type === 'item' && !expandedKeys.has(node.parentKey)) {\n target = node.parentKey;\n }\n node = parent;\n }\n return target;\n}\n\n// Moves the tree's focused key to the item matching selectedRoute. Runs when the route or the\n// collection changes; the shared syncedRouteRef dedupes across items so it fires once per change.\nfunction useRouteFocusSync({state}: {state: TreeState<unknown>}): void {\n let {selectedRoute, syncedRouteRef} = useContext(InternalNavigationTreeContext);\n let {collection, selectionManager, expandedKeys} = state;\n useEffect(() => {\n if (\n selectedRoute == null ||\n syncedRouteRef == null ||\n syncedRouteRef.current === selectedRoute\n ) {\n return;\n }\n let key = findKeyForRoute(collection, selectedRoute);\n if (key != null) {\n key = closestVisibleKey(collection, expandedKeys, key);\n syncedRouteRef.current = selectedRoute;\n selectionManager.setFocusedKey(key);\n }\n }, [selectedRoute, collection, expandedKeys, syncedRouteRef, selectionManager]);\n}\n\n// Cache so each row doesn't have to walk up the tree every time.\nlet selectedAncestorsCache = new WeakMap<\n Collection<Node<unknown>>,\n {selection: unknown; ancestors: Set<Key>}\n>();\n\n// The set of collection keys that are ancestors of the item matching `selectedRoute`.\nfunction getSelectedAncestors(state: TreeState<unknown>, selectedRoute: string): Set<Key> {\n let {collection} = state;\n let cached = selectedAncestorsCache.get(collection);\n if (cached && cached.selection === selectedRoute) {\n return cached.ancestors;\n }\n let matchKey = findKeyForRoute(collection, selectedRoute);\n let ancestors = new Set<Key>();\n let node = matchKey != null ? collection.getItem(matchKey) : null;\n while (node?.parentKey != null && !ancestors.has(node.parentKey)) {\n ancestors.add(node.parentKey);\n node = collection.getItem(node.parentKey);\n }\n selectedAncestorsCache.set(collection, {selection: selectedRoute, ancestors});\n return ancestors;\n}\n\n// Whether the row `id` is an ancestor of the item matching `selectedRoute`.\nfunction hasSelectedDescendant(\n id: Key | undefined,\n state: TreeState<unknown>,\n selectedRoute: string | undefined | null\n): boolean {\n if (id == null || selectedRoute == null || !state) {\n return false;\n }\n return getSelectedAncestors(state, selectedRoute).has(id);\n}\n\nexport function NavigationTreeItemContent(props: NavigationTreeItemContentProps): ReactNode {\n let linkCtx = useContext(NavigationTreeItemLinkContext);\n return (\n <TreeItemContent {...props}>\n {(treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined}) => (\n <NavigationTreeItemContentInner\n treeRenderProps={treeRenderProps}\n linkCtx={linkCtx}\n children={props.children}\n />\n )}\n </TreeItemContent>\n );\n}\n\ninterface NavigationTreeItemContentInnerProps {\n treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined};\n linkCtx: NavigationTreeItemLinkContextValue;\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\nfunction NavigationTreeItemContentInner(props: NavigationTreeItemContentInnerProps): ReactNode {\n let {treeRenderProps, linkCtx, children} = props;\n let {isCurrent, isLinkFocused, setLinkFocused, ...linkProps} = linkCtx;\n let {state, isFocusVisible, isFocusVisibleWithin, id, hasChildItems} = treeRenderProps;\n let {isCurrentAncestor} = useContext(NavigationTreeItemStateContext);\n\n useRouteFocusSync({state});\n\n // isFocusVisible follows the link: true when the row itself is keyboard focused, or when a child\n // is keyboard focused and that child is the link (not another button/action).\n let linkFocusVisible = isFocusVisible || (isFocusVisibleWithin && !!isLinkFocused);\n let values: NavigationTreeItemContentRenderProps & {defaultChildren: ReactNode | undefined} = {\n ...treeRenderProps,\n isCurrent: !!isCurrent,\n isCurrentAncestor,\n isFocusVisible: linkFocusVisible\n };\n let renderChildren = typeof children === 'function' ? children(values) : children;\n // Provide onFocusChange so the link reports its focus up to NavigationTreeItem.\n let linkContextValue = {\n ...linkProps,\n 'aria-current': isCurrent ? 'page' : undefined,\n onFocusChange: setLinkFocused,\n onPress: linkProps.href == null && hasChildItems ? () => state.toggleKey(id) : undefined\n };\n return <Provider values={[[LinkContext, linkContextValue]]}>{renderChildren}</Provider>;\n}\n\nexport interface NavigationTreeSectionProps<T> extends Omit<TreeSectionProps<T>, 'value'> {}\n\n/**\n * A NavigationTreeSection represents a section within a NavigationTree.\n */\nexport function NavigationTreeSection<T extends object>(\n props: NavigationTreeSectionProps<T>\n): ReactNode {\n return (\n <TreeSection className=\"react-aria-NavigationTreeSection\" {...props}>\n {props.children}\n </TreeSection>\n );\n}\n\nexport interface NavigationTreeHeaderProps extends TreeHeaderProps {}\n\n/**\n * A NavigationTreeHeader renders the header of a NavigationTreeSection.\n */\nexport function NavigationTreeHeader(props: NavigationTreeHeaderProps): ReactNode {\n return (\n <TreeHeader className=\"react-aria-NavigationTreeHeader\" {...props}>\n {props.children}\n </TreeHeader>\n );\n}\n"],"names":[],"version":3,"file":"NavigationTree.cjs.map"}
|
|
1
|
+
{"mappings":"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","sources":["packages/react-aria-components/src/NavigationTree.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 {\n ChildrenOrFunction,\n ClassNameOrFunction,\n ContextValue,\n dom,\n Provider,\n StyleRenderProps,\n useContextProps\n} from './utils';\nimport {Collection, forwardRefType, Key, Node, RouterOptions} from '@react-types/shared';\nimport {getScrollParent} from 'react-aria/private/utils/getScrollParent';\nimport {LinkContext} from './Link';\nimport {nodeContains} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n ReactNode,\n RefObject,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {scrollIntoView} from 'react-aria/private/utils/scrollIntoView';\nimport {\n Tree,\n TreeHeader,\n TreeHeaderProps,\n TreeItem,\n TreeItemContent,\n TreeItemContentRenderProps,\n TreeItemProps,\n TreeItemRenderProps,\n TreeProps,\n TreeRenderProps,\n TreeSection,\n TreeSectionProps\n} from './Tree';\nimport {TreeState} from 'react-stately/useTreeState';\nimport {useObjectRef} from 'react-aria/useObjectRef';\n\nexport const NavigationTreeContext =\n createContext<ContextValue<NavigationTreeProps<any>, HTMLDivElement>>(null);\n\ninterface InternalNavigationTreeContextValue {\n /** The route that is currently selected. */\n selectedRoute?: string | null;\n /** The last route the focused key was synced to; dedupes the focus sync across items. */\n syncedRouteRef?: RefObject<string | undefined>;\n /** The NavigationTree's root element, used to keep current-route scrolling inside the tree. */\n treeRef?: RefObject<HTMLDivElement | null>;\n}\nconst InternalNavigationTreeContext = createContext<InternalNavigationTreeContextValue>({});\n\ninterface NavigationTreeItemLinkContextValue {\n href?: string;\n hrefLang?: string;\n target?: string;\n rel?: string;\n download?: string | boolean;\n ping?: string;\n referrerPolicy?: ReferrerPolicy;\n routerOptions?: RouterOptions;\n isCurrent?: boolean;\n // Whether the item's link (as opposed to another focusable child such as a button) is focused.\n isLinkFocused?: boolean;\n setLinkFocused?: (isFocused: boolean) => void;\n}\nconst NavigationTreeItemLinkContext = createContext<NavigationTreeItemLinkContextValue>({});\n\nexport const NavigationTreeItemStateContext = createContext<{isCurrentAncestor: boolean}>({\n isCurrentAncestor: false\n});\n\nexport interface NavigationTreeRenderProps extends Pick<\n TreeRenderProps,\n 'isEmpty' | 'isFocused' | 'isFocusVisible' | 'state'\n> {}\n\nexport interface NavigationTreeProps<T>\n extends\n Omit<\n TreeProps<T>,\n | 'selectionMode'\n | 'selectionBehavior'\n | 'selectedKeys'\n | 'defaultSelectedKeys'\n | 'onSelectionChange'\n | 'disallowEmptySelection'\n | 'disabledBehavior'\n | 'keyboardNavigationBehavior'\n | 'escapeKeyBehavior'\n | 'shouldSelectOnPressUp'\n | 'dragAndDropHooks'\n | 'renderEmptyState'\n | 'onAction'\n | 'className'\n | 'style'\n | 'render'\n >,\n StyleRenderProps<NavigationTreeRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTree'\n */\n className?: ClassNameOrFunction<NavigationTreeRenderProps>;\n /** The route that is currently selected, matched against each item's `href`. */\n selectedRoute?: string | null;\n}\n\n/**\n * A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.\n */\nexport const NavigationTree = /*#__PURE__*/ (forwardRef as forwardRefType)(function NavigationTree<\n T\n>(props: NavigationTreeProps<T>, ref: ForwardedRef<HTMLDivElement>) {\n [props, ref] = useContextProps(props, ref, NavigationTreeContext);\n let {className, style, children, selectedRoute, ...rest} = props;\n let syncedRouteRef = useRef<string | undefined>(undefined);\n let treeRef = useObjectRef(ref);\n let context = useMemo(() => ({selectedRoute, syncedRouteRef, treeRef}), [selectedRoute, treeRef]);\n\n return (\n <InternalNavigationTreeContext.Provider value={context}>\n <Tree\n {...rest}\n ref={treeRef}\n className={className ?? 'react-aria-NavigationTree'}\n style={style}\n selectionMode=\"none\"\n keyboardNavigationBehavior=\"tab\">\n {children}\n </Tree>\n </InternalNavigationTreeContext.Provider>\n );\n});\n\nexport interface NavigationTreeItemRenderProps extends TreeItemRenderProps {\n /**\n * Whether this item is the current route (its `href` matches the NavigationTree's\n * `selectedRoute`).\n *\n * @selector [data-current]\n */\n isCurrent: boolean;\n /**\n * Whether this item is an ancestor of the current-route item (at any level, regardless of whether\n * it is expanded or collapsed).\n *\n * @selector [data-current-ancestor]\n */\n isCurrentAncestor: boolean;\n}\n\nexport interface NavigationTreeItemProps<T = object>\n extends\n Omit<\n TreeItemProps<T>,\n 'className' | 'style' | 'render' | 'onAction' | 'allowsArrowNavigation' | 'value'\n >,\n StyleRenderProps<NavigationTreeItemRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTreeItem'\n */\n className?: ClassNameOrFunction<NavigationTreeItemRenderProps>;\n /**\n * The content of the side nav item along with any nested children. Supports static nested side\n * nav items or use of a Collection to dynamically render nested side nav items.\n */\n children: ReactNode;\n}\n\n/**\n * A NavigationTreeItem represents an individual item in a NavigationTree.\n */\nexport const NavigationTreeItem = /*#__PURE__*/ (forwardRef as forwardRefType)(\n function NavigationTreeItem<T extends object>(\n props: NavigationTreeItemProps<T>,\n ref: ForwardedRef<HTMLDivElement>\n ) {\n let {\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n className,\n style,\n render,\n ...rest\n } = props;\n let {selectedRoute, treeRef} = useContext(InternalNavigationTreeContext);\n let hasLink = href != null && href.length > 0;\n let isCurrent = hasLink && href === selectedRoute;\n let [isLinkFocused, setLinkFocused] = useState(false);\n // Additional render props NavigationTreeItem adds to what TreeItem already provides.\n let getItemRenderProps = <R extends TreeItemRenderProps>(\n renderProps: R\n ): R & {isCurrent: boolean; isCurrentAncestor: boolean} => ({\n ...renderProps,\n isCurrent,\n isCurrentAncestor: hasSelectedDescendant(renderProps.id, renderProps.state, selectedRoute),\n isFocusVisible:\n renderProps.isFocusVisible || (renderProps.isFocusVisibleWithin && isLinkFocused)\n });\n\n let objRef = useObjectRef(ref);\n useEffect(() => {\n if (isCurrent && objRef.current) {\n let scrollParent = getScrollParent(objRef.current, true) as HTMLElement;\n // Only scroll the tree's own scroll container into view — never an outer ancestor such as the\n // page. When the tree isn't its own scroll container the nearest scroll parent is outside the\n // tree, so we skip rather than hijack the surrounding scroll position.\n let treeRoot = treeRef?.current;\n if (treeRoot && nodeContains(treeRoot, scrollParent)) {\n scrollIntoView(scrollParent, objRef.current, {block: 'center'});\n }\n }\n }, [isCurrent, objRef, treeRef]);\n\n return (\n <NavigationTreeItemLinkContext.Provider\n value={{\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n isCurrent,\n isLinkFocused,\n setLinkFocused\n }}>\n <TreeItem\n {...rest}\n ref={objRef}\n href={href}\n focusMode={hasLink ? 'child' : undefined}\n allowsArrowNavigation\n data-current={isCurrent || undefined}\n className={\n typeof className === 'function'\n ? renderProps => className(getItemRenderProps(renderProps))\n : (className ?? 'react-aria-NavigationTreeItem')\n }\n style={\n typeof style === 'function'\n ? renderProps => style(getItemRenderProps(renderProps))\n : style\n }\n render={(domProps, renderProps) => {\n let values = getItemRenderProps(renderProps);\n let {children: rowChildren, ...domRest} = domProps;\n let dataProps = {\n 'data-focus-visible': values.isFocusVisible || undefined,\n 'data-current-ancestor': values.isCurrentAncestor || undefined\n };\n let content = (\n <NavigationTreeItemStateContext.Provider\n value={{isCurrentAncestor: values.isCurrentAncestor}}>\n {rowChildren}\n </NavigationTreeItemStateContext.Provider>\n );\n return typeof render === 'function' ? (\n render({...domRest, ...dataProps, children: content}, values)\n ) : (\n <dom.div {...domRest} {...dataProps}>\n {content}\n </dom.div>\n );\n }}\n />\n </NavigationTreeItemLinkContext.Provider>\n );\n }\n);\n\nexport interface NavigationTreeItemContentRenderProps extends NavigationTreeItemRenderProps {}\n\nexport interface NavigationTreeItemContentProps {\n /**\n * The children of the component. A function may be provided to alter the children based on\n * component state.\n */\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\n// The collection key of the item whose href matches `route`, or null.\nfunction findKeyForRoute(collection: Collection<Node<unknown>>, route: string): Key | null {\n for (let key of collection.getKeys()) {\n if (collection.getItem(key)?.props?.href === route) {\n return key;\n }\n }\n return null;\n}\n\n// Walks up from `key` to the closest ancestor that is actually rendered (all ancestors expanded).\n// Returns `key` unchanged when already visible. A collapsed ancestor hides everything beneath it,\n// so the highest collapsed ancestor is the closest visible row.\nfunction closestVisibleKey(\n collection: Collection<Node<unknown>>,\n expandedKeys: Set<Key>,\n key: Key\n): Key {\n let target = key;\n let node = collection.getItem(key);\n while (node?.parentKey != null) {\n let parent = collection.getItem(node.parentKey);\n if (parent?.type === 'item' && !expandedKeys.has(node.parentKey)) {\n target = node.parentKey;\n }\n node = parent;\n }\n return target;\n}\n\n// Moves the tree's focused key to the item matching selectedRoute. Runs when the route or the\n// collection changes; the shared syncedRouteRef dedupes across items so it fires once per change.\nfunction useRouteFocusSync({state}: {state: TreeState<unknown>}): void {\n let {selectedRoute, syncedRouteRef} = useContext(InternalNavigationTreeContext);\n let {collection, selectionManager, expandedKeys} = state;\n useEffect(() => {\n if (\n selectedRoute == null ||\n syncedRouteRef == null ||\n syncedRouteRef.current === selectedRoute\n ) {\n return;\n }\n let key = findKeyForRoute(collection, selectedRoute);\n if (key != null) {\n key = closestVisibleKey(collection, expandedKeys, key);\n syncedRouteRef.current = selectedRoute;\n selectionManager.setFocusedKey(key);\n }\n }, [selectedRoute, collection, expandedKeys, syncedRouteRef, selectionManager]);\n}\n\n// Cache so each row doesn't have to walk up the tree every time.\nlet selectedAncestorsCache = new WeakMap<\n Collection<Node<unknown>>,\n {selection: unknown; ancestors: Set<Key>}\n>();\n\n// The set of collection keys that are ancestors of the item matching `selectedRoute`.\nfunction getSelectedAncestors(state: TreeState<unknown>, selectedRoute: string): Set<Key> {\n let {collection} = state;\n let cached = selectedAncestorsCache.get(collection);\n if (cached && cached.selection === selectedRoute) {\n return cached.ancestors;\n }\n let matchKey = findKeyForRoute(collection, selectedRoute);\n let ancestors = new Set<Key>();\n let node = matchKey != null ? collection.getItem(matchKey) : null;\n while (node?.parentKey != null && !ancestors.has(node.parentKey)) {\n ancestors.add(node.parentKey);\n node = collection.getItem(node.parentKey);\n }\n selectedAncestorsCache.set(collection, {selection: selectedRoute, ancestors});\n return ancestors;\n}\n\n// Whether the row `id` is an ancestor of the item matching `selectedRoute`.\nfunction hasSelectedDescendant(\n id: Key | undefined,\n state: TreeState<unknown>,\n selectedRoute: string | undefined | null\n): boolean {\n if (id == null || selectedRoute == null || !state) {\n return false;\n }\n return getSelectedAncestors(state, selectedRoute).has(id);\n}\n\nexport function NavigationTreeItemContent(props: NavigationTreeItemContentProps): ReactNode {\n let linkCtx = useContext(NavigationTreeItemLinkContext);\n return (\n <TreeItemContent {...props}>\n {(treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined}) => (\n <NavigationTreeItemContentInner\n treeRenderProps={treeRenderProps}\n linkCtx={linkCtx}\n children={props.children}\n />\n )}\n </TreeItemContent>\n );\n}\n\ninterface NavigationTreeItemContentInnerProps {\n treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined};\n linkCtx: NavigationTreeItemLinkContextValue;\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\nfunction NavigationTreeItemContentInner(props: NavigationTreeItemContentInnerProps): ReactNode {\n let {treeRenderProps, linkCtx, children} = props;\n let {isCurrent, isLinkFocused, setLinkFocused, ...linkProps} = linkCtx;\n let {state, isFocusVisible, isFocusVisibleWithin, id, hasChildItems} = treeRenderProps;\n let {isCurrentAncestor} = useContext(NavigationTreeItemStateContext);\n\n useRouteFocusSync({state});\n\n // isFocusVisible follows the link: true when the row itself is keyboard focused, or when a child\n // is keyboard focused and that child is the link (not another button/action).\n let linkFocusVisible = isFocusVisible || (isFocusVisibleWithin && !!isLinkFocused);\n let values: NavigationTreeItemContentRenderProps & {defaultChildren: ReactNode | undefined} = {\n ...treeRenderProps,\n isCurrent: !!isCurrent,\n isCurrentAncestor,\n isFocusVisible: linkFocusVisible\n };\n let renderChildren = typeof children === 'function' ? children(values) : children;\n // Provide onFocusChange so the link reports its focus up to NavigationTreeItem.\n let linkContextValue = {\n ...linkProps,\n 'aria-current': isCurrent ? ('page' as const) : undefined,\n onFocusChange: setLinkFocused,\n onPress: linkProps.href == null && hasChildItems ? () => state.toggleKey(id) : undefined\n };\n return <Provider values={[[LinkContext, linkContextValue]]}>{renderChildren}</Provider>;\n}\n\nexport interface NavigationTreeSectionProps<T> extends Omit<TreeSectionProps<T>, 'value'> {}\n\n/**\n * A NavigationTreeSection represents a section within a NavigationTree.\n */\nexport function NavigationTreeSection<T extends object>(\n props: NavigationTreeSectionProps<T>\n): ReactNode {\n return (\n <TreeSection className=\"react-aria-NavigationTreeSection\" {...props}>\n {props.children}\n </TreeSection>\n );\n}\n\nexport interface NavigationTreeHeaderProps extends TreeHeaderProps {}\n\n/**\n * A NavigationTreeHeader renders the header of a NavigationTreeSection.\n */\nexport function NavigationTreeHeader(props: NavigationTreeHeaderProps): ReactNode {\n return (\n <TreeHeader className=\"react-aria-NavigationTreeHeader\" {...props}>\n {props.children}\n </TreeHeader>\n );\n}\n"],"names":[],"version":3,"file":"NavigationTree.cjs.map"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/react-aria-components/src/NavigationTree.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 {\n ChildrenOrFunction,\n ClassNameOrFunction,\n ContextValue,\n dom,\n Provider,\n StyleRenderProps,\n useContextProps\n} from './utils';\nimport {Collection, forwardRefType, Key, Node, RouterOptions} from '@react-types/shared';\nimport {getScrollParent} from 'react-aria/private/utils/getScrollParent';\nimport {LinkContext} from './Link';\nimport {nodeContains} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n ReactNode,\n RefObject,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {scrollIntoView} from 'react-aria/private/utils/scrollIntoView';\nimport {\n Tree,\n TreeHeader,\n TreeHeaderProps,\n TreeItem,\n TreeItemContent,\n TreeItemContentRenderProps,\n TreeItemProps,\n TreeItemRenderProps,\n TreeProps,\n TreeRenderProps,\n TreeSection,\n TreeSectionProps\n} from './Tree';\nimport {TreeState} from 'react-stately/useTreeState';\nimport {useObjectRef} from 'react-aria/useObjectRef';\n\nexport const NavigationTreeContext =\n createContext<ContextValue<NavigationTreeProps<any>, HTMLDivElement>>(null);\n\ninterface InternalNavigationTreeContextValue {\n /** The route that is currently selected. */\n selectedRoute?: string | null;\n /** The last route the focused key was synced to; dedupes the focus sync across items. */\n syncedRouteRef?: RefObject<string | undefined>;\n /** The NavigationTree's root element, used to keep current-route scrolling inside the tree. */\n treeRef?: RefObject<HTMLDivElement | null>;\n}\nconst InternalNavigationTreeContext = createContext<InternalNavigationTreeContextValue>({});\n\ninterface NavigationTreeItemLinkContextValue {\n href?: string;\n hrefLang?: string;\n target?: string;\n rel?: string;\n download?: string | boolean;\n ping?: string;\n referrerPolicy?: ReferrerPolicy;\n routerOptions?: RouterOptions;\n isCurrent?: boolean;\n // Whether the item's link (as opposed to another focusable child such as a button) is focused.\n isLinkFocused?: boolean;\n setLinkFocused?: (isFocused: boolean) => void;\n}\nconst NavigationTreeItemLinkContext = createContext<NavigationTreeItemLinkContextValue>({});\n\nexport const NavigationTreeItemStateContext = createContext<{isCurrentAncestor: boolean}>({\n isCurrentAncestor: false\n});\n\nexport interface NavigationTreeRenderProps extends Pick<\n TreeRenderProps,\n 'isEmpty' | 'isFocused' | 'isFocusVisible' | 'state'\n> {}\n\nexport interface NavigationTreeProps<T>\n extends\n Omit<\n TreeProps<T>,\n | 'selectionMode'\n | 'selectionBehavior'\n | 'selectedKeys'\n | 'defaultSelectedKeys'\n | 'onSelectionChange'\n | 'disallowEmptySelection'\n | 'disabledBehavior'\n | 'keyboardNavigationBehavior'\n | 'escapeKeyBehavior'\n | 'shouldSelectOnPressUp'\n | 'dragAndDropHooks'\n | 'renderEmptyState'\n | 'onAction'\n | 'className'\n | 'style'\n | 'render'\n >,\n StyleRenderProps<NavigationTreeRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTree'\n */\n className?: ClassNameOrFunction<NavigationTreeRenderProps>;\n /** The route that is currently selected, matched against each item's `href`. */\n selectedRoute?: string | null;\n}\n\n/**\n * A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.\n */\nexport const NavigationTree = /*#__PURE__*/ (forwardRef as forwardRefType)(function NavigationTree<\n T\n>(props: NavigationTreeProps<T>, ref: ForwardedRef<HTMLDivElement>) {\n [props, ref] = useContextProps(props, ref, NavigationTreeContext);\n let {className, style, children, selectedRoute, ...rest} = props;\n let syncedRouteRef = useRef<string | undefined>(undefined);\n let treeRef = useObjectRef(ref);\n let context = useMemo(() => ({selectedRoute, syncedRouteRef, treeRef}), [selectedRoute, treeRef]);\n\n return (\n <InternalNavigationTreeContext.Provider value={context}>\n <Tree\n {...rest}\n ref={treeRef}\n className={className ?? 'react-aria-NavigationTree'}\n style={style}\n selectionMode=\"none\"\n keyboardNavigationBehavior=\"tab\">\n {children}\n </Tree>\n </InternalNavigationTreeContext.Provider>\n );\n});\n\nexport interface NavigationTreeItemRenderProps extends TreeItemRenderProps {\n /**\n * Whether this item is the current route (its `href` matches the NavigationTree's\n * `selectedRoute`).\n *\n * @selector [data-current]\n */\n isCurrent: boolean;\n /**\n * Whether this item is an ancestor of the current-route item (at any level, regardless of whether\n * it is expanded or collapsed).\n *\n * @selector [data-current-ancestor]\n */\n isCurrentAncestor: boolean;\n}\n\nexport interface NavigationTreeItemProps<T = object>\n extends\n Omit<\n TreeItemProps<T>,\n | 'className'\n | 'style'\n | 'render'\n | 'onAction'\n | 'allowsArrowNavigation'\n | 'focusMode'\n | 'value'\n >,\n StyleRenderProps<NavigationTreeItemRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTreeItem'\n */\n className?: ClassNameOrFunction<NavigationTreeItemRenderProps>;\n /**\n * The content of the side nav item along with any nested children. Supports static nested side\n * nav items or use of a Collection to dynamically render nested side nav items.\n */\n children: ReactNode;\n}\n\n/**\n * A NavigationTreeItem represents an individual item in a NavigationTree.\n */\nexport const NavigationTreeItem = /*#__PURE__*/ (forwardRef as forwardRefType)(\n function NavigationTreeItem<T extends object>(\n props: NavigationTreeItemProps<T>,\n ref: ForwardedRef<HTMLDivElement>\n ) {\n let {\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n className,\n style,\n render,\n ...rest\n } = props;\n let {selectedRoute, treeRef} = useContext(InternalNavigationTreeContext);\n let hasLink = href != null && href.length > 0;\n let isCurrent = hasLink && href === selectedRoute;\n let [isLinkFocused, setLinkFocused] = useState(false);\n // Additional render props NavigationTreeItem adds to what TreeItem already provides.\n let getItemRenderProps = <R extends TreeItemRenderProps>(\n renderProps: R\n ): R & {isCurrent: boolean; isCurrentAncestor: boolean} => ({\n ...renderProps,\n isCurrent,\n isCurrentAncestor: hasSelectedDescendant(renderProps.id, renderProps.state, selectedRoute),\n isFocusVisible:\n renderProps.isFocusVisible || (renderProps.isFocusVisibleWithin && isLinkFocused)\n });\n\n let objRef = useObjectRef(ref);\n useEffect(() => {\n if (isCurrent && objRef.current) {\n let scrollParent = getScrollParent(objRef.current, true) as HTMLElement;\n // Only scroll the tree's own scroll container into view — never an outer ancestor such as the\n // page. When the tree isn't its own scroll container the nearest scroll parent is outside the\n // tree, so we skip rather than hijack the surrounding scroll position.\n let treeRoot = treeRef?.current;\n if (treeRoot && nodeContains(treeRoot, scrollParent)) {\n scrollIntoView(scrollParent, objRef.current, {block: 'center'});\n }\n }\n }, [isCurrent, objRef, treeRef]);\n\n return (\n <NavigationTreeItemLinkContext.Provider\n value={{\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n isCurrent,\n isLinkFocused,\n setLinkFocused\n }}>\n <TreeItem\n {...rest}\n ref={objRef}\n href={href}\n focusMode={hasLink ? 'child' : undefined}\n allowsArrowNavigation\n data-current={isCurrent || undefined}\n className={\n typeof className === 'function'\n ? renderProps => className(getItemRenderProps(renderProps))\n : (className ?? 'react-aria-NavigationTreeItem')\n }\n style={\n typeof style === 'function'\n ? renderProps => style(getItemRenderProps(renderProps))\n : style\n }\n render={(domProps, renderProps) => {\n let values = getItemRenderProps(renderProps);\n let {children: rowChildren, ...domRest} = domProps;\n let dataProps = {\n 'data-focus-visible': values.isFocusVisible || undefined,\n 'data-current-ancestor': values.isCurrentAncestor || undefined\n };\n let content = (\n <NavigationTreeItemStateContext.Provider\n value={{isCurrentAncestor: values.isCurrentAncestor}}>\n {rowChildren}\n </NavigationTreeItemStateContext.Provider>\n );\n return typeof render === 'function' ? (\n render({...domRest, ...dataProps, children: content}, values)\n ) : (\n <dom.div {...domRest} {...dataProps}>\n {content}\n </dom.div>\n );\n }}\n />\n </NavigationTreeItemLinkContext.Provider>\n );\n }\n);\n\nexport interface NavigationTreeItemContentRenderProps extends NavigationTreeItemRenderProps {}\n\nexport interface NavigationTreeItemContentProps {\n /**\n * The children of the component. A function may be provided to alter the children based on\n * component state.\n */\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\n// The collection key of the item whose href matches `route`, or null.\nfunction findKeyForRoute(collection: Collection<Node<unknown>>, route: string): Key | null {\n for (let key of collection.getKeys()) {\n if (collection.getItem(key)?.props?.href === route) {\n return key;\n }\n }\n return null;\n}\n\n// Walks up from `key` to the closest ancestor that is actually rendered (all ancestors expanded).\n// Returns `key` unchanged when already visible. A collapsed ancestor hides everything beneath it,\n// so the highest collapsed ancestor is the closest visible row.\nfunction closestVisibleKey(\n collection: Collection<Node<unknown>>,\n expandedKeys: Set<Key>,\n key: Key\n): Key {\n let target = key;\n let node = collection.getItem(key);\n while (node?.parentKey != null) {\n let parent = collection.getItem(node.parentKey);\n if (parent?.type === 'item' && !expandedKeys.has(node.parentKey)) {\n target = node.parentKey;\n }\n node = parent;\n }\n return target;\n}\n\n// Moves the tree's focused key to the item matching selectedRoute. Runs when the route or the\n// collection changes; the shared syncedRouteRef dedupes across items so it fires once per change.\nfunction useRouteFocusSync({state}: {state: TreeState<unknown>}): void {\n let {selectedRoute, syncedRouteRef} = useContext(InternalNavigationTreeContext);\n let {collection, selectionManager, expandedKeys} = state;\n useEffect(() => {\n if (\n selectedRoute == null ||\n syncedRouteRef == null ||\n syncedRouteRef.current === selectedRoute\n ) {\n return;\n }\n let key = findKeyForRoute(collection, selectedRoute);\n if (key != null) {\n key = closestVisibleKey(collection, expandedKeys, key);\n syncedRouteRef.current = selectedRoute;\n selectionManager.setFocusedKey(key);\n }\n }, [selectedRoute, collection, expandedKeys, syncedRouteRef, selectionManager]);\n}\n\n// Cache so each row doesn't have to walk up the tree every time.\nlet selectedAncestorsCache = new WeakMap<\n Collection<Node<unknown>>,\n {selection: unknown; ancestors: Set<Key>}\n>();\n\n// The set of collection keys that are ancestors of the item matching `selectedRoute`.\nfunction getSelectedAncestors(state: TreeState<unknown>, selectedRoute: string): Set<Key> {\n let {collection} = state;\n let cached = selectedAncestorsCache.get(collection);\n if (cached && cached.selection === selectedRoute) {\n return cached.ancestors;\n }\n let matchKey = findKeyForRoute(collection, selectedRoute);\n let ancestors = new Set<Key>();\n let node = matchKey != null ? collection.getItem(matchKey) : null;\n while (node?.parentKey != null && !ancestors.has(node.parentKey)) {\n ancestors.add(node.parentKey);\n node = collection.getItem(node.parentKey);\n }\n selectedAncestorsCache.set(collection, {selection: selectedRoute, ancestors});\n return ancestors;\n}\n\n// Whether the row `id` is an ancestor of the item matching `selectedRoute`.\nfunction hasSelectedDescendant(\n id: Key | undefined,\n state: TreeState<unknown>,\n selectedRoute: string | undefined | null\n): boolean {\n if (id == null || selectedRoute == null || !state) {\n return false;\n }\n return getSelectedAncestors(state, selectedRoute).has(id);\n}\n\nexport function NavigationTreeItemContent(props: NavigationTreeItemContentProps): ReactNode {\n let linkCtx = useContext(NavigationTreeItemLinkContext);\n return (\n <TreeItemContent {...props}>\n {(treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined}) => (\n <NavigationTreeItemContentInner\n treeRenderProps={treeRenderProps}\n linkCtx={linkCtx}\n children={props.children}\n />\n )}\n </TreeItemContent>\n );\n}\n\ninterface NavigationTreeItemContentInnerProps {\n treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined};\n linkCtx: NavigationTreeItemLinkContextValue;\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\nfunction NavigationTreeItemContentInner(props: NavigationTreeItemContentInnerProps): ReactNode {\n let {treeRenderProps, linkCtx, children} = props;\n let {isCurrent, isLinkFocused, setLinkFocused, ...linkProps} = linkCtx;\n let {state, isFocusVisible, isFocusVisibleWithin, id, hasChildItems} = treeRenderProps;\n let {isCurrentAncestor} = useContext(NavigationTreeItemStateContext);\n\n useRouteFocusSync({state});\n\n // isFocusVisible follows the link: true when the row itself is keyboard focused, or when a child\n // is keyboard focused and that child is the link (not another button/action).\n let linkFocusVisible = isFocusVisible || (isFocusVisibleWithin && !!isLinkFocused);\n let values: NavigationTreeItemContentRenderProps & {defaultChildren: ReactNode | undefined} = {\n ...treeRenderProps,\n isCurrent: !!isCurrent,\n isCurrentAncestor,\n isFocusVisible: linkFocusVisible\n };\n let renderChildren = typeof children === 'function' ? children(values) : children;\n // Provide onFocusChange so the link reports its focus up to NavigationTreeItem.\n let linkContextValue = {\n ...linkProps,\n 'aria-current': isCurrent ? 'page' : undefined,\n onFocusChange: setLinkFocused,\n onPress: linkProps.href == null && hasChildItems ? () => state.toggleKey(id) : undefined\n };\n return <Provider values={[[LinkContext, linkContextValue]]}>{renderChildren}</Provider>;\n}\n\nexport interface NavigationTreeSectionProps<T> extends Omit<TreeSectionProps<T>, 'value'> {}\n\n/**\n * A NavigationTreeSection represents a section within a NavigationTree.\n */\nexport function NavigationTreeSection<T extends object>(\n props: NavigationTreeSectionProps<T>\n): ReactNode {\n return (\n <TreeSection className=\"react-aria-NavigationTreeSection\" {...props}>\n {props.children}\n </TreeSection>\n );\n}\n\nexport interface NavigationTreeHeaderProps extends TreeHeaderProps {}\n\n/**\n * A NavigationTreeHeader renders the header of a NavigationTreeSection.\n */\nexport function NavigationTreeHeader(props: NavigationTreeHeaderProps): ReactNode {\n return (\n <TreeHeader className=\"react-aria-NavigationTreeHeader\" {...props}>\n {props.children}\n </TreeHeader>\n );\n}\n"],"names":[],"version":3,"file":"NavigationTree.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["packages/react-aria-components/src/NavigationTree.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 {\n ChildrenOrFunction,\n ClassNameOrFunction,\n ContextValue,\n dom,\n Provider,\n StyleRenderProps,\n useContextProps\n} from './utils';\nimport {Collection, forwardRefType, Key, Node, RouterOptions} from '@react-types/shared';\nimport {getScrollParent} from 'react-aria/private/utils/getScrollParent';\nimport {LinkContext} from './Link';\nimport {nodeContains} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n ReactNode,\n RefObject,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {scrollIntoView} from 'react-aria/private/utils/scrollIntoView';\nimport {\n Tree,\n TreeHeader,\n TreeHeaderProps,\n TreeItem,\n TreeItemContent,\n TreeItemContentRenderProps,\n TreeItemProps,\n TreeItemRenderProps,\n TreeProps,\n TreeRenderProps,\n TreeSection,\n TreeSectionProps\n} from './Tree';\nimport {TreeState} from 'react-stately/useTreeState';\nimport {useObjectRef} from 'react-aria/useObjectRef';\n\nexport const NavigationTreeContext =\n createContext<ContextValue<NavigationTreeProps<any>, HTMLDivElement>>(null);\n\ninterface InternalNavigationTreeContextValue {\n /** The route that is currently selected. */\n selectedRoute?: string | null;\n /** The last route the focused key was synced to; dedupes the focus sync across items. */\n syncedRouteRef?: RefObject<string | undefined>;\n /** The NavigationTree's root element, used to keep current-route scrolling inside the tree. */\n treeRef?: RefObject<HTMLDivElement | null>;\n}\nconst InternalNavigationTreeContext = createContext<InternalNavigationTreeContextValue>({});\n\ninterface NavigationTreeItemLinkContextValue {\n href?: string;\n hrefLang?: string;\n target?: string;\n rel?: string;\n download?: string | boolean;\n ping?: string;\n referrerPolicy?: ReferrerPolicy;\n routerOptions?: RouterOptions;\n isCurrent?: boolean;\n // Whether the item's link (as opposed to another focusable child such as a button) is focused.\n isLinkFocused?: boolean;\n setLinkFocused?: (isFocused: boolean) => void;\n}\nconst NavigationTreeItemLinkContext = createContext<NavigationTreeItemLinkContextValue>({});\n\nexport const NavigationTreeItemStateContext = createContext<{isCurrentAncestor: boolean}>({\n isCurrentAncestor: false\n});\n\nexport interface NavigationTreeRenderProps extends Pick<\n TreeRenderProps,\n 'isEmpty' | 'isFocused' | 'isFocusVisible' | 'state'\n> {}\n\nexport interface NavigationTreeProps<T>\n extends\n Omit<\n TreeProps<T>,\n | 'selectionMode'\n | 'selectionBehavior'\n | 'selectedKeys'\n | 'defaultSelectedKeys'\n | 'onSelectionChange'\n | 'disallowEmptySelection'\n | 'disabledBehavior'\n | 'keyboardNavigationBehavior'\n | 'escapeKeyBehavior'\n | 'shouldSelectOnPressUp'\n | 'dragAndDropHooks'\n | 'renderEmptyState'\n | 'onAction'\n | 'className'\n | 'style'\n | 'render'\n >,\n StyleRenderProps<NavigationTreeRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTree'\n */\n className?: ClassNameOrFunction<NavigationTreeRenderProps>;\n /** The route that is currently selected, matched against each item's `href`. */\n selectedRoute?: string | null;\n}\n\n/**\n * A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.\n */\nexport const NavigationTree = /*#__PURE__*/ (forwardRef as forwardRefType)(function NavigationTree<\n T\n>(props: NavigationTreeProps<T>, ref: ForwardedRef<HTMLDivElement>) {\n [props, ref] = useContextProps(props, ref, NavigationTreeContext);\n let {className, style, children, selectedRoute, ...rest} = props;\n let syncedRouteRef = useRef<string | undefined>(undefined);\n let treeRef = useObjectRef(ref);\n let context = useMemo(() => ({selectedRoute, syncedRouteRef, treeRef}), [selectedRoute, treeRef]);\n\n return (\n <InternalNavigationTreeContext.Provider value={context}>\n <Tree\n {...rest}\n ref={treeRef}\n className={className ?? 'react-aria-NavigationTree'}\n style={style}\n selectionMode=\"none\"\n keyboardNavigationBehavior=\"tab\">\n {children}\n </Tree>\n </InternalNavigationTreeContext.Provider>\n );\n});\n\nexport interface NavigationTreeItemRenderProps extends TreeItemRenderProps {\n /**\n * Whether this item is the current route (its `href` matches the NavigationTree's\n * `selectedRoute`).\n *\n * @selector [data-current]\n */\n isCurrent: boolean;\n /**\n * Whether this item is an ancestor of the current-route item (at any level, regardless of whether\n * it is expanded or collapsed).\n *\n * @selector [data-current-ancestor]\n */\n isCurrentAncestor: boolean;\n}\n\nexport interface NavigationTreeItemProps<T = object>\n extends\n Omit<\n TreeItemProps<T>,\n 'className' | 'style' | 'render' | 'onAction' | 'allowsArrowNavigation' | 'value'\n >,\n StyleRenderProps<NavigationTreeItemRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTreeItem'\n */\n className?: ClassNameOrFunction<NavigationTreeItemRenderProps>;\n /**\n * The content of the side nav item along with any nested children. Supports static nested side\n * nav items or use of a Collection to dynamically render nested side nav items.\n */\n children: ReactNode;\n}\n\n/**\n * A NavigationTreeItem represents an individual item in a NavigationTree.\n */\nexport const NavigationTreeItem = /*#__PURE__*/ (forwardRef as forwardRefType)(\n function NavigationTreeItem<T extends object>(\n props: NavigationTreeItemProps<T>,\n ref: ForwardedRef<HTMLDivElement>\n ) {\n let {\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n className,\n style,\n render,\n ...rest\n } = props;\n let {selectedRoute, treeRef} = useContext(InternalNavigationTreeContext);\n let hasLink = href != null && href.length > 0;\n let isCurrent = hasLink && href === selectedRoute;\n let [isLinkFocused, setLinkFocused] = useState(false);\n // Additional render props NavigationTreeItem adds to what TreeItem already provides.\n let getItemRenderProps = <R extends TreeItemRenderProps>(\n renderProps: R\n ): R & {isCurrent: boolean; isCurrentAncestor: boolean} => ({\n ...renderProps,\n isCurrent,\n isCurrentAncestor: hasSelectedDescendant(renderProps.id, renderProps.state, selectedRoute),\n isFocusVisible:\n renderProps.isFocusVisible || (renderProps.isFocusVisibleWithin && isLinkFocused)\n });\n\n let objRef = useObjectRef(ref);\n useEffect(() => {\n if (isCurrent && objRef.current) {\n let scrollParent = getScrollParent(objRef.current, true) as HTMLElement;\n // Only scroll the tree's own scroll container into view — never an outer ancestor such as the\n // page. When the tree isn't its own scroll container the nearest scroll parent is outside the\n // tree, so we skip rather than hijack the surrounding scroll position.\n let treeRoot = treeRef?.current;\n if (treeRoot && nodeContains(treeRoot, scrollParent)) {\n scrollIntoView(scrollParent, objRef.current, {block: 'center'});\n }\n }\n }, [isCurrent, objRef, treeRef]);\n\n return (\n <NavigationTreeItemLinkContext.Provider\n value={{\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n isCurrent,\n isLinkFocused,\n setLinkFocused\n }}>\n <TreeItem\n {...rest}\n ref={objRef}\n href={href}\n focusMode={hasLink ? 'child' : undefined}\n allowsArrowNavigation\n data-current={isCurrent || undefined}\n className={\n typeof className === 'function'\n ? renderProps => className(getItemRenderProps(renderProps))\n : (className ?? 'react-aria-NavigationTreeItem')\n }\n style={\n typeof style === 'function'\n ? renderProps => style(getItemRenderProps(renderProps))\n : style\n }\n render={(domProps, renderProps) => {\n let values = getItemRenderProps(renderProps);\n let {children: rowChildren, ...domRest} = domProps;\n let dataProps = {\n 'data-focus-visible': values.isFocusVisible || undefined,\n 'data-current-ancestor': values.isCurrentAncestor || undefined\n };\n let content = (\n <NavigationTreeItemStateContext.Provider\n value={{isCurrentAncestor: values.isCurrentAncestor}}>\n {rowChildren}\n </NavigationTreeItemStateContext.Provider>\n );\n return typeof render === 'function' ? (\n render({...domRest, ...dataProps, children: content}, values)\n ) : (\n <dom.div {...domRest} {...dataProps}>\n {content}\n </dom.div>\n );\n }}\n />\n </NavigationTreeItemLinkContext.Provider>\n );\n }\n);\n\nexport interface NavigationTreeItemContentRenderProps extends NavigationTreeItemRenderProps {}\n\nexport interface NavigationTreeItemContentProps {\n /**\n * The children of the component. A function may be provided to alter the children based on\n * component state.\n */\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\n// The collection key of the item whose href matches `route`, or null.\nfunction findKeyForRoute(collection: Collection<Node<unknown>>, route: string): Key | null {\n for (let key of collection.getKeys()) {\n if (collection.getItem(key)?.props?.href === route) {\n return key;\n }\n }\n return null;\n}\n\n// Walks up from `key` to the closest ancestor that is actually rendered (all ancestors expanded).\n// Returns `key` unchanged when already visible. A collapsed ancestor hides everything beneath it,\n// so the highest collapsed ancestor is the closest visible row.\nfunction closestVisibleKey(\n collection: Collection<Node<unknown>>,\n expandedKeys: Set<Key>,\n key: Key\n): Key {\n let target = key;\n let node = collection.getItem(key);\n while (node?.parentKey != null) {\n let parent = collection.getItem(node.parentKey);\n if (parent?.type === 'item' && !expandedKeys.has(node.parentKey)) {\n target = node.parentKey;\n }\n node = parent;\n }\n return target;\n}\n\n// Moves the tree's focused key to the item matching selectedRoute. Runs when the route or the\n// collection changes; the shared syncedRouteRef dedupes across items so it fires once per change.\nfunction useRouteFocusSync({state}: {state: TreeState<unknown>}): void {\n let {selectedRoute, syncedRouteRef} = useContext(InternalNavigationTreeContext);\n let {collection, selectionManager, expandedKeys} = state;\n useEffect(() => {\n if (\n selectedRoute == null ||\n syncedRouteRef == null ||\n syncedRouteRef.current === selectedRoute\n ) {\n return;\n }\n let key = findKeyForRoute(collection, selectedRoute);\n if (key != null) {\n key = closestVisibleKey(collection, expandedKeys, key);\n syncedRouteRef.current = selectedRoute;\n selectionManager.setFocusedKey(key);\n }\n }, [selectedRoute, collection, expandedKeys, syncedRouteRef, selectionManager]);\n}\n\n// Cache so each row doesn't have to walk up the tree every time.\nlet selectedAncestorsCache = new WeakMap<\n Collection<Node<unknown>>,\n {selection: unknown; ancestors: Set<Key>}\n>();\n\n// The set of collection keys that are ancestors of the item matching `selectedRoute`.\nfunction getSelectedAncestors(state: TreeState<unknown>, selectedRoute: string): Set<Key> {\n let {collection} = state;\n let cached = selectedAncestorsCache.get(collection);\n if (cached && cached.selection === selectedRoute) {\n return cached.ancestors;\n }\n let matchKey = findKeyForRoute(collection, selectedRoute);\n let ancestors = new Set<Key>();\n let node = matchKey != null ? collection.getItem(matchKey) : null;\n while (node?.parentKey != null && !ancestors.has(node.parentKey)) {\n ancestors.add(node.parentKey);\n node = collection.getItem(node.parentKey);\n }\n selectedAncestorsCache.set(collection, {selection: selectedRoute, ancestors});\n return ancestors;\n}\n\n// Whether the row `id` is an ancestor of the item matching `selectedRoute`.\nfunction hasSelectedDescendant(\n id: Key | undefined,\n state: TreeState<unknown>,\n selectedRoute: string | undefined | null\n): boolean {\n if (id == null || selectedRoute == null || !state) {\n return false;\n }\n return getSelectedAncestors(state, selectedRoute).has(id);\n}\n\nexport function NavigationTreeItemContent(props: NavigationTreeItemContentProps): ReactNode {\n let linkCtx = useContext(NavigationTreeItemLinkContext);\n return (\n <TreeItemContent {...props}>\n {(treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined}) => (\n <NavigationTreeItemContentInner\n treeRenderProps={treeRenderProps}\n linkCtx={linkCtx}\n children={props.children}\n />\n )}\n </TreeItemContent>\n );\n}\n\ninterface NavigationTreeItemContentInnerProps {\n treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined};\n linkCtx: NavigationTreeItemLinkContextValue;\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\nfunction NavigationTreeItemContentInner(props: NavigationTreeItemContentInnerProps): ReactNode {\n let {treeRenderProps, linkCtx, children} = props;\n let {isCurrent, isLinkFocused, setLinkFocused, ...linkProps} = linkCtx;\n let {state, isFocusVisible, isFocusVisibleWithin, id, hasChildItems} = treeRenderProps;\n let {isCurrentAncestor} = useContext(NavigationTreeItemStateContext);\n\n useRouteFocusSync({state});\n\n // isFocusVisible follows the link: true when the row itself is keyboard focused, or when a child\n // is keyboard focused and that child is the link (not another button/action).\n let linkFocusVisible = isFocusVisible || (isFocusVisibleWithin && !!isLinkFocused);\n let values: NavigationTreeItemContentRenderProps & {defaultChildren: ReactNode | undefined} = {\n ...treeRenderProps,\n isCurrent: !!isCurrent,\n isCurrentAncestor,\n isFocusVisible: linkFocusVisible\n };\n let renderChildren = typeof children === 'function' ? children(values) : children;\n // Provide onFocusChange so the link reports its focus up to NavigationTreeItem.\n let linkContextValue = {\n ...linkProps,\n 'aria-current': isCurrent ? ('page' as const) : undefined,\n onFocusChange: setLinkFocused,\n onPress: linkProps.href == null && hasChildItems ? () => state.toggleKey(id) : undefined\n };\n return <Provider values={[[LinkContext, linkContextValue]]}>{renderChildren}</Provider>;\n}\n\nexport interface NavigationTreeSectionProps<T> extends Omit<TreeSectionProps<T>, 'value'> {}\n\n/**\n * A NavigationTreeSection represents a section within a NavigationTree.\n */\nexport function NavigationTreeSection<T extends object>(\n props: NavigationTreeSectionProps<T>\n): ReactNode {\n return (\n <TreeSection className=\"react-aria-NavigationTreeSection\" {...props}>\n {props.children}\n </TreeSection>\n );\n}\n\nexport interface NavigationTreeHeaderProps extends TreeHeaderProps {}\n\n/**\n * A NavigationTreeHeader renders the header of a NavigationTreeSection.\n */\nexport function NavigationTreeHeader(props: NavigationTreeHeaderProps): ReactNode {\n return (\n <TreeHeader className=\"react-aria-NavigationTreeHeader\" {...props}>\n {props.children}\n </TreeHeader>\n );\n}\n"],"names":[],"version":3,"file":"NavigationTree.js.map"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/react-aria-components/src/NavigationTree.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 {\n ChildrenOrFunction,\n ClassNameOrFunction,\n ContextValue,\n dom,\n Provider,\n StyleRenderProps,\n useContextProps\n} from './utils';\nimport {Collection, forwardRefType, Key, Node, RouterOptions} from '@react-types/shared';\nimport {getScrollParent} from 'react-aria/private/utils/getScrollParent';\nimport {LinkContext} from './Link';\nimport {nodeContains} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n ReactNode,\n RefObject,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {scrollIntoView} from 'react-aria/private/utils/scrollIntoView';\nimport {\n Tree,\n TreeHeader,\n TreeHeaderProps,\n TreeItem,\n TreeItemContent,\n TreeItemContentRenderProps,\n TreeItemProps,\n TreeItemRenderProps,\n TreeProps,\n TreeRenderProps,\n TreeSection,\n TreeSectionProps\n} from './Tree';\nimport {TreeState} from 'react-stately/useTreeState';\nimport {useObjectRef} from 'react-aria/useObjectRef';\n\nexport const NavigationTreeContext =\n createContext<ContextValue<NavigationTreeProps<any>, HTMLDivElement>>(null);\n\ninterface InternalNavigationTreeContextValue {\n /** The route that is currently selected. */\n selectedRoute?: string | null;\n /** The last route the focused key was synced to; dedupes the focus sync across items. */\n syncedRouteRef?: RefObject<string | undefined>;\n /** The NavigationTree's root element, used to keep current-route scrolling inside the tree. */\n treeRef?: RefObject<HTMLDivElement | null>;\n}\nconst InternalNavigationTreeContext = createContext<InternalNavigationTreeContextValue>({});\n\ninterface NavigationTreeItemLinkContextValue {\n href?: string;\n hrefLang?: string;\n target?: string;\n rel?: string;\n download?: string | boolean;\n ping?: string;\n referrerPolicy?: ReferrerPolicy;\n routerOptions?: RouterOptions;\n isCurrent?: boolean;\n // Whether the item's link (as opposed to another focusable child such as a button) is focused.\n isLinkFocused?: boolean;\n setLinkFocused?: (isFocused: boolean) => void;\n}\nconst NavigationTreeItemLinkContext = createContext<NavigationTreeItemLinkContextValue>({});\n\nexport const NavigationTreeItemStateContext = createContext<{isCurrentAncestor: boolean}>({\n isCurrentAncestor: false\n});\n\nexport interface NavigationTreeRenderProps extends Pick<\n TreeRenderProps,\n 'isEmpty' | 'isFocused' | 'isFocusVisible' | 'state'\n> {}\n\nexport interface NavigationTreeProps<T>\n extends\n Omit<\n TreeProps<T>,\n | 'selectionMode'\n | 'selectionBehavior'\n | 'selectedKeys'\n | 'defaultSelectedKeys'\n | 'onSelectionChange'\n | 'disallowEmptySelection'\n | 'disabledBehavior'\n | 'keyboardNavigationBehavior'\n | 'escapeKeyBehavior'\n | 'shouldSelectOnPressUp'\n | 'dragAndDropHooks'\n | 'renderEmptyState'\n | 'onAction'\n | 'className'\n | 'style'\n | 'render'\n >,\n StyleRenderProps<NavigationTreeRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTree'\n */\n className?: ClassNameOrFunction<NavigationTreeRenderProps>;\n /** The route that is currently selected, matched against each item's `href`. */\n selectedRoute?: string | null;\n}\n\n/**\n * A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.\n */\nexport const NavigationTree = /*#__PURE__*/ (forwardRef as forwardRefType)(function NavigationTree<\n T\n>(props: NavigationTreeProps<T>, ref: ForwardedRef<HTMLDivElement>) {\n [props, ref] = useContextProps(props, ref, NavigationTreeContext);\n let {className, style, children, selectedRoute, ...rest} = props;\n let syncedRouteRef = useRef<string | undefined>(undefined);\n let treeRef = useObjectRef(ref);\n let context = useMemo(() => ({selectedRoute, syncedRouteRef, treeRef}), [selectedRoute, treeRef]);\n\n return (\n <InternalNavigationTreeContext.Provider value={context}>\n <Tree\n {...rest}\n ref={treeRef}\n className={className ?? 'react-aria-NavigationTree'}\n style={style}\n selectionMode=\"none\"\n keyboardNavigationBehavior=\"tab\">\n {children}\n </Tree>\n </InternalNavigationTreeContext.Provider>\n );\n});\n\nexport interface NavigationTreeItemRenderProps extends TreeItemRenderProps {\n /**\n * Whether this item is the current route (its `href` matches the NavigationTree's\n * `selectedRoute`).\n *\n * @selector [data-current]\n */\n isCurrent: boolean;\n /**\n * Whether this item is an ancestor of the current-route item (at any level, regardless of whether\n * it is expanded or collapsed).\n *\n * @selector [data-current-ancestor]\n */\n isCurrentAncestor: boolean;\n}\n\nexport interface NavigationTreeItemProps<T = object>\n extends\n Omit<\n TreeItemProps<T>,\n | 'className'\n | 'style'\n | 'render'\n | 'onAction'\n | 'allowsArrowNavigation'\n | 'focusMode'\n | 'value'\n >,\n StyleRenderProps<NavigationTreeItemRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTreeItem'\n */\n className?: ClassNameOrFunction<NavigationTreeItemRenderProps>;\n /**\n * The content of the side nav item along with any nested children. Supports static nested side\n * nav items or use of a Collection to dynamically render nested side nav items.\n */\n children: ReactNode;\n}\n\n/**\n * A NavigationTreeItem represents an individual item in a NavigationTree.\n */\nexport const NavigationTreeItem = /*#__PURE__*/ (forwardRef as forwardRefType)(\n function NavigationTreeItem<T extends object>(\n props: NavigationTreeItemProps<T>,\n ref: ForwardedRef<HTMLDivElement>\n ) {\n let {\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n className,\n style,\n render,\n ...rest\n } = props;\n let {selectedRoute, treeRef} = useContext(InternalNavigationTreeContext);\n let hasLink = href != null && href.length > 0;\n let isCurrent = hasLink && href === selectedRoute;\n let [isLinkFocused, setLinkFocused] = useState(false);\n // Additional render props NavigationTreeItem adds to what TreeItem already provides.\n let getItemRenderProps = <R extends TreeItemRenderProps>(\n renderProps: R\n ): R & {isCurrent: boolean; isCurrentAncestor: boolean} => ({\n ...renderProps,\n isCurrent,\n isCurrentAncestor: hasSelectedDescendant(renderProps.id, renderProps.state, selectedRoute),\n isFocusVisible:\n renderProps.isFocusVisible || (renderProps.isFocusVisibleWithin && isLinkFocused)\n });\n\n let objRef = useObjectRef(ref);\n useEffect(() => {\n if (isCurrent && objRef.current) {\n let scrollParent = getScrollParent(objRef.current, true) as HTMLElement;\n // Only scroll the tree's own scroll container into view — never an outer ancestor such as the\n // page. When the tree isn't its own scroll container the nearest scroll parent is outside the\n // tree, so we skip rather than hijack the surrounding scroll position.\n let treeRoot = treeRef?.current;\n if (treeRoot && nodeContains(treeRoot, scrollParent)) {\n scrollIntoView(scrollParent, objRef.current, {block: 'center'});\n }\n }\n }, [isCurrent, objRef, treeRef]);\n\n return (\n <NavigationTreeItemLinkContext.Provider\n value={{\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n isCurrent,\n isLinkFocused,\n setLinkFocused\n }}>\n <TreeItem\n {...rest}\n ref={objRef}\n href={href}\n focusMode={hasLink ? 'child' : undefined}\n allowsArrowNavigation\n data-current={isCurrent || undefined}\n className={\n typeof className === 'function'\n ? renderProps => className(getItemRenderProps(renderProps))\n : (className ?? 'react-aria-NavigationTreeItem')\n }\n style={\n typeof style === 'function'\n ? renderProps => style(getItemRenderProps(renderProps))\n : style\n }\n render={(domProps, renderProps) => {\n let values = getItemRenderProps(renderProps);\n let {children: rowChildren, ...domRest} = domProps;\n let dataProps = {\n 'data-focus-visible': values.isFocusVisible || undefined,\n 'data-current-ancestor': values.isCurrentAncestor || undefined\n };\n let content = (\n <NavigationTreeItemStateContext.Provider\n value={{isCurrentAncestor: values.isCurrentAncestor}}>\n {rowChildren}\n </NavigationTreeItemStateContext.Provider>\n );\n return typeof render === 'function' ? (\n render({...domRest, ...dataProps, children: content}, values)\n ) : (\n <dom.div {...domRest} {...dataProps}>\n {content}\n </dom.div>\n );\n }}\n />\n </NavigationTreeItemLinkContext.Provider>\n );\n }\n);\n\nexport interface NavigationTreeItemContentRenderProps extends NavigationTreeItemRenderProps {}\n\nexport interface NavigationTreeItemContentProps {\n /**\n * The children of the component. A function may be provided to alter the children based on\n * component state.\n */\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\n// The collection key of the item whose href matches `route`, or null.\nfunction findKeyForRoute(collection: Collection<Node<unknown>>, route: string): Key | null {\n for (let key of collection.getKeys()) {\n if (collection.getItem(key)?.props?.href === route) {\n return key;\n }\n }\n return null;\n}\n\n// Walks up from `key` to the closest ancestor that is actually rendered (all ancestors expanded).\n// Returns `key` unchanged when already visible. A collapsed ancestor hides everything beneath it,\n// so the highest collapsed ancestor is the closest visible row.\nfunction closestVisibleKey(\n collection: Collection<Node<unknown>>,\n expandedKeys: Set<Key>,\n key: Key\n): Key {\n let target = key;\n let node = collection.getItem(key);\n while (node?.parentKey != null) {\n let parent = collection.getItem(node.parentKey);\n if (parent?.type === 'item' && !expandedKeys.has(node.parentKey)) {\n target = node.parentKey;\n }\n node = parent;\n }\n return target;\n}\n\n// Moves the tree's focused key to the item matching selectedRoute. Runs when the route or the\n// collection changes; the shared syncedRouteRef dedupes across items so it fires once per change.\nfunction useRouteFocusSync({state}: {state: TreeState<unknown>}): void {\n let {selectedRoute, syncedRouteRef} = useContext(InternalNavigationTreeContext);\n let {collection, selectionManager, expandedKeys} = state;\n useEffect(() => {\n if (\n selectedRoute == null ||\n syncedRouteRef == null ||\n syncedRouteRef.current === selectedRoute\n ) {\n return;\n }\n let key = findKeyForRoute(collection, selectedRoute);\n if (key != null) {\n key = closestVisibleKey(collection, expandedKeys, key);\n syncedRouteRef.current = selectedRoute;\n selectionManager.setFocusedKey(key);\n }\n }, [selectedRoute, collection, expandedKeys, syncedRouteRef, selectionManager]);\n}\n\n// Cache so each row doesn't have to walk up the tree every time.\nlet selectedAncestorsCache = new WeakMap<\n Collection<Node<unknown>>,\n {selection: unknown; ancestors: Set<Key>}\n>();\n\n// The set of collection keys that are ancestors of the item matching `selectedRoute`.\nfunction getSelectedAncestors(state: TreeState<unknown>, selectedRoute: string): Set<Key> {\n let {collection} = state;\n let cached = selectedAncestorsCache.get(collection);\n if (cached && cached.selection === selectedRoute) {\n return cached.ancestors;\n }\n let matchKey = findKeyForRoute(collection, selectedRoute);\n let ancestors = new Set<Key>();\n let node = matchKey != null ? collection.getItem(matchKey) : null;\n while (node?.parentKey != null && !ancestors.has(node.parentKey)) {\n ancestors.add(node.parentKey);\n node = collection.getItem(node.parentKey);\n }\n selectedAncestorsCache.set(collection, {selection: selectedRoute, ancestors});\n return ancestors;\n}\n\n// Whether the row `id` is an ancestor of the item matching `selectedRoute`.\nfunction hasSelectedDescendant(\n id: Key | undefined,\n state: TreeState<unknown>,\n selectedRoute: string | undefined | null\n): boolean {\n if (id == null || selectedRoute == null || !state) {\n return false;\n }\n return getSelectedAncestors(state, selectedRoute).has(id);\n}\n\nexport function NavigationTreeItemContent(props: NavigationTreeItemContentProps): ReactNode {\n let linkCtx = useContext(NavigationTreeItemLinkContext);\n return (\n <TreeItemContent {...props}>\n {(treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined}) => (\n <NavigationTreeItemContentInner\n treeRenderProps={treeRenderProps}\n linkCtx={linkCtx}\n children={props.children}\n />\n )}\n </TreeItemContent>\n );\n}\n\ninterface NavigationTreeItemContentInnerProps {\n treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined};\n linkCtx: NavigationTreeItemLinkContextValue;\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\nfunction NavigationTreeItemContentInner(props: NavigationTreeItemContentInnerProps): ReactNode {\n let {treeRenderProps, linkCtx, children} = props;\n let {isCurrent, isLinkFocused, setLinkFocused, ...linkProps} = linkCtx;\n let {state, isFocusVisible, isFocusVisibleWithin, id, hasChildItems} = treeRenderProps;\n let {isCurrentAncestor} = useContext(NavigationTreeItemStateContext);\n\n useRouteFocusSync({state});\n\n // isFocusVisible follows the link: true when the row itself is keyboard focused, or when a child\n // is keyboard focused and that child is the link (not another button/action).\n let linkFocusVisible = isFocusVisible || (isFocusVisibleWithin && !!isLinkFocused);\n let values: NavigationTreeItemContentRenderProps & {defaultChildren: ReactNode | undefined} = {\n ...treeRenderProps,\n isCurrent: !!isCurrent,\n isCurrentAncestor,\n isFocusVisible: linkFocusVisible\n };\n let renderChildren = typeof children === 'function' ? children(values) : children;\n // Provide onFocusChange so the link reports its focus up to NavigationTreeItem.\n let linkContextValue = {\n ...linkProps,\n 'aria-current': isCurrent ? 'page' : undefined,\n onFocusChange: setLinkFocused,\n onPress: linkProps.href == null && hasChildItems ? () => state.toggleKey(id) : undefined\n };\n return <Provider values={[[LinkContext, linkContextValue]]}>{renderChildren}</Provider>;\n}\n\nexport interface NavigationTreeSectionProps<T> extends Omit<TreeSectionProps<T>, 'value'> {}\n\n/**\n * A NavigationTreeSection represents a section within a NavigationTree.\n */\nexport function NavigationTreeSection<T extends object>(\n props: NavigationTreeSectionProps<T>\n): ReactNode {\n return (\n <TreeSection className=\"react-aria-NavigationTreeSection\" {...props}>\n {props.children}\n </TreeSection>\n );\n}\n\nexport interface NavigationTreeHeaderProps extends TreeHeaderProps {}\n\n/**\n * A NavigationTreeHeader renders the header of a NavigationTreeSection.\n */\nexport function NavigationTreeHeader(props: NavigationTreeHeaderProps): ReactNode {\n return (\n <TreeHeader className=\"react-aria-NavigationTreeHeader\" {...props}>\n {props.children}\n </TreeHeader>\n );\n}\n"],"names":[],"version":3,"file":"NavigationTree.mjs.map"}
|
|
1
|
+
{"mappings":";;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;;AA6CM,MAAM,0DACX,CAAA,GAAA,oBAAY,EAA0D;AAUxE,MAAM,oEAAgC,CAAA,GAAA,oBAAY,EAAsC,CAAC;AAgBzF,MAAM,oEAAgC,CAAA,GAAA,oBAAY,EAAsC,CAAC;AAElF,MAAM,0DAAiC,CAAA,GAAA,oBAAY,EAAgC;IACxF,mBAAmB;AACrB;AA2CO,MAAM,4CAA+B,AAAd,WAAW,GAAI,CAAA,GAAA,iBAAS,EAAqB,SAAS,eAElF,KAA6B,EAAE,GAAiC;IAChE,CAAC,OAAO,IAAI,GAAG,CAAA,GAAA,yCAAc,EAAE,OAAO,KAAK;IAC3C,IAAI,aAAC,SAAS,SAAE,KAAK,YAAE,QAAQ,iBAAE,aAAa,EAAE,GAAG,MAAK,GAAG;IAC3D,IAAI,iBAAiB,CAAA,GAAA,aAAK,EAAsB;IAChD,IAAI,UAAU,CAAA,GAAA,mBAAW,EAAE;IAC3B,IAAI,UAAU,CAAA,GAAA,cAAM,EAAE,IAAO,CAAA;2BAAC;4BAAe;qBAAgB;QAAO,CAAA,GAAI;QAAC;QAAe;KAAQ;IAEhG,qBACE,gCAAC,oDAA8B,QAAQ;QAAC,OAAO;qBAC7C,gCAAC,CAAA,GAAA,yCAAG;QACD,GAAG,IAAI;QACR,KAAK;QACL,WAAW,aAAa;QACxB,OAAO;QACP,eAAc;QACd,4BAA2B;OAC1B;AAIT;AA2CO,MAAM,4CAAmC,AAAd,WAAW,GAAI,CAAA,GAAA,iBAAS,EACxD,SAAS,mBACP,KAAiC,EACjC,GAAiC;IAEjC,IAAI,QACF,IAAI,YACJ,QAAQ,UACR,MAAM,OACN,GAAG,YACH,QAAQ,QACR,IAAI,kBACJ,cAAc,iBACd,aAAa,aACb,SAAS,SACT,KAAK,UACL,MAAM,EACN,GAAG,MACJ,GAAG;IACJ,IAAI,iBAAC,aAAa,WAAE,OAAO,EAAC,GAAG,CAAA,GAAA,iBAAS,EAAE;IAC1C,IAAI,UAAU,QAAQ,QAAQ,KAAK,MAAM,GAAG;IAC5C,IAAI,YAAY,WAAW,SAAS;IACpC,IAAI,CAAC,eAAe,eAAe,GAAG,CAAA,GAAA,eAAO,EAAE;IAC/C,qFAAqF;IACrF,IAAI,qBAAqB,CACvB,cAC0D,CAAA;YAC1D,GAAG,WAAW;uBACd;YACA,mBAAmB,4CAAsB,YAAY,EAAE,EAAE,YAAY,KAAK,EAAE;YAC5E,gBACE,YAAY,cAAc,IAAK,YAAY,oBAAoB,IAAI;QACvE,CAAA;IAEA,IAAI,SAAS,CAAA,GAAA,mBAAW,EAAE;IAC1B,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,aAAa,OAAO,OAAO,EAAE;YAC/B,IAAI,eAAe,CAAA,GAAA,sBAAc,EAAE,OAAO,OAAO,EAAE;YACnD,8FAA8F;YAC9F,8FAA8F;YAC9F,uEAAuE;YACvE,IAAI,WAAW,SAAS;YACxB,IAAI,YAAY,CAAA,GAAA,mBAAW,EAAE,UAAU,eACrC,CAAA,GAAA,qBAAa,EAAE,cAAc,OAAO,OAAO,EAAE;gBAAC,OAAO;YAAQ;QAEjE;IACF,GAAG;QAAC;QAAW;QAAQ;KAAQ;IAE/B,qBACE,gCAAC,oDAA8B,QAAQ;QACrC,OAAO;kBACL;sBACA;oBACA;iBACA;sBACA;kBACA;4BACA;2BACA;uBACA;2BACA;4BACA;QACF;qBACA,gCAAC,CAAA,GAAA,yCAAO;QACL,GAAG,IAAI;QACR,KAAK;QACL,MAAM;QACN,WAAW,UAAU,UAAU;QAC/B,uBAAA;QACA,gBAAc,aAAa;QAC3B,WACE,OAAO,cAAc,aACjB,CAAA,cAAe,UAAU,mBAAmB,gBAC3C,aAAa;QAEpB,OACE,OAAO,UAAU,aACb,CAAA,cAAe,MAAM,mBAAmB,gBACxC;QAEN,QAAQ,CAAC,UAAU;YACjB,IAAI,SAAS,mBAAmB;YAChC,IAAI,EAAC,UAAU,WAAW,EAAE,GAAG,SAAQ,GAAG;YAC1C,IAAI,YAAY;gBACd,sBAAsB,OAAO,cAAc,IAAI;gBAC/C,yBAAyB,OAAO,iBAAiB,IAAI;YACvD;YACA,IAAI,wBACF,gCAAC,0CAA+B,QAAQ;gBACtC,OAAO;oBAAC,mBAAmB,OAAO,iBAAiB;gBAAA;eAClD;YAGL,OAAO,OAAO,WAAW,aACvB,OAAO;gBAAC,GAAG,OAAO;gBAAE,GAAG,SAAS;gBAAE,UAAU;YAAO,GAAG,wBAEtD,gCAAC,CAAA,GAAA,yCAAE,EAAE,GAAG;gBAAE,GAAG,OAAO;gBAAG,GAAG,SAAS;eAChC;QAGP;;AAIR;AAaF,sEAAsE;AACtE,SAAS,sCAAgB,UAAqC,EAAE,KAAa;IAC3E,KAAK,IAAI,OAAO,WAAW,OAAO,GAAI;QACpC,IAAI,WAAW,OAAO,CAAC,MAAM,OAAO,SAAS,OAC3C,OAAO;IAEX;IACA,OAAO;AACT;AAEA,kGAAkG;AAClG,kGAAkG;AAClG,gEAAgE;AAChE,SAAS,wCACP,UAAqC,EACrC,YAAsB,EACtB,GAAQ;IAER,IAAI,SAAS;IACb,IAAI,OAAO,WAAW,OAAO,CAAC;IAC9B,MAAO,MAAM,aAAa,KAAM;QAC9B,IAAI,SAAS,WAAW,OAAO,CAAC,KAAK,SAAS;QAC9C,IAAI,QAAQ,SAAS,UAAU,CAAC,aAAa,GAAG,CAAC,KAAK,SAAS,GAC7D,SAAS,KAAK,SAAS;QAEzB,OAAO;IACT;IACA,OAAO;AACT;AAEA,8FAA8F;AAC9F,kGAAkG;AAClG,SAAS,wCAAkB,SAAC,KAAK,EAA8B;IAC7D,IAAI,iBAAC,aAAa,kBAAE,cAAc,EAAC,GAAG,CAAA,GAAA,iBAAS,EAAE;IACjD,IAAI,cAAC,UAAU,oBAAE,gBAAgB,gBAAE,YAAY,EAAC,GAAG;IACnD,CAAA,GAAA,gBAAQ,EAAE;QACR,IACE,iBAAiB,QACjB,kBAAkB,QAClB,eAAe,OAAO,KAAK,eAE3B;QAEF,IAAI,MAAM,sCAAgB,YAAY;QACtC,IAAI,OAAO,MAAM;YACf,MAAM,wCAAkB,YAAY,cAAc;YAClD,eAAe,OAAO,GAAG;YACzB,iBAAiB,aAAa,CAAC;QACjC;IACF,GAAG;QAAC;QAAe;QAAY;QAAc;QAAgB;KAAiB;AAChF;AAEA,iEAAiE;AACjE,IAAI,+CAAyB,IAAI;AAKjC,sFAAsF;AACtF,SAAS,2CAAqB,KAAyB,EAAE,aAAqB;IAC5E,IAAI,cAAC,UAAU,EAAC,GAAG;IACnB,IAAI,SAAS,6CAAuB,GAAG,CAAC;IACxC,IAAI,UAAU,OAAO,SAAS,KAAK,eACjC,OAAO,OAAO,SAAS;IAEzB,IAAI,WAAW,sCAAgB,YAAY;IAC3C,IAAI,YAAY,IAAI;IACpB,IAAI,OAAO,YAAY,OAAO,WAAW,OAAO,CAAC,YAAY;IAC7D,MAAO,MAAM,aAAa,QAAQ,CAAC,UAAU,GAAG,CAAC,KAAK,SAAS,EAAG;QAChE,UAAU,GAAG,CAAC,KAAK,SAAS;QAC5B,OAAO,WAAW,OAAO,CAAC,KAAK,SAAS;IAC1C;IACA,6CAAuB,GAAG,CAAC,YAAY;QAAC,WAAW;mBAAe;IAAS;IAC3E,OAAO;AACT;AAEA,4EAA4E;AAC5E,SAAS,4CACP,EAAmB,EACnB,KAAyB,EACzB,aAAwC;IAExC,IAAI,MAAM,QAAQ,iBAAiB,QAAQ,CAAC,OAC1C,OAAO;IAET,OAAO,2CAAqB,OAAO,eAAe,GAAG,CAAC;AACxD;AAEO,SAAS,0CAA0B,KAAqC;IAC7E,IAAI,UAAU,CAAA,GAAA,iBAAS,EAAE;IACzB,qBACE,gCAAC,CAAA,GAAA,yCAAc,GAAM,OAClB,CAAC,gCACA,gCAAC;YACC,iBAAiB;YACjB,SAAS;YACT,UAAU,MAAM,QAAQ;;AAKlC;AAQA,SAAS,qDAA+B,KAA0C;IAChF,IAAI,mBAAC,eAAe,WAAE,OAAO,YAAE,QAAQ,EAAC,GAAG;IAC3C,IAAI,aAAC,SAAS,iBAAE,aAAa,kBAAE,cAAc,EAAE,GAAG,WAAU,GAAG;IAC/D,IAAI,SAAC,KAAK,kBAAE,cAAc,wBAAE,oBAAoB,MAAE,EAAE,iBAAE,aAAa,EAAC,GAAG;IACvE,IAAI,qBAAC,iBAAiB,EAAC,GAAG,CAAA,GAAA,iBAAS,EAAE;IAErC,wCAAkB;eAAC;IAAK;IAExB,iGAAiG;IACjG,8EAA8E;IAC9E,IAAI,mBAAmB,kBAAmB,wBAAwB,CAAC,CAAC;IACpE,IAAI,SAA0F;QAC5F,GAAG,eAAe;QAClB,WAAW,CAAC,CAAC;2BACb;QACA,gBAAgB;IAClB;IACA,IAAI,iBAAiB,OAAO,aAAa,aAAa,SAAS,UAAU;IACzE,gFAAgF;IAChF,IAAI,mBAAmB;QACrB,GAAG,SAAS;QACZ,gBAAgB,YAAa,SAAmB;QAChD,eAAe;QACf,SAAS,UAAU,IAAI,IAAI,QAAQ,gBAAgB,IAAM,MAAM,SAAS,CAAC,MAAM;IACjF;IACA,qBAAO,gCAAC,CAAA,GAAA,yCAAO;QAAE,QAAQ;YAAC;gBAAC,CAAA,GAAA,yCAAU;gBAAG;aAAiB;SAAC;OAAG;AAC/D;AAOO,SAAS,0CACd,KAAoC;IAEpC,qBACE,gCAAC,CAAA,GAAA,yCAAU;QAAE,WAAU;QAAoC,GAAG,KAAK;OAChE,MAAM,QAAQ;AAGrB;AAOO,SAAS,0CAAqB,KAAgC;IACnE,qBACE,gCAAC,CAAA,GAAA,yCAAS;QAAE,WAAU;QAAmC,GAAG,KAAK;OAC9D,MAAM,QAAQ;AAGrB","sources":["packages/react-aria-components/src/NavigationTree.tsx"],"sourcesContent":["/*\n * Copyright 2026 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 {\n ChildrenOrFunction,\n ClassNameOrFunction,\n ContextValue,\n dom,\n Provider,\n StyleRenderProps,\n useContextProps\n} from './utils';\nimport {Collection, forwardRefType, Key, Node, RouterOptions} from '@react-types/shared';\nimport {getScrollParent} from 'react-aria/private/utils/getScrollParent';\nimport {LinkContext} from './Link';\nimport {nodeContains} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport React, {\n createContext,\n ForwardedRef,\n forwardRef,\n ReactNode,\n RefObject,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {scrollIntoView} from 'react-aria/private/utils/scrollIntoView';\nimport {\n Tree,\n TreeHeader,\n TreeHeaderProps,\n TreeItem,\n TreeItemContent,\n TreeItemContentRenderProps,\n TreeItemProps,\n TreeItemRenderProps,\n TreeProps,\n TreeRenderProps,\n TreeSection,\n TreeSectionProps\n} from './Tree';\nimport {TreeState} from 'react-stately/useTreeState';\nimport {useObjectRef} from 'react-aria/useObjectRef';\n\nexport const NavigationTreeContext =\n createContext<ContextValue<NavigationTreeProps<any>, HTMLDivElement>>(null);\n\ninterface InternalNavigationTreeContextValue {\n /** The route that is currently selected. */\n selectedRoute?: string | null;\n /** The last route the focused key was synced to; dedupes the focus sync across items. */\n syncedRouteRef?: RefObject<string | undefined>;\n /** The NavigationTree's root element, used to keep current-route scrolling inside the tree. */\n treeRef?: RefObject<HTMLDivElement | null>;\n}\nconst InternalNavigationTreeContext = createContext<InternalNavigationTreeContextValue>({});\n\ninterface NavigationTreeItemLinkContextValue {\n href?: string;\n hrefLang?: string;\n target?: string;\n rel?: string;\n download?: string | boolean;\n ping?: string;\n referrerPolicy?: ReferrerPolicy;\n routerOptions?: RouterOptions;\n isCurrent?: boolean;\n // Whether the item's link (as opposed to another focusable child such as a button) is focused.\n isLinkFocused?: boolean;\n setLinkFocused?: (isFocused: boolean) => void;\n}\nconst NavigationTreeItemLinkContext = createContext<NavigationTreeItemLinkContextValue>({});\n\nexport const NavigationTreeItemStateContext = createContext<{isCurrentAncestor: boolean}>({\n isCurrentAncestor: false\n});\n\nexport interface NavigationTreeRenderProps extends Pick<\n TreeRenderProps,\n 'isEmpty' | 'isFocused' | 'isFocusVisible' | 'state'\n> {}\n\nexport interface NavigationTreeProps<T>\n extends\n Omit<\n TreeProps<T>,\n | 'selectionMode'\n | 'selectionBehavior'\n | 'selectedKeys'\n | 'defaultSelectedKeys'\n | 'onSelectionChange'\n | 'disallowEmptySelection'\n | 'disabledBehavior'\n | 'keyboardNavigationBehavior'\n | 'escapeKeyBehavior'\n | 'shouldSelectOnPressUp'\n | 'dragAndDropHooks'\n | 'renderEmptyState'\n | 'onAction'\n | 'className'\n | 'style'\n | 'render'\n >,\n StyleRenderProps<NavigationTreeRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTree'\n */\n className?: ClassNameOrFunction<NavigationTreeRenderProps>;\n /** The route that is currently selected, matched against each item's `href`. */\n selectedRoute?: string | null;\n}\n\n/**\n * A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.\n */\nexport const NavigationTree = /*#__PURE__*/ (forwardRef as forwardRefType)(function NavigationTree<\n T\n>(props: NavigationTreeProps<T>, ref: ForwardedRef<HTMLDivElement>) {\n [props, ref] = useContextProps(props, ref, NavigationTreeContext);\n let {className, style, children, selectedRoute, ...rest} = props;\n let syncedRouteRef = useRef<string | undefined>(undefined);\n let treeRef = useObjectRef(ref);\n let context = useMemo(() => ({selectedRoute, syncedRouteRef, treeRef}), [selectedRoute, treeRef]);\n\n return (\n <InternalNavigationTreeContext.Provider value={context}>\n <Tree\n {...rest}\n ref={treeRef}\n className={className ?? 'react-aria-NavigationTree'}\n style={style}\n selectionMode=\"none\"\n keyboardNavigationBehavior=\"tab\">\n {children}\n </Tree>\n </InternalNavigationTreeContext.Provider>\n );\n});\n\nexport interface NavigationTreeItemRenderProps extends TreeItemRenderProps {\n /**\n * Whether this item is the current route (its `href` matches the NavigationTree's\n * `selectedRoute`).\n *\n * @selector [data-current]\n */\n isCurrent: boolean;\n /**\n * Whether this item is an ancestor of the current-route item (at any level, regardless of whether\n * it is expanded or collapsed).\n *\n * @selector [data-current-ancestor]\n */\n isCurrentAncestor: boolean;\n}\n\nexport interface NavigationTreeItemProps<T = object>\n extends\n Omit<\n TreeItemProps<T>,\n 'className' | 'style' | 'render' | 'onAction' | 'allowsArrowNavigation' | 'value'\n >,\n StyleRenderProps<NavigationTreeItemRenderProps> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-NavigationTreeItem'\n */\n className?: ClassNameOrFunction<NavigationTreeItemRenderProps>;\n /**\n * The content of the side nav item along with any nested children. Supports static nested side\n * nav items or use of a Collection to dynamically render nested side nav items.\n */\n children: ReactNode;\n}\n\n/**\n * A NavigationTreeItem represents an individual item in a NavigationTree.\n */\nexport const NavigationTreeItem = /*#__PURE__*/ (forwardRef as forwardRefType)(\n function NavigationTreeItem<T extends object>(\n props: NavigationTreeItemProps<T>,\n ref: ForwardedRef<HTMLDivElement>\n ) {\n let {\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n className,\n style,\n render,\n ...rest\n } = props;\n let {selectedRoute, treeRef} = useContext(InternalNavigationTreeContext);\n let hasLink = href != null && href.length > 0;\n let isCurrent = hasLink && href === selectedRoute;\n let [isLinkFocused, setLinkFocused] = useState(false);\n // Additional render props NavigationTreeItem adds to what TreeItem already provides.\n let getItemRenderProps = <R extends TreeItemRenderProps>(\n renderProps: R\n ): R & {isCurrent: boolean; isCurrentAncestor: boolean} => ({\n ...renderProps,\n isCurrent,\n isCurrentAncestor: hasSelectedDescendant(renderProps.id, renderProps.state, selectedRoute),\n isFocusVisible:\n renderProps.isFocusVisible || (renderProps.isFocusVisibleWithin && isLinkFocused)\n });\n\n let objRef = useObjectRef(ref);\n useEffect(() => {\n if (isCurrent && objRef.current) {\n let scrollParent = getScrollParent(objRef.current, true) as HTMLElement;\n // Only scroll the tree's own scroll container into view — never an outer ancestor such as the\n // page. When the tree isn't its own scroll container the nearest scroll parent is outside the\n // tree, so we skip rather than hijack the surrounding scroll position.\n let treeRoot = treeRef?.current;\n if (treeRoot && nodeContains(treeRoot, scrollParent)) {\n scrollIntoView(scrollParent, objRef.current, {block: 'center'});\n }\n }\n }, [isCurrent, objRef, treeRef]);\n\n return (\n <NavigationTreeItemLinkContext.Provider\n value={{\n href,\n hrefLang,\n target,\n rel,\n download,\n ping,\n referrerPolicy,\n routerOptions,\n isCurrent,\n isLinkFocused,\n setLinkFocused\n }}>\n <TreeItem\n {...rest}\n ref={objRef}\n href={href}\n focusMode={hasLink ? 'child' : undefined}\n allowsArrowNavigation\n data-current={isCurrent || undefined}\n className={\n typeof className === 'function'\n ? renderProps => className(getItemRenderProps(renderProps))\n : (className ?? 'react-aria-NavigationTreeItem')\n }\n style={\n typeof style === 'function'\n ? renderProps => style(getItemRenderProps(renderProps))\n : style\n }\n render={(domProps, renderProps) => {\n let values = getItemRenderProps(renderProps);\n let {children: rowChildren, ...domRest} = domProps;\n let dataProps = {\n 'data-focus-visible': values.isFocusVisible || undefined,\n 'data-current-ancestor': values.isCurrentAncestor || undefined\n };\n let content = (\n <NavigationTreeItemStateContext.Provider\n value={{isCurrentAncestor: values.isCurrentAncestor}}>\n {rowChildren}\n </NavigationTreeItemStateContext.Provider>\n );\n return typeof render === 'function' ? (\n render({...domRest, ...dataProps, children: content}, values)\n ) : (\n <dom.div {...domRest} {...dataProps}>\n {content}\n </dom.div>\n );\n }}\n />\n </NavigationTreeItemLinkContext.Provider>\n );\n }\n);\n\nexport interface NavigationTreeItemContentRenderProps extends NavigationTreeItemRenderProps {}\n\nexport interface NavigationTreeItemContentProps {\n /**\n * The children of the component. A function may be provided to alter the children based on\n * component state.\n */\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\n// The collection key of the item whose href matches `route`, or null.\nfunction findKeyForRoute(collection: Collection<Node<unknown>>, route: string): Key | null {\n for (let key of collection.getKeys()) {\n if (collection.getItem(key)?.props?.href === route) {\n return key;\n }\n }\n return null;\n}\n\n// Walks up from `key` to the closest ancestor that is actually rendered (all ancestors expanded).\n// Returns `key` unchanged when already visible. A collapsed ancestor hides everything beneath it,\n// so the highest collapsed ancestor is the closest visible row.\nfunction closestVisibleKey(\n collection: Collection<Node<unknown>>,\n expandedKeys: Set<Key>,\n key: Key\n): Key {\n let target = key;\n let node = collection.getItem(key);\n while (node?.parentKey != null) {\n let parent = collection.getItem(node.parentKey);\n if (parent?.type === 'item' && !expandedKeys.has(node.parentKey)) {\n target = node.parentKey;\n }\n node = parent;\n }\n return target;\n}\n\n// Moves the tree's focused key to the item matching selectedRoute. Runs when the route or the\n// collection changes; the shared syncedRouteRef dedupes across items so it fires once per change.\nfunction useRouteFocusSync({state}: {state: TreeState<unknown>}): void {\n let {selectedRoute, syncedRouteRef} = useContext(InternalNavigationTreeContext);\n let {collection, selectionManager, expandedKeys} = state;\n useEffect(() => {\n if (\n selectedRoute == null ||\n syncedRouteRef == null ||\n syncedRouteRef.current === selectedRoute\n ) {\n return;\n }\n let key = findKeyForRoute(collection, selectedRoute);\n if (key != null) {\n key = closestVisibleKey(collection, expandedKeys, key);\n syncedRouteRef.current = selectedRoute;\n selectionManager.setFocusedKey(key);\n }\n }, [selectedRoute, collection, expandedKeys, syncedRouteRef, selectionManager]);\n}\n\n// Cache so each row doesn't have to walk up the tree every time.\nlet selectedAncestorsCache = new WeakMap<\n Collection<Node<unknown>>,\n {selection: unknown; ancestors: Set<Key>}\n>();\n\n// The set of collection keys that are ancestors of the item matching `selectedRoute`.\nfunction getSelectedAncestors(state: TreeState<unknown>, selectedRoute: string): Set<Key> {\n let {collection} = state;\n let cached = selectedAncestorsCache.get(collection);\n if (cached && cached.selection === selectedRoute) {\n return cached.ancestors;\n }\n let matchKey = findKeyForRoute(collection, selectedRoute);\n let ancestors = new Set<Key>();\n let node = matchKey != null ? collection.getItem(matchKey) : null;\n while (node?.parentKey != null && !ancestors.has(node.parentKey)) {\n ancestors.add(node.parentKey);\n node = collection.getItem(node.parentKey);\n }\n selectedAncestorsCache.set(collection, {selection: selectedRoute, ancestors});\n return ancestors;\n}\n\n// Whether the row `id` is an ancestor of the item matching `selectedRoute`.\nfunction hasSelectedDescendant(\n id: Key | undefined,\n state: TreeState<unknown>,\n selectedRoute: string | undefined | null\n): boolean {\n if (id == null || selectedRoute == null || !state) {\n return false;\n }\n return getSelectedAncestors(state, selectedRoute).has(id);\n}\n\nexport function NavigationTreeItemContent(props: NavigationTreeItemContentProps): ReactNode {\n let linkCtx = useContext(NavigationTreeItemLinkContext);\n return (\n <TreeItemContent {...props}>\n {(treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined}) => (\n <NavigationTreeItemContentInner\n treeRenderProps={treeRenderProps}\n linkCtx={linkCtx}\n children={props.children}\n />\n )}\n </TreeItemContent>\n );\n}\n\ninterface NavigationTreeItemContentInnerProps {\n treeRenderProps: TreeItemContentRenderProps & {defaultChildren: ReactNode | undefined};\n linkCtx: NavigationTreeItemLinkContextValue;\n children: ChildrenOrFunction<NavigationTreeItemContentRenderProps>;\n}\n\nfunction NavigationTreeItemContentInner(props: NavigationTreeItemContentInnerProps): ReactNode {\n let {treeRenderProps, linkCtx, children} = props;\n let {isCurrent, isLinkFocused, setLinkFocused, ...linkProps} = linkCtx;\n let {state, isFocusVisible, isFocusVisibleWithin, id, hasChildItems} = treeRenderProps;\n let {isCurrentAncestor} = useContext(NavigationTreeItemStateContext);\n\n useRouteFocusSync({state});\n\n // isFocusVisible follows the link: true when the row itself is keyboard focused, or when a child\n // is keyboard focused and that child is the link (not another button/action).\n let linkFocusVisible = isFocusVisible || (isFocusVisibleWithin && !!isLinkFocused);\n let values: NavigationTreeItemContentRenderProps & {defaultChildren: ReactNode | undefined} = {\n ...treeRenderProps,\n isCurrent: !!isCurrent,\n isCurrentAncestor,\n isFocusVisible: linkFocusVisible\n };\n let renderChildren = typeof children === 'function' ? children(values) : children;\n // Provide onFocusChange so the link reports its focus up to NavigationTreeItem.\n let linkContextValue = {\n ...linkProps,\n 'aria-current': isCurrent ? ('page' as const) : undefined,\n onFocusChange: setLinkFocused,\n onPress: linkProps.href == null && hasChildItems ? () => state.toggleKey(id) : undefined\n };\n return <Provider values={[[LinkContext, linkContextValue]]}>{renderChildren}</Provider>;\n}\n\nexport interface NavigationTreeSectionProps<T> extends Omit<TreeSectionProps<T>, 'value'> {}\n\n/**\n * A NavigationTreeSection represents a section within a NavigationTree.\n */\nexport function NavigationTreeSection<T extends object>(\n props: NavigationTreeSectionProps<T>\n): ReactNode {\n return (\n <TreeSection className=\"react-aria-NavigationTreeSection\" {...props}>\n {props.children}\n </TreeSection>\n );\n}\n\nexport interface NavigationTreeHeaderProps extends TreeHeaderProps {}\n\n/**\n * A NavigationTreeHeader renders the header of a NavigationTreeSection.\n */\nexport function NavigationTreeHeader(props: NavigationTreeHeaderProps): ReactNode {\n return (\n <TreeHeader className=\"react-aria-NavigationTreeHeader\" {...props}>\n {props.children}\n </TreeHeader>\n );\n}\n"],"names":[],"version":3,"file":"NavigationTree.mjs.map"}
|
package/dist/private/Popover.cjs
CHANGED
|
@@ -10,6 +10,7 @@ var $kmEDY$reactariaprivateutilsshadowdomDOMFunctions = require("react-aria/priv
|
|
|
10
10
|
var $kmEDY$reactariamergeProps = require("react-aria/mergeProps");
|
|
11
11
|
var $kmEDY$reactstatelyuseOverlayTriggerState = require("react-stately/useOverlayTriggerState");
|
|
12
12
|
var $kmEDY$react = require("react");
|
|
13
|
+
var $kmEDY$reactariaprivateutilsrunAfterKeyboard = require("react-aria/private/utils/runAfterKeyboard");
|
|
13
14
|
var $kmEDY$reactariaprivateutilsanimation = require("react-aria/private/utils/animation");
|
|
14
15
|
var $kmEDY$reactariaprivatecollectionsHidden = require("react-aria/private/collections/Hidden");
|
|
15
16
|
var $kmEDY$reactariaprivateutilsuseLayoutEffect = require("react-aria/private/utils/useLayoutEffect");
|
|
@@ -54,6 +55,7 @@ $parcel$export(module.exports, "Popover", function () { return $74e35a768d38d46b
|
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
|
|
58
|
+
|
|
57
59
|
const $74e35a768d38d46b$export$9b9a0cd73afb7ca4 = /*#__PURE__*/ (0, $kmEDY$react.createContext)(null);
|
|
58
60
|
// Stores a ref for the portal container for a group of popovers (e.g. submenus).
|
|
59
61
|
const $74e35a768d38d46b$var$PopoverGroupContext = /*#__PURE__*/ (0, $kmEDY$react.createContext)(null);
|
|
@@ -97,6 +99,7 @@ function $74e35a768d38d46b$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
97
99
|
let containerRef = (0, $kmEDY$react.useRef)(null);
|
|
98
100
|
let groupCtx = (0, $kmEDY$react.useContext)($74e35a768d38d46b$var$PopoverGroupContext);
|
|
99
101
|
let isSubPopover = groupCtx && props.trigger === 'SubmenuTrigger';
|
|
102
|
+
let [isOpen, setIsOpen] = (0, $kmEDY$react.useState)(false);
|
|
100
103
|
let { popoverProps: popoverProps, underlayProps: underlayProps, arrowProps: arrowProps, placement: placement, triggerAnchorPoint: triggerAnchorPoint } = (0, $kmEDY$reactariausePopover.usePopover)({
|
|
101
104
|
...props,
|
|
102
105
|
offset: props.offset ?? 8,
|
|
@@ -108,7 +111,7 @@ function $74e35a768d38d46b$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
108
111
|
let ref = props.popoverRef;
|
|
109
112
|
// Skip the automatic entry animation when opening instantly (e.g. swapping between previews
|
|
110
113
|
// during warmup). An explicitly provided isEntering prop still takes precedence.
|
|
111
|
-
let enterAnimation = (0, $kmEDY$reactariaprivateutilsanimation.useEnterAnimation)(ref, !!placement);
|
|
114
|
+
let enterAnimation = (0, $kmEDY$reactariaprivateutilsanimation.useEnterAnimation)(ref, !!placement && isOpen);
|
|
112
115
|
// oxlint-disable-next-line react/react-compiler
|
|
113
116
|
let isEntering = props.isEntering || !props.shouldSkipAnimation && enterAnimation || false;
|
|
114
117
|
// oxlint-disable-next-line react/react-compiler
|
|
@@ -151,7 +154,10 @@ function $74e35a768d38d46b$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
151
154
|
// oxlint-enable react/react-compiler
|
|
152
155
|
let children = (0, $kmEDY$react.useMemo)(()=>{
|
|
153
156
|
let children = renderProps.children;
|
|
154
|
-
|
|
157
|
+
for (let Context of [
|
|
158
|
+
$74e35a768d38d46b$export$9b9a0cd73afb7ca4,
|
|
159
|
+
...clearContexts ?? []
|
|
160
|
+
])children = /*#__PURE__*/ (0, ($parcel$interopDefault($kmEDY$react))).createElement(Context.Provider, {
|
|
155
161
|
value: null
|
|
156
162
|
}, children);
|
|
157
163
|
return children;
|
|
@@ -181,6 +187,8 @@ function $74e35a768d38d46b$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
181
187
|
...renderProps.style,
|
|
182
188
|
'--trigger-width': renderProps.style?.['--trigger-width'] || triggerWidth
|
|
183
189
|
};
|
|
190
|
+
// Since our trigger may open the OSK, we defer the reveal, as a courtesy, to avoid layout shift.
|
|
191
|
+
(0, $kmEDY$reactariaprivateutilsuseLayoutEffect.useLayoutEffect)(()=>(0, $kmEDY$reactariaprivateutilsrunAfterKeyboard.runAfterKeyboard)(()=>setIsOpen(true)), []);
|
|
184
192
|
// oxlint-disable react/react-compiler
|
|
185
193
|
let overlay = /*#__PURE__*/ (0, ($parcel$interopDefault($kmEDY$react))).createElement((0, $048d76b84370f141$exports.dom).div, {
|
|
186
194
|
...(0, $kmEDY$reactariamergeProps.mergeProps)((0, $kmEDY$reactariafilterDOMProps.filterDOMProps)(props, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/react-aria-components/src/Popover.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 {\n AriaLabelingProps,\n forwardRefType,\n GlobalDOMAttributes,\n RefObject\n} from '@react-types/shared';\nimport {AriaPopoverProps, usePopover} from 'react-aria/usePopover';\nimport {\n ClassNameOrFunction,\n ContextValue,\n dom,\n RenderProps,\n SlotProps,\n useContextProps,\n useRenderProps\n} from './utils';\nimport {DismissButton, Overlay} from 'react-aria/Overlay';\nimport {filterDOMProps} from 'react-aria/filterDOMProps';\nimport {focusSafely} from 'react-aria/private/interactions/focusSafely';\nimport {getInteractionModality} from 'react-aria/private/interactions/useFocusVisible';\nimport {isFocusWithin} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport {mergeProps} from 'react-aria/mergeProps';\nimport {OverlayArrowContext} from './OverlayArrow';\nimport {\n OverlayTriggerProps,\n OverlayTriggerState,\n useOverlayTriggerState\n} from 'react-stately/useOverlayTriggerState';\nimport {OverlayTriggerStateContext} from './Dialog';\nimport {PlacementAxis, PositionProps} from 'react-aria/useOverlayPosition';\nimport React, {\n Context,\n createContext,\n ForwardedRef,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {useEnterAnimation, useExitAnimation} from 'react-aria/private/utils/animation';\nimport {useIsHidden} from 'react-aria/private/collections/Hidden';\nimport {useLayoutEffect} from 'react-aria/private/utils/useLayoutEffect';\nimport {useLocale} from 'react-aria/I18nProvider';\nimport {useResizeObserver} from 'react-aria/private/utils/useResizeObserver';\n\nexport interface PopoverProps\n extends\n Omit<PositionProps, 'isOpen'>,\n Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef' | 'groupRef' | 'offset' | 'arrowSize'>,\n OverlayTriggerProps,\n RenderProps<PopoverRenderProps>,\n SlotProps,\n AriaLabelingProps,\n GlobalDOMAttributes<HTMLDivElement> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-Popover'\n */\n className?: ClassNameOrFunction<PopoverRenderProps>;\n /**\n * The name of the component that triggered the popover. This is reflected on the element\n * as the `data-trigger` attribute, and can be used to provide specific\n * styles for the popover depending on which element triggered it.\n */\n trigger?: string;\n /**\n * The ref for the element which the popover positions itself with respect to.\n *\n * When used within a trigger component such as DialogTrigger, MenuTrigger, Select, etc.,\n * this is set automatically. It is only required when used standalone.\n */\n triggerRef?: RefObject<Element | null>;\n /**\n * Whether the popover is currently performing an entry animation.\n */\n isEntering?: boolean;\n /**\n * Whether the popover is currently performing an exit animation.\n */\n isExiting?: boolean;\n /**\n * Whether the popover should appear and disappear without an entry or exit animation. This is\n * used by components such as PreviewTrigger to skip animations when quickly swapping between\n * overlays.\n */\n shouldSkipAnimation?: boolean;\n /**\n * The container element in which the overlay portal will be placed. This may have unknown\n * behavior depending on where it is portalled to.\n *\n * @deprecated - Use a parent UNSAFE_PortalProvider to set your portal container instead.\n * @default document.body\n */\n UNSTABLE_portalContainer?: Element;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 8\n */\n offset?: number;\n}\n\nexport interface PopoverRenderProps {\n /**\n * The name of the component that triggered the popover, e.g. \"DialogTrigger\" or \"ComboBox\".\n *\n * @selector [data-trigger=\"...\"]\n */\n trigger: string | null;\n /**\n * The placement of the popover relative to the trigger.\n *\n * @selector [data-placement=\"left | right | top | bottom\"]\n */\n placement: PlacementAxis | null;\n /**\n * Whether the popover is currently entering. Use this to apply animations.\n *\n * @selector [data-entering]\n */\n isEntering: boolean;\n /**\n * Whether the popover is currently exiting. Use this to apply animations.\n *\n * @selector [data-exiting]\n */\n isExiting: boolean;\n}\n\ninterface PopoverContextValue extends PopoverProps {\n id?: string;\n /** Contexts to clear. */\n clearContexts?: Context<any>[];\n}\n\nexport const PopoverContext = createContext<ContextValue<PopoverContextValue, HTMLElement>>(null);\n\n// Stores a ref for the portal container for a group of popovers (e.g. submenus).\nconst PopoverGroupContext = createContext<RefObject<Element | null> | null>(null);\n\n/**\n * A popover is an overlay element positioned relative to a trigger.\n */\nexport const Popover = /*#__PURE__*/ (forwardRef as forwardRefType)(function Popover(\n props: PopoverProps,\n ref: ForwardedRef<HTMLElement>\n) {\n [props, ref] = useContextProps(props, ref, PopoverContext);\n let contextState = useContext(OverlayTriggerStateContext);\n let localState = useOverlayTriggerState(props);\n let state =\n props.isOpen != null || props.defaultOpen != null || !contextState ? localState : contextState;\n // Skip the automatic exit animation when closing instantly (e.g. swapping between previews\n // during warmup). An explicitly provided isExiting prop still takes precedence.\n let exitAnimation = useExitAnimation(ref, state.isOpen);\n let isExiting = props.isExiting || (!props.shouldSkipAnimation && exitAnimation) || false;\n let isHidden = useIsHidden();\n let {direction} = useLocale();\n\n // If we are in a hidden tree, we still need to preserve our children.\n if (isHidden) {\n let children = props.children;\n if (typeof children === 'function') {\n children = children({\n trigger: props.trigger || null,\n placement: 'bottom',\n isEntering: false,\n isExiting: false,\n defaultChildren: null\n });\n }\n\n return <>{children}</>;\n }\n\n if (state && !state.isOpen && !isExiting) {\n return null;\n }\n\n return (\n <PopoverInner\n {...props}\n triggerRef={props.triggerRef!}\n state={state}\n popoverRef={ref}\n isExiting={isExiting}\n dir={direction}\n />\n );\n});\n\ninterface PopoverInnerProps extends AriaPopoverProps, RenderProps<PopoverRenderProps>, SlotProps {\n state: OverlayTriggerState;\n isEntering?: boolean;\n isExiting: boolean;\n shouldSkipAnimation?: boolean;\n UNSTABLE_portalContainer?: Element;\n trigger?: string;\n dir?: 'ltr' | 'rtl';\n clearContexts?: Context<any>[];\n id?: string;\n}\n\nfunction PopoverInner({\n state,\n isExiting,\n UNSTABLE_portalContainer,\n clearContexts,\n ...props\n}: PopoverInnerProps) {\n // Calculate the arrow size internally (and remove props.arrowSize from PopoverProps)\n // Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx\n let arrowRef = useRef<HTMLDivElement>(null);\n let containerRef = useRef<HTMLDivElement | null>(null);\n let groupCtx = useContext(PopoverGroupContext);\n let isSubPopover = groupCtx && props.trigger === 'SubmenuTrigger';\n\n let {popoverProps, underlayProps, arrowProps, placement, triggerAnchorPoint} = usePopover(\n {\n ...props,\n offset: props.offset ?? 8,\n arrowRef,\n // If this is a submenu/subdialog, use the root popover's container\n // to detect outside interaction and add aria-hidden.\n groupRef: isSubPopover ? groupCtx! : containerRef\n },\n state\n );\n\n let ref = props.popoverRef as RefObject<HTMLDivElement | null>;\n // Skip the automatic entry animation when opening instantly (e.g. swapping between previews\n // during warmup). An explicitly provided isEntering prop still takes precedence.\n let enterAnimation = useEnterAnimation(ref, !!placement);\n // oxlint-disable-next-line react/react-compiler\n let isEntering = props.isEntering || (!props.shouldSkipAnimation && enterAnimation) || false;\n // oxlint-disable-next-line react/react-compiler\n let renderProps = useRenderProps({\n // oxlint-disable-next-line react/react-compiler\n ...props,\n defaultClassName: 'react-aria-Popover',\n // oxlint-disable-next-line react/react-compiler\n values: {\n // oxlint-disable-next-line react/react-compiler\n trigger: props.trigger || null,\n placement,\n // oxlint-disable-next-line react/react-compiler\n isEntering,\n isExiting\n }\n });\n\n // Automatically render Popover with role=dialog except when isNonModal is true,\n // or a dialog is already nested inside the popover.\n let shouldBeDialog =\n // oxlint-disable-next-line react/react-compiler\n !props.isNonModal || props.trigger === 'SubmenuTrigger' || props.trigger === 'PreviewTrigger';\n // oxlint-disable-next-line react/react-compiler\n let [isDialog, setDialog] = useState(props.trigger === 'PreviewTrigger');\n useLayoutEffect(() => {\n if (ref.current) {\n setDialog(shouldBeDialog && !ref.current.querySelector('[role=dialog]'));\n }\n }, [ref, shouldBeDialog]);\n\n // Focus the popover itself on mount, unless a child element is already focused.\n // Skip this for submenus since hovering a submenutrigger should keep focus on the trigger\n // oxlint-disable react/react-compiler\n useEffect(() => {\n if (\n isDialog &&\n props.trigger !== 'PreviewTrigger' &&\n (props.trigger !== 'SubmenuTrigger' || getInteractionModality() !== 'pointer') &&\n ref.current &&\n !isFocusWithin(ref.current)\n ) {\n focusSafely(ref.current);\n }\n }, [isDialog, ref, props.trigger]);\n // oxlint-enable react/react-compiler\n\n let children = useMemo(() => {\n let children = renderProps.children;\n if (clearContexts) {\n for (let Context of clearContexts) {\n children = <Context.Provider value={null}>{children}</Context.Provider>;\n }\n }\n return children;\n }, [renderProps.children, clearContexts]);\n\n let [triggerWidth, setTriggerWidth] = useState<string | null>(null);\n // oxlint-disable-next-line react/react-compiler\n let onResize = useCallback(() => {\n if (props.triggerRef.current) {\n setTriggerWidth(props.triggerRef.current.getBoundingClientRect().width + 'px');\n }\n }, [props.triggerRef]);\n\n useLayoutEffect(onResize, [onResize]);\n // oxlint-disable-next-line react/react-compiler\n useResizeObserver({\n // oxlint-disable-next-line react/react-compiler\n ref: renderProps.style?.['--trigger-width'] ? undefined : props.triggerRef,\n onResize: onResize\n });\n\n let style = {\n ...popoverProps.style,\n '--trigger-anchor-point': triggerAnchorPoint\n ? `${triggerAnchorPoint.x}px ${triggerAnchorPoint.y}px`\n : undefined,\n ...renderProps.style,\n '--trigger-width': renderProps.style?.['--trigger-width'] || triggerWidth\n };\n\n // oxlint-disable react/react-compiler\n let overlay = (\n <dom.div\n {...mergeProps(filterDOMProps(props, {global: true}), popoverProps)}\n {...renderProps}\n id={isDialog ? props.id : undefined}\n role={isDialog ? 'dialog' : undefined}\n tabIndex={isDialog ? -1 : undefined}\n aria-label={props['aria-label']}\n aria-labelledby={props['aria-labelledby']}\n ref={ref}\n slot={props.slot || undefined}\n style={style}\n dir={props.dir}\n data-trigger={props.trigger}\n data-placement={placement}\n data-entering={isEntering || undefined}\n data-exiting={isExiting || undefined}>\n {/* oxlint-disable-next-line react/react-compiler */}\n {!props.isNonModal && <DismissButton onDismiss={state.close} />}\n <OverlayArrowContext.Provider value={{...arrowProps, placement, ref: arrowRef}}>\n {children}\n </OverlayArrowContext.Provider>\n <DismissButton onDismiss={state.close} />\n </dom.div>\n );\n // oxlint-enable react/react-compiler\n\n // If this is a root popover, render an extra div to act as the portal container for submenus/subdialogs.\n if (!isSubPopover) {\n // oxlint-disable react/react-compiler\n return (\n <Overlay\n {...props}\n shouldContainFocus={isDialog && props.trigger !== 'PreviewTrigger'}\n isExiting={isExiting}\n portalContainer={UNSTABLE_portalContainer}>\n {/* oxlint-disable-next-line react/react-compiler */}\n {!props.isNonModal && state.isOpen && (\n <div data-testid=\"underlay\" {...underlayProps} style={{position: 'fixed', inset: 0}} />\n )}\n <div ref={containerRef} style={{display: 'contents'}}>\n <PopoverGroupContext.Provider value={containerRef}>\n {overlay}\n </PopoverGroupContext.Provider>\n </div>\n </Overlay>\n );\n // oxlint-enable react/react-compiler\n }\n\n // Submenus/subdialogs are mounted into the root popover's container.\n // oxlint-disable react/react-compiler\n return (\n <Overlay\n {...props}\n shouldContainFocus={isDialog && props.trigger !== 'PreviewTrigger'}\n isExiting={isExiting}\n portalContainer={UNSTABLE_portalContainer ?? groupCtx?.current ?? undefined}>\n {overlay}\n </Overlay>\n );\n // oxlint-enable react/react-compiler\n}\n"],"names":[],"version":3,"file":"Popover.cjs.map"}
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;;;;;;;;;;;;AAgJM,MAAM,0DAAiB,CAAA,GAAA,0BAAY,EAAkD;AAE5F,iFAAiF;AACjF,MAAM,0DAAsB,CAAA,GAAA,0BAAY,EAAoC;AAKrE,MAAM,4CAAwB,AAAd,WAAW,GAAI,CAAA,GAAA,uBAAS,EAAqB,SAAS,QAC3E,KAAmB,EACnB,GAA8B;IAE9B,CAAC,OAAO,IAAI,GAAG,CAAA,GAAA,yCAAc,EAAE,OAAO,KAAK;IAC3C,IAAI,eAAe,CAAA,GAAA,uBAAS,EAAE,CAAA,GAAA,oDAAyB;IACvD,IAAI,aAAa,CAAA,GAAA,gEAAqB,EAAE;IACxC,IAAI,QACF,MAAM,MAAM,IAAI,QAAQ,MAAM,WAAW,IAAI,QAAQ,CAAC,eAAe,aAAa;IACpF,2FAA2F;IAC3F,gFAAgF;IAChF,IAAI,gBAAgB,CAAA,GAAA,sDAAe,EAAE,KAAK,MAAM,MAAM;IACtD,IAAI,YAAY,MAAM,SAAS,IAAK,CAAC,MAAM,mBAAmB,IAAI,iBAAkB;IACpF,IAAI,WAAW,CAAA,GAAA,oDAAU;IACzB,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,sCAAQ;IAE1B,sEAAsE;IACtE,IAAI,UAAU;QACZ,IAAI,WAAW,MAAM,QAAQ;QAC7B,IAAI,OAAO,aAAa,YACtB,WAAW,SAAS;YAClB,SAAS,MAAM,OAAO,IAAI;YAC1B,WAAW;YACX,YAAY;YACZ,WAAW;YACX,iBAAiB;QACnB;QAGF,qBAAO,sHAAG;IACZ;IAEA,IAAI,SAAS,CAAC,MAAM,MAAM,IAAI,CAAC,WAC7B,OAAO;IAGT,qBACE,0DAAC;QACE,GAAG,KAAK;QACT,YAAY,MAAM,UAAU;QAC5B,OAAO;QACP,YAAY;QACZ,WAAW;QACX,KAAK;;AAGX;AAcA,SAAS,mCAAa,SACpB,KAAK,aACL,SAAS,4BACT,wBAAwB,iBACxB,aAAa,EACb,GAAG,OACe;IAClB,qFAAqF;IACrF,2EAA2E;IAC3E,IAAI,WAAW,CAAA,GAAA,mBAAK,EAAkB;IACtC,IAAI,eAAe,CAAA,GAAA,mBAAK,EAAyB;IACjD,IAAI,WAAW,CAAA,GAAA,uBAAS,EAAE;IAC1B,IAAI,eAAe,YAAY,MAAM,OAAO,KAAK;IAEjD,IAAI,CAAC,QAAQ,UAAU,GAAG,CAAA,GAAA,qBAAO,EAAE;IAEnC,IAAI,gBAAC,YAAY,iBAAE,aAAa,cAAE,UAAU,aAAE,SAAS,sBAAE,kBAAkB,EAAC,GAAG,CAAA,GAAA,qCAAS,EACtF;QACE,GAAG,KAAK;QACR,QAAQ,MAAM,MAAM,IAAI;kBACxB;QACA,mEAAmE;QACnE,qDAAqD;QACrD,UAAU,eAAe,WAAY;IACvC,GACA;IAGF,IAAI,MAAM,MAAM,UAAU;IAC1B,4FAA4F;IAC5F,iFAAiF;IACjF,IAAI,iBAAiB,CAAA,GAAA,uDAAgB,EAAE,KAAK,CAAC,CAAC,aAAa;IAC3D,gDAAgD;IAChD,IAAI,aAAa,MAAM,UAAU,IAAK,CAAC,MAAM,mBAAmB,IAAI,kBAAmB;IACvF,gDAAgD;IAChD,IAAI,cAAc,CAAA,GAAA,wCAAa,EAAE;QAC/B,gDAAgD;QAChD,GAAG,KAAK;QACR,kBAAkB;QAClB,gDAAgD;QAChD,QAAQ;YACN,gDAAgD;YAChD,SAAS,MAAM,OAAO,IAAI;uBAC1B;wBAEA,AADA,gDAAgD;YAChD;uBACA;QACF;IACF;IAEA,gFAAgF;IAChF,oDAAoD;IACpD,IAAI,iBACF,gDAAgD;IAChD,CAAC,MAAM,UAAU,IAAI,MAAM,OAAO,KAAK,oBAAoB,MAAM,OAAO,KAAK;IAC/E,gDAAgD;IAChD,IAAI,CAAC,UAAU,UAAU,GAAG,CAAA,GAAA,qBAAO,EAAE,MAAM,OAAO,KAAK;IACvD,CAAA,GAAA,2DAAc,EAAE;QACd,IAAI,IAAI,OAAO,EACb,UAAU,kBAAkB,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC;IAE3D,GAAG;QAAC;QAAK;KAAe;IAExB,gFAAgF;IAChF,0FAA0F;IAC1F,sCAAsC;IACtC,CAAA,GAAA,sBAAQ,EAAE;QACR,IACE,YACA,MAAM,OAAO,KAAK,oBACjB,CAAA,MAAM,OAAO,KAAK,oBAAoB,CAAA,GAAA,yEAAqB,QAAQ,SAAQ,KAC5E,IAAI,OAAO,IACX,CAAC,CAAA,GAAA,+DAAY,EAAE,IAAI,OAAO,GAE1B,CAAA,GAAA,0DAAU,EAAE,IAAI,OAAO;IAE3B,GAAG;QAAC;QAAU;QAAK,MAAM,OAAO;KAAC;IACjC,qCAAqC;IAErC,IAAI,WAAW,CAAA,GAAA,oBAAM,EAAE;QACrB,IAAI,WAAW,YAAY,QAAQ;QACnC,KAAK,IAAI,WAAW;YAAC;eAAoB,iBAAiB,EAAE;SAAE,CAC5D,yBAAW,0DAAC,QAAQ,QAAQ;YAAC,OAAO;WAAO;QAE7C,OAAO;IACT,GAAG;QAAC,YAAY,QAAQ;QAAE;KAAc;IAExC,IAAI,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAO,EAAiB;IAC9D,gDAAgD;IAChD,IAAI,WAAW,CAAA,GAAA,wBAAU,EAAE;QACzB,IAAI,MAAM,UAAU,CAAC,OAAO,EAC1B,gBAAgB,MAAM,UAAU,CAAC,OAAO,CAAC,qBAAqB,GAAG,KAAK,GAAG;IAE7E,GAAG;QAAC,MAAM,UAAU;KAAC;IAErB,CAAA,GAAA,2DAAc,EAAE,UAAU;QAAC;KAAS;IACpC,gDAAgD;IAChD,CAAA,GAAA,+DAAgB,EAAE;QAChB,gDAAgD;QAChD,KAAK,YAAY,KAAK,EAAE,CAAC,kBAAkB,GAAG,YAAY,MAAM,UAAU;QAC1E,UAAU;IACZ;IAEA,IAAI,QAAQ;QACV,GAAG,aAAa,KAAK;QACrB,0BAA0B,qBACtB,GAAG,mBAAmB,CAAC,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,GACrD;QACJ,GAAG,YAAY,KAAK;QACpB,mBAAmB,YAAY,KAAK,EAAE,CAAC,kBAAkB,IAAI;IAC/D;IAEA,iGAAiG;IACjG,CAAA,GAAA,2DAAc,EAAE,IAAM,CAAA,GAAA,6DAAe,EAAE,IAAM,UAAU,QAAQ,EAAE;IAEjE,sCAAsC;IACtC,IAAI,wBACF,0DAAC,CAAA,GAAA,6BAAE,EAAE,GAAG;QACL,GAAG,CAAA,GAAA,qCAAS,EAAE,CAAA,GAAA,6CAAa,EAAE,OAAO;YAAC,QAAQ;QAAI,IAAI,aAAa;QAClE,GAAG,WAAW;QACf,IAAI,WAAW,MAAM,EAAE,GAAG;QAC1B,MAAM,WAAW,WAAW;QAC5B,UAAU,WAAW,KAAK;QAC1B,cAAY,KAAK,CAAC,aAAa;QAC/B,mBAAiB,KAAK,CAAC,kBAAkB;QACzC,KAAK;QACL,MAAM,MAAM,IAAI,IAAI;QACpB,OAAO;QACP,KAAK,MAAM,GAAG;QACd,gBAAc,MAAM,OAAO;QAC3B,kBAAgB;QAChB,iBAAe,cAAc;QAC7B,gBAAc,aAAa;OAE1B,CAAC,MAAM,UAAU,kBAAI,0DAAC,CAAA,GAAA,qCAAY;QAAE,WAAW,MAAM,KAAK;sBAC3D,0DAAC,CAAA,GAAA,6CAAkB,EAAE,QAAQ;QAAC,OAAO;YAAC,GAAG,UAAU;uBAAE;YAAW,KAAK;QAAQ;OAC1E,yBAEH,0DAAC,CAAA,GAAA,qCAAY;QAAE,WAAW,MAAM,KAAK;;IAGzC,qCAAqC;IAErC,yGAAyG;IACzG,IAAI,CAAC,cACH,sCAAsC;IACtC,qBACE,0DAAC,CAAA,GAAA,+BAAM;QACJ,GAAG,KAAK;QACT,oBAAoB,YAAY,MAAM,OAAO,KAAK;QAClD,WAAW;QACX,iBAAiB;OAEhB,CAAC,MAAM,UAAU,IAAI,MAAM,MAAM,kBAChC,0DAAC;QAAI,eAAY;QAAY,GAAG,aAAa;QAAE,OAAO;YAAC,UAAU;YAAS,OAAO;QAAC;sBAEpF,0DAAC;QAAI,KAAK;QAAc,OAAO;YAAC,SAAS;QAAU;qBACjD,0DAAC,0CAAoB,QAAQ;QAAC,OAAO;OAClC;IAQX,qEAAqE;IACrE,sCAAsC;IACtC,qBACE,0DAAC,CAAA,GAAA,+BAAM;QACJ,GAAG,KAAK;QACT,oBAAoB,YAAY,MAAM,OAAO,KAAK;QAClD,WAAW;QACX,iBAAiB,4BAA4B,UAAU,WAAW;OACjE;AAGL,qCAAqC;AACvC","sources":["packages/react-aria-components/src/Popover.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 {\n AriaLabelingProps,\n forwardRefType,\n GlobalDOMAttributes,\n RefObject\n} from '@react-types/shared';\nimport {AriaPopoverProps, usePopover} from 'react-aria/usePopover';\nimport {\n ClassNameOrFunction,\n ContextValue,\n dom,\n RenderProps,\n SlotProps,\n useContextProps,\n useRenderProps\n} from './utils';\nimport {DismissButton, Overlay} from 'react-aria/Overlay';\nimport {filterDOMProps} from 'react-aria/filterDOMProps';\nimport {focusSafely} from 'react-aria/private/interactions/focusSafely';\nimport {getInteractionModality} from 'react-aria/private/interactions/useFocusVisible';\nimport {isFocusWithin} from 'react-aria/private/utils/shadowdom/DOMFunctions';\nimport {mergeProps} from 'react-aria/mergeProps';\nimport {OverlayArrowContext} from './OverlayArrow';\nimport {\n OverlayTriggerProps,\n OverlayTriggerState,\n useOverlayTriggerState\n} from 'react-stately/useOverlayTriggerState';\nimport {OverlayTriggerStateContext} from './Dialog';\nimport {PlacementAxis, PositionProps} from 'react-aria/useOverlayPosition';\nimport React, {\n Context,\n createContext,\n ForwardedRef,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {runAfterKeyboard} from 'react-aria/private/utils/runAfterKeyboard';\nimport {useEnterAnimation, useExitAnimation} from 'react-aria/private/utils/animation';\nimport {useIsHidden} from 'react-aria/private/collections/Hidden';\nimport {useLayoutEffect} from 'react-aria/private/utils/useLayoutEffect';\nimport {useLocale} from 'react-aria/I18nProvider';\nimport {useResizeObserver} from 'react-aria/private/utils/useResizeObserver';\n\nexport interface PopoverProps\n extends\n Omit<PositionProps, 'isOpen'>,\n Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef' | 'groupRef' | 'offset' | 'arrowSize'>,\n OverlayTriggerProps,\n RenderProps<PopoverRenderProps>,\n SlotProps,\n AriaLabelingProps,\n GlobalDOMAttributes<HTMLDivElement> {\n /**\n * The CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the\n * element. A function may be provided to compute the class based on component state.\n *\n * @default 'react-aria-Popover'\n */\n className?: ClassNameOrFunction<PopoverRenderProps>;\n /**\n * The name of the component that triggered the popover. This is reflected on the element\n * as the `data-trigger` attribute, and can be used to provide specific\n * styles for the popover depending on which element triggered it.\n */\n trigger?: string;\n /**\n * The ref for the element which the popover positions itself with respect to.\n *\n * When used within a trigger component such as DialogTrigger, MenuTrigger, Select, etc.,\n * this is set automatically. It is only required when used standalone.\n */\n triggerRef?: RefObject<Element | null>;\n /**\n * Whether the popover is currently performing an entry animation.\n */\n isEntering?: boolean;\n /**\n * Whether the popover is currently performing an exit animation.\n */\n isExiting?: boolean;\n /**\n * Whether the popover should appear and disappear without an entry or exit animation. This is\n * used by components such as PreviewTrigger to skip animations when quickly swapping between\n * overlays.\n */\n shouldSkipAnimation?: boolean;\n /**\n * The container element in which the overlay portal will be placed. This may have unknown\n * behavior depending on where it is portalled to.\n *\n * @deprecated - Use a parent UNSAFE_PortalProvider to set your portal container instead.\n * @default document.body\n */\n UNSTABLE_portalContainer?: Element;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 8\n */\n offset?: number;\n}\n\nexport interface PopoverRenderProps {\n /**\n * The name of the component that triggered the popover, e.g. \"DialogTrigger\" or \"ComboBox\".\n *\n * @selector [data-trigger=\"...\"]\n */\n trigger: string | null;\n /**\n * The placement of the popover relative to the trigger.\n *\n * @selector [data-placement=\"left | right | top | bottom\"]\n */\n placement: PlacementAxis | null;\n /**\n * Whether the popover is currently entering. Use this to apply animations.\n *\n * @selector [data-entering]\n */\n isEntering: boolean;\n /**\n * Whether the popover is currently exiting. Use this to apply animations.\n *\n * @selector [data-exiting]\n */\n isExiting: boolean;\n}\n\ninterface PopoverContextValue extends PopoverProps {\n id?: string;\n /** Contexts to clear. */\n clearContexts?: Context<any>[];\n}\n\nexport const PopoverContext = createContext<ContextValue<PopoverContextValue, HTMLElement>>(null);\n\n// Stores a ref for the portal container for a group of popovers (e.g. submenus).\nconst PopoverGroupContext = createContext<RefObject<Element | null> | null>(null);\n\n/**\n * A popover is an overlay element positioned relative to a trigger.\n */\nexport const Popover = /*#__PURE__*/ (forwardRef as forwardRefType)(function Popover(\n props: PopoverProps,\n ref: ForwardedRef<HTMLElement>\n) {\n [props, ref] = useContextProps(props, ref, PopoverContext);\n let contextState = useContext(OverlayTriggerStateContext);\n let localState = useOverlayTriggerState(props);\n let state =\n props.isOpen != null || props.defaultOpen != null || !contextState ? localState : contextState;\n // Skip the automatic exit animation when closing instantly (e.g. swapping between previews\n // during warmup). An explicitly provided isExiting prop still takes precedence.\n let exitAnimation = useExitAnimation(ref, state.isOpen);\n let isExiting = props.isExiting || (!props.shouldSkipAnimation && exitAnimation) || false;\n let isHidden = useIsHidden();\n let {direction} = useLocale();\n\n // If we are in a hidden tree, we still need to preserve our children.\n if (isHidden) {\n let children = props.children;\n if (typeof children === 'function') {\n children = children({\n trigger: props.trigger || null,\n placement: 'bottom',\n isEntering: false,\n isExiting: false,\n defaultChildren: null\n });\n }\n\n return <>{children}</>;\n }\n\n if (state && !state.isOpen && !isExiting) {\n return null;\n }\n\n return (\n <PopoverInner\n {...props}\n triggerRef={props.triggerRef!}\n state={state}\n popoverRef={ref}\n isExiting={isExiting}\n dir={direction}\n />\n );\n});\n\ninterface PopoverInnerProps extends AriaPopoverProps, RenderProps<PopoverRenderProps>, SlotProps {\n state: OverlayTriggerState;\n isEntering?: boolean;\n isExiting: boolean;\n shouldSkipAnimation?: boolean;\n UNSTABLE_portalContainer?: Element;\n trigger?: string;\n dir?: 'ltr' | 'rtl';\n clearContexts?: Context<any>[];\n id?: string;\n}\n\nfunction PopoverInner({\n state,\n isExiting,\n UNSTABLE_portalContainer,\n clearContexts,\n ...props\n}: PopoverInnerProps) {\n // Calculate the arrow size internally (and remove props.arrowSize from PopoverProps)\n // Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx\n let arrowRef = useRef<HTMLDivElement>(null);\n let containerRef = useRef<HTMLDivElement | null>(null);\n let groupCtx = useContext(PopoverGroupContext);\n let isSubPopover = groupCtx && props.trigger === 'SubmenuTrigger';\n\n let [isOpen, setIsOpen] = useState(false);\n\n let {popoverProps, underlayProps, arrowProps, placement, triggerAnchorPoint} = usePopover(\n {\n ...props,\n offset: props.offset ?? 8,\n arrowRef,\n // If this is a submenu/subdialog, use the root popover's container\n // to detect outside interaction and add aria-hidden.\n groupRef: isSubPopover ? groupCtx! : containerRef\n },\n state\n );\n\n let ref = props.popoverRef as RefObject<HTMLDivElement | null>;\n // Skip the automatic entry animation when opening instantly (e.g. swapping between previews\n // during warmup). An explicitly provided isEntering prop still takes precedence.\n let enterAnimation = useEnterAnimation(ref, !!placement && isOpen);\n // oxlint-disable-next-line react/react-compiler\n let isEntering = props.isEntering || (!props.shouldSkipAnimation && enterAnimation) || false;\n // oxlint-disable-next-line react/react-compiler\n let renderProps = useRenderProps({\n // oxlint-disable-next-line react/react-compiler\n ...props,\n defaultClassName: 'react-aria-Popover',\n // oxlint-disable-next-line react/react-compiler\n values: {\n // oxlint-disable-next-line react/react-compiler\n trigger: props.trigger || null,\n placement,\n // oxlint-disable-next-line react/react-compiler\n isEntering,\n isExiting\n }\n });\n\n // Automatically render Popover with role=dialog except when isNonModal is true,\n // or a dialog is already nested inside the popover.\n let shouldBeDialog =\n // oxlint-disable-next-line react/react-compiler\n !props.isNonModal || props.trigger === 'SubmenuTrigger' || props.trigger === 'PreviewTrigger';\n // oxlint-disable-next-line react/react-compiler\n let [isDialog, setDialog] = useState(props.trigger === 'PreviewTrigger');\n useLayoutEffect(() => {\n if (ref.current) {\n setDialog(shouldBeDialog && !ref.current.querySelector('[role=dialog]'));\n }\n }, [ref, shouldBeDialog]);\n\n // Focus the popover itself on mount, unless a child element is already focused.\n // Skip this for submenus since hovering a submenutrigger should keep focus on the trigger\n // oxlint-disable react/react-compiler\n useEffect(() => {\n if (\n isDialog &&\n props.trigger !== 'PreviewTrigger' &&\n (props.trigger !== 'SubmenuTrigger' || getInteractionModality() !== 'pointer') &&\n ref.current &&\n !isFocusWithin(ref.current)\n ) {\n focusSafely(ref.current);\n }\n }, [isDialog, ref, props.trigger]);\n // oxlint-enable react/react-compiler\n\n let children = useMemo(() => {\n let children = renderProps.children;\n for (let Context of [PopoverContext, ...(clearContexts ?? [])]) {\n children = <Context.Provider value={null}>{children}</Context.Provider>;\n }\n return children;\n }, [renderProps.children, clearContexts]);\n\n let [triggerWidth, setTriggerWidth] = useState<string | null>(null);\n // oxlint-disable-next-line react/react-compiler\n let onResize = useCallback(() => {\n if (props.triggerRef.current) {\n setTriggerWidth(props.triggerRef.current.getBoundingClientRect().width + 'px');\n }\n }, [props.triggerRef]);\n\n useLayoutEffect(onResize, [onResize]);\n // oxlint-disable-next-line react/react-compiler\n useResizeObserver({\n // oxlint-disable-next-line react/react-compiler\n ref: renderProps.style?.['--trigger-width'] ? undefined : props.triggerRef,\n onResize: onResize\n });\n\n let style = {\n ...popoverProps.style,\n '--trigger-anchor-point': triggerAnchorPoint\n ? `${triggerAnchorPoint.x}px ${triggerAnchorPoint.y}px`\n : undefined,\n ...renderProps.style,\n '--trigger-width': renderProps.style?.['--trigger-width'] || triggerWidth\n };\n\n // Since our trigger may open the OSK, we defer the reveal, as a courtesy, to avoid layout shift.\n useLayoutEffect(() => runAfterKeyboard(() => setIsOpen(true)), []);\n\n // oxlint-disable react/react-compiler\n let overlay = (\n <dom.div\n {...mergeProps(filterDOMProps(props, {global: true}), popoverProps)}\n {...renderProps}\n id={isDialog ? props.id : undefined}\n role={isDialog ? 'dialog' : undefined}\n tabIndex={isDialog ? -1 : undefined}\n aria-label={props['aria-label']}\n aria-labelledby={props['aria-labelledby']}\n ref={ref}\n slot={props.slot || undefined}\n style={style}\n dir={props.dir}\n data-trigger={props.trigger}\n data-placement={placement}\n data-entering={isEntering || undefined}\n data-exiting={isExiting || undefined}>\n {/* oxlint-disable-next-line react/react-compiler */}\n {!props.isNonModal && <DismissButton onDismiss={state.close} />}\n <OverlayArrowContext.Provider value={{...arrowProps, placement, ref: arrowRef}}>\n {children}\n </OverlayArrowContext.Provider>\n <DismissButton onDismiss={state.close} />\n </dom.div>\n );\n // oxlint-enable react/react-compiler\n\n // If this is a root popover, render an extra div to act as the portal container for submenus/subdialogs.\n if (!isSubPopover) {\n // oxlint-disable react/react-compiler\n return (\n <Overlay\n {...props}\n shouldContainFocus={isDialog && props.trigger !== 'PreviewTrigger'}\n isExiting={isExiting}\n portalContainer={UNSTABLE_portalContainer}>\n {/* oxlint-disable-next-line react/react-compiler */}\n {!props.isNonModal && state.isOpen && (\n <div data-testid=\"underlay\" {...underlayProps} style={{position: 'fixed', inset: 0}} />\n )}\n <div ref={containerRef} style={{display: 'contents'}}>\n <PopoverGroupContext.Provider value={containerRef}>\n {overlay}\n </PopoverGroupContext.Provider>\n </div>\n </Overlay>\n );\n // oxlint-enable react/react-compiler\n }\n\n // Submenus/subdialogs are mounted into the root popover's container.\n // oxlint-disable react/react-compiler\n return (\n <Overlay\n {...props}\n shouldContainFocus={isDialog && props.trigger !== 'PreviewTrigger'}\n isExiting={isExiting}\n portalContainer={UNSTABLE_portalContainer ?? groupCtx?.current ?? undefined}>\n {overlay}\n </Overlay>\n );\n // oxlint-enable react/react-compiler\n}\n"],"names":[],"version":3,"file":"Popover.cjs.map"}
|
package/dist/private/Popover.js
CHANGED
|
@@ -10,6 +10,7 @@ import {isFocusWithin as $jx81S$isFocusWithin} from "react-aria/private/utils/sh
|
|
|
10
10
|
import {mergeProps as $jx81S$mergeProps} from "react-aria/mergeProps";
|
|
11
11
|
import {useOverlayTriggerState as $jx81S$useOverlayTriggerState} from "react-stately/useOverlayTriggerState";
|
|
12
12
|
import $jx81S$react, {createContext as $jx81S$createContext, forwardRef as $jx81S$forwardRef, useContext as $jx81S$useContext, useRef as $jx81S$useRef, useState as $jx81S$useState, useEffect as $jx81S$useEffect, useMemo as $jx81S$useMemo, useCallback as $jx81S$useCallback} from "react";
|
|
13
|
+
import {runAfterKeyboard as $jx81S$runAfterKeyboard} from "react-aria/private/utils/runAfterKeyboard";
|
|
13
14
|
import {useExitAnimation as $jx81S$useExitAnimation, useEnterAnimation as $jx81S$useEnterAnimation} from "react-aria/private/utils/animation";
|
|
14
15
|
import {useIsHidden as $jx81S$useIsHidden} from "react-aria/private/collections/Hidden";
|
|
15
16
|
import {useLayoutEffect as $jx81S$useLayoutEffect} from "react-aria/private/utils/useLayoutEffect";
|
|
@@ -43,6 +44,7 @@ import {useResizeObserver as $jx81S$useResizeObserver} from "react-aria/private/
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
|
|
47
|
+
|
|
46
48
|
const $03df2f2d3cffb62f$export$9b9a0cd73afb7ca4 = /*#__PURE__*/ (0, $jx81S$createContext)(null);
|
|
47
49
|
// Stores a ref for the portal container for a group of popovers (e.g. submenus).
|
|
48
50
|
const $03df2f2d3cffb62f$var$PopoverGroupContext = /*#__PURE__*/ (0, $jx81S$createContext)(null);
|
|
@@ -87,6 +89,7 @@ function $03df2f2d3cffb62f$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
87
89
|
let containerRef = (0, $jx81S$useRef)(null);
|
|
88
90
|
let groupCtx = (0, $jx81S$useContext)($03df2f2d3cffb62f$var$PopoverGroupContext);
|
|
89
91
|
let isSubPopover = groupCtx && props.trigger === 'SubmenuTrigger';
|
|
92
|
+
let [isOpen, setIsOpen] = (0, $jx81S$useState)(false);
|
|
90
93
|
var _props_offset;
|
|
91
94
|
let { popoverProps: popoverProps, underlayProps: underlayProps, arrowProps: arrowProps, placement: placement, triggerAnchorPoint: triggerAnchorPoint } = (0, $jx81S$usePopover)({
|
|
92
95
|
...props,
|
|
@@ -99,7 +102,7 @@ function $03df2f2d3cffb62f$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
99
102
|
let ref = props.popoverRef;
|
|
100
103
|
// Skip the automatic entry animation when opening instantly (e.g. swapping between previews
|
|
101
104
|
// during warmup). An explicitly provided isEntering prop still takes precedence.
|
|
102
|
-
let enterAnimation = (0, $jx81S$useEnterAnimation)(ref, !!placement);
|
|
105
|
+
let enterAnimation = (0, $jx81S$useEnterAnimation)(ref, !!placement && isOpen);
|
|
103
106
|
// oxlint-disable-next-line react/react-compiler
|
|
104
107
|
let isEntering = props.isEntering || !props.shouldSkipAnimation && enterAnimation || false;
|
|
105
108
|
// oxlint-disable-next-line react/react-compiler
|
|
@@ -142,7 +145,10 @@ function $03df2f2d3cffb62f$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
142
145
|
// oxlint-enable react/react-compiler
|
|
143
146
|
let children = (0, $jx81S$useMemo)(()=>{
|
|
144
147
|
let children = renderProps.children;
|
|
145
|
-
|
|
148
|
+
for (let Context of [
|
|
149
|
+
$03df2f2d3cffb62f$export$9b9a0cd73afb7ca4,
|
|
150
|
+
...clearContexts !== null && clearContexts !== void 0 ? clearContexts : []
|
|
151
|
+
])children = /*#__PURE__*/ (0, $jx81S$react).createElement(Context.Provider, {
|
|
146
152
|
value: null
|
|
147
153
|
}, children);
|
|
148
154
|
return children;
|
|
@@ -172,6 +178,8 @@ function $03df2f2d3cffb62f$var$PopoverInner({ state: state, isExiting: isExiting
|
|
|
172
178
|
...renderProps.style,
|
|
173
179
|
'--trigger-width': ((_renderProps_style1 = renderProps.style) === null || _renderProps_style1 === void 0 ? void 0 : _renderProps_style1['--trigger-width']) || triggerWidth
|
|
174
180
|
};
|
|
181
|
+
// Since our trigger may open the OSK, we defer the reveal, as a courtesy, to avoid layout shift.
|
|
182
|
+
(0, $jx81S$useLayoutEffect)(()=>(0, $jx81S$runAfterKeyboard)(()=>setIsOpen(true)), []);
|
|
175
183
|
// oxlint-disable react/react-compiler
|
|
176
184
|
let overlay = /*#__PURE__*/ (0, $jx81S$react).createElement((0, $b7b7a92703138c9b$export$df3a06d6289f983e).div, {
|
|
177
185
|
...(0, $jx81S$mergeProps)((0, $jx81S$filterDOMProps)(props, {
|