@simplysm/angular 14.0.48 → 14.0.51

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 (144) hide show
  1. package/README.md +234 -226
  2. package/dist/controls/select/sd-select.js +3 -3
  3. package/dist/index.d.ts +0 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +0 -2
  6. package/dist/layout/dock/sd-dock-container.js +1 -1
  7. package/dist/styles.css +9 -0
  8. package/docs/bootstrap/provide-sd-angular.md +37 -0
  9. package/docs/bootstrap/sd-angular-config-provider.md +16 -0
  10. package/docs/directives/sd-command-directive.md +30 -0
  11. package/docs/directives/sd-events.md +25 -0
  12. package/docs/directives/sd-intersection-directive.md +36 -0
  13. package/docs/directives/sd-invalid.md +24 -0
  14. package/docs/directives/sd-resize-directive.md +42 -0
  15. package/docs/directives/sd-ripple.md +23 -0
  16. package/docs/directives/sd-router-link.md +38 -0
  17. package/docs/directives/sd-show-effect.md +18 -0
  18. package/docs/directives/sd-typed-template.md +69 -0
  19. package/docs/features/sd-address-search-modal.md +50 -0
  20. package/docs/features/sd-permission-table.md +20 -0
  21. package/docs/features/sd-shared-data-components.md +158 -0
  22. package/docs/features/sd-tiptap-editor.md +26 -0
  23. package/docs/{pipes.md → pipes/format-pipe.md} +14 -5
  24. package/docs/plugins/sd-global-error-handler.md +23 -0
  25. package/docs/{plugins.md → plugins/sd-option-event-plugin.md} +9 -12
  26. package/docs/provider-types/sd-menu.md +65 -0
  27. package/docs/provider-types/sd-modal-content-def.md +148 -0
  28. package/docs/provider-types/sd-toast-content-def.md +73 -0
  29. package/docs/provider-types/shared-data-base.md +59 -0
  30. package/docs/providers/sd-activated-modal-provider.md +34 -0
  31. package/docs/providers/sd-app-structure-provider.md +81 -0
  32. package/docs/providers/sd-busy-provider.md +18 -0
  33. package/docs/providers/sd-file-dialog-provider.md +40 -0
  34. package/docs/providers/sd-local-storage-provider.md +20 -0
  35. package/docs/providers/sd-modal-provider.md +67 -0
  36. package/docs/providers/sd-navigate-window-provider.md +18 -0
  37. package/docs/providers/sd-print-provider.md +25 -0
  38. package/docs/providers/sd-service-client-factory-provider.md +43 -0
  39. package/docs/providers/sd-shared-data-provider.md +64 -0
  40. package/docs/providers/sd-system-config-provider.md +46 -0
  41. package/docs/providers/sd-system-log-provider.md +18 -0
  42. package/docs/providers/sd-theme-provider.md +38 -0
  43. package/docs/providers/sd-toast-provider.md +65 -0
  44. package/docs/recipes/_common-rules.md +244 -0
  45. package/docs/recipes/crud-detail/extension-a-edit-save.md +230 -0
  46. package/docs/recipes/crud-detail/extension-b-delete-restore.md +142 -0
  47. package/docs/recipes/crud-detail/extension-c-modal-view.md +214 -0
  48. package/docs/recipes/crud-detail/extension-d-control-view.md +103 -0
  49. package/docs/recipes/crud-detail/extension-e-auxiliary.md +87 -0
  50. package/docs/recipes/crud-detail/extension-f-complex-detail.md +234 -0
  51. package/docs/recipes/crud-detail.md +215 -722
  52. package/docs/recipes/crud-list/extension-a-inline-edit.md +410 -0
  53. package/docs/recipes/crud-list/extension-b-selection.md +226 -0
  54. package/docs/recipes/crud-list/extension-c-inline-delete.md +87 -0
  55. package/docs/recipes/crud-list/extension-d-select-modal.md +207 -0
  56. package/docs/recipes/crud-list/extension-e-readonly-modal.md +165 -0
  57. package/docs/recipes/crud-list/extension-f-modal-edit.md +177 -0
  58. package/docs/recipes/crud-list/extension-g-excel.md +157 -0
  59. package/docs/recipes/crud-list.md +293 -626
  60. package/docs/recipes/data-select-button.md +194 -101
  61. package/docs/recipes/page-modal-container.md +168 -86
  62. package/docs/styling/classes.md +149 -0
  63. package/docs/styling/mixins.md +100 -0
  64. package/docs/styling/themes.md +35 -0
  65. package/docs/styling/variables.md +147 -0
  66. package/docs/{type-utilities.md → type-utilities/directive-input-signals.md} +17 -35
  67. package/docs/ui-data/sd-list.md +37 -0
  68. package/docs/ui-data/sd-sheet.md +227 -0
  69. package/docs/ui-form/sd-additional-button.md +26 -0
  70. package/docs/ui-form/sd-anchor.md +31 -0
  71. package/docs/ui-form/sd-button.md +105 -0
  72. package/docs/ui-form/sd-checkbox-group.md +39 -0
  73. package/docs/ui-form/sd-checkbox.md +81 -0
  74. package/docs/ui-form/sd-date-range-picker.md +27 -0
  75. package/docs/ui-form/sd-form.md +89 -0
  76. package/docs/ui-form/sd-modal-select-button.md +54 -0
  77. package/docs/ui-form/sd-numpad.md +26 -0
  78. package/docs/ui-form/sd-range.md +26 -0
  79. package/docs/ui-form/sd-select.md +68 -0
  80. package/docs/ui-form/sd-shared-data-select.md +52 -0
  81. package/docs/ui-form/sd-state-preset.md +37 -0
  82. package/docs/ui-form/sd-switch.md +27 -0
  83. package/docs/ui-form/sd-textarea.md +33 -0
  84. package/docs/ui-form/sd-textfield.md +145 -0
  85. package/docs/ui-layout/sd-dock-container.md +64 -0
  86. package/docs/ui-layout/sd-dock.md +37 -0
  87. package/docs/ui-layout/sd-gap.md +26 -0
  88. package/docs/{ui-layout.md → ui-layout/sd-kanban-board.md} +41 -85
  89. package/docs/ui-layout/sd-kanban-lane.md +34 -0
  90. package/docs/ui-layout/sd-kanban.md +29 -0
  91. package/docs/ui-navigation/sd-collapse.md +35 -0
  92. package/docs/ui-navigation/sd-pagination.md +26 -0
  93. package/docs/ui-navigation/sd-sidebar-container.md +49 -0
  94. package/docs/ui-navigation/sd-sidebar-menu.md +22 -0
  95. package/docs/ui-navigation/sd-sidebar-user.md +43 -0
  96. package/docs/ui-navigation/sd-tab.md +51 -0
  97. package/docs/ui-navigation/sd-topbar-container.md +97 -0
  98. package/docs/ui-navigation/sd-topbar-menu.md +23 -0
  99. package/docs/ui-navigation/sd-topbar-user.md +38 -0
  100. package/docs/ui-navigation/sd-topbar.md +30 -0
  101. package/docs/ui-overlay/sd-busy-container.md +69 -0
  102. package/docs/ui-overlay/sd-confirm-modal.md +30 -0
  103. package/docs/ui-overlay/sd-dropdown.md +40 -0
  104. package/docs/ui-overlay/sd-modal.md +34 -0
  105. package/docs/ui-overlay/sd-prompt-modal.md +30 -0
  106. package/docs/ui-overlay/sd-toast.md +35 -0
  107. package/docs/ui-visual/sd-barcode.md +36 -0
  108. package/docs/ui-visual/sd-calendar.md +34 -0
  109. package/docs/ui-visual/sd-echarts.md +32 -0
  110. package/docs/ui-visual/sd-label.md +24 -0
  111. package/docs/ui-visual/sd-note.md +23 -0
  112. package/docs/ui-visual/sd-progress.md +23 -0
  113. package/docs/utils/inject-routing-signals.md +161 -0
  114. package/docs/utils/inject-sd-system-config-resource.md +35 -0
  115. package/docs/utils/mark.md +43 -0
  116. package/docs/utils/selection-managers.md +96 -0
  117. package/docs/utils/set-safe-style.md +19 -0
  118. package/docs/utils/setup-functions.md +93 -0
  119. package/package.json +7 -7
  120. package/scss/commons/_styles.scss +12 -0
  121. package/src/controls/select/sd-select.ts +3 -3
  122. package/src/core/modal/sd-modal.provider.ts +1 -1
  123. package/src/core/modal/sd-modal.ts +1 -1
  124. package/src/core/routing/menu-utils.ts +1 -1
  125. package/src/core/shared-data/sd-shared-data.provider.ts +7 -7
  126. package/src/data/shared-data/sd-shared-data-select.ts +2 -2
  127. package/src/index.ts +0 -3
  128. package/src/layout/dock/sd-dock-container.ts +1 -1
  129. package/dist/data/getOrmDataEditToastErrorMessage.d.ts +0 -2
  130. package/dist/data/getOrmDataEditToastErrorMessage.d.ts.map +0 -1
  131. package/dist/data/getOrmDataEditToastErrorMessage.js +0 -8
  132. package/docs/bootstrap.md +0 -38
  133. package/docs/directives.md +0 -236
  134. package/docs/features.md +0 -169
  135. package/docs/provider-types.md +0 -283
  136. package/docs/providers.md +0 -379
  137. package/docs/styling.md +0 -222
  138. package/docs/ui-data.md +0 -333
  139. package/docs/ui-form.md +0 -502
  140. package/docs/ui-navigation.md +0 -273
  141. package/docs/ui-overlay.md +0 -157
  142. package/docs/ui-visual.md +0 -127
  143. package/docs/utils.md +0 -244
  144. package/src/data/getOrmDataEditToastErrorMessage.ts +0 -10
package/docs/styling.md DELETED
@@ -1,222 +0,0 @@
1
- # Styling
2
-
3
- `dist/styles.css`로 컴파일되며, `package.json`의 `style` 필드에서 참조된다. CSS Layers: `@layer base, theme-variant, utilities`.
4
-
5
- ## CSS Classes
6
-
7
- ### Flexbox
8
-
9
- | Class | Description |
10
- |-------|-------------|
11
- | `.flex-row` | `display: flex; flex-direction: row; flex-wrap: nowrap` |
12
- | `.flex-column` | `display: flex; flex-direction: column; flex-wrap: nowrap` |
13
- | `.flex-row-inline` | `display: inline-flex; flex-direction: row` |
14
- | `.flex-column-inline` | `display: inline-flex; flex-direction: column` |
15
- | `.flex-fill` | `flex: 1 1 auto; overflow: auto` (가용 공간 채우기) |
16
- | `.flex-auto` | `flex: 1 0 auto` (컨텐츠 크기 유지하며 확장) |
17
- | `.flex-min` | `flex: 0 0 0` (최소 크기) |
18
-
19
- ### Grid
20
-
21
- | Class | Description |
22
- |-------|-------------|
23
- | `.grid` | `display: grid` |
24
- | `.grid-{1..12}` | `grid-template-columns: repeat(N, 1fr)` |
25
- | `.grid-sm-{1..12}` | `@media (max-width: 1280px)` 반응형 |
26
- | `.grid-xs-{1..12}` | `@media (max-width: 1024px)` 반응형 |
27
- | `.grid-xxs-{1..12}` | `@media (max-width: 800px)` 반응형 |
28
-
29
- ### Layout
30
-
31
- | Class | Description |
32
- |-------|-------------|
33
- | `.card` | 카드 스타일 (배경, 테두리, 라운드, 엘리베이션) |
34
- | `.fill` | `height: 100%; width: 100%; overflow: auto` |
35
- | `.sticky-top` | `position: sticky; top: 0; z-index: 1` |
36
- | `.overflow-auto` | `overflow: auto` |
37
- | `.position-relative` | `position: relative` |
38
- | `.nowrap` | `white-space: nowrap` |
39
-
40
- ### Form Layout
41
-
42
- | Class | Description |
43
- |-------|-------------|
44
- | `.form-box` | 폼 박스 레이아웃 |
45
- | `.form-box-inline` | 인라인 폼 박스 |
46
- | `.form-table` | 테이블 형태 폼 |
47
- | `.form-control` | 기본 폼 컨트롤 스타일 (padding, border, font) |
48
- | `.table` | 테이블 스타일 |
49
- | `.table-inset` | 테두리 없는 테이블 |
50
- | `.table-inline` | 인라인 테이블 |
51
- | `.table-bd-v` | 수직 테두리만 있는 테이블 |
52
- | `.table-bd-h` | 수평 테두리만 있는 테이블 |
53
-
54
- ### Spacing
55
-
56
- 키: `xxs`, `xs`, `sm`, `default`, `lg`, `xl`, `xxl`, `0`, `auto`
57
-
58
- | Pattern | Description |
59
- |---------|-------------|
60
- | `.p-{key}` | 전체 padding |
61
- | `.pv-{key}`, `.ph-{key}` | 수직/수평 padding |
62
- | `.pt-{key}`, `.pr-{key}`, `.pb-{key}`, `.pl-{key}` | 방향별 padding |
63
- | `.m-{key}` | 전체 margin |
64
- | `.mv-{key}`, `.mh-{key}` | 수직/수평 margin |
65
- | `.mt-{key}`, `.mr-{key}`, `.mb-{key}`, `.ml-{key}` | 방향별 margin |
66
- | `.gap-{key}` | flex/grid gap |
67
- | `.sw-{key}` | width 설정 |
68
- | `.sh-{key}` | height 설정 |
69
- | `.p-{key1}-{key2}` | `padding: {key1} {key2}` 조합 |
70
-
71
- ### Font Size
72
-
73
- | Class | Description |
74
- |-------|-------------|
75
- | `.ft-size-{key}` | 폰트 크기 (h1~h6, sm, default, lg 등) |
76
-
77
- ### Text
78
-
79
- | Class | Description |
80
- |-------|-------------|
81
- | `.tx-left`, `.tx-right`, `.tx-center` | 텍스트 정렬 |
82
- | `.tx-line-through` | 취소선 |
83
- | `.tx-underline` | 밑줄 |
84
- | `.tx-trans-{key}` | 텍스트 투명도 색상 |
85
- | `.tx-theme-{group}-{shade}` | 테마 텍스트 색상 |
86
-
87
- ### Background
88
-
89
- | Class | Description |
90
- |-------|-------------|
91
- | `.bg-theme-{group}-{shade}` | 테마 배경 색상 |
92
- | `.bg-trans-{key}` | 투명도 배경 |
93
- | `.bg-default` | 기본 배경 |
94
- | `.bg-control` | 컨트롤 배경 |
95
-
96
- ### Border
97
-
98
- | Class | Description |
99
- |-------|-------------|
100
- | `.bd` | 전체 테두리 |
101
- | `.bdt`, `.bdr`, `.bdb`, `.bdl` | 방향별 테두리 |
102
- | `.bd-theme-{group}-{shade}` | 테마 테두리 색상 |
103
- | `.bd-trans-{key}` | 투명도 테두리 |
104
- | `.bd-none`, `.bd-transparent` | 테두리 없음/투명 |
105
- | `.bd-radius-{key}` | 테두리 라운드 |
106
- | `.bd-width-{key}` | 테두리 두께 |
107
-
108
- ### Alignment
109
-
110
- | Class | Description |
111
- |-------|-------------|
112
- | `.main-align-start`, `.main-align-end`, `.main-align-center` | justify-content |
113
- | `.cross-align-start`, `.cross-align-end`, `.cross-align-center` | align-items |
114
-
115
- ### Special
116
-
117
- | Class | Description |
118
- |-------|-------------|
119
- | `.sh-topbar` | 탑바 높이 |
120
- | `.sw-sidebar` | 사이드바 너비 |
121
- | `.help` | 도움말 스타일 (점선 밑줄, 도움말 커서) |
122
- | `.control-header` | 컨트롤 헤더 텍스트 |
123
- | `.page-header` | 페이지 헤더 텍스트 |
124
-
125
- ## CSS Custom Properties
126
-
127
- ### Theme Colors
128
-
129
- OKLCH 기반 색상 팔레트. 각 그룹에 7단계 shade가 있다.
130
-
131
- 테마 그룹: `gray`, `blue-gray`, `primary`, `secondary`, `info`, `success`, `warning`, `danger`
132
-
133
- | Property | Description |
134
- |----------|-------------|
135
- | `--theme-{group}-lightest` | 가장 밝은 색조 |
136
- | `--theme-{group}-lighter` | 더 밝은 색조 |
137
- | `--theme-{group}-light` | 밝은 색조 |
138
- | `--theme-{group}-default` | 기본 색조 |
139
- | `--theme-{group}-dark` | 어두운 색조 |
140
- | `--theme-{group}-darker` | 더 어두운 색조 |
141
- | `--theme-{group}-darkest` | 가장 어두운 색조 |
142
-
143
- ### Layout
144
-
145
- | Property | Description |
146
- |----------|-------------|
147
- | `--background-color` | body 배경 색상 |
148
- | `--control-color` | 컨트롤 배경 색상 |
149
- | `--font-family` | 기본 폰트 패밀리 |
150
- | `--font-family-monospace` | 고정폭 폰트 패밀리 |
151
- | `--font-size-default` | 기본 폰트 크기 |
152
- | `--line-height` | 기본 줄 높이 |
153
- | `--border-radius-default` | 기본 테두리 라운드 |
154
- | `--topbar-height` | 탑바 높이 |
155
- | `--sidebar-width` | 사이드바 너비 |
156
- | `--elevation-size` | 그림자 기본 크기 |
157
- | `--animation-duration` | 애니메이션 지속 시간 |
158
-
159
- ### Gap (Spacing)
160
-
161
- | Property | Description |
162
- |----------|-------------|
163
- | `--gap-xxs` | 가장 작은 간격 |
164
- | `--gap-xs` | 매우 작은 간격 |
165
- | `--gap-sm` | 작은 간격 |
166
- | `--gap-default` | 기본 간격 |
167
- | `--gap-lg` | 큰 간격 |
168
- | `--gap-xl` | 매우 큰 간격 |
169
- | `--gap-xxl` | 가장 큰 간격 |
170
-
171
- ### Transparency
172
-
173
- | Property | Description |
174
- |----------|-------------|
175
- | `--trans-lightest` | 가장 투명한 반투명 |
176
- | `--trans-lighter` | 더 투명한 반투명 |
177
- | `--trans-light` | 투명한 반투명 |
178
- | `--trans-default` | 기본 반투명 |
179
- | `--trans-dark` | 불투명한 반투명 |
180
- | `--trans-darker` | 더 불투명한 반투명 |
181
- | `--trans-darkest` | 가장 불투명한 반투명 |
182
-
183
- ### Text Transparency
184
-
185
- | Property | Description |
186
- |----------|-------------|
187
- | `--text-trans-default` | 기본 텍스트 색상 |
188
- | `--text-trans-light` | 밝은 텍스트 색상 |
189
- | `--text-trans-lighter` | 더 밝은 텍스트 색상 |
190
- | `--text-trans-dark` | 어두운 텍스트 색상 |
191
-
192
- ## Themes
193
-
194
- ### `.sd-theme-dark`
195
-
196
- 다크 모드 테마. `SdThemeProvider.dark` signal로 body에 토글된다. `themes/_variables-dark.scss`에서 색상 팔레트를 반전한다.
197
-
198
- - 배경: 어두운 색상으로 전환
199
- - 텍스트: 밝은 색상으로 전환
200
- - `img:not(.no-invert)`: 이미지 자동 반전
201
-
202
- ### Responsive Breakpoints
203
-
204
- SCSS 변수로 정의되어 media query에서 사용된다:
205
-
206
- | Variable | Value | Description |
207
- |----------|-------|-------------|
208
- | `$breakpoint-mobile` | `520px` | 모바일 |
209
- | `$breakpoint-xxs` | `800px` | 매우 작은 화면 |
210
- | `$breakpoint-xs` | `1024px` | 작은 화면 |
211
- | `$breakpoint-sm` | `1280px` | 중간 화면 |
212
-
213
- ## Mixins / Functions
214
-
215
- | Name | Signature | Description |
216
- |------|-----------|-------------|
217
- | `writeVars` | `@mixin writeVars($value, $prevKey)` | 맵을 재귀 순회하여 CSS custom properties 생성 |
218
- | `elevation` | `@mixin elevation($value)` | box-shadow 기반 엘리베이션 효과. 양수=외부, 음수=내부, 0/none=없음 |
219
- | `form-control-base` | `@mixin form-control-base()` | 폼 컨트롤 기본 스타일 (display, padding, border, font) |
220
- | `help` | `@mixin help()` | 도움말 스타일 (점선 밑줄, 커서) |
221
- | `border-direction-variants` | `@mixin border-direction-variants($dir, $d)` | 방향별 테두리 유틸리티 클래스 생성 |
222
- | `flex-direction` | `@mixin flex-direction($direction, $defaultGap?)` | flex-direction 설정 + Chrome 61 gap 폴백 |
package/docs/ui-data.md DELETED
@@ -1,333 +0,0 @@
1
- # UI - Data
2
-
3
- ## List
4
-
5
- ### `SdList`
6
-
7
- 리스트 컴포넌트.
8
-
9
- ```typescript
10
- @Component({ selector: "sd-list" })
11
- class SdList {
12
- inset = input(false, { transform: booleanAttribute });
13
- }
14
- ```
15
-
16
- | Input | Type | Default | Description |
17
- |-------|------|---------|-------------|
18
- | `inset` | `boolean` | `false` | 삽입 스타일 (테두리 없음) |
19
-
20
- ### `SdListItem`
21
-
22
- 리스트 항목 컴포넌트. 접기/펼치기 자식 리스트를 지원한다.
23
-
24
- ```typescript
25
- @Component({ selector: "sd-list-item" })
26
- class SdListItem {
27
- open = model(false);
28
- selected = input(false, { transform: booleanAttribute });
29
- readonly = input(false, { transform: booleanAttribute });
30
- }
31
- ```
32
-
33
- | Input | Type | Default | Description |
34
- |-------|------|---------|-------------|
35
- | `open` | `boolean` | `false` | 자식 리스트 펼침 (two-way) |
36
- | `selected` | `boolean` | `false` | 선택 상태 |
37
- | `readonly` | `boolean` | `false` | 읽기 전용 |
38
-
39
- ## Sheet
40
-
41
- ### `SdSheet`
42
-
43
- 스프레드시트 컴포넌트. 정렬, 컬럼 고정, 리사이즈, 페이지네이션, 설정 저장을 지원한다.
44
-
45
- ```typescript
46
- @Component({ selector: "sd-sheet" })
47
- class SdSheet<T> {
48
- key = input<string>();
49
- items = input<T[]>([]);
50
- trackByFn = input<(item: T, index: number) => unknown>();
51
- selectMode = input<"single" | "multi">();
52
- getItemSelectableFn = input<(item: T) => boolean | string>();
53
- getChildrenFn = input<(item: T, index: number) => T[] | undefined>();
54
- useAutoSort = input(false, { transform: booleanAttribute });
55
- visiblePageCount = input(10);
56
- totalPageCount = input(0);
57
- itemsPerPage = input(0);
58
- inset = input(false, { transform: booleanAttribute });
59
- hideConfigBar = input(false, { transform: booleanAttribute });
60
- cumulativeSelection = input(false, { transform: booleanAttribute });
61
-
62
- itemKeydown = output<SdSheetItemKeydownEventParam<T>>();
63
- cellKeydown = output<SdSheetCellKeydownEventParam<T>>();
64
-
65
- selectedItems = model<T[]>([]);
66
- expandedItems = model<T[]>([]);
67
- sorts = model<SortingDef[]>([]);
68
- currentPage = model(0);
69
- }
70
- ```
71
-
72
- | Input | Type | Default | Description |
73
- |-------|------|---------|-------------|
74
- | `key` | `string \| undefined` | `undefined` | 설정 저장 키 |
75
- | `items` | `T[]` | `[]` | 표시할 항목 |
76
- | `trackByFn` | `((item, index) => unknown) \| undefined` | `undefined` | 트랙킹 함수 |
77
- | `selectMode` | `"single" \| "multi" \| undefined` | `undefined` | 선택 모드 |
78
- | `getItemSelectableFn` | `((item) => boolean \| string) \| undefined` | `undefined` | 선택 가능 여부 함수. string은 비활성 사유 |
79
- | `getChildrenFn` | `((item, index) => T[] \| undefined) \| undefined` | `undefined` | 트리 구조 자식 반환 함수 |
80
- | `useAutoSort` | `boolean` | `false` | 클라이언트 측 자동 정렬 |
81
- | `visiblePageCount` | `number` | `10` | 한 번에 표시할 페이지 수 |
82
- | `totalPageCount` | `number` | `0` | 총 페이지 수 |
83
- | `itemsPerPage` | `number` | `0` | 페이지당 항목 수 |
84
- | `inset` | `boolean` | `false` | 삽입 스타일 |
85
- | `hideConfigBar` | `boolean` | `false` | 설정 바 숨김 |
86
- | `cumulativeSelection` | `boolean` | `false` | `true`면 `items` 변경(페이지 이동/검색/필터 등) 시 `selectedItems`를 유지하여 다중 페이지 선택 누적을 실현. `false`(기본)면 `items` 변경 시 `selectedItems`를 `[]`로 초기화. 체크 표시 판정은 두 모드 모두 `trackByFn` + `obj.equal` 기반 key 비교이므로 **누적 모드 사용 시 `trackByFn` 지정 필수**(기본 `(item) => item`은 reference 반환이라 서버 페이지네이션 등에서 복원 실패). 누적 모드에서 명시적 초기화는 소비자가 직접 `selectedItems.set([])` 호출. 선택된 키 배열이 필요하면 `selectedItems().map((it, i) => trackByFn()(it, i))` 수동 호출 |
87
- | `currentPage` | `number` | `0` | 현재 페이지 (two-way) |
88
- | `sorts` | `SortingDef[]` | `[]` | 정렬 설정 (two-way). **`SortingDef.key`는 컬럼 `key`에 지정된 값 그대로이므로 `"vendor.name"` 같은 체인 경로일 수 있다.** 정렬 처리 시 `item[sort.key]` 단순 접근 금지 → `obj.getChainValue(item, sort.key)` 사용 |
89
- | `selectedItems` | `T[]` | `[]` | 선택된 항목 (two-way) |
90
- | `expandedItems` | `T[]` | `[]` | 확장된 항목 (two-way) |
91
-
92
- #### `cumulativeSelection` 사용 패턴
93
-
94
- 시트의 용도에 따라 올바른 값이 다르다:
95
-
96
- - **선택 모달**(사용자가 여러 페이지 돌며 체크 후 확인 버튼으로 전체 반환) → `true`. 다중 페이지 선택이 유지되어야 한다
97
- - **현재 뷰 일괄 작업**(선택 삭제·복구 등 현재 페이지 내 처리) → `false` (기본값). `items` 변경 시 선택이 자동 초기화되어 오작동을 방지한다
98
-
99
- 정적 `true`/`false`보다 **동적 computed 바인딩**으로 상황에 맞게 쓰는 것을 권장한다:
100
-
101
- ```html
102
- <sd-sheet
103
- [cumulativeSelection]="viewType() === 'modal' && selectMode() === 'multi'"
104
- [trackByFn]="trackById"
105
- ...
106
- >
107
- ```
108
-
109
- - `viewType()` = `'modal'` + `selectMode()` = `'multi'`일 때만 누적
110
- - 그 외(page 뷰 또는 single 선택)는 기본 모드로 동작
111
-
112
- #### 주의사항
113
-
114
- - **초기 마운트 시 `selectedItems` 보존**: `cumulativeSelection=false`라도 **최초 `items` 구독 시점**의 `selectedItems`는 초기화되지 않는다. 이후 `items`가 교체될 때부터 초기화 규칙이 적용된다. 따라서 소비자가 컴포넌트 마운트 직후 초기 선택을 주입하는 시나리오는 안전하다.
115
- - **`trackByFn`은 index에 의존하지 않아야 한다**: 누적 모드에서 `selectedItems`는 현재 `displayItems`에 없는 다른 페이지 항목을 포함할 수 있다. 내부 key 비교는 이 항목에 대해 index를 `0`으로 fallback하여 `trackByFn(item, 0)`을 호출한다. `trackByFn`을 `(item, index) => \`${item.category}_${index}\`` 같이 **index에 의존하는 형태로 쓰면 동일 item에 대해 다른 key가 계산되어 `isSelected` 판정이 틀어진다**. 항상 item 속성만으로 key를 만든다: `(item) => item.id` 형태를 사용.
116
-
117
- ### `SdSheetColumn`
118
-
119
- 시트 컬럼 정의 디렉티브. 컬럼의 헤더, 너비, 고정, 정렬 등을 설정한다. 셀 내용은 `SdSheetColumnCellTemplate`으로 정의한다.
120
-
121
- ```typescript
122
- @Directive({ selector: "sd-sheet-column" })
123
- class SdSheetColumn<T = unknown> {
124
- key = input.required<string>();
125
- header = input<string | string[]>("");
126
- headerStyle = input<string>();
127
- tooltip = input<string>();
128
- width = input<string>();
129
- fixed = input(false, { transform: booleanAttribute });
130
- hidden = input(false, { transform: booleanAttribute });
131
- collapse = input(false, { transform: booleanAttribute });
132
- disableSorting = input(false, { transform: booleanAttribute });
133
- disableResizing = input(false, { transform: booleanAttribute });
134
- ordering = input(0);
135
-
136
- cellTplRef = contentChild.required(SdSheetColumnCellTemplate, { read: TemplateRef });
137
- headerTplRef = contentChild<TemplateRef<void>>("headerTpl");
138
- summaryTplRef = contentChild<TemplateRef<void>>("summaryTpl");
139
- }
140
- ```
141
-
142
- | Input | Type | Default | Description |
143
- |-------|------|---------|-------------|
144
- | `key` | `string` | required | 컬럼 식별 키 |
145
- | `header` | `string \| string[]` | `""` | 헤더 텍스트 (배열이면 멀티 행 헤더) |
146
- | `headerStyle` | `string \| undefined` | - | 헤더 셀 인라인 스타일 |
147
- | `tooltip` | `string \| undefined` | - | 헤더 툴팁 텍스트 |
148
- | `width` | `string \| undefined` | - | 컬럼 너비 (예: `"100px"`) |
149
- | `fixed` | `boolean` | `false` | 고정 컬럼 |
150
- | `hidden` | `boolean` | `false` | 숨김 |
151
- | `collapse` | `boolean` | `false` | 접힘 (너비 축소) |
152
- | `disableSorting` | `boolean` | `false` | 정렬 비활성화 |
153
- | `disableResizing` | `boolean` | `false` | 리사이즈 비활성화 |
154
- | `ordering` | `number` | `0` | 순서 (낮을수록 앞) |
155
-
156
- Content children:
157
- - `SdSheetColumnCellTemplate` (required): 셀 렌더링 템플릿
158
- - `#headerTpl`: 커스텀 헤더 템플릿
159
- - `#summaryTpl`: 요약 행 템플릿
160
-
161
- ### `SdSheetColumnCellTemplate`
162
-
163
- 시트 컬럼 셀 내용을 정의하는 디렉티브. `ng-template[cell]` 셀렉터를 사용하며, `SdSheetCellContext` 타입 가드를 제공한다.
164
-
165
- ```typescript
166
- @Directive({ selector: "ng-template[cell]" })
167
- class SdSheetColumnCellTemplate<T> {
168
- cell = input.required<T[]>();
169
-
170
- static ngTemplateContextGuard<TContextItem>(
171
- _dir: SdSheetColumnCellTemplate<TContextItem>,
172
- _ctx: unknown,
173
- ): _ctx is SdSheetCellContext<TContextItem>;
174
- }
175
- ```
176
-
177
- 사용법:
178
- ```html
179
- <sd-sheet-column key="name" header="이름">
180
- <ng-template [cell]="items()" let-item>
181
- {{ item.name }}
182
- </ng-template>
183
- </sd-sheet-column>
184
- ```
185
-
186
- **셀 내용 작성 지침**:
187
-
188
- - **일반 텍스트/값 표시**: 바깥에 `<div class="p-xs-sm">`로 감싸 기본 패딩을 적용한다. 정렬이 필요하면 `tx-right`, `tx-center` 등을 함께 사용한다.
189
- - **컨트롤(textfield/select/checkbox 등) 삽입**: 반드시 `[inset]="true"`와 `[size]="'sm'"`을 지정한다. `inset`은 컨트롤의 테두리·배경을 제거해 셀에 자연스럽게 녹아들게 하고, `sm` 사이즈는 시트 행 높이에 맞춘다. 이 경우 별도 `p-xs-sm` 래퍼는 사용하지 않는다.
190
-
191
- 예시:
192
- ```html
193
- <!-- 일반 값 표시 -->
194
- <sd-sheet-column [fixed]="true" [header]="'#'" [key]="'id'">
195
- <ng-template [cell]="items()" let-item>
196
- <div class="p-xs-sm tx-right">{{ item.id }}</div>
197
- </ng-template>
198
- </sd-sheet-column>
199
-
200
- <!-- 컨트롤 삽입 -->
201
- <sd-sheet-column [header]="'코드'" [key]="'code'">
202
- <ng-template [cell]="items()" let-item let-edit="edit">
203
- <sd-textfield
204
- [type]="'text'"
205
- [inset]="true"
206
- [size]="'sm'"
207
- [required]="true"
208
- [disabled]="!canEdit()"
209
- [readonly]="!edit"
210
- [(value)]="item.code"
211
- (valueChange)="mark(items)"
212
- />
213
- </ng-template>
214
- </sd-sheet-column>
215
- ```
216
-
217
- ### `SdSheetCellContext`
218
-
219
- 시트 셀 템플릿 컨텍스트.
220
-
221
- ```typescript
222
- interface SdSheetCellContext<T = unknown> {
223
- $implicit: T;
224
- item: T;
225
- index: number;
226
- depth: number;
227
- edit: boolean;
228
- }
229
- ```
230
-
231
- | Field | Type | Description |
232
- |-------|------|-------------|
233
- | `$implicit` | `T` | 현재 항목 (let-item으로 접근) |
234
- | `item` | `T` | 현재 항목 (명시적 접근) |
235
- | `index` | `number` | 행 인덱스 |
236
- | `depth` | `number` | 트리 깊이 |
237
- | `edit` | `boolean` | 편집 모드 여부 (인라인 편집 지원 시 셀에서 참조) |
238
-
239
- ### `SdSheetConfigModal`
240
-
241
- 시트 설정 모달. 컬럼 표시/숨김, 고정, 너비 등을 설정한다.
242
-
243
- ```typescript
244
- @Component({ selector: "sd-sheet-config-modal" })
245
- class SdSheetConfigModal implements SdModalContentDef<SdSheetConfig> {
246
- controls = input.required<readonly SdSheetColumn[]>();
247
- config = input.required<SdSheetConfig | undefined>();
248
- close = output<SdSheetConfig>();
249
- initialized = signal(true);
250
- }
251
- ```
252
-
253
- ### `SdSheetColumnDef`
254
-
255
- ```typescript
256
- interface SdSheetColumnDef {
257
- key: string;
258
- header: string | string[];
259
- headerStyle: string | undefined;
260
- tooltip: string | undefined;
261
- width: string | undefined;
262
- fixed: boolean;
263
- hidden: boolean;
264
- collapse: boolean;
265
- disableSorting: boolean;
266
- disableResizing: boolean;
267
- ordering: number;
268
- }
269
- ```
270
-
271
- | Field | Type | Description |
272
- |-------|------|-------------|
273
- | `key` | `string` | 컬럼 식별 키 |
274
- | `header` | `string \| string[]` | 헤더 텍스트 |
275
- | `headerStyle` | `string \| undefined` | 헤더 셀 인라인 스타일 |
276
- | `tooltip` | `string \| undefined` | 헤더 툴팁 텍스트 |
277
- | `width` | `string \| undefined` | 컬럼 너비 |
278
- | `fixed` | `boolean` | 고정 컬럼 여부 |
279
- | `hidden` | `boolean` | 숨김 여부 |
280
- | `collapse` | `boolean` | 접힘 여부 |
281
- | `disableSorting` | `boolean` | 정렬 비활성화 여부 |
282
- | `disableResizing` | `boolean` | 리사이즈 비활성화 여부 |
283
- | `ordering` | `number` | 순서 |
284
-
285
- ### `SdSheetConfig`
286
-
287
- ```typescript
288
- interface SdSheetConfig {
289
- columnRecord: Record<string, {
290
- width?: string;
291
- hidden?: boolean;
292
- fixed?: boolean;
293
- ordering?: number;
294
- }>;
295
- }
296
- ```
297
-
298
- ### `SdSheetHeaderDef`
299
-
300
- ```typescript
301
- interface SdSheetHeaderDef {
302
- text: string;
303
- colspan: number;
304
- rowspan: number;
305
- isLastRow: boolean;
306
- colDef: SdSheetColumnDef | undefined;
307
- }
308
- ```
309
-
310
- ### `SdSheetItemKeydownEventParam`
311
-
312
- ```typescript
313
- interface SdSheetItemKeydownEventParam<T> {
314
- item: T;
315
- event: KeyboardEvent;
316
- }
317
- ```
318
-
319
- ### `SdSheetCellKeydownEventParam`
320
-
321
- ```typescript
322
- interface SdSheetCellKeydownEventParam<T> {
323
- item: T;
324
- key: string;
325
- event: KeyboardEvent;
326
- }
327
- ```
328
-
329
- | Field | Type | Description |
330
- |-------|------|-------------|
331
- | `item` | `T` | 해당 행 항목 |
332
- | `key` | `string` | 컬럼 키 |
333
- | `event` | `KeyboardEvent` | 키보드 이벤트 |