MCPcopy Index your code
hub / github.com/adobe/react-spectrum / PopoverInner

Function PopoverInner

packages/react-aria-components/src/Popover.tsx:210–358  ·  view source on GitHub ↗
({
  state,
  isExiting,
  UNSTABLE_portalContainer,
  clearContexts,
  ...props
}: PopoverInnerProps)

Source from the content-addressed store, hash-verified

208}
209
210function PopoverInner({
211 state,
212 isExiting,
213 UNSTABLE_portalContainer,
214 clearContexts,
215 ...props
216}: PopoverInnerProps) {
217 // Calculate the arrow size internally (and remove props.arrowSize from PopoverProps)
218 // Referenced from: packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx
219 let arrowRef = useRef<HTMLDivElement>(null);
220 let containerRef = useRef<HTMLDivElement | null>(null);
221 let groupCtx = useContext(PopoverGroupContext);
222 let isSubPopover = groupCtx && props.trigger === 'SubmenuTrigger';
223
224 let {popoverProps, underlayProps, arrowProps, placement, triggerAnchorPoint} = usePopover(
225 {
226 ...props,
227 offset: props.offset ?? 8,
228 arrowRef,
229 // If this is a submenu/subdialog, use the root popover's container
230 // to detect outside interaction and add aria-hidden.
231 groupRef: isSubPopover ? groupCtx! : containerRef
232 },
233 state
234 );
235
236 let ref = props.popoverRef as RefObject<HTMLDivElement | null>;
237 let isEntering = useEnterAnimation(ref, !!placement) || props.isEntering || false;
238 let renderProps = useRenderProps({
239 ...props,
240 defaultClassName: 'react-aria-Popover',
241 values: {
242 trigger: props.trigger || null,
243 placement,
244 isEntering,
245 isExiting
246 }
247 });
248
249 // Automatically render Popover with role=dialog except when isNonModal is true,
250 // or a dialog is already nested inside the popover.
251 let shouldBeDialog = !props.isNonModal || props.trigger === 'SubmenuTrigger';
252 let [isDialog, setDialog] = useState(false);
253 useLayoutEffect(() => {
254 if (ref.current) {
255 setDialog(shouldBeDialog && !ref.current.querySelector('[role=dialog]'));
256 }
257 }, [ref, shouldBeDialog]);
258
259 // Focus the popover itself on mount, unless a child element is already focused.
260 // Skip this for submenus since hovering a submenutrigger should keep focus on the trigger
261 useEffect(() => {
262 if (
263 isDialog &&
264 (props.trigger !== 'SubmenuTrigger' || getInteractionModality() !== 'pointer') &&
265 ref.current &&
266 !isFocusWithin(ref.current)
267 ) {

Callers

nothing calls this directly

Calls 9

usePopoverFunction · 0.90
useEnterAnimationFunction · 0.90
useRenderPropsFunction · 0.90
getInteractionModalityFunction · 0.90
isFocusWithinFunction · 0.90
focusSafelyFunction · 0.90
useResizeObserverFunction · 0.90
mergePropsFunction · 0.90
filterDOMPropsFunction · 0.90

Tested by

no test coverage detected