sellmate-design-system-react 9.0.0-beta.87 → 9.0.0-beta.89

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.
@@ -50,7 +50,7 @@
50
50
  | **버튼·링크** | `SButton` `SGhostButton` `SMeatballButton`(⋯ 로 '더 보기' 메뉴를 여는 아이콘 버튼) `SDropdownButton` `STextLink` `SSwitch` `SToggle` |
51
51
  | **입력 (폼)** | `SForm` `SField` `SInput` `SChatInput`(대화 입력창) `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SChip` `SChipInput` `SBarcodeInput` `SFilePicker` |
52
52
  | **날짜·시간** | `SCalendar` `SCalendarBoard`(한 달치 일정 판) `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
53
- | **표·목록** | `SChatMessage`(대화의 메시지 한 건) `SChatAttachedFile`(입력창 위, 아직 보내지 않은 첨부 한 칸) `SChatFile`(대화 흐름에 선, 보낸 파일 한 칸) `SChatSystemMessage`(대화 흐름 가운데 서는 시스템 안내) `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` `STimeline`(날짜로 묶인 시간순 기록 — 작업 로그·메모 이력) |
53
+ | **표·목록** | `SChatMessage`(대화의 메시지 한 건) `SChatAttachedFile`(입력창 위, 아직 보내지 않은 첨부 한 칸) `SChatFile`(대화 흐름에 선, 보낸 파일 한 칸) `SChatSystemMessage`(대화 흐름 가운데 서는 시스템 안내) `STable` `STableBar` `STreeTable`(행이 부모-자식 계층을 이루는 표 — 펼치고 접는다) `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` `STimeline`(날짜로 묶인 시간순 기록 — 작업 로그·메모 이력) |
54
54
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SSystemActionButton`(GNB system 패널에 한 줄씩 쌓는 액션 행 — 버튼 고르기는 §3-5) `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SLauncherListBox`(런처 버튼을 눌러 뜨는 서비스 목록) `SPage` `SPageHeader`(페이지 제목 영역 — `SLayout` 안에서 `SPage` 앞에 둔다) `SSectionHeaderCard` `SCard` `SLoginCard`(통합 계정 로그인 화면의 카드) `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
55
55
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
56
56
  | **차트** | `SBarChart`(막대 그래프 — 항목끼리 크기를 견준다. `stacked` 로 항목 안의 구성까지) `SLineChart`(꺾은선 그래프 — 순서가 있는 항목의 추이를 본다. `area` 로 크기까지, `stacked` 로 구성까지) `SPieChart`(원그래프 — 한 시점의 전체를 몇 개의 몫으로 나눈다) `SDonutChart`(도넛 그래프 — 가운데가 빈 원그래프. 구멍에 글자를 두지 않는다) |
@@ -175,7 +175,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
175
175
  | 층 | 무엇인가 | 컴포넌트 |
176
176
  | --- | --- | --- |
177
177
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage` `SPageHeader`(`SLayout` 안에서 `SPage` 앞에 둔다) |
178
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `STimeline` `SCallout` `SContextAlert` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
178
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `STreeTable` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `STimeline` `SCallout` `SContextAlert` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
179
179
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `SButton` `SGhostButton` `SMeatballButton` `SDropdownButton` `SSystemActionButton` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SSwitch` `SToggle` `SChipInput` `SBarcodeInput` `SFilePicker` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` `SCalendar` `SListItem` `SExpansionItem` `SDraggableItem` `SChatAttachedFile` `SChatFile` `SImage` `SLinearProgress` `SCircleProgress` `SSkeleton` |
180
180
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `SLogo` `STextLink` `SChip` |
181
181
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SLauncherListBox`(런처 버튼에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -576,6 +576,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
576
576
  | 대화 중간에 시스템이 알리는 사실을 끼운다 (상담사 배정·대화 종료 등) | `SChatSystemMessage` | 사람이 보낸 말이면 `SChatMessage` |
577
577
  | 나열한 항목을 펼쳐 하위 내용을 보여준다 | `SExpansionList` + `SExpansionItem` | §3-7-7 |
578
578
  | 부모-자식 계층을 들여쓰기로 보여준다 | `STree` | §3-7-7 |
579
+ | 계층을 이루는 행들을 여러 열로 보여준다 (카테고리 > 상품 > 옵션) | `STreeTable` | §3-7-7 — 한 줄에 라벨 하나면 `STree` |
579
580
  | 사용자가 순서를 드래그로 바꾸게 한다 | `SDraggableList` + `SDraggableItem` | §3-7-6 |
580
581
  | 날짜별 일정을 한 달치 격자로 펼쳐 보여준다 | `SCalendarBoard` | §3-7-4 |
581
582
  | 항목끼리 크기를 눈으로 견주게 한다 (채널별 매출·상품별 판매량) | `SBarChart` | 정확한 값을 읽어야 하면 `STable` — 그래프는 "어느 쪽이 큰가" 를 답하지 "얼마인가" 를 답하지 않는다 |
@@ -1918,6 +1919,7 @@ const [from, setFrom] = useState<string | null>(null);
1918
1919
  | 항목마다 **시각**이 있고 날짜 머리글로 묶여 위에서 아래로 흐른다 (작업 로그·메모 이력) | `STimeline` |
1919
1920
 
1920
1921
  - **항목 하나의 속성을 나열하는 것은 목록이 아니다.** `라벨: 값` 이 세로로 쌓이는 것은 `SKeyValueTable` 이다 (§4-4).
1922
+ - **행끼리 부모-자식 계층을 이루면 `STable` 이 아니라 `STreeTable` 이다** (§3-7-7). 하위 행을 이름 앞 공백이나 `└` 로 흉내 내지 않는다.
1921
1923
  - **`STimeline` 의 레일(점·선)과 머리글·시각 열은 컴포넌트가 그린다.** `groups` 에 데이터만 넘기고, 점·선을 `border-l` 이나 절대 위치 `span` 으로 직접 그리지 않는다 — 선이 묶음 경계와 마지막 줄에서 끊기는 규칙을 컴포넌트가 계산한다. 작성자·편집 버튼 같은 업무 내용은 각 항목의 `content` 에 넣는다. 빈 상태 안내도 `emptyText` 로 넘기고, 불러오는 중에는 `emptyText={null}` 로 빈 안내를 숨긴다.
1922
1924
  - `SList` 는 레이아웃만 담당한다. depth 별 단일 펼침이 필요하면 `SExpansionList` 다 (§3-7-7).
1923
1925
  - **`SList` 의 자식은 `SListItem` 을 권장한다.** 다른 자식도 그대로 렌더되지만, 펼치는 항목은 `SExpansionList` + `SExpansionItem` 이, 끌어서 순서를 바꾸는 항목은 `SDraggableList` + `SDraggableItem` 이 여닫힘·정렬 동작까지 함께 관리하므로 그쪽을 쓴다 (§3-7-7).
@@ -1952,13 +1954,34 @@ const [from, setFrom] = useState<string | null>(null);
1952
1954
  ❌ <div onKeyDown={e => { e.stopPropagation(); … }}> {/* 리스트가 이미 걸러 준다 */}
1953
1955
  ```
1954
1956
 
1955
- #### 3-7-7. 펼치는 셋 — SExpansionItem vs SExpansionList vs STree
1957
+ #### 3-7-7. 펼치는 넷 — SExpansionItem vs SExpansionList vs STree vs STreeTable
1956
1958
 
1957
1959
  | 판별 | 사용 |
1958
1960
  | --- | --- |
1959
1961
  | 항목들이 **서로 독립적으로** 여닫힌다 (여러 개 동시에 열려도 됨) | `SExpansionItem` 단독 |
1960
1962
  | **한 번에 하나만** 열려야 한다 (아코디언) | `SExpansionList` + `SExpansionItem` |
1961
1963
  | **부모-자식 계층 자체**를 보여줘야 한다 (2단 이상, 연결선) | `STree` |
1964
+ | 계층을 이루는 행마다 **열이 둘 이상**이다 (재고·가격처럼 행끼리 비교하는 값) | `STreeTable` |
1965
+
1966
+ `STreeTable` 은 `STable` 에 계층을 붙인 것이다. 헤더·셀·밀도·정렬 버튼·sticky·가상 스크롤은 `STable` 과 같고, 컬럼 규칙(§3-4)도 그대로 따른다. 다른 점만 적는다.
1967
+
1968
+ - **하위 행은 각 행의 `children` 에 같은 모양으로 넣는다.** 필드 이름이 다르면 `childrenKey` 로 알려 준다. 평평한 목록에 `parentId` 를 달아 넘기지 않는다 — 계층으로 바꿔서 넘긴다.
1969
+ - **펼침 버튼·들여쓰기는 컴포넌트가 그린다.** 기본은 보이는 첫 컬럼이고 `treeColumn` 으로 옮긴다. 그 컬럼은 왼쪽 정렬로 두고, 셀 내용은 `render`·`format` 으로 바꾼다 — `renderCell` 은 펼침 버튼을 넣을 자리가 없어 에러가 난다.
1970
+ - **셀 병합은 가로(`colSpan`)만 한다.** 트리 컬럼이 아닌 컬럼은 `renderCell` 로 `<td>` 를 바꿀 수 있고, 한 행 안에서 끝나는 `colSpan` 은 접고 펴도 그대로다. **`rowSpan` 으로 세로 병합하지 않는다** — 행이 접히면 사라진 행 몫까지 병합이 남아 아래 행의 칸을 덮고, 덮인 행의 칸은 옆 컬럼으로 밀려난다. 부모와 하위 행에 같은 값이 반복되면 부모 행에만 쓰고 하위 행은 비워 둔다.
1971
+ - **펼침 영역은 트리 컬럼 셀 전체다.** 하위 행이 있는 행은 펼침 버튼뿐 아니라 그 셀 어디를 눌러도 접고 편다. 다른 셀을 누르면 행 클릭(`onRowClick`)이다 — 트리 컬럼 셀을 누른 것은 행 클릭으로 가지 않는다.
1972
+ - **펼침 모션은 컴포넌트가 넣는다.** 펼쳐서 새로 보이게 된 행이 위에서 내려오며 나타나고(접을 때는 바로 사라진다), 모션을 줄인 환경에서는 꺼진다. 행에 애니메이션 클래스를 직접 붙이지 않는다.
1973
+ - **트리 컬럼에 링크·버튼을 넣어도 된다.** 셀 안의 링크·버튼·입력을 누르면 그 동작만 일어나고 펼침은 일어나지 않는다 — `stopPropagation` 을 직접 넣지 않는다. 상품명을 상세 링크로 거는 것처럼 쓴다.
1974
+ - **선택은 계층을 따른다.** 부모를 고르면 접힌 하위 행까지 함께 골라지고, 일부만 골라진 부모는 "일부 선택"으로 그려진다. 하위 행이 모두 골라지면 부모도 `selected` 에 들어간다 — 처리 대상이 잎 행뿐이면 받은 목록에서 하위 행이 없는 행만 걸러 쓴다.
1975
+ - **가로로 스크롤되는 표는 트리 컬럼을 왼쪽에 고정한다**(`stickyColumn={{ left: 1 }}`, 트리 컬럼이 첫 컬럼일 때). 스크롤로 들여쓰기가 밀려나면 어느 행이 누구의 하위인지 읽히지 않는다. 체크박스 열은 `selectable` 이면 늘 고정되므로 개수에 넣지 않는다.
1976
+ - **컬럼 폭 조절(`resizable`)은 `STable` 과 달리 기본으로 켜져 있다.** 폭이 고정이어야 하는 표만 `resizable={false}` 로 끈다.
1977
+ - **트리 컬럼에는 `minWidth` 를 준다.** 폭 조절이 켜져 있으므로, 하한이 없으면 들여쓰기보다 좁게 줄어 깊은 행의 이름이 통째로 가려진다. 값은 가장 깊은 행의 이름이 남을 만큼으로 정한다.
1978
+ - **페이지네이션·드래그 선택은 받지 않는다.** 페이지 경계가 부모와 자식 사이를 자르면 계층이 읽히지 않는다. 행이 많으면 `virtualScroll` 을 쓴다.
1979
+ - **정렬은 형제끼리 한다.** `STable` 처럼 받은 순서대로 그리므로, 정렬한 결과를 넘길 때 계층을 풀어 한 줄로 정렬하지 않는다.
1980
+
1981
+ ```tsx
1982
+ ✅ <STreeTable<Category> columns={columns} rows={categories} selectable selected={selected} onSelectedChange={setSelected} />
1983
+ ❌ <STable rows={flatten(categories)} columns={[{ …, render: row => `${' '.repeat(row.depth)}${row.name}` }]} /> {/* 계층을 공백으로 흉내 내지 않는다 */}
1984
+ ```
1962
1985
 
1963
1986
  `SExpansionList` 는 depth 별 **단일 확장**을 관리하는 wrapper 다. 직접 `useState` 로 "열린 항목 하나"를 들고 있지 않는다. 항목 사이 구분선은 여기서도 리스트가 알아서 그린다 — 따로 줄 prop 이 없다 (§3-7-6).
1964
1987
 
@@ -8563,6 +8586,7 @@ export type SGhostButtonIntent =
8563
8586
  - [SToast](../SToast)
8564
8587
  - [STooltip](../STooltip)
8565
8588
  - [STree](../STree)
8589
+ - [STreeTable](../STreeTable)
8566
8590
 
8567
8591
  ### Depends on
8568
8592
 
@@ -10916,7 +10940,7 @@ export type SRadioValue = string | number | boolean;
10916
10940
  | `value?` | `string \| number \| null` | — | 현재 선택 값 |
10917
10941
  | `size?` | `SRadioButtonSize` | `'sm'` | 크기 |
10918
10942
  | `disabled?` | `boolean` | `false` | 전체 비활성 |
10919
- | `readOnly?` | `boolean` | `false` | 읽기 전용. 선택 값을 보여주기만 하고 바꿀 수 없다. 모든 버튼이 readOnly 배경, 선택된 버튼만 readOnly 테두리·기본 글자색으로 구분하고 선택되지 않은 버튼의 글자는 disabled 색이다. 포커스·툴팁은 유지된다. `disabled`(그룹·옵션)가 함께 오면 disabled 가 우선한다. |
10943
+ | `readOnly?` | `boolean` | `false` | 읽기 전용. 선택 값을 보여주기만 하고 바꿀 수 없다. 모든 버튼이 readOnly 배경, 선택된 버튼만 readOnly 테두리·기본 글자색으로 구분하고 선택되지 않은 버튼은 글자가 disabled 색이고 반투명하게 흐려진다. 포커스·툴팁은 유지된다. `disabled`(그룹·옵션)가 함께 오면 disabled 가 우선한다. |
10920
10944
  | `name?` | `string` | — | input name 속성 |
10921
10945
  | `showTooltip?` | `boolean` | `false` | 옵션 호버 시 툴팁 노출. 문구는 옵션별 `tooltip` 으로 주며, 문구가 없는 옵션은 툴팁을 띄우지 않는다. 툴팁 타입은 `accent` 고정이다. |
10922
10946
  | `className?` | `string` | — | |
@@ -11804,6 +11828,8 @@ export interface SSystemActionButtonMenuOption {
11804
11828
  | `dragSelectable?` | `boolean` | `false` | 행을 드래그해서 고른다. 기본 `false`. 고르는 수단만 다를 뿐 `selectable` 과 같은 선택이다 — `selected` · `onSelectedChange` · `isRowSelectable` 을 그대로 쓴다. 체크박스 열은 생기지 않고, 대신 고른 구간이 배경색과 바깥 테두리로 표시된다. **`selectable` 과 함께 켜면 `selectable` 이 이긴다** — 체크박스가 있는 표에서 드래그까지 걸리면 글자를 긁으려던 손이 선택을 갈아치운다. 둘 다 필요해 보이면 체크박스 쪽만 남긴다. 누른 자리가 구간의 기준점이고, 끌어간 자리까지가 구간이다. **새로 끌면 이전 선택은 풀린다** — 기존 선택에 더하려면 `Ctrl`(macOS 는 `Cmd`)을 짚고 끈다. 잠긴 행(`isRowSelectable`)은 구간 안에 있어도 그냥 지나간다. **켜 두면 셀 안의 글자를 긁어 복사할 수 없다** — 끌기가 곧 선택이라 글자 선택과 같은 손짓을 두고 다툰다. 값을 복사해 가는 표에는 켜지 않는다. 셀 안의 버튼·입력은 그대로 눌린다. |
11805
11829
  | `contextMenuItems?` | `STableContextMenuItem[]` | — | 드래그 선택에서 **행을 오른쪽 클릭했을 때** 커서 자리에 뜨는 메뉴의 항목. 주지 않거나 비면 메뉴가 뜨지 않고 브라우저 기본 메뉴가 나온다. **`dragSelectable` 에서만 동작한다** — 체크박스 모드에서는 무시된다. 고르지 않은 행에서 누르면 **그 행만 고른 뒤** 열린다. 메뉴가 다룰 대상과 화면에 칠해진 것이 어긋나지 않게 하기 위함이다. 잠긴 행(`isRowSelectable`) 위에서는 열리지 않는다 — 고를 수 없는 행을 대상으로 삼을 수 없기 때문이다. |
11806
11830
  | `isRowSelectable?` | `(row: TRow) => boolean` | — | 이 행을 고를 수 있는가. 주지 않으면 모든 행을 고를 수 있다. 고를 수 없는 행은 체크박스가 잠기고, **전체 선택·Shift 구간 선택의 셈에서도 빠진다** — 잠긴 행이 셈에 남으면 "전부 선택됨"에 닿지 못해 헤더 체크박스가 해제 방향으로 가지 못한다. 목록에서 지워 버리는 것과 다르다. 실패 0건인 차수처럼 **자리는 보여야 하지만 대상이 될 수는 없는 행**에 쓴다. 아예 대상이 아니라면 `rows` 에서 거르는 편이 낫다. 잠금은 그리기 시점의 판정일 뿐이라, 이미 `selected` 에 든 행이 나중에 잠겨도 DS 가 빼지 않는다(제어 상태를 말없이 바꾸지 않는다). 다만 헤더의 전체 해제로는 걷어낼 수 있다. |
11831
+ | `isRowIndeterminate?` | `(row: TRow) => boolean` | — | 이 행의 체크박스를 "일부 선택"(indeterminate)으로 그리는가. 주지 않으면 그리지 않는다. **표시만 바꾼다** — 선택 상태(`selected`)와 클릭 동작은 그대로다. 일부 선택된 행을 누르면 선택되지 않은 행을 누른 것과 같이 `selected` 에 더해진다. 선택된 행(`selected` 에 든 행)은 이 값과 무관하게 체크로 그린다. 하위 행을 가진 행처럼 **"아래가 일부만 골라졌다"를 행 스스로 말해야 하는 표**에 쓴다. 계층 선택을 통째로 맡기려면 `STreeTable` 을 쓴다 — 이 prop 은 그 표가 쓰는 통로다. |
11832
+ | `rowClassName?` | `(row: TRow) => string \| undefined` | — | 행(`<tr>`)에 더할 클래스. 행마다 다른 클래스를 줄 수 있다. 색·여백은 여기서 주지 않는다 — 셀이 배경을 칠하므로 행 배경은 보이지 않고, 여백은 토큰이 정한다. 행 전체에 걸리는 모션처럼 **셀 단위로는 줄 수 없는 것**만 쓴다. 셀 하나의 모양은 컬럼의 `tdClass` 다. |
11807
11833
  | `selected?` | `TRow[]` | `[]` | |
11808
11834
  | `sort?` | `STableSort \| null` | `null` | 정렬 상태 (controlled). `null`·미지정이면 정렬 없음. 컴포넌트는 정렬 상태를 갖지 않는다 — 서버 정렬이면 이 값이 곧 조회 조건이고, 뒤로가기·새로고침·링크 공유로 복원돼야 하므로 진실은 URL·store 쪽에 있어야 한다. 행을 실제로 정렬하는 것도 소비 앱 몫이다 (`STable` 은 받은 순서대로 그린다). |
11809
11835
  | `resizable?` | `boolean` | `false` | 컬럼 너비 조절 |
@@ -11957,6 +11983,10 @@ export type STableColumnField<TRow extends SRow = SRow> = string | ((row: TRow)
11957
11983
 
11958
11984
  ## Dependencies
11959
11985
 
11986
+ ### Used by
11987
+
11988
+ - [STreeTable](../STreeTable)
11989
+
11960
11990
  ### Depends on
11961
11991
 
11962
11992
  - [SCheckbox](../SCheckbox)
@@ -12714,7 +12744,6 @@ export type STooltipType = 'default' | 'danger' | 'warning' | 'accent';
12714
12744
  | `showSelectAll?` | `boolean` | `false` | 체크박스 사용 시 최상단 전체 선택 아이템 표시 여부 |
12715
12745
  | `guideline?` | `boolean` | `true` | depth 연결선 표시 여부 |
12716
12746
  | `border?` | `boolean` | `true` | 아이템 하단 border 표시 여부 |
12717
- | `cascadeSelection?` | `boolean` | `true` | 부모 선택 시 하위 노드까지 함께 토글 |
12718
12747
  | `leading?` | `ReactNode \| ((state: STreeItemRenderState) => ReactNode)` | — | 사용자 지정 leading 콘텐츠 |
12719
12748
  | `trailing?` | `ReactNode \| ((state: STreeItemRenderState) => ReactNode)` | — | 사용자 지정 trailing 콘텐츠 |
12720
12749
 
@@ -12771,3 +12800,48 @@ export interface STreeItemRenderState {
12771
12800
  - [SGhostButton](../SGhostButton)
12772
12801
 
12773
12802
  ### Graph
12803
+
12804
+ ---
12805
+
12806
+ # STreeTable
12807
+
12808
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
12809
+
12810
+ ### STreeTable
12811
+
12812
+ #### Props
12813
+
12814
+ | Prop | Type | Default | Description |
12815
+ |------|------|---------|-------------|
12816
+ | `rows?` | `TRow[]` | `[]` | 최상위 행. 하위 행은 각 행의 `childrenKey` 필드에 같은 모양으로 넣는다. 펼친 행만 표에 그려진다. 나머지 prop(`columns` · `selectable` · `sort` · `stickyColumn` · `virtualScroll` …)은 `STable` 과 같다. `STable` 처럼 행을 직접 정렬하지 않고 받은 순서대로 그리므로, 정렬하려면 소비 앱이 **형제끼리** 정렬해 넘긴다. 그리는 행이 펼침에 따라 늘고 줄므로, 컬럼의 `renderCell` 로 **`rowSpan` 세로 병합을 하지 않는다** — 행이 접히면 사라진 행 몫까지 병합이 남아 아래 행의 칸을 덮는다. 한 행 안의 `colSpan` 은 된다. |
12817
+ | `childrenKey?` | `string` | `'children'` | 하위 행 배열이 든 필드 |
12818
+ | `resizable?` | `boolean` | `true` | 컬럼 폭 조절. **`STable` 과 달리 기본이 `true` 다** — 깊이에 따라 트리 컬럼이 필요로 하는 폭이 달라 화면마다 맞는 폭을 미리 정하기 어렵다. 폭이 고정이어야 하는 표만 `false` 로 끈다. 켜 두면 트리 컬럼에 `minWidth` 를 준다. 하한이 없으면 들여쓰기보다 좁게 줄어 깊은 행의 이름이 통째로 가려진다. |
12819
+ | `treeColumn?` | `string` | — | 펼침 버튼과 들여쓰기가 붙는 컬럼의 `name`. 주지 않으면 보이는 첫 컬럼이다. 하위 행이 있는 행은 **이 셀 전체가 펼침 영역**이다 — 어디를 눌러도 접고 펴고, 행 클릭(`onRowClick`)으로는 가지 않는다. 셀 안에 넣은 링크·버튼·입력은 자기 동작만 하고 펼침은 일어나지 않는다. 이 컬럼에는 `renderCell` 을 쓰지 않는다 — `<td>` 를 통째로 바꾸면 펼침 버튼을 넣을 자리가 없다. 셀 내용은 `render` · `format` 으로 바꾼다. 들여쓰기가 왼쪽에서 쌓이므로 `align` 은 왼쪽으로 둔다. |
12820
+ | `expandedKeys?` | `STreeTableKey[]` | — | 펼친 행의 키 목록 (controlled) |
12821
+ | `defaultExpandedKeys?` | `STreeTableKey[]` | — | 비제어 펼침 초기값. 주지 않으면 하위 행이 있는 최상위 행이 펼쳐진 채로 시작한다 (`STree` 와 같다) |
12822
+ | `selected?` | `TRow[]` | `[]` | 고른 행 (controlled). 접혀서 보이지 않는 행도 들어 있을 수 있다. 선택은 계층을 따른다. 부모를 고르면 하위 행이 모두 함께 골라지고, 하위 행이 일부만 골라진 부모는 체크박스가 "일부 선택"으로 그려진다. 하위 행이 모두 골라지면 부모도 골라진 것으로 친다 — `onSelectedChange` 로 오는 목록에 부모가 들어간다. 고를 수 없는 행(`isRowSelectable`)과 그 아래는 함께 골라지지 않는다. |
12823
+
12824
+ #### Events
12825
+
12826
+ | Event | Type | Description |
12827
+ |-------|------|-------------|
12828
+ | `onExpandedChange` | `(expandedKeys: STreeTableKey[], row: TRow) => void` | 펼침 변경. 바뀐 뒤의 키 목록과 누른 행이 온다 |
12829
+ | `onSelectedChange` | `(rows: TRow[]) => void` | 선택 변경. 계층 순서(부모 다음에 그 하위 행)대로 정렬된 목록이 온다 |
12830
+
12831
+ ## Types
12832
+
12833
+ ### STreeTableKey
12834
+
12835
+ ```ts
12836
+ /** 행 식별 값 — `rowKey` 필드에 든 값이다 */
12837
+ export type STreeTableKey = string | number;
12838
+ ```
12839
+
12840
+ ## Dependencies
12841
+
12842
+ ### Depends on
12843
+
12844
+ - [SGhostButton](../SGhostButton)
12845
+ - [STable](../STable)
12846
+
12847
+ ### Graph
package/dist/llms.txt CHANGED
@@ -51,7 +51,7 @@
51
51
  | **버튼·링크** | `SButton` `SGhostButton` `SMeatballButton`(⋯ 로 '더 보기' 메뉴를 여는 아이콘 버튼) `SDropdownButton` `STextLink` `SSwitch` `SToggle` |
52
52
  | **입력 (폼)** | `SForm` `SField` `SInput` `SChatInput`(대화 입력창) `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SChip` `SChipInput` `SBarcodeInput` `SFilePicker` |
53
53
  | **날짜·시간** | `SCalendar` `SCalendarBoard`(한 달치 일정 판) `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
54
- | **표·목록** | `SChatMessage`(대화의 메시지 한 건) `SChatAttachedFile`(입력창 위, 아직 보내지 않은 첨부 한 칸) `SChatFile`(대화 흐름에 선, 보낸 파일 한 칸) `SChatSystemMessage`(대화 흐름 가운데 서는 시스템 안내) `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` `STimeline`(날짜로 묶인 시간순 기록 — 작업 로그·메모 이력) |
54
+ | **표·목록** | `SChatMessage`(대화의 메시지 한 건) `SChatAttachedFile`(입력창 위, 아직 보내지 않은 첨부 한 칸) `SChatFile`(대화 흐름에 선, 보낸 파일 한 칸) `SChatSystemMessage`(대화 흐름 가운데 서는 시스템 안내) `STable` `STableBar` `STreeTable`(행이 부모-자식 계층을 이루는 표 — 펼치고 접는다) `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` `STimeline`(날짜로 묶인 시간순 기록 — 작업 로그·메모 이력) |
55
55
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SSystemActionButton`(GNB system 패널에 한 줄씩 쌓는 액션 행 — 버튼 고르기는 §3-5) `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SLauncherListBox`(런처 버튼을 눌러 뜨는 서비스 목록) `SPage` `SPageHeader`(페이지 제목 영역 — `SLayout` 안에서 `SPage` 앞에 둔다) `SSectionHeaderCard` `SCard` `SLoginCard`(통합 계정 로그인 화면의 카드) `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
56
56
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
57
57
  | **차트** | `SBarChart`(막대 그래프 — 항목끼리 크기를 견준다. `stacked` 로 항목 안의 구성까지) `SLineChart`(꺾은선 그래프 — 순서가 있는 항목의 추이를 본다. `area` 로 크기까지, `stacked` 로 구성까지) `SPieChart`(원그래프 — 한 시점의 전체를 몇 개의 몫으로 나눈다) `SDonutChart`(도넛 그래프 — 가운데가 빈 원그래프. 구멍에 글자를 두지 않는다) |
@@ -176,7 +176,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
176
176
  | 층 | 무엇인가 | 컴포넌트 |
177
177
  | --- | --- | --- |
178
178
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage` `SPageHeader`(`SLayout` 안에서 `SPage` 앞에 둔다) |
179
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `STimeline` `SCallout` `SContextAlert` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
179
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `STreeTable` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `STimeline` `SCallout` `SContextAlert` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
180
180
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `SButton` `SGhostButton` `SMeatballButton` `SDropdownButton` `SSystemActionButton` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SSwitch` `SToggle` `SChipInput` `SBarcodeInput` `SFilePicker` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` `SCalendar` `SListItem` `SExpansionItem` `SDraggableItem` `SChatAttachedFile` `SChatFile` `SImage` `SLinearProgress` `SCircleProgress` `SSkeleton` |
181
181
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `SLogo` `STextLink` `SChip` |
182
182
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SLauncherListBox`(런처 버튼에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -577,6 +577,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
577
577
  | 대화 중간에 시스템이 알리는 사실을 끼운다 (상담사 배정·대화 종료 등) | `SChatSystemMessage` | 사람이 보낸 말이면 `SChatMessage` |
578
578
  | 나열한 항목을 펼쳐 하위 내용을 보여준다 | `SExpansionList` + `SExpansionItem` | §3-7-7 |
579
579
  | 부모-자식 계층을 들여쓰기로 보여준다 | `STree` | §3-7-7 |
580
+ | 계층을 이루는 행들을 여러 열로 보여준다 (카테고리 > 상품 > 옵션) | `STreeTable` | §3-7-7 — 한 줄에 라벨 하나면 `STree` |
580
581
  | 사용자가 순서를 드래그로 바꾸게 한다 | `SDraggableList` + `SDraggableItem` | §3-7-6 |
581
582
  | 날짜별 일정을 한 달치 격자로 펼쳐 보여준다 | `SCalendarBoard` | §3-7-4 |
582
583
  | 항목끼리 크기를 눈으로 견주게 한다 (채널별 매출·상품별 판매량) | `SBarChart` | 정확한 값을 읽어야 하면 `STable` — 그래프는 "어느 쪽이 큰가" 를 답하지 "얼마인가" 를 답하지 않는다 |
@@ -1919,6 +1920,7 @@ const [from, setFrom] = useState<string | null>(null);
1919
1920
  | 항목마다 **시각**이 있고 날짜 머리글로 묶여 위에서 아래로 흐른다 (작업 로그·메모 이력) | `STimeline` |
1920
1921
 
1921
1922
  - **항목 하나의 속성을 나열하는 것은 목록이 아니다.** `라벨: 값` 이 세로로 쌓이는 것은 `SKeyValueTable` 이다 (§4-4).
1923
+ - **행끼리 부모-자식 계층을 이루면 `STable` 이 아니라 `STreeTable` 이다** (§3-7-7). 하위 행을 이름 앞 공백이나 `└` 로 흉내 내지 않는다.
1922
1924
  - **`STimeline` 의 레일(점·선)과 머리글·시각 열은 컴포넌트가 그린다.** `groups` 에 데이터만 넘기고, 점·선을 `border-l` 이나 절대 위치 `span` 으로 직접 그리지 않는다 — 선이 묶음 경계와 마지막 줄에서 끊기는 규칙을 컴포넌트가 계산한다. 작성자·편집 버튼 같은 업무 내용은 각 항목의 `content` 에 넣는다. 빈 상태 안내도 `emptyText` 로 넘기고, 불러오는 중에는 `emptyText={null}` 로 빈 안내를 숨긴다.
1923
1925
  - `SList` 는 레이아웃만 담당한다. depth 별 단일 펼침이 필요하면 `SExpansionList` 다 (§3-7-7).
1924
1926
  - **`SList` 의 자식은 `SListItem` 을 권장한다.** 다른 자식도 그대로 렌더되지만, 펼치는 항목은 `SExpansionList` + `SExpansionItem` 이, 끌어서 순서를 바꾸는 항목은 `SDraggableList` + `SDraggableItem` 이 여닫힘·정렬 동작까지 함께 관리하므로 그쪽을 쓴다 (§3-7-7).
@@ -1953,13 +1955,34 @@ const [from, setFrom] = useState<string | null>(null);
1953
1955
  ❌ <div onKeyDown={e => { e.stopPropagation(); … }}> {/* 리스트가 이미 걸러 준다 */}
1954
1956
  ```
1955
1957
 
1956
- #### 3-7-7. 펼치는 셋 — SExpansionItem vs SExpansionList vs STree
1958
+ #### 3-7-7. 펼치는 넷 — SExpansionItem vs SExpansionList vs STree vs STreeTable
1957
1959
 
1958
1960
  | 판별 | 사용 |
1959
1961
  | --- | --- |
1960
1962
  | 항목들이 **서로 독립적으로** 여닫힌다 (여러 개 동시에 열려도 됨) | `SExpansionItem` 단독 |
1961
1963
  | **한 번에 하나만** 열려야 한다 (아코디언) | `SExpansionList` + `SExpansionItem` |
1962
1964
  | **부모-자식 계층 자체**를 보여줘야 한다 (2단 이상, 연결선) | `STree` |
1965
+ | 계층을 이루는 행마다 **열이 둘 이상**이다 (재고·가격처럼 행끼리 비교하는 값) | `STreeTable` |
1966
+
1967
+ `STreeTable` 은 `STable` 에 계층을 붙인 것이다. 헤더·셀·밀도·정렬 버튼·sticky·가상 스크롤은 `STable` 과 같고, 컬럼 규칙(§3-4)도 그대로 따른다. 다른 점만 적는다.
1968
+
1969
+ - **하위 행은 각 행의 `children` 에 같은 모양으로 넣는다.** 필드 이름이 다르면 `childrenKey` 로 알려 준다. 평평한 목록에 `parentId` 를 달아 넘기지 않는다 — 계층으로 바꿔서 넘긴다.
1970
+ - **펼침 버튼·들여쓰기는 컴포넌트가 그린다.** 기본은 보이는 첫 컬럼이고 `treeColumn` 으로 옮긴다. 그 컬럼은 왼쪽 정렬로 두고, 셀 내용은 `render`·`format` 으로 바꾼다 — `renderCell` 은 펼침 버튼을 넣을 자리가 없어 에러가 난다.
1971
+ - **셀 병합은 가로(`colSpan`)만 한다.** 트리 컬럼이 아닌 컬럼은 `renderCell` 로 `<td>` 를 바꿀 수 있고, 한 행 안에서 끝나는 `colSpan` 은 접고 펴도 그대로다. **`rowSpan` 으로 세로 병합하지 않는다** — 행이 접히면 사라진 행 몫까지 병합이 남아 아래 행의 칸을 덮고, 덮인 행의 칸은 옆 컬럼으로 밀려난다. 부모와 하위 행에 같은 값이 반복되면 부모 행에만 쓰고 하위 행은 비워 둔다.
1972
+ - **펼침 영역은 트리 컬럼 셀 전체다.** 하위 행이 있는 행은 펼침 버튼뿐 아니라 그 셀 어디를 눌러도 접고 편다. 다른 셀을 누르면 행 클릭(`onRowClick`)이다 — 트리 컬럼 셀을 누른 것은 행 클릭으로 가지 않는다.
1973
+ - **펼침 모션은 컴포넌트가 넣는다.** 펼쳐서 새로 보이게 된 행이 위에서 내려오며 나타나고(접을 때는 바로 사라진다), 모션을 줄인 환경에서는 꺼진다. 행에 애니메이션 클래스를 직접 붙이지 않는다.
1974
+ - **트리 컬럼에 링크·버튼을 넣어도 된다.** 셀 안의 링크·버튼·입력을 누르면 그 동작만 일어나고 펼침은 일어나지 않는다 — `stopPropagation` 을 직접 넣지 않는다. 상품명을 상세 링크로 거는 것처럼 쓴다.
1975
+ - **선택은 계층을 따른다.** 부모를 고르면 접힌 하위 행까지 함께 골라지고, 일부만 골라진 부모는 "일부 선택"으로 그려진다. 하위 행이 모두 골라지면 부모도 `selected` 에 들어간다 — 처리 대상이 잎 행뿐이면 받은 목록에서 하위 행이 없는 행만 걸러 쓴다.
1976
+ - **가로로 스크롤되는 표는 트리 컬럼을 왼쪽에 고정한다**(`stickyColumn={{ left: 1 }}`, 트리 컬럼이 첫 컬럼일 때). 스크롤로 들여쓰기가 밀려나면 어느 행이 누구의 하위인지 읽히지 않는다. 체크박스 열은 `selectable` 이면 늘 고정되므로 개수에 넣지 않는다.
1977
+ - **컬럼 폭 조절(`resizable`)은 `STable` 과 달리 기본으로 켜져 있다.** 폭이 고정이어야 하는 표만 `resizable={false}` 로 끈다.
1978
+ - **트리 컬럼에는 `minWidth` 를 준다.** 폭 조절이 켜져 있으므로, 하한이 없으면 들여쓰기보다 좁게 줄어 깊은 행의 이름이 통째로 가려진다. 값은 가장 깊은 행의 이름이 남을 만큼으로 정한다.
1979
+ - **페이지네이션·드래그 선택은 받지 않는다.** 페이지 경계가 부모와 자식 사이를 자르면 계층이 읽히지 않는다. 행이 많으면 `virtualScroll` 을 쓴다.
1980
+ - **정렬은 형제끼리 한다.** `STable` 처럼 받은 순서대로 그리므로, 정렬한 결과를 넘길 때 계층을 풀어 한 줄로 정렬하지 않는다.
1981
+
1982
+ ```tsx
1983
+ ✅ <STreeTable<Category> columns={columns} rows={categories} selectable selected={selected} onSelectedChange={setSelected} />
1984
+ ❌ <STable rows={flatten(categories)} columns={[{ …, render: row => `${' '.repeat(row.depth)}${row.name}` }]} /> {/* 계층을 공백으로 흉내 내지 않는다 */}
1985
+ ```
1963
1986
 
1964
1987
  `SExpansionList` 는 depth 별 **단일 확장**을 관리하는 wrapper 다. 직접 `useState` 로 "열린 항목 하나"를 들고 있지 않는다. 항목 사이 구분선은 여기서도 리스트가 알아서 그린다 — 따로 줄 prop 이 없다 (§3-7-6).
1965
1988
 
@@ -5589,7 +5612,7 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
5589
5612
  --sys-color-purple-strong
5590
5613
  --sys-color-purple-subtle
5591
5614
 
5592
- ## 3. 컴포넌트 인덱스 (88종)
5615
+ ## 3. 컴포넌트 인덱스 (89종)
5593
5616
 
5594
5617
  **Props 는 이 문서에 없다.** 쓸 컴포넌트를 정했으면 그 컴포넌트의 README 를 읽는다.
5595
5618
 
@@ -5598,4 +5621,4 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
5598
5621
  예) SButton 을 쓴다면 `dist/components/SButton/README.md`.
5599
5622
  prop 을 추측해서 쓰지 말고 반드시 README 로 확인한다 (분류별 용도는 §1 의 "전체 컴포넌트 인덱스" 참조).
5600
5623
 
5601
- SAccountListBox · SActionModal · SBadge · SBarChart · SBarcodeInput · SButton · SCalendar · SCalendarBoard · SCallout · SCard · SChatAttachedFile · SChatFile · SChatInput · SChatMessage · SChatSystemMessage · SCheckbox · SChip · SChipFilter · SChipInput · SCircleProgress · SConfirmModal · SContextAlert · SDatePicker · SDateRangePicker · SDivider · SDonutChart · SDraggableItem · SDraggableList · SDrawer · SDropdownButton · SEditor · SExpansionItem · SExpansionList · SField · SFilePicker · SForm · SGhostButton · SGnb · SGnbSystem · SGuide · SIcon · SImage · SInput · SKeyValueTable · SLauncherListBox · SLayout · SLineChart · SLinearProgress · SList · SListItem · SLoadingContainer · SLoadingModal · SLoginCard · SLogo · SMeatballButton · SModal · SNumberInput · SPage · SPagination · SPieChart · SPopover · SPopup · SPortal · SRadio · SRadioButton · SRadioCard · SScrollArea · SSearchInput · SSectionHeaderCard · SSelect · SSkeleton · SSplitter · SStepper · SSwitch · SSystemActionButton · STable · STableBar · STabs · STag · STextLink · STextarea · STimePicker · STimeRangePicker · STimeline · SToast · SToggle · STooltip · STree
5624
+ SAccountListBox · SActionModal · SBadge · SBarChart · SBarcodeInput · SButton · SCalendar · SCalendarBoard · SCallout · SCard · SChatAttachedFile · SChatFile · SChatInput · SChatMessage · SChatSystemMessage · SCheckbox · SChip · SChipFilter · SChipInput · SCircleProgress · SConfirmModal · SContextAlert · SDatePicker · SDateRangePicker · SDivider · SDonutChart · SDraggableItem · SDraggableList · SDrawer · SDropdownButton · SEditor · SExpansionItem · SExpansionList · SField · SFilePicker · SForm · SGhostButton · SGnb · SGnbSystem · SGuide · SIcon · SImage · SInput · SKeyValueTable · SLauncherListBox · SLayout · SLineChart · SLinearProgress · SList · SListItem · SLoadingContainer · SLoadingModal · SLoginCard · SLogo · SMeatballButton · SModal · SNumberInput · SPage · SPagination · SPieChart · SPopover · SPopup · SPortal · SRadio · SRadioButton · SRadioCard · SScrollArea · SSearchInput · SSectionHeaderCard · SSelect · SSkeleton · SSplitter · SStepper · SSwitch · SSystemActionButton · STable · STableBar · STabs · STag · STextLink · STextarea · STimePicker · STimeRangePicker · STimeline · SToast · SToggle · STooltip · STree · STreeTable
package/dist/styles.css CHANGED
@@ -425,6 +425,7 @@
425
425
  --animate-floating-out-bottom: floating-out-bottom 0.15s ease-in forwards;
426
426
  --animate-floating-out-left: floating-out-left 0.15s ease-in forwards;
427
427
  --animate-floating-out-right: floating-out-right 0.15s ease-in forwards;
428
+ --animate-table-row-in: floating-in-bottom 0.15s ease-out;
428
429
  --animate-skeleton-wave: skeleton-wave 1.5s linear 0.5s infinite;
429
430
  --animate-skeleton-pulse: skeleton-pulse 1.5s ease-in-out 0.5s infinite;
430
431
  --animate-skeleton-fade: skeleton-fade 1.5s linear 0.5s infinite;
@@ -3846,6 +3847,9 @@
3846
3847
  .pl-\(--cmp-radioCard-subtitle-paddingLeft\) {
3847
3848
  padding-left: var(--cmp-radioCard-subtitle-paddingLeft);
3848
3849
  }
3850
+ .pl-5 {
3851
+ padding-left: calc(var(--spacing) * 5);
3852
+ }
3849
3853
  .pl-\[16px\] {
3850
3854
  padding-left: 16px;
3851
3855
  }
@@ -5759,6 +5763,11 @@
5759
5763
  scrollbar-color: var(--color-grey-45) var(--color-white);
5760
5764
  }
5761
5765
  }
5766
+ .motion-safe\:animate-table-row-in {
5767
+ @media (prefers-reduced-motion: no-preference) {
5768
+ animation: var(--animate-table-row-in);
5769
+ }
5770
+ }
5762
5771
  .motion-reduce\:hidden {
5763
5772
  @media (prefers-reduced-motion: reduce) {
5764
5773
  display: none;
package/dist/theme.css CHANGED
@@ -2470,6 +2470,12 @@
2470
2470
  --animate-floating-out-left: floating-out-left 0.15s ease-in forwards;
2471
2471
  --animate-floating-out-right: floating-out-right 0.15s ease-in forwards;
2472
2472
 
2473
+ /* 표 행 펼침 (STreeTable) — 여러 행을 연달아 열고 닫는 반복 조작이라 툴팁(0.35s)·STree(0.2s)보다 짧게 둔다.
2474
+ 0.1s 아래로 내리면 움직임이 보이지 않아 깜빡임처럼 읽힌다.
2475
+ 모양은 아래로 열리는 floating 과 같다 (위에서 4px 내려오며 나타남) */
2476
+ --animate-table-row-in: floating-in-bottom 0.15s ease-out;
2477
+ /* 접을 때는 모션 없이 바로 뺀다. 사라지는 모션을 넣으면 그 동안 아래 행이 기다렸다 올라와 굼떠 보인다 */
2478
+
2473
2479
  /* 스켈레톤 (Quasar QSkeleton 포팅). 속도는 SSkeleton 이 animation-duration 으로 덮어쓴다 */
2474
2480
  --animate-skeleton-wave: skeleton-wave 1.5s linear 0.5s infinite;
2475
2481
  --animate-skeleton-pulse: skeleton-pulse 1.5s ease-in-out 0.5s infinite;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sellmate-design-system-react",
3
- "version": "9.0.0-beta.87",
3
+ "version": "9.0.0-beta.89",
4
4
  "description": "Sellmate Design System — React (TypeScript + Tailwind v4) port",
5
5
  "license": "UNLICENSED",
6
6
  "keywords": [