@synergy-design-system/mcp 2.8.0 → 2.8.2

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 (25) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/metadata/checksum.txt +1 -1
  3. package/metadata/packages/components/components/syn-dropdown/component.styles.ts +3 -5
  4. package/metadata/packages/components/components/syn-dropdown/component.ts +1 -2
  5. package/metadata/packages/components/components/syn-menu/component.styles.ts +23 -6
  6. package/metadata/packages/components/components/syn-menu/component.ts +1 -2
  7. package/metadata/packages/components/components/syn-menu-item/component.styles.ts +171 -43
  8. package/metadata/packages/components/components/syn-menu-item/component.ts +1 -2
  9. package/metadata/packages/components/components/syn-menu-label/component.styles.ts +17 -7
  10. package/metadata/packages/components/components/syn-menu-label/component.ts +1 -2
  11. package/metadata/packages/components/components/syn-validate/component.ts +18 -5
  12. package/metadata/packages/components/static/CHANGELOG.md +26 -0
  13. package/metadata/packages/tokens/CHANGELOG.md +4 -0
  14. package/metadata/packages/tokens/dark.css +1 -1
  15. package/metadata/packages/tokens/index.js +1 -1
  16. package/metadata/packages/tokens/light.css +1 -1
  17. package/metadata/packages/tokens/sick2018_dark.css +1 -1
  18. package/metadata/packages/tokens/sick2018_light.css +1 -1
  19. package/metadata/packages/tokens/sick2025_dark.css +1 -1
  20. package/metadata/packages/tokens/sick2025_light.css +1 -1
  21. package/package.json +4 -4
  22. package/metadata/packages/components/components/syn-dropdown/component.custom.styles.ts +0 -5
  23. package/metadata/packages/components/components/syn-menu/component.custom.styles.ts +0 -29
  24. package/metadata/packages/components/components/syn-menu-item/component.custom.styles.ts +0 -192
  25. package/metadata/packages/components/components/syn-menu-label/component.custom.styles.ts +0 -24
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1214](https://github.com/synergy-design-system/synergy-design-system/pull/1214) [`01c5e9c`](https://github.com/synergy-design-system/synergy-design-system/commit/01c5e9cc231c6bcc260cedc2f5d5713cf71ea254) Thanks [@schilchSICKAG](https://github.com/schilchSICKAG)! - Released on: 2026-03-06
8
+
9
+ fix: 🐛 Angular: `<syn-validate>` does not work when dynamically added to the DOM (#851)
10
+
11
+ This release fixes an issue that made `<syn-validate>` ignore its set `customValidationMessage` when the component gets dynamically added to the DOM in Angular. It does so by preferring the provided `customValidationMessage` over of the internally available `validationMessage`, which could be empty under certain conditions.
12
+
13
+ ## 2.8.1
14
+
15
+ ### Patch Changes
16
+
17
+ - [#1208](https://github.com/synergy-design-system/synergy-design-system/pull/1208) [`49c9d1c`](https://github.com/synergy-design-system/synergy-design-system/commit/49c9d1c30d777384024134ec983d183aed109421) Thanks [@schilchSICKAG](https://github.com/schilchSICKAG)! - Released on: 2026-03-03
18
+
19
+ fix: 🐛 `<syn-menu-item>`: Slotted `<syn-icon>` elements not visible on hover (#1194)
20
+
21
+ This release fixes a bug that accidentally set the color of slotted elements in `<syn-menu-item>` to white which lead to the icons appear to be invisible.
22
+
3
23
  ## 2.8.0
4
24
 
5
25
  ### Minor Changes
@@ -1 +1 @@
1
- 8e6d1d17a574847bbf85bc978ec6d9c9
1
+ 5682e415ee9342f4cf05aadd3e23b010
@@ -1,8 +1,6 @@
1
- /* eslint-disable */
2
1
  import { css } from 'lit';
3
2
 
4
3
  export default css`
5
- /* stylelint-disable */
6
4
  :host {
7
5
  display: inline-block;
8
6
  }
@@ -32,11 +30,11 @@ export default css`
32
30
  }
33
31
 
34
32
  .dropdown__panel {
33
+ border-radius: var(--syn-border-radius-medium);
34
+ box-shadow: var(--syn-shadow-large);
35
35
  font-family: var(--syn-font-sans);
36
36
  font-size: var(--syn-font-size-medium);
37
37
  font-weight: var(--syn-font-weight-normal);
38
- box-shadow: var(--syn-shadow-large);
39
- border-radius: var(--syn-border-radius-medium);
40
38
  pointer-events: none;
41
39
  }
42
40
 
@@ -47,7 +45,7 @@ export default css`
47
45
 
48
46
  /* When users slot a menu, make sure it conforms to the popup's auto-size */
49
47
  ::slotted(syn-menu) {
50
- max-width: var(--auto-size-available-width) !important;
51
48
  max-height: var(--auto-size-available-height) !important;
49
+ max-width: var(--auto-size-available-width) !important;
52
50
  }
53
51
  `;
@@ -14,7 +14,6 @@ import componentStyles from '../../styles/component.styles.js';
14
14
  import SynergyElement from '../../internal/synergy-element.js';
15
15
  import SynPopup from '../popup/popup.component.js';
16
16
  import styles from './dropdown.styles.js';
17
- import customStyles from './dropdown.custom.styles.js';
18
17
  import type { CSSResultGroup } from 'lit';
19
18
  import type { SynSelectEvent } from '../../events/syn-select.js';
20
19
  import type SynButton from '../button/button.js';
@@ -46,7 +45,7 @@ import type SynMenu from '../menu/menu.js';
46
45
  * @animation dropdown.hide - The animation to use when hiding the dropdown.
47
46
  */
48
47
  export default class SynDropdown extends SynergyElement {
49
- static styles: CSSResultGroup = [componentStyles, styles, customStyles];
48
+ static styles: CSSResultGroup = [componentStyles, styles];
50
49
  static dependencies = { 'syn-popup': SynPopup };
51
50
 
52
51
  @query('.dropdown') popup: SynPopup;
@@ -1,20 +1,37 @@
1
- /* eslint-disable */
2
1
  import { css } from 'lit';
3
2
 
4
3
  export default css`
5
- /* stylelint-disable */
6
4
  :host {
7
- display: block;
8
- position: relative;
9
5
  background: var(--syn-panel-background-color);
10
6
  border: solid var(--syn-panel-border-width) var(--syn-panel-border-color);
11
- border-radius: var(--syn-border-radius-medium);
12
- padding: var(--syn-spacing-x-small) 0;
7
+ border-radius: var(--syn-input-border-radius-medium);
8
+ display: block;
13
9
  overflow: auto;
14
10
  overscroll-behavior: none;
11
+ padding: var(--syn-spacing-x-small) 0;
12
+ position: relative;
15
13
  }
16
14
 
17
15
  ::slotted(syn-divider) {
16
+ /* #369: Slotted syn-dividers should use a lighter color so they do not crash with the border visually */
17
+ --color: var(--syn-panel-border-color);
18
18
  --spacing: var(--syn-spacing-x-small);
19
19
  }
20
+
21
+ /**
22
+ * Make sure to hide the syn-divider for the first syn-optgroup
23
+ * Note! ::slotted does currently not work with ::part, so we
24
+ * opted for using a css variable here.
25
+ */
26
+ ::slotted(syn-menu-label:first-of-type) {
27
+ --display-divider: none;
28
+ }
29
+
30
+ /*
31
+ * #368: Hide the checkmarks for menu items
32
+ * when no syn-menu-item[checkbox] or loading is present
33
+ */
34
+ .menu--no-checkmarks::slotted(syn-menu-item) {
35
+ --display-checkmark: none;
36
+ }
20
37
  `;
@@ -7,7 +7,6 @@ import type { SynAttributesChangedEvent } from '../../events/syn-attributes-chan
7
7
  import componentStyles from '../../styles/component.styles.js';
8
8
  import SynergyElement from '../../internal/synergy-element.js';
9
9
  import styles from './menu.styles.js';
10
- import customStyles from './menu.custom.styles.js';
11
10
  import type { CSSResultGroup } from 'lit';
12
11
  import type SynMenuItem from '../menu-item/menu-item.component.js';
13
12
 
@@ -26,7 +25,7 @@ export interface MenuSelectEventDetail {
26
25
  * @event {{ item: SynMenuItem }} syn-select - Emitted when a menu item is selected.
27
26
  */
28
27
  export default class SynMenu extends SynergyElement {
29
- static styles: CSSResultGroup = [componentStyles, styles, customStyles];
28
+ static styles: CSSResultGroup = [componentStyles, styles];
30
29
 
31
30
  @query('slot') defaultSlot: HTMLSlotElement;
32
31
  @state() hasMenuItemsWithCheckmarks = false;
@@ -1,11 +1,25 @@
1
- /* eslint-disable */
2
1
  import { css } from 'lit';
3
2
 
4
3
  export default css`
5
- /* stylelint-disable */
4
+ /* stylelint-disable no-descending-specificity */
6
5
  :host {
7
6
  --submenu-offset: -2px;
8
7
 
8
+ /* Custom override for hiding the checkmark in menus it is not needed */
9
+ --display-checkmark: flex;
10
+
11
+ /**
12
+ * Default size settings for menu-item
13
+ * This prepares the custom sizes that we will add later on
14
+ * @see https://github.com/synergy-design-system/design/issues/277
15
+ */
16
+ --menuitem-inset-border-horizontal: var(--syn-spacing-2x-small);
17
+ --menuitem-inset-border-vertical: calc(var(--syn-spacing-x-small) - 1px);
18
+ --menuitem-min-height: var(--syn-input-height-medium);
19
+ --menuitem-padding: var(--syn-input-spacing-medium);
20
+ --menuitem-font-size: var(--syn-input-font-size-medium);
21
+ --menuitem-icon-size: var(--syn-spacing-large);
22
+
9
23
  display: block;
10
24
  }
11
25
 
@@ -14,116 +28,168 @@ export default css`
14
28
  }
15
29
 
16
30
  .menu-item {
17
- position: relative;
31
+ align-items: center;
32
+
33
+ /*
34
+ * #1127: Brand2025 defines a small gap between options
35
+ * and rounded corners. We achieve that using an border
36
+ * that simulates the gap using the menu background color.
37
+ */
38
+ border: solid var(--syn-panel-background-color);
39
+
40
+ /* Border Radius needs to be increased to cover the outline */
41
+ border-radius: calc(var(--syn-focus-ring-border-radius) + var(--menuitem-inset-border-vertical));
42
+ border-width: var(--menuitem-inset-border-horizontal) var(--menuitem-inset-border-vertical);
43
+ color: var(--syn-option-color);
44
+ cursor: pointer;
18
45
  display: flex;
19
- align-items: stretch;
20
46
  font-family: var(--syn-font-sans);
21
- font-size: var(--syn-font-size-medium);
47
+ font-size: var(--menuitem-font-size);
22
48
  font-weight: var(--syn-font-weight-normal);
23
- line-height: var(--syn-line-height-normal);
24
49
  letter-spacing: var(--syn-letter-spacing-normal);
25
- color: var(--syn-color-neutral-700);
26
- padding: var(--syn-spacing-2x-small) var(--syn-spacing-2x-small);
50
+ line-height: var(--syn-line-height-normal);
51
+
52
+ /* Height is dependent on line-height of .option__label, which does not fit the layout completely */
53
+ min-height: var(--menuitem-min-height, var(--syn-input-height-medium));
54
+ padding: 0 calc(var(--menuitem-padding) - var(--menuitem-inset-border-vertical));
55
+ position: relative;
27
56
  transition: var(--syn-transition-fast) fill;
28
- user-select: none;
57
+ /* stylelint-disable-next-line property-no-vendor-prefix */
29
58
  -webkit-user-select: none;
59
+ user-select: none;
30
60
  white-space: nowrap;
31
- cursor: pointer;
32
61
  }
33
62
 
34
63
  .menu-item.menu-item--disabled {
35
- outline: none;
36
- opacity: 0.5;
37
64
  cursor: not-allowed;
65
+
66
+ /** #429: Use token for opacity */
67
+ opacity: var(--syn-opacity-50);
68
+ outline: none;
38
69
  }
39
70
 
40
71
  .menu-item.menu-item--loading {
41
- outline: none;
42
72
  cursor: wait;
73
+ outline: none;
43
74
  }
44
75
 
45
76
  .menu-item.menu-item--loading *:not(syn-spinner) {
46
- opacity: 0.5;
77
+ opacity: var(--syn-opacity-50);
47
78
  }
48
79
 
49
80
  .menu-item--loading syn-spinner {
50
81
  --indicator-color: currentColor;
51
- --track-width: 1px;
82
+ --track-width: 2px;
83
+
84
+ color: var(--syn-interactive-emphasis-color);
85
+ font-size: var(--syn-font-size-medium);
86
+ left: calc(var(--menuitem-padding) - var(--menuitem-inset-border-vertical));
87
+ opacity: 1;
52
88
  position: absolute;
53
- font-size: 0.75em;
54
89
  top: calc(50% - 0.5em);
55
- left: 0.65rem;
56
- opacity: 1;
57
90
  }
58
91
 
59
92
  .menu-item .menu-item__label {
60
- flex: 1 1 auto;
61
93
  display: inline-block;
62
- text-overflow: ellipsis;
94
+ flex: 1 1 auto;
63
95
  overflow: hidden;
96
+ text-overflow: ellipsis;
64
97
  }
65
98
 
66
99
  .menu-item .menu-item__prefix {
67
- flex: 0 0 auto;
68
- display: flex;
69
100
  align-items: center;
101
+ display: flex;
102
+ flex: 0 0 auto;
70
103
  }
71
104
 
72
105
  .menu-item .menu-item__prefix::slotted(*) {
73
- margin-inline-end: var(--syn-spacing-x-small);
106
+ margin-inline-end: var(--syn-spacing-small);
74
107
  }
75
108
 
76
109
  .menu-item .menu-item__suffix {
77
- flex: 0 0 auto;
78
- display: flex;
79
110
  align-items: center;
111
+ display: flex;
112
+ flex: 0 0 auto;
80
113
  }
81
114
 
82
115
  .menu-item .menu-item__suffix::slotted(*) {
83
- margin-inline-start: var(--syn-spacing-x-small);
116
+ margin-inline-start: var(--syn-spacing-small);
117
+ }
118
+
119
+ /**
120
+ * Set the default font size to make icons appear correct
121
+ */
122
+ .menu-item .menu-item__prefix::slotted(syn-icon),
123
+ .menu-item .menu-item__suffix::slotted(syn-icon) {
124
+ color: var(--syn-option-icon-color);
125
+ font-size: var(--syn-font-size-x-large);
126
+ }
127
+
128
+ /**
129
+ * #1194: Make sure hover is only done on non disabled items
130
+ */
131
+ :host(:hover) .menu-item:not(.menu-item--disabled) .menu-item__prefix::slotted(syn-icon),
132
+ :host(:hover) .menu-item:not(.menu-item--disabled) .menu-item__suffix::slotted(syn-icon) {
133
+ color: var(--syn-option-icon-color-hover);
134
+ }
135
+
136
+ :host(:focus-visible) .menu-item .menu-item__prefix::slotted(syn-icon),
137
+ :host(:focus-visible) .menu-item .menu-item__suffix::slotted(syn-icon) {
138
+ color: var(--syn-option-icon-color-active);
84
139
  }
85
140
 
86
141
  /* Safe triangle */
87
142
  .menu-item--submenu-expanded::after {
88
- content: '';
89
- position: fixed;
90
- z-index: calc(var(--syn-z-index-dropdown) - 1);
91
- top: 0;
92
- right: 0;
93
- bottom: 0;
94
- left: 0;
95
143
  clip-path: polygon(
96
144
  var(--safe-triangle-cursor-x, 0) var(--safe-triangle-cursor-y, 0),
97
145
  var(--safe-triangle-submenu-start-x, 0) var(--safe-triangle-submenu-start-y, 0),
98
146
  var(--safe-triangle-submenu-end-x, 0) var(--safe-triangle-submenu-end-y, 0)
99
147
  );
148
+ content: '';
149
+ inset: 0;
150
+ position: fixed;
151
+ z-index: calc(var(--syn-z-index-dropdown) - 1);
100
152
  }
101
153
 
102
154
  :host(:focus-visible) {
103
155
  outline: none;
104
156
  }
105
157
 
106
- :host(:hover:not([aria-disabled='true'], :focus-visible)) .menu-item,
158
+ :host(:hover:not([aria-disabled='true']):not(:focus-visible)) .menu-item,
107
159
  .menu-item--submenu-expanded {
108
- background-color: var(--syn-color-neutral-100);
109
- color: var(--syn-color-neutral-1000);
160
+ background-color: var(--syn-option-background-color-hover);
161
+ color: var(--syn-option-color-hover);
110
162
  }
111
163
 
112
164
  :host(:focus-visible) .menu-item {
113
- outline: none;
114
- background-color: var(--syn-color-primary-600);
165
+ background-color: var(--syn-option-background-color-active);
115
166
  color: var(--syn-color-neutral-0);
116
167
  opacity: 1;
168
+ outline: none;
117
169
  }
118
170
 
119
171
  .menu-item .menu-item__check,
120
172
  .menu-item .menu-item__chevron {
121
- flex: 0 0 auto;
122
- display: flex;
123
173
  align-items: center;
174
+ display: var(--display-checkmark);
175
+ flex: 0 0 auto;
176
+ font-size: var(--syn-font-size-x-large);
124
177
  justify-content: center;
125
- width: 1.5em;
126
178
  visibility: hidden;
179
+ width: var(--syn-font-size-x-large);
180
+ }
181
+
182
+ .menu-item .menu-item__check {
183
+ color: var(--syn-option-check-color);
184
+ margin-inline-end: var(--syn-spacing-small);
185
+ }
186
+
187
+ /**
188
+ * This makes sure the chevron does not take any space if we do not have children
189
+ */
190
+ .menu-item .menu-item__chevron {
191
+ display: none;
192
+ margin-inline-start: var(--syn-spacing-small);
127
193
  }
128
194
 
129
195
  .menu-item--checked .menu-item__check,
@@ -131,17 +197,79 @@ export default css`
131
197
  visibility: visible;
132
198
  }
133
199
 
200
+ /**
201
+ * Make sure to show the chevron if there are children
202
+ */
203
+ .menu-item--has-submenu .menu-item__chevron {
204
+ display: flex;
205
+ }
206
+
207
+ /**
208
+ * When in loading state, do not show the checkmark as it would bleed through
209
+ */
210
+ .menu-item--loading .menu-item__check {
211
+ visibility: hidden;
212
+ }
213
+
214
+ /**
215
+ * Make sure the checkbox is also visible when the item is active
216
+ */
217
+ :host(:focus-visible) .menu-item--checked .menu-item__check {
218
+ color: var(--syn-option-check-color-active);
219
+ }
220
+
221
+ :host(:hover) .menu-item--checked:not(.menu-item--disabled) .menu-item__check {
222
+ color: var(--syn-option-check-color-hover);
223
+ }
224
+
225
+ /**
226
+ * Special handling for the submenu chevron:
227
+ * We are using the "chevron-down" icon per default as
228
+ * we do not want all chevrons to be part of the bundle
229
+ * Therefore, we have to transform it into the right direction
230
+ */
231
+ .menu-item .menu-item__chevron syn-icon {
232
+ transform: rotate(-90deg);
233
+ }
234
+
235
+ .menu-item--rtl .menu-item__chevron syn-icon {
236
+ transform: rotate(90deg);
237
+ }
238
+
239
+ /**
240
+ * Highlight checked items
241
+ */
242
+ .menu-item--checked .menu-item__label {
243
+ font-weight: var(--syn-font-weight-semibold);
244
+ }
245
+
246
+ /* Needed if we do not show the checkmark */
247
+ :host(:not([type="checkmark"]):not([loading])) .menu-item__label {
248
+ min-height: var(--syn-font-size-x-large);
249
+ }
250
+
134
251
  /* Add elevation and z-index to submenus */
135
252
  syn-popup::part(popup) {
253
+ /* #1131: Make sure that slotted menus do show the correct border radius */
254
+ border-radius: var(--syn-input-border-radius-medium);
136
255
  box-shadow: var(--syn-shadow-large);
137
- z-index: var(--syn-z-index-dropdown);
138
256
  margin-left: var(--submenu-offset);
257
+ z-index: var(--syn-z-index-dropdown);
139
258
  }
140
259
 
141
260
  .menu-item--rtl syn-popup::part(popup) {
142
261
  margin-left: calc(-1 * var(--submenu-offset));
143
262
  }
144
263
 
264
+ /**
265
+ * #1009: Adjust the position for submenus when they are opened to the left, too.
266
+ * This works because the data-current-placement attribute is set on the popup accordingly.
267
+ * We do not use the actual placement attribute, because it does not update when the placement changes
268
+ */
269
+ syn-popup[data-current-placement^="left"]::part(popup) {
270
+ margin-left: calc(-1 * var(--submenu-offset));
271
+ }
272
+
145
273
  @media (forced-colors: active) {
146
274
  :host(:hover:not([aria-disabled='true'])) .menu-item,
147
275
  :host(:focus-visible) .menu-item {
@@ -151,7 +279,7 @@ export default css`
151
279
  }
152
280
 
153
281
  ::slotted(syn-menu) {
154
- max-width: var(--auto-size-available-width) !important;
155
282
  max-height: var(--auto-size-available-height) !important;
283
+ max-width: var(--auto-size-available-width) !important;
156
284
  }
157
285
  `;
@@ -12,7 +12,6 @@ import SynIcon from '../icon/icon.component.js';
12
12
  import SynPopup from '../popup/popup.component.js';
13
13
  import SynSpinner from '../spinner/spinner.component.js';
14
14
  import styles from './menu-item.styles.js';
15
- import customStyles from './menu-item.custom.styles.js';
16
15
  import { emitEventForPropertyUpdates } from '../../internal/watchEvent.js';
17
16
  import type { CSSResultGroup } from 'lit';
18
17
 
@@ -46,7 +45,7 @@ import type { CSSResultGroup } from 'lit';
46
45
  waitUntilFirstUpdated: true,
47
46
  })
48
47
  export default class SynMenuItem extends SynergyElement {
49
- static styles: CSSResultGroup = [componentStyles, styles, customStyles];
48
+ static styles: CSSResultGroup = [componentStyles, styles];
50
49
  static dependencies = {
51
50
  'syn-icon': SynIcon,
52
51
  'syn-popup': SynPopup,
@@ -1,21 +1,31 @@
1
- /* eslint-disable */
2
1
  import { css } from 'lit';
2
+
3
3
  export default css`
4
- /* stylelint-disable */
5
4
  :host {
5
+ --display-divider: block;
6
+
6
7
  display: block;
7
8
  }
8
9
 
10
+ .menu-label__divider {
11
+ --spacing: 0;
12
+
13
+ display: var(--display-divider);
14
+ margin-bottom: var(--syn-spacing-x-small);
15
+ }
16
+
9
17
  .menu-label {
18
+ color: var(--syn-input-color);
10
19
  display: inline-block;
11
20
  font-family: var(--syn-font-sans);
12
- font-size: var(--syn-font-size-small);
21
+ font-size: var(--syn-font-size-medium);
13
22
  font-weight: var(--syn-font-weight-semibold);
14
- line-height: var(--syn-line-height-normal);
15
23
  letter-spacing: var(--syn-letter-spacing-normal);
16
- color: var(--syn-color-neutral-500);
17
- padding: var(--syn-spacing-2x-small) var(--syn-spacing-x-large);
18
- user-select: none;
24
+ line-height: var(--syn-line-height-normal);
25
+ padding: var(--syn-spacing-small) var(--syn-spacing-medium);
26
+
27
+ /* stylelint-disable-next-line property-no-vendor-prefix */
19
28
  -webkit-user-select: none;
29
+ user-select: none;
20
30
  }
21
31
  `;
@@ -4,7 +4,6 @@ import SynDivider from '../divider/divider.component.js';
4
4
  import componentStyles from '../../styles/component.styles.js';
5
5
  import SynergyElement from '../../internal/synergy-element.js';
6
6
  import styles from './menu-label.styles.js';
7
- import customStyles from './menu-label.custom.styles.js';
8
7
  import type { CSSResultGroup } from 'lit';
9
8
 
10
9
  /**
@@ -24,7 +23,7 @@ import type { CSSResultGroup } from 'lit';
24
23
  * @cssproperty --display-divider - Display property of the divider. Defaults to "block"
25
24
  */
26
25
  export default class SynMenuLabel extends SynergyElement {
27
- static styles: CSSResultGroup = [componentStyles, styles, customStyles];
26
+ static styles: CSSResultGroup = [componentStyles, styles];
28
27
 
29
28
  static dependencies = {
30
29
  'syn-divider': SynDivider,
@@ -283,6 +283,16 @@ export default class SynValidate extends SynergyElement {
283
283
  });
284
284
  }
285
285
 
286
+ /**
287
+ * #851: Get the validation message that should be displayed to the user.
288
+ * Prioritizes customValidationMessage over the internal validationMessage state.
289
+ * This is needed because frameworks may clear the internal validation message on
290
+ * dynamically rendered elements, but the customValidationMessage is still valid.
291
+ */
292
+ private getDisplayValidationMessage(): string {
293
+ return this.customValidationMessage || this.validationMessage;
294
+ }
295
+
286
296
  private setValidationMessage(input: HTMLInputElement) {
287
297
  const { customValidationMessage } = this;
288
298
  const validationMessage = customValidationMessage || input.validationMessage;
@@ -514,10 +524,11 @@ export default class SynValidate extends SynergyElement {
514
524
  // we need to update the content and show or hide it based on the validation state and focus state.
515
525
  // We have to do this manually, as there is a problem when updating open and content at the same time.
516
526
  // The order is critical: fill before showing, don´t update the content during hide.
517
- const shouldShowTooltip = !this.isValid && this.validationMessage && this.hasFocus;
527
+ const displayMessage = this.getDisplayValidationMessage();
528
+ const shouldShowTooltip = !this.isValid && displayMessage && this.hasFocus;
518
529
 
519
530
  if (shouldShowTooltip) {
520
- tooltip.content = this.validationMessage;
531
+ tooltip.content = displayMessage;
521
532
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
522
533
  tooltip.show();
523
534
  } else {
@@ -527,7 +538,9 @@ export default class SynValidate extends SynergyElement {
527
538
  }
528
539
 
529
540
  private renderInlineValidation() {
530
- if (this.variant !== 'inline' || !this.validationMessage) {
541
+ const messageToShow = this.getDisplayValidationMessage();
542
+
543
+ if (this.variant !== 'inline' || !messageToShow) {
531
544
  return '';
532
545
  }
533
546
 
@@ -543,7 +556,7 @@ export default class SynValidate extends SynergyElement {
543
556
  ? html`<syn-icon slot="icon" name="status-error" library="system"></syn-icon>`
544
557
  : ''
545
558
  }
546
- ${this.validationMessage}
559
+ ${messageToShow}
547
560
  </syn-alert>
548
561
  `;
549
562
  }
@@ -555,7 +568,7 @@ export default class SynValidate extends SynergyElement {
555
568
  <syn-tooltip
556
569
  .anchor=${getActualInputElement(this.getInput()) as Element ?? undefined}
557
570
  exportparts="base:tooltip__base,base__popup:tooltip__popup,base__arrow:tooltip__arrow,body:tooltip__body"
558
- .open=${this.eager ? !this.isValid && this.validationMessage.length > 0 : false}
571
+ .open=${this.eager ? !this.isValid && this.getDisplayValidationMessage().length > 0 : false}
559
572
  part="tooltip"
560
573
  placement="bottom"
561
574
  trigger="manual"
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1214](https://github.com/synergy-design-system/synergy-design-system/pull/1214) [`01c5e9c`](https://github.com/synergy-design-system/synergy-design-system/commit/01c5e9cc231c6bcc260cedc2f5d5713cf71ea254) Thanks [@schilchSICKAG](https://github.com/schilchSICKAG)! - Released on: 2026-03-06
8
+
9
+ fix: 🐛 Angular: `<syn-validate>` does not work when dynamically added to the DOM (#851)
10
+
11
+ This release fixes an issue that made `<syn-validate>` ignore its set `customValidationMessage` when the component gets dynamically added to the DOM in Angular. It does so by preferring the provided `customValidationMessage` over of the internally available `validationMessage`, which could be empty under certain conditions.
12
+
13
+ - Updated dependencies []:
14
+ - @synergy-design-system/tokens@3.6.2
15
+
16
+ ## 3.6.1
17
+
18
+ ### Patch Changes
19
+
20
+ - [#1208](https://github.com/synergy-design-system/synergy-design-system/pull/1208) [`49c9d1c`](https://github.com/synergy-design-system/synergy-design-system/commit/49c9d1c30d777384024134ec983d183aed109421) Thanks [@schilchSICKAG](https://github.com/schilchSICKAG)! - Released on: 2026-03-03
21
+
22
+ fix: 🐛 `<syn-menu-item>`: Slotted `<syn-icon>` elements not visible on hover (#1194)
23
+
24
+ This release fixes a bug that accidentally set the color of slotted elements in `<syn-menu-item>` to white which lead to the icons appear to be invisible.
25
+
26
+ - Updated dependencies []:
27
+ - @synergy-design-system/tokens@3.6.1
28
+
3
29
  ## 3.6.0
4
30
 
5
31
  ### Minor Changes
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.6.2
4
+
5
+ ## 3.6.1
6
+
3
7
  ## 3.6.0
4
8
 
5
9
  ### Minor Changes
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  * Do not edit directly, this file was auto-generated.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  * Do not edit directly, this file was auto-generated.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  * Do not edit directly, this file was auto-generated.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  * Do not edit directly, this file was auto-generated.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  * Do not edit directly, this file was auto-generated.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @synergy-design-system/tokens version 3.5.0
2
+ * @synergy-design-system/tokens version 3.6.1
3
3
  * SICK Global UX Foundation
4
4
  * Do not edit directly, this file was auto-generated.
5
5
  */
package/package.json CHANGED
@@ -28,12 +28,12 @@
28
28
  "serve-handler": "^6.1.6",
29
29
  "ts-jest": "^29.4.6",
30
30
  "typescript": "^5.9.3",
31
- "@synergy-design-system/components": "3.6.0",
31
+ "@synergy-design-system/components": "3.6.2",
32
32
  "@synergy-design-system/docs": "0.1.0",
33
33
  "@synergy-design-system/fonts": "1.0.3",
34
- "@synergy-design-system/tokens": "^3.6.0",
35
34
  "@synergy-design-system/eslint-config-syn": "^0.1.0",
36
- "@synergy-design-system/styles": "2.0.1"
35
+ "@synergy-design-system/styles": "2.0.1",
36
+ "@synergy-design-system/tokens": "^3.6.2"
37
37
  },
38
38
  "exports": {
39
39
  ".": {
@@ -67,7 +67,7 @@
67
67
  "directory": "packages/mcp"
68
68
  },
69
69
  "type": "module",
70
- "version": "2.8.0",
70
+ "version": "2.8.2",
71
71
  "scripts": {
72
72
  "build": "pnpm run build:ts && pnpm run build:metadata && pnpm build:hash",
73
73
  "build:all": "pnpm run build && pnpm run build:storybook",
@@ -1,5 +0,0 @@
1
- import { css } from 'lit';
2
-
3
- export default css`
4
- /* Write custom CSS here */
5
- `;
@@ -1,29 +0,0 @@
1
- import { css } from 'lit';
2
-
3
- export default css`
4
- :host {
5
- border-radius: var(--syn-input-border-radius-medium);
6
- }
7
-
8
- /*
9
- * #368: Hide the checkmarks for menu items
10
- * when no syn-menu-item[checkbox] or loading is present
11
- */
12
- .menu--no-checkmarks::slotted(syn-menu-item) {
13
- --display-checkmark: none;
14
- }
15
-
16
- /**
17
- * Make sure to hide the syn-divider for the first syn-optgroup
18
- * Note! ::slotted does currently not work with ::part, so we
19
- * opted for using a css variable here.
20
- */
21
- ::slotted(syn-menu-label:first-of-type) {
22
- --display-divider: none;
23
- }
24
-
25
- ::slotted(syn-divider) {
26
- /* #369: Slotted syn-dividers should use a lighter color so they do not crash with the border visually */
27
- --color: var(--syn-panel-border-color);
28
- }
29
- `;
@@ -1,192 +0,0 @@
1
- import { css } from 'lit';
2
-
3
- export default css`
4
- :host {
5
- /* Custom override for hiding the checkmark in menus it is not needed */
6
- --display-checkmark: flex;
7
-
8
- /**
9
- * Default size settings for menu-item
10
- * This prepares the custom sizes that we will add later on
11
- * @see https://github.com/synergy-design-system/design/issues/277
12
- */
13
- --menuitem-inset-border-horizontal: var(--syn-spacing-2x-small);
14
- --menuitem-inset-border-vertical: calc(var(--syn-spacing-x-small) - 1px);
15
- --menuitem-min-height: var(--syn-input-height-medium);
16
- --menuitem-padding: var(--syn-input-spacing-medium);
17
- --menuitem-font-size: var(--syn-input-font-size-medium);
18
- --menuitem-icon-size: var(--syn-spacing-large);
19
- }
20
-
21
- .menu-item {
22
- align-items: center;
23
-
24
- /*
25
- * #1127: Brand2025 defines a small gap between options
26
- * and rounded corners. We achieve that using an border
27
- * that simulates the gap using the menu background color.
28
- */
29
- border: solid var(--syn-panel-background-color);
30
-
31
- /* Border Radius needs to be increased to cover the outline */
32
- border-radius: calc(var(--syn-focus-ring-border-radius) + var(--menuitem-inset-border-vertical));
33
- border-width: var(--menuitem-inset-border-horizontal) var(--menuitem-inset-border-vertical);
34
- color: var(--syn-option-color);
35
- font-size: var(--menuitem-font-size);
36
-
37
- /* Height is dependent on line-height of .option__label, which does not fit completely to layout */
38
- min-height: var(--menuitem-min-height, var(--syn-input-height-medium));
39
- padding: 0 calc(var(--menuitem-padding) - var(--menuitem-inset-border-vertical));
40
- }
41
-
42
- :host(:focus-visible) .menu-item {
43
- background-color: var(--syn-option-background-color-active);
44
- }
45
-
46
- /** #429: Use token for opacity */
47
- .menu-item.menu-item--disabled {
48
- opacity: var(--syn-opacity-50);
49
- }
50
-
51
- /**
52
- * Handling for slotted prefix and suffix
53
- */
54
- .menu-item .menu-item__prefix::slotted(*) {
55
- margin-inline-end: var(--syn-spacing-small);
56
- }
57
-
58
- .menu-item .menu-item__suffix::slotted(*) {
59
- margin-inline-start: var(--syn-spacing-small);
60
- }
61
-
62
- /**
63
- * Set the default font size to make icons appear correct
64
- */
65
- .menu-item .menu-item__prefix::slotted(syn-icon),
66
- .menu-item .menu-item__suffix::slotted(syn-icon) {
67
- color: var(--syn-option-icon-color);
68
- font-size: var(--syn-font-size-x-large);
69
- }
70
-
71
- :host(:hover) .menu-item .menu-item__prefix::slotted(syn-icon),
72
- :host(:hover) .menu-item__suffix::slotted(syn-icon) {
73
- color: var(--syn-option-icon-color-hover);
74
- }
75
-
76
- :host(:focus-visible) .menu-item .menu-item__prefix::slotted(syn-icon),
77
- :host(:focus-visible) .menu-item .menu-item__suffix::slotted(syn-icon) {
78
- color: var(--syn-option-icon-color-active);
79
- }
80
-
81
- /* Adjust background and text color for focused elements */
82
- /* stylelint-disable selector-not-notation, plugin/no-unsupported-browser-features */
83
- :host(:hover:not([aria-disabled='true'], :focus-visible)) .menu-item,
84
- .menu-item--submenu-expanded {
85
- background-color: var(--syn-option-background-color-hover);
86
- color: var(--syn-option-color-hover);
87
- }
88
- /* stylelint-enable selector-not-notation, plugin/no-unsupported-browser-features */
89
-
90
- /**
91
- * Adjust the size of icons
92
- */
93
- .menu-item .menu-item__chevron,
94
- .menu-item .menu-item__check {
95
- display: var(--display-checkmark);
96
- font-size: var(--syn-font-size-x-large);
97
- width: var(--syn-font-size-x-large);
98
- }
99
-
100
- /**
101
- * This makes sure the chevron does not take any space if we do not have children
102
- */
103
- .menu-item .menu-item__chevron {
104
- display: none;
105
- margin-inline-start: var(--syn-spacing-small);
106
- }
107
-
108
- .menu-item .menu-item__check {
109
- color: var(--syn-option-check-color);
110
- margin-inline-end: var(--syn-spacing-small);
111
- }
112
-
113
- /**
114
- * When in loading state, do not show the checkmark as it would bleed through
115
- */
116
- .menu-item--loading .menu-item__check {
117
- visibility: hidden;
118
- }
119
-
120
- /**
121
- * Make sure the checkbox is also visible when the item is active
122
- */
123
- :host(:focus-visible) .menu-item--checked .menu-item__check {
124
- color: var(--syn-option-check-color-active);
125
- }
126
-
127
- :host(:hover) .menu-item--checked .menu-item__check {
128
- color: var(--syn-option-check-color-hover);
129
- }
130
-
131
- /**
132
- * Special handling for the submenu chevron:
133
- * We are using the "chevron-down" icon per default as
134
- * we do not want all chevrons to be part of the bundle
135
- * Therefore, we have to transform it into the right direction
136
- */
137
- .menu-item .menu-item__chevron syn-icon {
138
- transform: rotate(-90deg);
139
- }
140
-
141
- .menu-item--rtl .menu-item__chevron syn-icon {
142
- transform: rotate(90deg);
143
- }
144
-
145
- .menu-item.menu-item--loading *:not(syn-spinner) {
146
- opacity: var(--syn-opacity-50);
147
- }
148
-
149
- /**
150
- * Make sure to show the chevron if there are children
151
- */
152
- .menu-item--has-submenu .menu-item__chevron {
153
- display: flex;
154
- }
155
-
156
- /**
157
- * Adjustments for the spinner in loading state
158
- */
159
- .menu-item--loading syn-spinner {
160
- --track-width: 2px;
161
-
162
- color: var(--syn-interactive-emphasis-color);
163
- font-size: var(--syn-font-size-medium);
164
- left: calc(var(--menuitem-padding) - var(--menuitem-inset-border-vertical));
165
- }
166
-
167
- /**
168
- * Highlight checked items
169
- */
170
- .menu-item--checked .menu-item__label {
171
- font-weight: var(--syn-font-weight-semibold);
172
- }
173
-
174
- /* Needed if we do not show the checkmark */
175
- :host(:not([type="checkmark"]):not([loading])) .menu-item__label {
176
- min-height: var(--syn-font-size-x-large);
177
- }
178
-
179
- /* #1131: Make sure that slotted menus do show the correct border radius */
180
- syn-popup::part(popup) {
181
- border-radius: var(--syn-input-border-radius-medium);
182
- }
183
-
184
- /**
185
- * #1009: Adjust the position for submenus when they are opened to the left, too.
186
- * This works because the data-current-placement attribute is set on the popup accordingly.
187
- * We do not use the actual placement attribute, because it does not update when the placement changes
188
- */
189
- syn-popup[data-current-placement^="left"]::part(popup) {
190
- margin-left: calc(-1 * var(--submenu-offset));
191
- }
192
- `;
@@ -1,24 +0,0 @@
1
- import { css } from 'lit';
2
-
3
- export default css`
4
- :host {
5
- --display-divider: block;
6
- }
7
-
8
- .menu-label__divider {
9
- --spacing: 0;
10
-
11
- display: var(--display-divider);
12
- margin-bottom: var(--syn-spacing-x-small);
13
- }
14
-
15
- .menu-label {
16
- color: var(--syn-input-color);
17
- font-family: var(--syn-font-sans);
18
- font-size: var(--syn-font-size-medium);
19
- font-weight: var(--syn-font-weight-semibold);
20
- letter-spacing: var(--syn-letter-spacing-normal);
21
- line-height: var(--syn-line-height-normal);
22
- padding: var(--syn-spacing-small) var(--syn-spacing-medium);
23
- }
24
- `;