@@ -13,7 +13,6 @@ import type { MenuListProps, MenuListState, MenuListType } from './MenuList.type
13
13
import { menuListName } from './MenuList.types' ;
14
14
import { useMenuList } from './useMenuList' ;
15
15
import { useMenuListContextValue } from './useMenuListContextValue' ;
16
- import { useMenuContext } from '../context' ;
17
16
import { MenuListProvider } from '../context/menuListContext' ;
18
17
19
18
const MenuStack = stagedComponent ( ( props : React . PropsWithRef < IViewProps > & { gap ?: number } ) => {
@@ -35,32 +34,28 @@ const MenuStack = stagedComponent((props: React.PropsWithRef<IViewProps> & { gap
35
34
} ) ;
36
35
MenuStack . displayName = 'MenuStack' ;
37
36
37
+ const shouldHaveFocusZone = [ 'macos' , 'win32' ] . includes ( Platform . OS as string ) ;
38
+ const focusLandsOnContainer = Platform . OS === 'macos' ;
39
+ const hasCircularNavigation = Platform . OS === ( 'win32' as any ) ;
40
+ const hasTabNavigation = Platform . OS === ( 'win32' as any ) ;
41
+
38
42
export const menuListLookup = ( layer : string , state : MenuListState , userProps : MenuListProps ) : boolean => {
39
43
return state [ layer ] || userProps [ layer ] || layer === 'hasMaxHeight' ;
40
44
} ;
45
+
41
46
export const MenuList = compose < MenuListType > ( {
42
47
displayName : menuListName ,
43
48
...stylingSettings ,
44
49
slots : {
45
50
root : MenuStack ,
46
51
scrollView : ScrollView ,
47
- ... ( Platform . OS === 'macos' && { focusZone : FocusZone } ) ,
52
+ focusZone : shouldHaveFocusZone ? FocusZone : React . Fragment ,
48
53
} ,
49
54
useRender : ( userProps : MenuListProps , useSlots : UseSlots < MenuListType > ) => {
50
55
const menuList = useMenuList ( userProps ) ;
51
- const menuContext = useMenuContext ( ) ;
52
56
const menuListContextValue = useMenuListContextValue ( menuList ) ;
53
57
const Slots = useSlots ( menuList . props , ( layer ) => menuListLookup ( layer , menuList , userProps ) ) ;
54
58
55
- const focusZoneRef = React . useRef < View > ( ) ;
56
- const setFocusZoneFocus = ( ) => {
57
- focusZoneRef ?. current ?. focus ( ) ;
58
- } ;
59
-
60
- React . useEffect ( ( ) => {
61
- setFocusZoneFocus ( ) ;
62
- } , [ ] ) ;
63
-
64
59
return ( _final : MenuListProps , children : React . ReactNode ) => {
65
60
const itemCount = React . Children . toArray ( children ) . filter (
66
61
( child ) => React . isValidElement ( child ) && ( child as any ) . type . displayName !== 'MenuDivider' ,
@@ -85,33 +80,34 @@ export const MenuList = compose<MenuListType>({
85
80
return child ;
86
81
} ) ;
87
82
88
- const content =
89
- Platform . OS === 'macos' ? (
90
- < Slots . root onMouseLeave = { setFocusZoneFocus } onKeyDown = { menuList . onListKeyDown } >
91
- < Slots . scrollView
92
- showsVerticalScrollIndicator = { menuContext . hasMaxHeight }
93
- showsHorizontalScrollIndicator = { menuContext . hasMaxWidth }
83
+ const shouldHaveScrollView = Platform . OS === 'macos' || menuList . hasMaxHeight || menuList . hasMaxWidth ;
84
+ const ScrollViewWrapper = shouldHaveScrollView ? Slots . scrollView : React . Fragment ;
85
+
86
+ const content = (
87
+ < Slots . root >
88
+ < ScrollViewWrapper
89
+ // avoid error that fires when props are passed into React.fragment
90
+ { ...( shouldHaveScrollView && {
91
+ showsVerticalScrollIndicator : menuList . hasMaxHeight ,
92
+ showsHorizontalScrollIndicator : menuList . hasMaxWidth ,
93
+ } ) }
94
+ >
95
+ < Slots . focusZone
96
+ // avoid error that fires when props are passed into React.fragment
97
+ { ...( shouldHaveFocusZone && {
98
+ componentRef : focusLandsOnContainer && menuList . focusZoneRef ,
99
+ focusZoneDirection : 'vertical' ,
100
+ defaultTabbableElement : focusLandsOnContainer && menuList . focusZoneRef ,
101
+ enableFocusRing : false ,
102
+ isCircularNavigation : hasCircularNavigation ,
103
+ tabKeyNavigation : hasTabNavigation ? 'Normal' : 'None' ,
104
+ } ) }
94
105
>
95
- < Slots . focusZone
96
- componentRef = { focusZoneRef }
97
- focusZoneDirection = { 'vertical' }
98
- defaultTabbableElement = { focusZoneRef } // eslint-disable-next-line @typescript-eslint/ban-ts-comment
99
- // @ts -ignore FocusZone takes ViewProps, but that isn't defined on it's type.
100
- enableFocusRing = { false }
101
- >
102
- { childrenWithSet }
103
- </ Slots . focusZone >
104
- </ Slots . scrollView >
105
- </ Slots . root >
106
- ) : menuContext . hasMaxHeight ? (
107
- < Slots . root onKeyDown = { menuList . onListKeyDown } style = { menuContext . minWidth ? { minWidth : menuContext . minWidth } : { } } >
108
- < Slots . scrollView > { childrenWithSet } </ Slots . scrollView >
109
- </ Slots . root >
110
- ) : (
111
- < Slots . root onKeyDown = { menuList . onListKeyDown } style = { menuContext . minWidth ? { minWidth : menuContext . minWidth } : { } } >
112
- { childrenWithSet }
113
- </ Slots . root >
114
- ) ;
106
+ { childrenWithSet }
107
+ </ Slots . focusZone >
108
+ </ ScrollViewWrapper >
109
+ </ Slots . root >
110
+ ) ;
115
111
116
112
return < MenuListProvider value = { menuListContextValue } > { content } </ MenuListProvider > ;
117
113
} ;
0 commit comments