Skip to content

Commit

Permalink
feat(ui/components): Checkbox 추가 (#326)
Browse files Browse the repository at this point in the history
* feat(ui/icons): CheckIcon 추가

* feat(ui/components): Checkbox 추가
  • Loading branch information
sukvvon authored Aug 22, 2024
1 parent 184bb8f commit db44ce0
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 1 deletion.
100 changes: 100 additions & 0 deletions packages/ui/src/components/checkbox/checkbox.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
createGlobalThemeContract,
createTheme,
style,
styleVariants,
} from '@vanilla-extract/css';
import { calc } from '@vanilla-extract/css-utils';
import { type RecipeVariants, recipe } from '@vanilla-extract/recipes';
import { alignItems, display, justifyContent } from '../../styles';
import { globalVars, paletteTokens } from '../../theme.css';

const color = styleVariants(paletteTokens, (_, paletteTokenKey) => ({
backgroundColor: globalVars.palette[paletteTokenKey],
}));

const borderColor = styleVariants(paletteTokens, (_, paletteTokenKey) => ({
borderColor: globalVars.palette[paletteTokenKey],
}));

const sizeTokens = {
'1': '1',
'2': '2',
'3': '3',
};

const sizeVars = createGlobalThemeContract(
sizeTokens,
(value) => `favolink-checkbox-size-${value}`,
);

const sizeClass = createTheme(sizeVars, {
'1': '16px',
'2': '24px',
'3': '32px',
});

const borderSizeVars = createGlobalThemeContract(
sizeTokens,
(value) => `favolink-checkbox-border-size-${value}`,
);

const borderSizeClass = createTheme(borderSizeVars, {
'1': '1px',
'2': '1.5px',
'3': '2px',
});

const size = styleVariants(sizeVars, (_, sizeKey) => ({
width: sizeVars[sizeKey],
height: sizeVars[sizeKey],
borderWidth: calc.multiply(borderSizeVars[sizeKey], 1.75),
borderRadius: calc.multiply(borderSizeVars[sizeKey], 3),
}));

const base = style([
sizeClass,
borderSizeClass,
display['inline-flex'],
alignItems.center,
justifyContent.center,
{
boxSizing: 'border-box',
padding: 0,
borderColor: globalVars.palette.gray800,
borderStyle: 'solid',

selectors: {
'&[data-state="false"]': {
backgroundColor: 'transparent',
},
},
},
]);

export const checkboxVariants = recipe({
base,

variants: {
color,
borderColor,
size,
},

defaultVariants: {
color: 'black',
borderColor: 'gray700',
size: '1',
},
});

export type CheckboxVariants = Exclude<
RecipeVariants<typeof checkboxVariants>,
undefined
>;

export const icon = style({
width: '100%',
height: '100%',
color: globalVars.palette.white,
});
42 changes: 42 additions & 0 deletions packages/ui/src/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as Styles from './checkbox.css';
import * as CheckboxPrimitive from './checkbox.primitive';
import { CheckIcon } from '../../icons';
import { type ComponentPropsWithout, forwardRef } from '../../system';
import { cx } from '../../utils';
import { type MarginVariants, extractMarginProps } from '../margin';

export type CheckboxProps = ComponentPropsWithout<
typeof CheckboxPrimitive.Root,
'asChild' | 'children' | 'color' | 'defaultValue'
> &
MarginVariants &
Styles.CheckboxVariants;

export const Checkbox = forwardRef<
CheckboxProps,
typeof CheckboxPrimitive.Root
>(function Checkbox(props, forwardedRef) {
const { className, color, borderColor, size, ...restProps } =
extractMarginProps(props);

return (
<CheckboxPrimitive.Root
data-accent-color={color ?? 'black'}
data-border-color={borderColor ?? 'gray700'}
{...restProps}
asChild={false}
ref={forwardedRef}
className={cx(
'favolink-checkbox',
Styles.checkboxVariants({ color, borderColor, size }),
className,
)}
>
<CheckboxPrimitive.Indicator asChild className={Styles.icon}>
<CheckIcon />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
);
});

Checkbox.displayName = 'Checkbox';
4 changes: 3 additions & 1 deletion packages/ui/src/components/checkbox/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/* eslint-disable @stylistic/padding-line-between-statements, react-refresh/only-export-components */
/* eslint-disable @stylistic/padding-line-between-statements */
export * as CheckboxPrimitive from './checkbox.primitive';

export { Checkbox, type CheckboxProps } from './checkbox';
10 changes: 10 additions & 0 deletions packages/ui/src/icons/check.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createIcon } from './icon';

export const CheckIcon = createIcon({
defaultProps: {
width: '1em',
height: '1em',
fill: 'currentColor',
},
d: 'M8.33268 11.6045L13.416 6.52116C13.5688 6.36838 13.7459 6.29199 13.9473 6.29199C14.1487 6.29199 14.3257 6.36838 14.4785 6.52116C14.6313 6.67394 14.7077 6.85102 14.7077 7.05241C14.7077 7.2538 14.6313 7.43088 14.4785 7.58366L8.85352 13.2087C8.70074 13.3614 8.52365 13.4378 8.32227 13.4378C8.12088 13.4378 7.94379 13.3614 7.79102 13.2087L5.52018 10.9378C5.3674 10.785 5.29102 10.608 5.29102 10.4066C5.29102 10.2052 5.3674 10.0281 5.52018 9.87533C5.67296 9.72255 5.85004 9.64616 6.05143 9.64616C6.25282 9.64616 6.4299 9.72255 6.58268 9.87533L8.33268 11.6045Z',
});
1 change: 1 addition & 0 deletions packages/ui/src/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from './add';
export * from './bell';
export * from './cancel';
export * from './check';
export * from './chevron-down';
export * from './chevron-left';
export * from './chevron-right';
Expand Down

0 comments on commit db44ce0

Please sign in to comment.