sellmate-design-system-react 3.0.0 → 3.1.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/AGENTS.md +661 -0
- package/README.md +85 -0
- package/dist/components/SActionModal/README.md +41 -0
- package/dist/components/SBadge/README.md +25 -0
- package/dist/components/SBarcodeInput/README.md +64 -0
- package/dist/components/SButton/README.md +49 -0
- package/dist/components/SCalendar/README.md +42 -0
- package/dist/components/SCallout/README.md +29 -0
- package/dist/components/SCard/README.md +12 -0
- package/dist/components/SCheckbox/README.md +44 -0
- package/dist/components/SChip/README.md +57 -0
- package/dist/components/SChipInput/README.md +77 -0
- package/dist/components/SCircleProgress/README.md +35 -0
- package/dist/components/SConfirmModal/README.md +61 -0
- package/dist/components/SDatePicker/README.md +62 -0
- package/dist/components/SDateRangePicker/README.md +64 -0
- package/dist/components/SDivider/README.md +25 -0
- package/dist/components/SDraggableItem/README.md +40 -0
- package/dist/components/SDropdownButton/README.md +50 -0
- package/dist/components/SExpansionItem/README.md +40 -0
- package/dist/components/SField/README.md +91 -0
- package/dist/components/SFilePicker/README.md +72 -0
- package/dist/components/SForm/README.md +31 -0
- package/dist/components/SGhostButton/README.md +76 -0
- package/dist/components/SGnb/README.md +56 -0
- package/dist/components/SGuide/README.md +34 -0
- package/dist/components/SIcon/README.md +91 -0
- package/dist/components/SInput/README.md +66 -0
- package/dist/components/SKeyValueTable/README.md +59 -0
- package/dist/components/SLayout/README.md +42 -0
- package/dist/components/SLinearProgress/README.md +17 -0
- package/dist/components/SList/README.md +14 -0
- package/dist/components/SListItem/README.md +19 -0
- package/dist/components/SLoadingContainer/README.md +29 -0
- package/dist/components/SLoadingModal/README.md +52 -0
- package/dist/components/SModal/README.md +192 -0
- package/dist/components/SModalContainer/README.md +49 -0
- package/dist/components/SNumberInput/README.md +74 -0
- package/dist/components/SPage/README.md +25 -0
- package/dist/components/SPagination/README.md +40 -0
- package/dist/components/SPopover/README.md +54 -0
- package/dist/components/SPopup/README.md +38 -0
- package/dist/components/SPortal/README.md +51 -0
- package/dist/components/SRadio/README.md +57 -0
- package/dist/components/SRadioButton/README.md +24 -0
- package/dist/components/SScrollArea/README.md +16 -0
- package/dist/components/SSectionHeaderCard/README.md +51 -0
- package/dist/components/SSelect/README.md +79 -0
- package/dist/components/SStepper/README.md +30 -0
- package/dist/components/SSwitch/README.md +24 -0
- package/dist/components/STable/README.md +82 -0
- package/dist/components/STableBar/README.md +28 -0
- package/dist/components/STabs/README.md +37 -0
- package/dist/components/STag/README.md +44 -0
- package/dist/components/STextLink/README.md +48 -0
- package/dist/components/STextarea/README.md +60 -0
- package/dist/components/STimePicker/README.md +65 -0
- package/dist/components/STimeRangePicker/README.md +63 -0
- package/dist/components/SToast/README.md +70 -0
- package/dist/components/SToggle/README.md +22 -0
- package/dist/components/STooltip/README.md +57 -0
- package/dist/llms.txt +3496 -0
- package/dist/styles.css +209 -0
- package/dist/theme.css +8 -0
- package/eslint/index.mjs +66 -0
- package/eslint/lib/class-names.mjs +119 -0
- package/eslint/lib/table-column.mjs +53 -0
- package/eslint/rules/no-arbitrary-class.mjs +91 -0
- package/eslint/rules/no-off-scale-spacing.mjs +67 -0
- package/eslint/rules/no-raw-html-control.mjs +117 -0
- package/eslint/rules/prefer-typo-preset.mjs +73 -0
- package/eslint/rules/require-locale-number.mjs +78 -0
- package/eslint/rules/table-numeric-align.mjs +93 -0
- package/eslint/scale.gen.mjs +16 -0
- package/package.json +9 -4
package/dist/llms.txt
ADDED
|
@@ -0,0 +1,3496 @@
|
|
|
1
|
+
<!-- 자동 생성: npm run build (scripts/gen-llms.mjs). 직접 수정 금지. -->
|
|
2
|
+
|
|
3
|
+
# sellmate-design-system-react — AI 에이전트 참조 문서
|
|
4
|
+
|
|
5
|
+
이 파일 하나에 사용 규칙(§1)·토큰 어휘(§2)·전체 컴포넌트 Props(§3)가 들어 있다.
|
|
6
|
+
|
|
7
|
+
## 1. 사용 규칙 (AGENTS.md 전문)
|
|
8
|
+
|
|
9
|
+
# sellmate-design-system-react — 사용 규칙 (AGENTS.md)
|
|
10
|
+
|
|
11
|
+
> **대상**: 이 패키지로 화면을 만드는 소비 앱의 개발자와 AI 코딩 에이전트(Claude 등).
|
|
12
|
+
> 이 문서는 "무엇을 언제 쓰고, 무엇을 쓰면 안 되는지"의 단일 기준이다.
|
|
13
|
+
> 개별 컴포넌트의 상세 Props/Events는 `node_modules/sellmate-design-system-react/dist/components/<이름>/README.md` 를 참조한다.
|
|
14
|
+
|
|
15
|
+
## 0. 최우선 원칙 — 디자인 시스템 컴포넌트가 먼저다
|
|
16
|
+
|
|
17
|
+
**화면 요소를 만들기 전에, 그 역할을 하는 컴포넌트가 이미 있는지 먼저 확인한다.**
|
|
18
|
+
있으면 반드시 그것을 쓴다. 직접 만드는 것은 대응 컴포넌트가 **없다는 것을 확인한 뒤**의 최후 수단이다.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
❌ <button onClick={save}>저장</button> ✅ <SButton label="저장" onClick={save} />
|
|
22
|
+
❌ <table>…</table> ✅ <STable columns={columns} rows={rows} />
|
|
23
|
+
❌ <div className="rounded border p-16">…</div> ✅ <SSectionHeaderCard>…</SSectionHeaderCard>
|
|
24
|
+
❌ <ul><li>…</li></ul> ✅ <SList><SListItem title="…" /></SList>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
"비슷하게 생긴 것을 직접 만드는 것"이 어색함의 가장 큰 원인이다. 대응 컴포넌트를 쓰면 색·간격·상태·접근성이 전부 따라온다.
|
|
28
|
+
|
|
29
|
+
### 0-1. 전체 컴포넌트 인덱스
|
|
30
|
+
|
|
31
|
+
무엇을 만들지 정했으면 **이 표에서 먼저 찾는다.** 상세 Props 는 `dist/components/<이름>/README.md` 참조.
|
|
32
|
+
|
|
33
|
+
| 분류 | 컴포넌트 |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| **버튼·링크** | `SButton` `SGhostButton` `SDropdownButton` `STextLink` `SSwitch` `SToggle` |
|
|
36
|
+
| **입력 (폼)** | `SForm` `SField` `SInput` `SNumberInput` `STextarea` `SSelect` `SCheckbox` `SRadio` `SRadioButton` `SChip` `SChipInput` `SBarcodeInput` `SFilePicker` |
|
|
37
|
+
| **날짜·시간** | `SCalendar` `SDatePicker` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
|
|
38
|
+
| **표·목록** | `STable` `STableBar` `SKeyValueTable` `SList` `SListItem` `SDraggableItem` |
|
|
39
|
+
| **레이아웃** | `SLayout` `SGnb` `SPage` `SSectionHeaderCard` `SCard` `SDivider` `SScrollArea` `SExpansionItem` |
|
|
40
|
+
| **내비게이션** | `STabs` `SPagination` `SStepper` |
|
|
41
|
+
| **표시·상태** | `STag` `SBadge` `SIcon` `SCallout` `SGuide` |
|
|
42
|
+
| **진행·로딩** | `SLinearProgress` `SCircleProgress` `SLoadingContainer` `SLoadingModal` |
|
|
43
|
+
| **오버레이** | `STooltip` `SPopover` `SPopup` `SPortal` |
|
|
44
|
+
| **모달** | `SModal.confirm()` `SModal.create()` + `SActionModal` `SConfirmModal` |
|
|
45
|
+
| **알림** | `SToast` `SToastContainer` |
|
|
46
|
+
|
|
47
|
+
표에 없는 UI 를 만들어야 할 때만 `div` 로 직접 조립하고, 그때도 §1-2 · §2 의 토큰 규칙을 지킨다.
|
|
48
|
+
|
|
49
|
+
### 0-2. 프로젝트 설정
|
|
50
|
+
|
|
51
|
+
설정(Tailwind v4 `theme.css` import, `@source` 지정, Next.js 주의사항)은 패키지 [README.md](./README.md)를 따른다. 이 문서는 설정이 끝난 상태에서의 **화면 작성 규칙**만 다룬다.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 1. 절대 규칙 (금지 목록)
|
|
56
|
+
|
|
57
|
+
AI 에이전트는 코드를 생성하기 전에 이 목록을 반드시 지킨다.
|
|
58
|
+
|
|
59
|
+
### 1-1. 생 HTML 컨트롤 금지
|
|
60
|
+
|
|
61
|
+
§0 원칙의 구체적 목록이다. 아래 요소는 **어떤 경우에도** 생 HTML 로 만들지 않는다.
|
|
62
|
+
|
|
63
|
+
| 금지 | 대신 사용 |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| `<button>` | `SButton`, `SGhostButton`, `SDropdownButton`, `STextLink` |
|
|
66
|
+
| `<input type="text/password/...">` | `SInput` |
|
|
67
|
+
| `<input type="number">` | `SNumberInput` |
|
|
68
|
+
| `<input type="checkbox">` | `SCheckbox`, `SToggle`, `SSwitch` |
|
|
69
|
+
| `<input type="radio">` | `SRadio`, `SRadioButton` |
|
|
70
|
+
| `<input type="file">` | `SFilePicker` |
|
|
71
|
+
| `<select>` | `SSelect` |
|
|
72
|
+
| `<textarea>` | `STextarea` |
|
|
73
|
+
| `<table>` | `STable`, `SKeyValueTable` |
|
|
74
|
+
| `<form>` | `SForm` |
|
|
75
|
+
| `<dialog>`, 직접 만든 오버레이 | `SModal.confirm(...)`, `SModal.create(...)`, `SPopup` |
|
|
76
|
+
| `alert()`, `confirm()` | `SToast`, `SModal.confirm(...)` |
|
|
77
|
+
| 직접 만든 탭/페이지네이션/스텝퍼 | `STabs`, `SPagination`, `SStepper` |
|
|
78
|
+
| `<ul>`/`<li>` 로 만든 목록 UI | `SList` + `SListItem` (드래그 정렬은 `SDraggableItem`) |
|
|
79
|
+
| 직접 만든 섹션 카드(제목 바 + 본문 박스) | `SSectionHeaderCard` + `.Header` / `.Body` |
|
|
80
|
+
| `<svg>` 직접 삽입, 이모지 아이콘 | `SIcon` |
|
|
81
|
+
| `<hr>` | `SDivider` |
|
|
82
|
+
| `<details>` / `<summary>` | `SExpansionItem` |
|
|
83
|
+
| `<progress>` | `SLinearProgress`, `SCircleProgress` |
|
|
84
|
+
| `<label>` (폼 레이블) | `SField` 의 `label` prop |
|
|
85
|
+
| 직접 만든 카드·패널 박스 | `SCard`, `SSectionHeaderCard` |
|
|
86
|
+
| 직접 만든 스크롤 영역 | `SScrollArea` |
|
|
87
|
+
|
|
88
|
+
예외: 순수 레이아웃 요소(`div`, `section`, 시맨틱 `h1~h6`, `p`, `span`, `a`)는 허용. 단 스타일은 아래 규칙을 따른다.
|
|
89
|
+
|
|
90
|
+
### 1-2. 임의 값(arbitrary literal) 금지
|
|
91
|
+
|
|
92
|
+
Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
❌ text-[14px] font-[600] bg-[#eee] gap-[13px] p-[10px] rounded-[5px] text-[#333]
|
|
96
|
+
✅ typo-body-sm-default text-fg-tertiary bg-bg-frame gap-12 p-8 rounded-md
|
|
97
|
+
✅ w-[var(--sys-size-control-md-height)] ← 토큰을 var()로 참조하는 것은 허용
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- 하드코딩 hex/px/rem 리터럴은 어디에도 쓰지 않는다 (인라인 `style` 포함).
|
|
101
|
+
- 인라인 `style`은 런타임 계산값(동적 width 등)에만 허용한다.
|
|
102
|
+
|
|
103
|
+
**단, 디자인 토큰이 없는 속성의 임의 값은 정당하다.** 화면 고유의 레이아웃 치수가 여기 해당한다.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
✅ <div className="w-[280px] max-w-[1200px] grid-cols-[200px_1fr]" /> // 앱 고유 치수
|
|
107
|
+
❌ <div className="text-[13px] bg-[#eee] gap-[13px] rounded-[5px]" /> // 토큰이 있는 속성
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
규칙은 **색 · 타이포 · 간격 · 모서리** 네 계열에만 적용된다 — 이 넷은 토큰이 이미 있으므로 임의 값은 곧 디자인 시스템 우회다.
|
|
111
|
+
|
|
112
|
+
### 1-3. 타이포그래피는 프리셋으로만
|
|
113
|
+
|
|
114
|
+
`text-14 font-bold` 같은 조합을 즉흥으로 만들지 않는다. §2-1의 `typo-*` 프리셋 클래스를 쓴다.
|
|
115
|
+
|
|
116
|
+
### 1-4. 숫자는 무조건 `toLocaleString()`
|
|
117
|
+
|
|
118
|
+
**숫자를 화면에 표시할 때는 예외 없이 `toLocaleString()` 을 거쳐 세 자리마다 콤마를 넣는다.**
|
|
119
|
+
금액·수량·건수·재고 무엇이든, 테이블·상세·요약 문구 어디에 놓이든 같다.
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
❌ <span>{price}원</span> ❌ {`${qty}개`} ❌ {String(count)}
|
|
123
|
+
✅ <span>{price.toLocaleString()}원</span>
|
|
124
|
+
✅ format: (v: number) => `${Number(v).toLocaleString()}개`
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
콤마 없는 `39000` 은 자릿수를 세어야 읽히지만 `39,000` 은 한눈에 읽힌다. 숫자를 그대로 출력하는 코드는 미완성으로 본다.
|
|
128
|
+
|
|
129
|
+
전화번호·사업자번호처럼 하이픈이 들어가는 값은 애초에 숫자가 아니라 **서식이 정해진 문자열**이므로 이 규칙의 대상이 아니다.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 2. 조합 어휘 — 컴포넌트 "사이"를 채울 때 쓰는 것들
|
|
134
|
+
|
|
135
|
+
### 2-1. 타이포그래피 프리셋
|
|
136
|
+
|
|
137
|
+
역할(role) → 크기 → 굵기 순으로 조합된 클래스가 이미 준비되어 있다.
|
|
138
|
+
|
|
139
|
+
| 용도 | 클래스 |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| 페이지/섹션 제목 | `typo-heading-lg`(18px) · `typo-heading-md`(16px) · `typo-heading-sm`(14px) · `typo-heading-xs`(12px) |
|
|
142
|
+
| 본문 | `typo-body-lg-*` (16px) · `typo-body-md-*`(14px) · `typo-body-sm-*`(12px) · `typo-body-xs-default`(11px) — `*` = `default`/`medium`/`bold` |
|
|
143
|
+
| 테이블 | `typo-table-header` · `typo-table-body` · `typo-table-accent` |
|
|
144
|
+
| 컨트롤·필드·피드백·내비 | `typo-control-*` `typo-field-*` `typo-feedback-*` `typo-navigation-*` (컴포넌트 내부용 — 직접 쓸 일은 드묾) |
|
|
145
|
+
|
|
146
|
+
**기본 선택 — 이 조합을 쓴다.** 이 서비스는 정보 밀도가 높아 본문이 12px 이다. 14px 를 본문 기본으로 쓰지 않는다.
|
|
147
|
+
|
|
148
|
+
| 역할 | 클래스 | 크기 |
|
|
149
|
+
| --- | --- | --- |
|
|
150
|
+
| 페이지 헤더 제목 (h1) | `typo-heading-lg` | 18px |
|
|
151
|
+
| 섹션 제목 | `typo-heading-sm` | 14px |
|
|
152
|
+
| 본문 | `typo-body-sm-default` | 12px |
|
|
153
|
+
| 보조 설명 | `typo-body-sm-default` + `text-fg-tertiary` | 12px / `grey_65` |
|
|
154
|
+
|
|
155
|
+
페이지 제목만 18px 로 크게 두고 그 아래는 14 / 12 로 촘촘하게 간다. 중간 크기(16px)는 기본 골격에서 쓰지 않는다.
|
|
156
|
+
|
|
157
|
+
### 2-2. 간격 (spacing)
|
|
158
|
+
|
|
159
|
+
- 유틸리티 숫자 = px. 스케일: `2 4 6 8 10 12 16 19 20 22 24 28 32 36 40 48 60`
|
|
160
|
+
- 형제 요소 간격은 margin 대신 부모의 `flex`/`grid` + `gap-*`으로 잡는다.
|
|
161
|
+
- 시맨틱 간격 토큰 (텍스트 덩어리·요소 사이 기본 리듬):
|
|
162
|
+
|
|
163
|
+
| 상황 | 값 |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| **페이지 콘텐츠 패딩** | **`p-20`** |
|
|
166
|
+
| **섹션 ↔ 섹션** | **`gap-12`** |
|
|
167
|
+
| **페이지 내 블록 ↔ 블록** (헤더·필터·툴바·테이블 사이) | **`gap-12`** |
|
|
168
|
+
| 요소 ↔ 요소 (기본) | `gap-8` (`--sys-space-stack-gap-element-normal`) |
|
|
169
|
+
| 제목 ↔ 설명 텍스트 | `gap-4` (`--sys-space-stack-gap-text-normal`) |
|
|
170
|
+
|
|
171
|
+
정보 밀도가 높은 서비스라 블록 간격을 넓게 벌리지 않는다. `gap-16` / `gap-24` 를 페이지 골격의 기본값으로 쓰지 않는다.
|
|
172
|
+
|
|
173
|
+
### 2-3. 색상
|
|
174
|
+
|
|
175
|
+
**시맨틱 유틸리티를 우선 사용한다** — 의미가 이름에 담긴 토큰이 이미 유틸리티로 존재한다.
|
|
176
|
+
|
|
177
|
+
#### 텍스트 색은 두 단계뿐이다
|
|
178
|
+
|
|
179
|
+
| 용도 | 유틸리티 | 값 |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| **본문·제목 (기본값)** | 지정하지 않는다 — 전역 기본색이 이미 적용된다 | `grey_95` `#222222` |
|
|
182
|
+
| **보조 설명 · 비활성** | **`text-fg-tertiary`** | `grey_65` `#888888` |
|
|
183
|
+
|
|
184
|
+
- `theme.css` 가 `body` 에 `grey_95` 를 깔아두므로 **본문에 텍스트 색 클래스를 붙이지 않는다.** `text-fg-primary` 를 매번 쓰는 것은 불필요하다.
|
|
185
|
+
- 흐리게 보여야 하는 것은 보조 설명이든 비활성이든 **전부 `text-fg-tertiary`** 다.
|
|
186
|
+
- 중간 톤(`text-fg-secondary` `#555`)은 텍스트 위계에 쓰지 않는다. 두 단계로만 간다.
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
✅ <p>주문이 접수되었습니다.</p> // 색 지정 없음 = grey_95
|
|
190
|
+
✅ <p className="text-fg-tertiary">최근 30일 기준</p> // 보조 설명
|
|
191
|
+
✅ <span className="text-fg-tertiary">-</span> // 빈 값 (§3-4)
|
|
192
|
+
❌ <p className="text-fg-primary">주문이 접수되었습니다.</p> // 불필요
|
|
193
|
+
❌ <p className="text-fg-secondary">최근 30일 기준</p> // 중간 톤 사용
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### 그 밖의 색
|
|
197
|
+
|
|
198
|
+
| 용도 | 유틸리티 |
|
|
199
|
+
| --- | --- |
|
|
200
|
+
| 상태 텍스트 | `text-fg-danger` `text-fg-success` `text-fg-warning` `text-fg-accent` `text-fg-inverse` |
|
|
201
|
+
| 배경 | `bg-bg-frame`(흰 콘텐츠 면) · `bg-bg-neutralLight`/`bg-bg-neutralBright`(옅은 회색 면) · `bg-bg-screen`(앱 바탕) |
|
|
202
|
+
| 보더/구분선 | `border-border-default` · `border-border-strong` · `border-divider-default` |
|
|
203
|
+
| 비활성 배경·보더 | `bg-disabled-bg` `border-disabled-border` |
|
|
204
|
+
| 링크 | `text-link-accent` |
|
|
205
|
+
|
|
206
|
+
- 시맨틱 토큰에 맞는 항목이 없을 때만 원색 스케일(`bg-blue-subtle` 등)을 쓴다.
|
|
207
|
+
- 어느 쪽이든 **토큰 유틸리티만** 사용 — 리터럴 hex 금지.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 3. 컴포넌트 선택 규칙 — "언제 뭘 쓰나"
|
|
212
|
+
|
|
213
|
+
> ⚠️ 초안(개발 작성). <!-- TODO(디자인): 전체 검수·확정 --> 표시가 있는 행은 디자인 확정 전까지 초안 기준으로 사용.
|
|
214
|
+
|
|
215
|
+
### 3-1. 라벨/표시류 — STag vs SBadge vs SChip
|
|
216
|
+
|
|
217
|
+
| 상황 | 사용 |
|
|
218
|
+
| --- | --- |
|
|
219
|
+
| **상태·분류를 라벨로 표시 (기본값)** | **`STag`** — `<STag size="sm" color="..." label="판매중" />`. 목록의 상태 컬럼, 상세의 분류 태그 등 대부분이 여기 해당한다 |
|
|
220
|
+
| 라벨 없이 **색 점만**으로 상태를 찍을 때 | `SBadge` — 점(dot)만 그리는 인디케이터. 텍스트가 이미 있고 앞에 점만 붙이는 좁은 경우에만 |
|
|
221
|
+
| 사용자가 입력·삭제·편집하는 **토큰** | `SChip` (단독) / `SChipInput` (입력 필드 안에서) |
|
|
222
|
+
|
|
223
|
+
> 상태 표시는 **`STag size="sm"` 이 기본**이다. 색 점 + 텍스트 조합(`SBadge`)을 기본으로 쓰지 않는다.
|
|
224
|
+
|
|
225
|
+
### 3-2. 알림/안내류
|
|
226
|
+
|
|
227
|
+
| 상황 | 사용 |
|
|
228
|
+
| --- | --- |
|
|
229
|
+
| 화면에 **상시 노출**되는 안내·경고 문구 | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
|
|
230
|
+
| 작업 결과를 **일시적으로** 알림 | `SToast` (+ 루트에 `SToastContainer`) |
|
|
231
|
+
| 진행 전 **확인/취소**를 받아야 할 때 | `SModal.confirm({...}).onOk(...)` |
|
|
232
|
+
| 특정 UI 요소에 대한 **온보딩·기능 안내** | `SGuide` |
|
|
233
|
+
| 로딩 중 화면 잠금 | `SLoadingModal` / 영역 로딩은 `SLoadingContainer` |
|
|
234
|
+
|
|
235
|
+
### 3-3. 플로팅/오버레이류
|
|
236
|
+
|
|
237
|
+
| 상황 | 사용 |
|
|
238
|
+
| --- | --- |
|
|
239
|
+
| hover 시 **짧은 보조 설명** (상호작용 없음) | `STooltip` |
|
|
240
|
+
| 클릭 시 **상호작용 가능한** 콘텐츠 (메뉴·미니 폼) | `SPopover` |
|
|
241
|
+
| **팝업** (별도 창 성격의 가벼운 표시) | `SPopup` |
|
|
242
|
+
| 페이지 흐름을 끊고 **작업을 완료**시키는 창 | **`SActionModal` 로 컴포넌트를 만들고 `SModal.create` 로 띄운다** (아래 참조) |
|
|
243
|
+
| 확인/취소만 받는 창 | `SModal.confirm(...)` |
|
|
244
|
+
| 로딩 중 화면 잠금 | `SModal.loading(...)` / `SLoadingModal` |
|
|
245
|
+
|
|
246
|
+
**모달 만드는 법** — 디자인 시스템이 띄우는 모달은 `SActionModal` · `SConfirmModal` · `SLoadingModal` 3종뿐이고 `create` · `confirm` · `loading` 이 1:1로 대응한다.
|
|
247
|
+
직접 오버레이를 만들지 않는다. 작업용 모달은 **`SActionModal` 을 루트로 하는 컴포넌트를 만들어 `SModal.create` 에 넘긴다.**
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
// 1) SActionModal 을 루트로 하는 컴포넌트를 만든다
|
|
251
|
+
// create 가 주입하는 open / onOpenChange / onClose 를 그대로 SActionModal 에 전달해야 한다
|
|
252
|
+
function OrderModal({ orderId, open, onOpenChange, onClose, modalRef }: OrderModalProps) {
|
|
253
|
+
return (
|
|
254
|
+
<SActionModal
|
|
255
|
+
open={open}
|
|
256
|
+
onOpenChange={onOpenChange}
|
|
257
|
+
onClose={onClose}
|
|
258
|
+
modalTitle="주문 상세"
|
|
259
|
+
width={720}
|
|
260
|
+
// 주 액션은 button(단수), 보조 버튼은 footerLeft — 하단 버튼 양끝 분리 규칙과 같다
|
|
261
|
+
button={{ label: '접수', onClick: () => modalRef.ok() }}
|
|
262
|
+
footerLeft={<SButton color="secondary" label="취소" onClick={() => modalRef.cancel()} />}
|
|
263
|
+
>
|
|
264
|
+
<SKeyValueTable fields={orderFields} values={order} />
|
|
265
|
+
</SActionModal>
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// 2) SModal.create 로 띄운다
|
|
270
|
+
SModal.create({ component: OrderModal, componentProps: { orderId } })
|
|
271
|
+
.onOk(() => refetch())
|
|
272
|
+
.onDismissed(() => {});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 3-4. 테이블 컬럼 정렬
|
|
276
|
+
|
|
277
|
+
**숫자가 들어가는 컬럼은 예외 없이 오른쪽 정렬한다** (`align: 'right'`).
|
|
278
|
+
자릿수가 세로로 맞아야 값의 크기를 눈으로 비교할 수 있기 때문이다.
|
|
279
|
+
|
|
280
|
+
| 컬럼 내용 | 정렬 | 예 |
|
|
281
|
+
| --- | --- | --- |
|
|
282
|
+
| **금액·수량·개수·비율 등 단위가 붙은 숫자** | **`'right'`** | `39,000원` · `12개` · `3건` · `15%` |
|
|
283
|
+
| **숫자만 있는 값** | **`'right'`** | `1024` · `39000` |
|
|
284
|
+
| 텍스트 | 생략(기본 `left`) | 상품명, 카테고리 |
|
|
285
|
+
| 상태 태그·아이콘·체크박스 등 고정폭 요소 | `'center'` | `STag`, `SIcon` |
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
const columns: STableColumn[] = [
|
|
289
|
+
{ name: 'id', label: 'ID', field: 'id', width: '80px', align: 'right' },
|
|
290
|
+
{ name: 'name', label: '상품명', field: 'name' }, // 텍스트 → 생략
|
|
291
|
+
{ name: 'qty', label: '수량', field: 'qty', width: '80px', align: 'right',
|
|
292
|
+
format: (v: number) => `${Number(v).toLocaleString()}개` },
|
|
293
|
+
{ name: 'price', label: '판매가', field: 'price', width: '120px', align: 'right',
|
|
294
|
+
format: (v: number) => `${Number(v).toLocaleString()}원` },
|
|
295
|
+
{ name: 'status', label: '상태', field: 'status', width: '100px', align: 'center',
|
|
296
|
+
render: () => <STag size="sm" color="green" label="판매중" /> },
|
|
297
|
+
];
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
- `format` 으로 단위를 붙이더라도 **숫자 기반이면 오른쪽 정렬**이다. 단위 때문에 문자열이 되는 것은 정렬 판단과 무관하다.
|
|
301
|
+
- 숫자는 §1-4 대로 **`toLocaleString()` 이 필수**다. 세 자리 콤마 없이 출력하지 않는다.
|
|
302
|
+
- `SKeyValueTable` 의 값 셀도 같은 기준을 따른다.
|
|
303
|
+
|
|
304
|
+
#### 값이 없는 셀은 회색 하이픈
|
|
305
|
+
|
|
306
|
+
셀을 **빈칸으로 두지 않는다.** 값이 `null` · `undefined` · 빈 문자열이면 `-` 를 `text-fg-tertiary`(`grey_65`)로 표시한다.
|
|
307
|
+
빈칸은 "데이터가 없음"인지 "렌더가 깨졌는지" 구분되지 않지만, 회색 하이픈은 없다는 사실을 명시한다.
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
// 재사용 헬퍼를 하나 두고 모든 컬럼에서 쓴다
|
|
311
|
+
const emptyCell = <span className="text-fg-tertiary">-</span>;
|
|
312
|
+
const hasValue = (v: unknown) => v !== null && v !== undefined && v !== '';
|
|
313
|
+
|
|
314
|
+
const columns: STableColumn[] = [
|
|
315
|
+
{ name: 'memo', label: '메모', field: 'memo',
|
|
316
|
+
render: (row: SRow) => (hasValue(row.memo) ? row.memo : emptyCell) },
|
|
317
|
+
{ name: 'price', label: '판매가', field: 'price', width: '120px', align: 'right',
|
|
318
|
+
render: (row: SRow) =>
|
|
319
|
+
hasValue(row.price) ? `${Number(row.price).toLocaleString()}원` : emptyCell },
|
|
320
|
+
];
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
`0` 은 값이 있는 것이므로 하이픈으로 바꾸지 않는다 — `0원` 그대로 표시한다.
|
|
324
|
+
|
|
325
|
+
### 3-5. 버튼류
|
|
326
|
+
|
|
327
|
+
| 상황 | 사용 |
|
|
328
|
+
| --- | --- |
|
|
329
|
+
| 일반 액션 | `SButton` (`color`: `primary` / `secondary` / `neutral` / `danger`, `size`: xs~lg) |
|
|
330
|
+
| **삭제 등 파괴적 액션** | **`SButton color="danger"`** 또는 **`color="danger" outline`** |
|
|
331
|
+
| 텍스트만 있는 저강조 액션 | `SGhostButton` |
|
|
332
|
+
| 본문 속 이동 링크 | `STextLink` |
|
|
333
|
+
| 메인 액션 + 부가 메뉴 | `SDropdownButton` |
|
|
334
|
+
|
|
335
|
+
한 화면의 primary 버튼 개수에 대한 제약은 없다. 다만 **삭제·초기화 등 되돌릴 수 없는 액션은 반드시 `danger`** 로 표시한다.
|
|
336
|
+
|
|
337
|
+
**하단 버튼 배치 (모든 화면 공통)** — 그룹을 모아 정렬하지 않고 **양끝으로 벌린다**(`justify-between`).
|
|
338
|
+
|
|
339
|
+
- **왼쪽 끝**: 취소·닫기·목록 등 되돌리는 액션
|
|
340
|
+
- **오른쪽 끝**: 저장·등록·수정·삭제 등 실행 액션
|
|
341
|
+
- 체크박스·안내 문구 등 **부가 요소는 오른쪽 그룹 안, 실행 버튼 바로 왼쪽**에 둔다
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
<div className="flex items-center justify-between">
|
|
345
|
+
<SButton color="secondary" label="취소" />
|
|
346
|
+
<div className="flex items-center gap-8">
|
|
347
|
+
<SCheckbox label="계속 등록하기" value={keep} onValueChange={setKeep} /> {/* 부가 요소 */}
|
|
348
|
+
<SButton label="저장" />
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 4. 페이지 레시피 — 표준 골격
|
|
356
|
+
|
|
357
|
+
> 새 페이지는 반드시 아래 골격에서 시작한다. 임의 골격을 발명하지 않는다.
|
|
358
|
+
>
|
|
359
|
+
> **핵심 원칙 — 표 형태의 정보는 `SKeyValueTable` 로 만든다.** 필터·등록/수정 폼·상세 정보가 모두 여기 해당한다.
|
|
360
|
+
> `SField` 컨트롤을 `div` 로 직접 나열해 폼을 만들지 않는다.
|
|
361
|
+
|
|
362
|
+
### 4-1. 앱 셸 (모든 페이지 공통)
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
import { SLayout, SGnb, SPage, type SGnbMenuItem } from 'sellmate-design-system-react';
|
|
366
|
+
|
|
367
|
+
const MENU: SGnbMenuItem[] = [
|
|
368
|
+
{ label: '주문', value: 'orders', icon: 'bill' },
|
|
369
|
+
{ label: '상품', value: 'products', icon: 'box', children: [{ label: '목록', value: 'product-list' }] },
|
|
370
|
+
];
|
|
371
|
+
|
|
372
|
+
export default function AppShell({ children }: { children: React.ReactNode }) {
|
|
373
|
+
return (
|
|
374
|
+
<SLayout type="box" header="fix">
|
|
375
|
+
{/* type/header/folded 는 SLayout 에만 준다 — SGnb 는 context 에서 읽는다 */}
|
|
376
|
+
<SGnb items={MENU} value={current} onValueChange={navigate} logo={<Logo />} />
|
|
377
|
+
<SPage background="frame" className="p-20">{children}</SPage>
|
|
378
|
+
</SLayout>
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### 4-2. 목록 페이지 (필터 + 테이블)
|
|
384
|
+
|
|
385
|
+
구조: **페이지 헤더(제목 + 가이드 링크) → 필터(`SKeyValueTable`) → `STableBar` → `STable`**
|
|
386
|
+
|
|
387
|
+
액션 버튼의 위치가 핵심이다:
|
|
388
|
+
|
|
389
|
+
- **페이지 제목 줄에는 액션 버튼을 두지 않는다.** 가이드·매뉴얼 링크 등 부가 정보만 온다.
|
|
390
|
+
- **주요 액션(등록 등)은 `STableBar` 의 `rightActions`** 에 둔다.
|
|
391
|
+
- **선택 상태 액션(선택 삭제 등)은 `STableBar` 의 `actions`** 에 둔다. `actions` 슬롯은 건수 요약이 있으면 앞에 구분선(`SDivider`)을 **자동으로** 넣으므로 직접 구분선을 만들지 않는다.
|
|
392
|
+
|
|
393
|
+
```tsx
|
|
394
|
+
import {
|
|
395
|
+
SButton, STextLink, SKeyValueTable, STableBar, STable, STag,
|
|
396
|
+
type STableColumn, type SRow, type SKeyValueField,
|
|
397
|
+
} from 'sellmate-design-system-react';
|
|
398
|
+
|
|
399
|
+
/** 필터도 표다 — SKeyValueTable 로 만든다 (서비스 전용 전역 필터가 따로 있는 경우 제외) */
|
|
400
|
+
const filterFields: SKeyValueField[][] = [
|
|
401
|
+
[
|
|
402
|
+
{ name: 'status', label: '상태', type: 'select',
|
|
403
|
+
options: { options: STATUS_OPTIONS, emitValue: true } },
|
|
404
|
+
{ name: 'keyword', label: '검색어', type: 'input',
|
|
405
|
+
options: { placeholder: '상품명 / 상품코드' } },
|
|
406
|
+
],
|
|
407
|
+
[
|
|
408
|
+
{ name: 'period', label: '등록일', type: 'date-range-picker', tdColSpan: 3 },
|
|
409
|
+
],
|
|
410
|
+
];
|
|
411
|
+
|
|
412
|
+
const columns: STableColumn[] = [
|
|
413
|
+
// 숫자 컬럼은 전부 align: 'right' — §3-4
|
|
414
|
+
{ name: 'id', label: 'ID', field: 'id', width: '80px', align: 'right' },
|
|
415
|
+
{ name: 'name', label: '상품명', field: 'name' },
|
|
416
|
+
{ name: 'stock', label: '재고', field: 'stock', width: '90px', align: 'right',
|
|
417
|
+
format: (v: number) => `${Number(v).toLocaleString()}개` },
|
|
418
|
+
{ name: 'price', label: '판매가', field: 'price', width: '120px', align: 'right',
|
|
419
|
+
format: (v: number) => `${Number(v).toLocaleString()}원` },
|
|
420
|
+
// 상태 컬럼은 STag size="sm" — SBadge 색 점을 기본으로 쓰지 않는다
|
|
421
|
+
{ name: 'status', label: '상태', field: 'status', width: '100px', align: 'center',
|
|
422
|
+
render: (row: SRow) =>
|
|
423
|
+
row.status === 'selling'
|
|
424
|
+
? <STag size="sm" color="green" label="판매중" />
|
|
425
|
+
: <STag size="sm" color="grey" label="판매중지" /> },
|
|
426
|
+
];
|
|
427
|
+
|
|
428
|
+
export default function ProductListPage() {
|
|
429
|
+
const [filters, setFilters] = useState<Record<string, unknown>>({});
|
|
430
|
+
const [selected, setSelected] = useState<SRow[]>([]);
|
|
431
|
+
|
|
432
|
+
return (
|
|
433
|
+
<div className="flex flex-col gap-12">
|
|
434
|
+
{/* 페이지 헤더 — 액션 버튼 없음. 가이드/매뉴얼 링크 자리 */}
|
|
435
|
+
<div className="flex items-center justify-between">
|
|
436
|
+
<h1 className="typo-heading-lg m-0">상품 목록</h1>
|
|
437
|
+
<STextLink label="이용 가이드" rightArrow="chevron" onClick={openGuide} />
|
|
438
|
+
</div>
|
|
439
|
+
|
|
440
|
+
{/* 필터 — search 를 켜면 우측에 검색 패널이 붙는다 */}
|
|
441
|
+
<SKeyValueTable
|
|
442
|
+
fields={filterFields}
|
|
443
|
+
values={filters}
|
|
444
|
+
search
|
|
445
|
+
onChange={({ values }) => setFilters(values)}
|
|
446
|
+
onSearch={fetchList}
|
|
447
|
+
/>
|
|
448
|
+
|
|
449
|
+
{/* 툴바 — 좌: 건수 + (구분선 자동) + 선택 액션 / 우: 주요 액션 */}
|
|
450
|
+
<STableBar
|
|
451
|
+
total={total}
|
|
452
|
+
selected={selected.length}
|
|
453
|
+
actions={
|
|
454
|
+
<SButton size="sm" color="secondary" label="선택 삭제"
|
|
455
|
+
disabled={!selected.length} onClick={removeSelected} />
|
|
456
|
+
}
|
|
457
|
+
rightActions={<SButton size="sm" label="상품 등록" onClick={goCreate} />}
|
|
458
|
+
/>
|
|
459
|
+
|
|
460
|
+
<STable
|
|
461
|
+
columns={columns}
|
|
462
|
+
rows={rows}
|
|
463
|
+
rowKey="id"
|
|
464
|
+
selectable
|
|
465
|
+
selected={selected}
|
|
466
|
+
onSelectedChange={setSelected}
|
|
467
|
+
pagination={{ currentPage, lastPage }}
|
|
468
|
+
isLoading={isLoading}
|
|
469
|
+
/>
|
|
470
|
+
</div>
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### 4-3. 폼 페이지 (등록/수정)
|
|
476
|
+
|
|
477
|
+
구조: **페이지 제목 → `SForm` + `SKeyValueTable` → 하단 버튼**
|
|
478
|
+
|
|
479
|
+
- 필드를 `div` 로 나열하지 않고 **`SKeyValueTable` 의 행으로 구성**한다.
|
|
480
|
+
- 검증 규칙은 각 field 의 `options.rules` 로 넘긴다. `SForm` 이 하위 컨트롤을 자동 수집해 submit 시 일괄 검증하고, 실패 시 첫 실패 필드로 포커스를 옮긴다.
|
|
481
|
+
- **버튼 순서: 취소·닫기가 왼쪽, 저장·등록·수정·삭제가 오른쪽.** 이 순서는 모든 화면에서 동일하다.
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
import {
|
|
485
|
+
SForm, SKeyValueTable, SButton, SCheckbox,
|
|
486
|
+
type SFormHandle, type SKeyValueField, type Rule,
|
|
487
|
+
} from 'sellmate-design-system-react';
|
|
488
|
+
|
|
489
|
+
const required = (msg: string): Rule => v =>
|
|
490
|
+
v != null && String(v).trim() !== '' ? true : msg;
|
|
491
|
+
|
|
492
|
+
const fields: SKeyValueField[][] = [
|
|
493
|
+
[
|
|
494
|
+
{ name: 'name', label: '상품명', required: true, type: 'input',
|
|
495
|
+
options: { placeholder: '상품명 입력', rules: [required('상품명을 입력해 주세요.')] } },
|
|
496
|
+
{ name: 'code', label: '상품코드', type: 'input', options: { placeholder: '자동 생성' } },
|
|
497
|
+
],
|
|
498
|
+
[
|
|
499
|
+
{ name: 'category', label: '카테고리', required: true, type: 'select',
|
|
500
|
+
options: { options: CATEGORY_OPTIONS, emitValue: true,
|
|
501
|
+
rules: [required('카테고리를 선택해 주세요.')] } },
|
|
502
|
+
{ name: 'price', label: '판매가', type: 'number-input' },
|
|
503
|
+
],
|
|
504
|
+
[
|
|
505
|
+
{ name: 'memo', label: '메모', type: 'textarea', tdColSpan: 3,
|
|
506
|
+
helpText: ['내부 관리용 메모입니다.'] },
|
|
507
|
+
],
|
|
508
|
+
];
|
|
509
|
+
|
|
510
|
+
export default function ProductCreatePage() {
|
|
511
|
+
const formRef = useRef<SFormHandle>(null);
|
|
512
|
+
const [values, setValues] = useState<Record<string, unknown>>({});
|
|
513
|
+
|
|
514
|
+
return (
|
|
515
|
+
<div className="flex flex-col gap-12">
|
|
516
|
+
<h1 className="typo-heading-lg m-0">상품 등록</h1>
|
|
517
|
+
|
|
518
|
+
<SForm ref={formRef} formClass="flex flex-col gap-12" onSubmit={save}>
|
|
519
|
+
<SKeyValueTable
|
|
520
|
+
fields={fields}
|
|
521
|
+
values={values}
|
|
522
|
+
onChange={({ values }) => setValues(values)}
|
|
523
|
+
/>
|
|
524
|
+
|
|
525
|
+
{/* 하단 버튼은 양끝으로 벌린다. 부가 요소(체크박스 등)는 저장 바로 왼쪽 */}
|
|
526
|
+
<div className="flex items-center justify-between">
|
|
527
|
+
<SButton type="button" color="secondary" label="취소" onClick={goBack} />
|
|
528
|
+
<div className="flex items-center gap-8">
|
|
529
|
+
<SCheckbox label="계속 등록하기" value={keepOpen} onValueChange={v => setKeepOpen(v as boolean)} />
|
|
530
|
+
<SButton type="submit" label="저장" />
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
</SForm>
|
|
534
|
+
</div>
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### 4-4. 상세(조회) 페이지
|
|
540
|
+
|
|
541
|
+
구조: **페이지 헤더(제목) → 섹션별 `SSectionHeaderCard` + `SKeyValueTable` → 하단 버튼**
|
|
542
|
+
|
|
543
|
+
- 조회 값은 `type: 'text'` 행으로 표시한다. **상태·분류 태그도 별도 영역이 아니라 표의 한 행**으로 넣는다 (`render` 에 `STag`).
|
|
544
|
+
- 행이 많아지면 **유형별로 섹션을 나누고, 각 섹션을 `SSectionHeaderCard` 로 감싼다.**
|
|
545
|
+
합성 컴포넌트라 `SSectionHeaderCard.Header` / `SSectionHeaderCard.Body` 를 자식으로 쓴다.
|
|
546
|
+
- **수정·삭제 버튼은 하단에 둔다.** 내용이 짧아 우측 상단에 두는 변형도 있으나 기본은 하단이다.
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
import {
|
|
550
|
+
SSectionHeaderCard, SKeyValueTable, SButton, STag, type SKeyValueField,
|
|
551
|
+
} from 'sellmate-design-system-react';
|
|
552
|
+
|
|
553
|
+
const basicFields: SKeyValueField[][] = [
|
|
554
|
+
[
|
|
555
|
+
{ name: 'code', label: '상품코드', type: 'text' },
|
|
556
|
+
{ name: 'createdAt', label: '등록일', type: 'text' },
|
|
557
|
+
],
|
|
558
|
+
[
|
|
559
|
+
{ name: 'category', label: '카테고리', type: 'text' },
|
|
560
|
+
// 상태 태그도 표의 한 행으로 표현한다
|
|
561
|
+
{ name: 'status', label: '상태',
|
|
562
|
+
render: <STag size="sm" color="green" label="판매중" /> },
|
|
563
|
+
],
|
|
564
|
+
];
|
|
565
|
+
|
|
566
|
+
const priceFields: SKeyValueField[][] = [
|
|
567
|
+
[
|
|
568
|
+
{ name: 'price', label: '판매가', type: 'text' },
|
|
569
|
+
{ name: 'cost', label: '원가', type: 'text' },
|
|
570
|
+
],
|
|
571
|
+
];
|
|
572
|
+
|
|
573
|
+
export default function ProductDetailPage() {
|
|
574
|
+
return (
|
|
575
|
+
<div className="flex flex-col gap-12">
|
|
576
|
+
<h1 className="typo-heading-lg m-0">클래식 셔츠</h1>
|
|
577
|
+
|
|
578
|
+
<SSectionHeaderCard>
|
|
579
|
+
<SSectionHeaderCard.Header title="기본 정보" marker thickness="accent" />
|
|
580
|
+
<SSectionHeaderCard.Body>
|
|
581
|
+
<SKeyValueTable fields={basicFields} values={product} />
|
|
582
|
+
</SSectionHeaderCard.Body>
|
|
583
|
+
</SSectionHeaderCard>
|
|
584
|
+
|
|
585
|
+
<SSectionHeaderCard>
|
|
586
|
+
{/* 헤더 우측에 액션이 필요하면 slot 을 쓴다 */}
|
|
587
|
+
<SSectionHeaderCard.Header
|
|
588
|
+
title="가격 정보"
|
|
589
|
+
marker
|
|
590
|
+
helpText={['부가세 포함 금액입니다.']}
|
|
591
|
+
slot={<SButton size="sm" color="secondary" label="이력" onClick={openHistory} />}
|
|
592
|
+
/>
|
|
593
|
+
<SSectionHeaderCard.Body>
|
|
594
|
+
<SKeyValueTable fields={priceFields} values={product} />
|
|
595
|
+
</SSectionHeaderCard.Body>
|
|
596
|
+
</SSectionHeaderCard>
|
|
597
|
+
|
|
598
|
+
{/* 액션은 하단 — 목록(되돌리기)은 왼쪽 끝, 실행 액션은 오른쪽 끝 */}
|
|
599
|
+
<div className="flex items-center justify-between">
|
|
600
|
+
<SButton color="secondary" label="목록" onClick={goList} />
|
|
601
|
+
<div className="flex items-center gap-8">
|
|
602
|
+
<SButton color="danger" outline label="삭제" onClick={confirmDelete} />
|
|
603
|
+
<SButton label="수정" onClick={goEdit} />
|
|
604
|
+
</div>
|
|
605
|
+
</div>
|
|
606
|
+
</div>
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### 4-5. 섹션 카드 — SSectionHeaderCard
|
|
612
|
+
|
|
613
|
+
폼 페이지에서도 입력 항목이 많으면 유형별로 `SSectionHeaderCard` 로 나눈다. 주요 옵션:
|
|
614
|
+
|
|
615
|
+
| Prop (Header) | 용도 |
|
|
616
|
+
| --- | --- |
|
|
617
|
+
| `title` | 섹션 제목 (필수) |
|
|
618
|
+
| `marker` | 제목 앞 점 표시 |
|
|
619
|
+
| `required` | 제목 뒤 필수(\*) 표시 — 필수 입력 섹션에 |
|
|
620
|
+
| `helpText` | 도움말 툴팁 (`string[]`) |
|
|
621
|
+
| `subtitle` | 부제 |
|
|
622
|
+
| `slot` | 헤더 우측 영역 (버튼 등) |
|
|
623
|
+
| `thickness` | 상단 강조선 — `false`(기본) / `'default'` / `'accent'` |
|
|
624
|
+
|
|
625
|
+
---
|
|
626
|
+
|
|
627
|
+
## 5. 자가 점검 체크리스트
|
|
628
|
+
|
|
629
|
+
페이지를 완성하면 다음을 확인한다. 하나라도 어기면 수정 후 완료를 보고한다.
|
|
630
|
+
|
|
631
|
+
- [ ] 생 HTML 컨트롤(`<button>` `<input>` `<select>` `<table>` …)이 없는가
|
|
632
|
+
- [ ] `text-[14px]`, `bg-[#...]` 같은 리터럴 임의 값이 없는가 (`var(--sys-*)` 참조는 허용)
|
|
633
|
+
- [ ] 텍스트에 `typo-*` 프리셋을 썼는가
|
|
634
|
+
- [ ] 간격이 전부 토큰 스케일 값인가 (`gap-13` ❌ → `gap-12` ✅)
|
|
635
|
+
- [ ] 본문이 12px(`typo-body-sm-default`)이고 보조 설명이 `text-fg-tertiary` 인가 (14px 본문 ❌)
|
|
636
|
+
- [ ] 페이지 패딩이 `p-20`, 블록·섹션 간격이 `gap-12` 인가 (`gap-16`/`gap-24` ❌)
|
|
637
|
+
- [ ] 페이지가 §4의 표준 골격에서 시작했는가
|
|
638
|
+
- [ ] 필터·폼·상세 정보를 `SKeyValueTable` 로 만들었는가 (컨트롤을 `div` 로 나열하지 않았는가)
|
|
639
|
+
- [ ] 섹션 구분에 `SSectionHeaderCard` 를 썼는가 (직접 만든 카드가 아니라)
|
|
640
|
+
- [ ] 목록의 주요 액션이 `STableBar` 의 `rightActions` 에 있는가 (페이지 제목 줄이 아니라)
|
|
641
|
+
- [ ] 상태 표시에 `STag size="sm"` 을 썼는가
|
|
642
|
+
- [ ] 테이블의 숫자 컬럼(금액·수량·개수 등)이 전부 `align: 'right'` 인가
|
|
643
|
+
- [ ] 화면에 표시하는 모든 숫자에 `toLocaleString()` 을 써서 세 자리 콤마를 넣었는가
|
|
644
|
+
- [ ] 금액·수량 등 양을 나타내는 숫자에 `toLocaleString()` 을 썼는가 (번호·코드는 제외)
|
|
645
|
+
- [ ] 하단 버튼이 양끝 분리(`justify-between`)이고, 되돌리기가 왼쪽 끝 · 실행이 오른쪽 끝인가
|
|
646
|
+
- [ ] 삭제 등 파괴적 액션에 `color="danger"` 를 썼는가
|
|
647
|
+
- [ ] 작업용 모달을 `SActionModal` + `SModal.create` 로 만들었는가 (직접 오버레이 ❌)
|
|
648
|
+
- [ ] 상태 표시·알림·확인 다이얼로그가 §3의 선택 규칙을 따르는가
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
## 6. 린트로 강제되는 규칙
|
|
653
|
+
|
|
654
|
+
위 규칙 중 일부는 소비 앱의 ESLint 로 검출된다 (`sellmate-design-system-react/eslint`).
|
|
655
|
+
**코드를 넘기기 전에 린트를 통과시킨다.**
|
|
656
|
+
|
|
657
|
+
| 규칙 | 잡히는 것 |
|
|
658
|
+
| --- | --- |
|
|
659
|
+
| `sellmate/no-raw-html-control` | §1-1 생 HTML 컨트롤, `alert()`/`confirm()` |
|
|
660
|
+
| `sellmate/no-arbitrary-class` | §1-2 토큰 있는 속성의 임의 값 (`text-[14px]`, `bg-[#eee]`) |
|
|
661
|
+
| `sellmate/no-off-scale-spacing` | §2-2 스케일 밖 간격 (`gap-13`) |
|
|
662
|
+
| `sellmate/table-numeric-align` | §3-4 숫자 컬럼의 `align: 'right'` 누락 (`--fix` 지원) |
|
|
663
|
+
| `sellmate/require-locale-number` | §1-4 숫자 컬럼의 `toLocaleString()` 누락 |
|
|
664
|
+
| `sellmate/require-locale-number` | §1-4 금액·수량 등의 `toLocaleString()` 누락 |
|
|
665
|
+
| `sellmate/prefer-typo-preset` | §1-3 낱개 폰트 조합 (`text-14 font-bold`) |
|
|
666
|
+
|
|
667
|
+
`gap-13` 처럼 스케일 밖 값은 Tailwind v4 에서 **에러 없이 조용히 무시된다**. "간격이 왜 안 먹지" 로만 보이므로 반드시 스케일 값을 쓴다.
|
|
668
|
+
|
|
669
|
+
린트가 잡지 못하는 것(§3 컴포넌트 선택, §4 페이지 골격, 버튼 배치)은 §5 체크리스트로 직접 확인한다.
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
## 2. 디자인 토큰 어휘 (theme.css 자동 추출)
|
|
673
|
+
|
|
674
|
+
Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터럴 임의 값(`text-[14px]`, `bg-[#eee]`)은 금지.
|
|
675
|
+
|
|
676
|
+
### 간격 (px 단위 — gap-N, p-N, m-N 등)
|
|
677
|
+
2 4 6 8 10 12 16 19 20 22 24 28 32 36 40 44 48 56 60 62 80
|
|
678
|
+
|
|
679
|
+
### 폰트 크기 (text-N — 단, 본문 텍스트는 아래 typo-* 프리셋 우선)
|
|
680
|
+
10 11 12 13 14 16 18 20 24 28 32
|
|
681
|
+
|
|
682
|
+
### radius (rounded-*)
|
|
683
|
+
2 4 6 8 full control-sm control-md feedback-xs-square feedback-sm-square feedback-pill field-sm field-md navigation item-bordered
|
|
684
|
+
|
|
685
|
+
### 색상 팔레트 (text-{family}-{step}, bg-…, border-…)
|
|
686
|
+
- white
|
|
687
|
+
- black
|
|
688
|
+
- grey: 10 20 25 30 35 45 50 55 60 65 70 80 85 90 95 05 strong subtle
|
|
689
|
+
- red: 15 20 30 45 60 70 75 80 85 90 95 99 strong subtle
|
|
690
|
+
- orange: 10 20 35 45 55 60 65 75 85 90 95 99 strong subtle
|
|
691
|
+
- yellow: 10 20 25 30 40 45 50 60 70 80 90 95 strong moderate subtle
|
|
692
|
+
- olive: 10 15 20 30 45 55 65 70 80 90 95 05
|
|
693
|
+
- green: 15 25 45 55 65 70 75 80 85 90 95 99 strong subtle
|
|
694
|
+
- steelblue: 10 25 45 60 65 70 75 80 85 90 95 99
|
|
695
|
+
- oceanblue: 15 25 50 60 65 70 75 80 85 90 95 99
|
|
696
|
+
- brilliantblue: 10 20 25 40 50 60 70 75 80 85 90 95 99 05
|
|
697
|
+
- bg: screen frame brand subtle accent accentLight accentBright accentFaint deep danger dangerLight warning caution progress success successLight neutralLight neutralBright tableHeader
|
|
698
|
+
- fg: primary secondary tertiary quaternary brand subtleWarm subtleCool deep success dangerLight accent accentLight danger warning inverse
|
|
699
|
+
- border: default strong accent accentLight danger success
|
|
700
|
+
- disabled: bg text icon border
|
|
701
|
+
- link: accent
|
|
702
|
+
- divider: default
|
|
703
|
+
- lightblue: strong subtle
|
|
704
|
+
- blue: strong subtle
|
|
705
|
+
- darkblue: strong subtle
|
|
706
|
+
- indigo: strong subtle
|
|
707
|
+
- primary: 10 20 25 40 50 60 70 75 80 85 90 95 99 05
|
|
708
|
+
- danger: 15 20 30 45 60 70 75 80 85 90 95 99 strong subtle
|
|
709
|
+
- success: 15 25 45 55 65 70 75 80 85 90 95 99 strong subtle
|
|
710
|
+
- warning: 10 20 35 45 55 60 65 75 85 90 95 99 strong subtle
|
|
711
|
+
|
|
712
|
+
### 타이포그래피 프리셋 (클래스 하나로 size/weight/line-height 적용)
|
|
713
|
+
| 클래스 | size | weight | line-height |
|
|
714
|
+
| --- | --- | --- | --- |
|
|
715
|
+
| typo-heading-sm | 14px | 700 | 24px |
|
|
716
|
+
| typo-heading-xs | 12px | 700 | 20px |
|
|
717
|
+
| typo-heading-md | 16px | 700 | 26px |
|
|
718
|
+
| typo-heading-lg | 18px | 700 | 30px |
|
|
719
|
+
| typo-body-xs-default | 11px | 400 | 18px |
|
|
720
|
+
| typo-body-sm-default | 12px | 400 | 20px |
|
|
721
|
+
| typo-body-sm-medium | 12px | 500 | 20px |
|
|
722
|
+
| typo-body-sm-bold | 12px | 700 | 20px |
|
|
723
|
+
| typo-body-md-default | 14px | 400 | 24px |
|
|
724
|
+
| typo-body-md-medium | 14px | 500 | 24px |
|
|
725
|
+
| typo-body-md-bold | 14px | 700 | 24px |
|
|
726
|
+
| typo-body-lg-default | 16px | 400 | 26px |
|
|
727
|
+
| typo-body-lg-medium | 16px | 500 | 26px |
|
|
728
|
+
| typo-body-lg-bold | 16px | 700 | 26px |
|
|
729
|
+
| typo-control-xs-default | 12px | 400 | 20px |
|
|
730
|
+
| typo-control-xs-medium | 12px | 500 | 20px |
|
|
731
|
+
| typo-control-xs-underline | 12px | 500 | 20px |
|
|
732
|
+
| typo-control-xs-bold | 12px | 700 | 20px |
|
|
733
|
+
| typo-control-sm-default | 14px | 500 | 24px |
|
|
734
|
+
| typo-control-sm-underline | 14px | 500 | 24px |
|
|
735
|
+
| typo-control-md-default | 16px | 500 | 26px |
|
|
736
|
+
| typo-control-md-underline | 16px | 500 | 26px |
|
|
737
|
+
| typo-control-lg | 18px | 500 | 30px |
|
|
738
|
+
| typo-feedback-xs | 11px | 500 | 18px |
|
|
739
|
+
| typo-feedback-sm-regular | 12px | 400 | 20px |
|
|
740
|
+
| typo-feedback-sm-medium | 12px | 500 | 20px |
|
|
741
|
+
| typo-feedback-sm-bold | 12px | 700 | 20px |
|
|
742
|
+
| typo-feedback-sm-underline | 12px | 500 | 20px |
|
|
743
|
+
| typo-feedback-md-bold | 14px | 700 | 24px |
|
|
744
|
+
| typo-feedback-md-medium | 14px | 500 | 24px |
|
|
745
|
+
| typo-feedback-md-underline | 14px | 700 | 24px |
|
|
746
|
+
| typo-field-xs-default | 11px | 400 | 18px |
|
|
747
|
+
| typo-field-sm-default | 12px | 400 | 20px |
|
|
748
|
+
| typo-field-sm-medium | 12px | 500 | 20px |
|
|
749
|
+
| typo-field-sm-bold | 12px | 700 | 20px |
|
|
750
|
+
| typo-field-md-default | 14px | 400 | 24px |
|
|
751
|
+
| typo-field-md-medium | 14px | 500 | 24px |
|
|
752
|
+
| typo-field-md-bold | 14px | 700 | 24px |
|
|
753
|
+
| typo-field-lg-default | 16px | 400 | 26px |
|
|
754
|
+
| typo-field-lg-medium | 16px | 500 | 26px |
|
|
755
|
+
| typo-field-lg-bold | 16px | 700 | 26px |
|
|
756
|
+
| typo-navigation-xs-medium | 11px | 500 | 18px |
|
|
757
|
+
| typo-navigation-xs-bold | 11px | 700 | 18px |
|
|
758
|
+
| typo-navigation-sm-default | 12px | 400 | 20px |
|
|
759
|
+
| typo-navigation-sm-medium | 12px | 500 | 20px |
|
|
760
|
+
| typo-navigation-sm-bold | 12px | 700 | 20px |
|
|
761
|
+
| typo-navigation-md-bold | 13px | 700 | 22px |
|
|
762
|
+
| typo-navigation-lg-medium | 14px | 500 | 24px |
|
|
763
|
+
| typo-navigation-lg-bold | 14px | 700 | 24px |
|
|
764
|
+
| typo-table-header | 12px | 500 | 20px |
|
|
765
|
+
| typo-table-body | 12px | 400 | 20px |
|
|
766
|
+
| typo-table-accent | 12px | 700 | 20px |
|
|
767
|
+
|
|
768
|
+
### 시맨틱 색 토큰 (var() 참조 전용 — 예: bg-[var(--sys-color-bg-frame)])
|
|
769
|
+
--sys-color-bg-accent
|
|
770
|
+
--sys-color-bg-accentBright
|
|
771
|
+
--sys-color-bg-accentFaint
|
|
772
|
+
--sys-color-bg-accentLight
|
|
773
|
+
--sys-color-bg-brand
|
|
774
|
+
--sys-color-bg-caution
|
|
775
|
+
--sys-color-bg-danger
|
|
776
|
+
--sys-color-bg-dangerLight
|
|
777
|
+
--sys-color-bg-deep
|
|
778
|
+
--sys-color-bg-frame
|
|
779
|
+
--sys-color-bg-neutralBright
|
|
780
|
+
--sys-color-bg-neutralLight
|
|
781
|
+
--sys-color-bg-progress
|
|
782
|
+
--sys-color-bg-screen
|
|
783
|
+
--sys-color-bg-subtle
|
|
784
|
+
--sys-color-bg-success
|
|
785
|
+
--sys-color-bg-successLight
|
|
786
|
+
--sys-color-bg-tableHeader
|
|
787
|
+
--sys-color-bg-warning
|
|
788
|
+
--sys-color-blue-strong
|
|
789
|
+
--sys-color-blue-subtle
|
|
790
|
+
--sys-color-border-accent
|
|
791
|
+
--sys-color-border-accentLight
|
|
792
|
+
--sys-color-border-danger
|
|
793
|
+
--sys-color-border-default
|
|
794
|
+
--sys-color-border-strong
|
|
795
|
+
--sys-color-border-success
|
|
796
|
+
--sys-color-control-bg-inverseHover
|
|
797
|
+
--sys-color-darkblue-strong
|
|
798
|
+
--sys-color-darkblue-subtle
|
|
799
|
+
--sys-color-disabled-bg
|
|
800
|
+
--sys-color-disabled-border
|
|
801
|
+
--sys-color-disabled-icon
|
|
802
|
+
--sys-color-disabled-text
|
|
803
|
+
--sys-color-divider-default
|
|
804
|
+
--sys-color-fg-accent
|
|
805
|
+
--sys-color-fg-accentLight
|
|
806
|
+
--sys-color-fg-brand
|
|
807
|
+
--sys-color-fg-danger
|
|
808
|
+
--sys-color-fg-dangerLight
|
|
809
|
+
--sys-color-fg-deep
|
|
810
|
+
--sys-color-fg-inverse
|
|
811
|
+
--sys-color-fg-primary
|
|
812
|
+
--sys-color-fg-quaternary
|
|
813
|
+
--sys-color-fg-secondary
|
|
814
|
+
--sys-color-fg-subtleCool
|
|
815
|
+
--sys-color-fg-subtleWarm
|
|
816
|
+
--sys-color-fg-success
|
|
817
|
+
--sys-color-fg-tertiary
|
|
818
|
+
--sys-color-fg-warning
|
|
819
|
+
--sys-color-field-bg-default
|
|
820
|
+
--sys-color-field-bg-hover
|
|
821
|
+
--sys-color-field-bg-readOnly
|
|
822
|
+
--sys-color-field-border-danger
|
|
823
|
+
--sys-color-field-border-default
|
|
824
|
+
--sys-color-field-border-focus
|
|
825
|
+
--sys-color-field-border-hover
|
|
826
|
+
--sys-color-field-border-success
|
|
827
|
+
--sys-color-field-icon-default
|
|
828
|
+
--sys-color-field-text-default
|
|
829
|
+
--sys-color-field-text-placeholder
|
|
830
|
+
--sys-color-field-text-readOnly
|
|
831
|
+
--sys-color-indigo-strong
|
|
832
|
+
--sys-color-indigo-subtle
|
|
833
|
+
--sys-color-lightblue-strong
|
|
834
|
+
--sys-color-lightblue-subtle
|
|
835
|
+
--sys-color-link-accent
|
|
836
|
+
--sys-color-navigation-gnb-bg-dark
|
|
837
|
+
|
|
838
|
+
## 3. 컴포넌트 카탈로그 (Props / Events / Methods)
|
|
839
|
+
|
|
840
|
+
# SActionModal
|
|
841
|
+
|
|
842
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
843
|
+
|
|
844
|
+
### SActionModal
|
|
845
|
+
|
|
846
|
+
#### Props
|
|
847
|
+
|
|
848
|
+
| Prop | Type | Default | Description |
|
|
849
|
+
|------|------|---------|-------------|
|
|
850
|
+
| `open?` | `boolean` | — | |
|
|
851
|
+
| `persistent?` | `boolean` | — | true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent) |
|
|
852
|
+
| `modalTitle?` | `string` | `''` | |
|
|
853
|
+
| `button?` | `SActionModalButton` | — | 하단 액션 버튼 (주 액션 1개). 의도적으로 단수다 — 보조 버튼(취소·삭제 등)은 `footerLeft` 슬롯에 직접 배치한다. |
|
|
854
|
+
| `footerLeft?` | `ReactNode` | — | footer 좌측 영역 (sd-action-modal 의 bottom-sub-content 슬롯). 보조 버튼이나 안내 문구를 넣는다. 버튼을 하나 더 쓰고 싶을 때 여기에 SButton 을 넣는다. |
|
|
855
|
+
| `width?` | `number \| string` | — | |
|
|
856
|
+
| `height?` | `number \| string` | — | |
|
|
857
|
+
| `children?` | `ReactNode` | — | |
|
|
858
|
+
|
|
859
|
+
#### Events
|
|
860
|
+
|
|
861
|
+
| Event | Type | Description |
|
|
862
|
+
|-------|------|-------------|
|
|
863
|
+
| `onOpenChange` | `(open: boolean) => void` | |
|
|
864
|
+
| `onClose` | `() => void` | 닫기(X) 버튼 클릭 (sdClose) |
|
|
865
|
+
|
|
866
|
+
## Dependencies
|
|
867
|
+
|
|
868
|
+
### Depends on
|
|
869
|
+
|
|
870
|
+
- [SButton](../SButton)
|
|
871
|
+
- [SModalContainer](../SModalContainer)
|
|
872
|
+
|
|
873
|
+
### Graph
|
|
874
|
+
|
|
875
|
+
---
|
|
876
|
+
|
|
877
|
+
# SBadge
|
|
878
|
+
|
|
879
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
880
|
+
|
|
881
|
+
### SBadge
|
|
882
|
+
|
|
883
|
+
#### Props
|
|
884
|
+
|
|
885
|
+
| Prop | Type | Default | Description |
|
|
886
|
+
|------|------|---------|-------------|
|
|
887
|
+
| `color?` | `SBadgeColor` | `'blue'` | 뱃지 색상 |
|
|
888
|
+
|
|
889
|
+
## Dependencies
|
|
890
|
+
|
|
891
|
+
### Used by
|
|
892
|
+
|
|
893
|
+
- [SList](../SList)
|
|
894
|
+
|
|
895
|
+
### Graph
|
|
896
|
+
|
|
897
|
+
---
|
|
898
|
+
|
|
899
|
+
# SBarcodeInput
|
|
900
|
+
|
|
901
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
902
|
+
|
|
903
|
+
### SBarcodeInput
|
|
904
|
+
|
|
905
|
+
#### Props
|
|
906
|
+
|
|
907
|
+
| Prop | Type | Default | Description |
|
|
908
|
+
|------|------|---------|-------------|
|
|
909
|
+
| `value?` | `string \| number \| null` | — | |
|
|
910
|
+
| `size?` | `SBarcodeInputSize` | `'sm'` | |
|
|
911
|
+
| `clearable?` | `boolean` | `false` | |
|
|
912
|
+
| `autoFocus?` | `boolean` | — | |
|
|
913
|
+
| `name?` | `string` | — | |
|
|
914
|
+
| `placeholder?` | `string` | `'입력해 주세요.'` | |
|
|
915
|
+
| `disabled?` | `boolean` | `false` | |
|
|
916
|
+
| `readOnly?` | `boolean` | `false` | |
|
|
917
|
+
| `rules?` | `Rule[]` | — | |
|
|
918
|
+
| `status?` | `SFieldStatus` | — | |
|
|
919
|
+
| `focused?` | `boolean` | — | |
|
|
920
|
+
| `hovered?` | `boolean` | — | |
|
|
921
|
+
| `prefix?` | `ReactNode` | — | 입력 앞 슬롯 |
|
|
922
|
+
| `suffix?` | `ReactNode` | — | 입력 뒤 슬롯 |
|
|
923
|
+
| `inputClass?` | `string` | — | |
|
|
924
|
+
| `inputStyle?` | `CSSProperties` | — | |
|
|
925
|
+
| `label?` | `string` | — | |
|
|
926
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
927
|
+
| `icon?` | `SIconName` | — | |
|
|
928
|
+
| `iconColor?` | `SColor` | — | |
|
|
929
|
+
| `labelTooltip?` | `string` | — | |
|
|
930
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
931
|
+
| `addonLabel?` | `string` | — | |
|
|
932
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | |
|
|
933
|
+
| `hint?` | `string` | — | |
|
|
934
|
+
| `error?` | `boolean` | — | |
|
|
935
|
+
| `errorMessage?` | `string` | — | |
|
|
936
|
+
| `width?` | `number \| string` | — | |
|
|
937
|
+
| `className?` | `string` | — | |
|
|
938
|
+
| `style?` | `CSSProperties` | — | |
|
|
939
|
+
|
|
940
|
+
#### Events
|
|
941
|
+
|
|
942
|
+
| Event | Type | Description |
|
|
943
|
+
|-------|------|-------------|
|
|
944
|
+
| `onValueChange` | `(value: string) => void` | 값 변경 (sdUpdate) |
|
|
945
|
+
| `onFocus` | `() => void` | |
|
|
946
|
+
| `onBlur` | `() => void` | |
|
|
947
|
+
|
|
948
|
+
## Dependencies
|
|
949
|
+
|
|
950
|
+
### Depends on
|
|
951
|
+
|
|
952
|
+
- [SField](../SField)
|
|
953
|
+
- [SGhostButton](../SGhostButton)
|
|
954
|
+
|
|
955
|
+
### Graph
|
|
956
|
+
|
|
957
|
+
---
|
|
958
|
+
|
|
959
|
+
# SButton
|
|
960
|
+
|
|
961
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
962
|
+
|
|
963
|
+
### SButton
|
|
964
|
+
|
|
965
|
+
#### Props
|
|
966
|
+
|
|
967
|
+
| Prop | Type | Default | Description |
|
|
968
|
+
|------|------|---------|-------------|
|
|
969
|
+
| `color?` | `SButtonColor` | `'primary'` | 색상 — sd-button preset의 색 계열 |
|
|
970
|
+
| `outline?` | `boolean` | `false` | 아웃라인(테두리) 스타일. primary·neutral·danger 만 지원 (secondary 는 무시) |
|
|
971
|
+
| `size?` | `SButtonSize` | `'sm'` | 크기 |
|
|
972
|
+
| `icon?` | `SIconName` | — | 레이블 왼쪽 아이콘 |
|
|
973
|
+
| `rightIcon?` | `SIconName` | — | 레이블 오른쪽 아이콘 |
|
|
974
|
+
| `label?` | `string` | — | 버튼 텍스트 (문자열만 — 아이콘은 icon/rightIcon 사용) |
|
|
975
|
+
|
|
976
|
+
## Dependencies
|
|
977
|
+
|
|
978
|
+
### Used by
|
|
979
|
+
|
|
980
|
+
- [SActionModal](../SActionModal)
|
|
981
|
+
- [SConfirmModal](../SConfirmModal)
|
|
982
|
+
- [SDropdownButton](../SDropdownButton)
|
|
983
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
984
|
+
- [SLoadingModal](../SLoadingModal)
|
|
985
|
+
- [SPopover](../SPopover)
|
|
986
|
+
- [SPopup](../SPopup)
|
|
987
|
+
- [SToast](../SToast)
|
|
988
|
+
|
|
989
|
+
### Depends on
|
|
990
|
+
|
|
991
|
+
- [SIcon](../SIcon)
|
|
992
|
+
|
|
993
|
+
### Graph
|
|
994
|
+
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
# SCalendar
|
|
998
|
+
|
|
999
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1000
|
+
|
|
1001
|
+
### SCalendar
|
|
1002
|
+
|
|
1003
|
+
#### Props
|
|
1004
|
+
|
|
1005
|
+
| Prop | Type | Default | Description |
|
|
1006
|
+
|------|------|---------|-------------|
|
|
1007
|
+
| `value?` | `string \| null` | — | 선택 날짜 (YYYY-MM-DD) |
|
|
1008
|
+
| `selectable?` | `[string, string]` | — | 선택 가능 범위 [시작, 종료] (빈 문자열이면 제한 없음) |
|
|
1009
|
+
| `events?` | `SCalendarEventGroup[]` | — | 이벤트 그룹 (날짜별 점) |
|
|
1010
|
+
| `elevated?` | `boolean` | `false` | 카드 그림자 |
|
|
1011
|
+
| `className?` | `string` | — | |
|
|
1012
|
+
| `style?` | `CSSProperties` | — | |
|
|
1013
|
+
|
|
1014
|
+
#### Events
|
|
1015
|
+
|
|
1016
|
+
| Event | Type | Description |
|
|
1017
|
+
|-------|------|-------------|
|
|
1018
|
+
| `onValueChange` | `(date: string) => void` | 선택 변경 (sdUpdate) |
|
|
1019
|
+
| `onViewChange` | `(v: { year: number; month: number }) => void` | 보이는 연·월 변경 (sdViewChange) |
|
|
1020
|
+
|
|
1021
|
+
## Dependencies
|
|
1022
|
+
|
|
1023
|
+
### Used by
|
|
1024
|
+
|
|
1025
|
+
- [SDatePicker](../SDatePicker)
|
|
1026
|
+
|
|
1027
|
+
### Depends on
|
|
1028
|
+
|
|
1029
|
+
- [SGhostButton](../SGhostButton)
|
|
1030
|
+
|
|
1031
|
+
### Graph
|
|
1032
|
+
|
|
1033
|
+
---
|
|
1034
|
+
|
|
1035
|
+
# SCallout
|
|
1036
|
+
|
|
1037
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1038
|
+
|
|
1039
|
+
### SCallout
|
|
1040
|
+
|
|
1041
|
+
#### Props
|
|
1042
|
+
|
|
1043
|
+
| Prop | Type | Default | Description |
|
|
1044
|
+
|------|------|---------|-------------|
|
|
1045
|
+
| `type?` | `SCalloutType` | `'default'` | 콜아웃 타입 (색상·아이콘·타이틀 결정) |
|
|
1046
|
+
| `message?` | `SCalloutMessage[]` | `[]` | 표시할 메시지 목록 (배열 중첩으로 depth 표현). 각 문자열은 인라인 HTML(`<b>`, `<a>` 등)을 허용하며 sanitizeInlineHtml 로 살균 후 렌더된다. |
|
|
1047
|
+
| `children?` | `ReactNode` | — | message 대신 직접 본문을 넣을 때 |
|
|
1048
|
+
| `className?` | `string` | — | |
|
|
1049
|
+
| `style?` | `CSSProperties` | — | |
|
|
1050
|
+
|
|
1051
|
+
## Dependencies
|
|
1052
|
+
|
|
1053
|
+
### Depends on
|
|
1054
|
+
|
|
1055
|
+
- [SIcon](../SIcon)
|
|
1056
|
+
|
|
1057
|
+
### Graph
|
|
1058
|
+
|
|
1059
|
+
---
|
|
1060
|
+
|
|
1061
|
+
# SCard
|
|
1062
|
+
|
|
1063
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1064
|
+
|
|
1065
|
+
### SCard
|
|
1066
|
+
|
|
1067
|
+
#### Props
|
|
1068
|
+
|
|
1069
|
+
| Prop | Type | Default | Description |
|
|
1070
|
+
|------|------|---------|-------------|
|
|
1071
|
+
| `bordered?` | `boolean` | `false` | 테두리 표시 여부 |
|
|
1072
|
+
|
|
1073
|
+
---
|
|
1074
|
+
|
|
1075
|
+
# SCheckbox
|
|
1076
|
+
|
|
1077
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1078
|
+
|
|
1079
|
+
### SCheckbox
|
|
1080
|
+
|
|
1081
|
+
#### Props
|
|
1082
|
+
|
|
1083
|
+
| Prop | Type | Default | Description |
|
|
1084
|
+
|------|------|---------|-------------|
|
|
1085
|
+
| `value?` | `SCheckboxValue` | `false` | 선택 상태. boolean(단일) / 배열(그룹) / null(indeterminate) |
|
|
1086
|
+
| `val?` | `unknown` | — | 배열(그룹) 모드에서 이 체크박스의 값 |
|
|
1087
|
+
| `label?` | `string` | `''` | 라벨 |
|
|
1088
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
1089
|
+
| `inverse?` | `boolean` | `false` | 어두운 배경용 흰색 스타일 |
|
|
1090
|
+
| `className?` | `string` | — | |
|
|
1091
|
+
| `style?` | `CSSProperties` | — | |
|
|
1092
|
+
|
|
1093
|
+
#### Events
|
|
1094
|
+
|
|
1095
|
+
| Event | Type | Description |
|
|
1096
|
+
|-------|------|-------------|
|
|
1097
|
+
| `onValueChange` | `(value: boolean \| unknown[]) => void` | 값 변경 (sdUpdate) |
|
|
1098
|
+
|
|
1099
|
+
## Dependencies
|
|
1100
|
+
|
|
1101
|
+
### Used by
|
|
1102
|
+
|
|
1103
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
1104
|
+
- [STable](../STable)
|
|
1105
|
+
|
|
1106
|
+
### Depends on
|
|
1107
|
+
|
|
1108
|
+
- [SIcon](../SIcon)
|
|
1109
|
+
|
|
1110
|
+
### Graph
|
|
1111
|
+
|
|
1112
|
+
---
|
|
1113
|
+
|
|
1114
|
+
# SChip
|
|
1115
|
+
|
|
1116
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1117
|
+
|
|
1118
|
+
### SChip
|
|
1119
|
+
|
|
1120
|
+
#### Props
|
|
1121
|
+
|
|
1122
|
+
| Prop | Type | Default | Description |
|
|
1123
|
+
|------|------|---------|-------------|
|
|
1124
|
+
| `name?` | `string` | — | 폼 연동용 name |
|
|
1125
|
+
| `value?` | `string` | `''` | 칩 텍스트 값 |
|
|
1126
|
+
| `error?` | `boolean` | — | 에러 상태 |
|
|
1127
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
1128
|
+
| `editable?` | `boolean` | `false` | 인라인 편집 가능 (기본값 false) |
|
|
1129
|
+
| `showRemove?` | `boolean` | `true` | 닫기 버튼 표시 |
|
|
1130
|
+
| `placeholder?` | `string` | `''` | 편집 중 placeholder |
|
|
1131
|
+
| `rules?` | `Rule[]` | — | 유효성 규칙 |
|
|
1132
|
+
| `className?` | `string` | — | |
|
|
1133
|
+
| `style?` | `CSSProperties` | — | |
|
|
1134
|
+
|
|
1135
|
+
#### Events
|
|
1136
|
+
|
|
1137
|
+
| Event | Type | Description |
|
|
1138
|
+
|-------|------|-------------|
|
|
1139
|
+
| `onValueChange` | `(value: string) => void` | 편집 완료 (sdUpdate) |
|
|
1140
|
+
| `onRemove` | `() => void` | 삭제 (sdRemove) |
|
|
1141
|
+
| `onFocus` | `() => void` | 편집 진입 (sdFocus) |
|
|
1142
|
+
| `onBlur` | `() => void` | 편집 이탈 (sdBlur) |
|
|
1143
|
+
|
|
1144
|
+
#### Methods (ref)
|
|
1145
|
+
|
|
1146
|
+
| Method | Type | Description |
|
|
1147
|
+
|--------|------|-------------|
|
|
1148
|
+
| `focus` | `() => void` | 편집 input에 포커스합니다. |
|
|
1149
|
+
| `getNativeElement` | `() => HTMLElement \| null` | 네이티브 편집 엘리먼트를 반환합니다. |
|
|
1150
|
+
|
|
1151
|
+
## Dependencies
|
|
1152
|
+
|
|
1153
|
+
### Used by
|
|
1154
|
+
|
|
1155
|
+
- [SChipInput](../SChipInput)
|
|
1156
|
+
- [SFilePicker](../SFilePicker)
|
|
1157
|
+
|
|
1158
|
+
### Depends on
|
|
1159
|
+
|
|
1160
|
+
- [SGhostButton](../SGhostButton)
|
|
1161
|
+
|
|
1162
|
+
### Graph
|
|
1163
|
+
|
|
1164
|
+
---
|
|
1165
|
+
|
|
1166
|
+
# SChipInput
|
|
1167
|
+
|
|
1168
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1169
|
+
|
|
1170
|
+
### SChipInput
|
|
1171
|
+
|
|
1172
|
+
#### Props
|
|
1173
|
+
|
|
1174
|
+
| Prop | Type | Default | Description |
|
|
1175
|
+
|------|------|---------|-------------|
|
|
1176
|
+
| `values?` | `string[]` | `[]` | 칩 값 목록 |
|
|
1177
|
+
| `errors?` | `boolean[] \| ((value: string) => boolean)` | `[]` | 칩별 에러 (배열 또는 판별 함수) |
|
|
1178
|
+
| `disabledChips?` | `boolean[] \| ((value: string) => boolean)` | `[]` | 칩별 비활성 (배열 또는 판별 함수) |
|
|
1179
|
+
| `size?` | `SChipInputSize` | `'sm'` | |
|
|
1180
|
+
| `disabled?` | `boolean` | `false` | |
|
|
1181
|
+
| `placeholder?` | `string` | `'태그 입력 (Enter로 등록 / 콤마로 구분 / 띄어쓰기 불가)'` | |
|
|
1182
|
+
| `name?` | `string` | — | |
|
|
1183
|
+
| `rules?` | `Rule[]` | — | |
|
|
1184
|
+
| `error?` | `boolean` | — | |
|
|
1185
|
+
| `useReset?` | `boolean` | `false` | 입력 초기화 버튼 표시 |
|
|
1186
|
+
| `maxCount?` | `number` | — | 최대 칩 개수 |
|
|
1187
|
+
| `metaPlacement?` | `SChipInputMetaPlacement` | `'end'` | 최대 개수·초기화 meta 위치 |
|
|
1188
|
+
| `duplicateLabel?` | `string` | — | 중복 에러 메시지 항목명 |
|
|
1189
|
+
| `suggestions?` | `string[]` | `[]` | 자동완성 후보 |
|
|
1190
|
+
| `loadingSuggestions?` | `boolean` | `false` | |
|
|
1191
|
+
| `recommendedItems?` | `string[]` | `[]` | 추천 항목 (입력값 없을 때) |
|
|
1192
|
+
| `loadingRecommendedItems?` | `boolean` | `false` | |
|
|
1193
|
+
| `dropdownMinWidth?` | `number \| string` | `200` | 드롭다운 최소 너비 (숫자=px) |
|
|
1194
|
+
| `label?` | `string` | — | |
|
|
1195
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
1196
|
+
| `hint?` | `string` | — | |
|
|
1197
|
+
| `errorMessage?` | `string` | — | |
|
|
1198
|
+
| `width?` | `number \| string` | — | |
|
|
1199
|
+
| `status?` | `SFieldStatus` | — | |
|
|
1200
|
+
| `icon?` | `SIconName` | — | |
|
|
1201
|
+
| `iconColor?` | `SColor` | — | |
|
|
1202
|
+
| `labelTooltip?` | `string` | — | |
|
|
1203
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
1204
|
+
| `className?` | `string` | — | |
|
|
1205
|
+
| `style?` | `CSSProperties` | — | |
|
|
1206
|
+
|
|
1207
|
+
#### Events
|
|
1208
|
+
|
|
1209
|
+
| Event | Type | Description |
|
|
1210
|
+
|-------|------|-------------|
|
|
1211
|
+
| `onValueChange` | `(values: string[]) => void` | 값 변경 (sdUpdate) — 전체 배열 |
|
|
1212
|
+
| `onInput` | `(value: string) => void` | 입력 중 문자열 변경 (sdInput) |
|
|
1213
|
+
| `onFocus` | `() => void` | |
|
|
1214
|
+
| `onBlur` | `() => void` | |
|
|
1215
|
+
|
|
1216
|
+
#### Methods (ref)
|
|
1217
|
+
|
|
1218
|
+
| Method | Type | Description |
|
|
1219
|
+
|--------|------|-------------|
|
|
1220
|
+
| `focus` | `() => void` | 입력 필드에 포커스를 이동합니다. |
|
|
1221
|
+
|
|
1222
|
+
## Dependencies
|
|
1223
|
+
|
|
1224
|
+
### Depends on
|
|
1225
|
+
|
|
1226
|
+
- [SChip](../SChip)
|
|
1227
|
+
- [SField](../SField)
|
|
1228
|
+
- [SIcon](../SIcon)
|
|
1229
|
+
- [SPortal](../SPortal)
|
|
1230
|
+
- [STextLink](../STextLink)
|
|
1231
|
+
|
|
1232
|
+
### Graph
|
|
1233
|
+
|
|
1234
|
+
---
|
|
1235
|
+
|
|
1236
|
+
# SCircleProgress
|
|
1237
|
+
|
|
1238
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1239
|
+
|
|
1240
|
+
### SCircleProgress
|
|
1241
|
+
|
|
1242
|
+
#### Props
|
|
1243
|
+
|
|
1244
|
+
| Prop | Type | Default | Description |
|
|
1245
|
+
|------|------|---------|-------------|
|
|
1246
|
+
| `value?` | `number` | `0` | 진행률 (0–100) |
|
|
1247
|
+
| `type?` | `SCircleProgressType` | `'primary'` | 색상 테마 |
|
|
1248
|
+
| `indeterminate?` | `boolean` | `false` | 불확정(스피너) 모드 — value 무시 |
|
|
1249
|
+
| `label?` | `string` | — | 하단 레이블 |
|
|
1250
|
+
| `innerValue?` | `boolean` | `false` | true면 퍼센트를 원 아래가 아닌 원 가운데에 표시 |
|
|
1251
|
+
| `className?` | `string` | — | |
|
|
1252
|
+
| `style?` | `CSSProperties` | — | |
|
|
1253
|
+
|
|
1254
|
+
## Dependencies
|
|
1255
|
+
|
|
1256
|
+
### Used by
|
|
1257
|
+
|
|
1258
|
+
- [SLoadingContainer](../SLoadingContainer)
|
|
1259
|
+
- [SLoadingModal](../SLoadingModal)
|
|
1260
|
+
- [STable](../STable)
|
|
1261
|
+
|
|
1262
|
+
### Graph
|
|
1263
|
+
|
|
1264
|
+
---
|
|
1265
|
+
|
|
1266
|
+
# SConfirmModal
|
|
1267
|
+
|
|
1268
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1269
|
+
|
|
1270
|
+
### SConfirmModal
|
|
1271
|
+
|
|
1272
|
+
#### Props
|
|
1273
|
+
|
|
1274
|
+
| Prop | Type | Default | Description |
|
|
1275
|
+
|------|------|---------|-------------|
|
|
1276
|
+
| `open?` | `boolean` | — | |
|
|
1277
|
+
| `persistent?` | `boolean` | — | true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent) |
|
|
1278
|
+
| `type?` | `SConfirmModalType` | `'positive'` | 타입 (아이콘·메인버튼 색 결정) |
|
|
1279
|
+
| `modalTitle?` | `string` | `''` | |
|
|
1280
|
+
| `titleClass?` | `string` | — | 제목 엘리먼트에 추가할 클래스 (sd-confirm-modal titleClass) |
|
|
1281
|
+
| `topMessage?` | `string[]` | `[]` | 콘텐츠 박스 상단 메시지 목록 (각 항목이 한 줄, HTML 문자열 허용 — innerHTML 렌더링) |
|
|
1282
|
+
| `bottomMessage?` | `string[]` | `[]` | 콘텐츠 박스 하단 메시지 목록 (각 항목이 한 줄, HTML 문자열 허용 — innerHTML 렌더링) |
|
|
1283
|
+
| `tagLabel?` | `string` | — | tag 슬롯 기본 태그 레이블 (tagSlot 미지정 시) |
|
|
1284
|
+
| `tagShape?` | `STagShape` | `'square'` | 태그 프리셋 (shape/size/color) — sd-confirm-modal tagPreset 대응 |
|
|
1285
|
+
| `tagSize?` | `STagSize` | `'sm'` | |
|
|
1286
|
+
| `tagColor?` | `STagColor` | `'grey'` | |
|
|
1287
|
+
| `slotLabel?` | `string` | — | 콘텐츠 박스에서 태그 오른쪽에 오는 텍스트 (optionSlot 미지정 시) |
|
|
1288
|
+
| `tagSlot?` | `ReactNode` | — | 콘텐츠 박스 tag 위치 커스텀 콘텐츠 (미지정 시 tagLabel 기반 STag) |
|
|
1289
|
+
| `optionSlot?` | `ReactNode` | — | 콘텐츠 박스에서 태그 오른쪽 커스텀 콘텐츠 (미지정 시 slotLabel 텍스트) |
|
|
1290
|
+
| `mainButtonLabel?` | `string` | `'확인'` | 메인 버튼 |
|
|
1291
|
+
| `mainButtonName?` | `ConfirmModalMainButton` | — | 확인 버튼 프리셋 (없으면 type에 따라 자동 결정) |
|
|
1292
|
+
| `subButtonLabel?` | `string` | — | 서브(취소) 버튼 |
|
|
1293
|
+
|
|
1294
|
+
#### Events
|
|
1295
|
+
|
|
1296
|
+
| Event | Type | Description |
|
|
1297
|
+
|-------|------|-------------|
|
|
1298
|
+
| `onOpenChange` | `(open: boolean) => void` | |
|
|
1299
|
+
| `onOk` | `() => void` | 확인 버튼 클릭 (sdOk) |
|
|
1300
|
+
| `onCancel` | `() => void` | |
|
|
1301
|
+
| `onClose` | `() => void` | 닫기(X) 버튼 클릭 (sdClose) |
|
|
1302
|
+
|
|
1303
|
+
## Dependencies
|
|
1304
|
+
|
|
1305
|
+
### Used by
|
|
1306
|
+
|
|
1307
|
+
- [SModal](../SModal)
|
|
1308
|
+
|
|
1309
|
+
### Depends on
|
|
1310
|
+
|
|
1311
|
+
- [SButton](../SButton)
|
|
1312
|
+
- [SIcon](../SIcon)
|
|
1313
|
+
- [SModalContainer](../SModalContainer)
|
|
1314
|
+
- [STag](../STag)
|
|
1315
|
+
|
|
1316
|
+
### Graph
|
|
1317
|
+
|
|
1318
|
+
---
|
|
1319
|
+
|
|
1320
|
+
# SDatePicker
|
|
1321
|
+
|
|
1322
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1323
|
+
|
|
1324
|
+
### SDatePicker
|
|
1325
|
+
|
|
1326
|
+
#### Props
|
|
1327
|
+
|
|
1328
|
+
| Prop | Type | Default | Description |
|
|
1329
|
+
|------|------|---------|-------------|
|
|
1330
|
+
| `value?` | `string \| null` | — | 선택 날짜 (YYYY-MM-DD) |
|
|
1331
|
+
| `size?` | `SDatePickerSize` | `'sm'` | |
|
|
1332
|
+
| `placeholder?` | `string` | `'YYYY-MM-DD'` | |
|
|
1333
|
+
| `selectable?` | `[string, string]` | — | 선택 가능 범위 [시작, 종료] |
|
|
1334
|
+
| `disabled?` | `boolean` | `false` | |
|
|
1335
|
+
| `width?` | `number \| string` | — | |
|
|
1336
|
+
| `name?` | `string` | — | |
|
|
1337
|
+
| `rules?` | `Rule[]` | — | |
|
|
1338
|
+
| `status?` | `SFieldStatus` | — | |
|
|
1339
|
+
| `label?` | `string` | — | |
|
|
1340
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
1341
|
+
| `icon?` | `SIconName` | — | |
|
|
1342
|
+
| `iconColor?` | `SColor` | — | |
|
|
1343
|
+
| `labelTooltip?` | `string` | — | |
|
|
1344
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
1345
|
+
| `addonLabel?` | `string` | — | |
|
|
1346
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | |
|
|
1347
|
+
| `hint?` | `string` | — | |
|
|
1348
|
+
| `error?` | `boolean` | — | |
|
|
1349
|
+
| `errorMessage?` | `string` | — | |
|
|
1350
|
+
| `className?` | `string` | — | |
|
|
1351
|
+
| `style?` | `CSSProperties` | — | |
|
|
1352
|
+
|
|
1353
|
+
#### Events
|
|
1354
|
+
|
|
1355
|
+
| Event | Type | Description |
|
|
1356
|
+
|-------|------|-------------|
|
|
1357
|
+
| `onValueChange` | `(date: string) => void` | 선택 변경 (sdUpdate) |
|
|
1358
|
+
| `onViewChange` | `(view: { year: number; month: number }) => void` | 보이는 연·월 변경 (sdViewChange) |
|
|
1359
|
+
|
|
1360
|
+
## Dependencies
|
|
1361
|
+
|
|
1362
|
+
### Used by
|
|
1363
|
+
|
|
1364
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
1365
|
+
|
|
1366
|
+
### Depends on
|
|
1367
|
+
|
|
1368
|
+
- [SCalendar](../SCalendar)
|
|
1369
|
+
- [SField](../SField)
|
|
1370
|
+
- [SIcon](../SIcon)
|
|
1371
|
+
|
|
1372
|
+
### Graph
|
|
1373
|
+
|
|
1374
|
+
---
|
|
1375
|
+
|
|
1376
|
+
# SDateRangePicker
|
|
1377
|
+
|
|
1378
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1379
|
+
|
|
1380
|
+
### SDateRangePicker
|
|
1381
|
+
|
|
1382
|
+
#### Props
|
|
1383
|
+
|
|
1384
|
+
| Prop | Type | Default | Description |
|
|
1385
|
+
|------|------|---------|-------------|
|
|
1386
|
+
| `value?` | `SDateRangeValue` | — | |
|
|
1387
|
+
| `size?` | `SDateRangePickerSize` | `'sm'` | |
|
|
1388
|
+
| `placeholder?` | `string` | `'YYYY-MM-DD ~ YYYY-MM-DD'` | |
|
|
1389
|
+
| `selectable?` | `[string, string]` | — | |
|
|
1390
|
+
| `maxRange?` | `number` | — | 최대 선택 일수 |
|
|
1391
|
+
| `useTimePicker?` | `boolean` | `false` | 시간(시:분) 선택 푸터 사용 여부. true이면 value는 "YYYY-MM-DD HH:mm" 형식이 되고, 캘린더 하단에 시작·종료 시간 입력이 표시된다. |
|
|
1392
|
+
| `disabled?` | `boolean` | `false` | |
|
|
1393
|
+
| `width?` | `number \| string` | — | |
|
|
1394
|
+
| `name?` | `string` | — | |
|
|
1395
|
+
| `rules?` | `Rule[]` | — | |
|
|
1396
|
+
| `status?` | `SFieldStatus` | — | |
|
|
1397
|
+
| `label?` | `string` | — | |
|
|
1398
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
1399
|
+
| `icon?` | `SIconName` | — | |
|
|
1400
|
+
| `iconColor?` | `SColor` | — | |
|
|
1401
|
+
| `labelTooltip?` | `string` | — | |
|
|
1402
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
1403
|
+
| `addonLabel?` | `string` | — | |
|
|
1404
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | |
|
|
1405
|
+
| `hint?` | `string` | — | |
|
|
1406
|
+
| `error?` | `boolean` | — | |
|
|
1407
|
+
| `errorMessage?` | `string` | — | |
|
|
1408
|
+
| `className?` | `string` | — | |
|
|
1409
|
+
| `style?` | `CSSProperties` | — | |
|
|
1410
|
+
|
|
1411
|
+
#### Events
|
|
1412
|
+
|
|
1413
|
+
| Event | Type | Description |
|
|
1414
|
+
|-------|------|-------------|
|
|
1415
|
+
| `onValueChange` | `(range: SDateRangeValue) => void` | 선택 변경 (sdUpdate) — [start, end] |
|
|
1416
|
+
| `onViewChange` | `(view: { year: number; month: number }) => void` | 보이는 연·월 변경 (sdViewChange) |
|
|
1417
|
+
|
|
1418
|
+
## Dependencies
|
|
1419
|
+
|
|
1420
|
+
### Used by
|
|
1421
|
+
|
|
1422
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
1423
|
+
|
|
1424
|
+
### Depends on
|
|
1425
|
+
|
|
1426
|
+
- [SField](../SField)
|
|
1427
|
+
- [SGhostButton](../SGhostButton)
|
|
1428
|
+
- [SIcon](../SIcon)
|
|
1429
|
+
|
|
1430
|
+
### Graph
|
|
1431
|
+
|
|
1432
|
+
---
|
|
1433
|
+
|
|
1434
|
+
# SDivider
|
|
1435
|
+
|
|
1436
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1437
|
+
|
|
1438
|
+
### SDivider
|
|
1439
|
+
|
|
1440
|
+
#### Props
|
|
1441
|
+
|
|
1442
|
+
| Prop | Type | Default | Description |
|
|
1443
|
+
|------|------|---------|-------------|
|
|
1444
|
+
| `vertical?` | `boolean` | `false` | true면 수직 분할선, false면 수평 분할선 |
|
|
1445
|
+
|
|
1446
|
+
## Dependencies
|
|
1447
|
+
|
|
1448
|
+
### Used by
|
|
1449
|
+
|
|
1450
|
+
- [STableBar](../STableBar)
|
|
1451
|
+
|
|
1452
|
+
### Graph
|
|
1453
|
+
|
|
1454
|
+
---
|
|
1455
|
+
|
|
1456
|
+
# SDraggableItem
|
|
1457
|
+
|
|
1458
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1459
|
+
|
|
1460
|
+
### SDraggableItem
|
|
1461
|
+
|
|
1462
|
+
#### Props
|
|
1463
|
+
|
|
1464
|
+
| Prop | Type | Default | Description |
|
|
1465
|
+
|------|------|---------|-------------|
|
|
1466
|
+
| `title` | `SDraggableItemSlot` | — | 드래그 아이템 제목 |
|
|
1467
|
+
| `trailing?` | `SDraggableItemSlot` | — | 타이틀 뒤에 표시할 태그/콘텐츠 |
|
|
1468
|
+
| `accentStripe?` | `boolean` | `false` | 아이템 왼쪽 accent stripe 표시 여부 |
|
|
1469
|
+
| `bordered?` | `boolean` | `false` | 외곽 테두리 사용 여부 |
|
|
1470
|
+
| `selected?` | `boolean` | `false` | 선택 상태 여부 |
|
|
1471
|
+
| `dense?` | `boolean` | `false` | 조밀한 높이 사용 여부 |
|
|
1472
|
+
| `disabled?` | `boolean` | `false` | 비활성 상태 여부 |
|
|
1473
|
+
| `dragOverlay?` | `boolean` | `true` | 드래그 시 마우스를 따라가는 overlay 표시 여부 |
|
|
1474
|
+
| `dragOverlayOpacity?` | `number` | `0.75` | 드래그 overlay 투명도 |
|
|
1475
|
+
| `dragHandleProps?` | `HTMLAttributes<HTMLDivElement>` | — | 드래그 핸들에 전달할 속성 |
|
|
1476
|
+
|
|
1477
|
+
#### Events
|
|
1478
|
+
|
|
1479
|
+
| Event | Type | Description |
|
|
1480
|
+
|-------|------|-------------|
|
|
1481
|
+
| `onDragHandleMouseDown` | `(event: MouseEvent<HTMLDivElement>) => void` | 드래그 핸들 mouse down 이벤트 |
|
|
1482
|
+
|
|
1483
|
+
## Dependencies
|
|
1484
|
+
|
|
1485
|
+
### Depends on
|
|
1486
|
+
|
|
1487
|
+
- [SIcon](../SIcon)
|
|
1488
|
+
|
|
1489
|
+
### Graph
|
|
1490
|
+
|
|
1491
|
+
---
|
|
1492
|
+
|
|
1493
|
+
# SDropdownButton
|
|
1494
|
+
|
|
1495
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1496
|
+
|
|
1497
|
+
### SDropdownButton
|
|
1498
|
+
|
|
1499
|
+
#### Props
|
|
1500
|
+
|
|
1501
|
+
| Prop | Type | Default | Description |
|
|
1502
|
+
|------|------|---------|-------------|
|
|
1503
|
+
| `color?` | `SButtonColor` | `'primary'` | 버튼 색상 |
|
|
1504
|
+
| `outline?` | `boolean` | `false` | 아웃라인(테두리) 스타일 |
|
|
1505
|
+
| `size?` | `SDropdownButtonSize` | `'sm'` | 크기 (lg 미지원) |
|
|
1506
|
+
| `label?` | `string` | `''` | 버튼 레이블 |
|
|
1507
|
+
| `items?` | `SDropdownButtonItem[]` | `[]` | 메뉴 아이템 목록 |
|
|
1508
|
+
| `split?` | `boolean` | `false` | split 모드 — 레이블 버튼과 토글 분리 |
|
|
1509
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
1510
|
+
| `className?` | `string` | — | |
|
|
1511
|
+
| `style?` | `CSSProperties` | — | |
|
|
1512
|
+
|
|
1513
|
+
#### Events
|
|
1514
|
+
|
|
1515
|
+
| Event | Type | Description |
|
|
1516
|
+
|-------|------|-------------|
|
|
1517
|
+
| `onItemClick` | `(value: string \| number) => void` | 메뉴 아이템 선택 (sdClick) |
|
|
1518
|
+
| `onLabelClick` | `() => void` | split 레이블 버튼 클릭 (sdButtonClick) |
|
|
1519
|
+
| `onOpenChange` | `(open: boolean) => void` | 열림/닫힘 변경 (sdDropDownShow) |
|
|
1520
|
+
|
|
1521
|
+
#### Methods (ref)
|
|
1522
|
+
|
|
1523
|
+
| Method | Type | Description |
|
|
1524
|
+
|--------|------|-------------|
|
|
1525
|
+
| `open` | `() => void` | 드롭다운 열기 (sdOpen) |
|
|
1526
|
+
| `close` | `() => void` | 드롭다운 닫기 (sdClose) |
|
|
1527
|
+
|
|
1528
|
+
## Dependencies
|
|
1529
|
+
|
|
1530
|
+
### Depends on
|
|
1531
|
+
|
|
1532
|
+
- [SButton](../SButton)
|
|
1533
|
+
- [SIcon](../SIcon)
|
|
1534
|
+
|
|
1535
|
+
### Graph
|
|
1536
|
+
|
|
1537
|
+
---
|
|
1538
|
+
|
|
1539
|
+
# SExpansionItem
|
|
1540
|
+
|
|
1541
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1542
|
+
|
|
1543
|
+
### SExpansionItem
|
|
1544
|
+
|
|
1545
|
+
#### Props
|
|
1546
|
+
|
|
1547
|
+
| Prop | Type | Default | Description |
|
|
1548
|
+
|------|------|---------|-------------|
|
|
1549
|
+
| `title` | `ReactNode` | — | |
|
|
1550
|
+
| `depth?` | `1 \| 2 \| 3` | `1` | 중첩 단계. Figma 기준 1~3단계 |
|
|
1551
|
+
| `leading?` | `ReactNode \| SExpansionItemRenderProp` | — | 타이틀 앞에 표시할 아이콘/콘텐츠 |
|
|
1552
|
+
| `trailing?` | `ReactNode` | — | 타이틀 뒤에 표시할 태그/콘텐츠 |
|
|
1553
|
+
| `bodyPadding?` | `boolean` | `true` | body 내부 패딩 사용 여부 |
|
|
1554
|
+
| `bordered?` | `boolean` | `false` | 외곽 테두리 사용 여부 |
|
|
1555
|
+
| `expanded?` | `boolean` | — | |
|
|
1556
|
+
| `defaultExpanded?` | `boolean` | `false` | |
|
|
1557
|
+
| `dense?` | `boolean` | `false` | |
|
|
1558
|
+
| `disabled?` | `boolean` | `false` | |
|
|
1559
|
+
|
|
1560
|
+
#### Events
|
|
1561
|
+
|
|
1562
|
+
| Event | Type | Description |
|
|
1563
|
+
|-------|------|-------------|
|
|
1564
|
+
| `onToggle` | `(expanded: boolean, event: MouseEvent<HTMLButtonElement>) => void` | |
|
|
1565
|
+
|
|
1566
|
+
## Dependencies
|
|
1567
|
+
|
|
1568
|
+
### Depends on
|
|
1569
|
+
|
|
1570
|
+
- [SIcon](../SIcon)
|
|
1571
|
+
|
|
1572
|
+
### Graph
|
|
1573
|
+
|
|
1574
|
+
---
|
|
1575
|
+
|
|
1576
|
+
# SField
|
|
1577
|
+
|
|
1578
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1579
|
+
|
|
1580
|
+
### SField
|
|
1581
|
+
|
|
1582
|
+
#### Props
|
|
1583
|
+
|
|
1584
|
+
| Prop | Type | Default | Description |
|
|
1585
|
+
|------|------|---------|-------------|
|
|
1586
|
+
| `name?` | `string` | — | 폼 연동용 name 속성 |
|
|
1587
|
+
| `label?` | `string` | `''` | 레이블 텍스트 |
|
|
1588
|
+
| `icon?` | `SIconName` | — | 레이블 영역 아이콘명 (크기는 size 토큰 16px 고정) |
|
|
1589
|
+
| `iconColor?` | `SColor` | — | 레이블 영역 아이콘 색상. 미지정 시 currentColor 상속 |
|
|
1590
|
+
| `labelTooltip?` | `string` | `''` | 레이블 툴팁 텍스트 |
|
|
1591
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 (SdTooltipProps 대응) |
|
|
1592
|
+
| `labelWidth?` | `number \| string` | — | 레이블/어드온 레이블 너비 (숫자=px). label·addonLabel 폭에 공통 적용 |
|
|
1593
|
+
| `labelHeight?` | `number \| string` | — | 레이블 박스 높이 (숫자=px). 미지정 시 size별 기본값 사용. 컨트롤 박스가 기본 필드 높이보다 큰 경우(multiline 등) 첫 행에 세로 중앙 정렬을 맞추기 위해 컨트롤 박스 높이를 넘겨받는다. |
|
|
1594
|
+
| `size?` | `SFieldSize` | `'sm'` | 필드 크기 |
|
|
1595
|
+
| `addonLabel?` | `string` | `''` | 우측 어드온 레이블 |
|
|
1596
|
+
| `addonAlign?` | `SFieldAddonAlign` | `'start'` | 어드온 정렬 |
|
|
1597
|
+
| `error?` | `boolean` | `false` | 에러 상태 |
|
|
1598
|
+
| `errorMessage?` | `string` | `''` | 에러 메시지 |
|
|
1599
|
+
| `status?` | `SFieldStatus` | — | 필드 상태 — 'error' | 'pass' | 'default'. 'pass'면 초록 테두리 |
|
|
1600
|
+
| `focused?` | `boolean` | `false` | 포커스 상태 (제어/반영) |
|
|
1601
|
+
| `hovered?` | `boolean` | `false` | 호버 상태 (제어/반영) |
|
|
1602
|
+
| `rules?` | `Rule[]` | — | 유효성 규칙 (검증은 컨트롤에서 수행, API 패리티) |
|
|
1603
|
+
| `hint?` | `string` | `''` | 하단 힌트 |
|
|
1604
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
1605
|
+
| `readOnly?` | `boolean` | `false` | 읽기 전용 (회색 배경) |
|
|
1606
|
+
| `width?` | `number \| string` | — | 컨트롤 너비 (숫자=px). 지정하면 필드가 부모 폭을 다 먹지 않고 (레이블 + width) 만큼만 차지한다. 다른 요소와 나란히 놓으려면 부모를 flex 로 두면 된다. |
|
|
1607
|
+
| `minWidth?` | `number \| string` | — | 컨트롤 최소 너비 (숫자=px). 하한선만 지정하며 필드는 계속 부모 폭을 채운다 |
|
|
1608
|
+
| `multiline?` | `boolean` | `false` | 멀티라인(textarea) — 컨트롤 높이를 고정하지 않고 min-height만 적용 |
|
|
1609
|
+
| `borderless?` | `boolean` | `false` | 테두리 박스 제거 (inline 컨트롤용) — border/배경/hover·focus 강조만 사라지고 label·hint·errorMessage 등 나머지 필드 구성은 그대로 동작한다. |
|
|
1610
|
+
| `children?` | `ReactNode` | — | 실제 컨트롤 (input/select 등) — 테두리 없이 렌더, 테두리는 SField가 제공 |
|
|
1611
|
+
| `className?` | `string` | — | |
|
|
1612
|
+
| `style?` | `CSSProperties` | — | |
|
|
1613
|
+
|
|
1614
|
+
#### Events
|
|
1615
|
+
|
|
1616
|
+
| Event | Type | Description |
|
|
1617
|
+
|-------|------|-------------|
|
|
1618
|
+
| `onMouseEnter` | `() => void` | |
|
|
1619
|
+
| `onMouseLeave` | `() => void` | |
|
|
1620
|
+
|
|
1621
|
+
#### Methods (ref)
|
|
1622
|
+
|
|
1623
|
+
| Method | Type | Description |
|
|
1624
|
+
|--------|------|-------------|
|
|
1625
|
+
| `focus` | `() => void` | 내부 컨트롤에 포커스하고 필드를 화면에 스크롤합니다. |
|
|
1626
|
+
|
|
1627
|
+
## Dependencies
|
|
1628
|
+
|
|
1629
|
+
### Used by
|
|
1630
|
+
|
|
1631
|
+
- [SBarcodeInput](../SBarcodeInput)
|
|
1632
|
+
- [SChipInput](../SChipInput)
|
|
1633
|
+
- [SDatePicker](../SDatePicker)
|
|
1634
|
+
- [SDateRangePicker](../SDateRangePicker)
|
|
1635
|
+
- [SFilePicker](../SFilePicker)
|
|
1636
|
+
- [SInput](../SInput)
|
|
1637
|
+
- [SNumberInput](../SNumberInput)
|
|
1638
|
+
- [SSelect](../SSelect)
|
|
1639
|
+
- [STextarea](../STextarea)
|
|
1640
|
+
- [STimePicker](../STimePicker)
|
|
1641
|
+
- [STimeRangePicker](../STimeRangePicker)
|
|
1642
|
+
|
|
1643
|
+
### Depends on
|
|
1644
|
+
|
|
1645
|
+
- [SIcon](../SIcon)
|
|
1646
|
+
- [STooltip](../STooltip)
|
|
1647
|
+
|
|
1648
|
+
### Graph
|
|
1649
|
+
|
|
1650
|
+
---
|
|
1651
|
+
|
|
1652
|
+
# SFilePicker
|
|
1653
|
+
|
|
1654
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1655
|
+
|
|
1656
|
+
### SFilePicker
|
|
1657
|
+
|
|
1658
|
+
#### Props
|
|
1659
|
+
|
|
1660
|
+
| Prop | Type | Default | Description |
|
|
1661
|
+
|------|------|---------|-------------|
|
|
1662
|
+
| `value?` | `SFilePickerValue` | `null` | |
|
|
1663
|
+
| `placeholder?` | `string` | `'Click to upload'` | |
|
|
1664
|
+
| `disabled?` | `boolean` | `false` | |
|
|
1665
|
+
| `focused?` | `boolean` | `false` | 포커스 상태 여부 |
|
|
1666
|
+
| `hovered?` | `boolean` | `false` | 호버 상태 여부 |
|
|
1667
|
+
| `inline?` | `boolean` | `false` | 인라인 표시 — SField 테두리 박스만 사라지고 label/rules/hint 는 그대로 동작 |
|
|
1668
|
+
| `multiple?` | `boolean` | `false` | |
|
|
1669
|
+
| `useMultipleListBox?` | `boolean` | `false` | multiple 파일 목록을 필드 아래 칩 대신, caret(▼) 클릭 시 열리는 리스트박스 카드로 표시 (바깥 클릭 시 닫힘) |
|
|
1670
|
+
| `accept?` | `string` | — | |
|
|
1671
|
+
| `maxFileSize?` | `number \| string` | — | |
|
|
1672
|
+
| `maxTotalSize?` | `number \| string` | — | |
|
|
1673
|
+
| `maxFiles?` | `number \| string` | — | |
|
|
1674
|
+
| `name?` | `string` | — | |
|
|
1675
|
+
| `rules?` | `Rule[]` | — | |
|
|
1676
|
+
| `status?` | `SFieldStatus` | — | |
|
|
1677
|
+
| `size?` | `SFieldSize` | `'sm'` | |
|
|
1678
|
+
| `label?` | `string` | — | |
|
|
1679
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
1680
|
+
| `icon?` | `SIconName` | — | |
|
|
1681
|
+
| `iconColor?` | `SColor` | — | |
|
|
1682
|
+
| `labelTooltip?` | `string` | — | |
|
|
1683
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
1684
|
+
| `addonLabel?` | `string` | — | |
|
|
1685
|
+
| `addonAlign?` | `SFieldAddonAlign` | `'start'` | |
|
|
1686
|
+
| `hint?` | `string` | — | |
|
|
1687
|
+
| `error?` | `boolean` | — | |
|
|
1688
|
+
| `errorMessage?` | `string` | — | |
|
|
1689
|
+
| `width?` | `number \| string` | — | |
|
|
1690
|
+
| `className?` | `string` | — | |
|
|
1691
|
+
| `style?` | `CSSProperties` | — | |
|
|
1692
|
+
|
|
1693
|
+
#### Events
|
|
1694
|
+
|
|
1695
|
+
| Event | Type | Description |
|
|
1696
|
+
|-------|------|-------------|
|
|
1697
|
+
| `onValueChange` | `(value: SFilePickerValue) => void` | 파일 변경 (sdUpdate) |
|
|
1698
|
+
| `onReject` | `(detail: { files: File[]; reason: SFilePickerRejectReason }) => void` | 제한 초과 거부 (sdReject) |
|
|
1699
|
+
|
|
1700
|
+
## Dependencies
|
|
1701
|
+
|
|
1702
|
+
### Used by
|
|
1703
|
+
|
|
1704
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
1705
|
+
|
|
1706
|
+
### Depends on
|
|
1707
|
+
|
|
1708
|
+
- [SChip](../SChip)
|
|
1709
|
+
- [SField](../SField)
|
|
1710
|
+
- [SGhostButton](../SGhostButton)
|
|
1711
|
+
- [SIcon](../SIcon)
|
|
1712
|
+
|
|
1713
|
+
### Graph
|
|
1714
|
+
|
|
1715
|
+
---
|
|
1716
|
+
|
|
1717
|
+
# SForm
|
|
1718
|
+
|
|
1719
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1720
|
+
|
|
1721
|
+
### SForm
|
|
1722
|
+
|
|
1723
|
+
#### Props
|
|
1724
|
+
|
|
1725
|
+
| Prop | Type | Default | Description |
|
|
1726
|
+
|------|------|---------|-------------|
|
|
1727
|
+
| `formClass?` | `string` | — | form 엘리먼트에 추가할 클래스 (sd-form formClass 대응) |
|
|
1728
|
+
| `children?` | `ReactNode` | — | |
|
|
1729
|
+
| `className?` | `string` | — | |
|
|
1730
|
+
| `style?` | `CSSProperties` | — | |
|
|
1731
|
+
|
|
1732
|
+
#### Events
|
|
1733
|
+
|
|
1734
|
+
| Event | Type | Description |
|
|
1735
|
+
|-------|------|-------------|
|
|
1736
|
+
| `onSubmit` | `() => void` | 모든 필드 검증 통과 후 발생 (sd-form sdSubmit 대응) |
|
|
1737
|
+
| `onValidationError` | `(error: SFormValidationError) => void` | 검증 실패 시 실패한 필드 name 목록 전달 (sd-form sdValidationError 대응) |
|
|
1738
|
+
|
|
1739
|
+
#### Methods (ref)
|
|
1740
|
+
|
|
1741
|
+
| Method | Type | Description |
|
|
1742
|
+
|--------|------|-------------|
|
|
1743
|
+
| `validate` | `() => boolean` | 등록된 모든 필드를 검증하고 통과 여부를 반환 |
|
|
1744
|
+
| `resetValidation` | `() => void` | 모든 필드의 검증 상태만 초기화 (값은 소비자 소유) |
|
|
1745
|
+
| `reset` | `() => void` | resetValidation 별칭 — sd-form sdReset 대응. 값 리셋은 소비자(value/onChange) 책임 |
|
|
1746
|
+
| `focusFirstInvalid` | `() => void` | 첫 번째 실패 필드로 포커스 이동 |
|
|
1747
|
+
|
|
1748
|
+
---
|
|
1749
|
+
|
|
1750
|
+
# SGhostButton
|
|
1751
|
+
|
|
1752
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1753
|
+
|
|
1754
|
+
### SGhostButton
|
|
1755
|
+
|
|
1756
|
+
#### Props
|
|
1757
|
+
|
|
1758
|
+
| Prop | Type | Default | Description |
|
|
1759
|
+
|------|------|---------|-------------|
|
|
1760
|
+
| `icon` | `SIconName` | — | 표시할 아이콘명 (필수) |
|
|
1761
|
+
| `size?` | `SGhostButtonSize` | `'sm'` | 버튼 크기 |
|
|
1762
|
+
| `intent?` | `SGhostButtonIntent` | `'default'` | 색상 의도 |
|
|
1763
|
+
| `ariaLabel?` | `string` | `''` | 스크린리더용 접근성 레이블 |
|
|
1764
|
+
| `ariaPressed?` | `boolean` | — | 토글 버튼일 때 눌림 상태 (aria-pressed). 미지정 시 속성 자체를 내보내지 않는다. |
|
|
1765
|
+
| `tooltipText?` | `string` | — | 호버 시 표시할 툴팁 텍스트 |
|
|
1766
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
1767
|
+
| `anchorClassName?` | `string` | — | tooltip anchor wrapper 클래스. tooltipText가 있을 때 위치 조정용으로 사용합니다. |
|
|
1768
|
+
| `anchorStyle?` | `CSSProperties` | — | tooltip anchor wrapper 스타일. tooltipText가 있을 때 위치 조정용으로 사용합니다. |
|
|
1769
|
+
| `className?` | `string` | — | |
|
|
1770
|
+
| `style?` | `CSSProperties` | — | |
|
|
1771
|
+
|
|
1772
|
+
#### Events
|
|
1773
|
+
|
|
1774
|
+
| Event | Type | Description |
|
|
1775
|
+
|-------|------|-------------|
|
|
1776
|
+
| `onClick` | `(e: MouseEvent<HTMLButtonElement>) => void` | 클릭 (sdClick) |
|
|
1777
|
+
|
|
1778
|
+
## Dependencies
|
|
1779
|
+
|
|
1780
|
+
### Used by
|
|
1781
|
+
|
|
1782
|
+
- [SBarcodeInput](../SBarcodeInput)
|
|
1783
|
+
- [SCalendar](../SCalendar)
|
|
1784
|
+
- [SChip](../SChip)
|
|
1785
|
+
- [SDateRangePicker](../SDateRangePicker)
|
|
1786
|
+
- [SFilePicker](../SFilePicker)
|
|
1787
|
+
- [SGnb](../SGnb)
|
|
1788
|
+
- [SGuide](../SGuide)
|
|
1789
|
+
- [SInput](../SInput)
|
|
1790
|
+
- [SModalContainer](../SModalContainer)
|
|
1791
|
+
- [SPopover](../SPopover)
|
|
1792
|
+
- [SSelect](../SSelect)
|
|
1793
|
+
- [STimePicker](../STimePicker)
|
|
1794
|
+
- [STimeRangePicker](../STimeRangePicker)
|
|
1795
|
+
- [SToast](../SToast)
|
|
1796
|
+
- [STooltip](../STooltip)
|
|
1797
|
+
|
|
1798
|
+
### Depends on
|
|
1799
|
+
|
|
1800
|
+
- [SIcon](../SIcon)
|
|
1801
|
+
- [STag](../STag)
|
|
1802
|
+
|
|
1803
|
+
### Graph
|
|
1804
|
+
|
|
1805
|
+
---
|
|
1806
|
+
|
|
1807
|
+
# SGnb
|
|
1808
|
+
|
|
1809
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1810
|
+
|
|
1811
|
+
### SGnb
|
|
1812
|
+
|
|
1813
|
+
#### Props
|
|
1814
|
+
|
|
1815
|
+
| Prop | Type | Default | Description |
|
|
1816
|
+
|------|------|---------|-------------|
|
|
1817
|
+
| `type?` | `SGnbType` | — | 메뉴 스타일: box(라운드) / belt(풀폭 행). 미지정 시 SLayout 의 type 을 따른다. |
|
|
1818
|
+
| `header?` | `SGnbHeader` | — | 상단바 구조: fix(GNB 폭 고정) / full(레이아웃 전폭). 미지정 시 SLayout 의 header 를 따른다. 단, useRail 이고 레일에 children 없는 아이템이 있으면 메뉴 폭이 출렁이므로 full 로 강제된다. |
|
|
1819
|
+
| `color?` | `SGnbColor` | `'light'` | 색상 테마: light / dark |
|
|
1820
|
+
| `items` | `SGnbMenuItem[]` | — | 메뉴 트리 (depth1 → depth2 → depth3). useRail 이면 첫 depth 가 레일이 되고 그 children 이 depth1 이 된다. |
|
|
1821
|
+
| `useRail?` | `boolean` | — | 좌측 레일 사용 여부. 켜면 items 의 첫 depth 가 아이콘+라벨 버튼의 세로 레일로 서고, 선택된 레일 아이템의 children 이 오른쪽 메뉴 패널에 깔린다. 미지정 시 SLayout 의 useRail 을 따른다. children 없는 레일 아이템이 활성이면 메뉴 패널은 렌더되지 않고 레일만 남는다. |
|
|
1822
|
+
| `value?` | `string` | `''` | 현재 선택된 아이템 value |
|
|
1823
|
+
| `folded?` | `boolean` | — | 접힘(레일) 상태. 미지정 시 SLayout 의 folded 를 따른다. |
|
|
1824
|
+
| `logo?` | `ReactNode` | — | 상단바 로고 영역 (slot) |
|
|
1825
|
+
| `railFooter?` | `ReactNode` | — | 레일 하단 고정 슬롯. 레일 아이템이 많아 넘치면 아이템 목록(ul)만 스크롤되고 이 슬롯은 레일 하단에 붙어 고정된다. useRail 일 때만 렌더된다. |
|
|
1826
|
+
| `menuFooter?` | `ReactNode` | — | 메뉴 하단 고정 슬롯. 메뉴 아이템이 많아 넘치면 메뉴 목록(ul)만 스크롤되고 이 슬롯은 메뉴 하단에 붙어 고정된다. 메뉴가 렌더될 때만(showMenu) 나타난다. |
|
|
1827
|
+
| `foldedFooter?` | `ReactNode` | — | 접힘(fix 레일) 하단 고정 슬롯. 접으면 본문이 빠져나가며 rail/menu footer 도 사라지므로, 48px 폴드 레일 바닥에 붙는 별도 슬롯이다. header="fix" 로 접혔을 때만 나타난다. |
|
|
1828
|
+
| `ariaLabel?` | `string` | `'global navigation'` | 메뉴 landmark(nav) 의 접근성 레이블. 한 화면에 nav 가 여럿일 때 구분한다. |
|
|
1829
|
+
|
|
1830
|
+
#### Events
|
|
1831
|
+
|
|
1832
|
+
| Event | Type | Description |
|
|
1833
|
+
|-------|------|-------------|
|
|
1834
|
+
| `onValueChange` | `(value: string) => void` | 선택 변경 (sdUpdate) |
|
|
1835
|
+
| `onRailChange` | `(value: string) => void` | 레일 선택 변경. 레일 아이템을 눌러 패널이 바뀔 때 알린다(선택 상태는 SGnb 가 자체 관리). |
|
|
1836
|
+
| `onFoldChange` | `(folded: boolean) => void` | 접힘 토글 (sdFoldChange) |
|
|
1837
|
+
| `onLauncherClick` | `() => void` | 앱런처(그리드) 버튼 클릭. 미지정 시 런처 버튼을 렌더하지 않는다. 접힘 레일(fix)에는 폴드 버튼만 남으므로 표시되지 않는다. |
|
|
1838
|
+
|
|
1839
|
+
## Dependencies
|
|
1840
|
+
|
|
1841
|
+
### Used by
|
|
1842
|
+
|
|
1843
|
+
- [SLayout](../SLayout)
|
|
1844
|
+
|
|
1845
|
+
### Depends on
|
|
1846
|
+
|
|
1847
|
+
- [SGhostButton](../SGhostButton)
|
|
1848
|
+
- [SIcon](../SIcon)
|
|
1849
|
+
- [SLayout](../SLayout)
|
|
1850
|
+
- [STag](../STag)
|
|
1851
|
+
|
|
1852
|
+
### Graph
|
|
1853
|
+
|
|
1854
|
+
---
|
|
1855
|
+
|
|
1856
|
+
# SGuide
|
|
1857
|
+
|
|
1858
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1859
|
+
|
|
1860
|
+
### SGuide
|
|
1861
|
+
|
|
1862
|
+
#### Props
|
|
1863
|
+
|
|
1864
|
+
| Prop | Type | Default | Description |
|
|
1865
|
+
|------|------|---------|-------------|
|
|
1866
|
+
| `type?` | `SGuideType` | `'tip'` | 가이드 타입 (tip: 팝업, notion: 외부 링크) |
|
|
1867
|
+
| `label?` | `string` | `''` | 버튼 레이블 (없으면 type 기본값) |
|
|
1868
|
+
| `message?` | `SGuideMessage` | `''` | 팝업 메시지 (배열이면 리스트, 중첩 배열이면 depth 표현) |
|
|
1869
|
+
| `url?` | `string` | `''` | notion 타입 클릭 시 이동 URL |
|
|
1870
|
+
| `popupTitle?` | `string` | `''` | 팝업 제목 (없으면 type 기본값) |
|
|
1871
|
+
| `popupWidth?` | `number` | — | 팝업 너비 (px, 기본 426) |
|
|
1872
|
+
| `className?` | `string` | — | |
|
|
1873
|
+
| `style?` | `CSSProperties` | — | |
|
|
1874
|
+
|
|
1875
|
+
## Dependencies
|
|
1876
|
+
|
|
1877
|
+
### Depends on
|
|
1878
|
+
|
|
1879
|
+
- [SGhostButton](../SGhostButton)
|
|
1880
|
+
- [SIcon](../SIcon)
|
|
1881
|
+
|
|
1882
|
+
### Graph
|
|
1883
|
+
|
|
1884
|
+
---
|
|
1885
|
+
|
|
1886
|
+
# SIcon
|
|
1887
|
+
|
|
1888
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1889
|
+
|
|
1890
|
+
### SIcon
|
|
1891
|
+
|
|
1892
|
+
#### Props
|
|
1893
|
+
|
|
1894
|
+
| Prop | Type | Default | Description |
|
|
1895
|
+
|------|------|---------|-------------|
|
|
1896
|
+
| `name` | `SIconName` | — | 아이콘명 |
|
|
1897
|
+
| `size?` | `number \| string` | `24` | 아이콘 크기(px 또는 CSS 길이) |
|
|
1898
|
+
| `color?` | `SColor` | — | 아이콘 색상. 팔레트 키(`grey_65`, `red_95` …) 또는 임의 CSS 색상. 미지정 시 currentColor 상속 |
|
|
1899
|
+
| `rotate?` | `0 \| 90 \| 180 \| 270` | — | 회전 각도 |
|
|
1900
|
+
| `label?` | `string` | — | 접근성 라벨. 없으면 aria-hidden 처리 |
|
|
1901
|
+
| `className?` | `string` | — | |
|
|
1902
|
+
| `style?` | `CSSProperties` | — | |
|
|
1903
|
+
|
|
1904
|
+
## Dependencies
|
|
1905
|
+
|
|
1906
|
+
### Used by
|
|
1907
|
+
|
|
1908
|
+
- [SButton](../SButton)
|
|
1909
|
+
- [SCallout](../SCallout)
|
|
1910
|
+
- [SCheckbox](../SCheckbox)
|
|
1911
|
+
- [SChipInput](../SChipInput)
|
|
1912
|
+
- [SConfirmModal](../SConfirmModal)
|
|
1913
|
+
- [SDatePicker](../SDatePicker)
|
|
1914
|
+
- [SDateRangePicker](../SDateRangePicker)
|
|
1915
|
+
- [SDraggableItem](../SDraggableItem)
|
|
1916
|
+
- [SDropdownButton](../SDropdownButton)
|
|
1917
|
+
- [SExpansionItem](../SExpansionItem)
|
|
1918
|
+
- [SField](../SField)
|
|
1919
|
+
- [SFilePicker](../SFilePicker)
|
|
1920
|
+
- [SGhostButton](../SGhostButton)
|
|
1921
|
+
- [SGnb](../SGnb)
|
|
1922
|
+
- [SGuide](../SGuide)
|
|
1923
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
1924
|
+
- [SList](../SList)
|
|
1925
|
+
- [SLoadingModal](../SLoadingModal)
|
|
1926
|
+
- [SNumberInput](../SNumberInput)
|
|
1927
|
+
- [SPagination](../SPagination)
|
|
1928
|
+
- [SPopover](../SPopover)
|
|
1929
|
+
- [SSectionHeaderCard](../SSectionHeaderCard)
|
|
1930
|
+
- [SSelect](../SSelect)
|
|
1931
|
+
- [SStepper](../SStepper)
|
|
1932
|
+
- [STable](../STable)
|
|
1933
|
+
- [STag](../STag)
|
|
1934
|
+
- [STextLink](../STextLink)
|
|
1935
|
+
- [STimePicker](../STimePicker)
|
|
1936
|
+
- [STimeRangePicker](../STimeRangePicker)
|
|
1937
|
+
- [SToast](../SToast)
|
|
1938
|
+
- [STooltip](../STooltip)
|
|
1939
|
+
|
|
1940
|
+
### Graph
|
|
1941
|
+
|
|
1942
|
+
---
|
|
1943
|
+
|
|
1944
|
+
# SInput
|
|
1945
|
+
|
|
1946
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
1947
|
+
|
|
1948
|
+
### SInput
|
|
1949
|
+
|
|
1950
|
+
#### Props
|
|
1951
|
+
|
|
1952
|
+
| Prop | Type | Default | Description |
|
|
1953
|
+
|------|------|---------|-------------|
|
|
1954
|
+
| `value?` | `string \| number` | — | 값 (제어) |
|
|
1955
|
+
| `type?` | `'text' \| 'password' \| 'email' \| 'number' \| 'tel' \| 'search' \| 'url'` | `'text'` | 입력 타입 |
|
|
1956
|
+
| `size?` | `SFieldSize` | `'sm'` | 크기 |
|
|
1957
|
+
| `icon?` | `SIconName` | — | 좌측 아이콘명 |
|
|
1958
|
+
| `iconColor?` | `SColor` | — | 좌측 아이콘 색상 |
|
|
1959
|
+
| `prefix?` | `ReactNode` | — | 입력 앞(좌측) 커스텀 노드 — 원본 slot="prefix" |
|
|
1960
|
+
| `suffix?` | `ReactNode` | — | 입력 뒤(우측) 커스텀 노드 — 원본 slot="suffix" |
|
|
1961
|
+
| `clearable?` | `boolean` | `false` | 지우기 버튼 |
|
|
1962
|
+
| `rules?` | `Rule[]` | — | 유효성 규칙 — blur 시 자동 검증 |
|
|
1963
|
+
| `status?` | `SFieldStatus` | — | 필드 상태 ('default' | 'pass' | 'error') |
|
|
1964
|
+
| `focused?` | `boolean` | — | 포커스 상태 (제어/반영) |
|
|
1965
|
+
| `hovered?` | `boolean` | — | 호버 상태 (제어/반영) |
|
|
1966
|
+
| `inputClass?` | `string` | — | 내부 input 요소 className |
|
|
1967
|
+
| `inputStyle?` | `CSSProperties` | — | 내부 input 요소 style |
|
|
1968
|
+
| `label?` | `string` | — | |
|
|
1969
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
1970
|
+
| `labelTooltip?` | `string` | — | 레이블 툴팁 텍스트 |
|
|
1971
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 |
|
|
1972
|
+
| `hint?` | `string` | — | |
|
|
1973
|
+
| `error?` | `boolean` | — | |
|
|
1974
|
+
| `errorMessage?` | `string` | — | |
|
|
1975
|
+
| `addonLabel?` | `string` | — | |
|
|
1976
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | 어드온 정렬 |
|
|
1977
|
+
| `width?` | `number \| string` | — | |
|
|
1978
|
+
| `disabled?` | `boolean` | `false` | |
|
|
1979
|
+
| `readOnly?` | `boolean` | `false` | |
|
|
1980
|
+
| `className?` | `string` | — | |
|
|
1981
|
+
| `style?` | `CSSProperties` | — | |
|
|
1982
|
+
|
|
1983
|
+
#### Events
|
|
1984
|
+
|
|
1985
|
+
| Event | Type | Description |
|
|
1986
|
+
|-------|------|-------------|
|
|
1987
|
+
| `onValueChange` | `(value: string) => void` | 값 변경 (sdUpdate) — 문자열 전달 |
|
|
1988
|
+
| `onChange` | `InputHTMLAttributes<HTMLInputElement>['onChange']` | 네이티브 onChange (form-agnostic 연동용, RHF 등) |
|
|
1989
|
+
|
|
1990
|
+
## Dependencies
|
|
1991
|
+
|
|
1992
|
+
### Used by
|
|
1993
|
+
|
|
1994
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
1995
|
+
|
|
1996
|
+
### Depends on
|
|
1997
|
+
|
|
1998
|
+
- [SField](../SField)
|
|
1999
|
+
- [SGhostButton](../SGhostButton)
|
|
2000
|
+
|
|
2001
|
+
### Graph
|
|
2002
|
+
|
|
2003
|
+
---
|
|
2004
|
+
|
|
2005
|
+
# SKeyValueTable
|
|
2006
|
+
|
|
2007
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2008
|
+
|
|
2009
|
+
### SKeyValueTable
|
|
2010
|
+
|
|
2011
|
+
#### Props
|
|
2012
|
+
|
|
2013
|
+
| Prop | Type | Default | Description |
|
|
2014
|
+
|------|------|---------|-------------|
|
|
2015
|
+
| `fields?` | `SKeyValueField[][]` | `[]` | 2차원 배열. row → [th|td] 필드들 |
|
|
2016
|
+
| `values?` | `Record<string, unknown>` | `{}` | field name을 key로 하는 값 객체 (`{ [name]: value }`). 지정 시 해당 field의 값으로 사용되며, field별 `options.value`보다 우선합니다. `onChange`의 `detail.values`와 함께 controlled 패턴으로 사용합니다. |
|
|
2017
|
+
| `search?` | `boolean` | `false` | 우측 검색 패널 |
|
|
2018
|
+
| `radius?` | `'default' \| 'useTop' \| 'full'` | `'default'` | border-radius 제어 |
|
|
2019
|
+
| `className?` | `string` | — | |
|
|
2020
|
+
| `style?` | `CSSProperties` | — | |
|
|
2021
|
+
|
|
2022
|
+
#### Events
|
|
2023
|
+
|
|
2024
|
+
| Event | Type | Description |
|
|
2025
|
+
|-------|------|-------------|
|
|
2026
|
+
| `onChange` | `(detail: SKeyValueChangeDetail) => void` | 값 변경 (sdChange) |
|
|
2027
|
+
| `onSearch` | `() => void` | 검색 클릭 (sdSearch) |
|
|
2028
|
+
|
|
2029
|
+
## Dependencies
|
|
2030
|
+
|
|
2031
|
+
### Depends on
|
|
2032
|
+
|
|
2033
|
+
- [SButton](../SButton)
|
|
2034
|
+
- [SCheckbox](../SCheckbox)
|
|
2035
|
+
- [SDatePicker](../SDatePicker)
|
|
2036
|
+
- [SDateRangePicker](../SDateRangePicker)
|
|
2037
|
+
- [SFilePicker](../SFilePicker)
|
|
2038
|
+
- [SIcon](../SIcon)
|
|
2039
|
+
- [SInput](../SInput)
|
|
2040
|
+
- [SNumberInput](../SNumberInput)
|
|
2041
|
+
- [SRadio](../SRadio)
|
|
2042
|
+
- [SSelect](../SSelect)
|
|
2043
|
+
- [STextarea](../STextarea)
|
|
2044
|
+
- [STooltip](../STooltip)
|
|
2045
|
+
|
|
2046
|
+
### Graph
|
|
2047
|
+
|
|
2048
|
+
---
|
|
2049
|
+
|
|
2050
|
+
# SLayout
|
|
2051
|
+
|
|
2052
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2053
|
+
|
|
2054
|
+
### SLayout
|
|
2055
|
+
|
|
2056
|
+
#### Props
|
|
2057
|
+
|
|
2058
|
+
| Prop | Type | Default | Description |
|
|
2059
|
+
|------|------|---------|-------------|
|
|
2060
|
+
| `type?` | `SLayoutType` | `'box'` | 메뉴 스타일: box(라운드) / belt(풀폭 행). 자식 SGnb 가 이 값을 따른다. |
|
|
2061
|
+
| `header?` | `SLayoutHeader` | `'fix'` | 레이아웃 구조: fix(가로 분할) / full(풀폭 상단바). 자식 SGnb·SPage 가 이 값을 따른다. |
|
|
2062
|
+
| `useRail?` | `boolean` | `false` | GNB 좌측 레일 사용 여부. 자식 SGnb 가 이 값을 따르고, full 의 메뉴 열 폭도 레일만큼 넓어진다. 레일에 children 없는 아이템이 있으면 SGnb 가 header 를 full 로 강제하고, 이 레이아웃도 그에 맞춰 full 그리드로 선다. |
|
|
2063
|
+
| `folded?` | `boolean` | — | GNB 접힘 상태 (controlled) |
|
|
2064
|
+
| `defaultFolded?` | `boolean` | `false` | GNB 초기 접힘 상태 (uncontrolled) |
|
|
2065
|
+
|
|
2066
|
+
#### Events
|
|
2067
|
+
|
|
2068
|
+
| Event | Type | Description |
|
|
2069
|
+
|-------|------|-------------|
|
|
2070
|
+
| `onFoldedChange` | `(folded: boolean) => void` | 접힘 상태 변경 |
|
|
2071
|
+
|
|
2072
|
+
## Dependencies
|
|
2073
|
+
|
|
2074
|
+
### Used by
|
|
2075
|
+
|
|
2076
|
+
- [SGnb](../SGnb)
|
|
2077
|
+
- [SPage](../SPage)
|
|
2078
|
+
|
|
2079
|
+
### Depends on
|
|
2080
|
+
|
|
2081
|
+
- [SGnb](../SGnb)
|
|
2082
|
+
|
|
2083
|
+
### Graph
|
|
2084
|
+
|
|
2085
|
+
---
|
|
2086
|
+
|
|
2087
|
+
# SLinearProgress
|
|
2088
|
+
|
|
2089
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2090
|
+
|
|
2091
|
+
### SLinearProgress
|
|
2092
|
+
|
|
2093
|
+
#### Props
|
|
2094
|
+
|
|
2095
|
+
| Prop | Type | Default | Description |
|
|
2096
|
+
|------|------|---------|-------------|
|
|
2097
|
+
| `value?` | `number` | `0` | 진행률 (0–100) |
|
|
2098
|
+
| `type?` | `SLinearProgressType` | `'primary'` | 색상 타입 |
|
|
2099
|
+
| `indeterminate?` | `boolean` | `false` | 진행률 없이 무한 애니메이션 |
|
|
2100
|
+
| `label?` | `string` | — | 하단 레이블 |
|
|
2101
|
+
| `className?` | `string` | — | |
|
|
2102
|
+
| `style?` | `CSSProperties` | — | |
|
|
2103
|
+
|
|
2104
|
+
---
|
|
2105
|
+
|
|
2106
|
+
# SList
|
|
2107
|
+
|
|
2108
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2109
|
+
|
|
2110
|
+
### SList
|
|
2111
|
+
|
|
2112
|
+
#### Props
|
|
2113
|
+
|
|
2114
|
+
| Prop | Type | Default | Description |
|
|
2115
|
+
|------|------|---------|-------------|
|
|
2116
|
+
| `children?` | `ReactNode` | — | 리스트 컨테이너 내부에 렌더링할 내용 |
|
|
2117
|
+
| `useGap?` | `boolean` | `false` | 리스트 아이템 사이 gap 토큰 적용 여부 |
|
|
2118
|
+
| `usePadding?` | `boolean` | `false` | 리스트 컨테이너 padding 토큰 적용 여부 |
|
|
2119
|
+
|
|
2120
|
+
---
|
|
2121
|
+
|
|
2122
|
+
# SListItem
|
|
2123
|
+
|
|
2124
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2125
|
+
|
|
2126
|
+
### SListItem
|
|
2127
|
+
|
|
2128
|
+
#### Props
|
|
2129
|
+
|
|
2130
|
+
| Prop | Type | Default | Description |
|
|
2131
|
+
|------|------|---------|-------------|
|
|
2132
|
+
| `title` | `SListItemSlot` | — | 리스트 아이템 제목 |
|
|
2133
|
+
| `depth?` | `1 \| 2 \| 3` | `1` | 중첩 단계. Figma 기준 1~3단계 |
|
|
2134
|
+
| `leading?` | `SListItemSlot` | — | 타이틀 앞에 표시할 아이콘/콘텐츠 |
|
|
2135
|
+
| `trailing?` | `SListItemSlot` | — | 타이틀 뒤에 표시할 태그/콘텐츠 |
|
|
2136
|
+
| `bordered?` | `boolean` | `false` | 외곽 테두리 사용 여부 |
|
|
2137
|
+
| `accentStripe?` | `boolean` | `false` | 아이템 왼쪽 accent stripe 표시 여부 |
|
|
2138
|
+
| `dense?` | `boolean` | `false` | 조밀한 높이 사용 여부 |
|
|
2139
|
+
| `disabled?` | `boolean` | `false` | 비활성 상태 여부 |
|
|
2140
|
+
|
|
2141
|
+
---
|
|
2142
|
+
|
|
2143
|
+
# SLoadingContainer
|
|
2144
|
+
|
|
2145
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2146
|
+
|
|
2147
|
+
### SLoadingContainer
|
|
2148
|
+
|
|
2149
|
+
#### Props
|
|
2150
|
+
|
|
2151
|
+
| Prop | Type | Default | Description |
|
|
2152
|
+
|------|------|---------|-------------|
|
|
2153
|
+
| `open?` | `boolean` | `false` | 오버레이 표시 여부 (Stencil의 show()/hide() 명령형 API → 제어 prop으로 대체) |
|
|
2154
|
+
| `message?` | `string` | — | 스피너 하단 메시지 |
|
|
2155
|
+
| `zIndex?` | `number` | `1200` | z-index. 기본값(1200)은 토스트(1100)·모달(1000/1001) 위 — 전체 화면을 막는 최상단 블로킹 오버레이 |
|
|
2156
|
+
| `className?` | `string` | — | |
|
|
2157
|
+
| `style?` | `CSSProperties` | — | |
|
|
2158
|
+
|
|
2159
|
+
## Dependencies
|
|
2160
|
+
|
|
2161
|
+
### Depends on
|
|
2162
|
+
|
|
2163
|
+
- [SCircleProgress](../SCircleProgress)
|
|
2164
|
+
|
|
2165
|
+
### Graph
|
|
2166
|
+
|
|
2167
|
+
---
|
|
2168
|
+
|
|
2169
|
+
# SLoadingModal
|
|
2170
|
+
|
|
2171
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2172
|
+
|
|
2173
|
+
### SLoadingModal
|
|
2174
|
+
|
|
2175
|
+
#### Props
|
|
2176
|
+
|
|
2177
|
+
| Prop | Type | Default | Description |
|
|
2178
|
+
|------|------|---------|-------------|
|
|
2179
|
+
| `open?` | `boolean` | — | |
|
|
2180
|
+
| `persistent?` | `boolean` | — | true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). 로딩 중 닫힘 방지에 유용 |
|
|
2181
|
+
| `state?` | `LoadingModalState` | `'loading'` | 상태 (loading: 스피너, error: 경고 아이콘) |
|
|
2182
|
+
| `progress?` | `number` | — | 진행률 (0–100) — 지정 시 determinate 스피너 |
|
|
2183
|
+
| `message?` | `string \| string[]` | — | 메시지 (없으면 state 기본값) |
|
|
2184
|
+
| `useButton?` | `boolean` | `false` | 하단 버튼 표시 |
|
|
2185
|
+
| `buttonLabel?` | `string` | — | 버튼 레이블 (없으면 state 기본값) |
|
|
2186
|
+
| `width?` | `number \| string` | `520` | |
|
|
2187
|
+
| `height?` | `number \| string` | `320` | |
|
|
2188
|
+
|
|
2189
|
+
#### Events
|
|
2190
|
+
|
|
2191
|
+
| Event | Type | Description |
|
|
2192
|
+
|-------|------|-------------|
|
|
2193
|
+
| `onOpenChange` | `(open: boolean) => void` | |
|
|
2194
|
+
| `onClose` | `() => void` | 닫기(X) 버튼 클릭 (sdClose) — error 상태에서만 노출 |
|
|
2195
|
+
| `onButtonClick` | `() => void` | 버튼 클릭 (sdClick) |
|
|
2196
|
+
|
|
2197
|
+
## Dependencies
|
|
2198
|
+
|
|
2199
|
+
### Used by
|
|
2200
|
+
|
|
2201
|
+
- [SModal](../SModal)
|
|
2202
|
+
|
|
2203
|
+
### Depends on
|
|
2204
|
+
|
|
2205
|
+
- [SButton](../SButton)
|
|
2206
|
+
- [SCircleProgress](../SCircleProgress)
|
|
2207
|
+
- [SIcon](../SIcon)
|
|
2208
|
+
- [SModalContainer](../SModalContainer)
|
|
2209
|
+
|
|
2210
|
+
### Graph
|
|
2211
|
+
|
|
2212
|
+
---
|
|
2213
|
+
|
|
2214
|
+
# SModal
|
|
2215
|
+
|
|
2216
|
+
> 수작성 문서 — SModal 은 컴포넌트가 아니라 **명령형 모달 서비스**라 `docs:gen`(Props/Events 표) 대상이 아니다.
|
|
2217
|
+
|
|
2218
|
+
버튼 핸들러에서 바로 호출해 모달을 띄우는 명령형 API. 선언형 `<SConfirmModal open>` / `<SLoadingModal open>` 을 **대체하지 않고 추가로** 제공한다. (원본 디자인 시스템 `sdModal` 파리티)
|
|
2219
|
+
|
|
2220
|
+
호출 시마다 `document.body` 에 컨테이너를 만들어 모달을 렌더하고, 닫힘 애니메이션이 끝나면 자동으로 언마운트한다. 모든 메서드는 체이닝 핸들 [`SModalRef`](#smodalref) 를 반환한다.
|
|
2221
|
+
|
|
2222
|
+
| 메서드 | 띄우는 모달 | 용도 | 주요 콜백/제어 |
|
|
2223
|
+
|---|---|---|---|
|
|
2224
|
+
| [`SModal.confirm(options)`](#smodalconfirm) | `SConfirmModal` | 확인/취소 | `onOk` / `onCancel` / `onClose` |
|
|
2225
|
+
| [`SModal.loading(options?)`](#smodalloading) | `SLoadingModal` | 로딩·에러 (persistent 기본 true) | `onClick` / `update` |
|
|
2226
|
+
| [`SModal.create({ component })`](#smodalcreate) | `SActionModal` | 액션 모달 | `modalRef` 주입 → `ok/cancel/close/submit` |
|
|
2227
|
+
|
|
2228
|
+
> **띄울 수 있는 모달은 `SActionModal` / `SConfirmModal` / `SLoadingModal` 세 가지뿐이고, 위 메서드가 1:1 로 대응한다.** 그 밖의 스타일로 모달을 띄우는 경로는 제공하지 않는다. `create` 는 컨테이너를 덧씌우지 않고 `component` 를 **그대로** 렌더하므로, `component` 는 루트에 `SActionModal` 을 렌더해야 한다 — 그러지 않으면 딤·카드 없이 콘텐츠만 뜨며, 개발 모드에서 `console.warn` 으로 경고한다.
|
|
2229
|
+
|
|
2230
|
+
```ts
|
|
2231
|
+
import { SModal } from 'sellmate-design-system-react';
|
|
2232
|
+
```
|
|
2233
|
+
|
|
2234
|
+
---
|
|
2235
|
+
|
|
2236
|
+
## SModal.confirm
|
|
2237
|
+
|
|
2238
|
+
아이콘 + 제목 + 메시지 + 확인/취소 버튼. `type` 에 따라 아이콘·메인 버튼 색이 결정된다.
|
|
2239
|
+
|
|
2240
|
+
```tsx
|
|
2241
|
+
SModal.confirm({
|
|
2242
|
+
type: 'negative', // 'positive' | 'negative' | 'default'
|
|
2243
|
+
modalTitle: '삭제하시겠습니까?',
|
|
2244
|
+
topMessage: ['이 작업은 되돌릴 수 없습니다.'],
|
|
2245
|
+
mainButtonLabel: '삭제',
|
|
2246
|
+
subButtonLabel: '취소',
|
|
2247
|
+
})
|
|
2248
|
+
.onOk(() => deleteItem())
|
|
2249
|
+
.onCancel(() => {});
|
|
2250
|
+
```
|
|
2251
|
+
|
|
2252
|
+
**옵션 (`SConfirmOptions`)** — 선언형 `SConfirmModalProps` 에서 제어 흐름 props(`open`/`onOpenChange`/`onOk`/`onCancel`/`onClose`)를 제외한 전부. 주요 키: `type`, `modalTitle`, `topMessage`/`bottomMessage`, `mainButtonLabel`/`mainButtonName`, `subButtonLabel`, `tagSlot`/`optionSlot`, `persistent`.
|
|
2253
|
+
|
|
2254
|
+
---
|
|
2255
|
+
|
|
2256
|
+
## SModal.loading
|
|
2257
|
+
|
|
2258
|
+
스피너/에러 모달. 로딩 중 임의 닫힘을 막기 위해 **`persistent` 기본값이 `true`** 다(백드롭·ESC로 안 닫힘). "띄우고 → 작업 → 결과 반영" 흐름을 `update()` / `close()` 로 제어한다.
|
|
2259
|
+
|
|
2260
|
+
```tsx
|
|
2261
|
+
const ref = SModal.loading({ message: '업로드 중...' });
|
|
2262
|
+
try {
|
|
2263
|
+
await upload();
|
|
2264
|
+
ref.close();
|
|
2265
|
+
} catch {
|
|
2266
|
+
ref.update({ state: 'error', message: '업로드 실패' }) // 표시 중 상태 갱신
|
|
2267
|
+
.onClick(() => retry()); // 「다시 시도」 버튼
|
|
2268
|
+
}
|
|
2269
|
+
```
|
|
2270
|
+
|
|
2271
|
+
진행률:
|
|
2272
|
+
|
|
2273
|
+
```tsx
|
|
2274
|
+
const ref = SModal.loading({ progress: 0, message: '파일 업로드 중...' });
|
|
2275
|
+
ref.update({ progress: 60 }); // 0–100
|
|
2276
|
+
ref.update({ progress: 100 });
|
|
2277
|
+
ref.close();
|
|
2278
|
+
```
|
|
2279
|
+
|
|
2280
|
+
> **버튼 클릭은 자동 닫힘이 아니다.** error 상태의 버튼(기본 "다시 시도")은 `onClick` 만 발화하고 모달은 유지된다. consumer 가 `update()`(다시 로딩) / `close()` 로 후속 동작을 결정한다.
|
|
2281
|
+
|
|
2282
|
+
**옵션 (`SLoadingOptions`)** — `state`('loading' | 'error'), `progress`(0–100), `message`(string | string[]), `useButton`, `buttonLabel`, `width`/`height`, `persistent`.
|
|
2283
|
+
|
|
2284
|
+
---
|
|
2285
|
+
|
|
2286
|
+
## SModal.create
|
|
2287
|
+
|
|
2288
|
+
**`SActionModal` 을 루트로 렌더하는 컴포넌트**를 띄운다. `create` 는 컨테이너를 덧씌우지 않고 `component` 를 **그대로** 렌더하며, 표시 제어(`open` / `onOpenChange` / `onClose`)와 [`modalRef`](#smodalref) 를 주입하고 닫힘 애니메이션 종료 후 언마운트를 담당한다.
|
|
2289
|
+
|
|
2290
|
+
컴포넌트는 주입받은 `open` / `onOpenChange` / `onClose` 를 **SActionModal 에 그대로 전달**해야 한다. 전달하지 않으면 모달이 열리지도, 닫히지도 않는다.
|
|
2291
|
+
|
|
2292
|
+
```tsx
|
|
2293
|
+
import { SModal, SActionModal, type SModalCreateComponentProps } from 'sellmate-design-system-react';
|
|
2294
|
+
|
|
2295
|
+
// componentProps 로 넘긴 값 + 주입 prop 을 함께 받는다
|
|
2296
|
+
interface OrderModalProps extends SModalCreateComponentProps {
|
|
2297
|
+
orderId: string;
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
function OrderModal({ open, onOpenChange, onClose, modalRef, orderId }: OrderModalProps) {
|
|
2301
|
+
return (
|
|
2302
|
+
<SActionModal
|
|
2303
|
+
open={open}
|
|
2304
|
+
onOpenChange={onOpenChange}
|
|
2305
|
+
onClose={onClose}
|
|
2306
|
+
modalTitle="주문 처리"
|
|
2307
|
+
button={{ label: '처리', onClick: () => modalRef.ok() }}
|
|
2308
|
+
>
|
|
2309
|
+
<p>주문번호 {orderId} 를 접수합니다.</p>
|
|
2310
|
+
</SActionModal>
|
|
2311
|
+
);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
SModal.create({ component: OrderModal, componentProps: { orderId: 'ORD-001' } })
|
|
2315
|
+
.onOk(() => toast('저장 완료'))
|
|
2316
|
+
.onDismissed(() => cleanup());
|
|
2317
|
+
```
|
|
2318
|
+
|
|
2319
|
+
**옵션 (`SCreateOptions<P>`)**
|
|
2320
|
+
|
|
2321
|
+
| 키 | 타입 | 설명 |
|
|
2322
|
+
|---|---|---|
|
|
2323
|
+
| `component` | `ComponentType<P & SModalCreateComponentProps>` | 루트에 `SActionModal` 을 렌더하는 컴포넌트 |
|
|
2324
|
+
| `componentProps?` | `P` | 컴포넌트에 전달할 추가 props |
|
|
2325
|
+
|
|
2326
|
+
**주입되는 prop (`SModalCreateComponentProps`)**
|
|
2327
|
+
|
|
2328
|
+
| 키 | 타입 | 설명 |
|
|
2329
|
+
|---|---|---|
|
|
2330
|
+
| `open` | `boolean` | SActionModal 의 `open` 에 그대로 전달 |
|
|
2331
|
+
| `onOpenChange` | `(open: boolean) => void` | SActionModal 의 `onOpenChange` 에 그대로 전달 |
|
|
2332
|
+
| `onClose` | `() => void` | SActionModal 의 `onClose` 에 그대로 전달 |
|
|
2333
|
+
| `modalRef` | `SModalRef` | `ok()`/`cancel()`/`close()`/`submit()` 으로 자기 모달 제어 |
|
|
2334
|
+
|
|
2335
|
+
### 비동기 제출 — 응답 보고 닫기
|
|
2336
|
+
|
|
2337
|
+
SActionModal `button` 의 푸터 버튼은 클릭 시 **즉시 닫힌다**. 저장 API 응답에 따라 닫힘 여부를 정해야 하면 푸터 버튼 대신 **본문에 버튼을 두고** `modalRef` 로 닫힘 시점을 직접 제어한다.
|
|
2338
|
+
|
|
2339
|
+
```tsx
|
|
2340
|
+
function OrderModal({ open, onOpenChange, onClose, modalRef, orderId }: OrderModalProps) {
|
|
2341
|
+
const [error, setError] = useState('');
|
|
2342
|
+
const handleSubmit = async () => {
|
|
2343
|
+
try {
|
|
2344
|
+
await save(orderId);
|
|
2345
|
+
modalRef.ok(); // 성공 → onOk + 닫기
|
|
2346
|
+
} catch {
|
|
2347
|
+
setError('저장 실패'); // 실패 → 모달 유지
|
|
2348
|
+
}
|
|
2349
|
+
};
|
|
2350
|
+
return (
|
|
2351
|
+
// button 을 주지 않으면 푸터가 렌더되지 않는다
|
|
2352
|
+
<SActionModal open={open} onOpenChange={onOpenChange} onClose={onClose} persistent modalTitle="주문 처리">
|
|
2353
|
+
{error && <p>{error}</p>}
|
|
2354
|
+
<SButton label="저장" onClick={handleSubmit} />
|
|
2355
|
+
<SButton label="취소" onClick={() => modalRef.cancel()} />
|
|
2356
|
+
</SActionModal>
|
|
2357
|
+
);
|
|
2358
|
+
}
|
|
2359
|
+
```
|
|
2360
|
+
|
|
2361
|
+
---
|
|
2362
|
+
|
|
2363
|
+
## SModalRef
|
|
2364
|
+
|
|
2365
|
+
모든 `SModal.*` 호출이 반환하고, `create` 에서는 컴포넌트 prop 으로도 주입되는 제어 핸들. 콜백 등록(체이닝)과 트리거/갱신 메서드를 함께 제공한다. 모달 종류에 따라 관련 있는 메서드만 실제로 발화한다.
|
|
2366
|
+
|
|
2367
|
+
### 콜백 등록 (체이닝)
|
|
2368
|
+
|
|
2369
|
+
| 메서드 | 발화 시점 |
|
|
2370
|
+
|---|---|
|
|
2371
|
+
| `onOk(fn)` | 확인 버튼(confirm) 또는 `ok()` |
|
|
2372
|
+
| `onCancel(fn)` | 취소 버튼(confirm) 또는 `cancel()` |
|
|
2373
|
+
| `onClose(fn)` | 닫기(X) 버튼 또는 `close()` |
|
|
2374
|
+
| `onClick(fn)` | 단일 버튼 모달(loading error)의 버튼 클릭 — **닫힘 없음** |
|
|
2375
|
+
| `onSubmit(fn)` | create 커스텀 모달의 `submit()` — **닫힘 없음** |
|
|
2376
|
+
| `onDismissed(fn)` | 사유 무관 완전히 닫혀 언마운트된 뒤(백드롭·ESC 포함) |
|
|
2377
|
+
|
|
2378
|
+
### 트리거 / 제어
|
|
2379
|
+
|
|
2380
|
+
| 메서드 | 동작 |
|
|
2381
|
+
|---|---|
|
|
2382
|
+
| `ok()` | `onOk` 발화 + 닫기 (저장/처리 성공) |
|
|
2383
|
+
| `cancel()` | `onCancel` 발화 + 닫기 (작업 취소) |
|
|
2384
|
+
| `close()` | `onClose` 발화 + 닫기 (중립적 닫기) |
|
|
2385
|
+
| `submit()` | `onSubmit` 발화 (닫힘 없음) |
|
|
2386
|
+
| `update(patch)` | 표시 중 옵션 갱신 (loading→error, progress 등). create 는 미지원. |
|
|
2387
|
+
|
|
2388
|
+
모든 닫힘은 애니메이션 종료 후 `onDismissed` 로 수렴한다. 이미 닫힘이 시작된 뒤의 중복 트리거는 무시된다.
|
|
2389
|
+
|
|
2390
|
+
---
|
|
2391
|
+
|
|
2392
|
+
## 주의사항
|
|
2393
|
+
|
|
2394
|
+
- **선언형과 공존**: 서비스는 추가 API다. open 상태가 앱 상태/라우트에 묶인 경우엔 선언형 `<SConfirmModal open>` / `<SLoadingModal open>` 이 더 적합하다.
|
|
2395
|
+
- **백드롭·ESC = 중립적 닫힘**: 특정 콜백(onClose 등) 없이 `onDismissed` 만 발화한다. 명시적 버튼·메서드만 onOk/onCancel/onClose 를 발화한다.
|
|
2396
|
+
- **Context 미상속**: `create` 의 커스텀 컴포넌트는 새 React 트리(createRoot)에서 렌더되어 부모의 Context Provider(Theme·Store 등)를 상속하지 않는다. 필요하면 컴포넌트 내부에서 직접 Provider 로 감싸라. (confirm/loading 은 토큰이 `:root` CSS 변수라 무관)
|
|
2397
|
+
- **`create` 의 `component` 는 SActionModal 을 루트로**: `create` 는 컨테이너를 덧씌우지 않으므로, 본문만 렌더하는 컴포넌트를 넘기면 딤·카드 없이 콘텐츠가 그대로 화면에 붙는다. TypeScript 는 이를 막지 못한다(`component` 타입이 아무 컴포넌트나 허용). 개발 모드에서는 마운트 직후 렌더 결과로 이를 감지해 `console.warn` 으로 경고한다 — 세 모달은 모두 Portal 로 `body` 에 렌더되므로 `create` 가 만든 host 는 비어 있어야 하는데, host 에 엘리먼트가 남아 있으면 모달이 아닌 것으로 판정한다.
|
|
2398
|
+
|
|
2399
|
+
## Dependencies
|
|
2400
|
+
|
|
2401
|
+
### Depends on
|
|
2402
|
+
|
|
2403
|
+
- [SActionModal](../SActionModal)
|
|
2404
|
+
- [SConfirmModal](../SConfirmModal)
|
|
2405
|
+
- [SLoadingModal](../SLoadingModal)
|
|
2406
|
+
|
|
2407
|
+
---
|
|
2408
|
+
|
|
2409
|
+
# SModalContainer
|
|
2410
|
+
|
|
2411
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2412
|
+
|
|
2413
|
+
### SModalContainer
|
|
2414
|
+
|
|
2415
|
+
#### Props
|
|
2416
|
+
|
|
2417
|
+
| Prop | Type | Default | Description |
|
|
2418
|
+
|------|------|---------|-------------|
|
|
2419
|
+
| `open?` | `boolean` | — | 표시 여부 (제어) |
|
|
2420
|
+
| `ariaTitle?` | `string` | `'모달'` | 접근성 제목 (스크린리더용). 시각 제목은 children이 담당 |
|
|
2421
|
+
| `showClose?` | `boolean` | `false` | 우측 상단 닫기 버튼 |
|
|
2422
|
+
| `persistent?` | `boolean` | `false` | true면 백드롭 클릭·ESC로 닫히지 않고 흔들림(shake) 애니메이션 (sd-modal-container persistent) |
|
|
2423
|
+
| `width?` | `number \| string` | — | 너비/높이 |
|
|
2424
|
+
| `height?` | `number \| string` | — | |
|
|
2425
|
+
| `children?` | `ReactNode` | — | |
|
|
2426
|
+
| `className?` | `string` | — | |
|
|
2427
|
+
| `style?` | `CSSProperties` | — | |
|
|
2428
|
+
|
|
2429
|
+
#### Events
|
|
2430
|
+
|
|
2431
|
+
| Event | Type | Description |
|
|
2432
|
+
|-------|------|-------------|
|
|
2433
|
+
| `onOpenChange` | `(open: boolean) => void` | 표시 상태 변경 |
|
|
2434
|
+
| `onClose` | `() => void` | 닫기(X) 버튼 클릭 시 발생 (sd-modal-container 닫기 버튼 대응) |
|
|
2435
|
+
|
|
2436
|
+
## Dependencies
|
|
2437
|
+
|
|
2438
|
+
### Used by
|
|
2439
|
+
|
|
2440
|
+
- [SActionModal](../SActionModal)
|
|
2441
|
+
- [SConfirmModal](../SConfirmModal)
|
|
2442
|
+
- [SLoadingModal](../SLoadingModal)
|
|
2443
|
+
|
|
2444
|
+
### Depends on
|
|
2445
|
+
|
|
2446
|
+
- [SGhostButton](../SGhostButton)
|
|
2447
|
+
|
|
2448
|
+
### Graph
|
|
2449
|
+
|
|
2450
|
+
---
|
|
2451
|
+
|
|
2452
|
+
# SNumberInput
|
|
2453
|
+
|
|
2454
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2455
|
+
|
|
2456
|
+
### SNumberInput
|
|
2457
|
+
|
|
2458
|
+
#### Props
|
|
2459
|
+
|
|
2460
|
+
| Prop | Type | Default | Description |
|
|
2461
|
+
|------|------|---------|-------------|
|
|
2462
|
+
| `value?` | `string \| number \| null` | — | 입력 값 |
|
|
2463
|
+
| `size?` | `SNumberInputSize` | `'sm'` | 크기 |
|
|
2464
|
+
| `min?` | `number` | `Number.NEGATIVE_INFINITY` | 최솟값 |
|
|
2465
|
+
| `max?` | `number` | `Number.POSITIVE_INFINITY` | 최댓값 |
|
|
2466
|
+
| `step?` | `number` | `1` | 스텝 단위 |
|
|
2467
|
+
| `useButton?` | `boolean` | `false` | 증감 버튼 표시 |
|
|
2468
|
+
| `useDecimal?` | `boolean` | `false` | 소수점 입력 허용 |
|
|
2469
|
+
| `maxDecimalLength?` | `number` | — | 소수점 이하 최대 자리수 |
|
|
2470
|
+
| `inputPrefix?` | `string` | `''` | 입력 앞 접두 텍스트 |
|
|
2471
|
+
| `inputSuffix?` | `string` | `''` | 입력 뒤 접미 텍스트 |
|
|
2472
|
+
| `inputClass?` | `string` | — | 네이티브 input className |
|
|
2473
|
+
| `inputStyle?` | `CSSProperties` | — | 네이티브 input style |
|
|
2474
|
+
| `autoFocus?` | `boolean` | — | 마운트 시 자동 포커스 |
|
|
2475
|
+
| `name?` | `string` | — | 폼 연동 name |
|
|
2476
|
+
| `placeholder?` | `string` | `'입력해 주세요.'` | |
|
|
2477
|
+
| `disabled?` | `boolean` | `false` | |
|
|
2478
|
+
| `readOnly?` | `boolean` | `false` | |
|
|
2479
|
+
| `rules?` | `Rule[]` | — | 유효성 규칙 — blur 시 검증 |
|
|
2480
|
+
| `status?` | `SFieldStatus` | — | |
|
|
2481
|
+
| `focused?` | `boolean` | — | |
|
|
2482
|
+
| `hovered?` | `boolean` | — | |
|
|
2483
|
+
| `label?` | `string` | — | |
|
|
2484
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
2485
|
+
| `icon?` | `SIconName` | — | |
|
|
2486
|
+
| `iconColor?` | `SColor` | — | |
|
|
2487
|
+
| `labelTooltip?` | `string` | — | |
|
|
2488
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
2489
|
+
| `addonLabel?` | `string` | — | |
|
|
2490
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | |
|
|
2491
|
+
| `hint?` | `string` | — | |
|
|
2492
|
+
| `error?` | `boolean` | — | |
|
|
2493
|
+
| `errorMessage?` | `string` | — | |
|
|
2494
|
+
| `width?` | `number \| string` | — | |
|
|
2495
|
+
| `className?` | `string` | — | |
|
|
2496
|
+
| `style?` | `CSSProperties` | — | |
|
|
2497
|
+
|
|
2498
|
+
#### Events
|
|
2499
|
+
|
|
2500
|
+
| Event | Type | Description |
|
|
2501
|
+
|-------|------|-------------|
|
|
2502
|
+
| `onValueChange` | `(value: number \| null) => void` | 값 변경 (sdUpdate) — number|null 전달 |
|
|
2503
|
+
| `onFocus` | `(e: React.FocusEvent<HTMLInputElement>) => void` | 포커스 이벤트 (sdFocus) |
|
|
2504
|
+
| `onBlur` | `(e: React.FocusEvent<HTMLInputElement>) => void` | 블러 이벤트 (sdBlur) |
|
|
2505
|
+
|
|
2506
|
+
## Dependencies
|
|
2507
|
+
|
|
2508
|
+
### Used by
|
|
2509
|
+
|
|
2510
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
2511
|
+
|
|
2512
|
+
### Depends on
|
|
2513
|
+
|
|
2514
|
+
- [SField](../SField)
|
|
2515
|
+
- [SIcon](../SIcon)
|
|
2516
|
+
|
|
2517
|
+
### Graph
|
|
2518
|
+
|
|
2519
|
+
---
|
|
2520
|
+
|
|
2521
|
+
# SPage
|
|
2522
|
+
|
|
2523
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2524
|
+
|
|
2525
|
+
### SPage
|
|
2526
|
+
|
|
2527
|
+
#### Props
|
|
2528
|
+
|
|
2529
|
+
| Prop | Type | Default | Description |
|
|
2530
|
+
|------|------|---------|-------------|
|
|
2531
|
+
| `background?` | `SPageBackground` | `'frame'` | 페이지 배경 표면. frame=흰 콘텐츠 면, neutral=옅은 회색 면, screen=앱 바탕. 스크롤바 처리도 여기 묶여 있다 — 셋 다 구분선+트랙 배경이고, 트랙 색만 neutral 에서 흰색이 된다. |
|
|
2532
|
+
|
|
2533
|
+
## Dependencies
|
|
2534
|
+
|
|
2535
|
+
### Depends on
|
|
2536
|
+
|
|
2537
|
+
- [SLayout](../SLayout)
|
|
2538
|
+
|
|
2539
|
+
### Graph
|
|
2540
|
+
|
|
2541
|
+
---
|
|
2542
|
+
|
|
2543
|
+
# SPagination
|
|
2544
|
+
|
|
2545
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2546
|
+
|
|
2547
|
+
### SPagination
|
|
2548
|
+
|
|
2549
|
+
#### Props
|
|
2550
|
+
|
|
2551
|
+
| Prop | Type | Default | Description |
|
|
2552
|
+
|------|------|---------|-------------|
|
|
2553
|
+
| `currentPage?` | `number` | `1` | 현재 페이지 |
|
|
2554
|
+
| `lastPage?` | `number` | `1` | 마지막 페이지 |
|
|
2555
|
+
| `simple?` | `boolean` | `false` | 단순 모드 (현재/마지막만 표시) |
|
|
2556
|
+
| `className?` | `string` | — | |
|
|
2557
|
+
| `style?` | `CSSProperties` | — | |
|
|
2558
|
+
|
|
2559
|
+
#### Events
|
|
2560
|
+
|
|
2561
|
+
| Event | Type | Description |
|
|
2562
|
+
|-------|------|-------------|
|
|
2563
|
+
| `onPageChange` | `(page: number) => void` | 페이지 변경 (sdPageChange) |
|
|
2564
|
+
|
|
2565
|
+
## Dependencies
|
|
2566
|
+
|
|
2567
|
+
### Used by
|
|
2568
|
+
|
|
2569
|
+
- [STable](../STable)
|
|
2570
|
+
|
|
2571
|
+
### Depends on
|
|
2572
|
+
|
|
2573
|
+
- [SIcon](../SIcon)
|
|
2574
|
+
|
|
2575
|
+
### Graph
|
|
2576
|
+
|
|
2577
|
+
---
|
|
2578
|
+
|
|
2579
|
+
# SPopover
|
|
2580
|
+
|
|
2581
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2582
|
+
|
|
2583
|
+
### SPopover
|
|
2584
|
+
|
|
2585
|
+
#### Props
|
|
2586
|
+
|
|
2587
|
+
| Prop | Type | Default | Description |
|
|
2588
|
+
|------|------|---------|-------------|
|
|
2589
|
+
| `open?` | `boolean` | — | 표시 여부 (제어). onOpenChange 와 함께 사용 |
|
|
2590
|
+
| `defaultOpen?` | `boolean` | — | 기본 표시 여부 (비제어) |
|
|
2591
|
+
| `placement?` | `SPopoverPlacement` | `'bottom'` | 표시 방향 |
|
|
2592
|
+
| `type?` | `SPopoverType` | `'default'` | 색상 타입 (default: 다크 / danger·warning·accent: 라이트 배경) |
|
|
2593
|
+
| `menuTitle` | `string` | — | 메뉴 제목 (필수) |
|
|
2594
|
+
| `titleIcon?` | `SIconName` | — | 제목 좌측 아이콘 (선택) |
|
|
2595
|
+
| `children?` | `ReactNode` | — | 본문 내용 |
|
|
2596
|
+
| `trigger?` | `ReactNode` | — | 커스텀 트리거. 없으면 아이콘 트리거 렌더 |
|
|
2597
|
+
| `icon?` | `SIconName` | `'helpOutline'` | 기본(아이콘) 트리거 설정 |
|
|
2598
|
+
| `iconSize?` | `number` | `12` | |
|
|
2599
|
+
| `color?` | `SColor` | `'#01BB4B'` | 트리거 아이콘 색상. 팔레트 키(`grey_65`, `red_95` …) 또는 임의 CSS 색상 |
|
|
2600
|
+
| `leftLinkLabel?` | `string` | — | 하단 좌측 링크 레이블 (선택). 스타일은 chevron 링크로 고정 |
|
|
2601
|
+
| `buttonLabel` | `string` | — | 하단 우측 버튼 레이블 (필수). 색상/스타일은 type 별로 고정 |
|
|
2602
|
+
| `ariaLabel?` | `string` | — | |
|
|
2603
|
+
| `menuClassName?` | `string` | — | |
|
|
2604
|
+
| `style?` | `CSSProperties` | — | |
|
|
2605
|
+
|
|
2606
|
+
#### Events
|
|
2607
|
+
|
|
2608
|
+
| Event | Type | Description |
|
|
2609
|
+
|-------|------|-------------|
|
|
2610
|
+
| `onOpenChange` | `(open: boolean) => void` | 표시 상태 변경 (sdShowChange) |
|
|
2611
|
+
| `onLeftLinkClick` | `() => void` | 하단 좌측 링크 클릭 |
|
|
2612
|
+
| `onButtonClick` | `() => void` | 하단 우측 버튼 클릭 |
|
|
2613
|
+
|
|
2614
|
+
## Dependencies
|
|
2615
|
+
|
|
2616
|
+
### Depends on
|
|
2617
|
+
|
|
2618
|
+
- [SButton](../SButton)
|
|
2619
|
+
- [SGhostButton](../SGhostButton)
|
|
2620
|
+
- [SIcon](../SIcon)
|
|
2621
|
+
- [STextLink](../STextLink)
|
|
2622
|
+
|
|
2623
|
+
### Graph
|
|
2624
|
+
|
|
2625
|
+
---
|
|
2626
|
+
|
|
2627
|
+
# SPopup
|
|
2628
|
+
|
|
2629
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2630
|
+
|
|
2631
|
+
### SPopup
|
|
2632
|
+
|
|
2633
|
+
#### Props
|
|
2634
|
+
|
|
2635
|
+
| Prop | Type | Default | Description |
|
|
2636
|
+
|------|------|---------|-------------|
|
|
2637
|
+
| `popupTitle?` | `string` | `''` | 헤더 제목 |
|
|
2638
|
+
| `type?` | `SPopupType` | `'default'` | 타입 (헤더 색상) |
|
|
2639
|
+
| `useFooter?` | `boolean` | `true` | 하단 footer 표시 여부 |
|
|
2640
|
+
| `submitButton?` | `SPopupSubmitButton` | — | 확인 버튼 설정 |
|
|
2641
|
+
| `footerLeft?` | `ReactNode` | — | footer 좌측 영역 |
|
|
2642
|
+
| `children?` | `ReactNode` | — | 본문 |
|
|
2643
|
+
| `className?` | `string` | — | |
|
|
2644
|
+
| `style?` | `CSSProperties` | — | |
|
|
2645
|
+
|
|
2646
|
+
#### Events
|
|
2647
|
+
|
|
2648
|
+
| Event | Type | Description |
|
|
2649
|
+
|-------|------|-------------|
|
|
2650
|
+
| `onSubmit` | `() => void` | 확인 버튼 클릭 (sdSubmit) |
|
|
2651
|
+
|
|
2652
|
+
## Dependencies
|
|
2653
|
+
|
|
2654
|
+
### Depends on
|
|
2655
|
+
|
|
2656
|
+
- [SButton](../SButton)
|
|
2657
|
+
|
|
2658
|
+
### Graph
|
|
2659
|
+
|
|
2660
|
+
---
|
|
2661
|
+
|
|
2662
|
+
# SPortal
|
|
2663
|
+
|
|
2664
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2665
|
+
|
|
2666
|
+
### SPortal
|
|
2667
|
+
|
|
2668
|
+
#### Props
|
|
2669
|
+
|
|
2670
|
+
| Prop | Type | Default | Description |
|
|
2671
|
+
|------|------|---------|-------------|
|
|
2672
|
+
| `open` | `boolean` | — | 표시 여부 (제어). onClose 와 함께 사용한다. |
|
|
2673
|
+
| `anchorRef` | `RefObject<HTMLElement \| null>` | — | 위치 기준이 되는 앵커 엘리먼트 ref (sd-portal `parentRef` 대응). 트리거 버튼 등에 그대로 걸면 그 엘리먼트에 붙어서 뜬다. |
|
|
2674
|
+
| `placement?` | `SPortalPlacement` | `'bottom'` | 표시 방향 (공간이 부족하면 자동으로 반대 방향으로 전환). |
|
|
2675
|
+
| `align?` | `SPortalAlign` | `'start'` | 교차축 정렬 (start·center·end). |
|
|
2676
|
+
| `offset?` | `number` | `4` | 앵커로부터의 간격 px (sd-portal offset[1]). |
|
|
2677
|
+
| `alignOffset?` | `number` | `0` | 정렬축 오프셋 px (sd-portal offset[0]). |
|
|
2678
|
+
| `fit?` | `boolean` | `false` | 앵커 너비에 맞춰 최소 너비를 잡는다. |
|
|
2679
|
+
| `maxHeight?` | `number` | — | 콘텐츠 최대 높이 px. 넘치면 세로 스크롤. |
|
|
2680
|
+
| `autoClose?` | `boolean` | `false` | 콘텐츠 내부를 클릭하면 자동으로 닫는다. |
|
|
2681
|
+
| `persistent?` | `boolean` | `false` | 외부 클릭 · ESC 로 닫히지 않게 한다. |
|
|
2682
|
+
| `viewportPadding?` | `number` | `0` | 뷰포트 경계 여백 px (충돌 회피 패딩). |
|
|
2683
|
+
| `children?` | `ReactNode` | — | 본문 내용 (콘텐츠 자유). |
|
|
2684
|
+
| `className?` | `string` | — | |
|
|
2685
|
+
| `style?` | `CSSProperties` | — | |
|
|
2686
|
+
| `ariaLabel?` | `string` | — | |
|
|
2687
|
+
|
|
2688
|
+
#### Events
|
|
2689
|
+
|
|
2690
|
+
| Event | Type | Description |
|
|
2691
|
+
|-------|------|-------------|
|
|
2692
|
+
| `onClose` | `() => void` | 외부 클릭 · ESC 등으로 닫힘이 요청될 때 (sd-portal `sdClose` 대응). |
|
|
2693
|
+
| `onOpenChange` | `(open: boolean) => void` | 열림/닫힘 변경 전체 콜백 (선택). |
|
|
2694
|
+
| `onOpenAutoFocus` | `(event: Event) => void` | 열릴 때 포커스 이동 처리 (기본은 Radix가 콘텐츠로 포커스를 옮김). e.preventDefault()로 막을 수 있다. |
|
|
2695
|
+
| `onCloseAutoFocus` | `(event: Event) => void` | 닫힐 때 포커스 복귀 처리 (기본은 Radix가 앵커로 포커스를 되돌림). e.preventDefault()로 막을 수 있다. |
|
|
2696
|
+
| `onPointerDownOutside` | `(event: Event) => void` | 바깥 영역 pointerdown 으로 닫힘이 시작될 때 (앵커 위 클릭·persistent 는 제외). |
|
|
2697
|
+
|
|
2698
|
+
## Dependencies
|
|
2699
|
+
|
|
2700
|
+
### Used by
|
|
2701
|
+
|
|
2702
|
+
- [SChipInput](../SChipInput)
|
|
2703
|
+
- [SSelect](../SSelect)
|
|
2704
|
+
|
|
2705
|
+
### Graph
|
|
2706
|
+
|
|
2707
|
+
---
|
|
2708
|
+
|
|
2709
|
+
# SRadio
|
|
2710
|
+
|
|
2711
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2712
|
+
|
|
2713
|
+
### SRadioGroup
|
|
2714
|
+
|
|
2715
|
+
#### Props
|
|
2716
|
+
|
|
2717
|
+
| Prop | Type | Default | Description |
|
|
2718
|
+
|------|------|---------|-------------|
|
|
2719
|
+
| `options?` | `SRadioOption[]` | `[]` | 옵션 목록 |
|
|
2720
|
+
| `value?` | `SRadioValue \| null` | — | 현재 선택 값 |
|
|
2721
|
+
| `direction?` | `'vertical' \| 'horizontal'` | `'vertical'` | 배치 방향 |
|
|
2722
|
+
| `disabled?` | `boolean` | `false` | 전체 비활성 |
|
|
2723
|
+
| `groupName?` | `string` | — | 라디오 name 속성 (form-agnostic 그룹핑) |
|
|
2724
|
+
| `className?` | `string` | — | |
|
|
2725
|
+
| `style?` | `CSSProperties` | — | |
|
|
2726
|
+
|
|
2727
|
+
#### Events
|
|
2728
|
+
|
|
2729
|
+
| Event | Type | Description |
|
|
2730
|
+
|-------|------|-------------|
|
|
2731
|
+
| `onValueChange` | `(val: SRadioValue) => void` | 선택 변경 (sdUpdate) |
|
|
2732
|
+
|
|
2733
|
+
### SRadio
|
|
2734
|
+
|
|
2735
|
+
#### Props
|
|
2736
|
+
|
|
2737
|
+
| Prop | Type | Default | Description |
|
|
2738
|
+
|------|------|---------|-------------|
|
|
2739
|
+
| `val` | `SRadioValue` | — | 이 라디오의 값 |
|
|
2740
|
+
| `value?` | `SRadioValue \| null` | — | 그룹의 현재 선택 값 |
|
|
2741
|
+
| `label?` | `string` | — | 라벨 |
|
|
2742
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
2743
|
+
| `name?` | `string` | — | native radio name (form-agnostic 그룹핑) |
|
|
2744
|
+
| `className?` | `string` | — | |
|
|
2745
|
+
| `style?` | `CSSProperties` | — | |
|
|
2746
|
+
|
|
2747
|
+
#### Events
|
|
2748
|
+
|
|
2749
|
+
| Event | Type | Description |
|
|
2750
|
+
|-------|------|-------------|
|
|
2751
|
+
| `onValueChange` | `(val: SRadioValue) => void` | 선택 변경 (sdUpdate) — 선택된 val 전달 |
|
|
2752
|
+
|
|
2753
|
+
## Dependencies
|
|
2754
|
+
|
|
2755
|
+
### Used by
|
|
2756
|
+
|
|
2757
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
2758
|
+
|
|
2759
|
+
### Graph
|
|
2760
|
+
|
|
2761
|
+
---
|
|
2762
|
+
|
|
2763
|
+
# SRadioButton
|
|
2764
|
+
|
|
2765
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2766
|
+
|
|
2767
|
+
### SRadioButton
|
|
2768
|
+
|
|
2769
|
+
#### Props
|
|
2770
|
+
|
|
2771
|
+
| Prop | Type | Default | Description |
|
|
2772
|
+
|------|------|---------|-------------|
|
|
2773
|
+
| `options?` | `SRadioButtonOption[]` | `[]` | 옵션 목록 |
|
|
2774
|
+
| `value?` | `string \| number \| null` | — | 현재 선택 값 |
|
|
2775
|
+
| `size?` | `SRadioButtonSize` | `'sm'` | 크기 |
|
|
2776
|
+
| `disabled?` | `boolean` | `false` | 전체 비활성 |
|
|
2777
|
+
| `name?` | `string` | — | input name 속성 |
|
|
2778
|
+
| `className?` | `string` | — | |
|
|
2779
|
+
| `style?` | `CSSProperties` | — | |
|
|
2780
|
+
|
|
2781
|
+
#### Events
|
|
2782
|
+
|
|
2783
|
+
| Event | Type | Description |
|
|
2784
|
+
|-------|------|-------------|
|
|
2785
|
+
| `onValueChange` | `(value: string \| number) => void` | 변경 (sdUpdate) |
|
|
2786
|
+
|
|
2787
|
+
---
|
|
2788
|
+
|
|
2789
|
+
# SScrollArea
|
|
2790
|
+
|
|
2791
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2792
|
+
|
|
2793
|
+
### SScrollArea
|
|
2794
|
+
|
|
2795
|
+
#### Props
|
|
2796
|
+
|
|
2797
|
+
| Prop | Type | Default | Description |
|
|
2798
|
+
|------|------|---------|-------------|
|
|
2799
|
+
| `axis?` | `SScrollAreaAxis` | `'both'` | 스크롤 방향. vertical=세로만, horizontal=가로만, both=양방향 |
|
|
2800
|
+
| `background?` | `boolean` | `false` | true면 스크롤바 트랙 배경을 채운다. 콘텐츠 영역 배경은 바뀌지 않는다. |
|
|
2801
|
+
| `bordered?` | `boolean` | `false` | true면 스크롤바와 콘텐츠 사이에 1px 구분선을 그린다. 컨테이너 테두리가 아니다. |
|
|
2802
|
+
| `maxHeight?` | `string` | — | viewport 최대 높이 (예: '400px'). 비우면 부모 크기를 따른다. |
|
|
2803
|
+
| `maxWidth?` | `string` | — | viewport 최대 너비 (예: '480px'). 비우면 부모 크기를 따른다. |
|
|
2804
|
+
|
|
2805
|
+
---
|
|
2806
|
+
|
|
2807
|
+
# SSectionHeaderCard
|
|
2808
|
+
|
|
2809
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2810
|
+
|
|
2811
|
+
### SSectionHeaderCardBody
|
|
2812
|
+
|
|
2813
|
+
#### Props
|
|
2814
|
+
|
|
2815
|
+
| Prop | Type | Default | Description |
|
|
2816
|
+
|------|------|---------|-------------|
|
|
2817
|
+
| `children?` | `SSectionHeaderCardBodyChildren` | — | 바디 슬롯. 특정 컴포넌트 타입으로 제한하지 않습니다. |
|
|
2818
|
+
|
|
2819
|
+
### SSectionHeaderCardHeader
|
|
2820
|
+
|
|
2821
|
+
#### Props
|
|
2822
|
+
|
|
2823
|
+
| Prop | Type | Default | Description |
|
|
2824
|
+
|------|------|---------|-------------|
|
|
2825
|
+
| `title` | `ReactNode` | — | 헤더 제목 |
|
|
2826
|
+
| `marker?` | `boolean` | `false` | 제목 앞 점 표시 여부 |
|
|
2827
|
+
| `required?` | `boolean` | `false` | 제목 뒤 필수 별 표시 여부 |
|
|
2828
|
+
| `helpText?` | `string[]` | — | 도움말 툴팁 메시지 |
|
|
2829
|
+
| `subtitle?` | `ReactNode` | — | 부제 |
|
|
2830
|
+
| `slot?` | `ReactNode` | — | 헤더 우측 슬롯 |
|
|
2831
|
+
| `thickness?` | `SSectionHeaderCardThickness` | `false` | 상단 border 색상 타입. false면 표시하지 않습니다. |
|
|
2832
|
+
|
|
2833
|
+
### SSectionHeaderCard
|
|
2834
|
+
|
|
2835
|
+
#### Props
|
|
2836
|
+
|
|
2837
|
+
| Prop | Type | Default | Description |
|
|
2838
|
+
|------|------|---------|-------------|
|
|
2839
|
+
| `children?` | `SSectionHeaderCardChildren` | — | SSectionHeaderCard 슬롯. 특정 컴포넌트 타입으로 제한하지 않습니다. |
|
|
2840
|
+
|
|
2841
|
+
## Dependencies
|
|
2842
|
+
|
|
2843
|
+
### Depends on
|
|
2844
|
+
|
|
2845
|
+
- [SBadge](../SBadge)
|
|
2846
|
+
- [SIcon](../SIcon)
|
|
2847
|
+
- [STooltip](../STooltip)
|
|
2848
|
+
|
|
2849
|
+
### Graph
|
|
2850
|
+
|
|
2851
|
+
---
|
|
2852
|
+
|
|
2853
|
+
# SSelect
|
|
2854
|
+
|
|
2855
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2856
|
+
|
|
2857
|
+
### SSelect
|
|
2858
|
+
|
|
2859
|
+
#### Props
|
|
2860
|
+
|
|
2861
|
+
| Prop | Type | Default | Description |
|
|
2862
|
+
|------|------|---------|-------------|
|
|
2863
|
+
| `value?` | `(string \| number \| SSelectOption) \| (string \| number \| SSelectOption)[] \| null` | — | 선택 값. multi 타입이면 배열. emitValue=false(기본) 라운드트립을 위해 SSelectOption 객체도 허용 |
|
|
2864
|
+
| `emitValue?` | `boolean` | `false` | true면 SSelectOption 대신 원시값(string|number) 방출 |
|
|
2865
|
+
| `name?` | `string` | — | 폼 연동용 name 속성 |
|
|
2866
|
+
| `options?` | `SSelectOption[]` | `[]` | 옵션 목록 (children으로 계층 표현) |
|
|
2867
|
+
| `type?` | `SSelectType` | `'default'` | 타입: default | multi | default_depth | multi_depth |
|
|
2868
|
+
| `useSearch?` | `boolean` | `false` | 검색 입력 사용 |
|
|
2869
|
+
| `useSelectAll?` | `boolean` | `false` | 전체선택 옵션 사용 (multi 전용) |
|
|
2870
|
+
| `allSelectedLabel?` | `string` | `'전체'` | 전체선택 레이블 |
|
|
2871
|
+
| `placeholder?` | `string` | `'선택'` | placeholder |
|
|
2872
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
2873
|
+
| `error?` | `boolean` | `false` | 에러 상태 |
|
|
2874
|
+
| `rules?` | `Rule[]` | — | 유효성 규칙 — 닫힐 때 자동 검증 |
|
|
2875
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 |
|
|
2876
|
+
| `dropdownHeight?` | `string` | `'260px'` | 드롭다운 최대 높이 |
|
|
2877
|
+
| `dropdownWidth?` | `string` | — | 드롭다운 너비 (없으면 트리거 너비) |
|
|
2878
|
+
| `maxDropdownWidth?` | `string` | `'640px'` | 드롭다운 최대 너비 |
|
|
2879
|
+
| `label?` | `string` | — | |
|
|
2880
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
2881
|
+
| `icon?` | `SIconName` | — | 레이블 영역 아이콘 |
|
|
2882
|
+
| `iconColor?` | `SColor` | — | |
|
|
2883
|
+
| `labelTooltip?` | `string` | — | 레이블 툴팁 텍스트 |
|
|
2884
|
+
| `addonLabel?` | `string` | — | 우측 어드온 레이블 |
|
|
2885
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | 어드온 정렬 |
|
|
2886
|
+
| `hint?` | `string` | — | |
|
|
2887
|
+
| `errorMessage?` | `string` | — | |
|
|
2888
|
+
| `width?` | `number \| string` | — | |
|
|
2889
|
+
| `className?` | `string` | — | |
|
|
2890
|
+
| `style?` | `CSSProperties` | — | |
|
|
2891
|
+
|
|
2892
|
+
#### Events
|
|
2893
|
+
|
|
2894
|
+
| Event | Type | Description |
|
|
2895
|
+
|-------|------|-------------|
|
|
2896
|
+
| `onValueChange` | `(value: any) => void` | 값 변경 (sdUpdate). emitValue=false(기본)면 SSelectOption(들), true면 원시값 |
|
|
2897
|
+
| `onOpenChange` | `(open: boolean) => void` | 열림/닫힘 변경 (sdDropDownShow) |
|
|
2898
|
+
|
|
2899
|
+
#### Methods (ref)
|
|
2900
|
+
|
|
2901
|
+
| Method | Type | Description |
|
|
2902
|
+
|--------|------|-------------|
|
|
2903
|
+
| `focus` | `() => void` | 트리거 버튼에 포커스 (sdFocus) |
|
|
2904
|
+
| `open` | `() => void` | 드롭다운 열기 (sdOpen) |
|
|
2905
|
+
|
|
2906
|
+
## Dependencies
|
|
2907
|
+
|
|
2908
|
+
### Used by
|
|
2909
|
+
|
|
2910
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
2911
|
+
- [STable](../STable)
|
|
2912
|
+
|
|
2913
|
+
### Depends on
|
|
2914
|
+
|
|
2915
|
+
- [SField](../SField)
|
|
2916
|
+
- [SGhostButton](../SGhostButton)
|
|
2917
|
+
- [SIcon](../SIcon)
|
|
2918
|
+
- [SPortal](../SPortal)
|
|
2919
|
+
|
|
2920
|
+
### Graph
|
|
2921
|
+
|
|
2922
|
+
---
|
|
2923
|
+
|
|
2924
|
+
# SStepper
|
|
2925
|
+
|
|
2926
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2927
|
+
|
|
2928
|
+
### SStepper
|
|
2929
|
+
|
|
2930
|
+
#### Props
|
|
2931
|
+
|
|
2932
|
+
| Prop | Type | Default | Description |
|
|
2933
|
+
|------|------|---------|-------------|
|
|
2934
|
+
| `items` | `SStepperItem[]` | — | 단계 목록 |
|
|
2935
|
+
| `value?` | `string` | — | 현재 활성 단계 value |
|
|
2936
|
+
| `size?` | `SStepperSize` | `'sm'` | 크기 |
|
|
2937
|
+
| `ariaLabel?` | `string` | `'진행 단계'` | 접근성 레이블 |
|
|
2938
|
+
| `className?` | `string` | — | |
|
|
2939
|
+
| `style?` | `CSSProperties` | — | |
|
|
2940
|
+
|
|
2941
|
+
## Dependencies
|
|
2942
|
+
|
|
2943
|
+
### Depends on
|
|
2944
|
+
|
|
2945
|
+
- [SIcon](../SIcon)
|
|
2946
|
+
|
|
2947
|
+
### Graph
|
|
2948
|
+
|
|
2949
|
+
---
|
|
2950
|
+
|
|
2951
|
+
# SSwitch
|
|
2952
|
+
|
|
2953
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2954
|
+
|
|
2955
|
+
### SSwitch
|
|
2956
|
+
|
|
2957
|
+
#### Props
|
|
2958
|
+
|
|
2959
|
+
| Prop | Type | Default | Description |
|
|
2960
|
+
|------|------|---------|-------------|
|
|
2961
|
+
| `value?` | `boolean` | `false` | on/off 상태 |
|
|
2962
|
+
| `leftLabel?` | `string` | — | 스위치 좌측 라벨 |
|
|
2963
|
+
| `rightLabel?` | `string` | — | 스위치 우측 라벨 |
|
|
2964
|
+
| `label?` | `string` | — | |
|
|
2965
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
2966
|
+
| `className?` | `string` | — | |
|
|
2967
|
+
| `style?` | `CSSProperties` | — | |
|
|
2968
|
+
|
|
2969
|
+
#### Events
|
|
2970
|
+
|
|
2971
|
+
| Event | Type | Description |
|
|
2972
|
+
|-------|------|-------------|
|
|
2973
|
+
| `onValueChange` | `(value: boolean) => void` | 변경 (sdUpdate) |
|
|
2974
|
+
|
|
2975
|
+
---
|
|
2976
|
+
|
|
2977
|
+
# STable
|
|
2978
|
+
|
|
2979
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
2980
|
+
|
|
2981
|
+
### STable
|
|
2982
|
+
|
|
2983
|
+
#### Props
|
|
2984
|
+
|
|
2985
|
+
| Prop | Type | Default | Description |
|
|
2986
|
+
|------|------|---------|-------------|
|
|
2987
|
+
| `columns?` | `STableColumn[]` | `[]` | |
|
|
2988
|
+
| `rows?` | `SRow[]` | `[]` | |
|
|
2989
|
+
| `rowKey?` | `string` | `'id'` | 행 식별 필드 |
|
|
2990
|
+
| `selectable?` | `boolean` | `false` | 행 선택 체크박스 |
|
|
2991
|
+
| `selected?` | `SRow[]` | `[]` | |
|
|
2992
|
+
| `resizable?` | `boolean` | `false` | 컬럼 너비 조절 |
|
|
2993
|
+
| `width?` | `string` | — | |
|
|
2994
|
+
| `height?` | `string` | — | |
|
|
2995
|
+
| `stickyHeader?` | `boolean` | — | |
|
|
2996
|
+
| `stickyColumn?` | `STableStickyColumn` | — | 고정할 좌/우 컬럼 수 |
|
|
2997
|
+
| `radius?` | `'default' \| 'useTop' \| 'full'` | `'default'` | border-radius 제어 |
|
|
2998
|
+
| `noDataLabel?` | `string` | `'데이터가 없습니다.'` | |
|
|
2999
|
+
| `noDataSlot?` | `ReactNode` | — | 데이터가 없을 때 body 영역 전체를 대체하는 슬롯. 지정하면 `noDataLabel` 대신 이 콘텐츠가 헤더 아래 영역을 채우며, 버튼 등 인터랙션도 동작한다. |
|
|
3000
|
+
| `isLoading?` | `boolean` | `false` | |
|
|
3001
|
+
| `dense?` | `boolean` | `false` | |
|
|
3002
|
+
| `noHover?` | `boolean` | `false` | true면 행에 마우스를 올려도 hover 배경(grey_05)을 표시하지 않는다 |
|
|
3003
|
+
| `pagination?` | `STablePagination` | — | 페이지네이션 (있으면 하단 표시) |
|
|
3004
|
+
| `useInternalPagination?` | `boolean` | `false` | 테이블 내부에서 페이지네이션을 직접 관리 (rows를 내부 슬라이싱) |
|
|
3005
|
+
| `useRowsPerPageSelect?` | `boolean` | `false` | 페이지당 행 수 셀렉트 표시 |
|
|
3006
|
+
| `rowsPerPageOption?` | `SSelectOption[]` | `DEFAULT_ROWS_PER_PAGE_OPTION` | |
|
|
3007
|
+
| `useVirtualScroll?` | `boolean` | `false` | 가상 스크롤 |
|
|
3008
|
+
| `rowHeight?` | `number` | — | |
|
|
3009
|
+
| `virtualBuffer?` | `number` | `5` | |
|
|
3010
|
+
| `virtualEndThreshold?` | `number` | `10` | |
|
|
3011
|
+
| `tableId?` | `string` | — | 테이블 식별자 (없으면 자동 생성) |
|
|
3012
|
+
| `className?` | `string` | — | |
|
|
3013
|
+
| `style?` | `CSSProperties` | — | |
|
|
3014
|
+
|
|
3015
|
+
#### Events
|
|
3016
|
+
|
|
3017
|
+
| Event | Type | Description |
|
|
3018
|
+
|-------|------|-------------|
|
|
3019
|
+
| `onSelectedChange` | `(rows: SRow[]) => void` | |
|
|
3020
|
+
| `onPageChange` | `(page: number) => void` | |
|
|
3021
|
+
| `onRowsPerPageChange` | `(perPage: number) => void` | |
|
|
3022
|
+
| `onVirtualUpdate` | `(range: { from: number; to: number }) => void` | |
|
|
3023
|
+
| `onVirtualReachEnd` | `(info: { from: number; to: number; rowCount: number; threshold: number; }) =>…` | |
|
|
3024
|
+
| `onRowClick` | `(row: SRow) => void` | 행 클릭 |
|
|
3025
|
+
|
|
3026
|
+
#### Methods (ref)
|
|
3027
|
+
|
|
3028
|
+
| Method | Type | Description |
|
|
3029
|
+
|--------|------|-------------|
|
|
3030
|
+
| `isRowSelected` | `(row: SRow) => boolean` | 행 선택 여부 |
|
|
3031
|
+
| `getIsAllChecked` | `(rows: SRow[]) => boolean \| null` | 주어진 행들의 전체 선택 상태 (true/false/null=indeterminate) |
|
|
3032
|
+
| `getPaginationInfo` | `<union 2종>` | 내부 페이지네이션 정보 (useInternalPagination 아니면 null) |
|
|
3033
|
+
| `getStickyStyle` | `(colIdx: number) => CSSProperties` | 컬럼 sticky 스타일 (CSS 변수 + 고정폭) |
|
|
3034
|
+
| `setRowCount` | `(count: number) => void` | 가상 스크롤 총 행 수 설정 |
|
|
3035
|
+
| `updateRowSelect` | `(row: SRow) => void` | 단일 행 선택 토글 (sd-table updateRowSelect) — onSelectedChange 발생 |
|
|
3036
|
+
| `toggleSelectAll` | `(checked: boolean, rows: SRow[]) => void` | 주어진 행들 전체 선택/해제 (sd-table toggleSelectAll) — onSelectedChange 발생 |
|
|
3037
|
+
|
|
3038
|
+
## Dependencies
|
|
3039
|
+
|
|
3040
|
+
### Depends on
|
|
3041
|
+
|
|
3042
|
+
- [SCheckbox](../SCheckbox)
|
|
3043
|
+
- [SCircleProgress](../SCircleProgress)
|
|
3044
|
+
- [SIcon](../SIcon)
|
|
3045
|
+
- [SPagination](../SPagination)
|
|
3046
|
+
- [SSelect](../SSelect)
|
|
3047
|
+
|
|
3048
|
+
### Graph
|
|
3049
|
+
|
|
3050
|
+
---
|
|
3051
|
+
|
|
3052
|
+
# STableBar
|
|
3053
|
+
|
|
3054
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3055
|
+
|
|
3056
|
+
### STableBar
|
|
3057
|
+
|
|
3058
|
+
#### Props
|
|
3059
|
+
|
|
3060
|
+
| Prop | Type | Default | Description |
|
|
3061
|
+
|------|------|---------|-------------|
|
|
3062
|
+
| `total?` | `number` | — | 전체 건수. 지정하면 "총 N 건" 을 표시한다 (천단위 구분 자동) |
|
|
3063
|
+
| `selected?` | `number` | — | 선택 건수. 지정하면 "N건 선택" 을 표시한다 |
|
|
3064
|
+
| `actions?` | `ReactNode` | — | 구분선 오른쪽 좌측 액션 영역 |
|
|
3065
|
+
| `rightActions?` | `ReactNode` | — | 우측 정렬 액션 영역 |
|
|
3066
|
+
|
|
3067
|
+
## Dependencies
|
|
3068
|
+
|
|
3069
|
+
### Depends on
|
|
3070
|
+
|
|
3071
|
+
- [SDivider](../SDivider)
|
|
3072
|
+
|
|
3073
|
+
### Graph
|
|
3074
|
+
|
|
3075
|
+
---
|
|
3076
|
+
|
|
3077
|
+
# STabs
|
|
3078
|
+
|
|
3079
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3080
|
+
|
|
3081
|
+
### STabs
|
|
3082
|
+
|
|
3083
|
+
#### Props
|
|
3084
|
+
|
|
3085
|
+
| Prop | Type | Default | Description |
|
|
3086
|
+
|------|------|---------|-------------|
|
|
3087
|
+
| `value` | `string` | — | 현재 선택된 탭 value |
|
|
3088
|
+
| `tabs` | `STabOption[]` | — | 탭 옵션 목록 |
|
|
3089
|
+
| `size?` | `STabSize` | `'md'` | 탭 크기 (main 전용) |
|
|
3090
|
+
| `isSub?` | `boolean` | `false` | 서브 탭(밑줄형) 스타일 |
|
|
3091
|
+
| `vertical?` | `boolean` | `false` | 세로 배치 (sub 전용 — main 폴더형은 항상 가로) |
|
|
3092
|
+
| `className?` | `string` | — | |
|
|
3093
|
+
| `style?` | `CSSProperties` | — | |
|
|
3094
|
+
|
|
3095
|
+
#### Events
|
|
3096
|
+
|
|
3097
|
+
| Event | Type | Description |
|
|
3098
|
+
|-------|------|-------------|
|
|
3099
|
+
| `onValueChange` | `(value: string) => void` | 탭 변경 (sdUpdate) |
|
|
3100
|
+
|
|
3101
|
+
## Dependencies
|
|
3102
|
+
|
|
3103
|
+
### Depends on
|
|
3104
|
+
|
|
3105
|
+
- [STag](../STag)
|
|
3106
|
+
|
|
3107
|
+
### Graph
|
|
3108
|
+
|
|
3109
|
+
---
|
|
3110
|
+
|
|
3111
|
+
# STag
|
|
3112
|
+
|
|
3113
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3114
|
+
|
|
3115
|
+
### STag
|
|
3116
|
+
|
|
3117
|
+
#### Props
|
|
3118
|
+
|
|
3119
|
+
| Prop | Type | Default | Description |
|
|
3120
|
+
|------|------|---------|-------------|
|
|
3121
|
+
| `shape?` | `STagShape` | `'square'` | 모양 |
|
|
3122
|
+
| `size?` | `STagSize` | `'sm'` | 크기 |
|
|
3123
|
+
| `color?` | `STagColor` | `'grey'` | 색상 |
|
|
3124
|
+
| `label?` | `string` | `''` | 레이블 텍스트 |
|
|
3125
|
+
| `icon?` | `SIconName` | — | 아이콘명 |
|
|
3126
|
+
| `iconLeft?` | `boolean` | `true` | 아이콘을 레이블 왼쪽에 배치 |
|
|
3127
|
+
| `width?` | `string \| number` | — | 태그 너비 (숫자면 px, 문자열이면 그대로 적용). 미지정 시 콘텐츠 크기 |
|
|
3128
|
+
|
|
3129
|
+
## Dependencies
|
|
3130
|
+
|
|
3131
|
+
### Used by
|
|
3132
|
+
|
|
3133
|
+
- [SConfirmModal](../SConfirmModal)
|
|
3134
|
+
- [SGhostButton](../SGhostButton)
|
|
3135
|
+
- [SGnb](../SGnb)
|
|
3136
|
+
- [STabs](../STabs)
|
|
3137
|
+
- [STextLink](../STextLink)
|
|
3138
|
+
|
|
3139
|
+
### Depends on
|
|
3140
|
+
|
|
3141
|
+
- [SIcon](../SIcon)
|
|
3142
|
+
|
|
3143
|
+
### Graph
|
|
3144
|
+
|
|
3145
|
+
---
|
|
3146
|
+
|
|
3147
|
+
# STextLink
|
|
3148
|
+
|
|
3149
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3150
|
+
|
|
3151
|
+
### STextLink
|
|
3152
|
+
|
|
3153
|
+
#### Props
|
|
3154
|
+
|
|
3155
|
+
| Prop | Type | Default | Description |
|
|
3156
|
+
|------|------|---------|-------------|
|
|
3157
|
+
| `label?` | `string` | `''` | 레이블 |
|
|
3158
|
+
| `icon?` | `SIconName` | — | 좌측 아이콘 |
|
|
3159
|
+
| `iconColor?` | `SColor` | — | 좌측 아이콘 색상. 팔레트 키(`grey_65`, `red_95` …) 또는 임의 CSS 색상 |
|
|
3160
|
+
| `labelClass?` | `string` | — | 레이블 span에 추가할 클래스 |
|
|
3161
|
+
| `rightArrow?` | `STextLinkArrow` | `'none'` | 우측 화살표 |
|
|
3162
|
+
| `underline?` | `boolean` | `false` | 밑줄 여부 |
|
|
3163
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
3164
|
+
| `size?` | `STextLinkSize` | `'sm'` | 크기 |
|
|
3165
|
+
| `tooltipText?` | `string` | — | 호버 시 표시할 툴팁 텍스트 (회색 STag 스타일) |
|
|
3166
|
+
|
|
3167
|
+
#### Events
|
|
3168
|
+
|
|
3169
|
+
| Event | Type | Description |
|
|
3170
|
+
|-------|------|-------------|
|
|
3171
|
+
| `onClick` | `() => void` | |
|
|
3172
|
+
|
|
3173
|
+
## Dependencies
|
|
3174
|
+
|
|
3175
|
+
### Used by
|
|
3176
|
+
|
|
3177
|
+
- [SChipInput](../SChipInput)
|
|
3178
|
+
- [SPopover](../SPopover)
|
|
3179
|
+
|
|
3180
|
+
### Depends on
|
|
3181
|
+
|
|
3182
|
+
- [SIcon](../SIcon)
|
|
3183
|
+
- [STag](../STag)
|
|
3184
|
+
|
|
3185
|
+
### Graph
|
|
3186
|
+
|
|
3187
|
+
---
|
|
3188
|
+
|
|
3189
|
+
# STextarea
|
|
3190
|
+
|
|
3191
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3192
|
+
|
|
3193
|
+
### STextarea
|
|
3194
|
+
|
|
3195
|
+
#### Props
|
|
3196
|
+
|
|
3197
|
+
| Prop | Type | Default | Description |
|
|
3198
|
+
|------|------|---------|-------------|
|
|
3199
|
+
| `value?` | `string` | — | 값 (제어) |
|
|
3200
|
+
| `rows?` | `number` | `3` | 행 수 |
|
|
3201
|
+
| `rules?` | `Rule[]` | — | 유효성 규칙 — blur 시 자동 검증 |
|
|
3202
|
+
| `status?` | `SFieldStatus` | — | 필드 상태 ('default' | 'pass' | 'error') |
|
|
3203
|
+
| `focused?` | `boolean` | — | 포커스 상태 (제어/반영) |
|
|
3204
|
+
| `hovered?` | `boolean` | — | 호버 상태 (제어/반영) |
|
|
3205
|
+
| `textareaClass?` | `string` | — | 내부 textarea 요소 className |
|
|
3206
|
+
| `textareaStyle?` | `CSSProperties` | — | 내부 textarea 요소 style |
|
|
3207
|
+
| `label?` | `string` | — | |
|
|
3208
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
3209
|
+
| `icon?` | `SIconName` | — | 레이블 영역 아이콘 |
|
|
3210
|
+
| `iconColor?` | `SColor` | — | |
|
|
3211
|
+
| `labelTooltip?` | `string` | — | 레이블 툴팁 텍스트 |
|
|
3212
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 |
|
|
3213
|
+
| `addonLabel?` | `string` | — | 우측 어드온 레이블 |
|
|
3214
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | 어드온 정렬 |
|
|
3215
|
+
| `hint?` | `string` | — | |
|
|
3216
|
+
| `error?` | `boolean` | — | |
|
|
3217
|
+
| `errorMessage?` | `string` | — | |
|
|
3218
|
+
| `width?` | `number \| string` | — | |
|
|
3219
|
+
| `disabled?` | `boolean` | `false` | |
|
|
3220
|
+
| `readOnly?` | `boolean` | `false` | |
|
|
3221
|
+
| `className?` | `string` | — | |
|
|
3222
|
+
| `style?` | `CSSProperties` | — | |
|
|
3223
|
+
|
|
3224
|
+
#### Events
|
|
3225
|
+
|
|
3226
|
+
| Event | Type | Description |
|
|
3227
|
+
|-------|------|-------------|
|
|
3228
|
+
| `onValueChange` | `(value: string) => void` | 값 변경 (sdUpdate) |
|
|
3229
|
+
| `onChange` | `TextareaHTMLAttributes<HTMLTextAreaElement>['onChange']` | 네이티브 onChange (form-agnostic) |
|
|
3230
|
+
|
|
3231
|
+
## Dependencies
|
|
3232
|
+
|
|
3233
|
+
### Used by
|
|
3234
|
+
|
|
3235
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
3236
|
+
|
|
3237
|
+
### Depends on
|
|
3238
|
+
|
|
3239
|
+
- [SField](../SField)
|
|
3240
|
+
|
|
3241
|
+
### Graph
|
|
3242
|
+
|
|
3243
|
+
---
|
|
3244
|
+
|
|
3245
|
+
# STimePicker
|
|
3246
|
+
|
|
3247
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3248
|
+
|
|
3249
|
+
### STimePicker
|
|
3250
|
+
|
|
3251
|
+
#### Props
|
|
3252
|
+
|
|
3253
|
+
| Prop | Type | Default | Description |
|
|
3254
|
+
|------|------|---------|-------------|
|
|
3255
|
+
| `value?` | `string \| null` | — | 선택 시간 (HH:mm) |
|
|
3256
|
+
| `type?` | `STimePickerType` | `'default'` | 표시 타입: default(24시간) / midday(오전·오후) |
|
|
3257
|
+
| `size?` | `STimePickerSize` | `'sm'` | |
|
|
3258
|
+
| `placeholder?` | `string` | `'00:00'` | |
|
|
3259
|
+
| `disabled?` | `boolean` | `false` | |
|
|
3260
|
+
| `clearable?` | `boolean` | `false` | |
|
|
3261
|
+
| `useMeridiem?` | `boolean` | — | 오전/오후 선택 표시 여부. 지정하지 않으면 type="midday"일 때만 켜집니다. |
|
|
3262
|
+
| `minuteStep?` | `number` | `1` | |
|
|
3263
|
+
| `width?` | `number \| string` | — | |
|
|
3264
|
+
| `name?` | `string` | — | |
|
|
3265
|
+
| `rules?` | `Rule[]` | — | |
|
|
3266
|
+
| `status?` | `SFieldStatus` | — | |
|
|
3267
|
+
| `label?` | `string` | — | |
|
|
3268
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
3269
|
+
| `icon?` | `SIconName` | — | |
|
|
3270
|
+
| `iconColor?` | `SColor` | — | |
|
|
3271
|
+
| `labelTooltip?` | `string` | — | |
|
|
3272
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
3273
|
+
| `addonLabel?` | `string` | — | |
|
|
3274
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | |
|
|
3275
|
+
| `hint?` | `string` | — | |
|
|
3276
|
+
| `error?` | `boolean` | — | |
|
|
3277
|
+
| `errorMessage?` | `string` | — | |
|
|
3278
|
+
| `className?` | `string` | — | |
|
|
3279
|
+
| `style?` | `CSSProperties` | — | |
|
|
3280
|
+
|
|
3281
|
+
#### Events
|
|
3282
|
+
|
|
3283
|
+
| Event | Type | Description |
|
|
3284
|
+
|-------|------|-------------|
|
|
3285
|
+
| `onValueChange` | `(time: string \| null) => void` | 선택 변경 (sdUpdate) |
|
|
3286
|
+
| `onOpenChange` | `(open: boolean) => void` | 열림/닫힘 변경 (sdDropDownShow) |
|
|
3287
|
+
|
|
3288
|
+
## Dependencies
|
|
3289
|
+
|
|
3290
|
+
### Used by
|
|
3291
|
+
|
|
3292
|
+
- [STimeRangePicker](../STimeRangePicker)
|
|
3293
|
+
|
|
3294
|
+
### Depends on
|
|
3295
|
+
|
|
3296
|
+
- [SField](../SField)
|
|
3297
|
+
- [SGhostButton](../SGhostButton)
|
|
3298
|
+
- [SIcon](../SIcon)
|
|
3299
|
+
|
|
3300
|
+
### Graph
|
|
3301
|
+
|
|
3302
|
+
---
|
|
3303
|
+
|
|
3304
|
+
# STimeRangePicker
|
|
3305
|
+
|
|
3306
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3307
|
+
|
|
3308
|
+
### STimeRangePicker
|
|
3309
|
+
|
|
3310
|
+
#### Props
|
|
3311
|
+
|
|
3312
|
+
| Prop | Type | Default | Description |
|
|
3313
|
+
|------|------|---------|-------------|
|
|
3314
|
+
| `value?` | `STimeRangeValue` | — | 선택 시간 범위 [시작, 종료] (HH:mm) |
|
|
3315
|
+
| `type?` | `STimeRangePickerType` | `'default'` | 표시 타입: default(24시간) / midday(오전·오후) |
|
|
3316
|
+
| `size?` | `STimeRangePickerSize` | `'sm'` | |
|
|
3317
|
+
| `placeholder?` | `string` | `'00:00 ~ 23:59'` | |
|
|
3318
|
+
| `disabled?` | `boolean` | `false` | |
|
|
3319
|
+
| `clearable?` | `boolean` | `false` | |
|
|
3320
|
+
| `useMeridiem?` | `boolean` | — | 오전/오후 선택 표시 여부. 지정하지 않으면 type="midday"일 때만 켜집니다. |
|
|
3321
|
+
| `minuteStep?` | `number` | `1` | |
|
|
3322
|
+
| `rangeOrder?` | `STimeRangePickerRangeOrder` | `'strict'` | 범위 순서 정책. strict는 시작 시간이 종료 시간보다 늦어지지 않도록 보정합니다. |
|
|
3323
|
+
| `width?` | `number \| string` | — | |
|
|
3324
|
+
| `name?` | `string` | — | |
|
|
3325
|
+
| `rules?` | `Rule[]` | — | |
|
|
3326
|
+
| `status?` | `SFieldStatus` | — | |
|
|
3327
|
+
| `label?` | `string` | — | |
|
|
3328
|
+
| `labelWidth?` | `number \| string` | — | |
|
|
3329
|
+
| `icon?` | `SIconName` | — | |
|
|
3330
|
+
| `iconColor?` | `SColor` | — | |
|
|
3331
|
+
| `labelTooltip?` | `string` | — | |
|
|
3332
|
+
| `labelTooltipProps?` | `Partial<STooltipProps>` | — | |
|
|
3333
|
+
| `addonLabel?` | `string` | — | |
|
|
3334
|
+
| `addonAlign?` | `SFieldAddonAlign` | — | |
|
|
3335
|
+
| `hint?` | `string` | — | |
|
|
3336
|
+
| `error?` | `boolean` | — | |
|
|
3337
|
+
| `errorMessage?` | `string` | — | |
|
|
3338
|
+
| `className?` | `string` | — | |
|
|
3339
|
+
| `style?` | `CSSProperties` | — | |
|
|
3340
|
+
|
|
3341
|
+
#### Events
|
|
3342
|
+
|
|
3343
|
+
| Event | Type | Description |
|
|
3344
|
+
|-------|------|-------------|
|
|
3345
|
+
| `onValueChange` | `(range: STimeRangeValue) => void` | 선택 변경 (sdUpdate) |
|
|
3346
|
+
| `onOpenChange` | `(open: boolean) => void` | 열림/닫힘 변경 (sdDropDownShow) |
|
|
3347
|
+
|
|
3348
|
+
## Dependencies
|
|
3349
|
+
|
|
3350
|
+
### Depends on
|
|
3351
|
+
|
|
3352
|
+
- [SField](../SField)
|
|
3353
|
+
- [SGhostButton](../SGhostButton)
|
|
3354
|
+
- [SIcon](../SIcon)
|
|
3355
|
+
- [STimePicker](../STimePicker)
|
|
3356
|
+
|
|
3357
|
+
### Graph
|
|
3358
|
+
|
|
3359
|
+
---
|
|
3360
|
+
|
|
3361
|
+
# SToast
|
|
3362
|
+
|
|
3363
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3364
|
+
|
|
3365
|
+
### SToastContainer
|
|
3366
|
+
|
|
3367
|
+
#### Props
|
|
3368
|
+
|
|
3369
|
+
| Prop | Type | Default | Description |
|
|
3370
|
+
|------|------|---------|-------------|
|
|
3371
|
+
| `position?` | `SToastPosition` | `'bottom-center'` | |
|
|
3372
|
+
| `maxVisible?` | `number` | `3` | |
|
|
3373
|
+
| `defaultDuration?` | `number` | `4000` | 자동 닫힘 기본 지연(ms) |
|
|
3374
|
+
| `zIndex?` | `number` | `1100` | 스택 z-index. 기본값(1100)은 모달(1000/1001) 위 — 토스트는 전역 알림이라 항상 최상단 |
|
|
3375
|
+
|
|
3376
|
+
#### Events
|
|
3377
|
+
|
|
3378
|
+
| Event | Type | Description |
|
|
3379
|
+
|-------|------|-------------|
|
|
3380
|
+
| `onShow` | `(payload: { id: string }) => void` | 토스트가 표시될 때 (sdToastShow) |
|
|
3381
|
+
| `onDismiss` | `(payload: { id: string }) => void` | 토스트가 제거될 때 (sdToastDismiss) |
|
|
3382
|
+
|
|
3383
|
+
#### Methods (ref)
|
|
3384
|
+
|
|
3385
|
+
| Method | Type | Description |
|
|
3386
|
+
|--------|------|-------------|
|
|
3387
|
+
| `create` | `(options: SToastNotifyOptions) => string` | |
|
|
3388
|
+
| `dismiss` | `(id: string) => void` | |
|
|
3389
|
+
| `dismissAll` | `() => void` | |
|
|
3390
|
+
|
|
3391
|
+
### SToast
|
|
3392
|
+
|
|
3393
|
+
#### Props
|
|
3394
|
+
|
|
3395
|
+
| Prop | Type | Default | Description |
|
|
3396
|
+
|------|------|---------|-------------|
|
|
3397
|
+
| `icon?` | `SIconName` | — | 좌측 아이콘 |
|
|
3398
|
+
| `message` | `string` | — | 메시지 |
|
|
3399
|
+
| `link?` | `string` | — | 우측 링크 URL |
|
|
3400
|
+
| `linkLabel?` | `string` | — | 링크 레이블 (없으면 URL) |
|
|
3401
|
+
| `buttonLabel?` | `string` | — | 우측 버튼 레이블 |
|
|
3402
|
+
| `useClose?` | `boolean` | `false` | 닫기 버튼 표시 |
|
|
3403
|
+
| `type?` | `SToastType` | `'default'` | 타입(색상/프리셋) |
|
|
3404
|
+
| `className?` | `string` | — | |
|
|
3405
|
+
| `style?` | `CSSProperties` | — | |
|
|
3406
|
+
|
|
3407
|
+
#### Events
|
|
3408
|
+
|
|
3409
|
+
| Event | Type | Description |
|
|
3410
|
+
|-------|------|-------------|
|
|
3411
|
+
| `onClose` | `() => void` | 닫기 (sdClose) |
|
|
3412
|
+
| `onButtonClick` | `(e: MouseEvent) => void` | 버튼 클릭 (sdButtonClick) |
|
|
3413
|
+
|
|
3414
|
+
## Dependencies
|
|
3415
|
+
|
|
3416
|
+
### Depends on
|
|
3417
|
+
|
|
3418
|
+
- [SButton](../SButton)
|
|
3419
|
+
- [SGhostButton](../SGhostButton)
|
|
3420
|
+
- [SIcon](../SIcon)
|
|
3421
|
+
|
|
3422
|
+
### Graph
|
|
3423
|
+
|
|
3424
|
+
---
|
|
3425
|
+
|
|
3426
|
+
# SToggle
|
|
3427
|
+
|
|
3428
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3429
|
+
|
|
3430
|
+
### SToggle
|
|
3431
|
+
|
|
3432
|
+
#### Props
|
|
3433
|
+
|
|
3434
|
+
| Prop | Type | Default | Description |
|
|
3435
|
+
|------|------|---------|-------------|
|
|
3436
|
+
| `value?` | `boolean` | `false` | 선택(on/off) 상태 |
|
|
3437
|
+
| `label?` | `string` | `''` | 라벨 |
|
|
3438
|
+
| `disabled?` | `boolean` | `false` | 비활성 |
|
|
3439
|
+
| `className?` | `string` | — | |
|
|
3440
|
+
| `style?` | `CSSProperties` | — | |
|
|
3441
|
+
|
|
3442
|
+
#### Events
|
|
3443
|
+
|
|
3444
|
+
| Event | Type | Description |
|
|
3445
|
+
|-------|------|-------------|
|
|
3446
|
+
| `onValueChange` | `(value: boolean) => void` | 변경 (sdUpdate) |
|
|
3447
|
+
|
|
3448
|
+
---
|
|
3449
|
+
|
|
3450
|
+
# STooltip
|
|
3451
|
+
|
|
3452
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
3453
|
+
|
|
3454
|
+
### STooltip
|
|
3455
|
+
|
|
3456
|
+
#### Props
|
|
3457
|
+
|
|
3458
|
+
| Prop | Type | Default | Description |
|
|
3459
|
+
|------|------|---------|-------------|
|
|
3460
|
+
| `content?` | `ReactNode` | — | 툴팁 본문 (ReactNode). message 보다 우선 |
|
|
3461
|
+
| `message?` | `string[]` | `[]` | 툴팁 본문 줄 목록 (각 항목이 한 줄, HTML 문자열 허용 — innerHTML 렌더링) |
|
|
3462
|
+
| `trigger?` | `STooltipTrigger` | `'hover'` | 트리거 방식 |
|
|
3463
|
+
| `placement?` | `STooltipPlacement` | `'top'` | 표시 방향 |
|
|
3464
|
+
| `tooltipType?` | `STooltipType` | `'default'` | 배경/텍스트 색상 타입 |
|
|
3465
|
+
| `useClose?` | `boolean` | `false` | 우측 상단 닫기 버튼. 켜면 자동 닫힘이 비활성화되고 X(또는 hide())로만 닫힘 (hover·click 공통) |
|
|
3466
|
+
| `disabled?` | `boolean` | `false` | 비활성 — 트리거만 렌더하고 툴팁을 열지 않음 |
|
|
3467
|
+
| `children?` | `ReactNode` | — | 커스텀 트리거. 없으면 아이콘 트리거를 렌더 |
|
|
3468
|
+
| `icon?` | `SIconName` | `'helpOutline'` | 기본(아이콘) 트리거 설정 |
|
|
3469
|
+
| `iconSize?` | `number` | `12` | |
|
|
3470
|
+
| `color?` | `SColor` | `'#01BB4B'` | 트리거 아이콘 색상. 팔레트 키(`grey_65`, `red_95` …) 또는 임의 CSS 색상 |
|
|
3471
|
+
| `ariaLabel?` | `string` | — | 접근성 레이블 |
|
|
3472
|
+
| `className?` | `string` | — | |
|
|
3473
|
+
| `triggerClassName?` | `string` | — | |
|
|
3474
|
+
| `style?` | `CSSProperties` | — | |
|
|
3475
|
+
|
|
3476
|
+
#### Methods (ref)
|
|
3477
|
+
|
|
3478
|
+
| Method | Type | Description |
|
|
3479
|
+
|--------|------|-------------|
|
|
3480
|
+
| `show` | `() => void` | 툴팁을 표시합니다. |
|
|
3481
|
+
| `hide` | `() => void` | 툴팁을 숨깁니다. |
|
|
3482
|
+
|
|
3483
|
+
## Dependencies
|
|
3484
|
+
|
|
3485
|
+
### Used by
|
|
3486
|
+
|
|
3487
|
+
- [SField](../SField)
|
|
3488
|
+
- [SKeyValueTable](../SKeyValueTable)
|
|
3489
|
+
- [SList](../SList)
|
|
3490
|
+
|
|
3491
|
+
### Depends on
|
|
3492
|
+
|
|
3493
|
+
- [SGhostButton](../SGhostButton)
|
|
3494
|
+
- [SIcon](../SIcon)
|
|
3495
|
+
|
|
3496
|
+
### Graph
|