@simplysm/angular 14.0.49 → 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 (134) hide show
  1. package/README.md +234 -225
  2. package/dist/controls/select/sd-select.js +3 -3
  3. package/dist/layout/dock/sd-dock-container.js +1 -1
  4. package/docs/bootstrap/provide-sd-angular.md +37 -0
  5. package/docs/bootstrap/sd-angular-config-provider.md +16 -0
  6. package/docs/directives/sd-command-directive.md +30 -0
  7. package/docs/directives/sd-events.md +25 -0
  8. package/docs/directives/sd-intersection-directive.md +36 -0
  9. package/docs/directives/sd-invalid.md +24 -0
  10. package/docs/directives/sd-resize-directive.md +42 -0
  11. package/docs/directives/sd-ripple.md +23 -0
  12. package/docs/directives/sd-router-link.md +38 -0
  13. package/docs/directives/sd-show-effect.md +18 -0
  14. package/docs/directives/sd-typed-template.md +69 -0
  15. package/docs/features/sd-address-search-modal.md +50 -0
  16. package/docs/features/sd-permission-table.md +20 -0
  17. package/docs/features/sd-shared-data-components.md +158 -0
  18. package/docs/features/sd-tiptap-editor.md +26 -0
  19. package/docs/{pipes.md → pipes/format-pipe.md} +14 -5
  20. package/docs/plugins/sd-global-error-handler.md +23 -0
  21. package/docs/{plugins.md → plugins/sd-option-event-plugin.md} +9 -12
  22. package/docs/provider-types/sd-menu.md +65 -0
  23. package/docs/provider-types/sd-modal-content-def.md +148 -0
  24. package/docs/provider-types/sd-toast-content-def.md +73 -0
  25. package/docs/provider-types/shared-data-base.md +59 -0
  26. package/docs/providers/sd-activated-modal-provider.md +34 -0
  27. package/docs/providers/sd-app-structure-provider.md +81 -0
  28. package/docs/providers/sd-busy-provider.md +18 -0
  29. package/docs/providers/sd-file-dialog-provider.md +40 -0
  30. package/docs/providers/sd-local-storage-provider.md +20 -0
  31. package/docs/providers/sd-modal-provider.md +67 -0
  32. package/docs/providers/sd-navigate-window-provider.md +18 -0
  33. package/docs/providers/sd-print-provider.md +25 -0
  34. package/docs/providers/sd-service-client-factory-provider.md +43 -0
  35. package/docs/providers/sd-shared-data-provider.md +64 -0
  36. package/docs/providers/sd-system-config-provider.md +46 -0
  37. package/docs/providers/sd-system-log-provider.md +18 -0
  38. package/docs/providers/sd-theme-provider.md +38 -0
  39. package/docs/providers/sd-toast-provider.md +65 -0
  40. package/docs/recipes/_common-rules.md +244 -0
  41. package/docs/recipes/crud-detail/extension-a-edit-save.md +230 -0
  42. package/docs/recipes/crud-detail/extension-b-delete-restore.md +142 -0
  43. package/docs/recipes/crud-detail/extension-c-modal-view.md +214 -0
  44. package/docs/recipes/crud-detail/extension-d-control-view.md +103 -0
  45. package/docs/recipes/crud-detail/extension-e-auxiliary.md +87 -0
  46. package/docs/recipes/crud-detail/extension-f-complex-detail.md +234 -0
  47. package/docs/recipes/crud-detail.md +184 -706
  48. package/docs/recipes/crud-list/extension-a-inline-edit.md +410 -0
  49. package/docs/recipes/crud-list/extension-b-selection.md +226 -0
  50. package/docs/recipes/crud-list/extension-c-inline-delete.md +87 -0
  51. package/docs/recipes/crud-list/extension-d-select-modal.md +207 -0
  52. package/docs/recipes/crud-list/extension-e-readonly-modal.md +165 -0
  53. package/docs/recipes/crud-list/extension-f-modal-edit.md +177 -0
  54. package/docs/recipes/crud-list/extension-g-excel.md +157 -0
  55. package/docs/recipes/crud-list.md +196 -787
  56. package/docs/recipes/data-select-button.md +185 -91
  57. package/docs/recipes/page-modal-container.md +168 -86
  58. package/docs/styling/classes.md +149 -0
  59. package/docs/styling/mixins.md +100 -0
  60. package/docs/styling/themes.md +35 -0
  61. package/docs/styling/variables.md +147 -0
  62. package/docs/{type-utilities.md → type-utilities/directive-input-signals.md} +17 -35
  63. package/docs/ui-data/sd-list.md +37 -0
  64. package/docs/ui-data/sd-sheet.md +227 -0
  65. package/docs/ui-form/sd-additional-button.md +26 -0
  66. package/docs/ui-form/sd-anchor.md +31 -0
  67. package/docs/ui-form/sd-button.md +105 -0
  68. package/docs/ui-form/sd-checkbox-group.md +39 -0
  69. package/docs/ui-form/sd-checkbox.md +81 -0
  70. package/docs/ui-form/sd-date-range-picker.md +27 -0
  71. package/docs/ui-form/sd-form.md +89 -0
  72. package/docs/ui-form/sd-modal-select-button.md +54 -0
  73. package/docs/ui-form/sd-numpad.md +26 -0
  74. package/docs/ui-form/sd-range.md +26 -0
  75. package/docs/ui-form/sd-select.md +68 -0
  76. package/docs/ui-form/sd-shared-data-select.md +52 -0
  77. package/docs/ui-form/sd-state-preset.md +37 -0
  78. package/docs/ui-form/sd-switch.md +27 -0
  79. package/docs/ui-form/sd-textarea.md +33 -0
  80. package/docs/ui-form/sd-textfield.md +145 -0
  81. package/docs/ui-layout/sd-dock-container.md +64 -0
  82. package/docs/ui-layout/sd-dock.md +37 -0
  83. package/docs/ui-layout/sd-gap.md +26 -0
  84. package/docs/{ui-layout.md → ui-layout/sd-kanban-board.md} +41 -85
  85. package/docs/ui-layout/sd-kanban-lane.md +34 -0
  86. package/docs/ui-layout/sd-kanban.md +29 -0
  87. package/docs/ui-navigation/sd-collapse.md +35 -0
  88. package/docs/ui-navigation/sd-pagination.md +26 -0
  89. package/docs/ui-navigation/sd-sidebar-container.md +49 -0
  90. package/docs/ui-navigation/sd-sidebar-menu.md +22 -0
  91. package/docs/ui-navigation/sd-sidebar-user.md +43 -0
  92. package/docs/ui-navigation/sd-tab.md +51 -0
  93. package/docs/ui-navigation/sd-topbar-container.md +97 -0
  94. package/docs/ui-navigation/sd-topbar-menu.md +23 -0
  95. package/docs/ui-navigation/sd-topbar-user.md +38 -0
  96. package/docs/ui-navigation/sd-topbar.md +30 -0
  97. package/docs/ui-overlay/sd-busy-container.md +69 -0
  98. package/docs/ui-overlay/sd-confirm-modal.md +30 -0
  99. package/docs/ui-overlay/sd-dropdown.md +40 -0
  100. package/docs/ui-overlay/sd-modal.md +34 -0
  101. package/docs/ui-overlay/sd-prompt-modal.md +30 -0
  102. package/docs/ui-overlay/sd-toast.md +35 -0
  103. package/docs/ui-visual/sd-barcode.md +36 -0
  104. package/docs/ui-visual/sd-calendar.md +34 -0
  105. package/docs/ui-visual/sd-echarts.md +32 -0
  106. package/docs/ui-visual/sd-label.md +24 -0
  107. package/docs/ui-visual/sd-note.md +23 -0
  108. package/docs/ui-visual/sd-progress.md +23 -0
  109. package/docs/utils/inject-routing-signals.md +161 -0
  110. package/docs/utils/inject-sd-system-config-resource.md +35 -0
  111. package/docs/utils/mark.md +43 -0
  112. package/docs/utils/selection-managers.md +96 -0
  113. package/docs/utils/set-safe-style.md +19 -0
  114. package/docs/utils/setup-functions.md +93 -0
  115. package/package.json +5 -5
  116. package/src/controls/select/sd-select.ts +3 -3
  117. package/src/core/modal/sd-modal.provider.ts +1 -1
  118. package/src/core/modal/sd-modal.ts +1 -1
  119. package/src/core/routing/menu-utils.ts +1 -1
  120. package/src/core/shared-data/sd-shared-data.provider.ts +7 -7
  121. package/src/data/shared-data/sd-shared-data-select.ts +2 -2
  122. package/src/layout/dock/sd-dock-container.ts +1 -1
  123. package/docs/bootstrap.md +0 -38
  124. package/docs/directives.md +0 -236
  125. package/docs/features.md +0 -154
  126. package/docs/provider-types.md +0 -283
  127. package/docs/providers.md +0 -379
  128. package/docs/styling.md +0 -222
  129. package/docs/ui-data.md +0 -333
  130. package/docs/ui-form.md +0 -502
  131. package/docs/ui-navigation.md +0 -303
  132. package/docs/ui-overlay.md +0 -157
  133. package/docs/ui-visual.md +0 -127
  134. package/docs/utils.md +0 -244
@@ -0,0 +1,145 @@
1
+ # `SdTextfield`
2
+
3
+ 텍스트 입력 컴포넌트. 13가지 타입을 지원한다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-textfield" })
7
+ class SdTextfield<K extends keyof SdTextfieldTypes> {
8
+ value = model<SdTextfieldTypes[K]>();
9
+ type = input.required<K>();
10
+ placeholder = input<string>();
11
+ title = input<string>();
12
+ inputStyle = input<string>();
13
+ inputClass = input<string>();
14
+ disabled = input(false, { transform: booleanAttribute });
15
+ readonly = input(false, { transform: booleanAttribute });
16
+ required = input(false, { transform: booleanAttribute });
17
+ min = input<SdTextfieldTypes[K]>();
18
+ max = input<SdTextfieldTypes[K]>();
19
+ minlength = input<number>();
20
+ maxlength = input<number>();
21
+ pattern = input<string>();
22
+ validatorFn = input<(value: SdTextfieldTypes[K] | undefined) => string | undefined>();
23
+ format = input<string>();
24
+ step = input<number>();
25
+ autocomplete = input<string>();
26
+ useNumberComma = input(true, { transform: booleanAttribute });
27
+ minDigits = input<number>();
28
+ inline = input(false, { transform: booleanAttribute });
29
+ inset = input(false, { transform: booleanAttribute });
30
+ size = input<"sm" | "lg">();
31
+ theme = input<string>();
32
+ }
33
+ ```
34
+
35
+ ## Members
36
+
37
+ | Member | Kind | Type | Default | Description |
38
+ |--------|------|------|---------|-------------|
39
+ | `type` | input (required) | `keyof SdTextfieldTypes` | - | 입력 타입 (number, text, password, color, email, format, date, month, year, datetime, datetime-sec, time, time-sec) |
40
+ | `value` | model | `SdTextfieldTypes[K] \| undefined` | - | 값 (two-way) |
41
+ | `placeholder` | input | `string \| undefined` | `undefined` | 플레이스홀더 |
42
+ | `title` | input | `string \| undefined` | `undefined` | title 속성 |
43
+ | `inputStyle` | input | `string \| undefined` | `undefined` | input 인라인 스타일 |
44
+ | `inputClass` | input | `string \| undefined` | `undefined` | input CSS 클래스 |
45
+ | `disabled` | input | `boolean` | `false` | 비활성화 |
46
+ | `readonly` | input | `boolean` | `false` | 읽기 전용 |
47
+ | `required` | input | `boolean` | `false` | 필수 |
48
+ | `min` | input | `SdTextfieldTypes[K] \| undefined` | `undefined` | 최소값 |
49
+ | `max` | input | `SdTextfieldTypes[K] \| undefined` | `undefined` | 최대값 |
50
+ | `minlength` | input | `number \| undefined` | `undefined` | 최소 길이 |
51
+ | `maxlength` | input | `number \| undefined` | `undefined` | 최대 길이 |
52
+ | `pattern` | input | `string \| undefined` | `undefined` | 입력 패턴 (정규식) |
53
+ | `validatorFn` | input | `((value) => string \| undefined) \| undefined` | `undefined` | 커스텀 유효성 검증 함수 (에러 메시지 반환) |
54
+ | `format` | input | `string \| undefined` | `undefined` | format 타입에서 사용할 포맷 문자열 |
55
+ | `step` | input | `number \| undefined` | `undefined` | 증감 단위 |
56
+ | `autocomplete` | input | `string \| undefined` | `undefined` | autocomplete 속성 |
57
+ | `useNumberComma` | input | `boolean` | `true` | number 타입에서 천 단위 쉼표 사용 |
58
+ | `minDigits` | input | `number \| undefined` | `undefined` | number 타입 최소 자릿수 |
59
+ | `inline` | input | `boolean` | `false` | 인라인 표시 |
60
+ | `inset` | input | `boolean` | `false` | 삽입 스타일 |
61
+ | `size` | input | `"sm" \| "lg" \| undefined` | `undefined` | 크기 |
62
+ | `theme` | input | `string \| undefined` | `undefined` | 테마 |
63
+
64
+ **스타일 적용**: 입력 영역 스타일은 `inputClass`/`inputStyle`을 사용한다. 호스트(`<sd-textfield>`)에 직접 `class`/`style`을 줘도 입력 영역 외형은 변경되지 않는다.
65
+
66
+ ### 실사용 예
67
+
68
+ - [crud-list.md §3 최소 뼈대: 조회 전용 page](../recipes/crud-list.md#3-최소-뼈대-조회-전용-page) — 필터 영역 텍스트 입력
69
+ - [crud-list.md §5 확장 A: inline 편집/저장](../recipes/crud-list.md#5-확장-a-inline-편집저장) — 시트 셀 내 편집 (inset+sm, readonly=!edit)
70
+ - [crud-detail.md §3 최소 뼈대: 읽기 전용 상세 폼](../recipes/crud-detail.md#3-최소-뼈대-읽기-전용-상세-폼) — 읽기 전용 필드 (readonly=true)
71
+ - [crud-detail.md §5 확장 A: 편집/저장](../recipes/crud-detail.md#5-확장-a-편집저장) — 편집 가능 필드 (disabled=!canEdit)
72
+ - [crud-detail.md §10 확장 F: 복합 상세](../recipes/crud-detail.md#10-확장-f-복합-상세-내부-sd-sheet) — 하위 컬렉션 시트 셀 내 편집
73
+
74
+ ## Related Types
75
+
76
+ ### `SdTextarea`
77
+
78
+ 멀티라인 텍스트 입력 컴포넌트.
79
+
80
+ ```typescript
81
+ @Component({ selector: "sd-textarea" })
82
+ class SdTextarea {
83
+ value = model<string>();
84
+ placeholder = input<string>();
85
+ title = input<string>();
86
+ minRows = input<number>(1);
87
+ disabled = input(false, { transform: booleanAttribute });
88
+ readonly = input(false, { transform: booleanAttribute });
89
+ required = input(false, { transform: booleanAttribute });
90
+ inline = input(false, { transform: booleanAttribute });
91
+ inset = input(false, { transform: booleanAttribute });
92
+ size = input<"sm" | "lg">();
93
+ validatorFn = input<(value: string | undefined) => string | undefined>();
94
+ theme = input<string>();
95
+ inputStyle = input<string>();
96
+ inputClass = input<string>();
97
+ }
98
+ ```
99
+
100
+ ### `SdNumpad`
101
+
102
+ 숫자 패드 컴포넌트.
103
+
104
+ ```typescript
105
+ @Component({ selector: "sd-numpad" })
106
+ class SdNumpad {
107
+ placeholder = input<string>();
108
+ value = model<number>();
109
+ required = input(false, { transform: booleanAttribute });
110
+ inputDisabled = input(false, { transform: booleanAttribute });
111
+ useEnterButton = input(false, { transform: booleanAttribute });
112
+ useMinusButton = input(false, { transform: booleanAttribute });
113
+ enterButtonClick = output();
114
+ }
115
+ ```
116
+
117
+ ### `SdRange`
118
+
119
+ 범위 슬라이더 컴포넌트.
120
+
121
+ ```typescript
122
+ @Component({ selector: "sd-range" })
123
+ class SdRange<K extends keyof SdTextfieldTypes> {
124
+ type = input.required<K>();
125
+ from = model<SdTextfieldTypes[K]>();
126
+ to = model<SdTextfieldTypes[K]>();
127
+ inputStyle = input<string>();
128
+ required = input(false, { transform: booleanAttribute });
129
+ disabled = input(false, { transform: booleanAttribute });
130
+ }
131
+ ```
132
+
133
+ ### `SdDateRangePicker`
134
+
135
+ 날짜 범위 선택기.
136
+
137
+ ```typescript
138
+ @Component({ selector: "sd-date-range-picker" })
139
+ class SdDateRangePicker {
140
+ periodType = model<"일" | "월" | "범위">("범위");
141
+ from = model<DateOnly>();
142
+ to = model<DateOnly>();
143
+ required = input(false, { transform: booleanAttribute });
144
+ }
145
+ ```
@@ -0,0 +1,64 @@
1
+ # `SdDockContainer`
2
+
3
+ 도킹 레이아웃 컨테이너. `SdDock`과 함께 사용하여 상/하/좌/우 고정 영역을 만든다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-dock-container" })
7
+ class SdDockContainer { }
8
+ ```
9
+
10
+ ## Related Types
11
+
12
+ ### `SdDock`
13
+
14
+ 도킹 영역 컴포넌트. `SdDockContainer` 내부에서 사용.
15
+
16
+ ```typescript
17
+ @Component({ selector: "sd-dock" })
18
+ class SdDock {
19
+ key = input<string>();
20
+ position = input<"top" | "bottom" | "right" | "left">("top");
21
+ resizable = input(false, { transform: booleanAttribute });
22
+ }
23
+ ```
24
+
25
+ | Input | Type | Default | Description |
26
+ |-------|------|---------|-------------|
27
+ | `key` | `string \| undefined` | `undefined` | 리사이즈 설정 저장 키 |
28
+ | `position` | `"top" \| "bottom" \| "right" \| "left"` | `"top"` | 도킹 위치 |
29
+ | `resizable` | `boolean` | `false` | 크기 조절 가능 여부 |
30
+
31
+ ## Usage
32
+
33
+ 필터·도구 바는 `position="top"` (기본값이므로 생략 가능), 하단 액션 바는 `[position]="'bottom'"`으로 배치한다.
34
+
35
+ ```html
36
+ <sd-dock-container>
37
+ <sd-dock>
38
+ <!-- 상단 필터/도구 바 (기본 position="top") -->
39
+ </sd-dock>
40
+ <!-- 메인 콘텐츠 -->
41
+ <sd-dock [position]="'bottom'">
42
+ <!-- 하단 액션 바 -->
43
+ </sd-dock>
44
+ </sd-dock-container>
45
+ ```
46
+
47
+ > **CRITICAL — modal 하단 바에 `[position]="'bottom'"` 반드시 명시**
48
+ > 기본값은 `"top"`이다. modal 하단 액션 바에 `[position]`을 누락하면 상단에 렌더링되어 레이아웃이 깨진다.
49
+
50
+ ### 실사용 예
51
+
52
+ - [crud-list.md §3 최소 뼈대: 조회 전용 page](../recipes/crud-list.md#3-최소-뼈대-조회-전용-page) — 필터 영역 dock(top)
53
+ - [crud-list.md §8 확장 D: 선택 모달 전환](../recipes/crud-list.md#8-확장-d-선택-모달-전환) — modal 하단 선택 바 dock(bottom)
54
+ - [crud-detail.md §7 확장 C: modal 뷰](../recipes/crud-detail.md#7-확장-c-modal-뷰) — modal 하단 액션 바 dock(bottom)
55
+ - [crud-detail.md §8 확장 D: control 뷰](../recipes/crud-detail.md#8-확장-d-control-뷰) — control 상단 바 dock(top)
56
+
57
+ ## `SdGap`
58
+
59
+ 간격(gap) 컴포넌트. 요소 사이에 공간을 추가한다.
60
+
61
+ ```typescript
62
+ @Component({ selector: "sd-gap" })
63
+ class SdGap { }
64
+ ```
@@ -0,0 +1,37 @@
1
+ # `SdDock`
2
+
3
+ `SdDockContainer` 내부에 배치되는 도킹 패널 컴포넌트. `position`으로 도킹 위치를 지정하고, `resizable`로 크기 조절을 허용한다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-dock", ... })
7
+ export class SdDock
8
+ ```
9
+
10
+ ## Members
11
+
12
+ | Member | Kind | Type | Description |
13
+ |--------|------|------|-------------|
14
+ | `key` | input | `string \| undefined` | 시스템 설정 저장 키 (크기 저장에 사용) |
15
+ | `position` | input | `"top" \| "bottom" \| "right" \| "left"` | 도킹 위치 (기본값: `"top"`) |
16
+ | `resizable` | input | `boolean` | 크기 조절 가능 여부 (기본값: `false`) |
17
+
18
+ ## Usage
19
+
20
+ ```html
21
+ <sd-dock-container>
22
+ <sd-dock [position]="'top'">
23
+ <!-- 상단 고정 영역 -->
24
+ </sd-dock>
25
+ <sd-dock [position]="'bottom'" [resizable]="true" [key]="'my-page-bottom-dock'">
26
+ <!-- 하단 조절 가능 영역 -->
27
+ </sd-dock>
28
+ <ng-content /> <!-- 나머지 영역 -->
29
+ </sd-dock-container>
30
+ ```
31
+
32
+ ### 실사용 예
33
+
34
+ - [crud-list.md §3 최소 뼈대: 조회 전용 page](../recipes/crud-list.md#3-최소-뼈대-조회-전용-page) — 필터 영역 dock(top)
35
+ - [crud-list.md §8 확장 D: 선택 모달 전환](../recipes/crud-list.md#8-확장-d-선택-모달-전환) — modal 하단 선택 바 dock(bottom)
36
+ - [crud-detail.md §7 확장 C: modal 뷰](../recipes/crud-detail.md#7-확장-c-modal-뷰) — modal 하단 액션 바 dock(bottom)
37
+ - [crud-detail.md §8 확장 D: control 뷰](../recipes/crud-detail.md#8-확장-d-control-뷰) — control 상단 바 dock(top)
@@ -0,0 +1,26 @@
1
+ # `SdGap`
2
+
3
+ 레이아웃 간격 컴포넌트. 세로/가로 공백을 삽입한다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-gap", ... })
7
+ export class SdGap
8
+ ```
9
+
10
+ ## Members
11
+
12
+ | Member | Kind | Type | Description |
13
+ |--------|------|------|-------------|
14
+ | `height` | input | `"xxs" \| "xs" \| "sm" \| "default" \| "lg" \| "xl" \| "xxl" \| undefined` | 세로 간격 (CSS 변수 `--gap-*` 기반) |
15
+ | `heightPx` | input | `number \| undefined` | 세로 간격 (픽셀) |
16
+ | `width` | input | `"xxs" \| "xs" \| "sm" \| "default" \| "lg" \| "xl" \| "xxl" \| undefined` | 가로 간격 (CSS 변수 `--gap-*` 기반) |
17
+ | `widthPx` | input | `number \| undefined` | 가로 간격 (픽셀) |
18
+ | `widthEm` | input | `number \| undefined` | 가로 간격 (em) |
19
+
20
+ ## Usage
21
+
22
+ ```html
23
+ <sd-gap [height]="'lg'" />
24
+ <sd-gap [width]="'default'" />
25
+ <sd-gap [heightPx]="32" />
26
+ ```
@@ -1,57 +1,65 @@
1
- # UI - Layout
1
+ # `SdKanbanBoard`
2
2
 
3
- ## `SdDockContainer`
4
-
5
- 도킹 레이아웃 컨테이너. `SdDock`과 함께 사용하여 상/하/좌/우 고정 영역을 만든다.
3
+ 칸반 보드 컨테이너. 드래그앤드롭을 지원한다.
6
4
 
7
5
  ```typescript
8
- @Component({ selector: "sd-dock-container" })
9
- class SdDockContainer { }
6
+ @Component({ selector: "sd-kanban-board" })
7
+ class SdKanbanBoard<L, T> {
8
+ selectedValues = model<T[]>([]);
9
+ drop = output<SdKanbanBoardDropInfo<L, T>>();
10
+ }
10
11
  ```
11
12
 
12
- ## `SdDock`
13
+ ## Members
14
+
15
+ | Member | Kind | Type | Default | Description |
16
+ |--------|------|------|---------|-------------|
17
+ | `selectedValues` | model | `T[]` | `[]` | 선택된 칸반 아이템 값 배열 (two-way) |
18
+ | `drop` | output | `SdKanbanBoardDropInfo<L, T>` | - | 드롭 완료 시 발생 |
19
+
20
+ ## Related Types
13
21
 
14
- 도킹 영역 컴포넌트. `SdDockContainer` 내부에서 사용.
22
+ ### `SdKanban`
23
+
24
+ 칸반 아이템 컴포넌트.
15
25
 
16
26
  ```typescript
17
- @Component({ selector: "sd-dock" })
18
- class SdDock {
19
- key = input<string>();
20
- position = input<"top" | "bottom" | "right" | "left">("top");
21
- resizable = input(false, { transform: booleanAttribute });
27
+ @Component({ selector: "sd-kanban" })
28
+ class SdKanban<L, T> {
29
+ value = input<T>();
30
+ selectable = input(false, { transform: booleanAttribute });
31
+ draggable = input(false, { transform: booleanAttribute });
32
+ contentClass = input<string>();
22
33
  }
23
34
  ```
24
35
 
25
36
  | Input | Type | Default | Description |
26
37
  |-------|------|---------|-------------|
27
- | `key` | `string \| undefined` | `undefined` | 리사이즈 설정 저장 |
28
- | `position` | `"top" \| "bottom" \| "right" \| "left"` | `"top"` | 도킹 위치 |
29
- | `resizable` | `boolean` | `false` | 크기 조절 가능 여부 |
30
-
31
- ## `SdGap`
32
-
33
- 간격(gap) 컴포넌트. 요소 사이에 공간을 추가한다.
34
-
35
- ```typescript
36
- @Component({ selector: "sd-gap" })
37
- class SdGap { }
38
- ```
38
+ | `value` | `T \| undefined` | `undefined` | 칸반 아이템의 |
39
+ | `selectable` | `boolean` | `false` | 선택 가능 여부 |
40
+ | `draggable` | `boolean` | `false` | 드래그 가능 여부 |
41
+ | `contentClass` | `string \| undefined` | `undefined` | 컨텐츠 CSS 클래스 |
39
42
 
40
- ## `SdKanbanBoard`
43
+ ### `SdKanbanLane`
41
44
 
42
- 칸반 보드 컨테이너. 드래그앤드롭을 지원한다.
45
+ 칸반 레인 컴포넌트.
43
46
 
44
47
  ```typescript
45
- @Component({ selector: "sd-kanban-board" })
46
- class SdKanbanBoard<L, T> {
47
- selectedValues = model<T[]>([]);
48
- drop = output<SdKanbanBoardDropInfo<L, T>>();
48
+ @Component({ selector: "sd-kanban-lane" })
49
+ class SdKanbanLane<L, T> {
50
+ busy = input(false, { transform: booleanAttribute });
51
+ useCollapse = input(false, { transform: booleanAttribute });
52
+ collapse = model(false);
53
+ value = input<L>();
49
54
  }
50
55
  ```
51
56
 
52
57
  | Input | Type | Default | Description |
53
58
  |-------|------|---------|-------------|
54
- | `selectedValues` | `T[]` | `[]` | 선택된 칸반 아이템 값 배열 (two-way) |
59
+ | `busy` | `boolean` | `false` | busy 상태 |
60
+ | `useCollapse` | `boolean` | `false` | 접기 기능 사용 |
61
+ | `collapse` | `boolean` | `false` | 접힘 상태 (two-way) |
62
+ | `value` | `L \| undefined` | `undefined` | 레인의 값 |
55
63
 
56
64
  ### `SdKanbanBoardDropInfo`
57
65
 
@@ -67,7 +75,7 @@ interface SdKanbanBoardDropInfo<L, T> {
67
75
  |-------|------|-------------|
68
76
  | `sourceKanbanValue` | `T \| undefined` | 드래그한 칸반 아이템의 값 |
69
77
  | `targetLaneValue` | `L \| undefined` | 드롭 대상 레인의 값 |
70
- | `targetKanbanValue` | `T \| undefined` | 드롭 대상 칸반 아이템의 값 (칸반 위에 드롭 시) |
78
+ | `targetKanbanValue` | `T \| undefined` | 드롭 대상 칸반 아이템의 값 |
71
79
 
72
80
  ### `SdKanbanDragRef`
73
81
 
@@ -78,11 +86,6 @@ interface SdKanbanDragRef<_L, T> {
78
86
  }
79
87
  ```
80
88
 
81
- | Field | Type | Description |
82
- |-------|------|-------------|
83
- | `value()` | `T \| undefined` | 드래그 중인 칸반 아이템의 값 |
84
- | `heightOnDrag()` | `number` | 드래그 시작 시점의 요소 높이 |
85
-
86
89
  ### `SdKanbanDropTarget`
87
90
 
88
91
  ```typescript
@@ -91,50 +94,3 @@ interface SdKanbanDropTarget<L, T> {
91
94
  targetKanbanValue?(): T | undefined;
92
95
  }
93
96
  ```
94
-
95
- | Field | Type | Description |
96
- |-------|------|-------------|
97
- | `targetLaneValue()` | `L \| undefined` | 드롭 대상 레인의 값 |
98
- | `targetKanbanValue?()` | `T \| undefined` | 드롭 대상 칸반 아이템의 값 (optional) |
99
-
100
- ## `SdKanban`
101
-
102
- 칸반 아이템 컴포넌트.
103
-
104
- ```typescript
105
- @Component({ selector: "sd-kanban" })
106
- class SdKanban<L, T> {
107
- value = input<T>();
108
- selectable = input(false, { transform: booleanAttribute });
109
- draggable = input(false, { transform: booleanAttribute });
110
- contentClass = input<string>();
111
- }
112
- ```
113
-
114
- | Input | Type | Default | Description |
115
- |-------|------|---------|-------------|
116
- | `value` | `T \| undefined` | `undefined` | 칸반 아이템의 값 |
117
- | `selectable` | `boolean` | `false` | 선택 가능 여부 |
118
- | `draggable` | `boolean` | `false` | 드래그 가능 여부 |
119
- | `contentClass` | `string \| undefined` | `undefined` | 컨텐츠 CSS 클래스 |
120
-
121
- ## `SdKanbanLane`
122
-
123
- 칸반 레인 컴포넌트.
124
-
125
- ```typescript
126
- @Component({ selector: "sd-kanban-lane" })
127
- class SdKanbanLane<L, T> {
128
- busy = input(false, { transform: booleanAttribute });
129
- useCollapse = input(false, { transform: booleanAttribute });
130
- collapse = model(false);
131
- value = input<L>();
132
- }
133
- ```
134
-
135
- | Input | Type | Default | Description |
136
- |-------|------|---------|-------------|
137
- | `busy` | `boolean` | `false` | busy 상태 |
138
- | `useCollapse` | `boolean` | `false` | 접기 기능 사용 |
139
- | `collapse` | `boolean` | `false` | 접힘 상태 (two-way) |
140
- | `value` | `L \| undefined` | `undefined` | 레인의 값 |
@@ -0,0 +1,34 @@
1
+ # `SdKanbanLane`
2
+
3
+ 칸반 레인 컴포넌트. `SdKanbanBoard` 내부에 배치되며, `SdKanban` 아이템을 수직으로 나열한다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-kanban-lane", ... })
7
+ export class SdKanbanLane<L, T> implements SdKanbanDropTarget<L, T>
8
+ ```
9
+
10
+ ## Members
11
+
12
+ | Member | Kind | Type | Description |
13
+ |--------|------|------|-------------|
14
+ | `value` | input | `L \| undefined` | 이 레인의 값 |
15
+ | `busy` | input | `boolean` | 로딩 표시 (기본값: `false`) |
16
+ | `useCollapse` | input | `boolean` | 접기 기능 사용 (기본값: `false`) |
17
+ | `collapse` | model | `boolean` | 접힘 상태 (기본값: `false`) |
18
+
19
+ ## Usage
20
+
21
+ ```html
22
+ <sd-kanban-board [(selectedValues)]="selectedItems">
23
+ @for (lane of lanes; track lane.id) {
24
+ <sd-kanban-lane [value]="lane">
25
+ <ng-template #titleTpl>{{ lane.name }}</ng-template>
26
+ @for (item of lane.items; track item.id) {
27
+ <sd-kanban [value]="item" [draggable]="true">
28
+ {{ item.title }}
29
+ </sd-kanban>
30
+ }
31
+ </sd-kanban-lane>
32
+ }
33
+ </sd-kanban-board>
34
+ ```
@@ -0,0 +1,29 @@
1
+ # `SdKanban`
2
+
3
+ 칸반 아이템 컴포넌트. `SdKanbanLane` 내부에 배치되며, 드래그앤드롭으로 레인 간 이동이 가능하다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-kanban", ... })
7
+ export class SdKanban<L, T> implements SdKanbanDragRef<L, T>, SdKanbanDropTarget<L, T>
8
+ ```
9
+
10
+ ## Members
11
+
12
+ | Member | Kind | Type | Description |
13
+ |--------|------|------|-------------|
14
+ | `value` | input | `T \| undefined` | 이 카드의 데이터 값 |
15
+ | `selectable` | input | `boolean` | 선택 가능 여부 (기본값: `false`) |
16
+ | `draggable` | input | `boolean` | 드래그 가능 여부 (기본값: `false`) |
17
+ | `contentClass` | input | `string \| undefined` | 카드 콘텐츠 CSS 클래스 |
18
+
19
+ ## Usage
20
+
21
+ ```html
22
+ <sd-kanban-lane [value]="lane">
23
+ @for (item of lane.items; track item.id) {
24
+ <sd-kanban [value]="item" [draggable]="true">
25
+ {{ item.title }}
26
+ </sd-kanban>
27
+ }
28
+ </sd-kanban-lane>
29
+ ```
@@ -0,0 +1,35 @@
1
+ # `SdCollapse`
2
+
3
+ 접기/펼치기 패널 컴포넌트.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-collapse" })
7
+ class SdCollapse {
8
+ open = input(false, { transform: booleanAttribute });
9
+ }
10
+ ```
11
+
12
+ ## Members
13
+
14
+ | Member | Kind | Type | Default | Description |
15
+ |--------|------|------|---------|-------------|
16
+ | `open` | input | `boolean` | `false` | 펼침 상태 |
17
+
18
+ ## Related Types
19
+
20
+ ### `SdCollapseIcon`
21
+
22
+ 접기/펼치기 아이콘 컴포넌트. 화살표 회전 애니메이션.
23
+
24
+ ```typescript
25
+ @Component({ selector: "sd-collapse-icon" })
26
+ class SdCollapseIcon {
27
+ open = input(false, { transform: booleanAttribute });
28
+ openRotate = input(90, { transform: numberAttribute });
29
+ }
30
+ ```
31
+
32
+ | Input | Type | Default | Description |
33
+ |-------|------|---------|-------------|
34
+ | `open` | `boolean` | `false` | 펼침 상태 |
35
+ | `openRotate` | `number` | `90` | 열림 시 회전 각도 |
@@ -0,0 +1,26 @@
1
+ # `SdPagination`
2
+
3
+ 페이지네이션 컴포넌트. 현재 페이지와 전체 페이지 수를 표시하고 네비게이션을 제공한다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-pagination", ... })
7
+ export class SdPagination
8
+ ```
9
+
10
+ ## Members
11
+
12
+ | Member | Kind | Type | Description |
13
+ |--------|------|------|-------------|
14
+ | `currentPage` | model | `number` | 현재 페이지 (0-based, 기본값: `0`) |
15
+ | `totalPageCount` | input | `number` | 전체 페이지 수 (기본값: `0`) |
16
+ | `visiblePageCount` | input | `number` | 한 번에 표시할 페이지 버튼 수 (기본값: `10`) |
17
+
18
+ ## Usage
19
+
20
+ ```html
21
+ <sd-pagination
22
+ [(currentPage)]="searchParams.page"
23
+ [totalPageCount]="totalPageCount()"
24
+ (currentPageChange)="onPageChange()"
25
+ />
26
+ ```
@@ -0,0 +1,49 @@
1
+ # `SdSidebarContainer`
2
+
3
+ 사이드바 컨테이너.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-sidebar-container" })
7
+ class SdSidebarContainer { }
8
+ ```
9
+
10
+ ## Related Types
11
+
12
+ ### `SdSidebar`
13
+
14
+ 사이드바 컴포넌트.
15
+
16
+ ```typescript
17
+ @Component({ selector: "sd-sidebar" })
18
+ class SdSidebar { }
19
+ ```
20
+
21
+ ### `SdSidebarMenu`
22
+
23
+ 사이드바 메뉴 항목. 재귀적 트리 구조 지원.
24
+
25
+ ```typescript
26
+ @Component({ selector: "sd-sidebar-menu" })
27
+ class SdSidebarMenu {
28
+ menus = input<SdMenu[]>([]);
29
+ layout = input<"accordion" | "flat">();
30
+ getMenuIsSelectedFn = input<(menu: SdMenu) => boolean>();
31
+ }
32
+ ```
33
+
34
+ | Input | Type | Default | Description |
35
+ |-------|------|---------|-------------|
36
+ | `menus` | `SdMenu[]` | `[]` | 메뉴 항목 |
37
+ | `layout` | `"accordion" \| "flat" \| undefined` | `undefined` | 레이아웃 모드 |
38
+ | `getMenuIsSelectedFn` | `((menu) => boolean) \| undefined` | `undefined` | 커스텀 메뉴 선택 여부 함수 |
39
+
40
+ ### `SdSidebarUser`
41
+
42
+ 사이드바 사용자 영역 컴포넌트.
43
+
44
+ ```typescript
45
+ @Component({ selector: "sd-sidebar-user" })
46
+ class SdSidebarUser {
47
+ userMenu = input<SdSidebarUserMenu>();
48
+ }
49
+ ```
@@ -0,0 +1,22 @@
1
+ # `SdSidebarMenu`
2
+
3
+ 사이드바 메뉴 컴포넌트. `SdMenu[]` 트리를 받아 아코디언 또는 플랫 레이아웃으로 렌더링한다.
4
+
5
+ ```typescript
6
+ @Component({ selector: "sd-sidebar-menu", ... })
7
+ export class SdSidebarMenu
8
+ ```
9
+
10
+ ## Members
11
+
12
+ | Member | Kind | Type | Description |
13
+ |--------|------|------|-------------|
14
+ | `menus` | input | `SdMenu[]` | 메뉴 트리 (기본값: `[]`) |
15
+ | `layout` | input | `"accordion" \| "flat" \| undefined` | 레이아웃. 미지정 시 메뉴 수 ≤ 3이면 `"flat"`, 초과이면 `"accordion"` |
16
+ | `getMenuIsSelectedFn` | input | `(menu: SdMenu) => boolean` | 메뉴 선택 여부 커스텀 함수 |
17
+
18
+ ## Usage
19
+
20
+ ```html
21
+ <sd-sidebar-menu [menus]="sdAppStructure.usableMenus()" />
22
+ ```