@gluestack-ui/core
Version:
Universal UI components for React Native, Expo, and Next.js
102 lines • 3.46 kB
JavaScript
import { getItemCount } from '@react-stately/collections';
import { isFocusVisible, useKeyboard } from '@react-aria/interactions';
import { useHover, usePress } from '@gluestack-ui/utils/aria';
import { mapDomPropsToRN } from '@gluestack-ui/utils/aria';
import { mergeProps, useSlotId } from '@react-aria/utils';
import { useSelectableItem } from '@react-aria/selection';
export function useMenuItem(props, state, ref) {
let { isSelected, isDisabled, key, onClose, closeOnSelect = true, isVirtualized, onAction, } = props;
let role = 'menuitem';
if (state.selectionManager.selectionMode === 'single') {
role = 'menuitemradio';
}
else if (state.selectionManager.selectionMode === 'multiple') {
role = 'menuitemcheckbox';
}
let labelId = useSlotId();
let descriptionId = useSlotId();
let keyboardId = useSlotId();
let ariaProps = {
'aria-disabled': isDisabled,
role,
'aria-label': props['aria-label'],
'aria-labelledby': labelId,
'aria-describedby': [descriptionId, keyboardId].filter(Boolean).join(' ') || undefined,
};
if (state.selectionManager.selectionMode !== 'none') {
ariaProps['aria-checked'] = isSelected;
}
if (isVirtualized) {
ariaProps['aria-posinset'] = state.collection.getItem(key).index;
ariaProps['aria-setsize'] = getItemCount(state.collection);
}
let onPressStart = (e) => {
if (e.pointerType === 'keyboard' && onAction) {
onAction(key);
}
};
let onPress = () => {
if (closeOnSelect && onClose) {
onClose();
}
};
let onPressUp = (e) => {
if (e.pointerType !== 'keyboard') {
if (onAction) {
onAction(key);
}
}
};
let { itemProps } = useSelectableItem({
selectionManager: state.selectionManager,
key,
ref,
shouldSelectOnPressUp: true,
});
let { pressProps } = usePress(mergeProps({ onPressStart, onPressUp, onPress, isDisabled }, mapDomPropsToRN(itemProps)));
let { hoverProps } = useHover({
isDisabled,
onHoverStart() {
if (!isFocusVisible()) {
state.selectionManager.setFocused(true);
state.selectionManager.setFocusedKey(key);
}
},
}, ref);
const { keyboardProps } = useKeyboard({
onKeyDown: (e) => {
if (e.repeat) {
e.continuePropagation();
return;
}
switch (e.key) {
case ' ':
if (!isDisabled && closeOnSelect && onClose) {
onClose();
}
break;
case 'Enter':
if (!isDisabled && closeOnSelect && onClose) {
onClose();
}
break;
default:
e.continuePropagation();
break;
}
},
});
return {
menuItemProps: Object.assign(Object.assign({}, mapDomPropsToRN(ariaProps)), mergeProps(pressProps, hoverProps, keyboardProps)),
labelProps: {
id: labelId,
},
descriptionProps: {
id: descriptionId,
},
keyboardShortcutProps: {
id: keyboardId,
},
};
}
//# sourceMappingURL=useMenuItem.web.js.map