Toggle
Toggle Primitive
Text Component
Terminal window
~/components/ui/toggle.tsx
Demo
A button with a true or false state, which can be activated or deactivated by toggling.
Installation
npx @react-native-reusables/cli@latest add toggle
Copy/paste the following code to ~/components/ui/toggle.tsx
:
import * as TogglePrimitive from '@rn-primitives/toggle';import { cva, type VariantProps } from 'class-variance-authority';import type { LucideIcon } from 'lucide-react-native';import * as React from 'react';import { cn } from '~/lib/utils';import { TextClassContext } from '~/components/ui/text';
const toggleVariants = cva( 'web:group web:inline-flex items-center justify-center rounded-md web:ring-offset-background web:transition-colors web:hover:bg-muted active:bg-muted web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2', { variants: { variant: { default: 'bg-transparent', outline: 'border border-input bg-transparent web:hover:bg-accent active:bg-accent active:bg-accent', }, size: { default: 'h-10 px-3 native:h-12 native:px-[12]', sm: 'h-9 px-2.5 native:h-10 native:px-[9]', lg: 'h-11 px-5 native:h-14 native:px-6', }, }, defaultVariants: { variant: 'default', size: 'default', }, });
const toggleTextVariants = cva('text-sm native:text-base text-foreground font-medium', { variants: { variant: { default: '', outline: 'web:group-hover:text-accent-foreground web:group-active:text-accent-foreground', }, size: { default: '', sm: '', lg: '', }, }, defaultVariants: { variant: 'default', size: 'default', },});
const Toggle = React.forwardRef< TogglePrimitive.RootRef, TogglePrimitive.RootProps & VariantProps<typeof toggleVariants>>(({ className, variant, size, ...props }, ref) => ( <TextClassContext.Provider value={cn( toggleTextVariants({ variant, size }), props.pressed ? 'text-accent-foreground' : 'web:group-hover:text-muted-foreground', className )} > <TogglePrimitive.Root ref={ref} className={cn( toggleVariants({ variant, size }), props.disabled && 'web:pointer-events-none opacity-50', props.pressed && 'bg-accent', className )} {...props} /> </TextClassContext.Provider>));
Toggle.displayName = TogglePrimitive.Root.displayName;
function ToggleIcon({ className, icon: Icon, ...props}: React.ComponentPropsWithoutRef<LucideIcon> & { icon: LucideIcon;}) { const textClass = React.useContext(TextClassContext); return <Icon className={cn(textClass, className)} {...props} />;}
export { Toggle, ToggleIcon, toggleTextVariants, toggleVariants };
Usage
import * as React from 'react';import { View } from 'react-native';import { Toggle, ToggleIcon } from '~/components/ui/toggle';import { Bold } from '~/lib/icons/Bold';
function Example() { const [pressed, setPressed] = React.useState(false); return ( <View className='flex-1 justify-center items-center p-6 gap-12'> <Toggle pressed={pressed} onPressedChange={setPressed} aria-label='Toggle bold' variant='outline' > <ToggleIcon icon={Bold} size={18} /> </Toggle> </View> );}
Props
Toggle
Extends Pressable
props
Prop | Type | Note |
---|---|---|
pressed | boolean | |
onPressedChange | (val: boolean) => void | |
asChild | boolean | (optional) |
disabled | boolean | (optional) |
variant | ’default’ | ‘outline’ | (optional) |
size | ’default’ | ‘sm’ | ‘lg’ | (optional) |
ToggleIcon
Extends LucideIcon
props
Prop | Type | Note |
---|---|---|
icon | LucideIcon |