️ feat: create checkbox component

This commit is contained in:
Wahyu Kurniawan 2024-02-20 18:24:28 +07:00
parent f31ee7349f
commit 5e3a6ad2b5
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33
3 changed files with 145 additions and 0 deletions

View File

@ -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>;

View File

@ -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>
);
};

View File

@ -0,0 +1 @@
export * from './Checkbox';