-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat] Chip 컴포넌트 추가 #70
Changes from 1 commit
e1dd273
f5c6800
4854aaa
64ed2f0
2723924
3e658fa
7fd96a6
864fd71
30b4f41
292f9ff
53c6460
e525e1f
6b1071e
2b85c0d
2b40867
b076748
b0fec2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,9 @@ | ||
import { ComponentPropsWithoutRef, forwardRef, ReactElement } from 'react'; | ||
import { addonRootRecipe, chipCloseButtonRecipe, chipRecipe } from './Chip.css'; | ||
import { Icon } from '../Icon/Icon'; | ||
import { Text } from '../Text/Text'; | ||
import { ChipIcon } from './ChipIcon'; | ||
import { ChipItem } from './ChipItem'; | ||
|
||
export type ButtonVariant = 'grey' | 'purple' | 'green'; | ||
export const Chip = Object.assign(ChipItem, { | ||
Icon: ChipIcon, | ||
}); | ||
|
||
export type ChipProps = ComponentPropsWithoutRef<'span'> & { | ||
variant: ButtonVariant; | ||
leftAddon?: ReactElement; | ||
rightAddon?: ReactElement; | ||
closable?: boolean; | ||
onClose?: () => void; | ||
}; | ||
|
||
export const Chip = forwardRef<HTMLSpanElement, ChipProps>( | ||
({ | ||
className = '', | ||
variant, | ||
leftAddon, | ||
rightAddon, | ||
closable = false, | ||
children, | ||
onClose, | ||
...rest | ||
}) => { | ||
return ( | ||
<span className={`${chipRecipe({ variant })} ${className}`} {...rest}> | ||
{leftAddon && ( | ||
<span className={addonRootRecipe({ color: variant })}> | ||
{leftAddon} | ||
</span> | ||
)} | ||
<Text fontSize={16} fontWeight="semibold"> | ||
{children} | ||
</Text> | ||
{rightAddon && ( | ||
<span className={addonRootRecipe({ color: variant })}> | ||
{rightAddon} | ||
</span> | ||
)} | ||
{closable && ( | ||
<button | ||
type="button" | ||
aria-label="Close" | ||
className={chipCloseButtonRecipe({ clickable: closable })} | ||
onClick={onClose} | ||
> | ||
<Icon | ||
name="x" | ||
size="1.6rem" | ||
type="stroke" | ||
strokeWidth={'0.244rem'} | ||
color={`${variant}400`} | ||
/> | ||
</button> | ||
)} | ||
</span> | ||
); | ||
} | ||
); | ||
export type { ChipProps } from './ChipItem'; | ||
export type { ChipIconProps } from './ChipIcon'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ColorsType } from '@repo/theme'; | ||
import { Icon, IconProps } from '../Icon/Icon'; | ||
import { ButtonVariant } from './ChipItem'; | ||
|
||
export type ChipIconProps = { | ||
variant: ButtonVariant; | ||
name?: IconProps['name']; | ||
type?: IconProps['type']; | ||
} & Omit<IconProps, 'color' | 'name' | 'type'>; | ||
|
||
const color: Record<ButtonVariant, keyof ColorsType> = { | ||
grey: 'grey600', | ||
purple: 'purple800', | ||
green: 'green800', | ||
}; | ||
|
||
export function ChipIcon({ | ||
variant, | ||
name = 'circle', | ||
type = 'fill', | ||
...rest | ||
}: ChipIconProps) { | ||
return <Icon name={name} type={type} color={color[variant]} {...rest} />; | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,54 @@ | ||||||
import { ComponentPropsWithoutRef, forwardRef, ReactElement } from 'react'; | ||||||
import { chipCloseButtonRecipe, chipRecipe } from './Chip.css'; | ||||||
import { Icon } from '../Icon/Icon'; | ||||||
import { Text } from '../Text/Text'; | ||||||
import { isNil } from '../../utils'; | ||||||
|
||||||
export type ButtonVariant = 'grey' | 'purple' | 'green'; | ||||||
|
||||||
export type ChipProps = ComponentPropsWithoutRef<'span'> & { | ||||||
variant: ButtonVariant; | ||||||
leftAddon?: ReactElement; | ||||||
rightAddon?: ReactElement; | ||||||
closable?: boolean; | ||||||
onClose?: () => void; | ||||||
}; | ||||||
|
||||||
export const ChipItem = forwardRef<HTMLSpanElement, ChipProps>( | ||||||
({ | ||||||
className = '', | ||||||
variant, | ||||||
leftAddon, | ||||||
rightAddon, | ||||||
closable = false, | ||||||
children, | ||||||
onClose, | ||||||
...rest | ||||||
}) => { | ||||||
return ( | ||||||
<span className={`${chipRecipe({ variant })} ${className}`} {...rest}> | ||||||
{leftAddon} | ||||||
<Text fontSize={16} fontWeight="semibold"> | ||||||
{children} | ||||||
</Text> | ||||||
{rightAddon} | ||||||
{isNil(closable) && ( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. closable 로직 문제 -{isNil(closable) && (
+{closable && (
<button
type="button"
aria-label="Close"
...
>
...
</button>
)} 📝 Committable suggestion
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. closable하지 않으면 close 버튼을 띄워주는 것이 아니라 반대가 아닌가요?.? 그리고 이미 closable은 boolean 값이라 nullish 체크를 별도로 할 필요가 없어요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아아 저 방금 발견해서 수정했습니다 다시 확인 부탁드려요! |
||||||
<button | ||||||
type="button" | ||||||
aria-label="Close" | ||||||
className={chipCloseButtonRecipe({ clickable: closable })} | ||||||
onClick={onClose} | ||||||
> | ||||||
<Icon | ||||||
name="x" | ||||||
size="1.6rem" | ||||||
type="stroke" | ||||||
strokeWidth={'0.244rem'} | ||||||
color={`${variant}400`} | ||||||
/> | ||||||
</button> | ||||||
)} | ||||||
</span> | ||||||
); | ||||||
} | ||||||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기다가 !isNil 다는 것이 좋지 않을까 리뷰 드렸었어요! isNotNil은 제가 다른 브랜치에 만들어놔서, 그 브랜치 반영되면 추후에 수정해둘게요!