@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.
- package/dist/controls/button/sd-additional-button.js +2 -2
- package/dist/controls/button/sd-anchor.d.ts.map +1 -1
- package/dist/controls/button/sd-anchor.js +3 -3
- package/dist/controls/button/sd-button.d.ts.map +1 -1
- package/dist/controls/button/sd-button.js +3 -3
- package/dist/controls/button/sd-modal-select-button.d.ts.map +1 -1
- package/dist/controls/button/sd-modal-select-button.js +2 -2
- package/dist/controls/checkbox/sd-checkbox.d.ts.map +1 -1
- package/dist/controls/checkbox/sd-checkbox.js +3 -3
- package/dist/controls/checkbox/sd-switch.d.ts.map +1 -1
- package/dist/controls/checkbox/sd-switch.js +3 -3
- package/dist/controls/collapse/sd-collapse-icon.d.ts +1 -1
- package/dist/controls/collapse/sd-collapse-icon.d.ts.map +1 -1
- package/dist/controls/collapse/sd-collapse-icon.js +2 -2
- package/dist/controls/collapse/sd-collapse.d.ts +1 -1
- package/dist/controls/collapse/sd-collapse.d.ts.map +1 -1
- package/dist/controls/collapse/sd-collapse.js +2 -2
- package/dist/controls/dropdown/sd-dropdown-popup.d.ts.map +1 -1
- package/dist/controls/dropdown/sd-dropdown-popup.js +2 -2
- package/dist/controls/dropdown/sd-dropdown.js +1 -1
- package/dist/controls/gap/sd-gap.d.ts.map +1 -1
- package/dist/controls/gap/sd-gap.js +5 -7
- package/dist/controls/input/sd-date-range-picker.js +2 -2
- package/dist/controls/input/sd-numpad.d.ts.map +1 -1
- package/dist/controls/input/sd-numpad.js +7 -15
- package/dist/controls/input/sd-range.js +2 -2
- package/dist/controls/input/sd-textarea.js +4 -4
- package/dist/controls/input/sd-textfield.d.ts.map +1 -1
- package/dist/controls/input/sd-textfield.js +10 -10
- package/dist/controls/list/sd-list-item.js +43 -43
- package/dist/controls/list/sd-list.js +2 -2
- package/dist/controls/pagination/sd-pagination.d.ts.map +1 -1
- package/dist/controls/pagination/sd-pagination.js +7 -5
- package/dist/controls/select/sd-select-button.d.ts.map +1 -1
- package/dist/controls/select/sd-select-button.js +4 -4
- package/dist/controls/select/sd-select-item.d.ts.map +1 -1
- package/dist/controls/select/sd-select-item.js +3 -3
- package/dist/controls/select/sd-select.d.ts.map +1 -1
- package/dist/controls/select/sd-select.js +10 -19
- package/dist/controls/tab/sd-tab-item.js +2 -2
- package/dist/controls/tab/sd-tab.js +2 -2
- package/dist/core/busy/sd-busy-container.d.ts.map +1 -1
- package/dist/core/busy/sd-busy-container.js +3 -3
- package/dist/core/modal/sd-modal.d.ts.map +1 -1
- package/dist/core/modal/sd-modal.js +3 -3
- package/dist/core/provideSdAngular.d.ts.map +1 -1
- package/dist/core/provideSdAngular.js +31 -10
- package/dist/core/ripple/setupRipple.js +2 -2
- package/dist/core/setupBgTheme.d.ts +0 -1
- package/dist/core/setupBgTheme.d.ts.map +1 -1
- package/dist/core/setupBgTheme.js +3 -4
- package/dist/core/show-effect/setupRevealOnShow.js +1 -1
- package/dist/core/toast/sd-toast-container.js +2 -2
- package/dist/core/toast/sd-toast.d.ts.map +1 -1
- package/dist/core/toast/sd-toast.js +3 -3
- package/dist/core/validation/setupInvalid.js +5 -5
- package/dist/data/crud/sd-base-container.d.ts.map +1 -1
- package/dist/data/crud/sd-base-container.js +50 -52
- package/dist/data/kanban/sd-kanban-board.js +2 -2
- package/dist/data/kanban/sd-kanban-lane.d.ts.map +1 -1
- package/dist/data/kanban/sd-kanban-lane.js +4 -4
- package/dist/data/kanban/sd-kanban.d.ts.map +1 -1
- package/dist/data/kanban/sd-kanban.js +4 -4
- package/dist/data/permission-table/sd-permission-table.d.ts.map +1 -1
- package/dist/data/permission-table/sd-permission-table.js +5 -17
- package/dist/data/shared-data/sd-shared-data-select-list.d.ts.map +1 -1
- package/dist/data/shared-data/sd-shared-data-select-list.js +5 -19
- package/dist/data/shared-data/sd-shared-data-select.d.ts.map +1 -1
- package/dist/data/shared-data/sd-shared-data-select.js +8 -15
- package/dist/data/sheet/sd-sheet-config.modal.d.ts.map +1 -1
- package/dist/data/sheet/sd-sheet-config.modal.js +7 -9
- package/dist/data/sheet/sd-sheet.d.ts.map +1 -1
- package/dist/data/sheet/sd-sheet.js +10 -12
- package/dist/data/sheet/useSheetCellStyling.d.ts.map +1 -1
- package/dist/data/sheet/useSheetCellStyling.js +1 -1
- package/dist/data/state-preset/sd-state-preset.js +5 -5
- package/dist/features/editor/sd-markdown-editor.d.ts.map +1 -1
- package/dist/features/editor/sd-markdown-editor.js +85 -34
- package/dist/features/editor/sd-tiptap-editor.d.ts.map +1 -1
- package/dist/features/editor/sd-tiptap-editor.js +192 -61
- package/dist/features/theme/sd-theme-provider.d.ts +18 -1
- package/dist/features/theme/sd-theme-provider.d.ts.map +1 -1
- package/dist/features/theme/sd-theme-provider.js +21 -4
- package/dist/features/theme/sd-theme-selector.d.ts.map +1 -1
- package/dist/features/theme/sd-theme-selector.js +50 -9
- package/dist/features/theme/wcag-contrast.d.ts +9 -0
- package/dist/features/theme/wcag-contrast.d.ts.map +1 -0
- package/dist/features/theme/wcag-contrast.js +83 -0
- package/dist/features/visual/sd-calendar.js +2 -2
- package/dist/features/visual/sd-label.d.ts.map +1 -1
- package/dist/features/visual/sd-label.js +5 -5
- package/dist/features/visual/sd-note.d.ts.map +1 -1
- package/dist/features/visual/sd-note.js +3 -3
- package/dist/features/visual/sd-progress.d.ts.map +1 -1
- package/dist/features/visual/sd-progress.js +3 -3
- package/dist/index.d.ts +12 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -9
- package/dist/layout/sidebar/sd-sidebar-container.d.ts.map +1 -1
- package/dist/layout/sidebar/sd-sidebar-container.js +11 -5
- package/dist/layout/sidebar/sd-sidebar-menu.d.ts.map +1 -1
- package/dist/layout/sidebar/sd-sidebar-menu.js +5 -17
- package/dist/layout/sidebar/sd-sidebar-user.js +32 -32
- package/dist/layout/sidebar/sd-sidebar.d.ts.map +1 -1
- package/dist/layout/sidebar/sd-sidebar.js +3 -3
- package/dist/layout/topbar/sd-topbar-menu.js +5 -5
- package/dist/layout/topbar/sd-topbar.d.ts.map +1 -1
- package/dist/layout/topbar/sd-topbar.js +5 -5
- package/package.json +5 -5
- package/scss/commons/_colors.scss +296 -242
- package/scss/commons/_density.scss +23 -0
- package/scss/commons/_mixins.scss +142 -129
- package/scss/commons/_styles.scss +78 -103
- package/scss/commons/_theme-variables.scss +16 -2
- package/scss/commons/_variables.scss +277 -149
- package/scss/controls/_card.scss +12 -8
- package/scss/controls/_form-box.scss +7 -7
- package/scss/controls/_form-table.scss +7 -7
- package/scss/controls/_table.scss +5 -5
- package/scss/sd-tokens.md +132 -0
- package/scss/styles.scss +3 -4
- package/scss/themes/_variables-blueprint.scss +127 -81
- package/scss/themes/_variables-ide-dark.scss +215 -0
- package/src/controls/button/sd-additional-button.ts +12 -12
- package/src/controls/button/sd-anchor.ts +7 -8
- package/src/controls/button/sd-button.ts +42 -44
- package/src/controls/button/sd-modal-select-button.ts +15 -19
- package/src/controls/checkbox/sd-checkbox.ts +55 -43
- package/src/controls/checkbox/sd-switch.ts +18 -19
- package/src/controls/collapse/sd-collapse-icon.ts +2 -2
- package/src/controls/collapse/sd-collapse.ts +2 -2
- package/src/controls/dropdown/sd-dropdown-popup.ts +10 -12
- package/src/controls/dropdown/sd-dropdown.ts +1 -1
- package/src/controls/gap/sd-gap.ts +11 -9
- package/src/controls/input/sd-date-range-picker.ts +1 -1
- package/src/controls/input/sd-numpad.ts +3 -11
- package/src/controls/input/sd-range.ts +1 -1
- package/src/controls/input/sd-textarea.ts +18 -18
- package/src/controls/input/sd-textfield.ts +39 -37
- package/src/controls/list/sd-list-item.ts +195 -195
- package/src/controls/list/sd-list.ts +8 -8
- package/src/controls/pagination/sd-pagination.ts +4 -2
- package/src/controls/select/sd-select-button.ts +6 -10
- package/src/controls/select/sd-select-item.ts +14 -15
- package/src/controls/select/sd-select.ts +34 -35
- package/src/controls/tab/sd-tab-item.ts +4 -4
- package/src/controls/tab/sd-tab.ts +2 -2
- package/src/core/busy/sd-busy-container.ts +17 -16
- package/src/core/modal/sd-modal.ts +38 -32
- package/src/core/provideSdAngular.ts +34 -10
- package/src/core/ripple/setupRipple.ts +2 -2
- package/src/core/setupBgTheme.ts +5 -14
- package/src/core/show-effect/setupRevealOnShow.ts +1 -1
- package/src/core/toast/sd-toast-container.ts +5 -5
- package/src/core/toast/sd-toast.ts +16 -17
- package/src/core/validation/setupInvalid.ts +5 -5
- package/src/data/crud/sd-base-container.ts +120 -122
- package/src/data/kanban/sd-kanban-board.ts +1 -1
- package/src/data/kanban/sd-kanban-lane.ts +9 -14
- package/src/data/kanban/sd-kanban.ts +9 -19
- package/src/data/permission-table/sd-permission-table.ts +12 -20
- package/src/data/shared-data/sd-shared-data-select-list.ts +5 -19
- package/src/data/shared-data/sd-shared-data-select.ts +11 -28
- package/src/data/sheet/sd-sheet-config.modal.ts +5 -7
- package/src/data/sheet/sd-sheet.ts +29 -28
- package/src/data/sheet/useSheetCellStyling.ts +12 -3
- package/src/data/state-preset/sd-state-preset.ts +16 -16
- package/src/features/editor/sd-markdown-editor.ts +110 -56
- package/src/features/editor/sd-tiptap-editor.ts +214 -81
- package/src/features/theme/sd-theme-provider.ts +28 -3
- package/src/features/theme/sd-theme-selector.ts +21 -2
- package/src/features/theme/wcag-contrast.ts +103 -0
- package/src/features/visual/sd-calendar.ts +8 -8
- package/src/features/visual/sd-label.ts +11 -12
- package/src/features/visual/sd-note.ts +10 -11
- package/src/features/visual/sd-progress.ts +9 -11
- package/src/index.ts +15 -40
- package/src/layout/sidebar/sd-sidebar-container.ts +21 -8
- package/src/layout/sidebar/sd-sidebar-menu.ts +15 -17
- package/src/layout/sidebar/sd-sidebar-user.ts +100 -100
- package/src/layout/sidebar/sd-sidebar.ts +7 -9
- package/src/layout/topbar/sd-topbar-menu.ts +3 -3
- package/src/layout/topbar/sd-topbar.ts +12 -14
- package/styles.css +1641 -2462
- package/scss/themes/_blueprint-surfaces.scss +0 -87
|
@@ -46,56 +46,148 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
46
46
|
@if (!disabled()) {
|
|
47
47
|
<div class="_toolbar">
|
|
48
48
|
<div class="_btn-group">
|
|
49
|
-
<button
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
<button
|
|
50
|
+
type="button"
|
|
51
|
+
data-cmd="h1"
|
|
52
|
+
[class._active]="activeStates().h1"
|
|
53
|
+
(click)="execCmd('h1')"
|
|
54
|
+
>
|
|
55
|
+
H1
|
|
56
|
+
</button>
|
|
57
|
+
<button
|
|
58
|
+
type="button"
|
|
59
|
+
data-cmd="h2"
|
|
60
|
+
[class._active]="activeStates().h2"
|
|
61
|
+
(click)="execCmd('h2')"
|
|
62
|
+
>
|
|
63
|
+
H2
|
|
64
|
+
</button>
|
|
53
65
|
</div>
|
|
54
66
|
<div class="_btn-group">
|
|
55
|
-
<button
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
data-cmd="bold"
|
|
70
|
+
[class._active]="activeStates().bold"
|
|
71
|
+
(click)="execCmd('bold')"
|
|
72
|
+
>
|
|
73
|
+
B
|
|
74
|
+
</button>
|
|
75
|
+
<button
|
|
76
|
+
type="button"
|
|
77
|
+
data-cmd="italic"
|
|
78
|
+
[class._active]="activeStates().italic"
|
|
79
|
+
(click)="execCmd('italic')"
|
|
80
|
+
>
|
|
81
|
+
I
|
|
82
|
+
</button>
|
|
83
|
+
<button
|
|
84
|
+
type="button"
|
|
85
|
+
data-cmd="underline"
|
|
86
|
+
[class._active]="activeStates().underline"
|
|
87
|
+
(click)="execCmd('underline')"
|
|
88
|
+
>
|
|
89
|
+
U
|
|
90
|
+
</button>
|
|
91
|
+
<button
|
|
92
|
+
type="button"
|
|
93
|
+
data-cmd="strike"
|
|
94
|
+
[class._active]="activeStates().strike"
|
|
95
|
+
(click)="execCmd('strike')"
|
|
96
|
+
>
|
|
97
|
+
S
|
|
98
|
+
</button>
|
|
63
99
|
</div>
|
|
64
100
|
<div class="_btn-group">
|
|
65
|
-
<button
|
|
66
|
-
|
|
101
|
+
<button
|
|
102
|
+
type="button"
|
|
103
|
+
data-cmd="textColor"
|
|
104
|
+
class="_color-btn"
|
|
105
|
+
(click)="toggleColorPicker('text')"
|
|
106
|
+
>
|
|
67
107
|
<span class="_color-indicator" [style.background-color]="activeColor()"></span>
|
|
68
108
|
A
|
|
69
109
|
</button>
|
|
70
|
-
<button
|
|
71
|
-
|
|
110
|
+
<button
|
|
111
|
+
type="button"
|
|
112
|
+
data-cmd="bgColor"
|
|
113
|
+
class="_color-btn"
|
|
114
|
+
(click)="toggleColorPicker('bg')"
|
|
115
|
+
>
|
|
72
116
|
<span class="_color-indicator" [style.background-color]="activeBgColor()"></span>
|
|
73
117
|
BG
|
|
74
118
|
</button>
|
|
75
119
|
</div>
|
|
76
120
|
<div class="_btn-group">
|
|
77
|
-
<button
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
121
|
+
<button
|
|
122
|
+
type="button"
|
|
123
|
+
data-cmd="bulletList"
|
|
124
|
+
[class._active]="activeStates().bulletList"
|
|
125
|
+
(click)="execCmd('bulletList')"
|
|
126
|
+
>
|
|
127
|
+
UL
|
|
128
|
+
</button>
|
|
129
|
+
<button
|
|
130
|
+
type="button"
|
|
131
|
+
data-cmd="orderedList"
|
|
132
|
+
[class._active]="activeStates().orderedList"
|
|
133
|
+
(click)="execCmd('orderedList')"
|
|
134
|
+
>
|
|
135
|
+
OL
|
|
136
|
+
</button>
|
|
81
137
|
<button type="button" data-cmd="indent" (click)="execCmd('indent')">→</button>
|
|
82
138
|
<button type="button" data-cmd="outdent" (click)="execCmd('outdent')">←</button>
|
|
83
139
|
</div>
|
|
84
140
|
<div class="_btn-group">
|
|
85
|
-
<button
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
141
|
+
<button
|
|
142
|
+
type="button"
|
|
143
|
+
data-cmd="blockquote"
|
|
144
|
+
[class._active]="activeStates().blockquote"
|
|
145
|
+
(click)="execCmd('blockquote')"
|
|
146
|
+
>
|
|
147
|
+
❝
|
|
148
|
+
</button>
|
|
149
|
+
<button
|
|
150
|
+
type="button"
|
|
151
|
+
data-cmd="codeBlock"
|
|
152
|
+
[class._active]="activeStates().codeBlock"
|
|
153
|
+
(click)="execCmd('codeBlock')"
|
|
154
|
+
>
|
|
155
|
+
</>
|
|
156
|
+
</button>
|
|
89
157
|
</div>
|
|
90
158
|
<div class="_btn-group">
|
|
91
|
-
<button
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
159
|
+
<button
|
|
160
|
+
type="button"
|
|
161
|
+
data-cmd="alignLeft"
|
|
162
|
+
[class._active]="activeStates().alignLeft"
|
|
163
|
+
(click)="execCmd('alignLeft')"
|
|
164
|
+
>
|
|
165
|
+
≡L
|
|
166
|
+
</button>
|
|
167
|
+
<button
|
|
168
|
+
type="button"
|
|
169
|
+
data-cmd="alignCenter"
|
|
170
|
+
[class._active]="activeStates().alignCenter"
|
|
171
|
+
(click)="execCmd('alignCenter')"
|
|
172
|
+
>
|
|
173
|
+
≡C
|
|
174
|
+
</button>
|
|
175
|
+
<button
|
|
176
|
+
type="button"
|
|
177
|
+
data-cmd="alignRight"
|
|
178
|
+
[class._active]="activeStates().alignRight"
|
|
179
|
+
(click)="execCmd('alignRight')"
|
|
180
|
+
>
|
|
181
|
+
≡R
|
|
182
|
+
</button>
|
|
183
|
+
<button
|
|
184
|
+
type="button"
|
|
185
|
+
data-cmd="alignJustify"
|
|
186
|
+
[class._active]="activeStates().alignJustify"
|
|
187
|
+
(click)="execCmd('alignJustify')"
|
|
188
|
+
>
|
|
189
|
+
≡J
|
|
190
|
+
</button>
|
|
99
191
|
</div>
|
|
100
192
|
<div class="_btn-group">
|
|
101
193
|
<button type="button" data-cmd="clean" (click)="execCmd('clean')">Tx</button>
|
|
@@ -104,13 +196,17 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
104
196
|
@if (colorPickerMode() != undefined) {
|
|
105
197
|
<div class="_color-picker">
|
|
106
198
|
@for (color of colorPresets; track color) {
|
|
107
|
-
<button
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
199
|
+
<button
|
|
200
|
+
type="button"
|
|
201
|
+
class="_color-swatch"
|
|
202
|
+
[style.background-color]="color"
|
|
203
|
+
[attr.aria-label]="color"
|
|
204
|
+
(click)="applyColor(color)"
|
|
205
|
+
></button>
|
|
111
206
|
}
|
|
112
|
-
<button type="button" class="_color-swatch _no-color"
|
|
113
|
-
|
|
207
|
+
<button type="button" class="_color-swatch _no-color" (click)="applyColor(undefined)">
|
|
208
|
+
✕
|
|
209
|
+
</button>
|
|
114
210
|
</div>
|
|
115
211
|
}
|
|
116
212
|
}
|
|
@@ -121,41 +217,41 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
121
217
|
sd-tiptap-editor {
|
|
122
218
|
display: block;
|
|
123
219
|
position: relative;
|
|
124
|
-
border: 1px solid var(--
|
|
125
|
-
border-radius: var(--
|
|
126
|
-
background: var(--
|
|
220
|
+
border: 1px solid var(--sd-bd-field);
|
|
221
|
+
border-radius: var(--sd-radius-default);
|
|
222
|
+
background-color: var(--sd-bg-field);
|
|
127
223
|
|
|
128
224
|
> ._toolbar {
|
|
129
225
|
display: flex;
|
|
130
226
|
flex-wrap: wrap;
|
|
131
|
-
gap: var(--gap-xs);
|
|
132
|
-
padding: var(--gap-xs);
|
|
133
|
-
border-bottom: 1px solid var(--
|
|
227
|
+
gap: var(--sd-gap-xs);
|
|
228
|
+
padding: var(--sd-gap-xs);
|
|
229
|
+
border-bottom: 1px solid var(--sd-bd-hairline);
|
|
134
230
|
|
|
135
231
|
> ._btn-group {
|
|
136
232
|
display: flex;
|
|
137
233
|
gap: 1px;
|
|
138
234
|
|
|
139
235
|
> button {
|
|
140
|
-
padding: var(--gap-xs) var(--gap-sm);
|
|
141
|
-
border: 1px solid var(--
|
|
142
|
-
border-radius: var(--
|
|
143
|
-
background: transparent;
|
|
236
|
+
padding: var(--sd-gap-xs) var(--sd-gap-sm);
|
|
237
|
+
border: 1px solid var(--sd-bd-hairline);
|
|
238
|
+
border-radius: var(--sd-radius-default);
|
|
239
|
+
background-color: transparent;
|
|
144
240
|
cursor: pointer;
|
|
145
|
-
font-size: var(--font-size-default);
|
|
241
|
+
font-size: var(--sd-font-size-default);
|
|
146
242
|
line-height: 1;
|
|
147
243
|
|
|
148
244
|
&._active {
|
|
149
|
-
background: var(--
|
|
150
|
-
color: var(--
|
|
245
|
+
background-color: var(--sd-bg-primary-solid);
|
|
246
|
+
color: var(--sd-tx-primary-solid);
|
|
151
247
|
}
|
|
152
248
|
|
|
153
249
|
&:hover {
|
|
154
|
-
background: var(--
|
|
250
|
+
background-color: var(--sd-bg-state-hover);
|
|
155
251
|
}
|
|
156
252
|
|
|
157
253
|
&._active:hover {
|
|
158
|
-
background: var(--
|
|
254
|
+
background-color: var(--sd-bg-primary-solid);
|
|
159
255
|
}
|
|
160
256
|
}
|
|
161
257
|
}
|
|
@@ -165,13 +261,13 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
165
261
|
display: flex;
|
|
166
262
|
flex-wrap: wrap;
|
|
167
263
|
gap: 2px;
|
|
168
|
-
padding: var(--gap-xs);
|
|
169
|
-
border-bottom: 1px solid var(--
|
|
264
|
+
padding: var(--sd-gap-xs);
|
|
265
|
+
border-bottom: 1px solid var(--sd-bd-hairline);
|
|
170
266
|
|
|
171
267
|
> ._color-swatch {
|
|
172
268
|
width: 1.25rem;
|
|
173
269
|
height: 1.25rem;
|
|
174
|
-
border: 1px solid var(--
|
|
270
|
+
border: 1px solid var(--sd-bd-hairline);
|
|
175
271
|
border-radius: 2px;
|
|
176
272
|
cursor: pointer;
|
|
177
273
|
padding: 0;
|
|
@@ -180,16 +276,16 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
180
276
|
display: flex;
|
|
181
277
|
align-items: center;
|
|
182
278
|
justify-content: center;
|
|
183
|
-
background: var(--control
|
|
279
|
+
background-color: var(--sd-bg-control);
|
|
184
280
|
font-size: 0.625rem;
|
|
185
281
|
}
|
|
186
282
|
}
|
|
187
283
|
}
|
|
188
284
|
|
|
189
285
|
> ._editor-container {
|
|
190
|
-
padding: var(--gap-sm);
|
|
286
|
+
padding: var(--sd-gap-sm);
|
|
191
287
|
min-height: 6.25rem;
|
|
192
|
-
font-family: var(--font-family-field);
|
|
288
|
+
font-family: var(--sd-font-family-field);
|
|
193
289
|
|
|
194
290
|
> .tiptap {
|
|
195
291
|
outline: none;
|
|
@@ -200,9 +296,10 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
200
296
|
}
|
|
201
297
|
}
|
|
202
298
|
|
|
299
|
+
// disabled 는 색 치환 단일 규약 (DEC-009)
|
|
203
300
|
&[data-sd-disabled="true"] {
|
|
204
|
-
background: var(--
|
|
205
|
-
color: var(--
|
|
301
|
+
background-color: var(--sd-bg-disabled);
|
|
302
|
+
color: var(--sd-tx-disabled);
|
|
206
303
|
|
|
207
304
|
> ._editor-container > .tiptap {
|
|
208
305
|
cursor: not-allowed;
|
|
@@ -248,11 +345,46 @@ export class SdTiptapEditor {
|
|
|
248
345
|
private readonly _destroyRef = inject(DestroyRef);
|
|
249
346
|
|
|
250
347
|
readonly colorPresets = [
|
|
251
|
-
"#000000",
|
|
252
|
-
"#
|
|
253
|
-
"#
|
|
254
|
-
"#
|
|
255
|
-
"#
|
|
348
|
+
"#000000",
|
|
349
|
+
"#434343",
|
|
350
|
+
"#666666",
|
|
351
|
+
"#999999",
|
|
352
|
+
"#b7b7b7",
|
|
353
|
+
"#cccccc",
|
|
354
|
+
"#d9d9d9",
|
|
355
|
+
"#efefef",
|
|
356
|
+
"#f3f3f3",
|
|
357
|
+
"#ffffff",
|
|
358
|
+
"#980000",
|
|
359
|
+
"#ff0000",
|
|
360
|
+
"#ff9900",
|
|
361
|
+
"#ffff00",
|
|
362
|
+
"#00ff00",
|
|
363
|
+
"#00ffff",
|
|
364
|
+
"#4a86e8",
|
|
365
|
+
"#0000ff",
|
|
366
|
+
"#9900ff",
|
|
367
|
+
"#ff00ff",
|
|
368
|
+
"#e6b8af",
|
|
369
|
+
"#f4cccc",
|
|
370
|
+
"#fce5cd",
|
|
371
|
+
"#fff2cc",
|
|
372
|
+
"#d9ead3",
|
|
373
|
+
"#d0e0e3",
|
|
374
|
+
"#c9daf8",
|
|
375
|
+
"#cfe2f3",
|
|
376
|
+
"#d9d2e9",
|
|
377
|
+
"#ead1dc",
|
|
378
|
+
"#dd7e6b",
|
|
379
|
+
"#ea9999",
|
|
380
|
+
"#f9cb9c",
|
|
381
|
+
"#ffe599",
|
|
382
|
+
"#b6d7a8",
|
|
383
|
+
"#a2c4c9",
|
|
384
|
+
"#a4c2f4",
|
|
385
|
+
"#9fc5e8",
|
|
386
|
+
"#b4a7d6",
|
|
387
|
+
"#d5a6bd",
|
|
256
388
|
];
|
|
257
389
|
|
|
258
390
|
/** @internal -- TipTap Editor 인스턴스. 테스트 및 고급 사용자용 */
|
|
@@ -344,20 +476,22 @@ export class SdTiptapEditor {
|
|
|
344
476
|
const container = this._elRef.nativeElement.querySelector("._editor-container");
|
|
345
477
|
if (container == null) return;
|
|
346
478
|
|
|
347
|
-
this.editor.set(
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
479
|
+
this.editor.set(
|
|
480
|
+
new Editor({
|
|
481
|
+
element: container,
|
|
482
|
+
extensions,
|
|
483
|
+
content: initialContent ?? "",
|
|
484
|
+
editable: untracked(() => !this.disabled() && !this.readonly()),
|
|
485
|
+
onUpdate: ({ editor }) => {
|
|
486
|
+
const html = this._getEditorHtmlFrom(editor);
|
|
487
|
+
this._lastEditorHtml = html;
|
|
488
|
+
this.value.set(html);
|
|
489
|
+
},
|
|
490
|
+
onTransaction: () => {
|
|
491
|
+
this._toolbar.refreshActiveStates();
|
|
492
|
+
},
|
|
493
|
+
}),
|
|
494
|
+
);
|
|
361
495
|
}
|
|
362
496
|
|
|
363
497
|
private _destroyEditor(): void {
|
|
@@ -374,5 +508,4 @@ export class SdTiptapEditor {
|
|
|
374
508
|
if (editor.isEmpty) return undefined;
|
|
375
509
|
return html;
|
|
376
510
|
}
|
|
377
|
-
|
|
378
511
|
}
|
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
import { effect, inject, Injectable, PLATFORM_ID, signal } from "@angular/core";
|
|
2
2
|
import { isPlatformBrowser } from "@angular/common";
|
|
3
3
|
|
|
4
|
+
// 내장 테마 단일 정의 — 새 테마 추가 시 여기 항목 1줄 +
|
|
5
|
+
// scss/themes 값 맵 + _theme-variables 의 .sd-theme-{value} writeVars 블록만 추가하면 된다.
|
|
6
|
+
// light 는 :root 기본값이라 값 맵/블록이 없어도 동작한다(클래스가 붙어도 규칙이 없어 무효).
|
|
7
|
+
export const SD_THEMES = [
|
|
8
|
+
{ value: "light", label: "라이트" },
|
|
9
|
+
{ value: "blueprint", label: "블루프린트" },
|
|
10
|
+
{ value: "ide-dark", label: "IDE 다크" },
|
|
11
|
+
] as const;
|
|
12
|
+
|
|
13
|
+
export type SdThemeName = (typeof SD_THEMES)[number]["value"];
|
|
14
|
+
|
|
15
|
+
// 밀도 축 — 테마와 직교(DEC-007). compact 는 치수 토큰 그룹(sd-density-compact)만 덮는다.
|
|
16
|
+
export type SdDensity = "normal" | "compact";
|
|
17
|
+
|
|
4
18
|
@Injectable({ providedIn: "root" })
|
|
5
19
|
export class SdThemeProvider {
|
|
6
|
-
|
|
7
|
-
|
|
20
|
+
readonly themes: readonly { value: SdThemeName; label: string }[] = SD_THEMES;
|
|
21
|
+
|
|
22
|
+
// 라이트(기본) / 블루프린트(도면) / IDE 다크
|
|
23
|
+
theme = signal<SdThemeName>("light");
|
|
24
|
+
|
|
25
|
+
density = signal<SdDensity>("normal");
|
|
8
26
|
|
|
9
27
|
readonly fontSizePresets: readonly number[] = [12, 14, 16, 20, 24, 28];
|
|
10
28
|
|
|
@@ -15,7 +33,14 @@ export class SdThemeProvider {
|
|
|
15
33
|
if (!isPlatformBrowser(inject(PLATFORM_ID))) return;
|
|
16
34
|
|
|
17
35
|
effect(() => {
|
|
18
|
-
|
|
36
|
+
const theme = this.theme();
|
|
37
|
+
for (const def of this.themes) {
|
|
38
|
+
document.body.classList.toggle(`sd-theme-${def.value}`, def.value === theme);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
effect(() => {
|
|
43
|
+
document.body.classList.toggle("sd-density-compact", this.density() === "compact");
|
|
19
44
|
});
|
|
20
45
|
|
|
21
46
|
effect(() => {
|
|
@@ -51,8 +51,27 @@ import { tablerMinus, tablerPalette, tablerPlus } from "@ng-icons/tabler-icons";
|
|
|
51
51
|
</div>
|
|
52
52
|
</div>
|
|
53
53
|
<div class="flex-row gap-sm cross-align-center">
|
|
54
|
-
<span
|
|
55
|
-
<
|
|
54
|
+
<span>테마</span>
|
|
55
|
+
<div class="flex-row gap-xs cross-align-center">
|
|
56
|
+
@for (item of _sdTheme.themes; track item.value) {
|
|
57
|
+
<sd-button
|
|
58
|
+
[inline]="true"
|
|
59
|
+
[size]="'sm'"
|
|
60
|
+
[theme]="_sdTheme.theme() === item.value ? 'primary' : 'link-gray'"
|
|
61
|
+
(click)="_sdTheme.theme.set(item.value)"
|
|
62
|
+
>
|
|
63
|
+
{{ item.label }}
|
|
64
|
+
</sd-button>
|
|
65
|
+
}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="flex-row gap-sm cross-align-center">
|
|
69
|
+
<span>compact</span>
|
|
70
|
+
<sd-switch
|
|
71
|
+
[inline]="true"
|
|
72
|
+
[value]="_sdTheme.density() === 'compact'"
|
|
73
|
+
(valueChange)="_sdTheme.density.set($event ? 'compact' : 'normal')"
|
|
74
|
+
/>
|
|
56
75
|
</div>
|
|
57
76
|
</div>
|
|
58
77
|
</sd-dropdown-popup>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// WCAG 2.x 대비율 계산 (DEC-012) — 테마(커스텀 테마 포함) 핵심 fg/bg 쌍 검증용.
|
|
2
|
+
// 알파 색은 배경 표면에 합성 후 계산한다.
|
|
3
|
+
|
|
4
|
+
interface RgbaColor {
|
|
5
|
+
r: number;
|
|
6
|
+
g: number;
|
|
7
|
+
b: number;
|
|
8
|
+
a: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function parseCssColor(colorText: string): RgbaColor {
|
|
12
|
+
const trimmed = colorText.trim().toLowerCase();
|
|
13
|
+
|
|
14
|
+
if (trimmed === "white") return { r: 255, g: 255, b: 255, a: 1 };
|
|
15
|
+
if (trimmed === "black") return { r: 0, g: 0, b: 0, a: 1 };
|
|
16
|
+
if (trimmed === "transparent") return { r: 0, g: 0, b: 0, a: 0 };
|
|
17
|
+
|
|
18
|
+
const hexMatch = /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/.exec(trimmed);
|
|
19
|
+
if (hexMatch) {
|
|
20
|
+
const hex = hexMatch[1];
|
|
21
|
+
if (hex.length === 3) {
|
|
22
|
+
return {
|
|
23
|
+
r: parseInt(hex[0] + hex[0], 16),
|
|
24
|
+
g: parseInt(hex[1] + hex[1], 16),
|
|
25
|
+
b: parseInt(hex[2] + hex[2], 16),
|
|
26
|
+
a: 1,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
r: parseInt(hex.slice(0, 2), 16),
|
|
31
|
+
g: parseInt(hex.slice(2, 4), 16),
|
|
32
|
+
b: parseInt(hex.slice(4, 6), 16),
|
|
33
|
+
a: hex.length === 8 ? parseInt(hex.slice(6, 8), 16) / 255 : 1,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const rgbMatch =
|
|
38
|
+
/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+)\s*)?\)$/.exec(trimmed);
|
|
39
|
+
if (rgbMatch) {
|
|
40
|
+
// 알파 캡처 그룹은 미매치 시 런타임에 undefined (exec 타입은 string 으로 나옴)
|
|
41
|
+
const alphaText = rgbMatch[4] as string | undefined;
|
|
42
|
+
return {
|
|
43
|
+
r: Number(rgbMatch[1]),
|
|
44
|
+
g: Number(rgbMatch[2]),
|
|
45
|
+
b: Number(rgbMatch[3]),
|
|
46
|
+
a: alphaText != null ? Number(alphaText) : 1,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
throw new Error(`WCAG 대비 계산: 색상을 해석할 수 없습니다: "${colorText}"`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function composite(fg: RgbaColor, bg: RgbaColor): RgbaColor {
|
|
54
|
+
const a = fg.a + bg.a * (1 - fg.a);
|
|
55
|
+
if (a === 0) return { r: 0, g: 0, b: 0, a: 0 };
|
|
56
|
+
return {
|
|
57
|
+
r: (fg.r * fg.a + bg.r * bg.a * (1 - fg.a)) / a,
|
|
58
|
+
g: (fg.g * fg.a + bg.g * bg.a * (1 - fg.a)) / a,
|
|
59
|
+
b: (fg.b * fg.a + bg.b * bg.a * (1 - fg.a)) / a,
|
|
60
|
+
a,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getRelativeLuminance(color: RgbaColor): number {
|
|
65
|
+
const [r, g, b] = [color.r, color.g, color.b].map((v) => {
|
|
66
|
+
const srgb = v / 255;
|
|
67
|
+
return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);
|
|
68
|
+
});
|
|
69
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* WCAG 2.x 대비율 (1-21).
|
|
74
|
+
*
|
|
75
|
+
* @param foregroundColor 전경색(텍스트 등). 알파면 배경 위에 합성 후 계산.
|
|
76
|
+
* @param backgroundColor 배경색. 알파면 `baseColor` 위에 합성(불투명 배경이면 불필요).
|
|
77
|
+
* @param baseColor 반투명 배경 아래의 최종 불투명 표면색.
|
|
78
|
+
*/
|
|
79
|
+
export function getWcagContrastRatio(
|
|
80
|
+
foregroundColor: string,
|
|
81
|
+
backgroundColor: string,
|
|
82
|
+
baseColor?: string,
|
|
83
|
+
): number {
|
|
84
|
+
let bg = parseCssColor(backgroundColor);
|
|
85
|
+
if (bg.a < 1) {
|
|
86
|
+
if (baseColor == null) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`WCAG 대비 계산: 반투명 배경("${backgroundColor}")은 base 표면색이 필요합니다`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const base = parseCssColor(baseColor);
|
|
92
|
+
if (base.a < 1) {
|
|
93
|
+
throw new Error(`WCAG 대비 계산: base 표면색("${baseColor}")은 불투명해야 합니다`);
|
|
94
|
+
}
|
|
95
|
+
bg = composite(bg, base);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const fg = composite(parseCssColor(foregroundColor), bg);
|
|
99
|
+
|
|
100
|
+
const l1 = getRelativeLuminance(fg);
|
|
101
|
+
const l2 = getRelativeLuminance(bg);
|
|
102
|
+
return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
|
|
103
|
+
}
|
|
@@ -85,18 +85,18 @@ import { NgTemplateOutlet } from "@angular/common";
|
|
|
85
85
|
border-collapse: collapse;
|
|
86
86
|
width: 100%;
|
|
87
87
|
height: 100%;
|
|
88
|
-
border-radius: var(--
|
|
88
|
+
border-radius: var(--sd-radius-default);
|
|
89
89
|
overflow: hidden;
|
|
90
90
|
|
|
91
91
|
> * > tr > * {
|
|
92
|
-
padding: var(--gap-sm) var(--gap-default);
|
|
93
|
-
border: 1px solid var(--
|
|
92
|
+
padding: var(--sd-gap-sm) var(--sd-gap-default);
|
|
93
|
+
border: 1px solid var(--sd-bd-default);
|
|
94
94
|
|
|
95
95
|
width: calc(100% / 7);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
> thead > tr > th {
|
|
99
|
-
background: var(--
|
|
99
|
+
background-color: var(--sd-bg-gray-subtle);
|
|
100
100
|
height: 10%;
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -105,14 +105,14 @@ import { NgTemplateOutlet } from "@angular/common";
|
|
|
105
105
|
height: 15%;
|
|
106
106
|
|
|
107
107
|
> .day {
|
|
108
|
-
margin-bottom: var(--gap-sm);
|
|
108
|
+
margin-bottom: var(--sd-gap-sm);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
&.not-current {
|
|
112
|
-
background: var(--
|
|
112
|
+
background-color: var(--sd-bg-canvas);
|
|
113
113
|
|
|
114
114
|
> .day {
|
|
115
|
-
color: var(--
|
|
115
|
+
color: var(--sd-tx-gray);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -120,7 +120,7 @@ import { NgTemplateOutlet } from "@angular/common";
|
|
|
120
120
|
display: flex;
|
|
121
121
|
flex-wrap: nowrap;
|
|
122
122
|
|
|
123
|
-
@include mixins.flex-direction(column, var(--gap-sm));
|
|
123
|
+
@include mixins.flex-direction(column, var(--sd-gap-sm));
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
}
|