Toggle Primitive
A button with a true or false state, which can be activated or deactivated by toggling.
Installation
Install the component via your command line.
npx expo install @rn-primitives/toggle
Install @radix-ui/react-toggle
npx expo install @radix-ui/react-toggle
Copy/paste the following code for web to ~/components/primitives/toggle/toggle.web.tsx
import * as Toggle from '@radix-ui/react-toggle';import * as Slot from '~/components/primitives/slot';import * as React from 'react';import { Pressable, type GestureResponderEvent } from 'react-native';import type { RootProps, RootRef } from './types';
const Root = React.forwardRef<RootRef, RootProps>( ({ asChild, pressed, onPressedChange, disabled, onPress: onPressProp, ...props }, ref) => { function onPress(ev: GestureResponderEvent) { onPressProp?.(ev); onPressedChange(!pressed); }
const Component = asChild ? Slot.Pressable : Pressable; return ( <Toggle.Root pressed={pressed} onPressedChange={onPressedChange} disabled={disabled} asChild> <Component ref={ref} onPress={onPress} disabled={disabled} role='button' {...props} /> </Toggle.Root> ); });
Root.displayName = 'RootWebToggle';
export { Root };
Copy/paste the following code for native to ~/components/primitives/toggle/toggle.tsx
import * as Slot from '~/components/primitives/slot';import * as React from 'react';import { Pressable, type GestureResponderEvent } from 'react-native';import type { RootProps, RootRef } from './types';
const Root = React.forwardRef<RootRef, RootProps>( ({ asChild, pressed, onPressedChange, disabled, onPress: onPressProp, ...props }, ref) => { function onPress(ev: GestureResponderEvent) { if (disabled) return; const newValue = !pressed; onPressedChange(newValue); onPressProp?.(ev); }
const Component = asChild ? Slot.Pressable : Pressable; return ( <Component ref={ref} aria-disabled={disabled} role='switch' aria-selected={pressed} onPress={onPress} accessibilityState={{ selected: pressed, disabled, }} disabled={disabled} {...props} /> ); });
Root.displayName = 'RootNativeToggle';
export { Root };
Copy/paste the following code for types to ~/components/primitives/toggle/types.ts
import type { PressableRef, SlottablePressableProps } from '~/components/primitives/types';
type RootProps = SlottablePressableProps & { pressed: boolean; onPressedChange: (pressed: boolean) => void; disabled?: boolean;};
type RootRef = PressableRef;
export type { RootProps, RootRef };
Copy/paste the following code for exporting to ~/components/primitives/toggle/index.ts
export * from './toggle';export * from './types';
Copy/paste the following code for native to ~/components/primitives/toggle/index.tsx
import * as Slot from '~/components/primitives/slot';import * as React from 'react';import { Pressable, type GestureResponderEvent } from 'react-native';import type { RootProps, RootRef } from './types';
const Root = React.forwardRef<RootRef, RootProps>( ({ asChild, pressed, onPressedChange, disabled, onPress: onPressProp, ...props }, ref) => { function onPress(ev: GestureResponderEvent) { if (disabled) return; const newValue = !pressed; onPressedChange(newValue); onPressProp?.(ev); }
const Component = asChild ? Slot.Pressable : Pressable; return ( <Component ref={ref} aria-disabled={disabled} role='switch' aria-selected={pressed} onPress={onPress} accessibilityState={{ selected: pressed, disabled, }} disabled={disabled} {...props} /> ); });
Root.displayName = 'RootNativeToggle';
export { Root };
Copy/paste the following code for types to ~/components/primitives/toggle/types.ts
import type { PressableRef, SlottablePressableProps } from '~/components/primitives/types';
type RootProps = SlottablePressableProps & { pressed: boolean; onPressedChange: (pressed: boolean) => void; disabled?: boolean;};
type RootRef = PressableRef;
export type { RootProps, RootRef };
Usage
import * as React from 'react';import { Text } from 'react-native';import * as TogglePrimitive from '@rn-primitives/toggle';
function Example() { const [isActive, setIsActive] = React.useState(false); return ( <TogglePrimitive.Root pressed={isActive} onPressedChange={setIsActive}> <Text>Bold</Text> </TogglePrimitive.Root> );}
Props
Root
Extends Pressable
props
Prop | Type | Note |
---|---|---|
pressed | boolean | |
onPressedChange | (val: boolean) => void | |
asChild | boolean | (optional) |
disabled | boolean | (optional) |