Skip to content

Commit

Permalink
Added checkbox component
Browse files Browse the repository at this point in the history
  • Loading branch information
jsimck committed Feb 24, 2024
1 parent 6227961 commit 44d1758
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-monkeys-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@utima/ui": minor
---

Added `Checkbox` component
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-aspect-ratio": "^1.0.3",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
Expand Down
29 changes: 29 additions & 0 deletions packages/ui/src/components/checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Meta, StoryObj } from '@storybook/react';

import { Checkbox } from './Checkbox';
import { Label } from '../label/Label';

const meta: Meta<typeof Checkbox> = {
component: Checkbox,
tags: ['autodocs'],
title: 'Components/Checkbox',
args: {
id: 'checkbox-id',
disabled: false,
required: false,
},
decorators: [
Story => (
<div className='flex items-center gap-2'>
<Story />
<Label htmlFor='checkbox-id'>Checkbox</Label>
</div>
),
],
};

export default meta;

type Story = StoryObj<typeof Checkbox>;

export const Basic: Story = {};
46 changes: 46 additions & 0 deletions packages/ui/src/components/checkbox/Checkbox.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { cva } from 'class-variance-authority';

import { twOverrides } from '@/overrides';

export const checkboxDef = twOverrides(
{
checkbox:
'peer transition-all shrink-0 rounded-sm border border-input-border focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 hover:bg-input-border/25',
indicator: 'flex items-center justify-center text-current',
icon: '',
iconSize: {
xs: 'h-2 w-2',
sm: 'h-3 w-3',
md: 'h-4 w-4',
lg: 'h-5 w-5',
},
variants: {
variant: {
primary:
'hover:data-[state=checked]:bg-primary/80 active:data-[state=checked]:bg-primary/90 data-[state=checked]:bg-primary data-[state=checked]:text-primary-fg data-[state=checked]:border-primary',
secondary:
'hover:data-[state=checked]:bg-secondary/80 active:data-[state=checked]:bg-secondary/90 data-[state=checked]:bg-secondary data-[state=checked]:text-secondary-fg data-[state=checked]:border-secondary',
muted:
'hover:data-[state=checked]:bg-muted/80 active:data-[state=checked]:bg-muted/90 data-[state=checked]:bg-muted data-[state=checked]:text-muted-fg data-[state=checked]border:text-muted',
success:
'hover:data-[state=checked]:bg-success/80 active:data-[state=checked]:bg-success/90 data-[state=checked]:bg-success data-[state=checked]:text-success-fg data-[state=checked]:border-success',
danger:
'hover:data-[state=checked]:bg-danger/80 active:data-[state=checked]:bg-danger/90 data-[state=checked]:bg-danger data-[state=checked]:text-danger-fg data-[state=checked]:border-danger',
warning:
'hover:data-[state=checked]:bg-warning/80 active:data-[state=checked]:bg-warning/90 data-[state=checked]:bg-warning data-[state=checked]:text-warning-fg data-[state=checked]:border-warning',
info: 'hover:data-[state=checked]:bg-info/80 active:data-[state=checked]:bg-info/90 data-[state=checked]:bg-info data-[state=checked]:text-info-fg data-[state=border]:text-info',
},
size: {
xs: 'h-3 w-3',
sm: 'h-4 w-4',
md: 'h-5 w-5',
lg: 'h-6 w-6',
},
},
},
'checkbox',
);

export const checkboxStyles = cva(checkboxDef.checkbox, {
variants: checkboxDef.variants,
});
32 changes: 32 additions & 0 deletions packages/ui/src/components/checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Root, Indicator } from '@radix-ui/react-checkbox';
import type { VariantProps } from 'class-variance-authority';
import { CheckIcon } from 'lucide-react';
import {
forwardRef,
type ElementRef,
type ComponentPropsWithoutRef,
} from 'react';

import { cn } from '@/utils';

import { checkboxDef, checkboxStyles } from './Checkbox.styles';

type CheckboxProps = ComponentPropsWithoutRef<typeof Root> &
Omit<VariantProps<typeof checkboxStyles>, 'thumbSize'>;

export const Checkbox = forwardRef<ElementRef<typeof Root>, CheckboxProps>(
({ className, variant = 'primary', size = 'md', ...props }, ref) => (
<Root
ref={ref}
className={cn(checkboxStyles({ variant, size }), className)}
{...props}
>
<Indicator className={cn(checkboxDef.indicator)}>
<CheckIcon
className={cn(checkboxDef.icon, size && checkboxDef.iconSize[size])}
strokeWidth={3}
/>
</Indicator>
</Root>
),
);
2 changes: 1 addition & 1 deletion packages/ui/src/components/input/Input.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { twOverrides } from '@/overrides';
export const inputDef = twOverrides(
{
input:
'transition-all text-input-fg font-normal flex w-full rounded-md border placeholder-placeholder bg-input ring-offset-input focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-input-border focus:ring-offset-1 focus-visible:border-input-fg disabled:cursor-not-allowed disabled:opacity-60',
'peer transition-all text-input-fg font-normal flex w-full rounded-md border placeholder-placeholder bg-input ring-offset-input focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-input-border focus:ring-offset-1 focus-visible:border-input-fg disabled:cursor-not-allowed disabled:opacity-60',
variants: {
size: {
xs: 'h-6 px-2 py-1.5 text-xs',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/label/Label.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { twOverrides } from '@/overrides';
export const labelDef = twOverrides(
{
label:
'text-foreground font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
'cursor-pointer text-foreground font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
variants: {
size: {
xs: 'text-xs leading-3',
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/switch/Switch.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { twOverrides } from '@/overrides';
export const switchDef = twOverrides(
{
switch:
'peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus:ring-2 focus:ring-offset-1 ring-input-border disabled:cursor-not-allowed disabled:opacity-65 data-[state=unchecked]:bg-input-fg/15 hover:data-[state=unchecked]:bg-input-fg/10',
'peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus:ring-2 focus:ring-offset-1 ring-input-border disabled:cursor-not-allowed disabled:opacity-65 data-[state=unchecked]:bg-muted hover:data-[state=unchecked]:bg-muted/80',
thumb:
'pointer-events-none block rounded-full bg-input shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0',
'pointer-events-none block rounded-full bg-input ring-0 transition-transform data-[state=unchecked]:translate-x-0',
thumbSize: {
xs: 'h-2 w-2 data-[state=checked]:translate-x-3',
sm: 'h-3 w-3 data-[state=checked]:translate-x-3',
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ export * as Popover from './components/popover';

// Separator
export { Separator } from './components/separator/Separator';

// Checkbox
export { Checkbox } from './components/checkbox/Checkbox';
2 changes: 2 additions & 0 deletions packages/ui/src/overrides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { aspectRatioDef } from './components/aspectRatio/AspectRatio.styles
import type { avatarDef } from './components/avatar/Avatar.styles';
import type { badgeDef } from './components/badge/Badge.styles';
import type { buttonDef } from './components/button/Button.styles';
import type { checkboxDef } from './components/checkbox/Checkbox.styles';
import type { dropdownDef } from './components/dropdown/Dropdown.styles';
import type { inputDef } from './components/input/Input.styles';
import type { labelDef } from './components/label/Label.styles';
Expand Down Expand Up @@ -36,6 +37,7 @@ type ComponentOverridesDef = {
dropdown: typeof dropdownDef;
popover: typeof popoverDef;
separator: typeof separatorDef;
checkbox: typeof checkboxDef;
};

export type ComponentOverrides = PartialDeep<ComponentOverridesDef>;
Expand Down

0 comments on commit 44d1758

Please sign in to comment.