teachable-design-system 0.2.1 → 0.3.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/package.json +1 -1
- package/src/components/Table/Table.stories.tsx +179 -0
- package/src/components/Table/Table.tsx +510 -0
- package/src/components/Table/index.ts +2 -0
- package/src/components/Table/style.ts +345 -0
- package/src/components/Table/table-body.tsx +112 -0
- package/src/components/Table/table-cell.tsx +153 -0
- package/src/components/Table/table-header.tsx +52 -0
- package/src/components/index.ts +5 -4
- package/src/types/table.d.ts +150 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/** 셀 데이터 타입 */
|
|
4
|
+
export type DataType = 'text' | 'number' | 'date' | 'boolean' | 'custom';
|
|
5
|
+
|
|
6
|
+
/** 정렬 방향 */
|
|
7
|
+
export type SortDirection = 'asc' | 'desc' | null;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 테이블 컬럼 정의
|
|
11
|
+
* @template T - 행 데이터 타입
|
|
12
|
+
*/
|
|
13
|
+
export interface TableColumn<T = Record<string, unknown>> {
|
|
14
|
+
/** 컬럼 고유 키 */
|
|
15
|
+
key: keyof T extends string ? keyof T : string;
|
|
16
|
+
/** 헤더 텍스트 */
|
|
17
|
+
header: string;
|
|
18
|
+
/** 컬럼 너비 (예: '100px', '20%') */
|
|
19
|
+
width?: string;
|
|
20
|
+
/** 편집 가능 여부 @default true */
|
|
21
|
+
editable?: boolean;
|
|
22
|
+
/** 셀 높이 */
|
|
23
|
+
height?: string;
|
|
24
|
+
/** 데이터 타입 @default 'text' */
|
|
25
|
+
dataType?: DataType;
|
|
26
|
+
/** 정렬 가능 여부 @default false */
|
|
27
|
+
sortable?: boolean;
|
|
28
|
+
/** 헤더 스타일 적용 (좌측 열 강조) */
|
|
29
|
+
isHeaderColumn?: boolean;
|
|
30
|
+
/** 행 병합 수 */
|
|
31
|
+
rowSpan?: number;
|
|
32
|
+
/** 열 병합 수 */
|
|
33
|
+
colSpan?: number;
|
|
34
|
+
/** 커스텀 렌더링 */
|
|
35
|
+
render?: (value: unknown, row: T, rowIndex: number) => ReactNode;
|
|
36
|
+
/** 커스텀 정렬 함수 */
|
|
37
|
+
sortFn?: (a: unknown, b: unknown) => number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 테이블 행 데이터 타입 */
|
|
41
|
+
export type TableRow<T = Record<string, unknown>> = T;
|
|
42
|
+
|
|
43
|
+
/** 테이블 컴포넌트 Props */
|
|
44
|
+
export interface TableProps<T = Record<string, unknown>> {
|
|
45
|
+
columns: TableColumn<T>[];
|
|
46
|
+
data: TableRow<T>[];
|
|
47
|
+
onCellEdit?: (rowIndex: number, columnKey: string, value: unknown) => void;
|
|
48
|
+
onSort?: (columnKey: string, direction: SortDirection) => void;
|
|
49
|
+
onSelectionChange?: (cells: CellPosition[]) => void;
|
|
50
|
+
onPaste?: (startRow: number, startCol: number, values: string[][]) => void;
|
|
51
|
+
/** 최대 높이 (스크롤 활성화) */
|
|
52
|
+
maxHeight?: string;
|
|
53
|
+
/** 행 높이 (기본값: 30px) */
|
|
54
|
+
rowHeight?: string;
|
|
55
|
+
/** 줄무늬 스타일 */
|
|
56
|
+
striped?: boolean;
|
|
57
|
+
className?: string;
|
|
58
|
+
/** 행 선택 활성화 */
|
|
59
|
+
enableRowSelection?: boolean;
|
|
60
|
+
/** 선택된 행 인덱스 */
|
|
61
|
+
selectedRowIndex?: number;
|
|
62
|
+
/** 행 클릭 콜백 */
|
|
63
|
+
onRowClick?: (rowIndex: number, row: T) => void;
|
|
64
|
+
/** 키보드 네비게이션 활성화 (↑↓ 화살표) */
|
|
65
|
+
enableKeyboardNavigation?: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** 테이블 셀 Props */
|
|
69
|
+
export interface TableCellProps {
|
|
70
|
+
value: unknown;
|
|
71
|
+
editable?: boolean;
|
|
72
|
+
width?: string;
|
|
73
|
+
height?: string;
|
|
74
|
+
rowHeight?: string;
|
|
75
|
+
dataType?: DataType;
|
|
76
|
+
isHeaderColumn?: boolean;
|
|
77
|
+
rowSpan?: number;
|
|
78
|
+
colSpan?: number;
|
|
79
|
+
isSelected?: boolean;
|
|
80
|
+
rowSelected?: boolean;
|
|
81
|
+
/** 부모에서 편집 시작 요청 여부 */
|
|
82
|
+
isEditingRequested?: boolean;
|
|
83
|
+
/** 편집 시작 트리거 토큰(값이 바뀌면 편집 시작) */
|
|
84
|
+
startEditingToken?: number;
|
|
85
|
+
/** 편집 시작 시 초기 입력 값(타이핑 시작 등) */
|
|
86
|
+
startEditingValue?: string | null;
|
|
87
|
+
selectionEdge?: {
|
|
88
|
+
top: boolean;
|
|
89
|
+
bottom: boolean;
|
|
90
|
+
left: boolean;
|
|
91
|
+
right: boolean;
|
|
92
|
+
};
|
|
93
|
+
onEdit?: (value: unknown) => void;
|
|
94
|
+
render?: (value: unknown) => ReactNode;
|
|
95
|
+
onMouseDown?: () => void;
|
|
96
|
+
onMouseEnter?: () => void;
|
|
97
|
+
onMouseUp?: () => void;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** 테이블 헤더 Props */
|
|
101
|
+
export interface TableHeaderProps<T = Record<string, unknown>> {
|
|
102
|
+
columns: TableColumn<T>[];
|
|
103
|
+
sortColumn?: string;
|
|
104
|
+
sortDirection?: SortDirection;
|
|
105
|
+
onSort?: (columnKey: string) => void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** 테이블 바디 Props */
|
|
109
|
+
export interface TableBodyProps<T = Record<string, unknown>> {
|
|
110
|
+
columns: TableColumn<T>[];
|
|
111
|
+
data: TableRow<T>[];
|
|
112
|
+
rowHeight?: string;
|
|
113
|
+
onCellEdit?: (rowIndex: number, columnKey: string, value: unknown) => void;
|
|
114
|
+
selectedCells?: Set<string>;
|
|
115
|
+
selectionStart?: CellPosition | null;
|
|
116
|
+
selectionEnd?: CellPosition | null;
|
|
117
|
+
/** 키 입력 등으로 시작되는 편집 대상 셀 */
|
|
118
|
+
editingCell?: CellPosition | null;
|
|
119
|
+
/** 키 입력으로 시작된 경우 초기 값 */
|
|
120
|
+
editStartValue?: string | null;
|
|
121
|
+
/** 편집 시작 트리거 토큰 */
|
|
122
|
+
editToken?: number;
|
|
123
|
+
onCellMouseDown?: (rowIndex: number, colIndex: number) => void;
|
|
124
|
+
onCellMouseEnter?: (rowIndex: number, colIndex: number) => void;
|
|
125
|
+
onCellMouseUp?: () => void;
|
|
126
|
+
/** 행 선택 활성화 */
|
|
127
|
+
enableRowSelection?: boolean;
|
|
128
|
+
/** 선택된 행 인덱스 */
|
|
129
|
+
selectedRowIndex?: number;
|
|
130
|
+
/** 호버된 행 인덱스 */
|
|
131
|
+
hoveredRowIndex?: number;
|
|
132
|
+
/** 행 클릭 콜백 */
|
|
133
|
+
onRowClick?: (rowIndex: number) => void;
|
|
134
|
+
/** 행 호버 콜백 */
|
|
135
|
+
onRowHover?: (rowIndex: number | null) => void;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** 셀 위치 */
|
|
139
|
+
export interface CellPosition {
|
|
140
|
+
row: number;
|
|
141
|
+
col: number;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** 선택 범위 */
|
|
145
|
+
export interface SelectionRange {
|
|
146
|
+
startRow: number;
|
|
147
|
+
endRow: number;
|
|
148
|
+
startCol: number;
|
|
149
|
+
endCol: number;
|
|
150
|
+
}
|