@simplysm/sd-claude 14.0.42 → 14.0.43
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/claude/references/sd-simplysm14/angular/docs/directives.md +74 -3
- package/claude/references/sd-simplysm14/angular/docs/features.md +64 -14
- package/claude/references/sd-simplysm14/angular/docs/plugins.md +2 -90
- package/claude/references/sd-simplysm14/angular/docs/providers.md +2 -2
- package/claude/references/sd-simplysm14/angular/docs/type-utilities.md +1 -2
- package/claude/references/sd-simplysm14/angular/docs/ui-data.md +103 -23
- package/claude/references/sd-simplysm14/angular/docs/ui-form.md +173 -28
- package/claude/references/sd-simplysm14/angular/docs/ui-layout.md +19 -4
- package/claude/references/sd-simplysm14/angular/docs/ui-navigation.md +20 -2
- package/claude/references/sd-simplysm14/angular/docs/ui-overlay.md +23 -14
- package/claude/references/sd-simplysm14/angular/docs/ui-visual.md +15 -7
- package/claude/references/sd-simplysm14/angular/docs/utils.md +1 -1
- package/claude/references/sd-simplysm14/angular/usage.md +16 -15
- package/claude/references/sd-simplysm14/capacitor-plugin-auto-update/usage.md +1 -1
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/file-operations.md +154 -0
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/permissions.md +84 -0
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/storage-paths.md +107 -0
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/types.md +83 -0
- package/claude/references/sd-simplysm14/capacitor-plugin-file-system/usage.md +83 -128
- package/claude/references/sd-simplysm14/capacitor-plugin-usb-storage/usage.md +99 -1
- package/claude/references/sd-simplysm14/core-node/docs/child-process.md +182 -0
- package/claude/references/sd-simplysm14/core-node/docs/features.md +1 -1
- package/claude/references/sd-simplysm14/core-node/docs/file-system.md +509 -0
- package/claude/references/sd-simplysm14/core-node/docs/file-watching.md +139 -0
- package/claude/references/sd-simplysm14/core-node/docs/logging.md +180 -0
- package/claude/references/sd-simplysm14/core-node/docs/path.md +176 -0
- package/claude/references/sd-simplysm14/core-node/docs/worker-threads.md +334 -0
- package/claude/references/sd-simplysm14/core-node/usage.md +192 -96
- package/claude/references/sd-simplysm14/excel/docs/core-classes.md +33 -14
- package/claude/references/sd-simplysm14/excel/usage.md +47 -45
- package/claude/references/sd-simplysm14/lint/usage.md +3 -2
- package/claude/references/sd-simplysm14/orm-common/docs/queryable-executable.md +30 -35
- package/claude/references/sd-simplysm14/orm-common/usage.md +9 -8
- package/claude/references/sd-simplysm14/sd-claude/docs/assets.md +43 -34
- package/claude/references/sd-simplysm14/sd-claude/docs/cli.md +1 -1
- package/claude/references/sd-simplysm14/sd-claude/docs/hooks.md +20 -2
- package/claude/references/sd-simplysm14/sd-claude/docs/scripts.md +5 -18
- package/claude/references/sd-simplysm14/sd-claude/usage.md +6 -5
- package/claude/references/sd-simplysm14/sd-cli/usage.md +176 -1
- package/claude/references/sd-simplysm14/service-client/usage.md +126 -61
- package/claude/references/sd-simplysm14/service-common/usage.md +28 -28
- package/claude/references/sd-simplysm14/storage/usage.md +123 -30
- package/claude/references/sd-testing.md +100 -4
- package/claude/rules/sd-claude-rules.md +19 -4
- package/claude/sd-check-write.py +1 -1
- package/claude/skills/sd-check/SKILL.md +7 -4
- package/claude/skills/sd-claude-docs/SKILL.md +7 -4
- package/claude/skills/sd-claude-docs/references/package-doc-gen.md +30 -7
- package/claude/skills/sd-commit/SKILL.md +2 -0
- package/claude/skills/sd-debug/SKILL.md +1 -1
- package/claude/skills/sd-deliverable/SKILL.md +2 -0
- package/claude/skills/sd-dev/SKILL.md +1 -1
- package/claude/skills/sd-doc-extract/SKILL.md +2 -0
- package/claude/{references/sd-debug.md → skills/sd-inner-debug/SKILL.md} +16 -20
- package/claude/{references/sd-review.md → skills/sd-inner-review/SKILL.md} +9 -4
- package/claude/skills/sd-issue/SKILL.md +2 -0
- package/claude/skills/sd-outlook/SKILL.md +2 -0
- package/claude/skills/sd-plan/SKILL.md +1 -1
- package/claude/skills/sd-prompt/SKILL.md +2 -2
- package/claude/skills/sd-refactor/SKILL.md +2 -2
- package/claude/skills/sd-review/SKILL.md +1 -1
- package/claude/skills/sd-tdd/SKILL.md +7 -7
- package/claude/skills/sd-use/SKILL.md +2 -0
- package/claude/skills/sd-wbs/SKILL.md +41 -18
- package/package.json +1 -1
- /package/claude/{rules → references}/sd-simplysm14.md +0 -0
- /package/claude/{references → rules}/sd-clarify.md +0 -0
|
@@ -9,19 +9,29 @@
|
|
|
9
9
|
```typescript
|
|
10
10
|
@Component({ selector: "sd-button" })
|
|
11
11
|
class SdButton {
|
|
12
|
+
type = input<"button" | "submit">("button");
|
|
13
|
+
theme = input<"primary" | "secondary" | "info" | ... | "link" | "link-primary" | ... | "link-rev">();
|
|
12
14
|
inline = input(false, { transform: booleanAttribute });
|
|
13
15
|
inset = input(false, { transform: booleanAttribute });
|
|
16
|
+
size = input<"sm" | "lg">();
|
|
14
17
|
disabled = input(false, { transform: booleanAttribute });
|
|
18
|
+
buttonStyle = input<string>();
|
|
19
|
+
buttonClass = input<string>();
|
|
15
20
|
}
|
|
16
21
|
```
|
|
17
22
|
|
|
18
23
|
| Input | Type | Default | Description |
|
|
19
24
|
|-------|------|---------|-------------|
|
|
25
|
+
| `type` | `"button" \| "submit"` | `"button"` | 버튼 HTML 타입 |
|
|
26
|
+
| `theme` | `string \| undefined` | `undefined` | 테마 (primary, secondary, info, success, warning, danger, gray, blue-gray, link, link-primary, link-secondary, link-info, link-success, link-warning, link-danger, link-gray, link-blue-gray, link-rev) |
|
|
20
27
|
| `inline` | `boolean` | `false` | 인라인 표시 |
|
|
21
28
|
| `inset` | `boolean` | `false` | 테두리 없는 삽입 스타일 |
|
|
29
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
22
30
|
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
31
|
+
| `buttonStyle` | `string \| undefined` | `undefined` | 버튼 인라인 스타일 |
|
|
32
|
+
| `buttonClass` | `string \| undefined` | `undefined` | 버튼 CSS 클래스 |
|
|
23
33
|
|
|
24
|
-
호스트 속성: `data-sd-theme`, `data-sd-size`, `data-sd-disabled`
|
|
34
|
+
호스트 속성: `data-sd-theme`, `data-sd-inline`, `data-sd-size`, `data-sd-inset`, `data-sd-disabled`
|
|
25
35
|
|
|
26
36
|
### `SdAnchor`
|
|
27
37
|
|
|
@@ -31,9 +41,15 @@ class SdButton {
|
|
|
31
41
|
@Component({ selector: "sd-anchor" })
|
|
32
42
|
class SdAnchor {
|
|
33
43
|
disabled = input(false, { transform: booleanAttribute });
|
|
44
|
+
theme = input<"primary" | "secondary" | "info" | "success" | "warning" | "danger" | "gray" | "blue-gray">("primary");
|
|
34
45
|
}
|
|
35
46
|
```
|
|
36
47
|
|
|
48
|
+
| Input | Type | Default | Description |
|
|
49
|
+
|-------|------|---------|-------------|
|
|
50
|
+
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
51
|
+
| `theme` | `string` | `"primary"` | 테마 색상 |
|
|
52
|
+
|
|
37
53
|
### `SdAdditionalButton`
|
|
38
54
|
|
|
39
55
|
추가 동작 버튼. 드롭다운 포함.
|
|
@@ -41,6 +57,7 @@ class SdAnchor {
|
|
|
41
57
|
```typescript
|
|
42
58
|
@Component({ selector: "sd-additional-button" })
|
|
43
59
|
class SdAdditionalButton {
|
|
60
|
+
size = input<"sm" | "lg">();
|
|
44
61
|
inset = input(false, { transform: booleanAttribute });
|
|
45
62
|
}
|
|
46
63
|
```
|
|
@@ -51,28 +68,32 @@ class SdAdditionalButton {
|
|
|
51
68
|
|
|
52
69
|
```typescript
|
|
53
70
|
@Component({ selector: "sd-modal-select-button" })
|
|
54
|
-
class SdModalSelectButton<T
|
|
71
|
+
class SdModalSelectButton<T extends object, K, M extends keyof SelectModeValue<K>> {
|
|
55
72
|
modal = input.required<SdSelectModalInfo<SdSelectModal<T>>>();
|
|
56
|
-
value = model<SelectModeValue<
|
|
73
|
+
value = model<SelectModeValue<K>[M]>();
|
|
74
|
+
selectedItems = model<T[]>([]);
|
|
57
75
|
disabled = input(false, { transform: booleanAttribute });
|
|
58
76
|
required = input(false, { transform: booleanAttribute });
|
|
59
77
|
inset = input(false, { transform: booleanAttribute });
|
|
60
|
-
|
|
61
|
-
|
|
78
|
+
size = input<"sm" | "lg">();
|
|
79
|
+
selectMode = input<M>("single" as M);
|
|
62
80
|
modalOptions = input<SdModalOptions>();
|
|
81
|
+
searchIcon = input(tablerSearch);
|
|
63
82
|
}
|
|
64
83
|
```
|
|
65
84
|
|
|
66
85
|
| Input | Type | Default | Description |
|
|
67
86
|
|-------|------|---------|-------------|
|
|
68
87
|
| `modal` | `SdSelectModalInfo<...>` | required | 모달 정보 |
|
|
69
|
-
| `value` | `
|
|
88
|
+
| `value` | `SelectModeValue<K>[M]` | - | 선택된 값 (two-way) |
|
|
89
|
+
| `selectedItems` | `T[]` | `[]` | 선택된 항목 객체 배열 (two-way) |
|
|
70
90
|
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
71
91
|
| `required` | `boolean` | `false` | 필수 (지우기 버튼 숨김) |
|
|
72
92
|
| `inset` | `boolean` | `false` | 삽입 스타일 |
|
|
73
|
-
| `
|
|
93
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
94
|
+
| `selectMode` | `M` | `"single"` | 선택 모드 |
|
|
95
|
+
| `modalOptions` | `SdModalOptions \| undefined` | `undefined` | 모달 옵션 |
|
|
74
96
|
| `searchIcon` | `string` | `tablerSearch` | 검색 아이콘 |
|
|
75
|
-
| `modalOptions` | `SdModalOptions \| undefined` | - | 모달 옵션 |
|
|
76
97
|
|
|
77
98
|
## Inputs
|
|
78
99
|
|
|
@@ -83,20 +104,30 @@ class SdModalSelectButton<T> {
|
|
|
83
104
|
```typescript
|
|
84
105
|
@Component({ selector: "sd-textfield" })
|
|
85
106
|
class SdTextfield<K extends keyof SdTextfieldTypes> {
|
|
107
|
+
value = model<SdTextfieldTypes[K]>();
|
|
86
108
|
type = input.required<K>();
|
|
87
|
-
|
|
109
|
+
placeholder = input<string>();
|
|
110
|
+
title = input<string>();
|
|
111
|
+
inputStyle = input<string>();
|
|
112
|
+
inputClass = input<string>();
|
|
88
113
|
disabled = input(false, { transform: booleanAttribute });
|
|
89
114
|
readonly = input(false, { transform: booleanAttribute });
|
|
90
115
|
required = input(false, { transform: booleanAttribute });
|
|
91
|
-
useNumberComma = input(true, { transform: booleanAttribute });
|
|
92
|
-
inline = input(false, { transform: booleanAttribute });
|
|
93
|
-
inset = input(false, { transform: booleanAttribute });
|
|
94
|
-
placeholder = input<string>();
|
|
95
|
-
format = input<string>();
|
|
96
116
|
min = input<SdTextfieldTypes[K]>();
|
|
97
117
|
max = input<SdTextfieldTypes[K]>();
|
|
118
|
+
minlength = input<number>();
|
|
119
|
+
maxlength = input<number>();
|
|
120
|
+
pattern = input<string>();
|
|
121
|
+
validatorFn = input<(value: SdTextfieldTypes[K] | undefined) => string | undefined>();
|
|
122
|
+
format = input<string>();
|
|
98
123
|
step = input<number>();
|
|
124
|
+
autocomplete = input<string>();
|
|
125
|
+
useNumberComma = input(true, { transform: booleanAttribute });
|
|
126
|
+
minDigits = input<number>();
|
|
127
|
+
inline = input(false, { transform: booleanAttribute });
|
|
128
|
+
inset = input(false, { transform: booleanAttribute });
|
|
99
129
|
size = input<"sm" | "lg">();
|
|
130
|
+
theme = input<string>();
|
|
100
131
|
}
|
|
101
132
|
```
|
|
102
133
|
|
|
@@ -104,13 +135,28 @@ class SdTextfield<K extends keyof SdTextfieldTypes> {
|
|
|
104
135
|
|-------|------|---------|-------------|
|
|
105
136
|
| `type` | `keyof SdTextfieldTypes` | required | 입력 타입 (number, text, password, color, email, format, date, month, year, datetime, datetime-sec, time, time-sec) |
|
|
106
137
|
| `value` | `SdTextfieldTypes[K] \| undefined` | - | 값 (two-way) |
|
|
138
|
+
| `placeholder` | `string \| undefined` | `undefined` | 플레이스홀더 |
|
|
139
|
+
| `title` | `string \| undefined` | `undefined` | title 속성 (없으면 placeholder 사용) |
|
|
140
|
+
| `inputStyle` | `string \| undefined` | `undefined` | input 인라인 스타일 |
|
|
141
|
+
| `inputClass` | `string \| undefined` | `undefined` | input CSS 클래스 |
|
|
107
142
|
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
108
143
|
| `readonly` | `boolean` | `false` | 읽기 전용 |
|
|
109
144
|
| `required` | `boolean` | `false` | 필수 |
|
|
145
|
+
| `min` | `SdTextfieldTypes[K] \| undefined` | `undefined` | 최소값 |
|
|
146
|
+
| `max` | `SdTextfieldTypes[K] \| undefined` | `undefined` | 최대값 |
|
|
147
|
+
| `minlength` | `number \| undefined` | `undefined` | 최소 길이 |
|
|
148
|
+
| `maxlength` | `number \| undefined` | `undefined` | 최대 길이 |
|
|
149
|
+
| `pattern` | `string \| undefined` | `undefined` | 입력 패턴 (정규식) |
|
|
150
|
+
| `validatorFn` | `((value) => string \| undefined) \| undefined` | `undefined` | 커스텀 유효성 검증 함수 (에러 메시지 반환) |
|
|
151
|
+
| `format` | `string \| undefined` | `undefined` | format 타입에서 사용할 포맷 문자열 |
|
|
152
|
+
| `step` | `number \| undefined` | `undefined` | 증감 단위 |
|
|
153
|
+
| `autocomplete` | `string \| undefined` | `undefined` | autocomplete 속성 |
|
|
110
154
|
| `useNumberComma` | `boolean` | `true` | number 타입에서 천 단위 쉼표 사용 |
|
|
155
|
+
| `minDigits` | `number \| undefined` | `undefined` | number 타입 최소 자릿수 |
|
|
111
156
|
| `inline` | `boolean` | `false` | 인라인 표시 |
|
|
112
157
|
| `inset` | `boolean` | `false` | 삽입 스타일 |
|
|
113
|
-
| `
|
|
158
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
159
|
+
| `theme` | `string \| undefined` | `undefined` | 테마 |
|
|
114
160
|
|
|
115
161
|
### `SdTextarea`
|
|
116
162
|
|
|
@@ -120,11 +166,19 @@ class SdTextfield<K extends keyof SdTextfieldTypes> {
|
|
|
120
166
|
@Component({ selector: "sd-textarea" })
|
|
121
167
|
class SdTextarea {
|
|
122
168
|
value = model<string>();
|
|
169
|
+
placeholder = input<string>();
|
|
170
|
+
title = input<string>();
|
|
171
|
+
minRows = input<number>(1);
|
|
123
172
|
disabled = input(false, { transform: booleanAttribute });
|
|
124
173
|
readonly = input(false, { transform: booleanAttribute });
|
|
125
174
|
required = input(false, { transform: booleanAttribute });
|
|
126
175
|
inline = input(false, { transform: booleanAttribute });
|
|
127
176
|
inset = input(false, { transform: booleanAttribute });
|
|
177
|
+
size = input<"sm" | "lg">();
|
|
178
|
+
validatorFn = input<(value: string | undefined) => string | undefined>();
|
|
179
|
+
theme = input<string>();
|
|
180
|
+
inputStyle = input<string>();
|
|
181
|
+
inputClass = input<string>();
|
|
128
182
|
}
|
|
129
183
|
```
|
|
130
184
|
|
|
@@ -135,14 +189,30 @@ class SdTextarea {
|
|
|
135
189
|
```typescript
|
|
136
190
|
@Component({ selector: "sd-numpad" })
|
|
137
191
|
class SdNumpad {
|
|
138
|
-
|
|
192
|
+
placeholder = input<string>();
|
|
193
|
+
value = model<number>();
|
|
139
194
|
required = input(false, { transform: booleanAttribute });
|
|
140
195
|
inputDisabled = input(false, { transform: booleanAttribute });
|
|
141
196
|
useEnterButton = input(false, { transform: booleanAttribute });
|
|
142
197
|
useMinusButton = input(false, { transform: booleanAttribute });
|
|
198
|
+
|
|
199
|
+
enterButtonClick = output();
|
|
143
200
|
}
|
|
144
201
|
```
|
|
145
202
|
|
|
203
|
+
| Input | Type | Default | Description |
|
|
204
|
+
|-------|------|---------|-------------|
|
|
205
|
+
| `placeholder` | `string \| undefined` | `undefined` | 플레이스홀더 |
|
|
206
|
+
| `value` | `number \| undefined` | - | 값 (two-way) |
|
|
207
|
+
| `required` | `boolean` | `false` | 필수 |
|
|
208
|
+
| `inputDisabled` | `boolean` | `false` | 입력 필드 비활성화 |
|
|
209
|
+
| `useEnterButton` | `boolean` | `false` | 엔터 버튼 표시 |
|
|
210
|
+
| `useMinusButton` | `boolean` | `false` | 마이너스 버튼 표시 |
|
|
211
|
+
|
|
212
|
+
| Output | Type | Description |
|
|
213
|
+
|--------|------|-------------|
|
|
214
|
+
| `enterButtonClick` | `void` | 엔터 버튼 클릭 시 발생 |
|
|
215
|
+
|
|
146
216
|
### `SdRange`
|
|
147
217
|
|
|
148
218
|
범위 슬라이더 컴포넌트.
|
|
@@ -151,8 +221,9 @@ class SdNumpad {
|
|
|
151
221
|
@Component({ selector: "sd-range" })
|
|
152
222
|
class SdRange<K extends keyof SdTextfieldTypes> {
|
|
153
223
|
type = input.required<K>();
|
|
154
|
-
from = model<SdTextfieldTypes[K]
|
|
155
|
-
to = model<SdTextfieldTypes[K]
|
|
224
|
+
from = model<SdTextfieldTypes[K]>();
|
|
225
|
+
to = model<SdTextfieldTypes[K]>();
|
|
226
|
+
inputStyle = input<string>();
|
|
156
227
|
required = input(false, { transform: booleanAttribute });
|
|
157
228
|
disabled = input(false, { transform: booleanAttribute });
|
|
158
229
|
}
|
|
@@ -165,12 +236,20 @@ class SdRange<K extends keyof SdTextfieldTypes> {
|
|
|
165
236
|
```typescript
|
|
166
237
|
@Component({ selector: "sd-date-range-picker" })
|
|
167
238
|
class SdDateRangePicker {
|
|
168
|
-
|
|
169
|
-
|
|
239
|
+
periodType = model<"일" | "월" | "범위">("범위");
|
|
240
|
+
from = model<DateOnly>();
|
|
241
|
+
to = model<DateOnly>();
|
|
170
242
|
required = input(false, { transform: booleanAttribute });
|
|
171
243
|
}
|
|
172
244
|
```
|
|
173
245
|
|
|
246
|
+
| Input | Type | Default | Description |
|
|
247
|
+
|-------|------|---------|-------------|
|
|
248
|
+
| `periodType` | `"일" \| "월" \| "범위"` | `"범위"` | 기간 선택 타입 (two-way) |
|
|
249
|
+
| `from` | `DateOnly \| undefined` | - | 시작일 (two-way) |
|
|
250
|
+
| `to` | `DateOnly \| undefined` | - | 종료일 (two-way) |
|
|
251
|
+
| `required` | `boolean` | `false` | 필수 |
|
|
252
|
+
|
|
174
253
|
## Choice
|
|
175
254
|
|
|
176
255
|
### `SdStatePreset`
|
|
@@ -181,9 +260,17 @@ class SdDateRangePicker {
|
|
|
181
260
|
@Component({ selector: "sd-state-preset" })
|
|
182
261
|
class SdStatePreset {
|
|
183
262
|
key = input.required<string>();
|
|
263
|
+
state = model<any>();
|
|
264
|
+
size = input<"sm" | "lg">();
|
|
184
265
|
}
|
|
185
266
|
```
|
|
186
267
|
|
|
268
|
+
| Input | Type | Default | Description |
|
|
269
|
+
|-------|------|---------|-------------|
|
|
270
|
+
| `key` | `string` | required | 프리셋 저장 키 |
|
|
271
|
+
| `state` | `any` | - | 상태 데이터 (two-way) |
|
|
272
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
273
|
+
|
|
187
274
|
### `SdStatePresetDef`
|
|
188
275
|
|
|
189
276
|
```typescript
|
|
@@ -208,22 +295,30 @@ interface SdStatePresetDef {
|
|
|
208
295
|
@Component({ selector: "sd-checkbox" })
|
|
209
296
|
class SdCheckbox {
|
|
210
297
|
value = model(false);
|
|
298
|
+
canChangeFn = input<(item: boolean) => boolean | Promise<boolean>>(() => true);
|
|
211
299
|
icon = input(tablerCheck);
|
|
212
300
|
radio = input(false, { transform: booleanAttribute });
|
|
213
301
|
disabled = input(false, { transform: booleanAttribute });
|
|
302
|
+
size = input<"sm" | "lg">();
|
|
214
303
|
inline = input(false, { transform: booleanAttribute });
|
|
215
304
|
inset = input(false, { transform: booleanAttribute });
|
|
305
|
+
theme = input<"primary" | "secondary" | ...>();
|
|
306
|
+
contentStyle = input<string>();
|
|
216
307
|
}
|
|
217
308
|
```
|
|
218
309
|
|
|
219
310
|
| Input | Type | Default | Description |
|
|
220
311
|
|-------|------|---------|-------------|
|
|
221
312
|
| `value` | `boolean` | `false` | 체크 여부 (two-way) |
|
|
313
|
+
| `canChangeFn` | `(item: boolean) => boolean \| Promise<boolean>` | `() => true` | 값 변경 가능 여부 함수 |
|
|
222
314
|
| `icon` | `string` | `tablerCheck` | 체크 아이콘 |
|
|
223
315
|
| `radio` | `boolean` | `false` | 라디오 버튼 스타일 |
|
|
224
316
|
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
317
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
225
318
|
| `inline` | `boolean` | `false` | 인라인 표시 |
|
|
226
319
|
| `inset` | `boolean` | `false` | 삽입 스타일 |
|
|
320
|
+
| `theme` | `string \| undefined` | `undefined` | 테마 색상 |
|
|
321
|
+
| `contentStyle` | `string \| undefined` | `undefined` | 컨텐츠 인라인 스타일 |
|
|
227
322
|
|
|
228
323
|
### `SdSwitch`
|
|
229
324
|
|
|
@@ -233,9 +328,12 @@ class SdCheckbox {
|
|
|
233
328
|
@Component({ selector: "sd-switch" })
|
|
234
329
|
class SdSwitch {
|
|
235
330
|
value = model(false);
|
|
331
|
+
canChangeFn = input<(item: boolean) => boolean | Promise<boolean>>(() => true);
|
|
236
332
|
disabled = input(false, { transform: booleanAttribute });
|
|
237
333
|
inline = input(false, { transform: booleanAttribute });
|
|
238
334
|
inset = input(false, { transform: booleanAttribute });
|
|
335
|
+
size = input<"sm" | "lg">();
|
|
336
|
+
theme = input<string>();
|
|
239
337
|
}
|
|
240
338
|
```
|
|
241
339
|
|
|
@@ -276,36 +374,71 @@ class SdTiptapEditor {
|
|
|
276
374
|
disabled = input(false, { transform: booleanAttribute });
|
|
277
375
|
readonly = input(false, { transform: booleanAttribute });
|
|
278
376
|
required = input(false, { transform: booleanAttribute });
|
|
377
|
+
placeholder = input<string>();
|
|
378
|
+
validatorFn = input<(value: string | undefined) => string | undefined>();
|
|
379
|
+
extensions = input<AnyExtension[]>();
|
|
279
380
|
}
|
|
280
381
|
```
|
|
281
382
|
|
|
383
|
+
| Input | Type | Default | Description |
|
|
384
|
+
|-------|------|---------|-------------|
|
|
385
|
+
| `value` | `string \| undefined` | - | HTML 콘텐츠 (two-way) |
|
|
386
|
+
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
387
|
+
| `readonly` | `boolean` | `false` | 읽기 전용 |
|
|
388
|
+
| `required` | `boolean` | `false` | 필수 |
|
|
389
|
+
| `placeholder` | `string \| undefined` | `undefined` | 플레이스홀더 |
|
|
390
|
+
| `validatorFn` | `((value) => string \| undefined) \| undefined` | `undefined` | 커스텀 유효성 검증 함수 |
|
|
391
|
+
| `extensions` | `AnyExtension[] \| undefined` | `undefined` | 추가 TipTap 확장 |
|
|
392
|
+
|
|
282
393
|
## Select
|
|
283
394
|
|
|
284
395
|
### `SdSelect`
|
|
285
396
|
|
|
286
|
-
드롭다운 선택 컴포넌트. single/multi
|
|
397
|
+
드롭다운 선택 컴포넌트. single/multi 모드를 지원한다.
|
|
287
398
|
|
|
288
399
|
```typescript
|
|
289
400
|
@Component({ selector: "sd-select" })
|
|
290
401
|
class SdSelect<T, M extends keyof SelectModeValue<T>> {
|
|
291
|
-
value = model<SelectModeValue<T>[M]>();
|
|
292
402
|
selectMode = input("single" as M);
|
|
403
|
+
value = model<SelectModeValue<any>[M]>();
|
|
404
|
+
placeholder = input<string>();
|
|
293
405
|
disabled = input(false, { transform: booleanAttribute });
|
|
294
406
|
inline = input(false, { transform: booleanAttribute });
|
|
295
407
|
inset = input(false, { transform: booleanAttribute });
|
|
408
|
+
size = input<"sm" | "lg">();
|
|
296
409
|
required = input(false, { transform: booleanAttribute });
|
|
297
410
|
hideSelectAll = input(false, { transform: booleanAttribute });
|
|
298
|
-
|
|
411
|
+
multiSelectionDisplayDirection = input<"vertical">();
|
|
412
|
+
items = input<T[]>();
|
|
413
|
+
getChildrenFn = input<(item: T) => T[] | undefined>();
|
|
414
|
+
contentClass = input<string>();
|
|
415
|
+
contentStyle = input<string>();
|
|
299
416
|
}
|
|
300
417
|
```
|
|
301
418
|
|
|
419
|
+
| Input | Type | Default | Description |
|
|
420
|
+
|-------|------|---------|-------------|
|
|
421
|
+
| `selectMode` | `M` | `"single"` | 선택 모드 |
|
|
422
|
+
| `value` | `SelectModeValue<any>[M]` | - | 선택된 값 (two-way) |
|
|
423
|
+
| `placeholder` | `string \| undefined` | `undefined` | 플레이스홀더 |
|
|
424
|
+
| `disabled` | `boolean` | `false` | 비활성화 |
|
|
425
|
+
| `inline` | `boolean` | `false` | 인라인 표시 |
|
|
426
|
+
| `inset` | `boolean` | `false` | 삽입 스타일 |
|
|
427
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
428
|
+
| `required` | `boolean` | `false` | 필수 |
|
|
429
|
+
| `hideSelectAll` | `boolean` | `false` | multi 모드에서 전체 선택 숨김 |
|
|
430
|
+
| `multiSelectionDisplayDirection` | `"vertical" \| undefined` | `undefined` | multi 모드 표시 방향 |
|
|
431
|
+
| `items` | `T[] \| undefined` | `undefined` | 항목 배열 (selectMode가 "multi"일 때 내부 목록 렌더링용) |
|
|
432
|
+
| `getChildrenFn` | `((item) => T[] \| undefined) \| undefined` | `undefined` | 트리 구조 자식 함수 |
|
|
433
|
+
| `contentClass` | `string \| undefined` | `undefined` | 컨텐츠 CSS 클래스 |
|
|
434
|
+
| `contentStyle` | `string \| undefined` | `undefined` | 컨텐츠 인라인 스타일 |
|
|
435
|
+
|
|
302
436
|
### `SelectModeValue`
|
|
303
437
|
|
|
304
438
|
```typescript
|
|
305
439
|
type SelectModeValue<T> = {
|
|
306
|
-
single: T | undefined;
|
|
307
440
|
multi: T[];
|
|
308
|
-
|
|
441
|
+
single: T;
|
|
309
442
|
}
|
|
310
443
|
```
|
|
311
444
|
|
|
@@ -335,11 +468,23 @@ class SdSelectButton<T> { }
|
|
|
335
468
|
|
|
336
469
|
### `SdForm`
|
|
337
470
|
|
|
338
|
-
폼 래퍼 컴포넌트. submit 이벤트
|
|
471
|
+
폼 래퍼 컴포넌트. `<form>` 태그를 렌더링하며 submit 이벤트 처리 및 유효성 검증을 수행한다.
|
|
339
472
|
|
|
340
473
|
```typescript
|
|
341
474
|
@Component({ selector: "sd-form" })
|
|
342
|
-
class SdForm {
|
|
475
|
+
class SdForm {
|
|
476
|
+
formSubmit = output<SubmitEvent>();
|
|
477
|
+
formInvalid = output();
|
|
478
|
+
|
|
479
|
+
requestSubmit(): void;
|
|
480
|
+
}
|
|
343
481
|
```
|
|
344
482
|
|
|
345
|
-
|
|
483
|
+
| Output | Type | Description |
|
|
484
|
+
|--------|------|-------------|
|
|
485
|
+
| `formSubmit` | `SubmitEvent` | 유효성 검증 통과 시 발생 |
|
|
486
|
+
| `formInvalid` | `void` | 유효성 검증 실패 시 발생 (`reportValidity()` 호출 후) |
|
|
487
|
+
|
|
488
|
+
| Method | Description |
|
|
489
|
+
|--------|-------------|
|
|
490
|
+
| `requestSubmit()` | 프로그래밍 방식으로 submit 트리거 |
|
|
@@ -16,12 +16,16 @@ class SdDockContainer { }
|
|
|
16
16
|
```typescript
|
|
17
17
|
@Component({ selector: "sd-dock" })
|
|
18
18
|
class SdDock {
|
|
19
|
+
key = input<string>();
|
|
20
|
+
position = input<"top" | "bottom" | "right" | "left">("top");
|
|
19
21
|
resizable = input(false, { transform: booleanAttribute });
|
|
20
22
|
}
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
| Input | Type | Default | Description |
|
|
24
26
|
|-------|------|---------|-------------|
|
|
27
|
+
| `key` | `string \| undefined` | `undefined` | 리사이즈 설정 저장 키 |
|
|
28
|
+
| `position` | `"top" \| "bottom" \| "right" \| "left"` | `"top"` | 도킹 위치 |
|
|
25
29
|
| `resizable` | `boolean` | `false` | 크기 조절 가능 여부 |
|
|
26
30
|
|
|
27
31
|
## `SdGap`
|
|
@@ -39,11 +43,16 @@ class SdGap { }
|
|
|
39
43
|
|
|
40
44
|
```typescript
|
|
41
45
|
@Component({ selector: "sd-kanban-board" })
|
|
42
|
-
class SdKanbanBoard {
|
|
43
|
-
|
|
46
|
+
class SdKanbanBoard<L, T> {
|
|
47
|
+
selectedValues = model<T[]>([]);
|
|
48
|
+
drop = output<SdKanbanBoardDropInfo<L, T>>();
|
|
44
49
|
}
|
|
45
50
|
```
|
|
46
51
|
|
|
52
|
+
| Input | Type | Default | Description |
|
|
53
|
+
|-------|------|---------|-------------|
|
|
54
|
+
| `selectedValues` | `T[]` | `[]` | 선택된 칸반 아이템 값 배열 (two-way) |
|
|
55
|
+
|
|
47
56
|
### `SdKanbanBoardDropInfo`
|
|
48
57
|
|
|
49
58
|
```typescript
|
|
@@ -94,16 +103,20 @@ interface SdKanbanDropTarget<L, T> {
|
|
|
94
103
|
|
|
95
104
|
```typescript
|
|
96
105
|
@Component({ selector: "sd-kanban" })
|
|
97
|
-
class SdKanban {
|
|
106
|
+
class SdKanban<L, T> {
|
|
107
|
+
value = input<T>();
|
|
98
108
|
selectable = input(false, { transform: booleanAttribute });
|
|
99
109
|
draggable = input(false, { transform: booleanAttribute });
|
|
110
|
+
contentClass = input<string>();
|
|
100
111
|
}
|
|
101
112
|
```
|
|
102
113
|
|
|
103
114
|
| Input | Type | Default | Description |
|
|
104
115
|
|-------|------|---------|-------------|
|
|
116
|
+
| `value` | `T \| undefined` | `undefined` | 칸반 아이템의 값 |
|
|
105
117
|
| `selectable` | `boolean` | `false` | 선택 가능 여부 |
|
|
106
118
|
| `draggable` | `boolean` | `false` | 드래그 가능 여부 |
|
|
119
|
+
| `contentClass` | `string \| undefined` | `undefined` | 컨텐츠 CSS 클래스 |
|
|
107
120
|
|
|
108
121
|
## `SdKanbanLane`
|
|
109
122
|
|
|
@@ -111,10 +124,11 @@ class SdKanban {
|
|
|
111
124
|
|
|
112
125
|
```typescript
|
|
113
126
|
@Component({ selector: "sd-kanban-lane" })
|
|
114
|
-
class SdKanbanLane {
|
|
127
|
+
class SdKanbanLane<L, T> {
|
|
115
128
|
busy = input(false, { transform: booleanAttribute });
|
|
116
129
|
useCollapse = input(false, { transform: booleanAttribute });
|
|
117
130
|
collapse = model(false);
|
|
131
|
+
value = input<L>();
|
|
118
132
|
}
|
|
119
133
|
```
|
|
120
134
|
|
|
@@ -123,3 +137,4 @@ class SdKanbanLane {
|
|
|
123
137
|
| `busy` | `boolean` | `false` | busy 상태 |
|
|
124
138
|
| `useCollapse` | `boolean` | `false` | 접기 기능 사용 |
|
|
125
139
|
| `collapse` | `boolean` | `false` | 접힘 상태 (two-way) |
|
|
140
|
+
| `value` | `L \| undefined` | `undefined` | 레인의 값 |
|
|
@@ -105,9 +105,19 @@ class SdSidebar { }
|
|
|
105
105
|
|
|
106
106
|
```typescript
|
|
107
107
|
@Component({ selector: "sd-sidebar-menu" })
|
|
108
|
-
class SdSidebarMenu {
|
|
108
|
+
class SdSidebarMenu {
|
|
109
|
+
menus = input<SdMenu[]>([]);
|
|
110
|
+
layout = input<"accordion" | "flat">();
|
|
111
|
+
getMenuIsSelectedFn = input<(menu: SdMenu) => boolean>();
|
|
112
|
+
}
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
| Input | Type | Default | Description |
|
|
116
|
+
|-------|------|---------|-------------|
|
|
117
|
+
| `menus` | `SdMenu[]` | `[]` | 메뉴 항목 |
|
|
118
|
+
| `layout` | `"accordion" \| "flat" \| undefined` | `undefined` | 레이아웃 모드 |
|
|
119
|
+
| `getMenuIsSelectedFn` | `((menu) => boolean) \| undefined` | `undefined` | 커스텀 메뉴 선택 여부 함수 |
|
|
120
|
+
|
|
111
121
|
### `SdSidebarUser`
|
|
112
122
|
|
|
113
123
|
사이드바 사용자 영역 컴포넌트.
|
|
@@ -162,9 +172,17 @@ class SdTopbar { }
|
|
|
162
172
|
|
|
163
173
|
```typescript
|
|
164
174
|
@Component({ selector: "sd-topbar-menu" })
|
|
165
|
-
class SdTopbarMenu {
|
|
175
|
+
class SdTopbarMenu {
|
|
176
|
+
menus = input<SdMenu[]>([]);
|
|
177
|
+
getMenuIsSelectedFn = input<(menu: SdMenu) => boolean>();
|
|
178
|
+
}
|
|
166
179
|
```
|
|
167
180
|
|
|
181
|
+
| Input | Type | Default | Description |
|
|
182
|
+
|-------|------|---------|-------------|
|
|
183
|
+
| `menus` | `SdMenu[]` | `[]` | 메뉴 항목 |
|
|
184
|
+
| `getMenuIsSelectedFn` | `((menu) => boolean) \| undefined` | `undefined` | 커스텀 메뉴 선택 여부 함수 |
|
|
185
|
+
|
|
168
186
|
### `SdTopbarUser`
|
|
169
187
|
|
|
170
188
|
탑바 사용자 영역 컴포넌트.
|
|
@@ -38,22 +38,25 @@ class SdDropdownPopup { }
|
|
|
38
38
|
@Component({ selector: "sd-modal" })
|
|
39
39
|
class SdModal {
|
|
40
40
|
open = model(false);
|
|
41
|
+
key = input<string | undefined>(undefined);
|
|
41
42
|
title = input("");
|
|
42
43
|
hideHeader = input(false);
|
|
43
44
|
hideCloseButton = input(false);
|
|
45
|
+
headerStyle = input<string | undefined>(undefined);
|
|
44
46
|
useCloseByBackdrop = input(true);
|
|
45
47
|
useCloseByEscapeKey = input(true);
|
|
46
48
|
float = input(false);
|
|
47
49
|
fill = input(false);
|
|
48
50
|
resizable = input(false);
|
|
49
51
|
movable = input(false);
|
|
50
|
-
position = input<"bottom-right" | "top-right">();
|
|
51
|
-
minHeightPx = input<number>();
|
|
52
|
-
minWidthPx = input<number>();
|
|
53
|
-
heightPx = input<number>();
|
|
54
|
-
widthPx = input<number>();
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
position = input<"bottom-right" | "top-right" | undefined>(undefined);
|
|
53
|
+
minHeightPx = input<number | undefined>(undefined);
|
|
54
|
+
minWidthPx = input<number | undefined>(undefined);
|
|
55
|
+
heightPx = input<number | undefined>(undefined);
|
|
56
|
+
widthPx = input<number | undefined>(undefined);
|
|
57
|
+
actionTplRef = input<TemplateRef<any> | undefined>(undefined);
|
|
58
|
+
|
|
59
|
+
closeRequest = output<void>();
|
|
57
60
|
}
|
|
58
61
|
```
|
|
59
62
|
|
|
@@ -70,7 +73,11 @@ class SdModal {
|
|
|
70
73
|
| `resizable` | `boolean` | `false` | 크기 조절 가능 |
|
|
71
74
|
| `movable` | `boolean` | `false` | 이동 가능 |
|
|
72
75
|
| `position` | `"bottom-right" \| "top-right"` | - | 위치 프리셋 |
|
|
73
|
-
| `
|
|
76
|
+
| `actionTplRef` | `TemplateRef<any> \| undefined` | `undefined` | 헤더 액션 영역 템플릿 (SdModalProvider에서 설정) |
|
|
77
|
+
|
|
78
|
+
| Output | Type | Description |
|
|
79
|
+
|--------|------|-------------|
|
|
80
|
+
| `closeRequest` | `void` | 배경 클릭, ESC 키, 닫기 버튼으로 닫기 요청 시 발생 |
|
|
74
81
|
|
|
75
82
|
### `SdPromptModal`
|
|
76
83
|
|
|
@@ -109,9 +116,9 @@ class SdConfirmModal implements SdModalContentDef<boolean> {
|
|
|
109
116
|
class SdToast {
|
|
110
117
|
open = model(false);
|
|
111
118
|
useProgress = input(false, { transform: booleanAttribute });
|
|
119
|
+
theme = input<SdToastTheme>("info");
|
|
112
120
|
progress = model(0);
|
|
113
|
-
|
|
114
|
-
message = signal<string>("");
|
|
121
|
+
message = model<string | undefined>(undefined);
|
|
115
122
|
}
|
|
116
123
|
```
|
|
117
124
|
|
|
@@ -136,13 +143,15 @@ busy 표시 컨테이너 컴포넌트. spinner/bar/cube 3가지 타입을 지원
|
|
|
136
143
|
@Component({ selector: "sd-busy-container" })
|
|
137
144
|
class SdBusyContainer {
|
|
138
145
|
busy = input(false, { transform: booleanAttribute });
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
message = input<string | undefined>(undefined);
|
|
147
|
+
type = input<SdBusyType | undefined>(undefined);
|
|
148
|
+
progressPercent = input<number | undefined>(undefined);
|
|
141
149
|
}
|
|
142
150
|
```
|
|
143
151
|
|
|
144
152
|
| Input | Type | Default | Description |
|
|
145
153
|
|-------|------|---------|-------------|
|
|
146
154
|
| `busy` | `boolean` | `false` | busy 상태 |
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
155
|
+
| `message` | `string \| undefined` | `undefined` | busy 메시지 |
|
|
156
|
+
| `type` | `SdBusyType \| undefined` | `undefined` | 표시 유형 (spinner, bar, cube). undefined이면 부모의 SdBusyProvider.type 사용 |
|
|
157
|
+
| `progressPercent` | `number \| undefined` | `undefined` | 진행률 (0-100). 설정 시 progress bar로 표시 |
|
|
@@ -7,15 +7,19 @@
|
|
|
7
7
|
```typescript
|
|
8
8
|
@Component({ selector: "sd-label" })
|
|
9
9
|
class SdLabel {
|
|
10
|
+
theme = input<"primary" | "secondary" | "info" | "success" | "warning" | "danger" | "gray" | "blue-gray">();
|
|
11
|
+
color = input<string>();
|
|
10
12
|
clickable = input(false, { transform: booleanAttribute });
|
|
11
13
|
}
|
|
12
14
|
```
|
|
13
15
|
|
|
14
16
|
| Input | Type | Default | Description |
|
|
15
17
|
|-------|------|---------|-------------|
|
|
18
|
+
| `theme` | `string \| undefined` | `undefined` | 테마 색상 |
|
|
19
|
+
| `color` | `string \| undefined` | `undefined` | 커스텀 CSS 색상 |
|
|
16
20
|
| `clickable` | `boolean` | `false` | 클릭 가능 여부 |
|
|
17
21
|
|
|
18
|
-
호스트 속성: `data-sd-theme`
|
|
22
|
+
호스트 속성: `data-sd-theme`
|
|
19
23
|
|
|
20
24
|
## `SdNote`
|
|
21
25
|
|
|
@@ -24,12 +28,16 @@ class SdLabel {
|
|
|
24
28
|
```typescript
|
|
25
29
|
@Component({ selector: "sd-note" })
|
|
26
30
|
class SdNote {
|
|
31
|
+
theme = input<"primary" | "secondary" | "info" | "success" | "warning" | "danger" | "gray" | "blue-gray">();
|
|
32
|
+
size = input<"sm" | "lg">();
|
|
27
33
|
inset = input(false, { transform: booleanAttribute });
|
|
28
34
|
}
|
|
29
35
|
```
|
|
30
36
|
|
|
31
37
|
| Input | Type | Default | Description |
|
|
32
38
|
|-------|------|---------|-------------|
|
|
39
|
+
| `theme` | `string \| undefined` | `undefined` | 테마 색상 |
|
|
40
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
33
41
|
| `inset` | `boolean` | `false` | 삽입 스타일 (테두리 없음) |
|
|
34
42
|
|
|
35
43
|
호스트 속성: `data-sd-theme`
|
|
@@ -41,17 +49,19 @@ class SdNote {
|
|
|
41
49
|
```typescript
|
|
42
50
|
@Component({ selector: "sd-progress" })
|
|
43
51
|
class SdProgress {
|
|
52
|
+
inset = input(false, { transform: booleanAttribute });
|
|
53
|
+
size = input<"sm" | "lg">();
|
|
44
54
|
theme = input.required<"primary" | "secondary" | "info" | "success" | "warning" | "danger" | "gray" | "blue-gray">();
|
|
45
55
|
value = input.required<number>();
|
|
46
|
-
inset = input(false, { transform: booleanAttribute });
|
|
47
56
|
}
|
|
48
57
|
```
|
|
49
58
|
|
|
50
59
|
| Input | Type | Default | Description |
|
|
51
60
|
|-------|------|---------|-------------|
|
|
61
|
+
| `inset` | `boolean` | `false` | 삽입 스타일 |
|
|
62
|
+
| `size` | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
|
|
52
63
|
| `theme` | `string` | required | 테마 색상 |
|
|
53
64
|
| `value` | `number` | required | 진행률 (0-100) |
|
|
54
|
-
| `inset` | `boolean` | `false` | 삽입 스타일 |
|
|
55
65
|
|
|
56
66
|
## `SdCalendar`
|
|
57
67
|
|
|
@@ -84,16 +94,14 @@ class SdCalendar<T> {
|
|
|
84
94
|
@Component({ selector: "sd-barcode" })
|
|
85
95
|
class SdBarcode {
|
|
86
96
|
type = input.required<BarcodeType>();
|
|
87
|
-
value = input
|
|
88
|
-
scale = input(2);
|
|
97
|
+
value = input<string>();
|
|
89
98
|
}
|
|
90
99
|
```
|
|
91
100
|
|
|
92
101
|
| Input | Type | Default | Description |
|
|
93
102
|
|-------|------|---------|-------------|
|
|
94
103
|
| `type` | `BarcodeType` | required | 바코드 타입 |
|
|
95
|
-
| `value` | `string` |
|
|
96
|
-
| `scale` | `number` | `2` | 렌더링 스케일 |
|
|
104
|
+
| `value` | `string \| undefined` | `undefined` | 바코드 값. 빈 문자열이거나 undefined이면 빈 출력 |
|
|
97
105
|
|
|
98
106
|
### `BarcodeType`
|
|
99
107
|
|