(props: {
children: ReactNode;
isSubmenu?: boolean;
hasOpenSubmenu?: boolean;
parentMenuTreeState?: TreeState<any>;
rootMenuTriggerState?: RootMenuTriggerState;
onBackButtonPress?: () => void;
wrapperKeyDown?: KeyboardEventHandler<HTMLDivElement> | undefined;
menuRef?: RefObject<HTMLDivElement | null>;
})
| 148 | }) as <T>(props: SpectrumMenuProps<T> & {ref?: DOMRef<HTMLDivElement>}) => ReactElement; |
| 149 | |
| 150 | export function TrayHeaderWrapper(props: { |
| 151 | children: ReactNode; |
| 152 | isSubmenu?: boolean; |
| 153 | hasOpenSubmenu?: boolean; |
| 154 | parentMenuTreeState?: TreeState<any>; |
| 155 | rootMenuTriggerState?: RootMenuTriggerState; |
| 156 | onBackButtonPress?: () => void; |
| 157 | wrapperKeyDown?: KeyboardEventHandler<HTMLDivElement> | undefined; |
| 158 | menuRef?: RefObject<HTMLDivElement | null>; |
| 159 | }): ReactNode { |
| 160 | let { |
| 161 | children, |
| 162 | isSubmenu, |
| 163 | hasOpenSubmenu, |
| 164 | parentMenuTreeState, |
| 165 | rootMenuTriggerState, |
| 166 | onBackButtonPress, |
| 167 | wrapperKeyDown, |
| 168 | menuRef |
| 169 | } = props; |
| 170 | let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/menu'); |
| 171 | let lastKey = rootMenuTriggerState?.expandedKeysStack.slice(-1)[0]; |
| 172 | let backButtonText = ''; |
| 173 | if (lastKey != null) { |
| 174 | backButtonText = parentMenuTreeState?.collection.getItem(lastKey)?.textValue ?? ''; |
| 175 | } |
| 176 | let backButtonLabel = stringFormatter.format('backButton', { |
| 177 | prevMenuButton: backButtonText ?? '' |
| 178 | }); |
| 179 | let headingId = useSlotId(); |
| 180 | let isMobile = useIsMobileDevice(); |
| 181 | let {direction} = useLocale(); |
| 182 | |
| 183 | let [traySubmenuAnimation, setTraySubmenuAnimation] = useState(''); |
| 184 | useLayoutEffect(() => { |
| 185 | if (!hasOpenSubmenu) { |
| 186 | setTraySubmenuAnimation('spectrum-TraySubmenu-enter'); |
| 187 | } |
| 188 | }, [hasOpenSubmenu, isMobile]); |
| 189 | |
| 190 | let timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null); |
| 191 | let handleBackButtonPress = () => { |
| 192 | setTraySubmenuAnimation('spectrum-TraySubmenu-exit'); |
| 193 | timeoutRef.current = setTimeout(() => { |
| 194 | onBackButtonPress?.(); |
| 195 | }, 220); // Matches transition duration |
| 196 | }; |
| 197 | |
| 198 | useEffect(() => { |
| 199 | return () => { |
| 200 | if (timeoutRef.current) { |
| 201 | clearTimeout(timeoutRef.current); |
| 202 | } |
| 203 | }; |
| 204 | }, []); |
| 205 | |
| 206 | // When opening submenu in tray, focus the first item in the submenu after animation completes |
| 207 | // This fixes an issue with iOS VO where the closed submenu was getting focus |
nothing calls this directly
no test coverage detected