Utilities
ToggleGroupUtils
: Utilities related to primitives with a toggle group.EmptyGestureResponderEvent
: Used for callingonPress
andonLongPress
without any arguments for accessibility purposes.
component. -->
A collection of utilities for core primitives.
Utilities
ToggleGroupUtils
: Utilities related to primitives with a toggle group.EmptyGestureResponderEvent
: Used for calling onPress
and onLongPress
without any arguments for accessibility purposes.Install the component via your command line.
npx expo install @rn-primitives/utils
Copy/paste the following code to ~/components/primitives/utils.tsx
import type { GestureResponderEvent } from 'react-native';
const ToggleGroupUtils = { getIsSelected(value: string | string[] | undefined, itemValue: string) { if (value === undefined) { return false; } if (typeof value === 'string') { return value === itemValue; } return value.includes(itemValue); }, getNewSingleValue(originalValue: string | string[] | undefined, itemValue: string) { if (originalValue === itemValue) { return undefined; } return itemValue; }, getNewMultipleValue(originalValue: string | string[] | undefined, itemValue: string) { if (originalValue === undefined) { return [itemValue]; } if (typeof originalValue === 'string') { return originalValue === itemValue ? [] : [originalValue, itemValue]; } if (originalValue.includes(itemValue)) { return originalValue.filter((v) => v !== itemValue); } return [...originalValue, itemValue]; },};
const EmptyGestureResponderEvent: GestureResponderEvent = { nativeEvent: { changedTouches: [], identifier: '0', locationX: 0, locationY: 0, pageX: 0, pageY: 0, target: '0', timestamp: 0, touches: [], }, bubbles: false, cancelable: false, currentTarget: {} as any, defaultPrevented: false, eventPhase: 0, persist: () => {}, isDefaultPrevented: () => false, isPropagationStopped: () => false, isTrusted: false, preventDefault: () => {}, stopPropagation: () => {}, target: {} as any, timeStamp: 0, type: '',};
export { ToggleGroupUtils, EmptyGestureResponderEvent };
getIsSelected
: Returns true if the item is selected.getNewSingleValue
: Returns the new value for a single toggle group.getNewMultipleValue
: Returns the new value for a multiple toggle group.import { ToggleGroupUtils } from '@rn-primitives/hooks';import type { PressableRef, SlottablePressableProps } from '@rn-primitives/types';
const Item = React.forwardRef<PressableRef, SlottablePressableProps>( ( { value: itemValue, onPress: onPressProp, ...props }, ref ) => { const { type, value, onValueChange } = useRootContext();
function onPress(ev: GestureResponderEvent) { if (type === 'single') { onValueChange(ToggleGroupUtils.getNewSingleValue(value, itemValue)); } if (type === 'multiple') { onValueChange(ToggleGroupUtils.getNewMultipleValue(value, itemValue)); } onPressProp?.(ev); }
const isChecked = type === 'single' ? ToggleGroupUtils.getIsSelected(value, itemValue) : undefined; const isSelected = type === 'multiple' ? ToggleGroupUtils.getIsSelected(value, itemValue) : undefined;
return ( <Pressable ref={ref} role={type === 'single' ? 'radio' : 'checkbox'} onPress={onPress} aria-checked={isChecked} aria-selected={isSelected} accessibilityState={{ checked: isChecked, selected: isSelected, }} {...props} /> </ItemContext.Provider> ); });
import { EmptyGestureResponderEvent } from '@rn-primitives/hooks';import type { PressableRef, SlottablePressableProps } from '@rn-primitives/types';
const Item = React.forwardRef<PressableRef, SlottablePressableProps>( ({ onPress: onPressProp, onKeyDown: onKeyDownProp, ...props }, ref) => {
function onKeyDown(ev: React.KeyboardEvent) { if (ev.key === 'Enter' || ev.key === ' ') { onKeyDownProp?.(ev); onPressProp?.(EmptyGestureResponderEvent); console.log("onKeyDown Enter or Space"); } }
function onPress(ev: GestureResponderEvent) { onPressProp?.(ev); console.log("onPress"); }
const Component = asChild ? Slot.Pressable : Pressable; return ( <Pressable ref={ref} onPress={onPress} onKeyDown={onKeyDown} {...props} /> ); });