sellmate-design-system-react 9.0.0-beta.2 → 9.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/AGENTS.md +488 -90
  2. package/README.md +101 -0
  3. package/dist/components/SBadge/README.md +24 -0
  4. package/dist/components/SBadge/SBadge.d.ts +1 -1
  5. package/dist/components/SBarcodeInput/README.md +9 -1
  6. package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +7 -1
  7. package/dist/components/SButton/README.md +36 -0
  8. package/dist/components/SCalendar/README.md +13 -0
  9. package/dist/components/SCallout/README.md +15 -0
  10. package/dist/components/SCard/README.md +16 -0
  11. package/dist/components/SCard/SCard.d.ts +17 -2
  12. package/dist/components/SCheckbox/README.md +8 -0
  13. package/dist/components/SChipFilter/README.md +288 -5
  14. package/dist/components/SChipFilter/SChipFilter.d.ts +95 -40
  15. package/dist/components/SChipFilter/index.d.ts +1 -1
  16. package/dist/components/SChipInput/README.md +15 -1
  17. package/dist/components/SChipInput/SChipInput.d.ts +7 -1
  18. package/dist/components/SCircleProgress/README.md +8 -0
  19. package/dist/components/SConfirmModal/README.md +16 -0
  20. package/dist/components/SDatePicker/README.md +60 -4
  21. package/dist/components/SDatePicker/SDatePicker.d.ts +61 -5
  22. package/dist/components/SDatePicker/index.d.ts +1 -1
  23. package/dist/components/SDateRangePicker/README.md +17 -2
  24. package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +16 -3
  25. package/dist/components/SDivider/README.md +4 -0
  26. package/dist/components/SDraggableItem/README.md +37 -0
  27. package/dist/components/SDraggableItem/SDraggableItem.d.ts +2 -0
  28. package/dist/components/SDraggableList/README.md +29 -0
  29. package/dist/components/SDraggableList/SDraggableList.d.ts +10 -0
  30. package/dist/components/SDraggableList/index.d.ts +1 -1
  31. package/dist/components/SDrawer/README.md +8 -0
  32. package/dist/components/SDropdownButton/README.md +19 -0
  33. package/dist/components/SEditor/EditorBody.d.ts +40 -0
  34. package/dist/components/SEditor/EditorToolbar.d.ts +87 -0
  35. package/dist/components/SEditor/README.md +230 -0
  36. package/dist/components/SEditor/SEditor.d.ts +124 -0
  37. package/dist/components/SEditor/editor-icons.d.ts +59 -0
  38. package/dist/components/SEditor/editor.config.d.ts +85 -0
  39. package/dist/components/SEditor/index.d.ts +2 -0
  40. package/dist/components/SEditor/tiptap-api.d.ts +29 -0
  41. package/dist/components/SEditor/use-is-mobile.d.ts +14 -0
  42. package/dist/components/SExpansionItem/README.md +36 -0
  43. package/dist/components/SField/README.md +27 -2
  44. package/dist/components/SField/SField.d.ts +22 -4
  45. package/dist/components/SFilePicker/README.md +15 -1
  46. package/dist/components/SFilePicker/SFilePicker.d.ts +7 -1
  47. package/dist/components/SFooter/README.md +25 -0
  48. package/dist/components/SFooter/SFooter.d.ts +4 -3
  49. package/dist/components/SForm/README.md +11 -0
  50. package/dist/components/SGhostButton/README.md +20 -2
  51. package/dist/components/SGnb/README.md +45 -0
  52. package/dist/components/SGnb/gnb.config.d.ts +7 -0
  53. package/dist/components/SGuide/README.md +15 -0
  54. package/dist/components/SIcon/README.md +4 -0
  55. package/dist/components/SIcon/SIcon.d.ts +1 -1
  56. package/dist/components/SIcon/icons.gen.d.ts +2 -0
  57. package/dist/components/SImage/README.md +14 -0
  58. package/dist/components/SInput/README.md +3 -1
  59. package/dist/components/SInput/SInput.d.ts +7 -1
  60. package/dist/components/SKeyValueTable/README.md +87 -0
  61. package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +14 -3
  62. package/dist/components/SLayout/README.md +16 -0
  63. package/dist/components/SLinearProgress/README.md +8 -0
  64. package/dist/components/SList/README.md +5 -1
  65. package/dist/components/SList/SList.d.ts +0 -2
  66. package/dist/components/SListItem/README.md +41 -0
  67. package/dist/components/SLoadingModal/README.md +8 -0
  68. package/dist/components/SNumberInput/README.md +9 -1
  69. package/dist/components/SNumberInput/SNumberInput.d.ts +7 -1
  70. package/dist/components/SPage/README.md +41 -1
  71. package/dist/components/SPage/SPage.d.ts +24 -2
  72. package/dist/components/SPage/index.d.ts +1 -1
  73. package/dist/components/SPage/page.config.d.ts +8 -0
  74. package/dist/components/SPopover/README.md +15 -0
  75. package/dist/components/SPopup/README.md +19 -0
  76. package/dist/components/SPortal/README.md +14 -0
  77. package/dist/components/SRadio/README.md +20 -0
  78. package/dist/components/SRadioButton/README.md +18 -0
  79. package/dist/components/SScrollArea/README.md +14 -0
  80. package/dist/components/SSearchInput/README.md +61 -0
  81. package/dist/components/SSearchInput/SSearchInput.d.ts +52 -0
  82. package/dist/components/SSearchInput/index.d.ts +1 -0
  83. package/dist/components/SSectionHeaderCard/README.md +44 -20
  84. package/dist/components/SSectionHeaderCard/SSectionHeaderCard.d.ts +31 -14
  85. package/dist/components/SSectionHeaderCard/index.d.ts +1 -1
  86. package/dist/components/SSelect/README.md +23 -3
  87. package/dist/components/SSelect/SSelect.d.ts +13 -1
  88. package/dist/components/SSplitter/README.md +15 -0
  89. package/dist/components/SStepper/README.md +26 -0
  90. package/dist/components/SSwitch/README.md +13 -0
  91. package/dist/components/STable/README.md +72 -1
  92. package/dist/components/STable/STable.d.ts +129 -11
  93. package/dist/components/STable/index.d.ts +1 -1
  94. package/dist/components/STabs/README.md +12 -1
  95. package/dist/components/STabs/STabs.d.ts +2 -4
  96. package/dist/components/STabs/index.d.ts +1 -1
  97. package/dist/components/STabs/tabs.config.d.ts +3 -4
  98. package/dist/components/STag/README.md +47 -0
  99. package/dist/components/STextLink/README.md +17 -0
  100. package/dist/components/STextLink/STextLink.d.ts +2 -0
  101. package/dist/components/STextarea/README.md +1 -1
  102. package/dist/components/STextarea/STextarea.d.ts +7 -1
  103. package/dist/components/STimePicker/README.md +15 -1
  104. package/dist/components/STimePicker/STimePicker.d.ts +7 -1
  105. package/dist/components/STimePicker/timepicker.config.d.ts +7 -0
  106. package/dist/components/STimeRangePicker/README.md +27 -1
  107. package/dist/components/STimeRangePicker/STimeRangePicker.d.ts +7 -1
  108. package/dist/components/SToast/README.md +24 -0
  109. package/dist/components/SToggle/README.md +8 -0
  110. package/dist/components/STooltip/README.md +22 -0
  111. package/dist/components/STree/README.md +41 -0
  112. package/dist/components/STree/STree.d.ts +8 -0
  113. package/dist/components/STree/index.d.ts +1 -1
  114. package/dist/index.cjs +4266 -750
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.ts +3 -0
  117. package/dist/index.js +4249 -750
  118. package/dist/index.js.map +1 -1
  119. package/dist/lib/field-width.d.ts +31 -0
  120. package/dist/lib/story-docs.d.ts +19 -3
  121. package/dist/lib/truncated-value-tooltip.d.ts +18 -0
  122. package/dist/llms-full.txt +2337 -183
  123. package/dist/llms.txt +490 -92
  124. package/dist/styles.css +684 -41
  125. package/dist/theme.css +22 -6
  126. package/eslint/index.mjs +10 -0
  127. package/eslint/lib/table-column.mjs +26 -0
  128. package/eslint/rules/field-width-grade.d.mts +41 -0
  129. package/eslint/rules/field-width-grade.mjs +311 -0
  130. package/eslint/rules/table-column-width.mjs +110 -0
  131. package/eslint/scale.gen.mjs +3 -0
  132. package/package.json +13 -1
@@ -0,0 +1,230 @@
1
+ # SEditor
2
+
3
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
4
+
5
+ ### EditorBody
6
+
7
+ #### Props
8
+
9
+ | Prop | Type | Default | Description |
10
+ |------|------|---------|-------------|
11
+ | `api` | `TiptapApi` | — | 다 불러온 tiptap — 이 컴포넌트는 준비된 뒤에만 마운트된다 |
12
+ | `value?` | `string` | — | |
13
+ | `defaultValue?` | `string` | — | |
14
+ | `htmlRef` | `RefObject<string>` | — | 지금 화면에 있는 HTML. 껍데기(SEditor)가 규칙 검증·폼 제출에 쓴다 |
15
+ | `placeholder` | `string` | — | |
16
+ | `typography` | `boolean` | — | |
17
+ | `editable` | `boolean` | — | |
18
+ | `disabled` | `boolean` | — | |
19
+ | `minHeight?` | `number \| string` | — | |
20
+ | `maxHeight?` | `number \| string` | — | |
21
+ | `toolbar` | `SEditorToolbarItem[] \| false` | — | |
22
+ | `bubbleMenu` | `SEditorToolbarItem[] \| false` | — | 선택 영역 위에 뜨는 서식 판. `false` 면 그리지 않는다 |
23
+ | `fontSizes` | `number[]` | — | |
24
+ | `colors` | `SEditorColorOption[]` | — | |
25
+ | `highlights` | `SEditorColorOption[]` | — | |
26
+ | `editorClass?` | `string` | — | |
27
+ | `editorStyle?` | `CSSProperties` | — | |
28
+
29
+ #### Events
30
+
31
+ | Event | Type | Description |
32
+ |-------|------|-------------|
33
+ | `onInput` | `(html: string) => void` | 사용자가 고쳐서 값이 바뀌었다 (setHTML·clear 같은 프로그램 조작은 제외) |
34
+ | `onFocusChange` | `(focused: boolean) => void` | |
35
+ | `onReady` | `() => void` | 에디터 인스턴스가 생겼다 — 껍데기가 밀린 focus() 를 흘려보낸다 |
36
+ | `onImageUpload` | `(file: File) => Promise<string>` | |
37
+
38
+ ### EditorToolbarBar
39
+
40
+ #### Props
41
+
42
+ | Prop | Type | Default | Description |
43
+ |------|------|---------|-------------|
44
+ | `state` | `EditorToolbarState` | — | 눌림 표시 — 에디터가 아직 없으면 `IDLE_TOOLBAR_STATE` |
45
+ | `editor` | `Editor \| null` | — | 없으면 버튼을 눌러도 아무 일도 하지 않는다 (그때는 disabled 로 함께 잠근다) |
46
+ | `items` | `SEditorToolbarItem[]` | — | |
47
+ | `fontSizes` | `readonly number[]` | — | |
48
+ | `colors` | `SEditorColorOption[]` | — | |
49
+ | `highlights` | `SEditorColorOption[]` | — | |
50
+ | `disabled` | `boolean` | — | 편집 불가(비활성·읽기전용·엔진 로딩 중) — 모든 버튼을 잠근다 |
51
+ | `variant?` | `'bar' \| 'bubble'` | `'bar'` | `'bar'` 는 편집 영역 위에 붙는 막대, `'bubble'` 은 선택 영역 위에 뜨는 판이다. 그리는 버튼은 같고 담는 상자와 줄바꿈만 다르다. |
52
+
53
+ #### Events
54
+
55
+ | Event | Type | Description |
56
+ |-------|------|-------------|
57
+ | `onImageUpload` | `(file: File) => Promise<string>` | 이미지 업로드 훅. 없으면 `image` 항목을 그리지 않는다 |
58
+
59
+ ### SEditor
60
+
61
+ #### Props
62
+
63
+ | Prop | Type | Default | Description |
64
+ |------|------|---------|-------------|
65
+ | `value?` | `string` | — | 값 (제어) — HTML 문자열 |
66
+ | `defaultValue?` | `string` | — | 초기값 (비제어) — HTML 문자열 |
67
+ | `placeholder?` | `string` | `'내용을 입력해 주세요.'` | 빈 문서에 보일 안내 문구 |
68
+ | `minHeight?` | `number \| string` | `200` | 편집 영역 최소 높이 (숫자=px) |
69
+ | `maxHeight?` | `number \| string` | — | 편집 영역 최대 높이 (숫자=px). 넘으면 편집 영역 안에서만 스크롤한다 |
70
+ | `toolbar?` | `SEditorToolbarItem[] \| false` | `SEDITOR_DEFAULT_TOOLBAR` | 툴바 구성. `false` 면 툴바 없이 본문만 (읽기 화면·간단 메모용) |
71
+ | `bubbleMenu?` | `SEditorToolbarItem[] \| false` | `SEDITOR_DEFAULT_BUBBLE_MENU` | 글을 선택했을 때 그 위에 뜨는 서식 판의 구성. `false` 면 뜨지 않는다. 읽기 전용·비활성일 때는 어차피 뜨지 않는다. 좁은 칸에 놓인 에디터라면 판이 필드 밖으로 넘칠 수 있으니 항목을 줄이거나 `false` 로 끈다. |
72
+ | `fontSizes?` | `number[]` | `[...SEDITOR_FONT_SIZES]` | 글자 크기 드롭다운 선택지 (px) |
73
+ | `colors?` | `SEditorColorOption[]` | `SEDITOR_DEFAULT_COLORS` | 글자색 팔레트 |
74
+ | `highlights?` | `SEditorColorOption[]` | `SEDITOR_DEFAULT_HIGHLIGHTS` | 형광펜(배경색) 팔레트 |
75
+ | `typography?` | `boolean` | `false` | 따옴표·하이픈·화살표 자동 치환 (`"` → `“”`, `--` → `—`, `->` → `→`). 상품 코드·규격 문자열이 입력한 그대로 남아야 하는 화면이 많아 기본은 끔이다. **마운트 시점에만 반영된다** — 값이 바뀌어도 이미 만들어진 에디터에는 적용되지 않는다. |
76
+ | `rules?` | `Rule[]` | — | 유효성 규칙 — blur 시 자동 검증 |
77
+ | `status?` | `SFieldStatus` | — | 필드 상태 ('default' | 'pass' | 'error') |
78
+ | `focused?` | `boolean` | — | 포커스 상태 (제어/반영) |
79
+ | `hovered?` | `boolean` | — | 호버 상태 (제어/반영) |
80
+ | `name?` | `string` | — | 폼 전송용 name |
81
+ | `editorClass?` | `string` | — | 편집 영역 className |
82
+ | `editorStyle?` | `CSSProperties` | — | 편집 영역 style |
83
+ | `label?` | `string` | — | |
84
+ | `labelWidth?` | `number \| string` | — | |
85
+ | `icon?` | `SIconName` | — | 레이블 영역 아이콘 |
86
+ | `iconColor?` | `SColor` | — | |
87
+ | `labelTooltip?` | `string` | — | 레이블 툴팁 텍스트 |
88
+ | `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 |
89
+ | `addonLabel?` | `string` | — | 우측 어드온 레이블 |
90
+ | `addonAlign?` | `SFieldAddonAlign` | — | 어드온 정렬 |
91
+ | `hint?` | `string` | — | |
92
+ | `error?` | `boolean` | — | |
93
+ | `errorMessage?` | `string` | — | |
94
+ | `width?` | `SFieldWidth` | `'100%'` | 컨트롤 너비 — 폭 등급(`'xs' | 'sm' | 'md' | 'lg' | 'xl'`) · 숫자=px · CSS 길이. 본문 길이에 상한이 없으므로 기본은 `"100%"`(행 전체)다. |
95
+ | `disabled?` | `boolean` | `false` | |
96
+ | `readOnly?` | `boolean` | `false` | |
97
+ | `className?` | `string` | — | |
98
+ | `style?` | `CSSProperties` | — | |
99
+
100
+ #### Events
101
+
102
+ | Event | Type | Description |
103
+ |-------|------|-------------|
104
+ | `onValueChange` | `(html: string) => void` | 값 변경 (sdUpdate) — 빈 문서면 빈 문자열을 준다 |
105
+ | `onImageUpload` | `(file: File) => Promise<string>` | 이미지 업로드 — 고른 파일을 저장하고 **표시할 URL 을 돌려준다.** 저장 위치는 앱마다 다르므로 DS 가 정하지 않는다. 이 훅이 없으면 툴바에서 이미지 항목이 빠진다 (본문에 base64 를 박지 않는다 — HTML 이 그대로 DB 로 실려 간다). |
106
+ | `onFocus` | `() => void` | 포커스 진입 |
107
+ | `onBlur` | `() => void` | 포커스 이탈 |
108
+
109
+ #### Methods (ref)
110
+
111
+ | Method | Type | Description |
112
+ |--------|------|-------------|
113
+ | `focus` | `() => void` | 편집 영역에 포커스 |
114
+ | `blur` | `() => void` | 포커스 해제 |
115
+ | `getHTML` | `() => string` | 현재 내용을 HTML 로 반환 (빈 문서면 빈 문자열) |
116
+ | `getText` | `() => string` | 현재 내용을 서식 없는 텍스트로 반환 |
117
+ | `setHTML` | `(html: string) => void` | 내용을 HTML 로 교체 (onValueChange 를 발생시키지 않는다) |
118
+ | `clear` | `() => void` | 내용을 비운다 |
119
+ | `editor` | `Editor \| null` | tiptap 에디터 인스턴스 — 확장 명령이 필요할 때만 쓴다 |
120
+
121
+ ## Types
122
+
123
+ ### TiptapApi
124
+
125
+ ```ts
126
+ /** 동적으로 불러온 tiptap — 이 객체를 거치지 않고는 에디터 코드가 tiptap 을 만지지 않는다. */
127
+ export interface TiptapApi {
128
+ useEditor: TiptapReact['useEditor'];
129
+ useEditorState: TiptapReact['useEditorState'];
130
+ EditorContent: TiptapReact['EditorContent'];
131
+ /** 선택 영역 위에 뜨는 판 — 자리는 floating-ui 가 잡는다 */
132
+ BubbleMenu: TiptapMenus['BubbleMenu'];
133
+ /** tiptap 확장 구성 — 아래 createExtensions 주석 참고 */
134
+ createExtensions: (options: SEditorExtensionOptions) => AnyExtension[];
135
+ }
136
+ ```
137
+
138
+ ### SEditorToolbarItem
139
+
140
+ ```ts
141
+ export type SEditorToolbarItem = SEditorToolbarAction | '|';
142
+ ```
143
+
144
+ ### SEditorColorOption
145
+
146
+ ```ts
147
+ export interface SEditorColorOption {
148
+ /** 팔레트 칸의 접근성 레이블·툴팁 */
149
+ label: string;
150
+ /** 팔레트 키(`red_75` …) 또는 CSS 색상 문자열 */
151
+ color: SColor;
152
+ }
153
+ ```
154
+
155
+ ### EditorToolbarState
156
+
157
+ ```ts
158
+ export type EditorToolbarState = ReturnType<typeof readEditorState>;
159
+ ```
160
+
161
+ ### SEditorExtensionOptions
162
+
163
+ ```ts
164
+ export interface SEditorExtensionOptions {
165
+ /** 빈 문서에 보일 문구를 그때그때 읽어 오는 게터 */
166
+ getPlaceholder: () => string;
167
+ /** 따옴표·하이픈·화살표 자동 치환 (Typography) */
168
+ typography: boolean;
169
+ }
170
+ ```
171
+
172
+ ### SEditorToolbarAction
173
+
174
+ ```ts
175
+ export type SEditorToolbarAction = (typeof SEDITOR_TOOLBAR_ITEMS)[number];
176
+ ```
177
+
178
+ ### SEDITOR_TOOLBAR_ITEMS
179
+
180
+ ```ts
181
+ /** 툴바에 놓을 수 있는 항목. `'|'` 는 구분선이다. */
182
+ export const SEDITOR_TOOLBAR_ITEMS = [
183
+ 'heading',
184
+ 'fontSize',
185
+ 'bold',
186
+ 'italic',
187
+ 'underline',
188
+ 'strike',
189
+ 'code',
190
+ 'color',
191
+ 'highlight',
192
+ 'superscript',
193
+ 'subscript',
194
+ 'alignLeft',
195
+ 'alignCenter',
196
+ 'alignRight',
197
+ 'alignJustify',
198
+ 'bulletList',
199
+ 'orderedList',
200
+ 'taskList',
201
+ 'list',
202
+ 'blockquote',
203
+ 'codeBlock',
204
+ 'horizontalRule',
205
+ 'link',
206
+ 'image',
207
+ 'undo',
208
+ 'redo',
209
+ ] as const;
210
+ ```
211
+
212
+ ## Dependencies
213
+
214
+ ### Depends on
215
+
216
+ - [SButton](../SButton)
217
+ - [SField](../SField)
218
+ - [SIcon](../SIcon)
219
+ - [SInput](../SInput)
220
+
221
+ ### Graph
222
+
223
+ ```mermaid
224
+ graph TD;
225
+ SEditor --> SButton
226
+ SEditor --> SField
227
+ SEditor --> SIcon
228
+ SEditor --> SInput
229
+ style SEditor fill:#f9f,stroke:#333,stroke-width:4px
230
+ ```
@@ -0,0 +1,124 @@
1
+ import { type CSSProperties } from 'react';
2
+ import type { Editor } from '@tiptap/core';
3
+ import { type SColor } from '../../lib/color';
4
+ import { type SFieldWidth } from '../../lib/field-width';
5
+ import { type Rule } from '../../lib/form';
6
+ import { type SFieldAddonAlign, type SFieldStatus } from '../SField';
7
+ import { type SIconName } from '../SIcon';
8
+ import { type STooltipProps } from '../STooltip';
9
+ import { type SEditorColorOption, type SEditorToolbarItem } from './editor.config';
10
+ /** ref 로 노출되는 조작 메서드 */
11
+ export interface SEditorHandle {
12
+ /** 편집 영역에 포커스 */
13
+ focus: () => void;
14
+ /** 포커스 해제 */
15
+ blur: () => void;
16
+ /** 현재 내용을 HTML 로 반환 (빈 문서면 빈 문자열) */
17
+ getHTML: () => string;
18
+ /** 현재 내용을 서식 없는 텍스트로 반환 */
19
+ getText: () => string;
20
+ /** 내용을 HTML 로 교체 (onValueChange 를 발생시키지 않는다) */
21
+ setHTML: (html: string) => void;
22
+ /** 내용을 비운다 */
23
+ clear: () => void;
24
+ /** tiptap 에디터 인스턴스 — 확장 명령이 필요할 때만 쓴다 */
25
+ editor: Editor | null;
26
+ }
27
+ export interface SEditorProps {
28
+ /** 값 (제어) — HTML 문자열 */
29
+ value?: string;
30
+ /** 초기값 (비제어) — HTML 문자열 */
31
+ defaultValue?: string;
32
+ /** 값 변경 (sdUpdate) — 빈 문서면 빈 문자열을 준다 */
33
+ onValueChange?: (html: string) => void;
34
+ /** 빈 문서에 보일 안내 문구 */
35
+ placeholder?: string;
36
+ /** 편집 영역 최소 높이 (숫자=px) */
37
+ minHeight?: number | string;
38
+ /** 편집 영역 최대 높이 (숫자=px). 넘으면 편집 영역 안에서만 스크롤한다 */
39
+ maxHeight?: number | string;
40
+ /** 툴바 구성. `false` 면 툴바 없이 본문만 (읽기 화면·간단 메모용) */
41
+ toolbar?: SEditorToolbarItem[] | false;
42
+ /**
43
+ * 글을 선택했을 때 그 위에 뜨는 서식 판의 구성. `false` 면 뜨지 않는다.
44
+ *
45
+ * 읽기 전용·비활성일 때는 어차피 뜨지 않는다. 좁은 칸에 놓인 에디터라면 판이 필드 밖으로
46
+ * 넘칠 수 있으니 항목을 줄이거나 `false` 로 끈다.
47
+ */
48
+ bubbleMenu?: SEditorToolbarItem[] | false;
49
+ /** 글자 크기 드롭다운 선택지 (px) */
50
+ fontSizes?: number[];
51
+ /** 글자색 팔레트 */
52
+ colors?: SEditorColorOption[];
53
+ /** 형광펜(배경색) 팔레트 */
54
+ highlights?: SEditorColorOption[];
55
+ /**
56
+ * 이미지 업로드 — 고른 파일을 저장하고 **표시할 URL 을 돌려준다.**
57
+ * 저장 위치는 앱마다 다르므로 DS 가 정하지 않는다. 이 훅이 없으면 툴바에서
58
+ * 이미지 항목이 빠진다 (본문에 base64 를 박지 않는다 — HTML 이 그대로 DB 로 실려 간다).
59
+ */
60
+ onImageUpload?: (file: File) => Promise<string>;
61
+ /**
62
+ * 따옴표·하이픈·화살표 자동 치환 (`"` → `“”`, `--` → `—`, `->` → `→`).
63
+ * 상품 코드·규격 문자열이 입력한 그대로 남아야 하는 화면이 많아 기본은 끔이다.
64
+ * **마운트 시점에만 반영된다** — 값이 바뀌어도 이미 만들어진 에디터에는 적용되지 않는다.
65
+ */
66
+ typography?: boolean;
67
+ /** 유효성 규칙 — blur 시 자동 검증 */
68
+ rules?: Rule[];
69
+ /** 필드 상태 ('default' | 'pass' | 'error') */
70
+ status?: SFieldStatus;
71
+ /** 포커스 상태 (제어/반영) */
72
+ focused?: boolean;
73
+ /** 호버 상태 (제어/반영) */
74
+ hovered?: boolean;
75
+ /** 폼 전송용 name */
76
+ name?: string;
77
+ /** 편집 영역 className */
78
+ editorClass?: string;
79
+ /** 편집 영역 style */
80
+ editorStyle?: CSSProperties;
81
+ /** 포커스 진입 */
82
+ onFocus?: () => void;
83
+ /** 포커스 이탈 */
84
+ onBlur?: () => void;
85
+ label?: string;
86
+ labelWidth?: number | string;
87
+ /** 레이블 영역 아이콘 */
88
+ icon?: SIconName;
89
+ iconColor?: SColor;
90
+ /** 레이블 툴팁 텍스트 */
91
+ labelTooltip?: string;
92
+ /** 레이블 툴팁 상세 옵션 */
93
+ labelTooltipProps?: Partial<STooltipProps>;
94
+ /** 우측 어드온 레이블 */
95
+ addonLabel?: string;
96
+ /** 어드온 정렬 */
97
+ addonAlign?: SFieldAddonAlign;
98
+ hint?: string;
99
+ error?: boolean;
100
+ errorMessage?: string;
101
+ /**
102
+ * 컨트롤 너비 — 폭 등급(`'xs' | 'sm' | 'md' | 'lg' | 'xl'`) · 숫자=px · CSS 길이.
103
+ * 본문 길이에 상한이 없으므로 기본은 `"100%"`(행 전체)다.
104
+ */
105
+ width?: SFieldWidth;
106
+ disabled?: boolean;
107
+ readOnly?: boolean;
108
+ className?: string;
109
+ style?: CSSProperties;
110
+ }
111
+ /**
112
+ * SEditor — tiptap 기반 리치 텍스트 에디터.
113
+ *
114
+ * 값은 **HTML 문자열**로 주고받는다. 들어온 HTML 은 tiptap 스키마가 파싱하므로 스키마에 없는
115
+ * 태그·속성(script·onerror …)은 그 자리에서 떨어져 나간다 — 별도 살균기를 거치지 않는다.
116
+ * 테두리 박스·라벨·에러 표시는 `SField`(multiline) 가 소유하고, 이 컴포넌트는 그 안에
117
+ * 툴바와 편집 영역만 세로로 쌓는다.
118
+ *
119
+ * tiptap 은 **마운트한 뒤에 불러온다** — 정적으로 묶으면 SEditor 를 한 번도 쓰지 않는 소비
120
+ * 앱까지 tiptap·prosemirror 를 번들에 지고 간다 (`tiptap-api.ts` 주석 참고). 불러오는 동안은
121
+ * 같은 크기의 빈 편집 영역이 자리를 지키므로 화면이 튀지 않고, 그 사이 `ref` 의 메서드는
122
+ * 아무 일도 하지 않는다 — `focus()` 만은 기억해 두었다가 준비되는 순간 흘려보낸다.
123
+ */
124
+ export declare const SEditor: import("react").ForwardRefExoticComponent<SEditorProps & import("react").RefAttributes<SEditorHandle>>;
@@ -0,0 +1,59 @@
1
+ import type { SVGProps } from 'react';
2
+ /**
3
+ * SEditor 서식 툴바 아이콘 (로컬 전용).
4
+ *
5
+ * 공용 아이콘 셋(`SIcon` / `icons.gen.tsx`)은 디자인팀 소유이고 서식(bold·italic·정렬·목록 …)
6
+ * 아이콘이 아직 없다. 여기 있는 것들은 그 자리를 메우는 임시 도형이며, 정식 아이콘이 셋에
7
+ * 들어오면 이 파일을 지우고 `SIcon` 으로 교체한다. **다른 컴포넌트에서 import 하지 않는다.**
8
+ *
9
+ * 도형은 tiptap Simple Editor 템플릿의 아이콘 셋을 그대로 옮겼다
10
+ * (ueberdosis/tiptap-ui-components, MIT © 2025 Tiptap — `apps/web/src/components/tiptap-icons`).
11
+ * 24×24 격자에 획 굵기 2 의 면(fill) 도형이고 색은 전부 `currentColor` 를 따른다 — 버튼이
12
+ * 토큰으로 정한 색이 그대로 내려온다. 새 아이콘을 더할 때도 이 격자·굵기를 지킨다.
13
+ *
14
+ * 템플릿에 없어 직접 그린 것은 `IconTextColor`·`IconHorizontalRule` 둘뿐이다 (아래 주석 참고).
15
+ */
16
+ export type SEditorIconProps = {
17
+ size?: number | string;
18
+ } & SVGProps<SVGSVGElement>;
19
+ /** 제목 — 지금 단계의 도형을 보여 준다 (본문이면 단계 없는 H) */
20
+ export declare const IconHeading: ({ level, ...p }: SEditorIconProps & {
21
+ level?: 0 | 1 | 2 | 3;
22
+ }) => import("react").JSX.Element;
23
+ export declare const IconBold: (p: SEditorIconProps) => import("react").JSX.Element;
24
+ export declare const IconItalic: (p: SEditorIconProps) => import("react").JSX.Element;
25
+ export declare const IconUnderline: (p: SEditorIconProps) => import("react").JSX.Element;
26
+ export declare const IconStrike: (p: SEditorIconProps) => import("react").JSX.Element;
27
+ /** 인라인 코드 */
28
+ export declare const IconCode: (p: SEditorIconProps) => import("react").JSX.Element;
29
+ export declare const IconCodeBlock: (p: SEditorIconProps) => import("react").JSX.Element;
30
+ export declare const IconBlockquote: (p: SEditorIconProps) => import("react").JSX.Element;
31
+ /** 형광펜 — 지금 고른 색은 툴바 버튼이 아이콘 아래 막대로 따로 보여 준다 */
32
+ export declare const IconHighlight: (p: SEditorIconProps) => import("react").JSX.Element;
33
+ export declare const IconSuperscript: (p: SEditorIconProps) => import("react").JSX.Element;
34
+ export declare const IconSubscript: (p: SEditorIconProps) => import("react").JSX.Element;
35
+ export declare const IconAlignLeft: (p: SEditorIconProps) => import("react").JSX.Element;
36
+ export declare const IconAlignCenter: (p: SEditorIconProps) => import("react").JSX.Element;
37
+ export declare const IconAlignRight: (p: SEditorIconProps) => import("react").JSX.Element;
38
+ export declare const IconAlignJustify: (p: SEditorIconProps) => import("react").JSX.Element;
39
+ export declare const IconBulletList: (p: SEditorIconProps) => import("react").JSX.Element;
40
+ export declare const IconOrderedList: (p: SEditorIconProps) => import("react").JSX.Element;
41
+ export declare const IconTaskList: (p: SEditorIconProps) => import("react").JSX.Element;
42
+ export declare const IconLink: (p: SEditorIconProps) => import("react").JSX.Element;
43
+ /** 좁은 화면 툴바의 하위 뷰에서 되돌아가기 */
44
+ export declare const IconArrowLeft: (p: SEditorIconProps) => import("react").JSX.Element;
45
+ export declare const IconUndo: (p: SEditorIconProps) => import("react").JSX.Element;
46
+ export declare const IconRedo: (p: SEditorIconProps) => import("react").JSX.Element;
47
+ /**
48
+ * 글자색 — 템플릿에 없어 직접 그렸다 (Simple Editor 에는 글자색 항목이 없다).
49
+ *
50
+ * 나머지 아이콘이 면 도형이라 A 도 같은 굵기(2)로 보이도록 획으로 긋고 끝을 둥글렸다 —
51
+ * 템플릿의 막대(`rx=1` 인 2px 사각형)와 같은 인상이다. 지금 고른 색은 형광펜과 마찬가지로
52
+ * 툴바 버튼이 아이콘 아래 막대로 보여 준다.
53
+ */
54
+ export declare const IconTextColor: (p: SEditorIconProps) => import("react").JSX.Element;
55
+ /**
56
+ * 구분선 — 템플릿에 없어 직접 그렸다 (Simple Editor 는 구분선 노드는 있지만 툴바 항목이 없다).
57
+ * 막대는 템플릿의 정렬 아이콘과 같은 규격(높이 2, `rx=1`)이다.
58
+ */
59
+ export declare const IconHorizontalRule: (p: SEditorIconProps) => import("react").JSX.Element;
@@ -0,0 +1,85 @@
1
+ import type { CSSProperties } from 'react';
2
+ import type { SColor } from '../../lib/color';
3
+ /** 툴바에 놓을 수 있는 항목. `'|'` 는 구분선이다. */
4
+ export declare const SEDITOR_TOOLBAR_ITEMS: readonly ["heading", "fontSize", "bold", "italic", "underline", "strike", "code", "color", "highlight", "superscript", "subscript", "alignLeft", "alignCenter", "alignRight", "alignJustify", "bulletList", "orderedList", "taskList", "list", "blockquote", "codeBlock", "horizontalRule", "link", "image", "undo", "redo"];
5
+ export type SEditorToolbarAction = (typeof SEDITOR_TOOLBAR_ITEMS)[number];
6
+ export type SEditorToolbarItem = SEditorToolbarAction | '|';
7
+ /**
8
+ * 기본 툴바 — tiptap Simple Editor 템플릿과 같은 순서다.
9
+ *
10
+ * 이력 → 블록(제목·목록·인용·코드블록) → 서식 → 첨자 → 정렬 → 삽입. 목록 셋은 `list`
11
+ * 드롭다운 하나로 묶여 있다(개별 버튼으로 펼치려면 `bulletList`·`orderedList`·`taskList`).
12
+ *
13
+ * 전체 항목(`SEDITOR_TOOLBAR_ITEMS`) 중 `fontSize`·`horizontalRule` 만 기본에서 빠져 있다 —
14
+ * 필요한 화면에서 `toolbar` 로 켠다. 글자색(`color`)은 템플릿에 없지만 공지·안내문에서
15
+ * 자주 쓰여 형광펜 옆에 함께 둔다.
16
+ *
17
+ * `image` 는 `onImageUpload` 를 받았을 때만 그려진다 (훅이 없으면 저장할 곳이 없다).
18
+ */
19
+ export declare const SEDITOR_DEFAULT_TOOLBAR: SEditorToolbarItem[];
20
+ /**
21
+ * 기본 버블 메뉴 — 글을 선택했을 때 그 위에 뜨는 판의 구성.
22
+ *
23
+ * tiptap Simple Editor 에는 버블 메뉴가 없다. 그래서 구성은 템플릿 툴바의 **서식 묶음**을
24
+ * 그대로 가져왔다 — 선택한 글에 바로 걸 수 있는 것만 남기고 블록(제목·목록·인용)·정렬·
25
+ * 삽입은 뺐다. 그것들은 커서만 있어도 되므로 막대에서 누르는 편이 낫다.
26
+ *
27
+ * 판은 선택 영역 위에 뜨는 한 줄이라 줄바꿈하지 않는다 — 항목을 늘릴 때 폭을 함께 본다.
28
+ */
29
+ export declare const SEDITOR_DEFAULT_BUBBLE_MENU: SEditorToolbarItem[];
30
+ /** 제목 단계 — 본문 12px 위로 14 / 16 / 18 (DS 타이포 heading sm·md·lg) */
31
+ export declare const SEDITOR_HEADING_LEVELS: readonly [1, 2, 3];
32
+ export type SEditorHeadingLevel = (typeof SEDITOR_HEADING_LEVELS)[number];
33
+ export declare const SEDITOR_HEADING_LABELS: Record<SEditorHeadingLevel | 0, string>;
34
+ /**
35
+ * 글자 크기 선택지 (px). DS 타이포 스케일(`--text-*`)에서 본문에 쓰이는 단계만 추렸다.
36
+ * 이 서비스는 정보 밀도가 높아 본문이 12px 다 (AGENTS.md §2-1).
37
+ */
38
+ export declare const SEDITOR_FONT_SIZES: readonly [11, 12, 14, 16, 18];
39
+ /** 크기를 지정하지 않은 문단이 실제로 보이는 크기 — 드롭다운의 선택 표시 기준이다. */
40
+ export declare const SEDITOR_DEFAULT_FONT_SIZE = 12;
41
+ export interface SEditorColorOption {
42
+ /** 팔레트 칸의 접근성 레이블·툴팁 */
43
+ label: string;
44
+ /** 팔레트 키(`red_75` …) 또는 CSS 색상 문자열 */
45
+ color: SColor;
46
+ }
47
+ /**
48
+ * 기본 글자색 팔레트 — 역할 토큰(`--color-fg-*`)을 그대로 쓴다.
49
+ *
50
+ * 저장되는 HTML 에 `style="color: var(--color-fg-danger)"` 형태로 남으므로 토큰이 바뀌면
51
+ * 이미 저장된 글도 따라간다. 대신 **DS `theme.css` 가 없는 환경(메일 본문 등)으로 그대로
52
+ * 내보내면 색이 풀린다** — 그런 용도라면 `colors` 에 hex 를 직접 넘긴다.
53
+ */
54
+ export declare const SEDITOR_DEFAULT_COLORS: SEditorColorOption[];
55
+ /** 기본 형광펜 팔레트 — 글자가 그 위에서 읽혀야 하므로 팔레트의 밝은 단계만 쓴다. */
56
+ export declare const SEDITOR_DEFAULT_HIGHLIGHTS: SEditorColorOption[];
57
+ /** ProseMirror 가 만드는 요소에 붙는 클래스 — 자식 선택자의 기준점이 된다. */
58
+ export declare const TASK_LIST_CLASS = "sd-editor-task-list";
59
+ export declare const TASK_ITEM_CLASS = "sd-editor-task-item";
60
+ export declare const IMAGE_CLASS = "sd-editor-image";
61
+ export interface SEditorExtensionOptions {
62
+ /** 빈 문서에 보일 문구를 그때그때 읽어 오는 게터 */
63
+ getPlaceholder: () => string;
64
+ /** 따옴표·하이픈·화살표 자동 치환 (Typography) */
65
+ typography: boolean;
66
+ }
67
+ /**
68
+ * 편집 영역 안쪽 서식 스타일.
69
+ *
70
+ * ProseMirror 가 만드는 자식 요소(h1·ul·blockquote …)는 JSX 에 없어 클래스를 달 수 없고,
71
+ * Tailwind preflight 가 목록·제목의 기본 스타일을 지워 버린다. 이 패키지에는 컴포넌트 CSS
72
+ * 파일이 없으므로 arbitrary variant 로 자식 선택자를 직접 쓴다.
73
+ */
74
+ export declare const SEDITOR_CONTENT_CLASS: string;
75
+ export interface SEditorContentStyleOptions {
76
+ minHeight?: number | string;
77
+ maxHeight?: number | string;
78
+ disabled?: boolean;
79
+ }
80
+ /**
81
+ * 편집 영역(그리고 엔진을 불러오는 동안 그 자리를 대신하는 빈 영역)의 상자·타이포.
82
+ *
83
+ * 두 곳이 같은 값을 써야 로딩이 끝나는 순간 글이 튀지 않는다.
84
+ */
85
+ export declare const editorContentStyle: ({ minHeight, maxHeight, disabled, }: SEditorContentStyleOptions) => CSSProperties;
@@ -0,0 +1,2 @@
1
+ export { SEditor, type SEditorProps, type SEditorHandle } from './SEditor';
2
+ export { SEDITOR_TOOLBAR_ITEMS, SEDITOR_DEFAULT_TOOLBAR, SEDITOR_DEFAULT_BUBBLE_MENU, SEDITOR_HEADING_LEVELS, SEDITOR_HEADING_LABELS, SEDITOR_FONT_SIZES, SEDITOR_DEFAULT_FONT_SIZE, SEDITOR_DEFAULT_COLORS, SEDITOR_DEFAULT_HIGHLIGHTS, type SEditorToolbarAction, type SEditorToolbarItem, type SEditorHeadingLevel, type SEditorColorOption, } from './editor.config';
@@ -0,0 +1,29 @@
1
+ import type { AnyExtension } from '@tiptap/core';
2
+ import { type SEditorExtensionOptions } from './editor.config';
3
+ type TiptapReact = typeof import('@tiptap/react');
4
+ type TiptapMenus = typeof import('@tiptap/react/menus');
5
+ /** 동적으로 불러온 tiptap — 이 객체를 거치지 않고는 에디터 코드가 tiptap 을 만지지 않는다. */
6
+ export interface TiptapApi {
7
+ useEditor: TiptapReact['useEditor'];
8
+ useEditorState: TiptapReact['useEditorState'];
9
+ EditorContent: TiptapReact['EditorContent'];
10
+ /** 선택 영역 위에 뜨는 판 — 자리는 floating-ui 가 잡는다 */
11
+ BubbleMenu: TiptapMenus['BubbleMenu'];
12
+ /** tiptap 확장 구성 — 아래 createExtensions 주석 참고 */
13
+ createExtensions: (options: SEditorExtensionOptions) => AnyExtension[];
14
+ }
15
+ /**
16
+ * tiptap 을 불러온다 (이미 불러왔으면 같은 약속을 돌려준다).
17
+ *
18
+ * 실패하면 캐시를 비워 다음 마운트가 다시 시도하게 한다 — 잠깐의 네트워크 문제로
19
+ * 그 세션 내내 에디터가 뜨지 않는 일을 막는다.
20
+ */
21
+ export declare const loadTiptapApi: () => Promise<TiptapApi>;
22
+ /**
23
+ * 불러온 tiptap. 아직 준비되지 않았으면 `null`.
24
+ *
25
+ * 두 번째 마운트부터는 첫 렌더에 바로 값이 있어 빈 자리가 보이지 않는다.
26
+ * 서버 렌더에서는 언제나 `null` 이라 하이드레이션이 어긋나지 않는다.
27
+ */
28
+ export declare const useTiptapApi: () => TiptapApi | null;
29
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 좁은 화면인가 (SEditor 전용 — 다른 컴포넌트에서 import 하지 않는다).
3
+ *
4
+ * 이 DS 에는 브레이크포인트 개념이 없다. 여기에 필요한 이유는 하나뿐이라서 — 손가락으로
5
+ * 쓰는 좁은 화면에서는 툴바 위에 뜨는 팝오버(형광펜 팔레트·링크 입력)가 화면 밖으로
6
+ * 밀리거나 소프트 키보드에 가린다 — 공용 `lib/` 로 올리지 않고 이 폴더에 둔다. 나중에
7
+ * DS 차원의 브레이크포인트가 생기면 그걸로 갈아끼운다.
8
+ *
9
+ * **뷰포트 폭**을 본다. 필드 자신의 폭이 아니다 — 넓은 화면에서 좁은 칸에 놓인 에디터는
10
+ * 팝오버를 띄울 자리가 옆에 얼마든지 있으므로 하위 뷰로 바꿀 이유가 없다.
11
+ *
12
+ * 서버 렌더와 첫 렌더에서는 언제나 `false` 다 (하이드레이션이 어긋나지 않게).
13
+ */
14
+ export declare const useIsMobile: () => boolean;
@@ -31,6 +31,42 @@
31
31
  |-------|------|-------------|
32
32
  | `onToggle` | `(expanded: boolean, event: MouseEvent<HTMLButtonElement>) => void` | |
33
33
 
34
+ ## Types
35
+
36
+ ### SExpansionItemSupportingTextPosition
37
+
38
+ ```ts
39
+ export type SExpansionItemSupportingTextPosition = 'right' | 'bottom';
40
+ ```
41
+
42
+ ### SExpansionItemRenderProp
43
+
44
+ ```ts
45
+ export type SExpansionItemRenderProp = (state: SExpansionItemRenderState) => ReactNode;
46
+ ```
47
+
48
+ ### SExpansionItemInteraction
49
+
50
+ ```ts
51
+ export type SExpansionItemInteraction = 'chevron';
52
+ ```
53
+
54
+ ### SExpansionItemSize
55
+
56
+ ```ts
57
+ export type SExpansionItemSize = 'sm' | 'md';
58
+ ```
59
+
60
+ ### SExpansionItemRenderState
61
+
62
+ ```ts
63
+ export interface SExpansionItemRenderState {
64
+ expanded: boolean;
65
+ selected: boolean;
66
+ disabled: boolean;
67
+ }
68
+ ```
69
+
34
70
  ## Dependencies
35
71
 
36
72
  ### Used by
@@ -28,8 +28,9 @@
28
28
  | `hint?` | `string` | `''` | 하단 힌트 |
29
29
  | `disabled?` | `boolean` | `false` | 비활성 |
30
30
  | `readOnly?` | `boolean` | `false` | 읽기 전용 (회색 배경) |
31
- | `width?` | `number \| string` | — | 컨트롤 너비 (숫자=px). 지정하면 필드가 부모 폭을 다 먹지 않고 (레이블 + width) 만큼만 차지한다. 다른 요소와 나란히 놓으려면 부모를 flex 로 두면 된다. |
32
- | `minWidth?` | `number \| string` | — | 컨트롤 최소 너비 (숫자=px). 하한선만 지정하며 필드는 계속 부모 폭을 채운다 |
31
+ | `width?` | `SFieldWidth` | — | 컨트롤 너비. 지정하면 필드가 부모 폭을 다 먹지 않고 (레이블 + width) 만큼만 차지한다. 다른 요소와 나란히 놓으려면 부모를 flex 로 두면 된다. **폭 등급(`'xs' | 'sm' | 'md' | 'lg' | 'xl'`)으로 준다** — `--cmp-field-width-*` 토큰으로 풀리므로 토큰이 바뀌면 화면이 따라간다. 등급은 `maxLength`(= 스키마 상한)로 고르고, 상한이 `xl` 을 넘거나 상한이 없으면 `"100%"` 로 둔다. (`sellmate/field-width-grade` 가 검사한다) 숫자는 px, 그 밖의 문자열은 CSS 길이 그대로다. |
32
+ | `minWidth?` | `SFieldWidth` | — | 컨트롤 최소 너비 (등급 · 숫자=px · CSS 길이). 하한선만 지정하며 필드는 계속 부모 폭을 채운다 |
33
+ | `maxWidth?` | `SFieldWidth` | — | 컨트롤 최대 너비 (등급 · 숫자=px · CSS 길이). 상한선만 지정하며 필드는 그 아래에서 부모 폭을 채운다. `width` 와 달리 hug 로 전환하지 않는다 — 부모가 좁으면 같이 좁아지고, 넓어도 여기서 멈춘다. 값 길이가 정해진 컨트롤(날짜·시간)이 `width="100%"` 를 받아 행 전체로 늘어나는 것을 막는 데 쓴다. **라벨은 상한에 들어가지 않는다** — 라벨은 컨트롤의 형제라 이 상한 밖이다. `addonLabel` 은 테두리 박스 안이라 상한을 나눠 먹으므로, `labelWidth`(= addon 폭)만큼 상한을 자동으로 늘린다. addon 이 있는데 `labelWidth` 가 없으면 폭을 알 수 없어 상한을 걸지 않는다 — 컨트롤이 잘리는 것보다 넓은 편이 낫다. |
33
34
  | `multiline?` | `boolean` | `false` | 멀티라인(textarea) — 컨트롤 높이를 고정하지 않고 min-height만 적용 |
34
35
  | `borderless?` | `boolean` | `false` | 테두리 박스 제거 (inline 컨트롤용) — border/배경/hover·focus 강조만 사라지고 label·hint·errorMessage 등 나머지 필드 구성은 그대로 동작한다. |
35
36
  | `children?` | `ReactNode` | — | 실제 컨트롤 (input/select 등) — 테두리 없이 렌더, 테두리는 SField가 제공 |
@@ -49,6 +50,26 @@
49
50
  |--------|------|-------------|
50
51
  | `focus` | `() => void` | 내부 컨트롤에 포커스하고 필드를 화면에 스크롤합니다. |
51
52
 
53
+ ## Types
54
+
55
+ ### SFieldSize
56
+
57
+ ```ts
58
+ export type SFieldSize = 'sm' | 'md';
59
+ ```
60
+
61
+ ### SFieldAddonAlign
62
+
63
+ ```ts
64
+ export type SFieldAddonAlign = 'start' | 'center' | 'end';
65
+ ```
66
+
67
+ ### SFieldStatus
68
+
69
+ ```ts
70
+ export type SFieldStatus = 'default' | 'pass' | 'error';
71
+ ```
72
+
52
73
  ## Dependencies
53
74
 
54
75
  ### Used by
@@ -57,9 +78,11 @@
57
78
  - [SChipInput](../SChipInput)
58
79
  - [SDatePicker](../SDatePicker)
59
80
  - [SDateRangePicker](../SDateRangePicker)
81
+ - [SEditor](../SEditor)
60
82
  - [SFilePicker](../SFilePicker)
61
83
  - [SInput](../SInput)
62
84
  - [SNumberInput](../SNumberInput)
85
+ - [SSearchInput](../SSearchInput)
63
86
  - [SSelect](../SSelect)
64
87
  - [STextarea](../STextarea)
65
88
  - [STimePicker](../STimePicker)
@@ -80,9 +103,11 @@ graph TD;
80
103
  SChipInput --> SField
81
104
  SDatePicker --> SField
82
105
  SDateRangePicker --> SField
106
+ SEditor --> SField
83
107
  SFilePicker --> SField
84
108
  SInput --> SField
85
109
  SNumberInput --> SField
110
+ SSearchInput --> SField
86
111
  SSelect --> SField
87
112
  STextarea --> SField
88
113
  STimePicker --> SField