@simplysm/angular 14.1.20 → 14.2.1

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 (185) hide show
  1. package/dist/controls/button/sd-additional-button.js +2 -2
  2. package/dist/controls/button/sd-anchor.d.ts.map +1 -1
  3. package/dist/controls/button/sd-anchor.js +3 -3
  4. package/dist/controls/button/sd-button.d.ts.map +1 -1
  5. package/dist/controls/button/sd-button.js +3 -3
  6. package/dist/controls/button/sd-modal-select-button.d.ts.map +1 -1
  7. package/dist/controls/button/sd-modal-select-button.js +2 -2
  8. package/dist/controls/checkbox/sd-checkbox.d.ts.map +1 -1
  9. package/dist/controls/checkbox/sd-checkbox.js +3 -3
  10. package/dist/controls/checkbox/sd-switch.d.ts.map +1 -1
  11. package/dist/controls/checkbox/sd-switch.js +3 -3
  12. package/dist/controls/collapse/sd-collapse-icon.d.ts +1 -1
  13. package/dist/controls/collapse/sd-collapse-icon.d.ts.map +1 -1
  14. package/dist/controls/collapse/sd-collapse-icon.js +2 -2
  15. package/dist/controls/collapse/sd-collapse.d.ts +1 -1
  16. package/dist/controls/collapse/sd-collapse.d.ts.map +1 -1
  17. package/dist/controls/collapse/sd-collapse.js +2 -2
  18. package/dist/controls/dropdown/sd-dropdown-popup.d.ts.map +1 -1
  19. package/dist/controls/dropdown/sd-dropdown-popup.js +2 -2
  20. package/dist/controls/dropdown/sd-dropdown.js +1 -1
  21. package/dist/controls/gap/sd-gap.d.ts.map +1 -1
  22. package/dist/controls/gap/sd-gap.js +5 -7
  23. package/dist/controls/input/sd-date-range-picker.js +2 -2
  24. package/dist/controls/input/sd-numpad.d.ts.map +1 -1
  25. package/dist/controls/input/sd-numpad.js +7 -15
  26. package/dist/controls/input/sd-range.js +2 -2
  27. package/dist/controls/input/sd-textarea.js +4 -4
  28. package/dist/controls/input/sd-textfield.d.ts.map +1 -1
  29. package/dist/controls/input/sd-textfield.js +10 -10
  30. package/dist/controls/list/sd-list-item.js +43 -43
  31. package/dist/controls/list/sd-list.js +2 -2
  32. package/dist/controls/pagination/sd-pagination.d.ts.map +1 -1
  33. package/dist/controls/pagination/sd-pagination.js +7 -5
  34. package/dist/controls/select/sd-select-button.d.ts.map +1 -1
  35. package/dist/controls/select/sd-select-button.js +4 -4
  36. package/dist/controls/select/sd-select-item.d.ts.map +1 -1
  37. package/dist/controls/select/sd-select-item.js +3 -3
  38. package/dist/controls/select/sd-select.d.ts.map +1 -1
  39. package/dist/controls/select/sd-select.js +10 -19
  40. package/dist/controls/tab/sd-tab-item.js +2 -2
  41. package/dist/controls/tab/sd-tab.js +2 -2
  42. package/dist/core/busy/sd-busy-container.d.ts.map +1 -1
  43. package/dist/core/busy/sd-busy-container.js +3 -3
  44. package/dist/core/modal/sd-modal.d.ts.map +1 -1
  45. package/dist/core/modal/sd-modal.js +3 -3
  46. package/dist/core/provideSdAngular.d.ts.map +1 -1
  47. package/dist/core/provideSdAngular.js +31 -10
  48. package/dist/core/ripple/setupRipple.js +2 -2
  49. package/dist/core/setupBgTheme.d.ts +0 -1
  50. package/dist/core/setupBgTheme.d.ts.map +1 -1
  51. package/dist/core/setupBgTheme.js +3 -4
  52. package/dist/core/show-effect/setupRevealOnShow.js +1 -1
  53. package/dist/core/toast/sd-toast-container.js +2 -2
  54. package/dist/core/toast/sd-toast.d.ts.map +1 -1
  55. package/dist/core/toast/sd-toast.js +3 -3
  56. package/dist/core/validation/setupInvalid.js +5 -5
  57. package/dist/data/crud/sd-base-container.d.ts.map +1 -1
  58. package/dist/data/crud/sd-base-container.js +50 -52
  59. package/dist/data/kanban/sd-kanban-board.js +2 -2
  60. package/dist/data/kanban/sd-kanban-lane.d.ts.map +1 -1
  61. package/dist/data/kanban/sd-kanban-lane.js +4 -4
  62. package/dist/data/kanban/sd-kanban.d.ts.map +1 -1
  63. package/dist/data/kanban/sd-kanban.js +4 -4
  64. package/dist/data/permission-table/sd-permission-table.d.ts.map +1 -1
  65. package/dist/data/permission-table/sd-permission-table.js +5 -17
  66. package/dist/data/shared-data/sd-shared-data-select-list.d.ts.map +1 -1
  67. package/dist/data/shared-data/sd-shared-data-select-list.js +5 -19
  68. package/dist/data/shared-data/sd-shared-data-select.d.ts.map +1 -1
  69. package/dist/data/shared-data/sd-shared-data-select.js +8 -15
  70. package/dist/data/sheet/sd-sheet-config.modal.d.ts.map +1 -1
  71. package/dist/data/sheet/sd-sheet-config.modal.js +7 -9
  72. package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
  73. package/dist/data/sheet/sd-sheet.js +10 -12
  74. package/dist/data/sheet/useSheetCellStyling.d.ts.map +1 -1
  75. package/dist/data/sheet/useSheetCellStyling.js +1 -1
  76. package/dist/data/state-preset/sd-state-preset.js +5 -5
  77. package/dist/features/editor/sd-markdown-editor.d.ts.map +1 -1
  78. package/dist/features/editor/sd-markdown-editor.js +85 -34
  79. package/dist/features/editor/sd-tiptap-editor.d.ts.map +1 -1
  80. package/dist/features/editor/sd-tiptap-editor.js +192 -61
  81. package/dist/features/theme/sd-theme-provider.d.ts +18 -1
  82. package/dist/features/theme/sd-theme-provider.d.ts.map +1 -1
  83. package/dist/features/theme/sd-theme-provider.js +21 -4
  84. package/dist/features/theme/sd-theme-selector.d.ts.map +1 -1
  85. package/dist/features/theme/sd-theme-selector.js +50 -9
  86. package/dist/features/theme/wcag-contrast.d.ts +9 -0
  87. package/dist/features/theme/wcag-contrast.d.ts.map +1 -0
  88. package/dist/features/theme/wcag-contrast.js +83 -0
  89. package/dist/features/visual/sd-calendar.js +2 -2
  90. package/dist/features/visual/sd-label.d.ts.map +1 -1
  91. package/dist/features/visual/sd-label.js +5 -5
  92. package/dist/features/visual/sd-note.d.ts.map +1 -1
  93. package/dist/features/visual/sd-note.js +3 -3
  94. package/dist/features/visual/sd-progress.d.ts.map +1 -1
  95. package/dist/features/visual/sd-progress.js +3 -3
  96. package/dist/index.d.ts +12 -11
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +10 -9
  99. package/dist/layout/sidebar/sd-sidebar-container.d.ts.map +1 -1
  100. package/dist/layout/sidebar/sd-sidebar-container.js +11 -5
  101. package/dist/layout/sidebar/sd-sidebar-menu.d.ts.map +1 -1
  102. package/dist/layout/sidebar/sd-sidebar-menu.js +5 -17
  103. package/dist/layout/sidebar/sd-sidebar-user.js +32 -32
  104. package/dist/layout/sidebar/sd-sidebar.d.ts.map +1 -1
  105. package/dist/layout/sidebar/sd-sidebar.js +3 -3
  106. package/dist/layout/topbar/sd-topbar-menu.js +5 -5
  107. package/dist/layout/topbar/sd-topbar.d.ts.map +1 -1
  108. package/dist/layout/topbar/sd-topbar.js +5 -5
  109. package/package.json +5 -5
  110. package/scss/commons/_colors.scss +296 -242
  111. package/scss/commons/_density.scss +23 -0
  112. package/scss/commons/_mixins.scss +142 -129
  113. package/scss/commons/_styles.scss +78 -103
  114. package/scss/commons/_theme-variables.scss +16 -2
  115. package/scss/commons/_variables.scss +277 -149
  116. package/scss/controls/_card.scss +12 -8
  117. package/scss/controls/_form-box.scss +7 -7
  118. package/scss/controls/_form-table.scss +7 -7
  119. package/scss/controls/_table.scss +5 -5
  120. package/scss/sd-tokens.md +132 -0
  121. package/scss/styles.scss +3 -4
  122. package/scss/themes/_variables-blueprint.scss +127 -81
  123. package/scss/themes/_variables-ide-dark.scss +215 -0
  124. package/src/controls/button/sd-additional-button.ts +12 -12
  125. package/src/controls/button/sd-anchor.ts +7 -8
  126. package/src/controls/button/sd-button.ts +42 -44
  127. package/src/controls/button/sd-modal-select-button.ts +15 -19
  128. package/src/controls/checkbox/sd-checkbox.ts +55 -43
  129. package/src/controls/checkbox/sd-switch.ts +18 -19
  130. package/src/controls/collapse/sd-collapse-icon.ts +2 -2
  131. package/src/controls/collapse/sd-collapse.ts +2 -2
  132. package/src/controls/dropdown/sd-dropdown-popup.ts +10 -12
  133. package/src/controls/dropdown/sd-dropdown.ts +1 -1
  134. package/src/controls/gap/sd-gap.ts +11 -9
  135. package/src/controls/input/sd-date-range-picker.ts +1 -1
  136. package/src/controls/input/sd-numpad.ts +3 -11
  137. package/src/controls/input/sd-range.ts +1 -1
  138. package/src/controls/input/sd-textarea.ts +18 -18
  139. package/src/controls/input/sd-textfield.ts +39 -37
  140. package/src/controls/list/sd-list-item.ts +195 -195
  141. package/src/controls/list/sd-list.ts +8 -8
  142. package/src/controls/pagination/sd-pagination.ts +4 -2
  143. package/src/controls/select/sd-select-button.ts +6 -10
  144. package/src/controls/select/sd-select-item.ts +14 -15
  145. package/src/controls/select/sd-select.ts +34 -35
  146. package/src/controls/tab/sd-tab-item.ts +4 -4
  147. package/src/controls/tab/sd-tab.ts +2 -2
  148. package/src/core/busy/sd-busy-container.ts +17 -16
  149. package/src/core/modal/sd-modal.ts +38 -32
  150. package/src/core/provideSdAngular.ts +34 -10
  151. package/src/core/ripple/setupRipple.ts +2 -2
  152. package/src/core/setupBgTheme.ts +5 -14
  153. package/src/core/show-effect/setupRevealOnShow.ts +1 -1
  154. package/src/core/toast/sd-toast-container.ts +5 -5
  155. package/src/core/toast/sd-toast.ts +16 -17
  156. package/src/core/validation/setupInvalid.ts +5 -5
  157. package/src/data/crud/sd-base-container.ts +120 -122
  158. package/src/data/kanban/sd-kanban-board.ts +1 -1
  159. package/src/data/kanban/sd-kanban-lane.ts +9 -14
  160. package/src/data/kanban/sd-kanban.ts +9 -19
  161. package/src/data/permission-table/sd-permission-table.ts +12 -20
  162. package/src/data/shared-data/sd-shared-data-select-list.ts +5 -19
  163. package/src/data/shared-data/sd-shared-data-select.ts +11 -28
  164. package/src/data/sheet/sd-sheet-config.modal.ts +5 -7
  165. package/src/data/sheet/sd-sheet.ts +29 -28
  166. package/src/data/sheet/useSheetCellStyling.ts +12 -3
  167. package/src/data/state-preset/sd-state-preset.ts +16 -16
  168. package/src/features/editor/sd-markdown-editor.ts +110 -56
  169. package/src/features/editor/sd-tiptap-editor.ts +214 -81
  170. package/src/features/theme/sd-theme-provider.ts +28 -3
  171. package/src/features/theme/sd-theme-selector.ts +21 -2
  172. package/src/features/theme/wcag-contrast.ts +103 -0
  173. package/src/features/visual/sd-calendar.ts +8 -8
  174. package/src/features/visual/sd-label.ts +11 -12
  175. package/src/features/visual/sd-note.ts +10 -11
  176. package/src/features/visual/sd-progress.ts +9 -11
  177. package/src/index.ts +15 -40
  178. package/src/layout/sidebar/sd-sidebar-container.ts +21 -8
  179. package/src/layout/sidebar/sd-sidebar-menu.ts +15 -17
  180. package/src/layout/sidebar/sd-sidebar-user.ts +100 -100
  181. package/src/layout/sidebar/sd-sidebar.ts +7 -9
  182. package/src/layout/topbar/sd-topbar-menu.ts +3 -3
  183. package/src/layout/topbar/sd-topbar.ts +12 -14
  184. package/styles.css +1641 -2462
  185. package/scss/themes/_blueprint-surfaces.scss +0 -87
@@ -43,11 +43,10 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
43
43
  /* language=SCSS */ `
44
44
  @use "../../../scss/commons/variables";
45
45
  @use "../../../scss/commons/mixins";
46
- @use "sass:map";
47
46
 
48
47
  sd-toast {
49
48
  display: block;
50
- margin-bottom: var(--gap-sm);
49
+ margin-bottom: var(--sd-gap-sm);
51
50
  text-align: center;
52
51
  width: 100%;
53
52
  pointer-events: none;
@@ -55,43 +54,43 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
55
54
  > ._sd-toast-block {
56
55
  display: inline-block;
57
56
  text-align: left;
58
- color: var(--text-trans-rev-default);
59
57
  transform: translateY(-100%);
60
- border-radius: var(--border-radius-lg);
58
+ border-radius: var(--sd-radius-lg);
61
59
  opacity: 0;
62
60
  @include mixins.elevation(12);
63
61
  pointer-events: auto;
64
62
 
65
63
  > ._sd-toast-message {
66
- padding: var(--gap-default) var(--gap-lg);
64
+ padding: var(--sd-gap-default) var(--sd-gap-lg);
67
65
  word-break: break-all;
68
66
  white-space: pre-wrap;
69
67
  }
70
68
 
71
69
  > ._sd-toast-progress {
72
- background: var(--theme-gray-default);
70
+ background-color: var(--sd-bg-state-active);
73
71
  height: 4px;
74
- border-radius: var(--border-radius-xl);
72
+ border-radius: var(--sd-radius-xl);
75
73
  margin: 0 4px 4px 4px;
76
74
 
77
75
  > ._sd-toast-progress-bar {
78
- border-radius: var(--border-radius-xl);
76
+ border-radius: var(--sd-radius-xl);
79
77
  height: 4px;
80
78
  transition: width 1s ease-out;
81
79
  }
82
80
  }
83
81
  }
84
82
 
85
- @each $theme-name, $theme-map in map.get(variables.$vars, theme) {
86
- &[data-sd-theme="#{$theme-name}"] {
83
+ @each $key in variables.$theme-keys {
84
+ &[data-sd-theme="#{$key}"] {
87
85
  > ._sd-toast-block {
88
- background: var(--theme-#{$theme-name}-default);
86
+ background-color: var(--sd-bg-#{$key}-solid);
87
+ color: var(--sd-tx-#{$key}-solid);
89
88
 
90
89
  > ._sd-toast-progress {
91
- background: var(--theme-#{$theme-name}-darker);
90
+ background-color: var(--sd-bg-state-active);
92
91
 
93
92
  > ._sd-toast-progress-bar {
94
- background: var(--theme-#{$theme-name}-lighter);
93
+ background-color: var(--sd-bg-#{$key}-subtle);
95
94
  }
96
95
  }
97
96
  }
@@ -101,7 +100,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
101
100
  &[data-sd-open="true"] {
102
101
  > ._sd-toast-block {
103
102
  transform: none;
104
- transition: var(--animation-duration) ease-out;
103
+ transition: var(--sd-animation-duration) ease-out;
105
104
  transition-property: transform, opacity;
106
105
  opacity: 1;
107
106
  }
@@ -110,7 +109,7 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
110
109
  &[data-sd-open="false"] {
111
110
  > ._sd-toast-block {
112
111
  transform: translateY(-100%);
113
- transition: var(--animation-duration) ease-in;
112
+ transition: var(--sd-animation-duration) ease-in;
114
113
  transition-property: transform, opacity;
115
114
  opacity: 0;
116
115
  }
@@ -118,11 +117,11 @@ const ASSERTIVE_THEMES: ReadonlySet<string> = new Set(["warning", "danger"]);
118
117
 
119
118
  @media all and (max-width: variables.$breakpoint-mobile) {
120
119
  > ._sd-toast-block {
121
- border-radius: calc(var(--line-height) / 2);
120
+ border-radius: calc(var(--sd-line-height) / 2);
122
121
  transform: translateY(100%);
123
122
 
124
123
  > ._sd-toast-message {
125
- padding: var(--gap-xs) var(--gap-default);
124
+ padding: var(--sd-gap-xs) var(--sd-gap-default);
126
125
  }
127
126
  }
128
127
 
@@ -46,12 +46,12 @@ function createIndicatorEl(renderer: Renderer2, hostEl: HTMLElement): HTMLDivEle
46
46
  display: "none",
47
47
  position: "absolute",
48
48
  zIndex: "1",
49
- background: "var(--theme-danger-default)",
49
+ backgroundColor: "var(--sd-bg-danger-solid)",
50
50
 
51
- top: "var(--gap-xs)",
52
- left: "var(--gap-xs)",
53
- width: "var(--gap-sm)",
54
- height: "var(--gap-sm)",
51
+ top: "var(--sd-gap-xs)",
52
+ left: "var(--sd-gap-xs)",
53
+ width: "var(--sd-gap-sm)",
54
+ height: "var(--sd-gap-sm)",
55
55
  borderRadius: "100%",
56
56
 
57
57
  userSelect: "none",
@@ -1,122 +1,120 @@
1
- import {
2
- ChangeDetectionStrategy,
3
- Component,
4
- contentChild,
5
- effect,
6
- inject,
7
- input,
8
- model,
9
- type TemplateRef,
10
- untracked,
11
- ViewEncapsulation,
12
- } from "@angular/core";
13
- import { injectViewTitleSignal } from "../../core/routing/injectViewTitleSignal";
14
- import { SdBusyContainer } from "../../core/busy/sd-busy-container";
15
- import { SdSharedDataProvider } from "../../core/shared-data/sd-shared-data.provider";
16
- import { SdToastProvider } from "../../core/toast/sd-toast.provider";
17
- import { SdTopbar } from "../../layout/topbar/sd-topbar";
18
- import { SdTopbarContainer } from "../../layout/topbar/sd-topbar-container";
19
- import type { SdViewType } from "../../core/routing/injectViewTypeSignal";
20
- import { NgIcon } from "@ng-icons/core";
21
- import { tablerAlertTriangle } from "@ng-icons/tabler-icons";
22
- import { NgTemplateOutlet } from "@angular/common";
23
-
24
- @Component({
25
- selector: "sd-base-container",
26
- changeDetection: ChangeDetectionStrategy.OnPush,
27
- encapsulation: ViewEncapsulation.None,
28
- standalone: true,
29
- imports: [SdBusyContainer, NgIcon, SdTopbarContainer, NgTemplateOutlet, SdTopbar],
30
- template: `
31
- <sd-busy-container [busy]="initialized() && busyCount() > 0">
32
- @if (initialized()) {
33
- @if (restricted()) {
34
- <div class="fill tx-theme-gray-light p-xxl tx-center">
35
- <br />
36
- <ng-icon [svg]="tablerAlertTriangle" [size]="'5rem'" />
37
- <br />
38
- <br />
39
- '{{ viewTitle() }}'에 대한 사용권한이 없습니다. 시스템 관리자에게 문의하세요.
40
- </div>
41
- } @else if (viewType() === "page") {
42
- <sd-topbar-container>
43
- <sd-topbar>
44
- <h5 class="tx-trans-light">{{ viewTitle() }}</h5>
45
-
46
- <ng-template [ngTemplateOutlet]="topbarTplRef()" />
47
- </sd-topbar>
48
-
49
- <ng-template [ngTemplateOutlet]="content" />
50
- </sd-topbar-container>
51
- } @else {
52
- <ng-template [ngTemplateOutlet]="content" />
53
- }
54
- }
55
- </sd-busy-container>
56
-
57
- <ng-template #content>
58
- <div class="flex-column fill bg-control">
59
- @if (commandTplRef()) {
60
- <div class="p-sm-default flex-row gap-default bdb bdb-color-lighter">
61
- <ng-template [ngTemplateOutlet]="commandTplRef()" />
62
- </div>
63
- }
64
-
65
- <div class="flex-fill">
66
- @if (contentTplRef()) {
67
- <ng-template [ngTemplateOutlet]="contentTplRef()" />
68
- }
69
- </div>
70
-
71
- @if (bottomCommandTplRef()) {
72
- <div
73
- class="p-sm-default flex-row main-align-end gap-sm bdt bdt-theme-gray-lighter"
74
- >
75
- <ng-template [ngTemplateOutlet]="bottomCommandTplRef()" />
76
- </div>
77
- }
78
- </div>
79
- </ng-template>
80
- `,
81
- })
82
- export class SdBaseContainer {
83
- private readonly _sdSharedData = inject(SdSharedDataProvider, { optional: true });
84
- private readonly _sdToast = inject(SdToastProvider);
85
-
86
- viewTitle = injectViewTitleSignal();
87
-
88
- ready = model(false);
89
- initialized = input(false);
90
- busyCount = model(0);
91
-
92
- restricted = input(false);
93
-
94
- viewType = input.required<SdViewType>();
95
-
96
- topbarTplRef = contentChild<TemplateRef<void>>("topbarTpl");
97
- commandTplRef = contentChild<TemplateRef<void>>("commandTpl");
98
- contentTplRef = contentChild<TemplateRef<void>>("contentTpl");
99
- bottomCommandTplRef = contentChild<TemplateRef<void>>("bottomCommandTpl");
100
-
101
- constructor() {
102
- effect(() => {
103
- if (this.restricted()) {
104
- this.ready.set(true);
105
- return;
106
- }
107
-
108
- void untracked(async () => {
109
- if (this._sdSharedData) {
110
- this.busyCount.update((v) => v + 1);
111
- await this._sdToast.try(async () => {
112
- await this._sdSharedData!.wait();
113
- });
114
- this.busyCount.update((v) => v - 1);
115
- }
116
- this.ready.set(true);
117
- });
118
- });
119
- }
120
-
121
- protected readonly tablerAlertTriangle = tablerAlertTriangle;
122
- }
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ contentChild,
5
+ effect,
6
+ inject,
7
+ input,
8
+ model,
9
+ type TemplateRef,
10
+ untracked,
11
+ ViewEncapsulation,
12
+ } from "@angular/core";
13
+ import { injectViewTitleSignal } from "../../core/routing/injectViewTitleSignal";
14
+ import { SdBusyContainer } from "../../core/busy/sd-busy-container";
15
+ import { SdSharedDataProvider } from "../../core/shared-data/sd-shared-data.provider";
16
+ import { SdToastProvider } from "../../core/toast/sd-toast.provider";
17
+ import { SdTopbar } from "../../layout/topbar/sd-topbar";
18
+ import { SdTopbarContainer } from "../../layout/topbar/sd-topbar-container";
19
+ import type { SdViewType } from "../../core/routing/injectViewTypeSignal";
20
+ import { NgIcon } from "@ng-icons/core";
21
+ import { tablerAlertTriangle } from "@ng-icons/tabler-icons";
22
+ import { NgTemplateOutlet } from "@angular/common";
23
+
24
+ @Component({
25
+ selector: "sd-base-container",
26
+ changeDetection: ChangeDetectionStrategy.OnPush,
27
+ encapsulation: ViewEncapsulation.None,
28
+ standalone: true,
29
+ imports: [SdBusyContainer, NgIcon, SdTopbarContainer, NgTemplateOutlet, SdTopbar],
30
+ template: `
31
+ <sd-busy-container [busy]="initialized() && busyCount() > 0">
32
+ @if (initialized()) {
33
+ @if (restricted()) {
34
+ <div class="fill tx-faint p-xxl tx-center">
35
+ <br />
36
+ <ng-icon [svg]="tablerAlertTriangle" [size]="'5rem'" />
37
+ <br />
38
+ <br />
39
+ '{{ viewTitle() }}'에 대한 사용권한이 없습니다. 시스템 관리자에게 문의하세요.
40
+ </div>
41
+ } @else if (viewType() === "page") {
42
+ <sd-topbar-container>
43
+ <sd-topbar>
44
+ <h5 class="tx-muted">{{ viewTitle() }}</h5>
45
+
46
+ <ng-template [ngTemplateOutlet]="topbarTplRef()" />
47
+ </sd-topbar>
48
+
49
+ <ng-template [ngTemplateOutlet]="content" />
50
+ </sd-topbar-container>
51
+ } @else {
52
+ <ng-template [ngTemplateOutlet]="content" />
53
+ }
54
+ }
55
+ </sd-busy-container>
56
+
57
+ <ng-template #content>
58
+ <div class="flex-column fill bg-control">
59
+ @if (commandTplRef()) {
60
+ <div class="p-sm-default flex-row gap-default bdb bdb-soft">
61
+ <ng-template [ngTemplateOutlet]="commandTplRef()" />
62
+ </div>
63
+ }
64
+
65
+ <div class="flex-fill">
66
+ @if (contentTplRef()) {
67
+ <ng-template [ngTemplateOutlet]="contentTplRef()" />
68
+ }
69
+ </div>
70
+
71
+ @if (bottomCommandTplRef()) {
72
+ <div class="p-sm-default flex-row main-align-end gap-sm bdt bdt-hairline">
73
+ <ng-template [ngTemplateOutlet]="bottomCommandTplRef()" />
74
+ </div>
75
+ }
76
+ </div>
77
+ </ng-template>
78
+ `,
79
+ })
80
+ export class SdBaseContainer {
81
+ private readonly _sdSharedData = inject(SdSharedDataProvider, { optional: true });
82
+ private readonly _sdToast = inject(SdToastProvider);
83
+
84
+ viewTitle = injectViewTitleSignal();
85
+
86
+ ready = model(false);
87
+ initialized = input(false);
88
+ busyCount = model(0);
89
+
90
+ restricted = input(false);
91
+
92
+ viewType = input.required<SdViewType>();
93
+
94
+ topbarTplRef = contentChild<TemplateRef<void>>("topbarTpl");
95
+ commandTplRef = contentChild<TemplateRef<void>>("commandTpl");
96
+ contentTplRef = contentChild<TemplateRef<void>>("contentTpl");
97
+ bottomCommandTplRef = contentChild<TemplateRef<void>>("bottomCommandTpl");
98
+
99
+ constructor() {
100
+ effect(() => {
101
+ if (this.restricted()) {
102
+ this.ready.set(true);
103
+ return;
104
+ }
105
+
106
+ void untracked(async () => {
107
+ if (this._sdSharedData) {
108
+ this.busyCount.update((v) => v + 1);
109
+ await this._sdToast.try(async () => {
110
+ await this._sdSharedData!.wait();
111
+ });
112
+ this.busyCount.update((v) => v - 1);
113
+ }
114
+ this.ready.set(true);
115
+ });
116
+ });
117
+ }
118
+
119
+ protected readonly tablerAlertTriangle = tablerAlertTriangle;
120
+ }
@@ -28,7 +28,7 @@ import {
28
28
  flex-wrap: nowrap;
29
29
  white-space: nowrap;
30
30
  height: 100%;
31
- @include mixins.flex-direction(row, var(--gap-lg));
31
+ @include mixins.flex-direction(row, var(--sd-gap-lg));
32
32
  }
33
33
  `,
34
34
  ],
@@ -16,10 +16,7 @@ import {
16
16
  } from "@angular/core";
17
17
  import { SdBusyContainer } from "../../core/busy/sd-busy-container";
18
18
  import { SdCheckbox } from "../../controls/checkbox/sd-checkbox";
19
- import {
20
- SdKanbanBoard,
21
- type SdKanbanDropTarget,
22
- } from "./sd-kanban-board";
19
+ import { SdKanbanBoard, type SdKanbanDropTarget } from "./sd-kanban-board";
23
20
  import { SdKanban } from "./sd-kanban";
24
21
  import { SdAnchor } from "../../controls/button/sd-anchor";
25
22
  import { NgIcon } from "@ng-icons/core";
@@ -89,20 +86,20 @@ import { tablerEye, tablerEyeOff } from "@ng-icons/tabler-icons";
89
86
  sd-kanban-lane {
90
87
  > .flex-fill {
91
88
  > sd-busy-container {
92
- padding: var(--gap-xl) var(--gap-lg);
93
- background: var(--theme-gray-lightest);
94
- border-radius: var(--border-radius-default);
89
+ padding: var(--sd-gap-xl) var(--sd-gap-lg);
90
+ background-color: var(--sd-bg-gray-subtle);
91
+ border-radius: var(--sd-radius-default);
95
92
  height: 100%;
96
93
 
97
94
  > ._drop-position {
98
95
  pointer-events: none;
99
- border-radius: var(--border-radius-default);
100
- background: var(--trans-light);
96
+ border-radius: var(--sd-radius-default);
97
+ background-color: var(--sd-bg-state-active);
101
98
 
102
99
  height: 0;
103
100
  margin-bottom: 0;
104
101
  visibility: hidden;
105
- transition: var(--animation-duration) linear;
102
+ transition: var(--sd-animation-duration) linear;
106
103
  transition-property: height, margin-bottom, visibility;
107
104
  }
108
105
  }
@@ -110,7 +107,7 @@ import { tablerEye, tablerEyeOff } from "@ng-icons/tabler-icons";
110
107
 
111
108
  &[data-sd-drag-over="true"] {
112
109
  > .flex-fill > sd-busy-container > ._drop-position {
113
- margin-bottom: var(--gap-lg);
110
+ margin-bottom: var(--sd-gap-lg);
114
111
  visibility: visible;
115
112
  }
116
113
  }
@@ -119,9 +116,7 @@ import { tablerEye, tablerEyeOff } from "@ng-icons/tabler-icons";
119
116
  ],
120
117
  })
121
118
  export class SdKanbanLane<L, T> implements SdKanbanDropTarget<L, T> {
122
- private readonly _boardControl = inject<SdKanbanBoard<L, T>>(
123
- forwardRef(() => SdKanbanBoard),
124
- );
119
+ private readonly _boardControl = inject<SdKanbanBoard<L, T>>(forwardRef(() => SdKanbanBoard));
125
120
 
126
121
  busy = input(false, { transform: booleanAttribute });
127
122
 
@@ -11,11 +11,7 @@ import {
11
11
  signal,
12
12
  ViewEncapsulation,
13
13
  } from "@angular/core";
14
- import {
15
- SdKanbanBoard,
16
- type SdKanbanDragRef,
17
- type SdKanbanDropTarget,
18
- } from "./sd-kanban-board";
14
+ import { SdKanbanBoard, type SdKanbanDragRef, type SdKanbanDropTarget } from "./sd-kanban-board";
19
15
  import { SdKanbanLane } from "./sd-kanban-lane";
20
16
  import { SdResizeDirective, type SdResizeEvent } from "../../core/events/sd-resize";
21
17
 
@@ -85,19 +81,19 @@ import { SdResizeDirective, type SdResizeEvent } from "../../core/events/sd-resi
85
81
  }
86
82
 
87
83
  > ._drop-position {
88
- border-radius: var(--border-radius-default);
89
- background: var(--trans-light);
84
+ border-radius: var(--sd-radius-default);
85
+ background-color: var(--sd-bg-state-active);
90
86
 
91
87
  height: 0;
92
88
  margin-bottom: 0;
93
89
  visibility: hidden;
94
- transition: var(--animation-duration) linear;
90
+ transition: var(--sd-animation-duration) linear;
95
91
  transition-property: height, margin-bottom, visibility;
96
92
  }
97
93
 
98
94
  &[data-sd-drag-over="true"] {
99
95
  > ._drop-position {
100
- margin-bottom: var(--gap-lg);
96
+ margin-bottom: var(--sd-gap-lg);
101
97
  visibility: visible;
102
98
  }
103
99
  }
@@ -105,19 +101,15 @@ import { SdResizeDirective, type SdResizeEvent } from "../../core/events/sd-resi
105
101
  > .card {
106
102
  white-space: normal;
107
103
  user-select: none;
108
- margin-bottom: var(--gap-lg);
104
+ margin-bottom: var(--sd-gap-lg);
109
105
  }
110
106
  }
111
107
  `,
112
108
  ],
113
109
  })
114
110
  export class SdKanban<L, T> implements SdKanbanDragRef<L, T>, SdKanbanDropTarget<L, T> {
115
- private readonly _boardControl = inject<SdKanbanBoard<L, T>>(
116
- forwardRef(() => SdKanbanBoard),
117
- );
118
- private readonly _laneControl = inject<SdKanbanLane<L, T>>(
119
- forwardRef(() => SdKanbanLane),
120
- );
111
+ private readonly _boardControl = inject<SdKanbanBoard<L, T>>(forwardRef(() => SdKanbanBoard));
112
+ private readonly _laneControl = inject<SdKanbanLane<L, T>>(forwardRef(() => SdKanbanLane));
121
113
  private readonly _elRef = inject<ElementRef<HTMLElement>>(ElementRef);
122
114
 
123
115
  readonly thisRef = this;
@@ -186,9 +178,7 @@ export class SdKanban<L, T> implements SdKanbanDragRef<L, T>, SdKanbanDropTarget
186
178
 
187
179
  onCardResize(event: SdResizeEvent) {
188
180
  const marginBottom = getComputedStyle(event.target).marginBottom;
189
- this.cardHeight.set(
190
- event.target.clientHeight + (parseInt(marginBottom) || 0),
191
- );
181
+ this.cardHeight.set(event.target.clientHeight + (parseInt(marginBottom) || 0));
192
182
  }
193
183
 
194
184
  onCardDragStart() {
@@ -21,13 +21,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
21
21
  changeDetection: ChangeDetectionStrategy.OnPush,
22
22
  encapsulation: ViewEncapsulation.None,
23
23
  standalone: true,
24
- imports: [
25
- SdTypedTemplate,
26
- NgTemplateOutlet,
27
- SdCollapseIcon,
28
- SdCheckbox,
29
- SdAnchor,
30
- ],
24
+ imports: [SdTypedTemplate, NgTemplateOutlet, SdCollapseIcon, SdCheckbox, SdAnchor],
31
25
  styles: [
32
26
  /* language=SCSS */ `
33
27
  sd-permission-table {
@@ -36,22 +30,22 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
36
30
 
37
31
  > * > tr {
38
32
  > * {
39
- padding: var(--gap-sm) var(--gap-lg);
33
+ padding: var(--sd-gap-sm) var(--sd-gap-lg);
40
34
  position: sticky;
41
35
  top: 0;
42
36
  border-top: 1px solid transparent;
43
37
  border-bottom: 1px solid transparent;
44
38
 
45
- color: var(--text-trans-default);
39
+ color: var(--sd-tx-default);
46
40
 
47
41
  > * {
48
- color: var(--text-trans-default) !important;
42
+ color: var(--sd-tx-default) !important;
49
43
  }
50
44
 
51
45
  &._title {
52
46
  border-top-left-radius: 14px;
53
47
  border-bottom-left-radius: 14px;
54
- padding-left: var(--gap-lg);
48
+ padding-left: var(--sd-gap-lg);
55
49
  }
56
50
  }
57
51
 
@@ -63,12 +57,12 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
63
57
  > * {
64
58
  &._title,
65
59
  &._after {
66
- background: var(--theme-info-default);
60
+ background-color: var(--sd-permission-group-bg);
67
61
 
68
- color: var(--text-trans-rev-default);
62
+ color: var(--sd-permission-group-tx);
69
63
 
70
64
  > * {
71
- color: var(--text-trans-rev-default) !important;
65
+ color: var(--sd-permission-group-tx) !important;
72
66
  }
73
67
  }
74
68
  }
@@ -78,7 +72,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
78
72
  > * {
79
73
  &._title,
80
74
  &._after {
81
- background: var(--theme-info-lightest);
75
+ background-color: var(--sd-bg-info-subtle);
82
76
  }
83
77
  }
84
78
  }
@@ -87,7 +81,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
87
81
  > * {
88
82
  &._title,
89
83
  &._after {
90
- background: var(--theme-warning-lightest);
84
+ background-color: var(--sd-bg-warning-subtle);
91
85
  }
92
86
  }
93
87
  }
@@ -96,7 +90,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
96
90
  > * {
97
91
  &._title,
98
92
  &._after {
99
- background: var(--theme-success-lightest);
93
+ background-color: var(--sd-bg-success-subtle);
100
94
  }
101
95
  }
102
96
  }
@@ -130,9 +124,7 @@ import { SdAnchor } from "../../controls/button/sd-anchor";
130
124
  let-depth="depth"
131
125
  let-parent="parent"
132
126
  >
133
- @if (
134
- (item.children && item.children.length !== 0) || (item.perms && item.perms.length > 0)
135
- ) {
127
+ @if ((item.children && item.children.length !== 0) || (item.perms && item.perms.length > 0)) {
136
128
  <tr
137
129
  [attr.data-sd-collapse]="!!parent && getIsPermCollapsed(parent)"
138
130
  [attr.data-sd-theme]="
@@ -40,15 +40,7 @@ import { tablerExternalLink } from "@ng-icons/tabler-icons";
40
40
  changeDetection: ChangeDetectionStrategy.OnPush,
41
41
  encapsulation: ViewEncapsulation.None,
42
42
  standalone: true,
43
- imports: [
44
- NgTemplateOutlet,
45
- SdTextfield,
46
- SdPagination,
47
- SdAnchor,
48
- SdList,
49
- SdListItem,
50
- NgIcon,
51
- ],
43
+ imports: [NgTemplateOutlet, SdTextfield, SdPagination, SdAnchor, SdList, SdListItem, NgIcon],
52
44
  host: {
53
45
  class: "flex-column fill",
54
46
  },
@@ -99,7 +91,7 @@ import { tablerExternalLink } from "@ng-icons/tabler-icons";
99
91
  @if (undefinedTplRef()) {
100
92
  <ng-template [ngTemplateOutlet]="undefinedTplRef()!" />
101
93
  } @else {
102
- <span class="tx-theme-gray-default">미지정</span>
94
+ <span class="tx-gray">미지정</span>
103
95
  }
104
96
  </sd-list-item>
105
97
  }
@@ -132,9 +124,7 @@ export class SdSharedDataSelectList<
132
124
  private readonly _sdModal = inject(SdModalProvider);
133
125
 
134
126
  selectedItem = model<TItem>();
135
- canChangeFn = input<(item: TItem | undefined) => boolean | Promise<boolean>>(
136
- () => true,
137
- );
127
+ canChangeFn = input<(item: TItem | undefined) => boolean | Promise<boolean>>(() => true);
138
128
 
139
129
  items = input.required<TItem[]>();
140
130
  selectedIcon = input<string>();
@@ -168,9 +158,7 @@ export class SdSharedDataSelectList<
168
158
  let result = this.items().filter((item) => !item.__isHidden);
169
159
 
170
160
  if (!str.isNullOrEmpty(this.searchText())) {
171
- result = result.filter((item) =>
172
- matchesSearchText(item.__searchText, this.searchText()),
173
- );
161
+ result = result.filter((item) => matchesSearchText(item.__searchText, this.searchText()));
174
162
  }
175
163
 
176
164
  if (this.filterFn() != null) {
@@ -207,9 +195,7 @@ export class SdSharedDataSelectList<
207
195
  const items = this.items();
208
196
  const current = untracked(() => this.selectedItem());
209
197
  if (current != null) {
210
- const updated = items.find(
211
- (item) => item.__valueKey === current.__valueKey,
212
- );
198
+ const updated = items.find((item) => item.__valueKey === current.__valueKey);
213
199
  if (updated !== current) {
214
200
  this.selectedItem.set(updated);
215
201
  }