@x-plat/design-system 0.4.6 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Accordion/index.cjs +4 -4
- package/dist/components/Accordion/index.css +11 -11
- package/dist/components/Accordion/index.js +4 -4
- package/dist/components/Alert/index.css +19 -19
- package/dist/components/Avatar/index.cjs +11 -5
- package/dist/components/Avatar/index.css +41 -11
- package/dist/components/Avatar/index.d.cts +1 -2
- package/dist/components/Avatar/index.d.ts +1 -2
- package/dist/components/Avatar/index.js +11 -5
- package/dist/components/Badge/index.cjs +3 -4
- package/dist/components/Badge/index.css +32 -19
- package/dist/components/Badge/index.d.cts +3 -2
- package/dist/components/Badge/index.d.ts +3 -2
- package/dist/components/Badge/index.js +3 -4
- package/dist/components/Breadcrumb/index.css +6 -6
- package/dist/components/Button/index.cjs +1 -3
- package/dist/components/Button/index.css +67 -23
- package/dist/components/Button/index.d.cts +2 -3
- package/dist/components/Button/index.d.ts +2 -3
- package/dist/components/Button/index.js +1 -3
- package/dist/components/Calendar/index.cjs +10 -10
- package/dist/components/Calendar/index.css +51 -52
- package/dist/components/Calendar/index.d.cts +3 -3
- package/dist/components/Calendar/index.d.ts +3 -3
- package/dist/components/Calendar/index.js +10 -10
- package/dist/components/Card/index.css +6 -6
- package/dist/components/CardTab/index.css +28 -28
- package/dist/components/Chart/index.cjs +228 -14548
- package/dist/components/Chart/index.css +57 -0
- package/dist/components/Chart/index.d.cts +3 -2
- package/dist/components/Chart/index.d.ts +3 -2
- package/dist/components/Chart/index.js +219 -14541
- package/dist/components/CheckBox/index.cjs +13 -8
- package/dist/components/CheckBox/index.css +50 -27
- package/dist/components/CheckBox/index.d.cts +3 -2
- package/dist/components/CheckBox/index.d.ts +3 -2
- package/dist/components/CheckBox/index.js +13 -8
- package/dist/components/Chip/index.cjs +1 -3
- package/dist/components/Chip/index.css +35 -23
- package/dist/components/Chip/index.d.cts +2 -3
- package/dist/components/Chip/index.d.ts +2 -3
- package/dist/components/Chip/index.js +1 -3
- package/dist/components/DatePicker/index.cjs +37 -46
- package/dist/components/DatePicker/index.css +175 -122
- package/dist/components/DatePicker/index.d.cts +2 -3
- package/dist/components/DatePicker/index.d.ts +2 -3
- package/dist/components/DatePicker/index.js +37 -46
- package/dist/components/Divider/index.css +2 -2
- package/dist/components/Drawer/index.css +7 -7
- package/dist/components/Dropdown/index.css +10 -10
- package/dist/components/EmptyState/index.css +8 -9
- package/dist/components/FileUpload/index.cjs +4 -4
- package/dist/components/FileUpload/index.css +13 -14
- package/dist/components/FileUpload/index.js +4 -4
- package/dist/components/HtmlTypeWriter/index.cjs +10 -10
- package/dist/components/HtmlTypeWriter/index.css +3 -3
- package/dist/components/HtmlTypeWriter/index.js +10 -10
- package/dist/components/ImageSelector/index.cjs +4 -4
- package/dist/components/ImageSelector/index.css +15 -15
- package/dist/components/ImageSelector/index.js +4 -4
- package/dist/components/Input/index.css +37 -26
- package/dist/components/Modal/index.css +5 -4
- package/dist/components/Pagination/index.cjs +9 -10
- package/dist/components/Pagination/index.css +37 -26
- package/dist/components/Pagination/index.d.cts +3 -2
- package/dist/components/Pagination/index.d.ts +3 -2
- package/dist/components/Pagination/index.js +9 -10
- package/dist/components/PopOver/index.css +3 -3
- package/dist/components/Progress/index.cjs +4 -5
- package/dist/components/Progress/index.css +23 -9
- package/dist/components/Progress/index.d.cts +3 -2
- package/dist/components/Progress/index.d.ts +3 -2
- package/dist/components/Progress/index.js +4 -5
- package/dist/components/Radio/index.cjs +3 -4
- package/dist/components/Radio/index.css +61 -29
- package/dist/components/Radio/index.d.cts +3 -2
- package/dist/components/Radio/index.d.ts +3 -2
- package/dist/components/Radio/index.js +3 -4
- package/dist/components/Select/index.cjs +4 -4
- package/dist/components/Select/index.css +46 -40
- package/dist/components/Select/index.js +4 -4
- package/dist/components/Skeleton/index.css +3 -3
- package/dist/components/Spinner/index.cjs +2 -3
- package/dist/components/Spinner/index.css +22 -8
- package/dist/components/Spinner/index.d.cts +3 -2
- package/dist/components/Spinner/index.d.ts +3 -2
- package/dist/components/Spinner/index.js +2 -3
- package/dist/components/Steps/index.cjs +8 -9
- package/dist/components/Steps/index.css +77 -22
- package/dist/components/Steps/index.d.cts +3 -2
- package/dist/components/Steps/index.d.ts +3 -2
- package/dist/components/Steps/index.js +8 -9
- package/dist/components/Swiper/index.css +10 -10
- package/dist/components/Switch/index.cjs +4 -5
- package/dist/components/Switch/index.css +58 -26
- package/dist/components/Switch/index.d.cts +3 -2
- package/dist/components/Switch/index.d.ts +3 -2
- package/dist/components/Switch/index.js +4 -5
- package/dist/components/Tab/index.css +15 -15
- package/dist/components/Table/index.cjs +0 -3
- package/dist/components/Table/index.css +15 -15
- package/dist/components/Table/index.d.cts +1 -2
- package/dist/components/Table/index.d.ts +1 -2
- package/dist/components/Table/index.js +0 -3
- package/dist/components/Tag/index.cjs +23 -10
- package/dist/components/Tag/index.css +58 -17
- package/dist/components/Tag/index.d.cts +5 -2
- package/dist/components/Tag/index.d.ts +5 -2
- package/dist/components/Tag/index.js +23 -10
- package/dist/components/TextArea/index.css +20 -9
- package/dist/components/Toast/index.css +22 -22
- package/dist/components/Tooltip/index.cjs +1 -3
- package/dist/components/Tooltip/index.css +6 -6
- package/dist/components/Tooltip/index.d.cts +1 -2
- package/dist/components/Tooltip/index.d.ts +1 -2
- package/dist/components/Tooltip/index.js +1 -3
- package/dist/components/Video/index.css +5 -5
- package/dist/components/index.cjs +970 -15289
- package/dist/components/index.css +2167 -1061
- package/dist/components/index.d.cts +1 -2
- package/dist/components/index.d.ts +1 -2
- package/dist/components/index.js +871 -15192
- package/dist/index.cjs +1077 -15378
- package/dist/index.css +2164 -1058
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +877 -15182
- package/dist/layout/Grid/FullGrid/index.cjs +9 -18
- package/dist/layout/Grid/FullGrid/index.d.cts +1 -1
- package/dist/layout/Grid/FullGrid/index.d.ts +1 -1
- package/dist/layout/Grid/FullGrid/index.js +9 -18
- package/dist/layout/Grid/FullScreen/index.cjs +9 -18
- package/dist/layout/Grid/FullScreen/index.d.cts +3 -3
- package/dist/layout/Grid/FullScreen/index.d.ts +3 -3
- package/dist/layout/Grid/FullScreen/index.js +9 -18
- package/dist/layout/Grid/index.cjs +34 -20
- package/dist/layout/Grid/index.js +34 -20
- package/dist/layout/index.cjs +34 -20
- package/dist/layout/index.css +1000 -295
- package/dist/layout/index.js +34 -20
- package/dist/tokens/index.cjs +33 -142
- package/dist/tokens/index.d.cts +23 -6
- package/dist/tokens/index.d.ts +23 -6
- package/dist/tokens/index.js +29 -140
- package/guidelines/Guidelines.md +57 -0
- package/guidelines/components/accordion.md +72 -0
- package/guidelines/components/avatar.md +35 -0
- package/guidelines/components/button.md +58 -0
- package/guidelines/components/card.md +28 -0
- package/guidelines/components/chart.md +58 -0
- package/guidelines/components/chip-tag.md +49 -0
- package/guidelines/components/data-display.md +96 -0
- package/guidelines/components/datepicker.md +60 -0
- package/guidelines/components/dropdown.md +49 -0
- package/guidelines/components/feedback.md +64 -0
- package/guidelines/components/file-media.md +95 -0
- package/guidelines/components/form.md +60 -0
- package/guidelines/components/html-typewriter.md +38 -0
- package/guidelines/components/input.md +55 -0
- package/guidelines/components/navigation.md +80 -0
- package/guidelines/components/overlay.md +72 -0
- package/guidelines/components/select.md +44 -0
- package/guidelines/components/swiper.md +84 -0
- package/guidelines/components/table.md +62 -0
- package/guidelines/composition/grid.md +95 -0
- package/guidelines/composition/layout.md +30 -0
- package/guidelines/foundations/color.md +81 -0
- package/guidelines/foundations/icons.md +55 -0
- package/guidelines/foundations/spacing.md +51 -0
- package/guidelines/foundations/typography.md +63 -0
- package/guidelines/setup.md +42 -0
- package/package.json +5 -5
- package/dist/colors-CY4JXVHj.d.cts +0 -137
- package/dist/colors-CY4JXVHj.d.ts +0 -137
- package/dist/layout/Grid/GapGrid/index.cjs +0 -32
- package/dist/layout/Grid/GapGrid/index.d.cts +0 -12
- package/dist/layout/Grid/GapGrid/index.d.ts +0 -12
- package/dist/layout/Grid/GapGrid/index.js +0 -11
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# 데이터 표시: Divider / EmptyState / Skeleton / Spinner
|
|
2
|
+
|
|
3
|
+
## Divider
|
|
4
|
+
|
|
5
|
+
구분선을 표시한다.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Divider } from "@xplat/design-system";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
12
|
+
|------|------|--------|------|
|
|
13
|
+
| orientation | `"horizontal" \| "vertical"` | `"horizontal"` | 방향 |
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Divider />
|
|
17
|
+
<Divider orientation="vertical" />
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## EmptyState
|
|
23
|
+
|
|
24
|
+
빈 상태 안내를 표시한다.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { EmptyState } from "@xplat/design-system";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
31
|
+
|------|------|--------|------|
|
|
32
|
+
| icon | `ReactNode` | 기본 폴더 아이콘 | 상단 아이콘 |
|
|
33
|
+
| title | `string` | `"데이터가 없습니다"` | 제목 |
|
|
34
|
+
| description | `string` | — | 부가 설명 |
|
|
35
|
+
| action | `ReactNode` | — | 하단 액션 영역 (버튼 등) |
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
<EmptyState
|
|
39
|
+
title="검색 결과가 없습니다"
|
|
40
|
+
description="다른 키워드로 검색해 보세요."
|
|
41
|
+
action={<Button type="primary">전체 목록</Button>}
|
|
42
|
+
/>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Skeleton
|
|
48
|
+
|
|
49
|
+
로딩 플레이스홀더를 표시한다.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { Skeleton } from "@xplat/design-system";
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
56
|
+
|------|------|--------|------|
|
|
57
|
+
| variant | `"text" \| "circular" \| "rectangular"` | `"text"` | 형태 |
|
|
58
|
+
| width | `string \| number` | — | 너비 |
|
|
59
|
+
| height | `string \| number` | — | 높이 |
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
<Skeleton variant="text" width="200px" />
|
|
63
|
+
<Skeleton variant="circular" width={48} height={48} />
|
|
64
|
+
<Skeleton variant="rectangular" width="100%" height={120} />
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Spinner
|
|
70
|
+
|
|
71
|
+
로딩 인디케이터를 표시한다.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { Spinner } from "@xplat/design-system";
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
78
|
+
|------|------|--------|------|
|
|
79
|
+
| size | `"sm" \| "md" \| "lg"` | `"md"` | 크기 |
|
|
80
|
+
| type | `"brand" \| "success" \| "error" \| "warning" \| "info"` | `"brand"` | 색상 타입 |
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
<Spinner />
|
|
84
|
+
<Spinner size="lg" type="success" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 의사결정
|
|
90
|
+
|
|
91
|
+
| 상황 | 사용할 것 |
|
|
92
|
+
|------|----------|
|
|
93
|
+
| 영역 구분선 | Divider |
|
|
94
|
+
| 데이터가 없는 상태 안내 | EmptyState |
|
|
95
|
+
| 콘텐츠 로딩 전 자리 차지 | Skeleton |
|
|
96
|
+
| 로딩 중 표시 (인디케이터) | Spinner |
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# DatePicker: Calendar / DatePicker 4종
|
|
2
|
+
|
|
3
|
+
## Calendar
|
|
4
|
+
|
|
5
|
+
달력을 표시한다. 이벤트 표시와 `renderDay` 커스텀을 지원한다.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Calendar
|
|
9
|
+
events={[{ date: "2026-03-15", type: "success" }]}
|
|
10
|
+
renderDay={(date) => <span>{date.getDate()}</span>}
|
|
11
|
+
/>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## SingleDatePicker
|
|
17
|
+
|
|
18
|
+
단일 날짜를 선택한다.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<SingleDatePicker value={date} onChange={(d) => setDate(d)} />
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## RangeDatePicker
|
|
25
|
+
|
|
26
|
+
날짜 범위를 선택한다.
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
<RangeDatePicker startDate={start} endDate={end} onChange={handleRange} />
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## InputDatePicker
|
|
33
|
+
|
|
34
|
+
Input + 드롭다운 형태이다.
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<InputDatePicker value={date} onChange={(d) => setDate(d)} />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## PopupDatePicker
|
|
41
|
+
|
|
42
|
+
버튼 + 모달 형태이다.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
<PopupDatePicker
|
|
46
|
+
type="single"
|
|
47
|
+
component={<Button>날짜 선택</Button>}
|
|
48
|
+
value={date}
|
|
49
|
+
onChange={(d) => setDate(d)}
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 의사결정
|
|
56
|
+
|
|
57
|
+
| 상황 | 사용할 것 |
|
|
58
|
+
|------|----------|
|
|
59
|
+
| 달력 표시 / 이벤트 | Calendar |
|
|
60
|
+
| 날짜 선택 | DatePicker (Single/Range/Input/Popup) |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Dropdown
|
|
2
|
+
|
|
3
|
+
액션 메뉴를 표시한다. `children`이 트리거 역할을 하며, 클릭 시 메뉴가 열린다.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { Dropdown } from "@xplat/design-system";
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
12
|
+
|------|------|--------|------|
|
|
13
|
+
| items `*` | `DropdownItem[]` | — | 메뉴 아이템 배열 |
|
|
14
|
+
| children `*` | `ReactNode` | — | 트리거 요소 |
|
|
15
|
+
|
|
16
|
+
### DropdownItem
|
|
17
|
+
|
|
18
|
+
| 필드 | 타입 | 설명 |
|
|
19
|
+
|------|------|------|
|
|
20
|
+
| key `*` | `string` | 고유 식별자 |
|
|
21
|
+
| label `*` | `ReactNode` | 표시 텍스트 |
|
|
22
|
+
| onClick | `() => void` | 클릭 콜백 |
|
|
23
|
+
| disabled | `boolean` | 비활성화 |
|
|
24
|
+
| danger | `boolean` | 위험 액션 스타일 (빨간색) |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 사용 예시
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<Dropdown
|
|
32
|
+
items={[
|
|
33
|
+
{ key: "edit", label: "수정", onClick: () => handleEdit() },
|
|
34
|
+
{ key: "copy", label: "복사", onClick: () => handleCopy() },
|
|
35
|
+
{ key: "delete", label: "삭제", onClick: () => handleDelete(), danger: true },
|
|
36
|
+
]}
|
|
37
|
+
>
|
|
38
|
+
<Button type="ghost">더보기</Button>
|
|
39
|
+
</Dropdown>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 유사 컴포넌트 구분
|
|
45
|
+
|
|
46
|
+
| 목적 | 사용할 것 |
|
|
47
|
+
|------|----------|
|
|
48
|
+
| 값 선택 (폼 필드) | Select |
|
|
49
|
+
| 액션 실행 (메뉴) | Dropdown |
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 피드백: Alert / Toast / Badge
|
|
2
|
+
|
|
3
|
+
## Alert
|
|
4
|
+
|
|
5
|
+
인라인 알림을 표시한다.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Alert type="info">정보 메시지</Alert>
|
|
9
|
+
<Alert type="success">성공</Alert>
|
|
10
|
+
<Alert type="warning">경고</Alert>
|
|
11
|
+
<Alert type="error" onClose={() => {}}>에러 (닫기 가능)</Alert>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Prop | 설명 |
|
|
15
|
+
|------|------|
|
|
16
|
+
| type | `"info" \| "success" \| "warning" \| "error"` |
|
|
17
|
+
| onClose | 닫기 버튼 콜백 (전달 시 닫기 버튼 표시) |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Toast
|
|
22
|
+
|
|
23
|
+
일시적 알림을 표시한다. **ToastProvider가 앱 최상위에 필수이다.**
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// 앱 루트
|
|
27
|
+
<ToastProvider position="top-right">
|
|
28
|
+
<App />
|
|
29
|
+
</ToastProvider>
|
|
30
|
+
|
|
31
|
+
// 컴포넌트 내
|
|
32
|
+
const { toast } = useToast();
|
|
33
|
+
toast("success", "저장 완료");
|
|
34
|
+
toast("error", "오류 발생", 5000);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`toast(type, message, duration?)` 형태로 호출한다.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Badge
|
|
42
|
+
|
|
43
|
+
카운트 또는 도트를 표시한다.
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
<Badge type="error" count={5}><BellIcon /></Badge>
|
|
47
|
+
<Badge type="success" dot><UserIcon /></Badge>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Prop | 설명 |
|
|
51
|
+
|------|------|
|
|
52
|
+
| type | `"error" \| "success" \| "warning" \| "info" \| "brand"` |
|
|
53
|
+
| count | 숫자 표시 |
|
|
54
|
+
| dot | 도트만 표시 |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 의사결정
|
|
59
|
+
|
|
60
|
+
| 상황 | 사용할 것 |
|
|
61
|
+
|------|----------|
|
|
62
|
+
| 인라인 알림 (페이지 내 고정) | Alert |
|
|
63
|
+
| 일시적 알림 (자동 사라짐) | Toast |
|
|
64
|
+
| 카운트/상태 표시 | Badge |
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# 파일/미디어: FileUpload / ImageSelector / Video
|
|
2
|
+
|
|
3
|
+
## FileUpload
|
|
4
|
+
|
|
5
|
+
파일 업로드 영역을 표시한다. 드래그 앤 드롭과 클릭 업로드를 모두 지원한다.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { FileUpload } from "@xplat/design-system";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
12
|
+
|------|------|--------|------|
|
|
13
|
+
| accept | `string` | — | 허용 파일 타입 (예: `"image/*,.pdf"`) |
|
|
14
|
+
| multiple | `boolean` | `false` | 다중 파일 허용 |
|
|
15
|
+
| maxSize | `number` | — | 최대 파일 크기 (bytes). 초과 파일은 자동 필터 |
|
|
16
|
+
| onChange | `(files: File[]) => void` | — | 파일 선택 콜백 |
|
|
17
|
+
| label | `string` | `"파일을 드래그하거나 클릭하여 업로드"` | 안내 텍스트 |
|
|
18
|
+
| description | `string` | — | 부가 설명 |
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<FileUpload
|
|
22
|
+
accept="image/*"
|
|
23
|
+
multiple
|
|
24
|
+
maxSize={5 * 1024 * 1024}
|
|
25
|
+
onChange={(files) => console.log(files)}
|
|
26
|
+
description="최대 5MB, 이미지만 허용"
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## ImageSelector
|
|
33
|
+
|
|
34
|
+
단일 이미지를 선택/미리보기하는 컨트롤이다. controlled 방식으로 동작한다.
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { ImageSelector } from "@xplat/design-system";
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
41
|
+
|------|------|--------|------|
|
|
42
|
+
| value | `File` | — | 선택된 이미지 파일 |
|
|
43
|
+
| label | `string` | `"이미지 추가하기"` | 빈 상태 안내 텍스트 |
|
|
44
|
+
| onChange | `(value: File \| undefined) => void` | — | 변경 콜백 (삭제 시 `undefined`) |
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
const [image, setImage] = useState<File | undefined>();
|
|
48
|
+
|
|
49
|
+
<ImageSelector value={image} onChange={setImage} />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Video
|
|
55
|
+
|
|
56
|
+
비디오 플레이어를 표시한다. `controls={false}`이면 커스텀 재생/일시정지 오버레이를 표시한다. `ref`를 지원한다.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { Video } from "@xplat/design-system";
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
63
|
+
|------|------|--------|------|
|
|
64
|
+
| src `*` | `string` | — | 비디오 URL |
|
|
65
|
+
| poster | `string` | — | 썸네일 이미지 URL |
|
|
66
|
+
| controls | `boolean` | `true` | 네이티브 컨트롤 표시. `false`면 커스텀 오버레이 |
|
|
67
|
+
| autoPlay | `boolean` | — | 자동 재생 |
|
|
68
|
+
| muted | `boolean` | — | 음소거 |
|
|
69
|
+
| loop | `boolean` | — | 반복 재생 |
|
|
70
|
+
| playsInline | `boolean` | `true` | 인라인 재생 (모바일) |
|
|
71
|
+
|
|
72
|
+
`HTMLVideoElement`의 나머지 속성도 전달 가능하다.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
const videoRef = useRef<HTMLVideoElement>(null);
|
|
76
|
+
|
|
77
|
+
<Video
|
|
78
|
+
ref={videoRef}
|
|
79
|
+
src="/intro.mp4"
|
|
80
|
+
poster="/thumb.jpg"
|
|
81
|
+
controls={false}
|
|
82
|
+
muted
|
|
83
|
+
loop
|
|
84
|
+
/>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 의사결정
|
|
90
|
+
|
|
91
|
+
| 상황 | 사용할 것 |
|
|
92
|
+
|------|----------|
|
|
93
|
+
| 파일 업로드 (범용) | FileUpload |
|
|
94
|
+
| 이미지 1장 선택 + 미리보기 | ImageSelector |
|
|
95
|
+
| 비디오 재생 | Video |
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# 폼 컨트롤: CheckBox / Radio / Switch
|
|
2
|
+
|
|
3
|
+
## CheckBox
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
<CheckBox label="동의합니다" checked={checked} onChange={setChecked} />
|
|
7
|
+
<CheckBox label="에러 상태" type="error" checked={false} />
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
| Prop | 설명 |
|
|
11
|
+
|------|------|
|
|
12
|
+
| label | 라벨 텍스트 |
|
|
13
|
+
| checked | 체크 상태 |
|
|
14
|
+
| type | `"brand" \| "success" \| "error" \| "warning" \| "info"` |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Radio
|
|
19
|
+
|
|
20
|
+
**RadioGroup 안에 Radio를 조합한다.**
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
<RadioGroup name="fruit" value={value} onChange={(e) => setValue(e.target.value)}>
|
|
24
|
+
<Radio value="apple" label="사과" />
|
|
25
|
+
<Radio value="banana" label="바나나" />
|
|
26
|
+
</RadioGroup>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Prop (RadioGroup) | 설명 |
|
|
30
|
+
|-------------------|------|
|
|
31
|
+
| name | 그룹 이름 |
|
|
32
|
+
| value | 선택된 값 |
|
|
33
|
+
| onChange | 변경 콜백 |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Switch
|
|
38
|
+
|
|
39
|
+
**controlled 패턴**을 사용한다.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<Switch value={isOn} onChange={setIsOn} />
|
|
43
|
+
<Switch value={isOn} onChange={setIsOn} type="brand" />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
| Prop | 설명 |
|
|
47
|
+
|------|------|
|
|
48
|
+
| value | 토글 상태 |
|
|
49
|
+
| onChange | 변경 콜백 |
|
|
50
|
+
| type | 스타일 타입 |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 의사결정
|
|
55
|
+
|
|
56
|
+
| 상황 | 사용할 것 |
|
|
57
|
+
|------|----------|
|
|
58
|
+
| 다중 선택 | CheckBox |
|
|
59
|
+
| 단일 선택 (여러 옵션 중 하나) | Radio |
|
|
60
|
+
| 켜기/끄기 토글 | Switch |
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# HtmlTypeWriter
|
|
2
|
+
|
|
3
|
+
HTML 문자열을 한 글자씩 타이핑하는 효과를 표시한다. HTML 태그 구조를 유지하면서 텍스트만 순차적으로 렌더한다.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { HtmlTypeWriter } from "@xplat/design-system";
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
12
|
+
|------|------|--------|------|
|
|
13
|
+
| html `*` | `string` | — | 타이핑할 HTML 문자열 |
|
|
14
|
+
| duration | `number` | `20` | 글자당 타이핑 간격 (ms) |
|
|
15
|
+
| onDone | `() => void` | — | 타이핑 완료 콜백 |
|
|
16
|
+
| onChange | `() => void` | — | 타이핑 진행 중 매 글자마다 호출 |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 사용 예시
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
<HtmlTypeWriter
|
|
24
|
+
html="<p>안녕하세요. <strong>타이핑</strong> 효과입니다.</p>"
|
|
25
|
+
duration={30}
|
|
26
|
+
onDone={() => console.log("타이핑 완료")}
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 동적 HTML 변경
|
|
31
|
+
|
|
32
|
+
`html` prop이 변경되면 타이핑을 처음부터 다시 시작한다.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
const [content, setContent] = useState("<p>첫 번째 메시지</p>");
|
|
36
|
+
|
|
37
|
+
<HtmlTypeWriter html={content} onDone={() => setContent("<p>두 번째 메시지</p>")} />
|
|
38
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Input / PasswordInput / TextArea
|
|
2
|
+
|
|
3
|
+
## Input
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
<Input placeholder="이름" />
|
|
7
|
+
<Input type="email" placeholder="이메일" />
|
|
8
|
+
<Input
|
|
9
|
+
type="tel"
|
|
10
|
+
validations={[{ status: "error", message: "필수 항목입니다" }]}
|
|
11
|
+
/>
|
|
12
|
+
<Input suffix={<SearchIcon />} />
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
16
|
+
|------|------|--------|------|
|
|
17
|
+
| type | `"text" \| "number" \| "email" \| "tel"` | `"text"` | 입력 타입 |
|
|
18
|
+
| size | `"sm" \| "md" \| "lg"` | `"md"` | 크기 |
|
|
19
|
+
| validations | `{ status, message }[]` | - | 유효성 검사 |
|
|
20
|
+
| suffix | `ReactNode` | - | 우측 아이콘 |
|
|
21
|
+
|
|
22
|
+
`ref` 전달을 지원한다 (`HTMLInputElement`).
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## PasswordInput
|
|
27
|
+
|
|
28
|
+
비밀번호 입력 전용이다. 눈 아이콘으로 비밀번호 표시/숨김을 토글한다.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<PasswordInput placeholder="비밀번호" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## TextArea
|
|
37
|
+
|
|
38
|
+
자동 높이 조정을 지원한다. `ref` 전달을 지원한다 (`HTMLTextAreaElement`).
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<TextArea placeholder="내용을 입력하세요" />
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 상태
|
|
47
|
+
|
|
48
|
+
| 상태 | 설명 |
|
|
49
|
+
|------|------|
|
|
50
|
+
| default | 기본 |
|
|
51
|
+
| hover | 마우스 오버 |
|
|
52
|
+
| focused | 포커스 |
|
|
53
|
+
| typing | 입력 중 |
|
|
54
|
+
| filled | 입력 완료 |
|
|
55
|
+
| disabled | 비활성화 |
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 내비게이션: Tab / CardTab / Breadcrumb / Pagination / Steps
|
|
2
|
+
|
|
3
|
+
## Tab
|
|
4
|
+
|
|
5
|
+
인덱스 기반 탭이다. 탭 영역만 제공한다.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Tab activeIndex={activeIndex} onChange={setActiveIndex} type="default">
|
|
9
|
+
<Tab.Item>탭1</Tab.Item>
|
|
10
|
+
<Tab.Item>탭2</Tab.Item>
|
|
11
|
+
</Tab>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| Prop | 설명 |
|
|
15
|
+
|------|------|
|
|
16
|
+
| activeIndex | 활성 탭 인덱스 (controlled) |
|
|
17
|
+
| type | `"default" \| "toggle"` |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## CardTab
|
|
22
|
+
|
|
23
|
+
값 기반 탭이다. **CardTab.Panel만 children으로 허용한다.**
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
<CardTab tabs={[{ value: "tab1", title: "탭1" }, { value: "tab2", title: "탭2" }]}>
|
|
27
|
+
<CardTab.Panel value="tab1">탭1 내용</CardTab.Panel>
|
|
28
|
+
<CardTab.Panel value="tab2">탭2 내용</CardTab.Panel>
|
|
29
|
+
</CardTab>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Breadcrumb
|
|
35
|
+
|
|
36
|
+
경로를 표시한다.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<Breadcrumb items={[
|
|
40
|
+
{ label: "홈", href: "/" },
|
|
41
|
+
{ label: "설정", href: "/settings" },
|
|
42
|
+
{ label: "프로필" },
|
|
43
|
+
]} />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Pagination
|
|
49
|
+
|
|
50
|
+
페이지네이션을 표시한다.
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
<Pagination current={page} total={100} onChange={setPage} />
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Steps
|
|
59
|
+
|
|
60
|
+
단계 진행을 표시한다.
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
<Steps
|
|
64
|
+
items={[
|
|
65
|
+
{ title: "정보 입력" },
|
|
66
|
+
{ title: "확인" },
|
|
67
|
+
{ title: "완료" },
|
|
68
|
+
]}
|
|
69
|
+
current={1}
|
|
70
|
+
/>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 의사결정
|
|
76
|
+
|
|
77
|
+
| 상황 | 사용할 것 |
|
|
78
|
+
|------|----------|
|
|
79
|
+
| 탭 영역만 (콘텐츠는 직접 관리) | Tab |
|
|
80
|
+
| 탭 + 패널 콘텐츠 | CardTab |
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# 오버레이: Modal / Drawer / PopOver / Tooltip
|
|
2
|
+
|
|
3
|
+
모두 **controlled 패턴**을 사용한다 (`isOpen`, `onClose`).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Modal
|
|
8
|
+
|
|
9
|
+
중앙 다이얼로그를 표시한다.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
13
|
+
<h2>제목</h2>
|
|
14
|
+
<p>내용</p>
|
|
15
|
+
</Modal>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Drawer
|
|
21
|
+
|
|
22
|
+
사이드 패널을 표시한다.
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
<Drawer isOpen={isOpen} onClose={handleClose} placement="right" width={400}>
|
|
26
|
+
<p>사이드 패널</p>
|
|
27
|
+
</Drawer>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Prop | 설명 |
|
|
31
|
+
|------|------|
|
|
32
|
+
| placement | `"left" \| "right"` |
|
|
33
|
+
| width | 패널 너비 |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## PopOver
|
|
38
|
+
|
|
39
|
+
트리거 요소 기반 팝오버를 표시한다.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<PopOver
|
|
43
|
+
isOpen={isOpen}
|
|
44
|
+
onClose={() => setIsOpen(false)}
|
|
45
|
+
trigger={<Button>열기</Button>}
|
|
46
|
+
>
|
|
47
|
+
<p>팝오버 내용</p>
|
|
48
|
+
</PopOver>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Tooltip
|
|
54
|
+
|
|
55
|
+
부가 정보를 표시한다. **description이 필수이다.** children이 트리거이다.
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<Tooltip description="도움말 텍스트">
|
|
59
|
+
<Button>호버하세요</Button>
|
|
60
|
+
</Tooltip>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 의사결정
|
|
66
|
+
|
|
67
|
+
| 상황 | 사용할 것 |
|
|
68
|
+
|------|----------|
|
|
69
|
+
| 전체 화면 차단 (확인/취소) | Modal |
|
|
70
|
+
| 사이드 패널 (상세 정보/폼) | Drawer |
|
|
71
|
+
| 트리거 기반 부가 정보 | PopOver |
|
|
72
|
+
| 간단한 설명 텍스트 | Tooltip |
|