@x-plat/design-system 0.6.1 → 0.7.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.
Files changed (81) hide show
  1. package/dist/components/Accordion/index.css +10 -3
  2. package/dist/components/Alert/index.css +7 -0
  3. package/dist/components/AutoResizeTextArea/index.css +3 -0
  4. package/dist/components/Avatar/index.css +13 -1
  5. package/dist/components/Badge/index.cjs +10 -7
  6. package/dist/components/Badge/index.css +26 -15
  7. package/dist/components/Badge/index.d.cts +3 -19
  8. package/dist/components/Badge/index.d.ts +3 -19
  9. package/dist/components/Badge/index.js +8 -6
  10. package/dist/components/Box/index.css +8 -5
  11. package/dist/components/Breadcrumb/index.css +5 -1
  12. package/dist/components/Button/index.css +10 -1
  13. package/dist/components/Calendar/index.css +10 -6
  14. package/dist/components/CardTab/index.css +14 -2
  15. package/dist/components/Chart/index.css +32 -11
  16. package/dist/components/ChatInput/index.css +6 -0
  17. package/dist/components/CheckBox/index.css +10 -1
  18. package/dist/components/Chip/index.css +12 -0
  19. package/dist/components/DatePicker/index.css +51 -12
  20. package/dist/components/Drawer/index.css +14 -7
  21. package/dist/components/Dropdown/index.css +5 -1
  22. package/dist/components/Editor/index.css +49 -10
  23. package/dist/components/EmptyState/index.css +9 -2
  24. package/dist/components/FileUpload/index.css +9 -2
  25. package/dist/components/HtmlTypeWriter/index.cjs +2 -0
  26. package/dist/components/HtmlTypeWriter/index.css +13 -1
  27. package/dist/components/HtmlTypeWriter/index.d.cts +3 -3
  28. package/dist/components/HtmlTypeWriter/index.d.ts +3 -3
  29. package/dist/components/HtmlTypeWriter/index.js +1 -0
  30. package/dist/components/ImageSelector/index.css +8 -0
  31. package/dist/components/Input/index.css +12 -0
  32. package/dist/components/Modal/index.css +1 -1
  33. package/dist/components/NotificationBadge/index.cjs +68 -0
  34. package/dist/components/NotificationBadge/index.css +75 -0
  35. package/dist/components/NotificationBadge/index.d.cts +47 -0
  36. package/dist/components/NotificationBadge/index.d.ts +47 -0
  37. package/dist/components/NotificationBadge/index.js +40 -0
  38. package/dist/components/Pagination/index.css +25 -1
  39. package/dist/components/PopOver/index.css +1 -1
  40. package/dist/components/Progress/index.css +5 -2
  41. package/dist/components/Radio/index.css +9 -0
  42. package/dist/components/Select/index.css +20 -3
  43. package/dist/components/Steps/index.css +14 -4
  44. package/dist/components/Switch/index.css +1 -1
  45. package/dist/components/Tab/index.css +16 -1
  46. package/dist/components/Table/index.cjs +6 -1
  47. package/dist/components/Table/index.css +12 -0
  48. package/dist/components/Table/index.d.cts +4 -0
  49. package/dist/components/Table/index.d.ts +4 -0
  50. package/dist/components/Table/index.js +6 -1
  51. package/dist/components/Tag/index.css +12 -0
  52. package/dist/components/TextArea/index.css +9 -0
  53. package/dist/components/Toast/index.css +8 -1
  54. package/dist/components/Tooltip/index.css +8 -4
  55. package/dist/components/Video/index.css +30 -19
  56. package/dist/components/index.cjs +274 -265
  57. package/dist/components/index.css +547 -162
  58. package/dist/components/index.d.cts +2 -2
  59. package/dist/components/index.d.ts +2 -2
  60. package/dist/components/index.js +272 -265
  61. package/dist/index.cjs +274 -265
  62. package/dist/index.css +547 -162
  63. package/dist/index.d.cts +2 -2
  64. package/dist/index.d.ts +2 -2
  65. package/dist/index.js +272 -265
  66. package/dist/layout/index.css +40 -0
  67. package/guidelines/AGENT_PROMPT.md +1 -1
  68. package/guidelines/Guidelines.md +1 -1
  69. package/guidelines/components/accordion.md +1 -1
  70. package/guidelines/components/avatar.md +1 -1
  71. package/guidelines/components/card.md +1 -1
  72. package/guidelines/components/chart.md +1 -1
  73. package/guidelines/components/data-display.md +4 -4
  74. package/guidelines/components/dropdown.md +1 -1
  75. package/guidelines/components/feedback.md +39 -11
  76. package/guidelines/components/file-media.md +3 -3
  77. package/guidelines/components/html-typewriter.md +1 -1
  78. package/guidelines/components/navigation.md +144 -20
  79. package/guidelines/components/swiper.md +2 -2
  80. package/guidelines/components/table.md +68 -5
  81. package/package.json +1 -1
@@ -266,6 +266,7 @@
266
266
  --semantic-interaction-overlay-25: var(--brand-base-overlay-25);
267
267
  --semantic-interaction-overlay-50: var(--brand-base-overlay-50);
268
268
  --semantic-interaction-overlay-75: var(--brand-base-overlay-75);
269
+ --semantic-interaction-overlay-85: var(--brand-base-overlay-85);
269
270
  --semantic-interaction-focus-ring: var(--brand-primary-700);
270
271
  }
271
272
  :root {
@@ -511,11 +512,26 @@
511
512
  --semantic-typo-caption-1-sb-lh: var(--typo-lh-caption-1);
512
513
  --semantic-typo-caption-1-sb-weight: var(--typo-weight-semibold);
513
514
  --semantic-typo-caption-1-sb-ls: var(--typo-ls-wide);
515
+ --semantic-typo-caption-1-m-font: var(--typo-font-family-default);
516
+ --semantic-typo-caption-1-m-size: var(--typo-size-caption-1);
517
+ --semantic-typo-caption-1-m-lh: var(--typo-lh-caption-1);
518
+ --semantic-typo-caption-1-m-weight: var(--typo-weight-medium);
519
+ --semantic-typo-caption-1-m-ls: var(--typo-ls-wide);
514
520
  --semantic-typo-caption-1-r-font: var(--typo-font-family-default);
515
521
  --semantic-typo-caption-1-r-size: var(--typo-size-caption-1);
516
522
  --semantic-typo-caption-1-r-lh: var(--typo-lh-caption-1);
517
523
  --semantic-typo-caption-1-r-weight: var(--typo-weight-regular);
518
524
  --semantic-typo-caption-1-r-ls: var(--typo-ls-wide);
525
+ --semantic-typo-caption-2-sb-font: var(--typo-font-family-default);
526
+ --semantic-typo-caption-2-sb-size: var(--typo-size-caption-2);
527
+ --semantic-typo-caption-2-sb-lh: var(--typo-lh-caption-2);
528
+ --semantic-typo-caption-2-sb-weight: var(--typo-weight-semibold);
529
+ --semantic-typo-caption-2-sb-ls: var(--typo-ls-wide);
530
+ --semantic-typo-caption-2-m-font: var(--typo-font-family-default);
531
+ --semantic-typo-caption-2-m-size: var(--typo-size-caption-2);
532
+ --semantic-typo-caption-2-m-lh: var(--typo-lh-caption-2);
533
+ --semantic-typo-caption-2-m-weight: var(--typo-weight-medium);
534
+ --semantic-typo-caption-2-m-ls: var(--typo-ls-wide);
519
535
  --semantic-typo-caption-2-r-font: var(--typo-font-family-default);
520
536
  --semantic-typo-caption-2-r-size: var(--typo-size-caption-2);
521
537
  --semantic-typo-caption-2-r-lh: var(--typo-lh-caption-2);
@@ -669,6 +685,13 @@
669
685
  font-weight: var(--semantic-typo-caption-1-sb-weight);
670
686
  letter-spacing: var(--semantic-typo-caption-1-sb-ls);
671
687
  }
688
+ .typo-caption-1-m {
689
+ font-family: var(--semantic-typo-caption-1-m-font);
690
+ font-size: var(--semantic-typo-caption-1-m-size);
691
+ line-height: var(--semantic-typo-caption-1-m-lh);
692
+ font-weight: var(--semantic-typo-caption-1-m-weight);
693
+ letter-spacing: var(--semantic-typo-caption-1-m-ls);
694
+ }
672
695
  .typo-caption-1-r {
673
696
  font-family: var(--semantic-typo-caption-1-r-font);
674
697
  font-size: var(--semantic-typo-caption-1-r-size);
@@ -676,6 +699,20 @@
676
699
  font-weight: var(--semantic-typo-caption-1-r-weight);
677
700
  letter-spacing: var(--semantic-typo-caption-1-r-ls);
678
701
  }
702
+ .typo-caption-2-sb {
703
+ font-family: var(--semantic-typo-caption-2-sb-font);
704
+ font-size: var(--semantic-typo-caption-2-sb-size);
705
+ line-height: var(--semantic-typo-caption-2-sb-lh);
706
+ font-weight: var(--semantic-typo-caption-2-sb-weight);
707
+ letter-spacing: var(--semantic-typo-caption-2-sb-ls);
708
+ }
709
+ .typo-caption-2-m {
710
+ font-family: var(--semantic-typo-caption-2-m-font);
711
+ font-size: var(--semantic-typo-caption-2-m-size);
712
+ line-height: var(--semantic-typo-caption-2-m-lh);
713
+ font-weight: var(--semantic-typo-caption-2-m-weight);
714
+ letter-spacing: var(--semantic-typo-caption-2-m-ls);
715
+ }
679
716
  .typo-caption-2-r {
680
717
  font-family: var(--semantic-typo-caption-2-r-font);
681
718
  font-size: var(--semantic-typo-caption-2-r-size);
@@ -869,6 +906,9 @@
869
906
  .semantic-interaction-overlay-75 {
870
907
  --ds-color: var(--semantic-interaction-overlay-75);
871
908
  }
909
+ .semantic-interaction-overlay-85 {
910
+ --ds-color: var(--semantic-interaction-overlay-85);
911
+ }
872
912
  .semantic-interaction-focus-ring {
873
913
  --ds-color: var(--semantic-interaction-focus-ring);
874
914
  }
@@ -594,7 +594,7 @@ CSS 변수 `--semantic-{category}-{role}` 사용.
594
594
  | 카테고리 | 컴포넌트 |
595
595
  |---|---|
596
596
  | 입력 | `Button`, `Input`, `PasswordInput`, `TextArea`, `Select`, `CheckBox`, `Radio`, `Switch`, `DatePicker`, `Calendar` |
597
- | 표시 | `Table`, `Card`, `Tag`, `Chip`, `Avatar`, `Badge`, `Skeleton`, `Spinner`, `Divider`, `EmptyState`, `Progress` |
597
+ | 표시 | `Table`, `Card`, `Tag`, `Chip`, `Avatar`, `NotificationBadge`, `Skeleton`, `Spinner`, `Divider`, `EmptyState`, `Progress` |
598
598
  | 오버레이 | `Modal`, `Drawer`, `PopOver`, `Tooltip`, `Alert`, `Toast` (`ToastProvider` 필요) |
599
599
  | 네비 | `Tab`, `CardTab`, `Breadcrumb`, `Pagination`, `Steps`, `Dropdown` |
600
600
  | 미디어 | `Video`, `FileUpload`, `ImageSelector`, `Swiper` |
@@ -52,7 +52,7 @@ React 기반 디자인 시스템 라이브러리이다. Figma Make Kit과 1:1
52
52
  - [Input](./components/input.md) - Input, PasswordInput, TextArea
53
53
  - [Select](./components/select.md)
54
54
  - [Table](./components/table.md)
55
- - [피드백](./components/feedback.md) - Alert, Toast, Badge
55
+ - [피드백](./components/feedback.md) - Alert, Toast, NotificationBadge
56
56
  - [오버레이](./components/overlay.md) - Modal, Drawer, PopOver, Tooltip
57
57
  - [폼 컨트롤](./components/form.md) - CheckBox, Radio, Switch
58
58
  - [Chip & Tag](./components/chip-tag.md)
@@ -3,7 +3,7 @@
3
3
  접이식 패널을 표시한다. 단일/다중 모드를 지원하며, controlled/uncontrolled 모두 가능하다.
4
4
 
5
5
  ```tsx
6
- import { Accordion } from "@xplat/design-system";
6
+ import { Accordion } from "@x-plat/design-system";
7
7
  ```
8
8
 
9
9
  ## Props
@@ -3,7 +3,7 @@
3
3
  프로필 이미지 또는 이니셜을 표시한다. `src`가 있으면 이미지를 렌더하고, 없으면 `name` 기반 이니셜을 표시한다. 둘 다 없으면 기본 사람 아이콘을 표시한다.
4
4
 
5
5
  ```tsx
6
- import { Avatar } from "@xplat/design-system";
6
+ import { Avatar } from "@x-plat/design-system";
7
7
  ```
8
8
 
9
9
  ## Props
@@ -3,7 +3,7 @@
3
3
  콘텐츠를 카드 형태로 감싸는 컨테이너이다.
4
4
 
5
5
  ```tsx
6
- import { Card } from "@xplat/design-system";
6
+ import { Card } from "@x-plat/design-system";
7
7
  ```
8
8
 
9
9
  ## Props
@@ -3,7 +3,7 @@
3
3
  SVG 기반 차트를 렌더한다. line, bar, pie, doughnut 4가지 타입을 지원한다.
4
4
 
5
5
  ```tsx
6
- import { Chart } from "@xplat/design-system";
6
+ import { Chart } from "@x-plat/design-system";
7
7
  ```
8
8
 
9
9
  ## Props
@@ -5,7 +5,7 @@
5
5
  구분선을 표시한다.
6
6
 
7
7
  ```tsx
8
- import { Divider } from "@xplat/design-system";
8
+ import { Divider } from "@x-plat/design-system";
9
9
  ```
10
10
 
11
11
  | Prop | 타입 | 기본값 | 설명 |
@@ -24,7 +24,7 @@ import { Divider } from "@xplat/design-system";
24
24
  빈 상태 안내를 표시한다.
25
25
 
26
26
  ```tsx
27
- import { EmptyState } from "@xplat/design-system";
27
+ import { EmptyState } from "@x-plat/design-system";
28
28
  ```
29
29
 
30
30
  | Prop | 타입 | 기본값 | 설명 |
@@ -49,7 +49,7 @@ import { EmptyState } from "@xplat/design-system";
49
49
  로딩 플레이스홀더를 표시한다.
50
50
 
51
51
  ```tsx
52
- import { Skeleton } from "@xplat/design-system";
52
+ import { Skeleton } from "@x-plat/design-system";
53
53
  ```
54
54
 
55
55
  | Prop | 타입 | 기본값 | 설명 |
@@ -71,7 +71,7 @@ import { Skeleton } from "@xplat/design-system";
71
71
  로딩 인디케이터를 표시한다.
72
72
 
73
73
  ```tsx
74
- import { Spinner } from "@xplat/design-system";
74
+ import { Spinner } from "@x-plat/design-system";
75
75
  ```
76
76
 
77
77
  | Prop | 타입 | 기본값 | 설명 |
@@ -3,7 +3,7 @@
3
3
  액션 메뉴를 표시한다. `children`이 트리거 역할을 하며, 클릭 시 메뉴가 열린다.
4
4
 
5
5
  ```tsx
6
- import { Dropdown } from "@xplat/design-system";
6
+ import { Dropdown } from "@x-plat/design-system";
7
7
  ```
8
8
 
9
9
  ## Props
@@ -1,4 +1,4 @@
1
- # 피드백: Alert / Toast / Badge
1
+ # 피드백: Alert / Toast / NotificationBadge
2
2
 
3
3
  ## Alert
4
4
 
@@ -38,20 +38,46 @@ toast("error", "오류 발생", 5000);
38
38
 
39
39
  ---
40
40
 
41
- ## Badge
41
+ ## NotificationBadge
42
42
 
43
- 카운트 또는 도트를 표시한다.
43
+ 다른 요소의 **우상단 모서리에 얹히는 작은 원**이다. 아이콘·버튼 위에 읽지 않은
44
+ 개수나 상태 점을 표시한다.
45
+
46
+ **`children` 은 뱃지 내용이 아니라 뱃지가 올라탈 대상이다.**
44
47
 
45
48
  ```tsx
46
- <Badge type="error" count={5}><BellIcon /></Badge>
47
- <Badge type="success" dot><UserIcon /></Badge>
49
+ <NotificationBadge type="error" count={5}><BellIcon /></NotificationBadge>
50
+ <NotificationBadge type="success" dot><UserIcon /></NotificationBadge>
48
51
  ```
49
52
 
50
- | Prop | 설명 |
51
- |------|------|
52
- | type | `"error" \| "success" \| "warning" \| "info" \| "brand"` |
53
- | count | 숫자 표시 |
54
- | dot | 도트만 표시 |
53
+ <!-- props:NotificationBadge -->
54
+ | Prop | 타입 | 기본값 | 설명 |
55
+ |------|------|--------|------|
56
+ | children * | `ReactNode` | - | 뱃지가 올라탈 **대상**. 뱃지에 표시할 내용이 아니다. 보통 아이콘이나 버튼을 넣는다. |
57
+ | count | `number` | - | 표시할 개수. `count` 나 `dot` 중 하나가 없으면 **뱃지가 렌더되지 않는다** (`type` 을 줘도 아무 일도 일어나지 않는다). `count={0}` 도 표시하지 않는다 — 읽지 않은 항목이 없으면 숨기는 동작이다. |
58
+ | dot | `boolean` | `false` | 개수 대신 점만 표시한다. `count` 없이 "새 항목 있음" 만 알릴 때 쓴다 |
59
+ | type | `"error" \| "success" \| "warning" \| "info" \| "brand"` | `"error"` | 뱃지 색. 뱃지가 렌더될 때만 의미가 있다 |
60
+ | maxCount | `number` | `99` | `count` 가 이 값을 넘으면 `99+` 처럼 표시한다 |
61
+ | size | `"sm" \| "md" \| "lg"` | `"md"` | 뱃지 크기. 대상의 크기가 아니다 |
62
+
63
+ `*` = 필수
64
+ <!-- /props:NotificationBadge -->
65
+
66
+ ### 흔한 오용
67
+
68
+ 알약 모양 상태 라벨로 쓰면 **조용히 실패한다.** `count` 도 `dot` 도 없으면
69
+ 뱃지가 렌더되지 않고 `children` 만 그대로 통과한다. `type` 을 줘도 무시된다.
70
+
71
+ ```tsx
72
+ <NotificationBadge type="success">진행중</NotificationBadge>
73
+ // → <div class="lib-xplat-notification-badge md">진행중</div> — 아무 모양 없는 맨 글자
74
+
75
+ <Chip type="success">진행중</Chip> // ✅ 알약 라벨은 Chip
76
+ <Tag onClose={fn}>진행중</Tag> // ✅ 제거 가능한 태그는 Tag
77
+ ```
78
+
79
+ > 이전 이름은 `Badge` 였다. 알약 라벨로 오해되어 바뀌었다. `Badge` 와
80
+ > `components/Badge` 경로는 기존 사용처를 위해 남아 있지만 새 코드에는 쓰지 않는다.
55
81
 
56
82
  ---
57
83
 
@@ -61,4 +87,6 @@ toast("error", "오류 발생", 5000);
61
87
  |------|----------|
62
88
  | 인라인 알림 (페이지 내 고정) | Alert |
63
89
  | 일시적 알림 (자동 사라짐) | Toast |
64
- | 카운트/상태 표시 | Badge |
90
+ | 아이콘 위 카운트/상태 점 | `NotificationBadge` |
91
+ | 알약 모양 상태 라벨 | `Chip` |
92
+ | 제거 가능한 태그 | `Tag` |
@@ -5,7 +5,7 @@
5
5
  파일 업로드 영역을 표시한다. 드래그 앤 드롭과 클릭 업로드를 모두 지원한다.
6
6
 
7
7
  ```tsx
8
- import { FileUpload } from "@xplat/design-system";
8
+ import { FileUpload } from "@x-plat/design-system";
9
9
  ```
10
10
 
11
11
  | Prop | 타입 | 기본값 | 설명 |
@@ -34,7 +34,7 @@ import { FileUpload } from "@xplat/design-system";
34
34
  단일 이미지를 선택/미리보기하는 컨트롤이다. controlled 방식으로 동작한다.
35
35
 
36
36
  ```tsx
37
- import { ImageSelector } from "@xplat/design-system";
37
+ import { ImageSelector } from "@x-plat/design-system";
38
38
  ```
39
39
 
40
40
  | Prop | 타입 | 기본값 | 설명 |
@@ -56,7 +56,7 @@ const [image, setImage] = useState<File | undefined>();
56
56
  비디오 플레이어를 표시한다. `controls={false}`이면 커스텀 재생/일시정지 오버레이를 표시한다. `ref`를 지원한다.
57
57
 
58
58
  ```tsx
59
- import { Video } from "@xplat/design-system";
59
+ import { Video } from "@x-plat/design-system";
60
60
  ```
61
61
 
62
62
  | Prop | 타입 | 기본값 | 설명 |
@@ -3,7 +3,7 @@
3
3
  HTML 문자열을 한 글자씩 타이핑하는 효과를 표시한다. HTML 태그 구조를 유지하면서 텍스트만 순차적으로 렌더한다.
4
4
 
5
5
  ```tsx
6
- import { HtmlTypeWriter } from "@xplat/design-system";
6
+ import { HtmlTypeWriter } from "@x-plat/design-system";
7
7
  ```
8
8
 
9
9
  ## Props
@@ -1,46 +1,120 @@
1
1
  # 내비게이션: Tab / CardTab / Breadcrumb / Pagination / Steps
2
2
 
3
+ > 각 컴포넌트는 **배리언트가 여러 개다.** 첫 번째 예시만 보고 고르지 말고,
4
+ > 아래 "배리언트" 표를 먼저 확인한 뒤 화면 맥락에 맞는 값을 고를 것.
5
+
6
+ ---
7
+
3
8
  ## Tab
4
9
 
5
- 인덱스 기반 탭이다. 탭 영역만 제공한다.
10
+ 인덱스 기반 탭이다. 탭 영역만 렌더링하고 패널 콘텐츠는 직접 관리한다.
11
+
12
+ **children 을 받지 않는다. `tabs` 배열로 전달한다.**
6
13
 
7
14
  ```tsx
8
- <Tab activeIndex={activeIndex} onChange={setActiveIndex} type="default">
9
- <Tab.Item>탭1</Tab.Item>
10
- <Tab.Item>탭2</Tab.Item>
11
- </Tab>
15
+ const [activeIndex, setActiveIndex] = useState(0);
16
+
17
+ <Tab
18
+ type="default"
19
+ activeIndex={activeIndex}
20
+ tabs={[
21
+ { value: "all", title: "전체" },
22
+ { value: "active", title: "진행중" },
23
+ ]}
24
+ onChange={(tab, idx) => setActiveIndex(idx)}
25
+ />
12
26
  ```
13
27
 
14
- | Prop | 설명 |
15
- |------|------|
16
- | activeIndex | 활성 탭 인덱스 (controlled) |
17
- | type | `"default" \| "toggle"` |
28
+ <!-- props:Tab -->
29
+ | Prop | 타입 | 기본값 | 설명 |
30
+ |------|------|--------|------|
31
+ | activeIndex * | `number` | - | |
32
+ | tabs * | `{ value: string \| number; title: string }[]` | - | |
33
+ | onChange * | `(value: { value: string \| number; title: string }, index: number) => void` | - | |
34
+ | type * | `"default" \| "toggle"` | - | |
35
+ | size | `"sm" \| "md" \| "lg"` | `"md"` | |
36
+
37
+ `*` = 필수
38
+ <!-- /props:Tab -->
39
+
40
+ ### 배리언트 — type (필수, 기본값 없음)
41
+
42
+ | 값 | 생김새 | 쓰는 곳 |
43
+ |----|--------|---------|
44
+ | `default` | 밑줄 없는 평면 탭 | 페이지 상단 주 내비게이션 |
45
+ | `toggle` | 활성 탭 아래로 인디케이터가 슬라이드 | 콘텐츠 전환 토글, 세그먼트 컨트롤 |
46
+
47
+ ```tsx
48
+ // toggle — 인디케이터가 따라 움직인다
49
+ <Tab
50
+ type="toggle"
51
+ activeIndex={activeIndex}
52
+ tabs={[{ value: 1, title: "목록" }, { value: 2, title: "지도" }]}
53
+ onChange={(tab, idx) => setActiveIndex(idx)}
54
+ />
55
+ ```
56
+
57
+ - `onChange` 에 `setActiveIndex` 를 **그대로 넘기면 안 된다.** 첫 인자가 탭 객체라 상태가 깨진다.
58
+ 반드시 `(tab, idx) => setActiveIndex(idx)` 형태로 감쌀 것.
18
59
 
19
60
  ---
20
61
 
21
62
  ## CardTab
22
63
 
23
- 값 기반 탭이다. **CardTab.Panel만 children으로 허용한다.**
64
+ 값 기반 탭이다. 탭 + 패널 콘텐츠를 함께 제공한다. **`CardTab.Panel` 만 children 으로 허용한다.**
24
65
 
25
66
  ```tsx
26
- <CardTab tabs={[{ value: "tab1", title: "탭1" }, { value: "tab2", title: "탭2" }]}>
67
+ <CardTab
68
+ size="md"
69
+ tabs={[{ value: "tab1", title: "탭1" }, { value: "tab2", title: "탭2" }]}
70
+ onChange={(tab) => console.log(tab.value)}
71
+ >
27
72
  <CardTab.Panel value="tab1">탭1 내용</CardTab.Panel>
28
73
  <CardTab.Panel value="tab2">탭2 내용</CardTab.Panel>
29
74
  </CardTab>
30
75
  ```
31
76
 
77
+ <!-- props:CardTab -->
78
+ | Prop | 타입 | 기본값 | 설명 |
79
+ |------|------|--------|------|
80
+ | tabs * | `{ value: string \| number; title: string }[]` | - | |
81
+ | children * | `ReactElement< CardTabPanelProps, typeof CardTabPanel > \| ReactElement< CardTabPanelProps, typeof CardTabPanel >[]` | - | CardTab.Panel 만 허용 |
82
+ | activeValue | `string \| number` | - | controlled: 외부에서 활성 탭 제어 |
83
+ | onChange | `(tab: { value: string \| number; title: string }) => void` | - | 탭 변경 콜백 |
84
+ | size | `"sm" \| "md" \| "lg"` | `"md"` | |
85
+
86
+ `*` = 필수
87
+ <!-- /props:CardTab -->
88
+
89
+ - `activeValue` 를 **생략하면 컴포넌트가 스스로 상태를 관리한다.** 단순 탭 전환이면 생략하는 쪽이 낫다.
90
+
32
91
  ---
33
92
 
34
93
  ## Breadcrumb
35
94
 
36
- 경로를 표시한다.
95
+ 경로를 표시한다. 마지막 항목은 자동으로 현재 위치로 렌더링된다 (`href` 를 줘도 링크가 아니다).
37
96
 
38
97
  ```tsx
39
- <Breadcrumb items={[
40
- { label: "홈", href: "/" },
41
- { label: "설정", href: "/settings" },
42
- { label: "프로필" },
43
- ]} />
98
+ <Breadcrumb
99
+ items={[
100
+ { label: "홈", href: "/" },
101
+ { label: "설정", href: "/settings" },
102
+ { label: "프로필" },
103
+ ]}
104
+ />
105
+ ```
106
+
107
+ <!-- props:Breadcrumb -->
108
+ | Prop | 타입 | 기본값 | 설명 |
109
+ |------|------|--------|------|
110
+ | items * | `{ label: string; href?: string; onClick?: () => void }[]` | - | |
111
+ | separator | `ReactNode` | `"/"` | |
112
+
113
+ `*` = 필수
114
+ <!-- /props:Breadcrumb -->
115
+
116
+ ```tsx
117
+ <Breadcrumb separator={<ChevronRightIcon />} items={...} />
44
118
  ```
45
119
 
46
120
  ---
@@ -53,6 +127,28 @@
53
127
  <Pagination current={page} total={100} onChange={setPage} />
54
128
  ```
55
129
 
130
+ <!-- props:Pagination -->
131
+ | Prop | 타입 | 기본값 | 설명 |
132
+ |------|------|--------|------|
133
+ | current * | `number` | - | |
134
+ | total * | `number` | - | |
135
+ | pageSize | `number` | `10` | |
136
+ | siblingCount | `number` | `1` | |
137
+ | onChange | `(page: number) => void` | - | |
138
+ | size | `"sm" \| "md" \| "lg"` | `"md"` | |
139
+ | type | `"brand" \| "success" \| "error" \| "warning" \| "info"` | `"brand"` | |
140
+
141
+ `*` = 필수
142
+ <!-- /props:Pagination -->
143
+
144
+ ### 배리언트 — type (5종)
145
+
146
+ `brand` 가 기본이다. 나머지는 페이지네이션이 상태를 가진 목록(오류 목록, 경고 목록 등)에 붙을 때 그 맥락 색을 따라간다.
147
+
148
+ ```tsx
149
+ <Pagination current={page} total={240} pageSize={20} type="error" size="sm" onChange={setPage} />
150
+ ```
151
+
56
152
  ---
57
153
 
58
154
  ## Steps
@@ -62,7 +158,7 @@
62
158
  ```tsx
63
159
  <Steps
64
160
  items={[
65
- { title: "정보 입력" },
161
+ { title: "정보 입력", description: "기본 정보를 입력한다" },
66
162
  { title: "확인" },
67
163
  { title: "완료" },
68
164
  ]}
@@ -70,11 +166,39 @@
70
166
  />
71
167
  ```
72
168
 
169
+ <!-- props:Steps -->
170
+ | Prop | 타입 | 기본값 | 설명 |
171
+ |------|------|--------|------|
172
+ | items * | `{ title: string; description?: string }[]` | - | |
173
+ | current * | `number` | - | |
174
+ | type | `"brand" \| "success" \| "error" \| "warning" \| "info"` | `"brand"` | |
175
+
176
+ `*` = 필수
177
+ <!-- /props:Steps -->
178
+
179
+ ### 배리언트 — type (5종)
180
+
181
+ | 값 | 쓰는 곳 |
182
+ |----|---------|
183
+ | `brand` | 일반 진행 플로우 (기본) |
184
+ | `success` | 완료된 프로세스 회고 표시 |
185
+ | `error` | 실패 지점이 있는 플로우 |
186
+ | `warning` | 주의가 필요한 단계가 포함된 플로우 |
187
+ | `info` | 안내성 플로우 |
188
+
189
+ - `current` 보다 앞 = 완료, 같으면 = 진행 중, 뒤 = 대기. 상태를 직접 넘기지 않는다.
190
+
73
191
  ---
74
192
 
75
193
  ## 의사결정
76
194
 
77
195
  | 상황 | 사용할 것 |
78
196
  |------|----------|
79
- | 탭 영역만 (콘텐츠는 직접 관리) | Tab |
80
- | 탭 + 패널 콘텐츠 | CardTab |
197
+ | 탭 영역만 (콘텐츠는 직접 관리) | `Tab` |
198
+ | 탭 + 패널 콘텐츠 | `CardTab` |
199
+ | 탭 상태를 외부에서 제어해야 함 | `Tab` (controlled 전용) 또는 `CardTab` + `activeValue` |
200
+ | 탭 상태를 신경쓰고 싶지 않음 | `CardTab` (`activeValue` 생략) |
201
+ | 세그먼트 컨트롤 느낌 | `Tab` + `type="toggle"` |
202
+ | 현재 위치 경로 | `Breadcrumb` |
203
+ | 페이지 이동 | `Pagination` |
204
+ | 순차 진행 단계 | `Steps` |
@@ -3,8 +3,8 @@
3
3
  슬라이더/캐러셀을 표시한다. 드래그, 자동 재생, 루프를 지원하며 controlled/uncontrolled 모두 가능하다.
4
4
 
5
5
  ```tsx
6
- import { Swiper } from "@xplat/design-system";
7
- import type { SwiperHandle } from "@xplat/design-system";
6
+ import { Swiper } from "@x-plat/design-system";
7
+ import type { SwiperHandle } from "@x-plat/design-system";
8
8
  ```
9
9
 
10
10
  ## Props
@@ -21,18 +21,81 @@
21
21
 
22
22
  ## Props
23
23
 
24
- | Prop | 설명 |
25
- |------|------|
26
- | headerSticky | 헤더 고정 |
27
- | isSticky | 특정 셀 고정 |
24
+ ### Table
25
+
26
+ <!-- props:Table -->
27
+ | Prop | 타입 | 기본값 | 설명 |
28
+ |------|------|--------|------|
29
+ | children * | `ReactNode` | - | |
30
+ | size | `"sm" \| "md" \| "lg"` | `"md"` | |
31
+ | rowBorderUse | `boolean` | `true` | |
32
+ | colBorderUse | `boolean` | `true` | |
33
+ | headerSticky | `boolean` | `false` | |
34
+ | stickyShadow | `boolean` | `true` | |
35
+
36
+ `*` = 필수
37
+ <!-- /props:Table -->
38
+
39
+ ### TableHead
40
+
41
+ <!-- props:Table.TableHead -->
42
+ | Prop | 타입 | 기본값 | 설명 |
43
+ |------|------|--------|------|
44
+ | children * | `ReactNode` | - | |
45
+ | cellHover | `boolean` | `false` | |
46
+
47
+ `*` = 필수
48
+ <!-- /props:Table.TableHead -->
49
+
50
+ ### TableRow
51
+
52
+ <!-- props:Table.TableRow -->
53
+ | Prop | 타입 | 기본값 | 설명 |
54
+ |------|------|--------|------|
55
+ | children * | `ReactNode` | - | |
56
+ | type | `"primary" \| "secondary" \| "success" \| "error" \| "warning" \| "info"` | `"secondary"` | |
57
+ | color | `1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| "neutral"` | - | |
58
+ | isHover | `boolean` | - | |
59
+ | onClick | `(e: MouseEvent<HTMLTableRowElement>) => void` | - | |
28
60
 
29
- ## TableRow type
61
+ `*` = 필수
62
+ <!-- /props:Table.TableRow -->
30
63
 
31
64
  | type | 용도 |
32
65
  |------|------|
33
66
  | primary | 기본 행 |
34
67
  | secondary | 보조 행 (배경색 구분) |
35
68
 
69
+ ### TableCell
70
+
71
+ <!-- props:Table.TableCell -->
72
+ | Prop | 타입 | 기본값 | 설명 |
73
+ |------|------|--------|------|
74
+ | children * | `ReactNode` | - | |
75
+ | align | `"start" \| "center" \| "end"` | `"center"` | |
76
+ | isSticky | `boolean` | `false` | |
77
+ | width | `string \| number` | - | |
78
+ | nowrap | `boolean` | `false` | |
79
+ | scope | `"col" \| "row"` | `"col"` | th 로 렌더될 때의 scope. 기본 "col" (thead 안에서만 의미가 있다) |
80
+ | colSpan | `number` | - | 가로로 합칠 칸 수. 합계 행처럼 표 안에서 칸을 합칠 때 쓴다 |
81
+ | onClick | `(e: MouseEvent<HTMLTableCellElement>) => void` | - | |
82
+
83
+ `*` = 필수
84
+ <!-- /props:Table.TableCell -->
85
+
86
+ - `TableHead` 안의 `TableCell` 은 자동으로 `<th scope="col">` 로 렌더된다. 별도 prop 이 필요 없다.
87
+ - `align` 기본값은 `center` 다. 왼쪽 정렬이 필요하면 칸마다 `align="start"` 를 준다.
88
+ - `colSpan` 은 합계 행처럼 표 **안**에서 칸을 합칠 때 쓴다. "데이터 없음" 같은 빈 상태는
89
+ 표를 비우고 바깥에 `EmptyState` 를 두는 쪽이 낫다.
90
+
91
+ ```tsx
92
+ // 합계 행 — 앞 2칸을 합쳐 라벨, 마지막 칸에 값
93
+ <TableRow type="secondary">
94
+ <TableCell colSpan={2} align="start">합계</TableCell>
95
+ <TableCell align="end">1,240,000</TableCell>
96
+ </TableRow>
97
+ ```
98
+
36
99
  ---
37
100
 
38
101
  ## 올바른 예시
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-plat/design-system",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "XPLAT UI Design System",
5
5
  "author": "XPLAT WOONG",
6
6
  "main": "dist/index.cjs",