sellmate-design-system-react 9.0.0-beta.75 → 9.0.0-beta.76

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 (36) hide show
  1. package/AGENTS.md +35 -0
  2. package/README.md +5 -5
  3. package/bin/sellmate-ds.mjs +91 -59
  4. package/dist/components/SCircleProgress/README.md +6 -3
  5. package/dist/components/SCircleProgress/SCircleProgress.d.ts +11 -3
  6. package/dist/components/SLinearProgress/README.md +2 -2
  7. package/dist/components/SLinearProgress/SLinearProgress.d.ts +8 -2
  8. package/dist/components/SSelect/README.md +18 -2
  9. package/dist/components/SSelect/SSelect.d.ts +28 -5
  10. package/dist/components/SSelect/index.d.ts +1 -1
  11. package/dist/components/STable/README.md +29 -20
  12. package/dist/components/STable/STable.d.ts +47 -31
  13. package/dist/components/STable/index.d.ts +1 -1
  14. package/dist/index.cjs +107 -50
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.js +107 -50
  17. package/dist/index.js.map +1 -1
  18. package/dist/llms-full.txt +90 -28
  19. package/dist/llms.txt +37 -1
  20. package/dist/styles.css +16 -0
  21. package/dist/theme.css +3 -0
  22. package/eslint/index.mjs +42 -42
  23. package/eslint/lib/class-names.mjs +23 -25
  24. package/eslint/lib/table-column.mjs +11 -11
  25. package/eslint/rules/component-group-gap.mjs +32 -30
  26. package/eslint/rules/divider-vertical-height.mjs +22 -22
  27. package/eslint/rules/field-width-grade.mjs +50 -50
  28. package/eslint/rules/no-arbitrary-class.mjs +63 -20
  29. package/eslint/rules/no-off-scale-spacing.mjs +61 -41
  30. package/eslint/rules/no-raw-html-control.mjs +38 -36
  31. package/eslint/rules/prefer-typo-preset.mjs +23 -17
  32. package/eslint/rules/require-locale-number.mjs +14 -19
  33. package/eslint/rules/table-column-width.mjs +21 -17
  34. package/eslint/rules/table-numeric-align.mjs +14 -14
  35. package/eslint/scale.gen.mjs +1 -1
  36. package/package.json +3 -3
@@ -1 +1 @@
1
- export { SSelect, type SSelectHandle, type SSelectProps, type SSelectOption, type SSelectType, } from './SSelect';
1
+ export { SSelect, type SSelectHandle, type SSelectProps, type SSelectChangeValue, type SSelectOption, type SSelectType, } from './SSelect';
@@ -8,15 +8,15 @@
8
8
 
9
9
  | Prop | Type | Default | Description |
10
10
  |------|------|---------|-------------|
11
- | `columns?` | `STableColumn[]` | `[]` | |
11
+ | `columns?` | `STableColumn<TRow>[]` | `[]` | |
12
12
  | `headerGroups?` | `STableHeaderGroup[]` | — | 상위 그룹 헤더. 지정하면 기존 컬럼 헤더가 두 번째 행에 렌더링된다. |
13
- | `rows?` | `SRow[]` | `[]` | |
13
+ | `rows?` | `TRow[]` | `[]` | |
14
14
  | `rowKey?` | `string` | `'id'` | 행 식별 필드 |
15
15
  | `selectable?` | `boolean` | `false` | 행 선택 체크박스 |
16
16
  | `dragSelectable?` | `boolean` | `false` | 행을 드래그해서 고른다. 기본 `false`. 고르는 수단만 다를 뿐 `selectable` 과 같은 선택이다 — `selected` · `onSelectedChange` · `isRowSelectable` 을 그대로 쓴다. 체크박스 열은 생기지 않고, 대신 고른 구간이 배경색과 바깥 테두리로 표시된다. **`selectable` 과 함께 켜면 `selectable` 이 이긴다** — 체크박스가 있는 표에서 드래그까지 걸리면 글자를 긁으려던 손이 선택을 갈아치운다. 둘 다 필요해 보이면 체크박스 쪽만 남긴다. 누른 자리가 구간의 기준점이고, 끌어간 자리까지가 구간이다. **새로 끌면 이전 선택은 풀린다** — 기존 선택에 더하려면 `Ctrl`(macOS 는 `Cmd`)을 짚고 끈다. 잠긴 행(`isRowSelectable`)은 구간 안에 있어도 그냥 지나간다. **켜 두면 셀 안의 글자를 긁어 복사할 수 없다** — 끌기가 곧 선택이라 글자 선택과 같은 손짓을 두고 다툰다. 값을 복사해 가는 표에는 켜지 않는다. 셀 안의 버튼·입력은 그대로 눌린다. |
17
17
  | `contextMenuItems?` | `STableContextMenuItem[]` | — | 드래그 선택에서 **행을 오른쪽 클릭했을 때** 커서 자리에 뜨는 메뉴의 항목. 주지 않거나 비면 메뉴가 뜨지 않고 브라우저 기본 메뉴가 나온다. **`dragSelectable` 에서만 동작한다** — 체크박스 모드에서는 무시된다. 고르지 않은 행에서 누르면 **그 행만 고른 뒤** 열린다. 메뉴가 다룰 대상과 화면에 칠해진 것이 어긋나지 않게 하기 위함이다. 잠긴 행(`isRowSelectable`) 위에서는 열리지 않는다 — 고를 수 없는 행을 대상으로 삼을 수 없기 때문이다. |
18
- | `isRowSelectable?` | `(row: SRow) => boolean` | — | 이 행을 고를 수 있는가. 주지 않으면 모든 행을 고를 수 있다. 고를 수 없는 행은 체크박스가 잠기고, **전체 선택·Shift 구간 선택의 셈에서도 빠진다** — 잠긴 행이 셈에 남으면 "전부 선택됨"에 닿지 못해 헤더 체크박스가 해제 방향으로 가지 못한다. 목록에서 지워 버리는 것과 다르다. 실패 0건인 차수처럼 **자리는 보여야 하지만 대상이 될 수는 없는 행**에 쓴다. 아예 대상이 아니라면 `rows` 에서 거르는 편이 낫다. 잠금은 그리기 시점의 판정일 뿐이라, 이미 `selected` 에 든 행이 나중에 잠겨도 DS 가 빼지 않는다(제어 상태를 말없이 바꾸지 않는다). 다만 헤더의 전체 해제로는 걷어낼 수 있다. |
19
- | `selected?` | `SRow[]` | `[]` | |
18
+ | `isRowSelectable?` | `(row: TRow) => boolean` | — | 이 행을 고를 수 있는가. 주지 않으면 모든 행을 고를 수 있다. 고를 수 없는 행은 체크박스가 잠기고, **전체 선택·Shift 구간 선택의 셈에서도 빠진다** — 잠긴 행이 셈에 남으면 "전부 선택됨"에 닿지 못해 헤더 체크박스가 해제 방향으로 가지 못한다. 목록에서 지워 버리는 것과 다르다. 실패 0건인 차수처럼 **자리는 보여야 하지만 대상이 될 수는 없는 행**에 쓴다. 아예 대상이 아니라면 `rows` 에서 거르는 편이 낫다. 잠금은 그리기 시점의 판정일 뿐이라, 이미 `selected` 에 든 행이 나중에 잠겨도 DS 가 빼지 않는다(제어 상태를 말없이 바꾸지 않는다). 다만 헤더의 전체 해제로는 걷어낼 수 있다. |
19
+ | `selected?` | `TRow[]` | `[]` | |
20
20
  | `sort?` | `STableSort \| null` | `null` | 정렬 상태 (controlled). `null`·미지정이면 정렬 없음. 컴포넌트는 정렬 상태를 갖지 않는다 — 서버 정렬이면 이 값이 곧 조회 조건이고, 뒤로가기·새로고침·링크 공유로 복원돼야 하므로 진실은 URL·store 쪽에 있어야 한다. 행을 실제로 정렬하는 것도 소비 앱 몫이다 (`STable` 은 받은 순서대로 그린다). |
21
21
  | `resizable?` | `boolean` | `false` | 컬럼 너비 조절 |
22
22
  | `width?` | `string` | — | |
@@ -45,8 +45,8 @@
45
45
 
46
46
  | Event | Type | Description |
47
47
  |-------|------|-------------|
48
- | `onContextMenuItemClick` | `(value: string \| number, rows: SRow[]) => void` | 메뉴 항목을 골랐을 때. 고른 항목의 `value` 와 **그 메뉴가 다루는 행들**이 함께 온다. 행 목록은 메뉴가 열린 시점에 확정되므로 `selected` 를 따로 읽지 않아도 된다 — 오른쪽 클릭이 선택을 바꾸는 경우(고르지 않은 행)에도 바뀐 뒤의 행이 온다. |
49
- | `onSelectedChange` | `(rows: SRow[]) => void` | |
48
+ | `onContextMenuItemClick` | `(value: string \| number, rows: TRow[]) => void` | 메뉴 항목을 골랐을 때. 고른 항목의 `value` 와 **그 메뉴가 다루는 행들**이 함께 온다. 행 목록은 메뉴가 열린 시점에 확정되므로 `selected` 를 따로 읽지 않아도 된다 — 오른쪽 클릭이 선택을 바꾸는 경우(고르지 않은 행)에도 바뀐 뒤의 행이 온다. |
49
+ | `onSelectedChange` | `(rows: TRow[]) => void` | |
50
50
  | `onSortChange` | `(sort: STableSort \| null) => void` | 정렬 헤더 클릭 (`asc → desc → 해제` 3단). 해제되면 `null` 이 온다. 다중 정렬은 1차 안에서 지원하지 않는다. |
51
51
  | `onDenseChange` | `(dense: boolean) => void` | 밀도 변경 (하단 바의 밀도 토글을 눌렀을 때). 표시는 테이블이 알아서 바꾸므로 받지 않아도 되고, 사용자가 고른 밀도를 다음 방문까지 기억해 두려는(로컬 저장 등) 페이지만 받으면 된다. |
52
52
  | `onPageChange` | `(page: number) => void` | |
@@ -54,25 +54,39 @@
54
54
  | `onScroll` | `(event: ReactUIEvent<HTMLDivElement>) => void` | 본문이 스크롤될 때. **실제 스크롤에만 울린다** — 행 수·컬럼 폭·로딩이 바뀌어 내부에서 위치를 다시 잴 때는 오지 않는다. `onVirtualUpdate` 는 그리는 창이 바뀔 때만 오므로 그 사이 스크롤을 알 수 없다. 스크롤 위치를 읽어 두었다 되돌리는 것처럼 **위치 자체가 필요하면** 이쪽을 쓴다. |
55
55
  | `onVirtualUpdate` | `(range: { from: number; to: number }) => void` | |
56
56
  | `onVirtualReachEnd` | `(info: { from: number; to: number; rowCount: number; threshold: number; }) =>…` | |
57
- | `onRowClick` | `(row: SRow) => void` | 행 클릭 |
57
+ | `onRowClick` | `(row: TRow) => void` | 행 클릭 |
58
58
 
59
59
  #### Methods (ref)
60
60
 
61
61
  | Method | Type | Description |
62
62
  |--------|------|-------------|
63
- | `isRowSelected` | `(row: SRow) => boolean` | 행 선택 여부 |
64
- | `getIsAllChecked` | `(rows: SRow[]) => boolean \| null` | 주어진 행들의 전체 선택 상태 (true/false/null=indeterminate) |
63
+ | `isRowSelected` | `(row: TRow) => boolean` | 행 선택 여부 |
64
+ | `getIsAllChecked` | `(rows: TRow[]) => boolean \| null` | 주어진 행들의 전체 선택 상태 (true/false/null=indeterminate) |
65
65
  | `getPaginationInfo` | `<union 2종>` | 내부 페이지네이션 정보 (internalPagination 아니면 null) |
66
66
  | `getStickyStyle` | `(colIdx: number) => CSSProperties` | 컬럼 sticky 스타일 (CSS 변수 + 고정폭) |
67
67
  | `getScrollElement` | `() => HTMLDivElement \| null` | 본문의 세로 스크롤 컨테이너. 본문이 슬롯으로 대체됐거나 아직 안 그려졌으면 `null`. 스크롤 위치를 읽고 되돌리거나, 표 안에서 스크롤 여지를 재야 할 때 쓴다 — **DOM 을 뒤져 컨테이너를 찾지 않는다.** 내부 구조는 예고 없이 바뀐다. ⚠️ `virtualScroll` 에서 **위치를 픽셀로 저장했다 되돌리는 것은 미덥지 않다.** 다시 그릴 때 아직 안 그려진 행은 추정 높이로 잡히므로, 실측이 쌓이기 전의 같은 `scrollTop` 이 다른 행을 가리킨다. 그 경우엔 위치가 아니라 **보고 있던 행**을 기억해 두는 편이 맞다. |
68
68
  | `getFirstVisibleRow` | `() => number` | 지금 본문 맨 위에 걸린 행의 인덱스 (`rows` 기준). 행이 없으면 `0`. **스크롤 위치를 저장할 때는 픽셀이 아니라 이 값을 저장한다** — `virtualScroll` 에서 픽셀은 좌표계가 실측으로 움직이는 값이라, 되돌릴 때 다른 행을 가리킨다. |
69
69
  | `scrollToRow` | `(index: number) => void` | 그 행이 본문 맨 위에 오도록 스크롤한다 (`rows` 기준 인덱스, 범위를 벗어나면 잘린다). `virtualScroll` 에서는 **실측이 정착할 때까지 그 행을 계속 다시 겨냥한다** — 옮기는 시점의 좌표는 아직 추정치라 한 번만 옮기면 몇 행씩 밀린다. 사용자가 직접 스크롤하면 겨냥을 놓는다. 페이지네이션을 쓰는 표에서는 **지금 페이지에 그려진 행만** 닿는다 — 다른 페이지의 행이라면 페이지를 먼저 옮긴다. |
70
70
  | `setRowCount` | `(count: number) => void` | 가상 스크롤 총 행 수 설정 |
71
- | `updateRowSelect` | `(row: SRow) => void` | 단일 행 선택 토글 (sd-table updateRowSelect) — onSelectedChange 발생 |
72
- | `toggleSelectAll` | `(checked: boolean, rows: SRow[]) => void` | 주어진 행들 전체 선택/해제 (sd-table toggleSelectAll) — onSelectedChange 발생 |
71
+ | `updateRowSelect` | `(row: TRow) => void` | 단일 행 선택 토글 (sd-table updateRowSelect) — onSelectedChange 발생 |
72
+ | `toggleSelectAll` | `(checked: boolean, rows: TRow[]) => void` | 주어진 행들 전체 선택/해제 (sd-table toggleSelectAll) — onSelectedChange 발생 |
73
73
 
74
74
  ## Types
75
75
 
76
+ ### SRow
77
+
78
+ ```ts
79
+ /**
80
+ * 행 데이터의 기본 타입 — 키만 아는 느슨한 레코드다.
81
+ *
82
+ * 행 타입을 알면 `STableColumn<Order>[]` · `<STable<Order> rows={orders} />` 처럼 넘겨 좁힌다.
83
+ * 그러면 `render`·`format`·`onRowClick` 이 `Order` 를 받는다. 넘기지 않은 기존 코드는 이 기본값으로
84
+ * 예전처럼 동작한다 — 기본값을 `unknown` 으로 바꾸면 `row.statusLabel` 같은 코드가 전부 깨진다.
85
+ */
86
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- 행 타입을 넘기지 않은 화면의 의도된 탈출구
87
+ export type SRow = Record<string, any>;
88
+ ```
89
+
76
90
  ### STableColumn
77
91
 
78
92
  ```ts
@@ -80,9 +94,10 @@
80
94
  * `autoWidth` 스페이서 열은 값을 그리지 않으므로 `field` 를 생략할 수 있다.
81
95
  * 그 밖의 열은 값 접근자가 있어야 한다.
82
96
  */
83
- export type STableColumn = STableColumnBase &
97
+ export type STableColumn<TRow extends SRow = SRow> = STableColumnBase<TRow> &
84
98
  (
85
- { autoWidth: true; field?: STableColumnField } | { autoWidth?: false; field: STableColumnField }
99
+ | { autoWidth: true; field?: STableColumnField<TRow> }
100
+ | { autoWidth?: false; field: STableColumnField<TRow> }
86
101
  );
87
102
  ```
88
103
 
@@ -101,12 +116,6 @@ export interface STableHeaderGroup {
101
116
  }
102
117
  ```
103
118
 
104
- ### SRow
105
-
106
- ```ts
107
- export type SRow = Record<string, any>;
108
- ```
109
-
110
119
  ### STableContextMenuItem
111
120
 
112
121
  ```ts
@@ -154,7 +163,7 @@ export interface STablePagination {
154
163
 
155
164
  ```ts
156
165
  /** 값 접근: 필드명 또는 접근 함수 */
157
- export type STableColumnField = string | ((row: SRow) => any);
166
+ export type STableColumnField<TRow extends SRow = SRow> = string | ((row: TRow) => unknown);
158
167
  ```
159
168
 
160
169
  ## Dependencies
@@ -1,7 +1,21 @@
1
- import { type CSSProperties, type UIEvent as ReactUIEvent, type ReactNode } from 'react';
1
+ import { type CSSProperties, type UIEvent as ReactUIEvent, type ForwardedRef, type ReactElement, type ReactNode } from 'react';
2
2
  import { type SIconName } from '../SIcon';
3
3
  import { type SSelectOption } from '../SSelect';
4
+ /**
5
+ * 행 데이터의 기본 타입 — 키만 아는 느슨한 레코드다.
6
+ *
7
+ * 행 타입을 알면 `STableColumn<Order>[]` · `<STable<Order> rows={orders} />` 처럼 넘겨 좁힌다.
8
+ * 그러면 `render`·`format`·`onRowClick` 이 `Order` 를 받는다. 넘기지 않은 기존 코드는 이 기본값으로
9
+ * 예전처럼 동작한다 — 기본값을 `unknown` 으로 바꾸면 `row.statusLabel` 같은 코드가 전부 깨진다.
10
+ */
4
11
  export type SRow = Record<string, any>;
12
+ /**
13
+ * 셀 값(`format`·`render` 가 받는 값)의 타입.
14
+ *
15
+ * 행 타입을 좁히지 않았으면(`SRow`) 예전처럼 느슨하게 받고, 좁혔으면 `unknown` 이다 — `field` 가
16
+ * 접근 함수일 수도 있어 행 타입만으로는 값의 타입을 정할 수 없으므로 받는 쪽이 확인한다.
17
+ */
18
+ export type STableCellValue<TRow extends SRow = SRow> = SRow extends TRow ? any : unknown;
5
19
  /** 오른쪽 클릭 메뉴의 항목 한 줄 */
6
20
  export interface STableContextMenuItem {
7
21
  /** 클릭 시 `onContextMenuItemClick` 으로 돌아오는 값 */
@@ -11,11 +25,11 @@ export interface STableContextMenuItem {
11
25
  disabled?: boolean;
12
26
  }
13
27
  /** `STableColumn.renderCell`에 전달되는 컨텍스트 */
14
- export interface STableCellContext {
15
- row: SRow;
28
+ export interface STableCellContext<TRow extends SRow = SRow> {
29
+ row: TRow;
16
30
  /** `field` + `format`이 적용된 표시 값 */
17
- value: any;
18
- column: STableColumn;
31
+ value: STableCellValue<TRow>;
32
+ column: STableColumn<TRow>;
19
33
  /** 보이는 컬럼 기준 인덱스 */
20
34
  colIndex: number;
21
35
  /** 현재 렌더 중인 행 목록 기준 인덱스 (페이지/가상 스크롤 윈도우 기준) */
@@ -28,8 +42,8 @@ export interface STableCellContext {
28
42
  style: CSSProperties;
29
43
  }
30
44
  /** 값 접근: 필드명 또는 접근 함수 */
31
- export type STableColumnField = string | ((row: SRow) => any);
32
- interface STableColumnBase {
45
+ export type STableColumnField<TRow extends SRow = SRow> = string | ((row: TRow) => unknown);
46
+ interface STableColumnBase<TRow extends SRow = SRow> {
33
47
  name: string;
34
48
  label: string;
35
49
  align?: 'left' | 'center' | 'right';
@@ -58,7 +72,7 @@ interface STableColumnBase {
58
72
  minWidth?: number;
59
73
  maxWidth?: number;
60
74
  /** 표시 포맷 */
61
- format?: (value: any, row: SRow) => string;
75
+ format?: (value: STableCellValue<TRow>, row: TRow) => string;
62
76
  visible?: boolean;
63
77
  /**
64
78
  * 헤더 라벨 뒤 도움말 툴팁 (각 항목이 한 줄). `SKeyValueTable` 의 `field.helpText` 와 같은 역할 —
@@ -117,7 +131,7 @@ interface STableColumnBase {
117
131
  */
118
132
  contentType?: 'text' | 'control';
119
133
  /** 셀 커스텀 렌더 (React 확장) — `<td>` 안쪽 내용만 교체한다 */
120
- render?: (row: SRow, value: any) => ReactNode;
134
+ render?: (row: TRow, value: STableCellValue<TRow>) => ReactNode;
121
135
  /**
122
136
  * 셀(`<td>`) 자체를 커스텀 렌더 (React 확장). 반환한 엘리먼트가 그대로 `<td>`가 되므로
123
137
  * `colSpan` / `rowSpan`을 직접 지정할 수 있다. `render`보다 우선한다.
@@ -128,11 +142,11 @@ interface STableColumnBase {
128
142
  * - 병합은 sticky 컬럼(인덱스 기준 offset 계산)과 함께 쓰지 않는 것을 전제로 한다.
129
143
  * `rowSpan`은 행을 잘라 쓰는 가상 스크롤 / 내부 페이지네이션과 경계에서 어긋날 수 있다.
130
144
  */
131
- renderCell?: (ctx: STableCellContext) => ReactNode;
145
+ renderCell?: (ctx: STableCellContext<TRow>) => ReactNode;
132
146
  /** 헤더 셀 커스텀 렌더 (React 확장) */
133
- renderHeader?: (column: STableColumn, index: number) => ReactNode;
147
+ renderHeader?: (column: STableColumn<TRow>, index: number) => ReactNode;
134
148
  /** 본문 셀 커스텀 클래스. 함수를 주면 행마다 다른 클래스를 반환할 수 있다 */
135
- tdClass?: string | ((row: SRow) => string | undefined);
149
+ tdClass?: string | ((row: TRow) => string | undefined);
136
150
  /** 헤더 셀 커스텀 클래스/스타일 (sd-table thClass/thStyle) */
137
151
  thClass?: string;
138
152
  thStyle?: CSSProperties;
@@ -141,12 +155,12 @@ interface STableColumnBase {
141
155
  * `autoWidth` 스페이서 열은 값을 그리지 않으므로 `field` 를 생략할 수 있다.
142
156
  * 그 밖의 열은 값 접근자가 있어야 한다.
143
157
  */
144
- export type STableColumn = STableColumnBase & ({
158
+ export type STableColumn<TRow extends SRow = SRow> = STableColumnBase<TRow> & ({
145
159
  autoWidth: true;
146
- field?: STableColumnField;
160
+ field?: STableColumnField<TRow>;
147
161
  } | {
148
162
  autoWidth?: false;
149
- field: STableColumnField;
163
+ field: STableColumnField<TRow>;
150
164
  });
151
165
  export interface STablePagination {
152
166
  page: number;
@@ -174,11 +188,11 @@ export interface STableHeaderGroup {
174
188
  render?: () => ReactNode;
175
189
  }
176
190
  /** STable ref 명령형 API (sd-table @Method 대응) */
177
- export interface STableHandle {
191
+ export interface STableHandle<TRow extends SRow = SRow> {
178
192
  /** 행 선택 여부 */
179
- isRowSelected: (row: SRow) => boolean;
193
+ isRowSelected: (row: TRow) => boolean;
180
194
  /** 주어진 행들의 전체 선택 상태 (true/false/null=indeterminate) */
181
- getIsAllChecked: (rows: SRow[]) => boolean | null;
195
+ getIsAllChecked: (rows: TRow[]) => boolean | null;
182
196
  /** 내부 페이지네이션 정보 (internalPagination 아니면 null) */
183
197
  getPaginationInfo: () => {
184
198
  startIndex: number;
@@ -220,15 +234,15 @@ export interface STableHandle {
220
234
  /** 가상 스크롤 총 행 수 설정 */
221
235
  setRowCount: (count: number) => void;
222
236
  /** 단일 행 선택 토글 (sd-table updateRowSelect) — onSelectedChange 발생 */
223
- updateRowSelect: (row: SRow) => void;
237
+ updateRowSelect: (row: TRow) => void;
224
238
  /** 주어진 행들 전체 선택/해제 (sd-table toggleSelectAll) — onSelectedChange 발생 */
225
- toggleSelectAll: (checked: boolean, rows: SRow[]) => void;
239
+ toggleSelectAll: (checked: boolean, rows: TRow[]) => void;
226
240
  }
227
- export interface STableProps {
228
- columns?: STableColumn[];
241
+ export interface STableProps<TRow extends SRow = SRow> {
242
+ columns?: STableColumn<TRow>[];
229
243
  /** 상위 그룹 헤더. 지정하면 기존 컬럼 헤더가 두 번째 행에 렌더링된다. */
230
244
  headerGroups?: STableHeaderGroup[];
231
- rows?: SRow[];
245
+ rows?: TRow[];
232
246
  /** 행 식별 필드 */
233
247
  rowKey?: string;
234
248
  /** 행 선택 체크박스 */
@@ -268,7 +282,7 @@ export interface STableProps {
268
282
  * 행 목록은 메뉴가 열린 시점에 확정되므로 `selected` 를 따로 읽지 않아도 된다 — 오른쪽
269
283
  * 클릭이 선택을 바꾸는 경우(고르지 않은 행)에도 바뀐 뒤의 행이 온다.
270
284
  */
271
- onContextMenuItemClick?: (value: string | number, rows: SRow[]) => void;
285
+ onContextMenuItemClick?: (value: string | number, rows: TRow[]) => void;
272
286
  /**
273
287
  * 이 행을 고를 수 있는가. 주지 않으면 모든 행을 고를 수 있다.
274
288
  *
@@ -281,9 +295,9 @@ export interface STableProps {
281
295
  * 잠금은 그리기 시점의 판정일 뿐이라, 이미 `selected` 에 든 행이 나중에 잠겨도 DS 가 빼지
282
296
  * 않는다(제어 상태를 말없이 바꾸지 않는다). 다만 헤더의 전체 해제로는 걷어낼 수 있다.
283
297
  */
284
- isRowSelectable?: (row: SRow) => boolean;
285
- selected?: SRow[];
286
- onSelectedChange?: (rows: SRow[]) => void;
298
+ isRowSelectable?: (row: TRow) => boolean;
299
+ selected?: TRow[];
300
+ onSelectedChange?: (rows: TRow[]) => void;
287
301
  /**
288
302
  * 정렬 상태 (controlled). `null`·미지정이면 정렬 없음.
289
303
  *
@@ -385,13 +399,15 @@ export interface STableProps {
385
399
  /** 테이블 식별자 (없으면 자동 생성) */
386
400
  tableId?: string;
387
401
  /** 행 클릭 */
388
- onRowClick?: (row: SRow) => void;
402
+ onRowClick?: (row: TRow) => void;
389
403
  className?: string;
390
404
  style?: CSSProperties;
391
405
  }
392
406
  /**
393
- * STable — sd-table 포팅. 컬럼/행 + 선택 + sticky 헤더/컬럼 + 리사이즈 +
394
- * 내부 페이지네이션 + rows-per-page + 가상 스크롤 + 로딩 + dense.
407
+ * 행 타입을 받는 제네릭 컴포넌트로 내보낸다 — `forwardRef` 는 타입 파라미터를 지워 버리므로
408
+ * 바깥 시그니처만 다시 씌운다(SDraggableList 와 같은 방식). 구현 안쪽은 `SRow` 로 다룬다.
395
409
  */
396
- export declare const STable: import("react").ForwardRefExoticComponent<STableProps & import("react").RefAttributes<STableHandle>>;
410
+ export declare const STable: <TRow extends SRow = SRow>(props: STableProps<TRow> & {
411
+ ref?: ForwardedRef<STableHandle<TRow>>;
412
+ }) => ReactElement | null;
397
413
  export {};
@@ -1 +1 @@
1
- export { STable, type STableProps, type STableColumn, type STableColumnField, type STableSort, type STableHeaderGroup, type STableCellContext, type STablePagination, type STableStickyColumn, type STableHandle, type SRow, } from './STable';
1
+ export { STable, type STableProps, type STableColumn, type STableColumnField, type STableSort, type STableHeaderGroup, type STableCellContext, type STableCellValue, type STablePagination, type STableStickyColumn, type STableHandle, type SRow, } from './STable';