@synergy-design-system/metadata 3.9.0 → 3.11.0
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/CHANGELOG.md +21 -0
- package/data/core/setup/setup:angular-components-module.json +1 -1
- package/data/core/setup/setup:angular-forms-module.json +1 -1
- package/data/core/setup/setup:angular-package.json +2 -2
- package/data/core/setup/setup:angular-validators-module.json +1 -1
- package/data/core/setup/setup:components-package.json +2 -2
- package/data/core/setup/setup:react-package.json +2 -2
- package/data/core/setup/setup:tokens-package.json +2 -2
- package/data/core/setup/setup:vue-package.json +2 -2
- package/data/core/token/token:tokens-charts-js-index-d-ts.json +1 -1
- package/data/core/token/token:tokens-charts-js-index-js.json +1 -1
- package/data/core/token/token:tokens-charts-scss-tokens-scss.json +1 -1
- package/data/core/token/token:tokens-charts-themes-sick2025-dark-css.json +1 -1
- package/data/core/token/token:tokens-charts-themes-sick2025-light-css.json +1 -1
- package/data/core/token/token:tokens-figma-variables-sick2018-dark-json.json +1 -1
- package/data/core/token/token:tokens-figma-variables-sick2018-light-json.json +1 -1
- package/data/core/token/token:tokens-figma-variables-sick2025-dark-json.json +1 -1
- package/data/core/token/token:tokens-figma-variables-sick2025-light-json.json +1 -1
- package/data/core/token/token:tokens-js-index-d-ts.json +1 -1
- package/data/core/token/token:tokens-js-index-js.json +1 -1
- package/data/core/token/token:tokens-scss-tokens-scss.json +1 -1
- package/data/core/token/token:tokens-themes-sick2018-dark-css.json +1 -1
- package/data/core/token/token:tokens-themes-sick2018-light-css.json +1 -1
- package/data/core/token/token:tokens-themes-sick2025-dark-css.json +1 -1
- package/data/core/token/token:tokens-themes-sick2025-light-css.json +1 -1
- package/data/index.json +1 -1
- package/data/layers/full/component/component:syn-menu/components/menu.component.ts +62 -25
- package/data/layers/full/component/component:syn-menu/components/menu.styles.ts +0 -8
- package/data/layers/full/component/component:syn-menu-item/components/menu-item.component.ts +0 -7
- package/data/layers/full/component/component:syn-menu-item/components/submenu-controller.ts +94 -0
- package/data/layers/full/setup/setup:angular-package/angular/CHANGELOG.md +8 -0
- package/data/layers/full/setup/setup:angular-package/angular/package.json +1 -1
- package/data/layers/full/setup/setup:components-package/components/CHANGELOG.md +16 -0
- package/data/layers/full/setup/setup:components-package/components/package.json +1 -1
- package/data/layers/full/setup/setup:react-package/react/CHANGELOG.md +8 -0
- package/data/layers/full/setup/setup:react-package/react/package.json +1 -1
- package/data/layers/full/setup/setup:tokens-package/tokens/CHANGELOG.md +2 -0
- package/data/layers/full/setup/setup:tokens-package/tokens/package.json +1 -1
- package/data/layers/full/setup/setup:vue-package/vue/CHANGELOG.md +8 -0
- package/data/layers/full/setup/setup:vue-package/vue/package.json +1 -1
- package/data/layers/full/tokens/charts/js/index.d.ts +1 -1
- package/data/layers/full/tokens/charts/js/index.js +1 -1
- package/data/layers/full/tokens/charts/scss/_tokens.scss +1 -1
- package/data/layers/full/tokens/charts/themes/sick2025_dark.css +1 -1
- package/data/layers/full/tokens/charts/themes/sick2025_light.css +1 -1
- package/data/layers/full/tokens/js/index.d.ts +1 -1
- package/data/layers/full/tokens/js/index.js +1 -1
- package/data/layers/full/tokens/scss/_tokens.scss +1 -1
- package/data/layers/full/tokens/themes/sick2018_dark.css +1 -1
- package/data/layers/full/tokens/themes/sick2018_light.css +1 -1
- package/data/layers/full/tokens/themes/sick2025_dark.css +1 -1
- package/data/layers/full/tokens/themes/sick2025_light.css +1 -1
- package/data/manifest.json +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.11.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1296](https://github.com/synergy-design-system/synergy-design-system/pull/1296) [`4fdb69a`](https://github.com/synergy-design-system/synergy-design-system/commit/4fdb69aec5ddb0ddfa76a948c87eaf84be6fd670) Thanks [@schilchSICKAG](https://github.com/schilchSICKAG)! - Released on: 2026-06-03
|
|
8
|
+
|
|
9
|
+
fix: 🐛 `<syn-menu>` multiple issues ([#1295](https://github.com/synergy-design-system/synergy-design-system/issues/1295))
|
|
10
|
+
|
|
11
|
+
This release fixes multiple issues when using `<syn-menu>`:
|
|
12
|
+
- submenus no longer stay open when leaving the browser window ([#882](https://github.com/synergy-design-system/synergy-design-system/issues/882))
|
|
13
|
+
- `<syn-menu-item>` wrapped in tooltip can now be used reliably (including navigation and selection) ([#1162](https://github.com/synergy-design-system/synergy-design-system/issues/1162))
|
|
14
|
+
- `<syn-menu-item>` no longer steals focus on hover ([#1286](https://github.com/synergy-design-system/synergy-design-system/issues/1286))
|
|
15
|
+
|
|
16
|
+
## 3.10.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- Released on: 2026-06-02
|
|
21
|
+
|
|
22
|
+
chore: ✨ Update Metadata and MCP with latest metadata
|
|
23
|
+
|
|
3
24
|
## 3.9.0
|
|
4
25
|
|
|
5
26
|
### Minor Changes
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"custom": {
|
|
3
3
|
"framework": "angular",
|
|
4
4
|
"packageName": "@synergy-design-system/angular",
|
|
5
|
-
"packageVersion": "3.15.
|
|
5
|
+
"packageVersion": "3.15.1",
|
|
6
6
|
"subpathExports": [
|
|
7
7
|
".",
|
|
8
8
|
"./components/*",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"name": "Angular Framework Package",
|
|
40
40
|
"package": "angular",
|
|
41
41
|
"relations": [],
|
|
42
|
-
"since": "3.15.
|
|
42
|
+
"since": "3.15.1",
|
|
43
43
|
"sources": [
|
|
44
44
|
"packages/angular/README.md",
|
|
45
45
|
"packages/angular/CHANGELOG.md",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"custom": {
|
|
3
3
|
"packageName": "@synergy-design-system/components",
|
|
4
|
-
"packageVersion": "3.15.
|
|
4
|
+
"packageVersion": "3.15.1"
|
|
5
5
|
},
|
|
6
6
|
"id": "setup:components-package",
|
|
7
7
|
"kind": "setup",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"name": "Components Package",
|
|
41
41
|
"package": "components",
|
|
42
42
|
"relations": [],
|
|
43
|
-
"since": "3.15.
|
|
43
|
+
"since": "3.15.1",
|
|
44
44
|
"sources": [
|
|
45
45
|
"packages/components/README.md",
|
|
46
46
|
"packages/components/CHANGELOG.md",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"custom": {
|
|
3
3
|
"framework": "react",
|
|
4
4
|
"packageName": "@synergy-design-system/react",
|
|
5
|
-
"packageVersion": "3.15.
|
|
5
|
+
"packageVersion": "3.15.1",
|
|
6
6
|
"subpathExports": [
|
|
7
7
|
".",
|
|
8
8
|
"./components/*",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"name": "React Framework Package",
|
|
43
43
|
"package": "react",
|
|
44
44
|
"relations": [],
|
|
45
|
-
"since": "3.15.
|
|
45
|
+
"since": "3.15.1",
|
|
46
46
|
"sources": [
|
|
47
47
|
"packages/react/README.md",
|
|
48
48
|
"packages/react/CHANGELOG.md",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"./themes/*"
|
|
33
33
|
],
|
|
34
34
|
"packageName": "@synergy-design-system/tokens",
|
|
35
|
-
"packageVersion": "3.15.
|
|
35
|
+
"packageVersion": "3.15.1"
|
|
36
36
|
},
|
|
37
37
|
"id": "setup:tokens-package",
|
|
38
38
|
"kind": "setup",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"name": "Tokens Package",
|
|
60
60
|
"package": "tokens",
|
|
61
61
|
"relations": [],
|
|
62
|
-
"since": "3.15.
|
|
62
|
+
"since": "3.15.1",
|
|
63
63
|
"sources": [
|
|
64
64
|
"packages/tokens/BREAKING_CHANGES.md",
|
|
65
65
|
"packages/tokens/CHANGELOG.md",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"custom": {
|
|
3
3
|
"framework": "vue",
|
|
4
4
|
"packageName": "@synergy-design-system/vue",
|
|
5
|
-
"packageVersion": "3.15.
|
|
5
|
+
"packageVersion": "3.15.1"
|
|
6
6
|
},
|
|
7
7
|
"id": "setup:vue-package",
|
|
8
8
|
"kind": "setup",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"name": "Vue Framework Package",
|
|
34
34
|
"package": "vue",
|
|
35
35
|
"relations": [],
|
|
36
|
-
"since": "3.15.
|
|
36
|
+
"since": "3.15.1",
|
|
37
37
|
"sources": [
|
|
38
38
|
"packages/vue/README.md",
|
|
39
39
|
"packages/vue/CHANGELOG.md",
|
package/data/index.json
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { html } from 'lit';
|
|
3
3
|
import { query } from 'lit/decorators.js';
|
|
4
4
|
import { state } from 'lit/decorators.js';
|
|
5
|
-
import { classMap } from 'lit/directives/class-map.js';
|
|
6
5
|
import type { SynAttributesChangedEvent } from '../../events/syn-attributes-changed.js';
|
|
7
6
|
import componentStyles from '../../styles/component.styles.js';
|
|
8
7
|
import SynergyElement from '../../internal/synergy-element.js';
|
|
@@ -29,11 +28,35 @@ export default class SynMenu extends SynergyElement {
|
|
|
29
28
|
|
|
30
29
|
@query('slot') defaultSlot: HTMLSlotElement;
|
|
31
30
|
@state() hasMenuItemsWithCheckmarks = false;
|
|
31
|
+
private checkmarkStyledItems = new Set<SynMenuItem>();
|
|
32
32
|
|
|
33
33
|
private handleUpdateCheckmarks(items: SynMenuItem[]) {
|
|
34
34
|
// #368: Treat a menu as having checkmarks if it has any checkboxes or items with loading states
|
|
35
35
|
// The loading indicator has to be checked as well, as it's specially placed over the check mark
|
|
36
|
-
this.hasMenuItemsWithCheckmarks = items.some(item => item.type === 'checkbox' || item.loading);
|
|
36
|
+
this.hasMenuItemsWithCheckmarks = items.some(item => item.type === 'checkbox' || item.loading);
|
|
37
|
+
this.syncCheckmarkVisibility(items);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private syncCheckmarkVisibility(items: SynMenuItem[]) {
|
|
41
|
+
this.checkmarkStyledItems.forEach(item => {
|
|
42
|
+
if (!items.includes(item)) {
|
|
43
|
+
item.style.removeProperty('--display-checkmark');
|
|
44
|
+
this.checkmarkStyledItems.delete(item);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (this.hasMenuItemsWithCheckmarks) {
|
|
49
|
+
items.forEach(item => {
|
|
50
|
+
item.style.removeProperty('--display-checkmark');
|
|
51
|
+
this.checkmarkStyledItems.delete(item);
|
|
52
|
+
});
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
items.forEach(item => {
|
|
57
|
+
item.style.setProperty('--display-checkmark', 'none');
|
|
58
|
+
this.checkmarkStyledItems.add(item);
|
|
59
|
+
});
|
|
37
60
|
}
|
|
38
61
|
|
|
39
62
|
private updateCheckMarksByChildPropChange = (e: SynAttributesChangedEvent) => {
|
|
@@ -43,6 +66,8 @@ export default class SynMenu extends SynergyElement {
|
|
|
43
66
|
|
|
44
67
|
disconnectedCallback() {
|
|
45
68
|
this.removeEventListener('syn-attributes-changed', this.updateCheckMarksByChildPropChange);
|
|
69
|
+
this.checkmarkStyledItems.forEach(item => item.style.removeProperty('--display-checkmark'));
|
|
70
|
+
this.checkmarkStyledItems.clear();
|
|
46
71
|
}
|
|
47
72
|
|
|
48
73
|
connectedCallback() {
|
|
@@ -51,22 +76,26 @@ export default class SynMenu extends SynergyElement {
|
|
|
51
76
|
this.addEventListener('syn-attributes-changed', this.updateCheckMarksByChildPropChange);
|
|
52
77
|
}
|
|
53
78
|
|
|
54
|
-
private
|
|
55
|
-
const menuItemTypes = ['menuitem', 'menuitemcheckbox'];
|
|
56
|
-
|
|
79
|
+
private getMenuItemFromEvent(event: Event) {
|
|
57
80
|
const composedPath = event.composedPath();
|
|
58
|
-
const target = composedPath.find((el:
|
|
81
|
+
const target = composedPath.find((el: EventTarget) => el instanceof HTMLElement && this.isMenuItem(el));
|
|
82
|
+
|
|
83
|
+
if (!target || !(target instanceof HTMLElement)) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
59
86
|
|
|
60
|
-
|
|
87
|
+
const closestMenu = composedPath.find((el: EventTarget) => el instanceof Element && el.getAttribute('role') === 'menu');
|
|
88
|
+
if (closestMenu !== this) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
61
91
|
|
|
62
|
-
|
|
63
|
-
|
|
92
|
+
return target as SynMenuItem;
|
|
93
|
+
}
|
|
64
94
|
|
|
65
|
-
|
|
66
|
-
|
|
95
|
+
private handleClick(event: MouseEvent) {
|
|
96
|
+
const item = this.getMenuItemFromEvent(event);
|
|
67
97
|
|
|
68
|
-
|
|
69
|
-
const item = target as SynMenuItem;
|
|
98
|
+
if (!item) return;
|
|
70
99
|
|
|
71
100
|
if (item.type === 'checkbox') {
|
|
72
101
|
item.checked = !item.checked;
|
|
@@ -120,10 +149,10 @@ export default class SynMenu extends SynergyElement {
|
|
|
120
149
|
}
|
|
121
150
|
|
|
122
151
|
private handleMouseDown(event: MouseEvent) {
|
|
123
|
-
const target = event
|
|
152
|
+
const target = this.getMenuItemFromEvent(event);
|
|
124
153
|
|
|
125
|
-
if (
|
|
126
|
-
this.setCurrentItem(target
|
|
154
|
+
if (target) {
|
|
155
|
+
this.setCurrentItem(target);
|
|
127
156
|
}
|
|
128
157
|
}
|
|
129
158
|
|
|
@@ -144,14 +173,25 @@ export default class SynMenu extends SynergyElement {
|
|
|
144
173
|
);
|
|
145
174
|
}
|
|
146
175
|
|
|
176
|
+
private getMenuItemsFromElement(element: HTMLElement): SynMenuItem[] {
|
|
177
|
+
if (element.inert) {
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (this.isMenuItem(element)) {
|
|
182
|
+
return [element as SynMenuItem];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (element.tagName.toLowerCase() === 'syn-menu') {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return [...element.children].flatMap(child => this.getMenuItemsFromElement(child as HTMLElement));
|
|
190
|
+
}
|
|
191
|
+
|
|
147
192
|
/** @internal Gets all slotted menu items, ignoring dividers, headers, and other elements. */
|
|
148
193
|
getAllItems() {
|
|
149
|
-
return [...this.defaultSlot.assignedElements({ flatten: true })].
|
|
150
|
-
if (el.inert || !this.isMenuItem(el)) {
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
return true;
|
|
154
|
-
}) as SynMenuItem[];
|
|
194
|
+
return [...this.defaultSlot.assignedElements({ flatten: true })].flatMap(el => this.getMenuItemsFromElement(el as HTMLElement));
|
|
155
195
|
}
|
|
156
196
|
|
|
157
197
|
/**
|
|
@@ -178,9 +218,6 @@ export default class SynMenu extends SynergyElement {
|
|
|
178
218
|
render() {
|
|
179
219
|
return html`
|
|
180
220
|
<slot
|
|
181
|
-
class=${classMap({
|
|
182
|
-
'menu--no-checkmarks': !this.hasMenuItemsWithCheckmarks,
|
|
183
|
-
})}
|
|
184
221
|
@slotchange=${this.handleSlotChange}
|
|
185
222
|
@click=${this.handleClick}
|
|
186
223
|
@keydown=${this.handleKeyDown}
|
|
@@ -26,12 +26,4 @@ export default css`
|
|
|
26
26
|
::slotted(syn-menu-label:first-of-type) {
|
|
27
27
|
--display-divider: none;
|
|
28
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
|
-
}
|
|
37
29
|
`;
|
package/data/layers/full/component/component:syn-menu-item/components/menu-item.component.ts
CHANGED
|
@@ -79,13 +79,11 @@ export default class SynMenuItem extends SynergyElement {
|
|
|
79
79
|
connectedCallback() {
|
|
80
80
|
super.connectedCallback();
|
|
81
81
|
this.addEventListener('click', this.handleHostClick);
|
|
82
|
-
this.addEventListener('mouseover', this.handleMouseOver);
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
disconnectedCallback() {
|
|
86
85
|
super.disconnectedCallback();
|
|
87
86
|
this.removeEventListener('click', this.handleHostClick);
|
|
88
|
-
this.removeEventListener('mouseover', this.handleMouseOver);
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
private handleDefaultSlotChange() {
|
|
@@ -112,11 +110,6 @@ export default class SynMenuItem extends SynergyElement {
|
|
|
112
110
|
}
|
|
113
111
|
};
|
|
114
112
|
|
|
115
|
-
private handleMouseOver = (event: MouseEvent) => {
|
|
116
|
-
this.focus();
|
|
117
|
-
event.stopPropagation();
|
|
118
|
-
};
|
|
119
|
-
|
|
120
113
|
@watch('checked')
|
|
121
114
|
handleCheckedChange() {
|
|
122
115
|
// For proper accessibility, users have to use type="checkbox" to use the checked attribute
|
|
@@ -11,6 +11,7 @@ export class SubmenuController implements ReactiveController {
|
|
|
11
11
|
private host: ReactiveControllerHost & SynMenuItem;
|
|
12
12
|
private popupRef: Ref<SynPopup> = createRef();
|
|
13
13
|
private enableSubmenuTimer = -1;
|
|
14
|
+
private hasGlobalDismissListeners = false;
|
|
14
15
|
private isConnected = false;
|
|
15
16
|
private isPopupConnected = false;
|
|
16
17
|
private skidding = 0;
|
|
@@ -45,6 +46,7 @@ export class SubmenuController implements ReactiveController {
|
|
|
45
46
|
if (!this.isConnected) {
|
|
46
47
|
this.host.addEventListener('mousemove', this.handleMouseMove);
|
|
47
48
|
this.host.addEventListener('mouseover', this.handleMouseOver);
|
|
49
|
+
this.host.addEventListener('mouseleave', this.handleHostMouseLeave);
|
|
48
50
|
this.host.addEventListener('keydown', this.handleKeyDown);
|
|
49
51
|
this.host.addEventListener('click', this.handleClick);
|
|
50
52
|
this.host.addEventListener('focusout', this.handleFocusOut);
|
|
@@ -56,6 +58,7 @@ export class SubmenuController implements ReactiveController {
|
|
|
56
58
|
if (!this.isPopupConnected) {
|
|
57
59
|
if (this.popupRef.value) {
|
|
58
60
|
this.popupRef.value.addEventListener('mouseover', this.handlePopupMouseover);
|
|
61
|
+
this.popupRef.value.addEventListener('mouseleave', this.handlePopupMouseLeave);
|
|
59
62
|
this.popupRef.value.addEventListener('syn-reposition', this.handlePopupReposition);
|
|
60
63
|
this.isPopupConnected = true;
|
|
61
64
|
}
|
|
@@ -66,6 +69,7 @@ export class SubmenuController implements ReactiveController {
|
|
|
66
69
|
if (this.isConnected) {
|
|
67
70
|
this.host.removeEventListener('mousemove', this.handleMouseMove);
|
|
68
71
|
this.host.removeEventListener('mouseover', this.handleMouseOver);
|
|
72
|
+
this.host.removeEventListener('mouseleave', this.handleHostMouseLeave);
|
|
69
73
|
this.host.removeEventListener('keydown', this.handleKeyDown);
|
|
70
74
|
this.host.removeEventListener('click', this.handleClick);
|
|
71
75
|
this.host.removeEventListener('focusout', this.handleFocusOut);
|
|
@@ -74,10 +78,37 @@ export class SubmenuController implements ReactiveController {
|
|
|
74
78
|
if (this.isPopupConnected) {
|
|
75
79
|
if (this.popupRef.value) {
|
|
76
80
|
this.popupRef.value.removeEventListener('mouseover', this.handlePopupMouseover);
|
|
81
|
+
this.popupRef.value.removeEventListener('mouseleave', this.handlePopupMouseLeave);
|
|
77
82
|
this.popupRef.value.removeEventListener('syn-reposition', this.handlePopupReposition);
|
|
78
83
|
this.isPopupConnected = false;
|
|
79
84
|
}
|
|
80
85
|
}
|
|
86
|
+
|
|
87
|
+
this.removeGlobalDismissListeners();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private addGlobalDismissListeners() {
|
|
91
|
+
if (this.hasGlobalDismissListeners) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
document.addEventListener('keydown', this.handleDocumentKeyDown);
|
|
96
|
+
window.addEventListener('blur', this.handleWindowBlur);
|
|
97
|
+
window.addEventListener('pagehide', this.handlePageHide);
|
|
98
|
+
document.addEventListener('visibilitychange', this.handleVisibilityChange);
|
|
99
|
+
this.hasGlobalDismissListeners = true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private removeGlobalDismissListeners() {
|
|
103
|
+
if (!this.hasGlobalDismissListeners) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
|
108
|
+
window.removeEventListener('blur', this.handleWindowBlur);
|
|
109
|
+
window.removeEventListener('pagehide', this.handlePageHide);
|
|
110
|
+
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
|
|
111
|
+
this.hasGlobalDismissListeners = false;
|
|
81
112
|
}
|
|
82
113
|
|
|
83
114
|
// Set the safe triangle cursor position
|
|
@@ -92,6 +123,35 @@ export class SubmenuController implements ReactiveController {
|
|
|
92
123
|
}
|
|
93
124
|
};
|
|
94
125
|
|
|
126
|
+
private isWithinSubmenuInteractionTree(target: EventTarget | null): boolean {
|
|
127
|
+
if (!(target instanceof Node)) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (this.host.contains(target)) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (this.popupRef.value?.contains(target)) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const rootNode = target.getRootNode();
|
|
140
|
+
if (rootNode instanceof ShadowRoot) {
|
|
141
|
+
return this.isWithinSubmenuInteractionTree(rootNode.host);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private handleHostMouseLeave = (event: MouseEvent) => {
|
|
148
|
+
if (this.isWithinSubmenuInteractionTree(event.relatedTarget)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.disableSubmenu();
|
|
153
|
+
};
|
|
154
|
+
|
|
95
155
|
private handleSubmenuEntry(event: KeyboardEvent) {
|
|
96
156
|
// Pass focus to the first menu-item in the submenu.
|
|
97
157
|
const submenuSlot: HTMLSlotElement | null = this.host.renderRoot.querySelector("slot[name='submenu']");
|
|
@@ -187,11 +247,40 @@ export class SubmenuController implements ReactiveController {
|
|
|
187
247
|
this.disableSubmenu();
|
|
188
248
|
};
|
|
189
249
|
|
|
250
|
+
private handleWindowBlur = () => {
|
|
251
|
+
this.disableSubmenu();
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
private handlePageHide = () => {
|
|
255
|
+
this.disableSubmenu();
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
private handleVisibilityChange = () => {
|
|
259
|
+
if (document.visibilityState === 'hidden') {
|
|
260
|
+
this.disableSubmenu();
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
private handleDocumentKeyDown = (event: KeyboardEvent) => {
|
|
265
|
+
if (event.key === 'Escape' && this.isExpanded()) {
|
|
266
|
+
this.disableSubmenu();
|
|
267
|
+
event.stopPropagation();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
190
271
|
// Prevent the parent menu-item from getting focus on mouse movement on the submenu
|
|
191
272
|
private handlePopupMouseover = (event: MouseEvent) => {
|
|
192
273
|
event.stopPropagation();
|
|
193
274
|
};
|
|
194
275
|
|
|
276
|
+
private handlePopupMouseLeave = (event: MouseEvent) => {
|
|
277
|
+
if (this.isWithinSubmenuInteractionTree(event.relatedTarget)) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
this.disableSubmenu();
|
|
282
|
+
};
|
|
283
|
+
|
|
195
284
|
// Set the safe triangle values for the submenu when the position changes
|
|
196
285
|
private handlePopupReposition = () => {
|
|
197
286
|
const submenuSlot: HTMLSlotElement | null = this.host.renderRoot.querySelector("slot[name='submenu']");
|
|
@@ -213,6 +302,11 @@ export class SubmenuController implements ReactiveController {
|
|
|
213
302
|
if (this.popupRef.value) {
|
|
214
303
|
if (this.popupRef.value.active !== state) {
|
|
215
304
|
this.popupRef.value.active = state;
|
|
305
|
+
if (state) {
|
|
306
|
+
this.addGlobalDismissListeners();
|
|
307
|
+
} else {
|
|
308
|
+
this.removeGlobalDismissListeners();
|
|
309
|
+
}
|
|
216
310
|
this.host.requestUpdate();
|
|
217
311
|
}
|
|
218
312
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @synergy-design-system/angular
|
|
2
2
|
|
|
3
|
+
## 3.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`4fdb69a`](https://github.com/synergy-design-system/synergy-design-system/commit/4fdb69aec5ddb0ddfa76a948c87eaf84be6fd670)]:
|
|
8
|
+
- @synergy-design-system/components@3.15.1
|
|
9
|
+
- @synergy-design-system/tokens@3.15.1
|
|
10
|
+
|
|
3
11
|
## 3.15.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"url": "https://github.com/synergy-design-system/synergy-design-system.git",
|
|
23
23
|
"directory": "packages/angular"
|
|
24
24
|
},
|
|
25
|
-
"version": "3.15.
|
|
25
|
+
"version": "3.15.1",
|
|
26
26
|
"scripts": {
|
|
27
27
|
"_build": "pnpm _clean && ng-packagr -c tsconfig.lib.json && pnpm _after-build",
|
|
28
28
|
"_clean": "rm -rf ../_private/angular-demo/.angular",
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1296](https://github.com/synergy-design-system/synergy-design-system/pull/1296) [`4fdb69a`](https://github.com/synergy-design-system/synergy-design-system/commit/4fdb69aec5ddb0ddfa76a948c87eaf84be6fd670) Thanks [@schilchSICKAG](https://github.com/schilchSICKAG)! - Released on: 2026-06-03
|
|
8
|
+
|
|
9
|
+
fix: 🐛 `<syn-menu>` multiple issues ([#1295](https://github.com/synergy-design-system/synergy-design-system/issues/1295))
|
|
10
|
+
|
|
11
|
+
This release fixes multiple issues when using `<syn-menu>`:
|
|
12
|
+
- submenus no longer stay open when leaving the browser window ([#882](https://github.com/synergy-design-system/synergy-design-system/issues/882))
|
|
13
|
+
- `<syn-menu-item>` wrapped in tooltip can now be used reliably (including navigation and selection) ([#1162](https://github.com/synergy-design-system/synergy-design-system/issues/1162))
|
|
14
|
+
- `<syn-menu-item>` no longer steals focus on hover ([#1286](https://github.com/synergy-design-system/synergy-design-system/issues/1286))
|
|
15
|
+
|
|
16
|
+
- Updated dependencies []:
|
|
17
|
+
- @synergy-design-system/tokens@3.15.1
|
|
18
|
+
|
|
3
19
|
## 3.15.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @synergy-design-system/react
|
|
2
2
|
|
|
3
|
+
## 3.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`4fdb69a`](https://github.com/synergy-design-system/synergy-design-system/commit/4fdb69aec5ddb0ddfa76a948c87eaf84be6fd670)]:
|
|
8
|
+
- @synergy-design-system/components@3.15.1
|
|
9
|
+
- @synergy-design-system/tokens@3.15.1
|
|
10
|
+
|
|
3
11
|
## 3.15.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @synergy-design-system/vue
|
|
2
2
|
|
|
3
|
+
## 3.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`4fdb69a`](https://github.com/synergy-design-system/synergy-design-system/commit/4fdb69aec5ddb0ddfa76a948c87eaf84be6fd670)]:
|
|
8
|
+
- @synergy-design-system/components@3.15.1
|
|
9
|
+
- @synergy-design-system/tokens@3.15.1
|
|
10
|
+
|
|
3
11
|
## 3.15.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/data/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"serve-handler": "^6.1.7",
|
|
23
23
|
"typescript": "^5.9.3",
|
|
24
24
|
"zod": "^4.3.6",
|
|
25
|
-
"@synergy-design-system/
|
|
26
|
-
"@synergy-design-system/
|
|
25
|
+
"@synergy-design-system/eslint-config-syn": "^0.1.0",
|
|
26
|
+
"@synergy-design-system/fonts": "1.0.6",
|
|
27
27
|
"@synergy-design-system/docs": "0.1.0",
|
|
28
|
+
"@synergy-design-system/components": "3.15.1",
|
|
28
29
|
"@synergy-design-system/styles": "2.1.0",
|
|
29
|
-
"@synergy-design-system/
|
|
30
|
-
"@synergy-design-system/eslint-config-syn": "^0.1.0"
|
|
30
|
+
"@synergy-design-system/tokens": "^3.15.1"
|
|
31
31
|
},
|
|
32
32
|
"exports": {
|
|
33
33
|
".": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"types": "./dist/index.d.ts",
|
|
72
72
|
"type": "module",
|
|
73
|
-
"version": "3.
|
|
73
|
+
"version": "3.11.0",
|
|
74
74
|
"scripts": {
|
|
75
75
|
"build:all": "METADATA_LOG_LEVEL=info pnpm run build:ts && RUN_STORYBOOK_SCRAPER=true pnpm run build:data",
|
|
76
76
|
"build": "METADATA_LOG_LEVEL=info pnpm run build:ts && pnpm run build:data",
|