({
state,
isExiting,
UNSTABLE_portalContainer,
clearContexts,
...props
}: PopoverInnerProps)
| 220 | } |
| 221 | |
| 222 | function PopoverInner({ |
| 223 | state, |
| 224 | isExiting, |
| 225 | UNSTABLE_portalContainer, |
| 226 | clearContexts, |
| 227 | ...props |
| 228 | }: PopoverInnerProps) { |
| 229 | // Calculate the arrow size internally (and remove props.arrowSize from PopoverProps) |
| 230 | // Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx |
| 231 | let arrowRef = useRef<HTMLDivElement>(null); |
| 232 | let containerRef = useRef<HTMLDivElement | null>(null); |
| 233 | let groupCtx = useContext(PopoverGroupContext); |
| 234 | let isSubPopover = groupCtx && props.trigger === 'SubmenuTrigger'; |
| 235 | |
| 236 | let {popoverProps, underlayProps, arrowProps, placement, triggerAnchorPoint} = usePopover( |
| 237 | { |
| 238 | ...props, |
| 239 | offset: props.offset ?? 8, |
| 240 | arrowRef, |
| 241 | // If this is a submenu/subdialog, use the root popover's container |
| 242 | // to detect outside interaction and add aria-hidden. |
| 243 | groupRef: isSubPopover ? groupCtx! : containerRef |
| 244 | }, |
| 245 | state |
| 246 | ); |
| 247 | |
| 248 | let ref = props.popoverRef as RefObject<HTMLDivElement | null>; |
| 249 | // Skip the automatic entry animation when opening instantly (e.g. swapping between previews |
| 250 | // during warmup). An explicitly provided isEntering prop still takes precedence. |
| 251 | let enterAnimation = useEnterAnimation(ref, !!placement); |
| 252 | // oxlint-disable-next-line react/react-compiler |
| 253 | let isEntering = props.isEntering || (!props.shouldSkipAnimation && enterAnimation) || false; |
| 254 | // oxlint-disable-next-line react/react-compiler |
| 255 | let renderProps = useRenderProps({ |
| 256 | // oxlint-disable-next-line react/react-compiler |
| 257 | ...props, |
| 258 | defaultClassName: 'react-aria-Popover', |
| 259 | // oxlint-disable-next-line react/react-compiler |
| 260 | values: { |
| 261 | // oxlint-disable-next-line react/react-compiler |
| 262 | trigger: props.trigger || null, |
| 263 | placement, |
| 264 | // oxlint-disable-next-line react/react-compiler |
| 265 | isEntering, |
| 266 | isExiting |
| 267 | } |
| 268 | }); |
| 269 | |
| 270 | // Automatically render Popover with role=dialog except when isNonModal is true, |
| 271 | // or a dialog is already nested inside the popover. |
| 272 | let shouldBeDialog = |
| 273 | // oxlint-disable-next-line react/react-compiler |
| 274 | !props.isNonModal || props.trigger === 'SubmenuTrigger' || props.trigger === 'PreviewTrigger'; |
| 275 | // oxlint-disable-next-line react/react-compiler |
| 276 | let [isDialog, setDialog] = useState(props.trigger === 'PreviewTrigger'); |
| 277 | useLayoutEffect(() => { |
| 278 | if (ref.current) { |
| 279 | setDialog(shouldBeDialog && !ref.current.querySelector('[role=dialog]')); |
nothing calls this directly
no test coverage detected