({children, 'aria-label': ariaLabel, ...rest}: TabNavProps)
| 31 | export type TabNavProps = ComponentProps<typeof TabNavBase> |
| 32 | |
| 33 | function TabNav({children, 'aria-label': ariaLabel, ...rest}: TabNavProps) { |
| 34 | const customContainerRef = useRef<HTMLElement>(null) |
| 35 | |
| 36 | // Detect if the TabNav is inside an ActionMenu. |
| 37 | const [isInsideMenu, setIsInsideMenu] = useState(false) |
| 38 | React.useEffect(() => { |
| 39 | if (customContainerRef.current) { |
| 40 | const menu = customContainerRef.current.closest<HTMLElement>('[role=menu]') |
| 41 | if (menu) { |
| 42 | setIsInsideMenu(true) |
| 43 | } |
| 44 | } |
| 45 | }, [customContainerRef]) |
| 46 | |
| 47 | const customStrategy = React.useCallback(() => { |
| 48 | const selectedTab = customContainerRef.current?.querySelector<HTMLElement>('[role=tab][aria-selected=true]') |
| 49 | const firstTab = customContainerRef.current?.querySelector<HTMLElement>('[role=tab]') |
| 50 | return selectedTab ?? firstTab ?? undefined |
| 51 | }, [customContainerRef]) |
| 52 | |
| 53 | const {containerRef: navRef} = useFocusZone( |
| 54 | { |
| 55 | containerRef: customContainerRef, |
| 56 | bindKeys: FocusKeys.ArrowHorizontal | FocusKeys.HomeAndEnd, |
| 57 | focusOutBehavior: 'wrap', |
| 58 | // Use 'previous' strategy when inside an ActionMenu to avoid |
| 59 | // conflicting with the ActionMenu's focus zone. |
| 60 | // |
| 61 | // WARNING: We don't recommend using TabNav inside an ActionMenu. |
| 62 | // This is a workaround to avoid breaking existing code. |
| 63 | focusInStrategy: isInsideMenu ? 'previous' : customStrategy, |
| 64 | focusableElementFilter: element => element.getAttribute('role') === 'tab', |
| 65 | }, |
| 66 | [isInsideMenu], |
| 67 | ) |
| 68 | |
| 69 | return ( |
| 70 | <TabNavBase {...rest} ref={navRef as React.RefObject<HTMLDivElement>}> |
| 71 | <TabNavNav aria-label={ariaLabel}> |
| 72 | <TabNavTabList role="tablist">{children}</TabNavTabList> |
| 73 | </TabNavNav> |
| 74 | </TabNavBase> |
| 75 | ) |
| 76 | } |
| 77 | |
| 78 | export type TabNavLinkProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement> & { |
| 79 | to?: To |
nothing calls this directly
no test coverage detected