forked from cerc-io/snowballtools-base
⚡️ feat: create checkbox component
This commit is contained in:
parent
f31ee7349f
commit
5e3a6ad2b5
@ -0,0 +1,68 @@
|
|||||||
|
import { tv, type VariantProps } from 'tailwind-variants';
|
||||||
|
|
||||||
|
export const getCheckboxVariant = tv({
|
||||||
|
slots: {
|
||||||
|
wrapper: ['group', 'flex', 'gap-3'],
|
||||||
|
indicator: [
|
||||||
|
'grid',
|
||||||
|
'place-content-center',
|
||||||
|
'text-transparent',
|
||||||
|
'group-hover:text-controls-disabled',
|
||||||
|
'focus-visible:text-controls-disabled',
|
||||||
|
'group-focus-visible:text-controls-disabled',
|
||||||
|
'data-[state=checked]:text-elements-on-primary',
|
||||||
|
'data-[state=checked]:group-focus-visible:text-elements-on-primary',
|
||||||
|
'data-[state=indeterminate]:text-elements-on-primary',
|
||||||
|
'data-[state=checked]:data-[disabled]:text-elements-on-disabled-active',
|
||||||
|
],
|
||||||
|
icon: ['w-3', 'h-3', 'stroke-current', 'text-current'],
|
||||||
|
input: [
|
||||||
|
'h-5',
|
||||||
|
'w-5',
|
||||||
|
'group',
|
||||||
|
'border',
|
||||||
|
'border-border-interactive/10',
|
||||||
|
'bg-controls-tertiary',
|
||||||
|
'rounded-md',
|
||||||
|
'transition-all',
|
||||||
|
'duration-150',
|
||||||
|
'focus-ring',
|
||||||
|
'shadow-button',
|
||||||
|
'group-hover:border-border-interactive/[0.14]',
|
||||||
|
'group-hover:bg-controls-tertiary',
|
||||||
|
'data-[state=checked]:bg-controls-primary',
|
||||||
|
'data-[state=checked]:hover:bg-controls-primary-hovered',
|
||||||
|
'data-[state=checked]:focus-visible:bg-controls-primary-hovered',
|
||||||
|
'data-[disabled]:bg-controls-disabled',
|
||||||
|
'data-[disabled]:shadow-none',
|
||||||
|
'data-[disabled]:hover:border-border-interactive/10',
|
||||||
|
'data-[disabled]:cursor-not-allowed',
|
||||||
|
'data-[state=checked]:data-[disabled]:bg-controls-disabled-active',
|
||||||
|
],
|
||||||
|
label: [
|
||||||
|
'text-sm',
|
||||||
|
'tracking-[-0.006em]',
|
||||||
|
'text-elements-high-em',
|
||||||
|
'flex',
|
||||||
|
'flex-col',
|
||||||
|
'gap-1',
|
||||||
|
'px-1',
|
||||||
|
],
|
||||||
|
description: ['text-xs', 'text-elements-low-em'],
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
disabled: {
|
||||||
|
true: {
|
||||||
|
wrapper: ['cursor-not-allowed'],
|
||||||
|
indicator: ['group-hover:text-current'],
|
||||||
|
input: [
|
||||||
|
'group-hover:border-border-interactive/[0.14]',
|
||||||
|
'group-hover:bg-controls-disabled',
|
||||||
|
],
|
||||||
|
label: ['cursor-not-allowed'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CheckboxVariants = VariantProps<typeof getCheckboxVariant>;
|
@ -0,0 +1,76 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import * as CheckboxRadix from '@radix-ui/react-checkbox';
|
||||||
|
import { type CheckboxProps as CheckboxRadixProps } from '@radix-ui/react-checkbox';
|
||||||
|
|
||||||
|
import { getCheckboxVariant, type CheckboxVariants } from './Checkbox.theme';
|
||||||
|
import { CheckIcon } from 'components/shared/CustomIcon';
|
||||||
|
|
||||||
|
interface CheckBoxProps extends CheckboxRadixProps, CheckboxVariants {
|
||||||
|
/**
|
||||||
|
* The label of the checkbox.
|
||||||
|
*/
|
||||||
|
label?: string;
|
||||||
|
/**
|
||||||
|
* The description of the checkbox.
|
||||||
|
*/
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checkbox component is used to allow users to select one or more items from a set.
|
||||||
|
* It is a wrapper around the `@radix-ui/react-checkbox` component.
|
||||||
|
*
|
||||||
|
* It accepts all the props from `@radix-ui/react-checkbox` component and the variants from the theme.
|
||||||
|
*
|
||||||
|
* It also accepts `label` and `description` props to display the label and description of the checkbox.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```tsx
|
||||||
|
* <Checkbox
|
||||||
|
* id="checkbox"
|
||||||
|
* label="Checkbox"
|
||||||
|
* description="This is a checkbox"
|
||||||
|
* />
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const Checkbox = ({
|
||||||
|
id,
|
||||||
|
className,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
onCheckedChange,
|
||||||
|
...props
|
||||||
|
}: CheckBoxProps) => {
|
||||||
|
const {
|
||||||
|
wrapper: wrapperStyle,
|
||||||
|
indicator: indicatorStyle,
|
||||||
|
icon: iconStyle,
|
||||||
|
input: inputStyle,
|
||||||
|
label: labelStyle,
|
||||||
|
description: descriptionStyle,
|
||||||
|
} = getCheckboxVariant({
|
||||||
|
disabled: props?.disabled,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div className={wrapperStyle()}>
|
||||||
|
<CheckboxRadix.Root
|
||||||
|
{...props}
|
||||||
|
className={inputStyle({ className })}
|
||||||
|
id={id}
|
||||||
|
onCheckedChange={onCheckedChange}
|
||||||
|
>
|
||||||
|
<CheckboxRadix.Indicator forceMount className={indicatorStyle()}>
|
||||||
|
<CheckIcon className={iconStyle()} />
|
||||||
|
</CheckboxRadix.Indicator>
|
||||||
|
</CheckboxRadix.Root>
|
||||||
|
{label && (
|
||||||
|
<label className={labelStyle()} htmlFor={id}>
|
||||||
|
{label}
|
||||||
|
{description && (
|
||||||
|
<span className={descriptionStyle()}>{description}</span>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1 @@
|
|||||||
|
export * from './Checkbox';
|
Loading…
Reference in New Issue
Block a user