Skip to content

Commit

Permalink
Merge pull request #34 from cobaltinc/park/deletable-chip
Browse files Browse the repository at this point in the history
Chip 에 onDelete prop 추가했다
  • Loading branch information
kciter authored Sep 15, 2023
2 parents ea98191 + 6f46930 commit 349489a
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 9 deletions.
53 changes: 46 additions & 7 deletions packages/co-design-core/src/components/Chips/Chip.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@ export const sizes = {
xlarge: 40,
};

const iconSizes = {
const checkIconSizes = {
xsmall: 10,
small: 12,
medium: 14,
large: 16,
xlarge: 18,
};

const closeIconSizes = {
xsmall: 14,
small: 16,
medium: 18,
large: 20,
xlarge: 22,
};

const padding = {
xsmall: 16,
small: 20,
Expand All @@ -33,6 +41,14 @@ const checkedPadding = {
xlarge: 15,
};

const deletablePadding = {
xsmall: 7.5,
small: 10,
medium: 11.5,
large: 13,
xlarge: 15,
};

interface ChipStyles {
radius: CoRadius | number;
size: CoSize;
Expand Down Expand Up @@ -72,15 +88,26 @@ export default createStyles((theme, { radius, size, color }: ChipStyles, getRef)
},
},

iconWrapper: {
checkWrapper: {
display: 'inline-block',
verticalAlign: 'middle',
ref: iconWrapper,
color: theme.palettes[color][theme.colorScheme === 'dark' ? 3 : 5],
width: getFieldValue(size, iconSizes),
maxWidth: getFieldValue(size, iconSizes),
height: getFieldValue(size, iconSizes),
width: getFieldValue(size, checkIconSizes),
maxWidth: getFieldValue(size, checkIconSizes),
height: getFieldValue(size, checkIconSizes),
marginRight: theme.spacing.small,
overflow: 'hidden',
},

closeWrapper: {
display: 'inline-block',
verticalAlign: 'middle',
ref: iconWrapper,
width: getFieldValue(size, closeIconSizes),
maxWidth: getFieldValue(size, closeIconSizes),
height: getFieldValue(size, closeIconSizes),
marginLeft: theme.spacing.small,
overflow: 'hidden',
},

Expand All @@ -103,11 +130,23 @@ export default createStyles((theme, { radius, size, color }: ChipStyles, getRef)
paddingLeft: getFieldValue(size, checkedPadding),
paddingRight: getFieldValue(size, checkedPadding),
border: `1px solid ${theme.palettes[color][theme.colorScheme === 'dark' ? 3 : 5]}`,
color: theme.palettes[color][theme.colorScheme === 'dark' ? 3 : 5],
},

deletable: {
paddingLeft: getFieldValue(size, deletablePadding),
paddingRight: getFieldValue(size, deletablePadding),
},

checkIcon: {
width: getFieldValue(size, iconSizes),
height: getFieldValue(size, iconSizes) / 1.1,
width: getFieldValue(size, checkIconSizes),
height: getFieldValue(size, checkIconSizes) / 1.1,
display: 'block',
},

deleteIcon: {
width: getFieldValue(size, closeIconSizes),
height: getFieldValue(size, closeIconSizes) / 1.1,
display: 'block',
},

Expand Down
19 changes: 17 additions & 2 deletions packages/co-design-core/src/components/Chips/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CoComponentProps, CoPalette, CoSize, CoRadius, useCoTheme, ClassNames }
import { View } from '../View';
import { CheckboxIcon } from './CheckboxIcon';
import useStyles from './Chip.style';
import CloseIcon from './CloseIcon';

export type ChipStylesNames = ClassNames<typeof useStyles>;

Expand Down Expand Up @@ -55,6 +56,10 @@ export interface ChipProps extends CoComponentProps<ChipStylesNames>, Omit<React
*/
onChange?(checked: boolean): void;

/**
* Chip 에 Delete Icon 을 추가하고, 클릭 시 onDelete 함수가 실행됩니다.
*/
onDelete?(): void;
__staticSelector?: string;
}

Expand All @@ -74,6 +79,7 @@ export const Chip = forwardRef<HTMLInputElement, ChipProps>(
checked,
defaultChecked,
onChange,
onDelete,
co,
overrideStyles,
...props
Expand All @@ -83,6 +89,7 @@ export const Chip = forwardRef<HTMLInputElement, ChipProps>(
const uuid = useId(id);
const theme = useCoTheme();
const _color = color || theme.primaryColor;

const { classes, cx } = useStyles({ radius, size, color: _color }, { overrideStyles, name: __staticSelector });

const [value, setValue] = useUncontrolled({
Expand All @@ -105,13 +112,21 @@ export const Chip = forwardRef<HTMLInputElement, ChipProps>(
ref={ref}
{...props}
/>
<label htmlFor={uuid} className={cx(classes.label, { [classes.checked]: value, [classes.disabled]: disabled })}>
<label
htmlFor={uuid}
className={cx(classes.label, { [classes.checked]: value, [classes.disabled]: disabled, [classes.deletable]: !!onDelete })}
>
{value && (
<span className={classes.iconWrapper}>
<span className={classes.checkWrapper}>
<CheckboxIcon indeterminate={false} className={classes.checkIcon} />
</span>
)}
{children}
{onDelete && (
<span className={classes.closeWrapper} onClick={onDelete}>
<CloseIcon className={classes.deleteIcon} />
</span>
)}
</label>
</View>
);
Expand Down
13 changes: 13 additions & 0 deletions packages/co-design-core/src/components/Chips/CloseIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import type { SVGProps } from 'react';

const CloseIcon = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" {...props}>
<path
fill="currentColor"
d="M17.65 7.06 16.59 6l-4.76 4.77L7.06 6 6 7.06l4.77 4.77L6 16.59l1.06 1.06 4.77-4.76 4.76 4.76 1.06-1.06-4.76-4.76 4.76-4.77Z"
/>
</svg>
);

export default CloseIcon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useState } from 'react';
import { Chip } from '../Chip';
import { Chips } from '../Chips';

export default {
title: '@co-design/core/Chip',
component: Chip,
argTypes: {
size: {
options: ['xsmall', 'small', 'medium', 'large', 'xlarge'],
control: { type: 'inline-radio' },
},
color: {
options: ['purple', 'gray', 'red', 'blue', 'orange', 'green'],
control: { type: 'inline-radio' },
},
radius: {
options: ['small', 'medium', 'large', 'round'],
control: { type: 'inline-radio' },
},
checked: {
control: { type: 'boolean' },
},
},
args: {
size: 'small',
color: 'purple',
radius: 'medium',
},
};

export const Default = {
render: (props) => {
return <Chip {...props}>React</Chip>;
},
};

export const Deletable = {
render: (props) => {
const [chips, setChips] = useState(['React', 'Angular', 'Svelte', 'Vue']);
return (
<Chips>
{chips.map((chip) => (
<Chip
key={chip}
value={chip}
radius={props.radius}
size={props.size}
onDelete={() => {
setChips(chips.filter((c) => c !== chip));
}}
>
{chip}
</Chip>
))}
</Chips>
);
},
};

0 comments on commit 349489a

Please sign in to comment.