-
Notifications
You must be signed in to change notification settings - Fork 1
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 컴포넌트 구현 #137
Merged
Merged
feat: Chip 컴포넌트 구현 #137
Changes from 7 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
af40b2e
.
fecapark 2314b28
.
fecapark 93435cf
Merge branch 'develop' into feat/#131-chip-component
fecapark c30003e
refactor: chip group의 gap을 token으로 수정
fecapark e1f71ad
feat: Chip, ChipGroup 컴포넌트 구현 완료
fecapark 03683ff
Merge branch 'develop' into feat/#131-chip-component
fecapark aae4094
feat: Chip 문서에서 ChipGroup 링크 생성
fecapark d8a8783
package: framer-motion 멸종
fecapark d8ac043
fix: mdx와 stories 컴포넌트 내용 불일치 수정
fecapark f7a49a2
fix: ChipGroup 자식 Gap을 10px로 고정
fecapark 38ea451
refactor: style prop이 2개 이상인 컴포넌트들에 대해 interface로 추출
fecapark c348404
Merge branch 'develop' into feat/#131-chip-component
fecapark File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
import { Canvas, Meta, Controls } from '@storybook/blocks'; | ||
import * as ChipStories from './Chip.stories'; | ||
|
||
<Meta of={ChipStories} /> | ||
|
||
# Chip | ||
|
||
Chip은 항목을 설명하는 키워드를 사용하여 항목에 레이블을 지정하거나 분류하거나 구성합니다. | ||
사용자는 칩을 통해 정보를 입력하거나 선택하여 콘텐츠를 필터링하거나 행동을 유발할 수 있습니다. | ||
|
||
<Canvas of={ChipStories.Control} /> | ||
<Controls /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
## ChipGroup | ||
|
||
둘 이상의 Chip들을 조작하는 UI를 구성하고 싶다면, <code><a style={{ textDecoration: "underline" }} href="/?path=/docs/components-chipgroup--docs#chipgroup" alt="ChipGroup">ChipGroup</a></code>을 사용하세요. | ||
|
||
<br /> | ||
<br /> | ||
|
||
## 사용법 | ||
|
||
Chip은 필수 프로퍼티로 `size` 와 `role` 을 받습니다. | ||
|
||
- `size`: 칩의 크기를 결정합니다. 값은 `small`, `medium`, `large` 중 하나입니다. | ||
- `role`: 칩의 용법을 결정합니다. 값은 `input`, `filter`, `suggestion` 중 하나입니다. | ||
|
||
```tsx | ||
import { Chip } from '@yourssu/design-system-react'; | ||
``` | ||
|
||
```tsx | ||
<Chip size="medium" role="suggestion"> | ||
칩 | ||
</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.DefaultUsage} withSource="none" /> | ||
|
||
### role | ||
|
||
Chip 컴포넌트는 `role` 프로퍼티를 통해 칩의 용법을 결정합니다. | ||
|
||
- `input`: 사용자가 입력한 개별적인 정보를 나타내기 위해 사용합니다. | ||
- `filter`: 콘텐츠를 필터링할 때 사용합니다. `ChipGroup` 과 함께 사용했을 때 다중선택이 가능합니다. | ||
- `suggestion`: 사용자가 선택할 수 있는 옵션을 제공할 때 사용합니다. `ChipGroup` 과 함께 사용했을 때 다중선택이 불가능합니다. | ||
|
||
또한, `filter` 와 `suggestion` 의 경우 기본적으로 사용자 인터랙션에 따른 스타일이 적용됩니다. | ||
|
||
```tsx | ||
<Chip size="medium" role="input">input</Chip> | ||
|
||
<Chip size="medium" role="filter">filter</Chip> | ||
|
||
<Chip size="medium" role="suggestion">suggestion</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.Role} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
### role : input | ||
|
||
role:input 으로 설정된 Chip 컴포넌트에서 | ||
사용자에게 인터랙션이 존재한다고 알려주어야 한다면, `onClick` 프로퍼티를 사용하세요. | ||
|
||
```tsx | ||
<Chip size="medium" role="input">No Interaction</Chip> | ||
|
||
<Chip size="medium" role="input" onClick={() => {}}>Can Interaction</Chip> | ||
|
||
<Chip size="medium" role="input" onClick={() => alert('클릭했습니다')}>Alert</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.RoleInput} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
### role : group | ||
|
||
단일 Chip 컴포넌트에 부여할 수 없습니다. | ||
|
||
단, `ChipGroup` 컴포넌트와 함께 사용할 때 반드시 부여해야합니다. | ||
|
||
`ChipGroup` 내부의 Chip 컴포넌트는 마운트시 `ChipGroup` 컴포넌트의 `role` 프로퍼티를 상속받습니다. | ||
|
||
```tsx | ||
<Chip size="medium" role="group"> | ||
❌ | ||
</Chip> | ||
|
||
|
||
<ChipGroup role="suggestion"> | ||
<Chip size="medium" role="group"> | ||
✅ | ||
</Chip> | ||
</ChipGroup> | ||
``` | ||
|
||
<br /> | ||
<br /> | ||
|
||
### 삭제 아이콘 | ||
|
||
`Chip.Remove` 컴포넌트를 선언하여 | ||
Chip 컴포넌트에 삭제 아이콘을 추가할 수 있습니다. | ||
|
||
삭제 아이콘의 위치는 JSX 상의 선언 위치에 관계없이 항상 Chip 컴포넌트의 마지막에 위치합니다. | ||
이를 보장하기 위해 칩의 콘텐츠 선언은 `Chip.Content` 컴포넌트로 감싸주는 것을 권장합니다. | ||
|
||
```tsx | ||
<Chip size="medium" role="group"> | ||
<Chip.Content>삭제 가능한 칩1</Chip.Content> | ||
<Chip.Remove /> | ||
</Chip> | ||
``` | ||
|
||
```tsx | ||
// ✅ Chip.Remove의 선언 위치에 상관없이 삭제 아이콘은 항상 마지막에 위치하게 됩니다. | ||
<Chip size="medium" role="group"> | ||
<Chip.Remove /> | ||
<Chip.Content>삭제 가능한 칩2</Chip.Content> | ||
</Chip> | ||
|
||
// ❌ 추천하지 않음 | ||
<Chip size="medium" role="group"> | ||
<Chip.Remove /> | ||
삭제 가능한 칩3 | ||
</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.RemovableChip} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
### 삭제 아이콘 : onClick | ||
|
||
삭제 아이콘에 클릭 이벤트를 부여하고 싶다면, `Chip.Remove` 컴포넌트에 `onClick` 프로퍼티를 사용하세요. | ||
|
||
```tsx | ||
const Component = () => { | ||
const onRemoveClick = (e: React.MouseEvent<HTMLDivElement>) => { | ||
const target = e.currentTarget as HTMLDivElement; | ||
const chip = target.closest('.chip') as HTMLDivElement; | ||
alert(`삭제되었습니다: ${chip?.dataset.chip}`); | ||
}; | ||
|
||
return ( | ||
<Chip size="medium" role="suggestion" data-chip="2024"> | ||
이벤트가 달린 삭제 가능한 칩 | ||
<Chip.Remove onClick={onRemoveClick} /> | ||
</Chip> | ||
); | ||
}; | ||
``` | ||
|
||
<Canvas of={ChipStories.EventRemovableChip} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
### 아이콘 추가 | ||
|
||
삭제 아이콘 외에도, Chip 컴포넌트에 원하는 아이콘을 추가할 수 있습니다. | ||
|
||
`Chip.Icon` 컴포넌트를 사용해주세요. | ||
|
||
```tsx | ||
<Chip size="medium" role="suggestion"> | ||
<Chip.Icon> | ||
<IcInfoCircleLine /> | ||
</Chip.Icon> | ||
<Chip.Content>아이콘 추가</Chip.Content> | ||
</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.IconChip} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
### 아이콘 추가 : position | ||
|
||
`Chip.Icon` 컴포넌트는 `position` 프로퍼티를 통해 아이콘의 위치를 결정할 수 있습니다. | ||
|
||
- `left`: 아이콘을 왼쪽에 배치합니다. | ||
- `right`: 아이콘을 오른쪽에 배치합니다. | ||
|
||
만약 `position` 프로퍼티를 선언하지 않는다면, 선언된 순서에 따라 아이콘의 위치가 결정됩니다. | ||
|
||
이 순서를 보장하기 위해 칩의 콘텐츠 선언은 `Chip.Content` 컴포넌트로 감싸주는 것을 권장합니다. | ||
|
||
```tsx | ||
<Chip size="medium" role="suggestion"> | ||
<Chip.Icon position="left"> | ||
<IcInfoCircleLine /> | ||
</Chip.Icon> | ||
<Chip.Icon position="right"> | ||
<IcArrowDownLine /> | ||
</Chip.Icon> | ||
<Chip.Icon position="right"> | ||
<IcArrowDownLine /> | ||
</Chip.Icon> | ||
<Chip.Content>아이콘 순서 변경</Chip.Content> | ||
</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.IconOrderChip} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
## 예시 | ||
|
||
### disabled | ||
|
||
인터랙션에 의한 Chip의 상태를 변경할 수 없도록 막습니다. | ||
|
||
```tsx | ||
<Chip size="medium" role="suggestion" disabled> | ||
변경 불가 | ||
</Chip> | ||
``` | ||
|
||
<Canvas of={ChipStories.ChipDisabled} withSource="none" /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
### 상태 전달 | ||
|
||
체크박스의 선택 여부를 외부에서 상태로 관리할 수 있게 합니다. | ||
|
||
```tsx | ||
const Component = () => { | ||
const [selected, setSelected] = useState(false); | ||
|
||
const onClick = () => { | ||
setSelected((prev) => !prev); | ||
}; | ||
|
||
return ( | ||
<Chip size="medium" role="suggestion" selected={selected} onClick={onClick}> | ||
상태 관리 칩 | ||
</Chip> | ||
); | ||
}; | ||
``` | ||
|
||
<Canvas of={ChipStories.StateManagement} withSource="none" /> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
framer-motion 왜 설치됐는지는 지난주 모각코에서 들어서 알고 있는데! 지금은 안 쓰니까 멸종시켜버리죠
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.
멸종시켰습니다!