Toggle
A two-state button that can be either on or off.
import { component$ } from '@builder.io/qwik';
import { Toggle } from '~/components/ui';
export default component$(() => {
return <Toggle>Hello</Toggle>;
});
In a world of endless choices, sometimes you just need a simple yes or no. The Qwik UI Styled Toggle component is a welcomed rest for the mind.
Installation
Run the following cli command or copy/paste the component code into your project
qwik-ui add toggle
import { component$, type PropsOf, Slot } from '@builder.io/qwik';
import { cn } from '@qwik-ui/utils';
import { cva, type VariantProps } from 'class-variance-authority';
import { Toggle as HeadlessToggle } from '@qwik-ui/headless';
export const toggleVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 aria-[pressed=true]:bg-primary aria-[pressed=true]:text-accent-foreground',
{
variants: {
look: {
default: 'border border-input bg-transparent',
outline:
'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',
},
size: {
default: 'h-10 px-3',
sm: 'h-9 px-2.5',
lg: 'h-11 px-5',
},
},
defaultVariants: {
look: 'default',
size: 'default',
},
},
);
type ToggleProps = PropsOf<typeof HeadlessToggle> & VariantProps<typeof toggleVariants>;
export const Toggle = component$<ToggleProps>(({ size, look, ...props }) => {
return (
<HeadlessToggle {...props} class={cn(toggleVariants({ size, look }), props.class)}>
<Slot />
</HeadlessToggle>
);
});
Usage
import { Toggle } from '~/components/ui';
<Toggle>Hello</Toggle
Usage / Component State
Initial Value (Uncontrolled)
An initial, uncontrolled value can be provided using the pressed
prop.
import { component$ } from '@builder.io/qwik';
import { Toggle } from '~/components/ui';
export default component$(() => {
return <Toggle pressed={true}>Hello</Toggle>;
});
If you want to have some control when the toggle is pressed, like making some side effect you can use
the onPressedChange$
. The event is fired when the user toggle the button, and receives the new value.
Unpress me
import { component$, useSignal } from '@builder.io/qwik';
import { Toggle } from '~/components/ui';
export default component$(() => {
const text = useSignal('Unpress me');
return (
<div class="flex flex-col">
<Toggle
pressed
onPressedChange$={(p) =>
p ? (text.value = 'Unpress me') : (text.value = 'Press me')
}
>
Hello
</Toggle>
<span>{text.value}</span>
</div>
);
});
Reactive Value (Controlled)
Pass a signal to bind:value
prop to make the pressed state controlled (binding the value with a signal).
You pressed me
import { component$, useComputed$, useSignal } from '@builder.io/qwik';
import { Toggle } from '~/components/ui';
export default component$(() => {
const pressedState = useSignal(true);
const text = useComputed$(() => {
return pressedState.value ? 'You pressed me' : 'You unpressed me';
});
return (
<div class="flex flex-col items-center justify-center">
<Toggle bind:pressed={pressedState} class="shrink-0">
Hello
</Toggle>
<span>{text.value}</span>
<button
style={{ border: '1px solid black', padding: '10px' }}
onClick$={() => (pressedState.value = true)}
>
I can only press
</button>
</div>
);
});
Disabled
Pass the disabled
prop.
import { component$ } from '@builder.io/qwik';
import { Toggle } from '~/components/ui';
export default component$(() => {
return <Toggle disabled>Hello</Toggle>;
});