@idbrnd/design-system 1.10.0 → 1.11.0
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/README.md +106 -1
- package/dist/components/Tab/Tab.d.ts +23 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2071 -1891
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @idbrnd/design-system
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|

|
|
5
5
|

|
|
6
6
|

|
|
@@ -69,6 +69,7 @@ export default function App() {
|
|
|
69
69
|
- [FilterChip](#filterchip)
|
|
70
70
|
- [FilterBar](#filterbar)
|
|
71
71
|
- [SegmentedControl](#segmentedcontrol)
|
|
72
|
+
- [Tab](#tab)
|
|
72
73
|
- [테이블](#테이블)
|
|
73
74
|
- [TableContainer](#tablecontainer)
|
|
74
75
|
- [Table](#table)
|
|
@@ -1216,6 +1217,104 @@ function Example() {
|
|
|
1216
1217
|
|
|
1217
1218
|
---
|
|
1218
1219
|
|
|
1220
|
+
## Tab
|
|
1221
|
+
|
|
1222
|
+
`value` + `onChange`를 받는 controlled 탭 컴포넌트입니다. WAI-ARIA `tablist` 패턴을 따르며 키보드(ArrowLeft/Right, Home, End)로 탐색할 수 있습니다. 탭이 뷰포트를 초과하면 드래그 가능한 캐러셀이 자동으로 활성화됩니다.
|
|
1223
|
+
|
|
1224
|
+
```tsx
|
|
1225
|
+
import { useState } from "react";
|
|
1226
|
+
import { Tab } from "@idbrnd/design-system";
|
|
1227
|
+
import type { TabItem } from "@idbrnd/design-system";
|
|
1228
|
+
|
|
1229
|
+
const items: TabItem[] = [
|
|
1230
|
+
{ value: "all", label: "전체" },
|
|
1231
|
+
{ value: "active", label: "진행 중" },
|
|
1232
|
+
{ value: "done", label: "완료" },
|
|
1233
|
+
];
|
|
1234
|
+
|
|
1235
|
+
function TabExample() {
|
|
1236
|
+
const [tab, setTab] = useState("all");
|
|
1237
|
+
|
|
1238
|
+
return <Tab items={items} value={tab} onChange={setTab} />;
|
|
1239
|
+
}
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
**뱃지 + 숫자 뱃지**
|
|
1243
|
+
|
|
1244
|
+
```tsx
|
|
1245
|
+
const items: TabItem[] = [
|
|
1246
|
+
{ value: "inbox", label: "받은 메시지" },
|
|
1247
|
+
{ value: "unread", label: "안읽은 메시지", badge: true },
|
|
1248
|
+
{ value: "sent", label: "보낸 메시지", numberBadge: 12 },
|
|
1249
|
+
];
|
|
1250
|
+
|
|
1251
|
+
<Tab items={items} value={tab} onChange={setTab} />;
|
|
1252
|
+
```
|
|
1253
|
+
|
|
1254
|
+
**fill 모드 (균등 분배)**
|
|
1255
|
+
|
|
1256
|
+
```tsx
|
|
1257
|
+
<Tab items={items} value={tab} onChange={setTab} resize="fill" />
|
|
1258
|
+
```
|
|
1259
|
+
|
|
1260
|
+
**왼쪽 패딩 + trailing 아이콘 버튼**
|
|
1261
|
+
|
|
1262
|
+
```tsx
|
|
1263
|
+
<Tab
|
|
1264
|
+
items={items}
|
|
1265
|
+
value={tab}
|
|
1266
|
+
onChange={setTab}
|
|
1267
|
+
horizontalPadding
|
|
1268
|
+
trailingIcon={
|
|
1269
|
+
<button type="button" onClick={handleAdd}>
|
|
1270
|
+
<PlusIcon />
|
|
1271
|
+
</button>
|
|
1272
|
+
}
|
|
1273
|
+
/>
|
|
1274
|
+
```
|
|
1275
|
+
|
|
1276
|
+
**비활성화 탭 포함**
|
|
1277
|
+
|
|
1278
|
+
```tsx
|
|
1279
|
+
const items: TabItem[] = [
|
|
1280
|
+
{ value: "a", label: "사용 가능" },
|
|
1281
|
+
{ value: "b", label: "비활성화", disabled: true },
|
|
1282
|
+
{ value: "c", label: "사용 가능" },
|
|
1283
|
+
];
|
|
1284
|
+
```
|
|
1285
|
+
|
|
1286
|
+
| Prop | 타입 | 기본값 | 설명 |
|
|
1287
|
+
| ------------------- | ------------------------------------ | ---------- | ---------------------------------------------------------------------- |
|
|
1288
|
+
| `items` | `TabItem[]` | — | **(필수)** 탭 목록 |
|
|
1289
|
+
| `value` | `string \| number` | — | **(필수)** 현재 선택된 탭 값 |
|
|
1290
|
+
| `onChange` | `(value: string \| number) => void` | — | 탭 변경 콜백 |
|
|
1291
|
+
| `size` | `"large"` \| `"medium"` \| `"small"` | `"medium"` | 크기. 폰트 기준: large = heading-1, medium = heading-2, small = body-1 |
|
|
1292
|
+
| `resize` | `"hug"` \| `"fill"` | `"hug"` | `hug`: 탭이 자연 폭, `fill`: 탭이 컨테이너를 균등 분배 |
|
|
1293
|
+
| `horizontalPadding` | `boolean` | `false` | `true` 시 왼쪽 20px 패딩 적용 |
|
|
1294
|
+
| `trailingIcon` | `ReactNode` | — | 탭 목록 오른쪽에 고정 노출되는 아이콘 슬롯. `resize="hug"`일 때만 적용 |
|
|
1295
|
+
| `label` | `string` | — | 스크린 리더용 그룹 레이블 (`aria-label`) |
|
|
1296
|
+
| `customStyle` | `CSSProperties` | — | 추가 인라인 스타일 |
|
|
1297
|
+
|
|
1298
|
+
**`TabItem`**
|
|
1299
|
+
|
|
1300
|
+
| 필드 | 타입 | 설명 |
|
|
1301
|
+
| ------------- | ------------------ | ------------------------------------------------------------------------------------- |
|
|
1302
|
+
| `value` | `string \| number` | **(필수)** 탭 고유 값 |
|
|
1303
|
+
| `label` | `ReactNode` | **(필수)** 탭 레이블 |
|
|
1304
|
+
| `badge` | `boolean` | `true` 시 레이블 우측 상단에 빨간 점(dot) 뱃지 표시 |
|
|
1305
|
+
| `numberBadge` | `number` | 양수일 때 레이블 우측에 숫자 뱃지 표시. 999 초과 시 "999+"로 클리핑. `badge`보다 우선 |
|
|
1306
|
+
| `disabled` | `boolean` | 비활성화. 키보드 탐색에서도 건너뜀 |
|
|
1307
|
+
|
|
1308
|
+
유의사항:
|
|
1309
|
+
|
|
1310
|
+
- 탭이 뷰포트를 초과하면 드래그 가능한 캐러셀이 자동으로 활성화되고, 선택된 탭으로 자동 스크롤됩니다.
|
|
1311
|
+
- `resize="fill"` 모드에서도 탭 개수가 많아 초과하면 캐러셀이 활성화됩니다.
|
|
1312
|
+
- `trailingIcon`은 `resize="hug"`일 때만 렌더링됩니다.
|
|
1313
|
+
- `value`에 해당하는 item이 없으면 슬라이딩 인디케이터가 숨겨지고, 첫 번째 활성 탭에 키보드 포커스가 유지됩니다.
|
|
1314
|
+
- `numberBadge={0}` 또는 음수이면 뱃지가 표시되지 않습니다.
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1219
1318
|
## 테이블
|
|
1220
1319
|
|
|
1221
1320
|
`TableContainer`, `Table`, `Pagination` 3개의 컴포넌트로 구성됩니다. 내부적으로 [TanStack Table v8](https://tanstack.com/table/v8)을 사용하므로 `@tanstack/react-table` 패키지가 필요합니다.
|
|
@@ -1610,6 +1709,12 @@ import type {
|
|
|
1610
1709
|
SegmentedControlSize,
|
|
1611
1710
|
SegmentedControlItem,
|
|
1612
1711
|
|
|
1712
|
+
// Tab
|
|
1713
|
+
TabProps,
|
|
1714
|
+
TabItem,
|
|
1715
|
+
TabSize,
|
|
1716
|
+
TabResize,
|
|
1717
|
+
|
|
1613
1718
|
// Table
|
|
1614
1719
|
TableProps,
|
|
1615
1720
|
TableVariant,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from "react";
|
|
2
|
+
export type TabSize = "large" | "medium" | "small";
|
|
3
|
+
export type TabResize = "hug" | "fill";
|
|
4
|
+
export interface TabItem {
|
|
5
|
+
value: string | number;
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
badge?: boolean;
|
|
8
|
+
numberBadge?: number;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface TabProps {
|
|
12
|
+
resize?: TabResize;
|
|
13
|
+
size?: TabSize;
|
|
14
|
+
items: TabItem[];
|
|
15
|
+
value: string | number;
|
|
16
|
+
onChange?: (value: string | number) => void;
|
|
17
|
+
horizontalPadding?: boolean;
|
|
18
|
+
trailingIcon?: ReactNode;
|
|
19
|
+
label?: string;
|
|
20
|
+
customStyle?: CSSProperties;
|
|
21
|
+
}
|
|
22
|
+
declare function Tab({ items, value, onChange, size, resize, horizontalPadding, trailingIcon, label, customStyle, }: TabProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export default Tab;
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,8 @@ export type { FilterChipProps } from "./components/Chip/FilterChip/FilterChip";
|
|
|
54
54
|
export type { FilterBarProps, FilterBarSize, } from "./components/Chip/FilterBar/FilterBar";
|
|
55
55
|
export { default as Tooltip } from "./components/Tooltip/Tooltip";
|
|
56
56
|
export type { TooltipProps, TooltipPosition, TooltipVariant, TooltipTrigger, TooltipContent, } from "./components/Tooltip/Tooltip.types";
|
|
57
|
+
export { default as Tab } from "./components/Tab/Tab";
|
|
58
|
+
export type { TabProps, TabItem, TabSize, TabResize, } from "./components/Tab/Tab";
|
|
57
59
|
export { default as SegmentedControl } from "./components/SegmentedControl/SegmentedControl";
|
|
58
60
|
export type { SegmentedControlProps, SegmentedControlVariant, SegmentedControlType, SegmentedControlSize, SegmentedControlItem, } from "./components/SegmentedControl/SegmentedControl";
|
|
59
61
|
export { default as Table } from "./components/Table/Table";
|