@simplysm/angular 14.0.41 → 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.
Files changed (256) hide show
  1. package/dist/controls/button/sd-additional-button.js +1 -1
  2. package/dist/controls/button/sd-anchor.js +1 -1
  3. package/dist/controls/button/sd-button.js +1 -1
  4. package/dist/controls/button/sd-modal-select-button.d.ts +1 -1
  5. package/dist/controls/button/sd-modal-select-button.d.ts.map +1 -1
  6. package/dist/controls/button/sd-modal-select-button.js +8 -6
  7. package/dist/controls/checkbox/sd-checkbox-group-item.js +1 -1
  8. package/dist/controls/checkbox/sd-checkbox-group.js +1 -1
  9. package/dist/controls/checkbox/sd-checkbox.js +1 -1
  10. package/dist/controls/checkbox/sd-switch.js +1 -1
  11. package/dist/controls/collapse/sd-collapse-icon.d.ts +2 -4
  12. package/dist/controls/collapse/sd-collapse-icon.d.ts.map +1 -1
  13. package/dist/controls/collapse/sd-collapse-icon.js +7 -7
  14. package/dist/controls/collapse/sd-collapse.d.ts +1 -1
  15. package/dist/controls/collapse/sd-collapse.d.ts.map +1 -1
  16. package/dist/controls/collapse/sd-collapse.js +8 -7
  17. package/dist/controls/dropdown/sd-dropdown-popup.d.ts +2 -0
  18. package/dist/controls/dropdown/sd-dropdown-popup.d.ts.map +1 -1
  19. package/dist/controls/dropdown/sd-dropdown-popup.js +21 -8
  20. package/dist/controls/dropdown/sd-dropdown.d.ts.map +1 -1
  21. package/dist/controls/dropdown/sd-dropdown.js +5 -16
  22. package/dist/controls/form/sd-form.js +1 -1
  23. package/dist/controls/gap/sd-gap.js +5 -5
  24. package/dist/controls/input/sd-date-range-picker.d.ts +1 -0
  25. package/dist/controls/input/sd-date-range-picker.d.ts.map +1 -1
  26. package/dist/controls/input/sd-date-range-picker.js +14 -19
  27. package/dist/controls/input/sd-numpad.js +3 -3
  28. package/dist/controls/input/sd-range.js +1 -1
  29. package/dist/controls/input/sd-textarea.js +2 -2
  30. package/dist/controls/input/sd-textfield-type-handlers.js +2 -2
  31. package/dist/controls/input/sd-textfield.js +9 -9
  32. package/dist/controls/list/sd-list-item.d.ts +0 -1
  33. package/dist/controls/list/sd-list-item.d.ts.map +1 -1
  34. package/dist/controls/list/sd-list-item.js +38 -38
  35. package/dist/controls/list/sd-list.d.ts.map +1 -1
  36. package/dist/controls/list/sd-list.js +3 -3
  37. package/dist/controls/pagination/sd-pagination.js +1 -1
  38. package/dist/controls/select/sd-select-button.d.ts.map +1 -1
  39. package/dist/controls/select/sd-select-button.js +4 -8
  40. package/dist/controls/select/sd-select-item.d.ts +3 -3
  41. package/dist/controls/select/sd-select-item.d.ts.map +1 -1
  42. package/dist/controls/select/sd-select-item.js +27 -20
  43. package/dist/controls/select/sd-select.d.ts +5 -4
  44. package/dist/controls/select/sd-select.d.ts.map +1 -1
  45. package/dist/controls/select/sd-select.js +20 -17
  46. package/dist/controls/tab/sd-tab-item.js +1 -1
  47. package/dist/controls/tab/sd-tab.js +1 -1
  48. package/dist/core/app-structure/sd-app-structure.utils.js +1 -1
  49. package/dist/core/busy/sd-busy-container.d.ts.map +1 -1
  50. package/dist/core/busy/sd-busy-container.js +62 -68
  51. package/dist/core/busy/sd-busy.provider.js +1 -1
  52. package/dist/core/commands/sd-command.d.ts +13 -0
  53. package/dist/core/commands/sd-command.d.ts.map +1 -0
  54. package/dist/core/commands/sd-command.js +52 -0
  55. package/dist/core/error-handler/sd-global-error-handler.plugin.js +1 -1
  56. package/dist/core/events/sd-events.d.ts +1 -6
  57. package/dist/core/events/sd-events.d.ts.map +1 -1
  58. package/dist/core/events/sd-events.js +3 -11
  59. package/dist/core/events/sd-intersection.d.ts +13 -0
  60. package/dist/core/events/sd-intersection.d.ts.map +1 -0
  61. package/dist/core/events/sd-intersection.js +27 -0
  62. package/dist/core/events/sd-resize.d.ts +16 -0
  63. package/dist/core/events/sd-resize.d.ts.map +1 -0
  64. package/dist/core/events/{sd-resize-event.plugin.js → sd-resize.js} +18 -20
  65. package/dist/core/file-dialog/sd-file-dialog.provider.js +1 -1
  66. package/dist/core/modal/injectDragResize.js +9 -9
  67. package/dist/core/modal/injectFocusTrap.js +1 -1
  68. package/dist/core/modal/sd-confirm-modal.js +1 -1
  69. package/dist/core/modal/sd-modal.d.ts +9 -1
  70. package/dist/core/modal/sd-modal.d.ts.map +1 -1
  71. package/dist/core/modal/sd-modal.js +140 -42
  72. package/dist/core/modal/sd-modal.provider.d.ts +1 -0
  73. package/dist/core/modal/sd-modal.provider.d.ts.map +1 -1
  74. package/dist/core/modal/sd-modal.provider.js +5 -5
  75. package/dist/core/modal/sd-prompt-modal.js +1 -1
  76. package/dist/core/provideSdAngular.d.ts.map +1 -1
  77. package/dist/core/provideSdAngular.js +0 -10
  78. package/dist/core/ripple/setupRipple.js +5 -5
  79. package/dist/core/routing/menu-utils.js +1 -1
  80. package/dist/core/routing/sd-navigate-window.provider.js +1 -1
  81. package/dist/core/routing/sd-router-link.js +1 -1
  82. package/dist/core/selection/setupCumulateSelectedKeys.js +3 -3
  83. package/dist/core/setupModelHook.js +1 -1
  84. package/dist/core/toast/sd-toast-container.d.ts +1 -1
  85. package/dist/core/toast/sd-toast-container.js +3 -7
  86. package/dist/core/toast/sd-toast.d.ts.map +1 -1
  87. package/dist/core/toast/sd-toast.js +27 -24
  88. package/dist/core/toast/sd-toast.provider.js +6 -6
  89. package/dist/core/validation/setupInvalid.js +2 -1
  90. package/dist/data/data-detail/sd-data-detail.d.ts +2 -1
  91. package/dist/data/data-detail/sd-data-detail.d.ts.map +1 -1
  92. package/dist/data/data-detail/sd-data-detail.js +37 -33
  93. package/dist/data/data-select-button/sd-data-select-button.js +1 -1
  94. package/dist/data/data-sheet/sd-data-sheet.d.ts +2 -1
  95. package/dist/data/data-sheet/sd-data-sheet.d.ts.map +1 -1
  96. package/dist/data/data-sheet/sd-data-sheet.js +99 -59
  97. package/dist/data/kanban/sd-kanban-board.js +1 -1
  98. package/dist/data/kanban/sd-kanban-lane.js +1 -1
  99. package/dist/data/kanban/sd-kanban.d.ts +1 -1
  100. package/dist/data/kanban/sd-kanban.d.ts.map +1 -1
  101. package/dist/data/kanban/sd-kanban.js +4 -4
  102. package/dist/data/permission-table/sd-permission-table.js +6 -6
  103. package/dist/data/shared-data/sd-shared-data-select-button.js +1 -1
  104. package/dist/data/shared-data/sd-shared-data-select-list.js +3 -3
  105. package/dist/data/shared-data/sd-shared-data-select.d.ts +1 -1
  106. package/dist/data/shared-data/sd-shared-data-select.d.ts.map +1 -1
  107. package/dist/data/shared-data/sd-shared-data-select.js +29 -54
  108. package/dist/data/sheet/injectSheetDomAccessor.d.ts +6 -2
  109. package/dist/data/sheet/injectSheetDomAccessor.d.ts.map +1 -1
  110. package/dist/data/sheet/injectSheetDomAccessor.js +27 -22
  111. package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts +10 -0
  112. package/dist/data/sheet/injectSheetSelectRowIndicator.d.ts.map +1 -0
  113. package/dist/data/sheet/injectSheetSelectRowIndicator.js +55 -0
  114. package/dist/data/sheet/sd-sheet-column-cell-template.d.ts +9 -0
  115. package/dist/data/sheet/sd-sheet-column-cell-template.d.ts.map +1 -0
  116. package/dist/data/sheet/sd-sheet-column-cell-template.js +17 -0
  117. package/dist/data/sheet/sd-sheet-column.d.ts +10 -7
  118. package/dist/data/sheet/sd-sheet-column.d.ts.map +1 -1
  119. package/dist/data/sheet/sd-sheet-column.js +10 -6
  120. package/dist/data/sheet/sd-sheet-config.modal.d.ts +19 -20
  121. package/dist/data/sheet/sd-sheet-config.modal.d.ts.map +1 -1
  122. package/dist/data/sheet/sd-sheet-config.modal.js +357 -217
  123. package/dist/data/sheet/sd-sheet.d.ts +30 -15
  124. package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
  125. package/dist/data/sheet/sd-sheet.js +617 -274
  126. package/dist/data/sheet/types.d.ts +2 -0
  127. package/dist/data/sheet/types.d.ts.map +1 -1
  128. package/dist/data/sheet/useSheetCellAgent.js +6 -6
  129. package/dist/data/sheet/useSheetCellStyling.d.ts.map +1 -1
  130. package/dist/data/sheet/useSheetCellStyling.js +11 -5
  131. package/dist/data/sheet/useSheetFocusIndicator.d.ts +7 -0
  132. package/dist/data/sheet/useSheetFocusIndicator.d.ts.map +1 -0
  133. package/dist/data/sheet/useSheetFocusIndicator.js +53 -0
  134. package/dist/data/sheet/useSheetLayoutEngine.d.ts.map +1 -1
  135. package/dist/data/sheet/useSheetLayoutEngine.js +3 -1
  136. package/dist/data/state-preset/sd-state-preset.d.ts.map +1 -1
  137. package/dist/data/state-preset/sd-state-preset.js +14 -14
  138. package/dist/features/address/sd-address-search.modal.js +3 -3
  139. package/dist/features/editor/sd-tiptap-editor.js +6 -6
  140. package/dist/features/editor/useTiptapToolbar.js +2 -2
  141. package/dist/features/theme/sd-theme-selector.js +1 -1
  142. package/dist/features/visual/sd-barcode.js +1 -1
  143. package/dist/features/visual/sd-calendar.js +2 -2
  144. package/dist/features/visual/sd-echarts.d.ts +2 -1
  145. package/dist/features/visual/sd-echarts.d.ts.map +1 -1
  146. package/dist/features/visual/sd-echarts.js +5 -3
  147. package/dist/features/visual/sd-label.js +1 -1
  148. package/dist/features/visual/sd-note.js +1 -1
  149. package/dist/features/visual/sd-progress.js +1 -1
  150. package/dist/index.d.ts +5 -6
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +4 -5
  153. package/dist/layout/base-container/sd-base-container.js +3 -3
  154. package/dist/layout/dock/sd-dock-container.js +1 -1
  155. package/dist/layout/dock/sd-dock.d.ts +3 -2
  156. package/dist/layout/dock/sd-dock.d.ts.map +1 -1
  157. package/dist/layout/dock/sd-dock.js +6 -4
  158. package/dist/layout/sidebar/sd-sidebar-container.js +5 -5
  159. package/dist/layout/sidebar/sd-sidebar-menu.d.ts.map +1 -1
  160. package/dist/layout/sidebar/sd-sidebar-menu.js +7 -6
  161. package/dist/layout/sidebar/sd-sidebar-user.js +1 -1
  162. package/dist/layout/sidebar/sd-sidebar.js +1 -1
  163. package/dist/layout/topbar/sd-topbar-container.js +1 -1
  164. package/dist/layout/topbar/sd-topbar-menu.d.ts.map +1 -1
  165. package/dist/layout/topbar/sd-topbar-menu.js +7 -7
  166. package/dist/layout/topbar/sd-topbar-user.js +1 -1
  167. package/dist/layout/topbar/sd-topbar.js +3 -3
  168. package/package.json +6 -6
  169. package/src/controls/button/sd-modal-select-button.ts +7 -2
  170. package/src/controls/collapse/sd-collapse-icon.ts +3 -4
  171. package/src/controls/collapse/sd-collapse.ts +4 -5
  172. package/src/controls/dropdown/sd-dropdown-popup.ts +15 -2
  173. package/src/controls/dropdown/sd-dropdown.ts +4 -16
  174. package/src/controls/gap/sd-gap.ts +4 -4
  175. package/src/controls/input/sd-date-range-picker.ts +13 -16
  176. package/src/controls/input/sd-numpad.ts +1 -1
  177. package/src/controls/input/sd-textarea.ts +1 -1
  178. package/src/controls/input/sd-textfield-type-handlers.ts +2 -2
  179. package/src/controls/input/sd-textfield.ts +6 -6
  180. package/src/controls/list/sd-list-item.ts +40 -26
  181. package/src/controls/list/sd-list.ts +2 -1
  182. package/src/controls/select/sd-select-button.ts +8 -11
  183. package/src/controls/select/sd-select-item.ts +35 -27
  184. package/src/controls/select/sd-select.ts +111 -41
  185. package/src/core/app-structure/sd-app-structure.utils.ts +1 -1
  186. package/src/core/busy/sd-busy-container.ts +235 -123
  187. package/src/core/busy/sd-busy.provider.ts +1 -1
  188. package/src/core/commands/sd-command.ts +46 -0
  189. package/src/core/error-handler/sd-global-error-handler.plugin.ts +1 -1
  190. package/src/core/events/sd-events.ts +1 -12
  191. package/src/core/events/sd-intersection.ts +29 -0
  192. package/src/core/events/{sd-resize-event.plugin.ts → sd-resize.ts} +17 -24
  193. package/src/core/file-dialog/sd-file-dialog.provider.ts +1 -1
  194. package/src/core/modal/injectDragResize.ts +9 -9
  195. package/src/core/modal/injectFocusTrap.ts +1 -1
  196. package/src/core/modal/sd-modal.provider.ts +6 -5
  197. package/src/core/modal/sd-modal.ts +121 -42
  198. package/src/core/provideSdAngular.ts +0 -10
  199. package/src/core/ripple/setupRipple.ts +5 -5
  200. package/src/core/routing/menu-utils.ts +1 -1
  201. package/src/core/routing/sd-navigate-window.provider.ts +1 -1
  202. package/src/core/routing/sd-router-link.ts +1 -1
  203. package/src/core/selection/setupCumulateSelectedKeys.ts +3 -3
  204. package/src/core/setupModelHook.ts +1 -1
  205. package/src/core/toast/sd-toast-container.ts +1 -1
  206. package/src/core/toast/sd-toast.provider.ts +6 -6
  207. package/src/core/toast/sd-toast.ts +25 -22
  208. package/src/core/validation/setupInvalid.ts +2 -1
  209. package/src/data/data-detail/sd-data-detail.ts +15 -11
  210. package/src/data/data-sheet/sd-data-sheet.ts +27 -20
  211. package/src/data/kanban/sd-kanban.ts +4 -5
  212. package/src/data/permission-table/sd-permission-table.ts +4 -4
  213. package/src/data/shared-data/sd-shared-data-select-list.ts +1 -1
  214. package/src/data/shared-data/sd-shared-data-select.ts +8 -27
  215. package/src/data/sheet/injectSheetDomAccessor.ts +37 -25
  216. package/src/data/sheet/injectSheetSelectRowIndicator.ts +69 -0
  217. package/src/data/sheet/sd-sheet-column-cell-template.ts +17 -0
  218. package/src/data/sheet/sd-sheet-column.ts +12 -5
  219. package/src/data/sheet/sd-sheet-config.modal.ts +215 -191
  220. package/src/data/sheet/sd-sheet.ts +534 -203
  221. package/src/data/sheet/types.ts +2 -0
  222. package/src/data/sheet/useSheetCellAgent.ts +8 -8
  223. package/src/data/sheet/useSheetCellStyling.ts +9 -9
  224. package/src/data/sheet/useSheetFocusIndicator.ts +66 -0
  225. package/src/data/sheet/useSheetLayoutEngine.ts +3 -1
  226. package/src/data/state-preset/sd-state-preset.ts +26 -13
  227. package/src/features/address/sd-address-search.modal.ts +1 -1
  228. package/src/features/editor/sd-tiptap-editor.ts +4 -4
  229. package/src/features/editor/useTiptapToolbar.ts +2 -2
  230. package/src/features/visual/sd-calendar.ts +1 -1
  231. package/src/features/visual/sd-echarts.ts +2 -0
  232. package/src/index.ts +6 -7
  233. package/src/layout/base-container/sd-base-container.ts +1 -1
  234. package/src/layout/dock/sd-dock.ts +3 -2
  235. package/src/layout/sidebar/sd-sidebar-container.ts +2 -2
  236. package/src/layout/sidebar/sd-sidebar-menu.ts +1 -3
  237. package/src/layout/topbar/sd-topbar-menu.ts +11 -15
  238. package/src/layout/topbar/sd-topbar.ts +1 -1
  239. package/dist/core/commands/sd-insert-command-event.plugin.d.ts +0 -11
  240. package/dist/core/commands/sd-insert-command-event.plugin.d.ts.map +0 -1
  241. package/dist/core/commands/sd-insert-command-event.plugin.js +0 -35
  242. package/dist/core/commands/sd-refresh-command-event.plugin.d.ts +0 -11
  243. package/dist/core/commands/sd-refresh-command-event.plugin.d.ts.map +0 -1
  244. package/dist/core/commands/sd-refresh-command-event.plugin.js +0 -38
  245. package/dist/core/commands/sd-save-command-event.plugin.d.ts +0 -11
  246. package/dist/core/commands/sd-save-command-event.plugin.d.ts.map +0 -1
  247. package/dist/core/commands/sd-save-command-event.plugin.js +0 -38
  248. package/dist/core/events/sd-intersection-event.plugin.d.ts +0 -13
  249. package/dist/core/events/sd-intersection-event.plugin.d.ts.map +0 -1
  250. package/dist/core/events/sd-intersection-event.plugin.js +0 -29
  251. package/dist/core/events/sd-resize-event.plugin.d.ts +0 -16
  252. package/dist/core/events/sd-resize-event.plugin.d.ts.map +0 -1
  253. package/src/core/commands/sd-insert-command-event.plugin.ts +0 -39
  254. package/src/core/commands/sd-refresh-command-event.plugin.ts +0 -44
  255. package/src/core/commands/sd-save-command-event.plugin.ts +0 -44
  256. package/src/core/events/sd-intersection-event.plugin.ts +0 -35
@@ -24,14 +24,17 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
24
24
  "[attr.aria-live]": "ariaLive()",
25
25
  },
26
26
  template: `
27
- <div class="_block">
28
- @if (message() !== undefined) {
29
- <div class="_message">{{ message() }}</div>
30
- }
31
- <ng-content />
27
+ <div class="_sd-toast-block">
28
+ <div class="_sd-toast-message">
29
+ @if (message() != undefined) {
30
+ {{ message() }}
31
+ } @else {
32
+ <ng-content />
33
+ }
34
+ </div>
32
35
  @if (useProgress()) {
33
- <div class="_progress">
34
- <div class="_progress-bar" [style.width.%]="progress()"></div>
36
+ <div class="_sd-toast-progress">
37
+ <div class="_sd-toast-progress-bar" [style.width.%]="progress()"></div>
35
38
  </div>
36
39
  }
37
40
  </div>
@@ -49,7 +52,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
49
52
  width: 100%;
50
53
  pointer-events: none;
51
54
 
52
- > ._block {
55
+ > ._sd-toast-block {
53
56
  display: inline-block;
54
57
  text-align: left;
55
58
  color: var(--text-trans-rev-default);
@@ -59,19 +62,19 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
59
62
  @include mixins.elevation(12);
60
63
  pointer-events: auto;
61
64
 
62
- > ._message {
65
+ > ._sd-toast-message {
63
66
  padding: var(--gap-default) var(--gap-lg);
64
67
  word-break: break-all;
65
68
  white-space: pre-wrap;
66
69
  }
67
70
 
68
- > ._progress {
71
+ > ._sd-toast-progress {
69
72
  background: var(--theme-gray-default);
70
73
  height: 4px;
71
74
  border-radius: var(--border-radius-xl);
72
75
  margin: 0 4px 4px 4px;
73
76
 
74
- > ._progress-bar {
77
+ > ._sd-toast-progress-bar {
75
78
  border-radius: var(--border-radius-xl);
76
79
  height: 4px;
77
80
  transition: width 1s ease-out;
@@ -81,14 +84,14 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
81
84
 
82
85
  @each $theme-name, $theme-map in map.get(variables.$vars, theme) {
83
86
  &[data-sd-theme="#{$theme-name}"] {
84
- > ._block {
85
- background: map.get($theme-map, default);
87
+ > ._sd-toast-block {
88
+ background: var(--theme-#{$theme-name}-default);
86
89
 
87
- > ._progress {
88
- background: map.get($theme-map, darker);
90
+ > ._sd-toast-progress {
91
+ background: var(--theme-#{$theme-name}-darker);
89
92
 
90
- > ._progress-bar {
91
- background: map.get($theme-map, lighter);
93
+ > ._sd-toast-progress-bar {
94
+ background: var(--theme-#{$theme-name}-lighter);
92
95
  }
93
96
  }
94
97
  }
@@ -96,7 +99,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
96
99
  }
97
100
 
98
101
  &[data-sd-open="true"] {
99
- > ._block {
102
+ > ._sd-toast-block {
100
103
  transform: none;
101
104
  transition: var(--animation-duration) ease-out;
102
105
  transition-property: transform, opacity;
@@ -105,7 +108,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
105
108
  }
106
109
 
107
110
  &[data-sd-open="false"] {
108
- > ._block {
111
+ > ._sd-toast-block {
109
112
  transform: translateY(-100%);
110
113
  transition: var(--animation-duration) ease-in;
111
114
  transition-property: transform, opacity;
@@ -114,17 +117,17 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
114
117
  }
115
118
 
116
119
  @media all and (max-width: variables.$breakpoint-mobile) {
117
- > ._block {
120
+ > ._sd-toast-block {
118
121
  border-radius: calc(var(--line-height) / 2);
119
122
  transform: translateY(100%);
120
123
 
121
- > ._message {
124
+ > ._sd-toast-message {
122
125
  padding: var(--gap-xs) var(--gap-default);
123
126
  }
124
127
  }
125
128
 
126
129
  &[data-sd-open="false"] {
127
- > ._block {
130
+ > ._sd-toast-block {
128
131
  transform: translateY(100%);
129
132
  }
130
133
  }
@@ -66,6 +66,7 @@ function createInputHiddenEl(renderer: Renderer2, hostEl: HTMLElement): HTMLInpu
66
66
  newEl.name = Uuid.generate().toString();
67
67
  newEl.className = "sd-invalid-input";
68
68
  newEl.tabIndex = -1;
69
+ newEl.autocomplete = "off";
69
70
  setSafeStyle(renderer, newEl, {
70
71
  position: "absolute",
71
72
  left: "2px",
@@ -83,7 +84,7 @@ function createInputHiddenEl(renderer: Renderer2, hostEl: HTMLElement): HTMLInpu
83
84
  const tabbableElement =
84
85
  (isTabbable(hostEl) ? hostEl : hostEl.findFirstTabbableChild()) ??
85
86
  hostEl.findTabbableParent();
86
- if (tabbableElement !== undefined) {
87
+ if (tabbableElement != null) {
87
88
  tabbableElement.focus();
88
89
  }
89
90
  });
@@ -22,6 +22,7 @@ import {
22
22
  tablerRestore,
23
23
  } from "@ng-icons/tabler-icons";
24
24
  import { SdDataDetailBase } from "./sd-data-detail.base";
25
+ import { SdCommandDirective } from "../../core/commands/sd-command";
25
26
 
26
27
  export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
27
28
 
@@ -41,6 +42,9 @@ export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
41
42
  SdAnchor,
42
43
  NgIcon,
43
44
  ],
45
+ hostDirectives: [
46
+ { directive: SdCommandDirective, outputs: ["sdRefreshCommand", "sdSaveCommand"] },
47
+ ],
44
48
  host: {
45
49
  "(sdRefreshCommand)": "onRefreshButtonClick()",
46
50
  "(sdSaveCommand)": "onSubmitButtonClick()",
@@ -169,18 +173,18 @@ export type { SdDataDetailDataInfo } from "./sd-data-detail.base";
169
173
  </div>
170
174
  </div>
171
175
  </ng-template>
172
- }
173
176
 
174
- <ng-template #modalActionTpl>
175
- <sd-anchor
176
- [theme]="'gray'"
177
- class="p-sm-default"
178
- (click)="onRefreshButtonClick()"
179
- title="새로고침(CTRL+ALT+L)"
180
- >
181
- <ng-icon [svg]="icons.tablerRefresh" />
182
- </sd-anchor>
183
- </ng-template>
177
+ <ng-template #modalActionTpl>
178
+ <sd-anchor
179
+ [theme]="'gray'"
180
+ class="p-sm-default"
181
+ (click)="onRefreshButtonClick()"
182
+ title="새로고침(CTRL+ALT+L)"
183
+ >
184
+ <ng-icon [svg]="icons.tablerRefresh" />
185
+ </sd-anchor>
186
+ </ng-template>
187
+ }
184
188
  </sd-base-container>
185
189
  `,
186
190
  })
@@ -13,6 +13,7 @@ import {
13
13
  import { SdButton } from "../../controls/button/sd-button";
14
14
  import { SdForm } from "../../controls/form/sd-form";
15
15
  import { SdSheetColumn } from "../sheet/sd-sheet-column";
16
+ import { SdSheetColumnCellTemplate } from "../sheet/sd-sheet-column-cell-template";
16
17
  import { SdSheet } from "../sheet/sd-sheet";
17
18
  import { injectParent } from "../../core/injectParent";
18
19
  import { FormatPipe } from "../../core/format.pipe";
@@ -32,6 +33,7 @@ import {
32
33
  tablerUpload,
33
34
  } from "@ng-icons/tabler-icons";
34
35
  import { SdDataSheetBase } from "./sd-data-sheet.base";
36
+ import { SdCommandDirective } from "../../core/commands/sd-command";
35
37
 
36
38
  //#region SdDataSheet
37
39
 
@@ -45,12 +47,16 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
45
47
  SdButton,
46
48
  SdSheet,
47
49
  SdSheetColumn,
50
+ SdSheetColumnCellTemplate,
48
51
  NgTemplateOutlet,
49
52
  SdBaseContainer,
50
53
  FormatPipe,
51
54
  SdAnchor,
52
55
  NgIcon,
53
56
  ],
57
+ hostDirectives: [
58
+ { directive: SdCommandDirective, outputs: ["sdRefreshCommand", "sdSaveCommand"] },
59
+ ],
54
60
  host: {
55
61
  "(sdRefreshCommand)": "onRefreshButtonClick()",
56
62
  "(sdSaveCommand)": "onSubmitButtonClick()",
@@ -209,12 +215,15 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
209
215
  [getItemSelectableFn]="parent.getItemSelectableFn"
210
216
  >
211
217
  @if (
212
- parent.editMode === "inline" &&
213
- parent.canEdit() &&
214
- parent.itemPropInfo.isDeleted
218
+ parent.editMode === "inline" && parent.canEdit() && parent.itemPropInfo.isDeleted
215
219
  ) {
216
220
  <sd-sheet-column [fixed]="true" [key]="parent.itemPropInfo.isDeleted!">
217
- <ng-template #cellTpl let-item>
221
+ <ng-template #headerTpl>
222
+ <div class="p-xs-sm tx-center">
223
+ <ng-icon [svg]="deleteIcon()" />
224
+ </div>
225
+ </ng-template>
226
+ <ng-template [cell]="parent.items()" let-item="item">
218
227
  <div class="p-xs-sm tx-center">
219
228
  <sd-anchor
220
229
  [theme]="'danger'"
@@ -223,16 +232,10 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
223
232
  >
224
233
  <ng-icon
225
234
  [svg]="
226
- item[parent.itemPropInfo.isDeleted!]
227
- ? restoreIcon()
228
- : deleteIcon()
235
+ item[parent.itemPropInfo.isDeleted!] ? restoreIcon() : deleteIcon()
229
236
  "
230
237
  />
231
- {{
232
- item[parent.itemPropInfo.isDeleted!]
233
- ? (restoreText() ?? "복구")
234
- : (deleteText() ?? "삭제")
235
- }}
238
+ {{ item[parent.itemPropInfo.isDeleted!] ? restoreText() : deleteText() }}
236
239
  </sd-anchor>
237
240
  </div>
238
241
  </ng-template>
@@ -244,12 +247,19 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
244
247
  [key]="columnControl.key()"
245
248
  [fixed]="columnControl.fixed()"
246
249
  [header]="columnControl.header()"
250
+ [headerStyle]="columnControl.headerStyle()"
251
+ [tooltip]="columnControl.tooltip()"
247
252
  [width]="columnControl.width()"
248
253
  [disableSorting]="columnControl.disableSorting()"
249
254
  [disableResizing]="columnControl.disableResizing()"
250
255
  [hidden]="columnControl.hidden()"
251
256
  [collapse]="columnControl.collapse()"
252
257
  >
258
+ @if (columnControl.headerTplRef()) {
259
+ <ng-template #headerTpl>
260
+ <ng-template [ngTemplateOutlet]="columnControl.headerTplRef()!" />
261
+ </ng-template>
262
+ }
253
263
  @if (columnControl.summaryTplRef()) {
254
264
  <ng-template #summaryTpl>
255
265
  <ng-template [ngTemplateOutlet]="columnControl.summaryTplRef()!" />
@@ -257,8 +267,8 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
257
267
  }
258
268
 
259
269
  <ng-template
260
- #cellTpl
261
- let-item
270
+ [cell]="parent.items()"
271
+ let-item="item"
262
272
  let-index="index"
263
273
  let-depth="depth"
264
274
  let-edit="edit"
@@ -311,12 +321,9 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
311
321
  [key]="parent.itemPropInfo.lastModifiedAt!"
312
322
  [hidden]="true"
313
323
  >
314
- <ng-template #cellTpl let-item>
324
+ <ng-template [cell]="parent.items()" let-item="item">
315
325
  <div class="p-xs-sm tx-center">
316
- {{
317
- item[parent.itemPropInfo.lastModifiedAt!]
318
- | format: "yyyy-MM-dd HH:mm"
319
- }}
326
+ {{ item[parent.itemPropInfo.lastModifiedAt!] | format: "yyyy-MM-dd HH:mm" }}
320
327
  </div>
321
328
  </ng-template>
322
329
  </sd-sheet-column>
@@ -327,7 +334,7 @@ import { SdDataSheetBase } from "./sd-data-sheet.base";
327
334
  [key]="parent.itemPropInfo.lastModifiedBy!"
328
335
  [hidden]="true"
329
336
  >
330
- <ng-template #cellTpl let-item>
337
+ <ng-template [cell]="parent.items()" let-item="item">
331
338
  <div class="p-xs-sm tx-center">
332
339
  {{ item[parent.itemPropInfo.lastModifiedBy!] }}
333
340
  </div>
@@ -17,15 +17,14 @@ import {
17
17
  type SdKanbanDropTarget,
18
18
  } from "./sd-kanban-board";
19
19
  import { SdKanbanLane } from "./sd-kanban-lane";
20
- import { SdEvents } from "../../core/events/sd-events";
21
- import type { SdResizeEvent } from "../../core/events/sd-resize-event.plugin";
20
+ import { SdResizeDirective, type SdResizeEvent } from "../../core/events/sd-resize";
22
21
 
23
22
  @Component({
24
23
  selector: "sd-kanban",
25
24
  changeDetection: ChangeDetectionStrategy.OnPush,
26
25
  encapsulation: ViewEncapsulation.None,
27
26
  standalone: true,
28
- imports: [SdEvents],
27
+ imports: [SdResizeDirective],
29
28
  host: {
30
29
  "[attr.data-sd-dragging-this]": "dragKanban() === thisRef",
31
30
  "[attr.data-sd-dragging]": "dragKanban() != null",
@@ -186,9 +185,9 @@ export class SdKanban<L, T> implements SdKanbanDragRef<L, T>, SdKanbanDropTarget
186
185
  }
187
186
 
188
187
  onCardResize(event: SdResizeEvent) {
189
- const marginBottom = getComputedStyle(event.target as HTMLElement).marginBottom;
188
+ const marginBottom = getComputedStyle(event.target).marginBottom;
190
189
  this.cardHeight.set(
191
- (event.target as HTMLElement).clientHeight + (parseInt(marginBottom) || 0),
190
+ event.target.clientHeight + (parseInt(marginBottom) || 0),
192
191
  );
193
192
  }
194
193
 
@@ -152,7 +152,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
152
152
  <td class="_title">
153
153
  @if (item.children && item.children.length > 0) {
154
154
  <sd-anchor (click)="onPermCollapseToggle(item)">
155
- <sd-collapse-icon [open]="!getIsPermCollapsed(item)" />
155
+ <sd-collapse-icon [open]="getIsPermCollapsed(item)" />
156
156
  {{ item.title }}
157
157
  </sd-anchor>
158
158
  } @else {
@@ -226,7 +226,7 @@ export class SdPermissionTable<TModule> {
226
226
  const walk = (item: SdPermission<TModule>, type: "use" | "edit"): boolean => {
227
227
  const key = item.codeChain.join(".") + "." + type;
228
228
  const cached = cache.get(key);
229
- if (cached !== undefined) return cached;
229
+ if (cached != null) return cached;
230
230
 
231
231
  if (item.perms) {
232
232
  const result = item.perms.includes(type);
@@ -259,7 +259,7 @@ export class SdPermissionTable<TModule> {
259
259
  const walk = (item: SdPermission<TModule>, type: "use" | "edit"): boolean => {
260
260
  const key = item.codeChain.join(".") + "." + type;
261
261
  const cached = cache.get(key);
262
- if (cached !== undefined) return cached;
262
+ if (cached != null) return cached;
263
263
 
264
264
  if (item.perms) {
265
265
  const permCode = item.codeChain.join(".");
@@ -295,7 +295,7 @@ export class SdPermissionTable<TModule> {
295
295
  const walk = (item: SdPermission<TModule>): boolean => {
296
296
  const key = item.codeChain.join(".");
297
297
  const cached = cache.get(key);
298
- if (cached !== undefined) return cached;
298
+ if (cached != null) return cached;
299
299
 
300
300
  if (isDisabled) {
301
301
  cache.set(key, true);
@@ -93,7 +93,7 @@ import { tablerExternalLink } from "@ng-icons/tabler-icons";
93
93
  <sd-list [inset]="true" class="flex-fill">
94
94
  @if (useUndefined()) {
95
95
  <sd-list-item
96
- [selected]="selectedItem() === undefined"
96
+ [selected]="selectedItem() == null"
97
97
  (click)="select(undefined)"
98
98
  [selectedIcon]="selectedIcon()"
99
99
  >
@@ -61,6 +61,7 @@ import { matchesSearchText } from "./matchesSearchText";
61
61
  [inline]="inline()"
62
62
  [size]="size()"
63
63
  [items]="rootDisplayItems()"
64
+ [trackByFn]="trackByFn"
64
65
  [selectMode]="selectMode()"
65
66
  [contentClass]="selectClass()"
66
67
  [multiSelectionDisplayDirection]="multiSelectionDisplayDirection()"
@@ -93,19 +94,13 @@ import { matchesSearchText } from "./matchesSearchText";
93
94
  (!required() && selectMode() === "single") ||
94
95
  (useUndefined() && selectMode() === "multi")
95
96
  ) {
96
- <div
97
- class="_sd-shared-data-select-undefined"
98
- tabindex="0"
99
- (click)="onUndefinedClick()"
100
- (keydown.enter)="onUndefinedClick()"
101
- (keydown.space)="onUndefinedClick(); $event.preventDefault()"
102
- >
97
+ <sd-select-item>
103
98
  @if (undefinedTplRef()) {
104
99
  <ng-template [ngTemplateOutlet]="undefinedTplRef()!" />
105
100
  } @else {
106
101
  <span class="tx-theme-gray-default">미지정</span>
107
102
  }
108
- </div>
103
+ </sd-select-item>
109
104
  }
110
105
  </ng-template>
111
106
 
@@ -185,6 +180,8 @@ export class SdSharedDataSelect<
185
180
  read: TemplateRef,
186
181
  });
187
182
 
183
+ trackByFn = (item: TItem): TItem["__valueKey"] => item.__valueKey;
184
+
188
185
  searchText = signal<string | undefined>(undefined);
189
186
 
190
187
  isDropdownOpen = computed(() => this._selectCtrl()?.dropdownOpen() ?? false);
@@ -224,13 +221,7 @@ export class SdSharedDataSelect<
224
221
 
225
222
  const orderProp = this.displayOrderKeyProp();
226
223
  if (orderProp != null) {
227
- result = [...result].sort((a, b) => {
228
- const aVal = (a as any)[orderProp];
229
- const bVal = (b as any)[orderProp];
230
- if (aVal < bVal) return -1;
231
- if (aVal > bVal) return 1;
232
- return 0;
233
- });
224
+ result = result.orderBy((item) => (item as any)[orderProp]);
234
225
  }
235
226
 
236
227
  return result;
@@ -247,7 +238,7 @@ export class SdSharedDataSelect<
247
238
  const check = (item: TItem, index: number): boolean => {
248
239
  const key = item.__valueKey;
249
240
  const cached = cache.get(key);
250
- if (cached !== undefined) return cached;
241
+ if (cached != null) return cached;
251
242
 
252
243
  const itemText = getSearchTextFn(item, index);
253
244
  if (matchesSearchText(itemText, searchText)) {
@@ -332,13 +323,7 @@ export class SdSharedDataSelect<
332
323
  for (const [key, children] of parentMap) {
333
324
  sorted.set(
334
325
  key,
335
- [...children].sort((a, b) => {
336
- const aVal = (a as any)[orderProp];
337
- const bVal = (b as any)[orderProp];
338
- if (aVal < bVal) return -1;
339
- if (aVal > bVal) return 1;
340
- return 0;
341
- }),
326
+ children.orderBy((item) => (item as any)[orderProp]),
342
327
  );
343
328
  }
344
329
  return sorted;
@@ -351,10 +336,6 @@ export class SdSharedDataSelect<
351
336
  );
352
337
  };
353
338
 
354
- onUndefinedClick(): void {
355
- this.value.set(undefined as any);
356
- }
357
-
358
339
  async onModalButtonClick(event: MouseEvent): Promise<void> {
359
340
  event.preventDefault();
360
341
  event.stopPropagation();
@@ -8,45 +8,53 @@ export function injectSheetDomAccessor() {
8
8
  }
9
9
 
10
10
  function getContainer(): HTMLElement {
11
- return elRef.nativeElement.querySelector("._container")!;
11
+ return elRef.nativeElement.querySelector<HTMLElement>("._sheet-container")!;
12
12
  }
13
13
 
14
14
  function getTable(): HTMLTableElement {
15
- return elRef.nativeElement.querySelector("table")!;
15
+ return elRef.nativeElement.querySelector<HTMLTableElement>("table")!;
16
16
  }
17
17
 
18
18
  function getTHead(): HTMLTableSectionElement {
19
- return getTable().querySelector("thead")!;
19
+ return getTable().querySelector<HTMLTableSectionElement>("thead")!;
20
+ }
21
+
22
+ function getLastDepthFixedHeaders(): HTMLElement[] {
23
+ return Array.from(getTHead().querySelectorAll<HTMLElement>("tr > th._last-depth._fixed"));
24
+ }
25
+
26
+ function getFocusRowIndicator(): HTMLElement {
27
+ return getContainer().querySelector<HTMLElement>("._focus-row-indicator")!;
28
+ }
29
+
30
+ function getFocusCellIndicator(): HTMLElement {
31
+ return getFocusRowIndicator().firstElementChild as HTMLElement;
32
+ }
33
+
34
+ function getSelectRowIndicatorContainer(): HTMLElement {
35
+ return getContainer().querySelector<HTMLElement>("._select-row-indicator-container")!;
36
+ }
37
+
38
+ function getSelectRowIndicators(): HTMLElement[] {
39
+ return Array.from(
40
+ getSelectRowIndicatorContainer().querySelectorAll<HTMLElement>("._select-row-indicator"),
41
+ );
42
+ }
43
+
44
+ function getColumnResizeIndicator(): HTMLElement {
45
+ return getContainer().querySelector<HTMLElement>("._resize-indicator")!;
20
46
  }
21
47
 
22
48
  function getRow(r: number): HTMLTableRowElement | null {
23
49
  const tbody = getTable().querySelector("tbody");
24
50
  if (tbody == null) return null;
25
- const rows = tbody.querySelectorAll<HTMLTableRowElement>("tr");
26
- return rows[r] ?? null;
51
+ return tbody.querySelector<HTMLTableRowElement>(`tr[data-r='${r}']`);
27
52
  }
28
53
 
29
54
  function getCell(r: number, c: number): HTMLTableCellElement | null {
30
55
  const row = getRow(r);
31
56
  if (row == null) return null;
32
- const cells = row.querySelectorAll<HTMLTableCellElement>("td[data-c]");
33
- for (const cell of cells) {
34
- if (cell.getAttribute("data-c") === String(c)) {
35
- return cell;
36
- }
37
- }
38
- return null;
39
- }
40
-
41
- function getColumnResizeIndicator(): HTMLElement {
42
- return elRef.nativeElement.querySelector("._resize-indicator")!;
43
- }
44
-
45
- function getLastDepthFixedHeaders(): HTMLElement[] {
46
- const thead = getTHead();
47
- const lastRow = thead.querySelector("tr:last-child");
48
- if (lastRow == null) return [];
49
- return Array.from(lastRow.querySelectorAll<HTMLElement>("th[style*='sticky']"));
57
+ return row.querySelector<HTMLTableCellElement>(`td[data-c='${c}']`);
50
58
  }
51
59
 
52
60
  return {
@@ -54,9 +62,13 @@ export function injectSheetDomAccessor() {
54
62
  getContainer,
55
63
  getTable,
56
64
  getTHead,
65
+ getLastDepthFixedHeaders,
66
+ getFocusRowIndicator,
67
+ getFocusCellIndicator,
68
+ getSelectRowIndicatorContainer,
69
+ getSelectRowIndicators,
70
+ getColumnResizeIndicator,
57
71
  getRow,
58
72
  getCell,
59
- getColumnResizeIndicator,
60
- getLastDepthFixedHeaders,
61
73
  };
62
74
  }
@@ -0,0 +1,69 @@
1
+ import { afterEveryRender, type Signal } from "@angular/core";
2
+ import type { injectSheetDomAccessor } from "./injectSheetDomAccessor";
3
+
4
+ export function injectSheetSelectRowIndicator<T>(options: {
5
+ domAccessor: ReturnType<typeof injectSheetDomAccessor>;
6
+ selectedItems: Signal<T[]>;
7
+ displayItems: Signal<T[]>;
8
+ }) {
9
+ afterEveryRender(() => {
10
+ const containerEl = options.domAccessor.getSelectRowIndicatorContainer();
11
+
12
+ if (options.selectedItems().length <= 0) {
13
+ containerEl.innerHTML = "";
14
+ containerEl.style.display = "none";
15
+ return;
16
+ }
17
+
18
+ const selectedTrInfos = options.selectedItems()
19
+ .map((item) => {
20
+ const r = options.displayItems().indexOf(item);
21
+ return getTrInfo(r);
22
+ })
23
+ .filter((info): info is NonNullable<typeof info> => info != null);
24
+
25
+ let indicatorHtml = "";
26
+ for (const info of selectedTrInfos) {
27
+ const style = `top: ${info.top}px; height: ${info.height - 1}px; width: ${info.width - 1}px;`;
28
+ indicatorHtml += `<div class="_select-row-indicator" style="${style}" data-r="${info.r}"></div>`;
29
+ }
30
+ containerEl.innerHTML = indicatorHtml;
31
+ containerEl.style.display = "block";
32
+ });
33
+
34
+ function getTrInfo(
35
+ r: number,
36
+ ): { r: number; top: number; width: number; height: number } | undefined {
37
+ const trEl = options.domAccessor.getRow(r);
38
+ if (trEl == null) return undefined;
39
+
40
+ return {
41
+ r,
42
+ top: trEl.offsetTop,
43
+ width: trEl.offsetWidth,
44
+ height: trEl.offsetHeight,
45
+ };
46
+ }
47
+
48
+ function redraw(): void {
49
+ const selectRowIndicatorEls = options.domAccessor.getSelectRowIndicators();
50
+
51
+ for (const el of selectRowIndicatorEls) {
52
+ const rAttr = el.getAttribute("data-r");
53
+ if (rAttr == null) continue;
54
+ const r = parseInt(rAttr, 10);
55
+ if (Number.isNaN(r)) continue;
56
+
57
+ const trInfo = getTrInfo(r);
58
+ if (trInfo == null) continue;
59
+
60
+ Object.assign(el.style, {
61
+ top: trInfo.top + "px",
62
+ width: trInfo.width + "px",
63
+ height: trInfo.height + "px",
64
+ });
65
+ }
66
+ }
67
+
68
+ return { redraw };
69
+ }
@@ -0,0 +1,17 @@
1
+ import { Directive, input } from "@angular/core";
2
+ import type { SdSheetCellContext } from "./sd-sheet-column";
3
+
4
+ @Directive({
5
+ selector: "ng-template[cell]",
6
+ standalone: true,
7
+ })
8
+ export class SdSheetColumnCellTemplate<T> {
9
+ cell = input.required<T[]>();
10
+
11
+ static ngTemplateContextGuard<TContextItem>(
12
+ _dir: SdSheetColumnCellTemplate<TContextItem>,
13
+ _ctx: unknown,
14
+ ): _ctx is SdSheetCellContext<TContextItem> {
15
+ return true;
16
+ }
17
+ }