@@ -39,7 +39,7 @@ const testIds = {
3939 } ,
4040}
4141
42- type NavListRootProps = {
42+ export type NavListRootProps = {
4343 /**
4444 * Accessible label for the navigation landmark. Defaults to "Navigation".
4545 */
@@ -100,24 +100,32 @@ const NavListRoot = forwardRef<HTMLElement, NavListRootProps>(
100100 ...rest
101101 } ,
102102 ref ,
103- ) => (
104- < NavListContext . Provider value = { { internalAccessibleLabels} } >
105- < nav
106- ref = { ref }
107- className = { clsx ( styles . NavList , className ) }
108- aria-label = { ariaLabelledBy ? undefined : ariaLabel ?? internalAccessibleLabels . defaultNavigationLabel }
109- aria-labelledby = { ariaLabelledBy }
110- data-testid = { testId || testIds . root }
111- { ...rest }
112- >
113- < NavListLevelContext . Provider value = { 1 } >
114- < ul className = { styles . NavList__list } data-testid = { testIds . list } >
115- { children }
116- </ ul >
117- </ NavListLevelContext . Provider >
118- </ nav >
119- </ NavListContext . Provider >
120- ) ,
103+ ) => {
104+ const hasTopLevelSubNav = Children . toArray ( children ) . some ( childHasDirectSubNav )
105+ const rootLevel = hasTopLevelSubNav ? 1 : 2
106+
107+ return (
108+ < NavListContext . Provider value = { { internalAccessibleLabels} } >
109+ < nav
110+ ref = { ref }
111+ className = { clsx ( styles . NavList , className ) }
112+ aria-label = { ariaLabelledBy ? undefined : ariaLabel ?? internalAccessibleLabels . defaultNavigationLabel }
113+ aria-labelledby = { ariaLabelledBy }
114+ data-testid = { testId || testIds . root }
115+ { ...rest }
116+ >
117+ < NavListLevelContext . Provider value = { rootLevel } >
118+ < ul
119+ className = { clsx ( styles . NavList__list , ! hasTopLevelSubNav && styles [ 'NavList__list--flat' ] ) }
120+ data-testid = { testIds . list }
121+ >
122+ { children }
123+ </ ul >
124+ </ NavListLevelContext . Provider >
125+ </ nav >
126+ </ NavListContext . Provider >
127+ )
128+ } ,
121129)
122130
123131type Visual = ReactElement | React . ElementType
@@ -186,6 +194,18 @@ function getTextContent(node: ReactNode): string {
186194 . join ( '' )
187195}
188196
197+ function childHasDirectSubNav ( node : ReactNode ) : boolean {
198+ if ( ! isValidElement ( node ) ) return false
199+
200+ if ( node . type === React . Fragment ) {
201+ return Children . toArray ( ( node as ElementWithChildren ) . props . children ) . some ( childHasDirectSubNav )
202+ }
203+
204+ return Children . toArray ( ( node as ElementWithChildren ) . props . children ) . some (
205+ child => isValidElement < NavListSubNavProps > ( child ) && child . type === NavListSubNav ,
206+ )
207+ }
208+
189209function renderVisual ( visual : Visual | undefined , className : string ) {
190210 if ( ! visual ) return null
191211
@@ -216,7 +236,6 @@ const NavListItem = forwardRef(
216236 leadingVisual,
217237 onClick,
218238 onExpandedChange,
219- onKeyDown,
220239 trailingVisual,
221240 'aria-current' : ariaCurrent ,
222241 'data-testid' : testId ,
@@ -332,11 +351,9 @@ const NavListItem = forwardRef(
332351 )
333352
334353 return (
335- // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
336354 < li
337355 className = { clsx ( styles . NavList__item , levelClassNames [ level ] , isLeafItem && styles [ 'NavList__item--leaf' ] ) }
338356 data-testid = { testId || testIds . item }
339- onKeyDown = { onKeyDown }
340357 >
341358 < div className = { styles . NavList__itemContent } >
342359 { hasSubNav && canExpand ? (
0 commit comments