@mgdis/mg-components 5.5.0 → 5.6.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.
Files changed (142) hide show
  1. package/dist/cjs/{index-c3450336.js → index-4dcc1812.js} +11 -1
  2. package/dist/cjs/loader.cjs.js +3 -3
  3. package/dist/cjs/mg-badge_30.cjs.entry.js +742 -244
  4. package/dist/cjs/mg-components.cjs.js +3 -3
  5. package/dist/collection/collection-manifest.json +4 -4
  6. package/dist/collection/components/atoms/mg-badge/mg-badge.conf.js +1 -1
  7. package/dist/collection/components/atoms/mg-badge/mg-badge.css +13 -0
  8. package/dist/collection/components/atoms/mg-badge/mg-badge.js +3 -3
  9. package/dist/collection/components/atoms/mg-button/mg-button.css +2 -1
  10. package/dist/collection/components/atoms/mg-card/mg-card.css +13 -6
  11. package/dist/collection/components/atoms/mg-icon/mg-icon.conf.js +13 -3
  12. package/dist/collection/components/atoms/mg-tag/mg-tag.css +6 -6
  13. package/dist/collection/components/atoms/mg-tag/mg-tag.js +3 -3
  14. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip.css +2 -0
  15. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip.js +3 -3
  16. package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.css +3 -3
  17. package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.js +4 -1
  18. package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.css +3 -3
  19. package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.css +3 -3
  20. package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.css +3 -3
  21. package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.js +7 -3
  22. package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.css +3 -3
  23. package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.css +3 -3
  24. package/dist/collection/components/molecules/menu/mg-menu/doc/mg-menu.stories.js +43 -11
  25. package/dist/collection/components/molecules/menu/mg-menu/mg-menu.conf.js +17 -0
  26. package/dist/collection/components/molecules/menu/mg-menu/mg-menu.css +27 -0
  27. package/dist/collection/components/molecules/menu/mg-menu/mg-menu.js +141 -18
  28. package/dist/collection/components/molecules/menu/mg-menu-item/doc/mg-menu-item.stories.js +5 -10
  29. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.conf.js +0 -4
  30. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.css +47 -21
  31. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.js +118 -70
  32. package/dist/collection/components/molecules/mg-illustrated-message/mg-illustrated-message.js +4 -3
  33. package/dist/collection/components/molecules/mg-message/mg-message.css +7 -0
  34. package/dist/collection/components/molecules/mg-message/mg-message.js +53 -12
  35. package/dist/collection/components/molecules/mg-modal/mg-modal.css +8 -1
  36. package/dist/collection/components/molecules/mg-panel/mg-panel.css +7 -0
  37. package/dist/collection/components/molecules/mg-popover/mg-popover.css +72 -14
  38. package/dist/collection/components/molecules/mg-popover/mg-popover.js +48 -4
  39. package/dist/collection/components/molecules/mg-skip-links/doc/mg-skip-links.stories.js +1 -1
  40. package/dist/collection/components/molecules/mg-skip-links/mg-skip-links.js +32 -1
  41. package/dist/collection/components/molecules/mg-tabs/doc/mg-tabs.stories.js +5 -3
  42. package/dist/collection/components/molecules/mg-tabs/mg-tabs.css +11 -7
  43. package/dist/collection/components/molecules/mg-tabs/mg-tabs.js +101 -54
  44. package/dist/collection/locales/en/messages.json +4 -0
  45. package/dist/collection/locales/fr/messages.json +4 -0
  46. package/dist/collection/locales/index.js +2 -25
  47. package/dist/collection/styles/a11y.scss +32 -0
  48. package/dist/collection/styles/components.scss +3 -0
  49. package/dist/collection/styles/fonts.scss +21 -0
  50. package/dist/collection/styles/form.scss +3 -0
  51. package/dist/collection/styles/global.scss +87 -0
  52. package/dist/collection/styles/layout.scss +29 -0
  53. package/dist/collection/styles/main.scss +23 -0
  54. package/dist/collection/styles/navigation-button.scss +76 -0
  55. package/dist/collection/styles/reset-mg-card-slotted-variables.scss +9 -0
  56. package/dist/collection/styles/typography.scss +75 -0
  57. package/dist/collection/styles/utilities.scss +21 -0
  58. package/dist/collection/utils/behaviors.utils.js +169 -0
  59. package/dist/collection/utils/components.utils.js +50 -0
  60. package/dist/collection/utils/locale.utils.js +22 -0
  61. package/dist/collection/utils/unit.test.utils.js +37 -32
  62. package/dist/collection/variables.css +9 -9
  63. package/dist/components/components.utils.js +51 -1
  64. package/dist/components/index2.js +65 -18
  65. package/dist/components/mg-badge2.js +4 -4
  66. package/dist/components/mg-button2.js +1 -1
  67. package/dist/components/mg-card2.js +1 -1
  68. package/dist/components/mg-icon2.js +13 -3
  69. package/dist/components/mg-illustrated-message.js +4 -3
  70. package/dist/components/mg-input-date.js +6 -4
  71. package/dist/components/mg-input-numeric.js +2 -3
  72. package/dist/components/mg-input-password.js +1 -1
  73. package/dist/components/mg-input-select2.js +8 -4
  74. package/dist/components/mg-input-text2.js +1 -1
  75. package/dist/components/mg-input-textarea.js +1 -1
  76. package/dist/components/mg-menu-item.js +1 -253
  77. package/dist/components/mg-menu-item2.js +517 -0
  78. package/dist/components/mg-menu.js +138 -21
  79. package/dist/components/mg-message.js +54 -13
  80. package/dist/components/mg-modal.js +1 -1
  81. package/dist/components/mg-panel.js +1 -1
  82. package/dist/components/mg-popover.js +1 -190
  83. package/dist/components/mg-popover2.js +212 -0
  84. package/dist/components/mg-skip-links.js +16 -2
  85. package/dist/components/mg-tabs.js +100 -52
  86. package/dist/components/mg-tag.js +4 -4
  87. package/dist/components/mg-tooltip2.js +4 -4
  88. package/dist/esm/{index-78edde1d.js → index-dc9a2348.js} +11 -1
  89. package/dist/esm/loader.js +3 -3
  90. package/dist/esm/mg-badge_30.entry.js +742 -244
  91. package/dist/esm/mg-components.js +3 -3
  92. package/dist/esm/polyfills/css-shim.js +1 -1
  93. package/dist/mg-components/locales/en/messages.json +4 -0
  94. package/dist/mg-components/locales/fr/messages.json +4 -0
  95. package/dist/mg-components/mg-components.css +1 -1
  96. package/dist/mg-components/mg-components.esm.js +1 -1
  97. package/dist/mg-components/{p-125c54ca.js → p-182bd802.js} +2 -2
  98. package/dist/mg-components/p-f7da9dd2.entry.js +1 -0
  99. package/dist/mg-components/styles/a11y.scss +32 -0
  100. package/dist/mg-components/styles/components.scss +3 -0
  101. package/dist/mg-components/styles/fonts.scss +21 -0
  102. package/dist/mg-components/styles/form.scss +3 -0
  103. package/dist/mg-components/styles/global.scss +87 -0
  104. package/dist/mg-components/styles/layout.scss +29 -0
  105. package/dist/mg-components/styles/main.scss +23 -0
  106. package/dist/mg-components/styles/navigation-button.scss +76 -0
  107. package/dist/mg-components/styles/reset-mg-card-slotted-variables.scss +9 -0
  108. package/dist/mg-components/styles/typography.scss +75 -0
  109. package/dist/mg-components/styles/utilities.scss +21 -0
  110. package/dist/mg-components/variables.css +9 -9
  111. package/dist/types/components/atoms/mg-badge/mg-badge.conf.d.ts +2 -2
  112. package/dist/types/components/atoms/mg-button/mg-button.conf.d.ts +2 -2
  113. package/dist/types/components/atoms/mg-icon/mg-icon.conf.d.ts +2 -2
  114. package/dist/types/components/atoms/mg-tag/mg-tag.conf.d.ts +1 -1
  115. package/dist/types/components/molecules/inputs/MgInput.conf.d.ts +2 -2
  116. package/dist/types/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.conf.d.ts +2 -2
  117. package/dist/types/components/molecules/inputs/mg-input-radio/mg-input-radio.conf.d.ts +1 -1
  118. package/dist/types/components/molecules/inputs/mg-input-select/mg-input-select.conf.d.ts +2 -2
  119. package/dist/types/components/molecules/inputs/mg-input-toggle/mg-input-toggle.conf.d.ts +1 -1
  120. package/dist/types/components/molecules/menu/mg-menu/doc/mg-menu.stories.d.ts +5 -0
  121. package/dist/types/components/molecules/menu/mg-menu/mg-menu.conf.d.ts +37 -0
  122. package/dist/types/components/molecules/menu/mg-menu/mg-menu.d.ts +51 -3
  123. package/dist/types/components/molecules/menu/mg-menu-item/mg-menu-item.conf.d.ts +0 -8
  124. package/dist/types/components/molecules/menu/mg-menu-item/mg-menu-item.d.ts +55 -15
  125. package/dist/types/components/molecules/mg-message/mg-message.d.ts +21 -4
  126. package/dist/types/components/molecules/mg-popover/mg-popover.d.ts +12 -0
  127. package/dist/types/components/molecules/mg-skip-links/mg-skip-links.conf.d.ts +1 -1
  128. package/dist/types/components/molecules/mg-skip-links/mg-skip-links.d.ts +15 -0
  129. package/dist/types/components/molecules/mg-tabs/mg-tabs.conf.d.ts +5 -3
  130. package/dist/types/components/molecules/mg-tabs/mg-tabs.d.ts +22 -12
  131. package/dist/types/components.d.ts +44 -12
  132. package/dist/types/locales/index.d.ts +10 -9
  133. package/dist/types/stencil-public-runtime.d.ts +39 -3
  134. package/dist/types/utils/behaviors.utils.d.ts +83 -0
  135. package/dist/types/utils/components.utils.d.ts +14 -0
  136. package/dist/types/utils/locale.utils.d.ts +13 -0
  137. package/dist/types/utils/unit.test.utils.d.ts +50 -14
  138. package/package.json +26 -26
  139. package/readme.md +22 -13
  140. package/dist/components/locale.utils.js +0 -40
  141. package/dist/components/mg-menu.conf.js +0 -10
  142. package/dist/mg-components/p-4961c96c.entry.js +0 -1
@@ -1,7 +1,9 @@
1
1
  import { h, Host } from '@stencil/core';
2
+ import { OverflowBehaviorElements } from '../../../../utils/behaviors.utils';
2
3
  import { ClassList } from '../../../../utils/components.utils';
4
+ import { initLocales } from '../../../../locales';
3
5
  import { Direction } from '../mg-menu/mg-menu.conf';
4
- import { sizes, Status } from './mg-menu-item.conf';
6
+ import { Status } from './mg-menu-item.conf';
5
7
  export class MgMenuItem {
6
8
  constructor() {
7
9
  /************
@@ -9,9 +11,9 @@ export class MgMenuItem {
9
11
  ************/
10
12
  this.name = 'mg-menu-item';
11
13
  this.navigationButton = `${this.name}__navigation-button`;
12
- /************
14
+ /***********
13
15
  * Methods *
14
- ************/
16
+ **********/
15
17
  /**
16
18
  * Toggle expanded prop value
17
19
  *
@@ -21,20 +23,20 @@ export class MgMenuItem {
21
23
  this.expanded = !this.expanded;
22
24
  };
23
25
  /**
24
- * Does an HTMLElement contain child with given Status
26
+ * Does an Element have given Status
25
27
  *
26
- * @param {HTMLElement} element to parse
28
+ * @param {Element} element to parse
27
29
  * @param {MgMenuItem['status']} status to check
28
30
  * @returns {boolean} true if element with status is found
29
31
  */
30
- this.hasChildElementStatus = (element, status) => element.querySelector(`${this.name}[status="${status}"]`) !== null;
32
+ this.hasStatus = (element, status) => element.querySelector(`${this.name}[status="${status}"]`) !== null;
31
33
  /**
32
34
  * Is component contextual direction match the given direction
33
35
  *
34
36
  * @param {MgMenuItem['direction']} direction in parent menu
35
37
  * @returns {boolean} true is direction match the direction propertie
36
38
  */
37
- this.isdirection = (direction) => this.direction === direction;
39
+ this.isDirection = (direction) => this.direction === direction;
38
40
  /************
39
41
  * Handlers *
40
42
  ************/
@@ -45,7 +47,7 @@ export class MgMenuItem {
45
47
  * @returns {void}
46
48
  */
47
49
  this.handleElementCLick = (event) => {
48
- if (this.hasChildren || this.status === Status.DISABLED) {
50
+ if ((this.hasChildren && !this.isInMainMenu) || this.status === Status.DISABLED) {
49
51
  event.preventDefault();
50
52
  event.stopPropagation();
51
53
  }
@@ -53,27 +55,49 @@ export class MgMenuItem {
53
55
  if (this.hasChildren)
54
56
  this.toggleExpanded();
55
57
  };
58
+ /**
59
+ * Handle popover element display-change event
60
+ *
61
+ * @param {CustomEvent} event popover display event
62
+ * @returns {void}
63
+ */
64
+ this.handlePopoverDisplay = (event) => {
65
+ this.expanded = event.detail;
66
+ };
67
+ /**
68
+ * Update displayNotificationBadge
69
+ * current component notification badge have priority over the slot badge when submenu contain badge
70
+ *
71
+ * @returns {void} update displayNotificationBadge value
72
+ */
73
+ this.updateDisplayNotificationBadge = () => {
74
+ const childMenu = this.element.querySelector('mg-menu');
75
+ this.displayNotificationBadge =
76
+ childMenu !== null &&
77
+ Array.from(childMenu.children).some((subItem) => subItem.querySelector('mg-badge') !== null && subItem.getAttribute('hidden') === null);
78
+ };
79
+ /**
80
+ * Render slot
81
+ *
82
+ * @returns {HTMLElement} HTML Element
83
+ */
84
+ this.renderSlot = () => h("slot", null);
56
85
  this.href = undefined;
57
86
  this.status = Status.VISIBLE;
58
- this.size = 'large';
59
87
  this.expanded = false;
88
+ this.size = 'regular';
60
89
  this.navigationButtonClassList = new ClassList([this.navigationButton]);
61
90
  this.direction = undefined;
62
91
  this.isInMainMenu = undefined;
63
92
  this.hasChildren = false;
93
+ this.displayNotificationBadge = undefined;
64
94
  }
65
95
  validateStatus(newValue, oldValue) {
66
96
  if (oldValue !== undefined) {
67
97
  this.navigationButtonClassList.delete(`${this.navigationButton}--${oldValue}`);
68
98
  }
69
99
  this.navigationButtonClassList.add(`${this.navigationButton}--${newValue}`);
70
- }
71
- validateSize(newValue, oldValue) {
72
- if (!sizes.includes(newValue)) {
73
- throw new Error(`<${this.name}> prop "size" must be one of : ${sizes.join(', ')}.`);
74
- }
75
- this.navigationButtonClassList.delete(`${this.navigationButton}--size-${oldValue}`);
76
- this.navigationButtonClassList.add(`${this.navigationButton}--size-${newValue}`);
100
+ this.statusChange.emit(newValue);
77
101
  }
78
102
  validateExpanded(newValue) {
79
103
  if (typeof newValue !== 'boolean')
@@ -87,16 +111,20 @@ export class MgMenuItem {
87
111
  item.expanded = false;
88
112
  });
89
113
  }
90
- else if (newValue && this.hasChildElementStatus(this.element, Status.ACTIVE)) {
114
+ else if (this.hasStatus(this.element, Status.ACTIVE)) {
91
115
  // - when expanded and contain an active item parents are expended too
92
116
  subItems.forEach(item => {
93
- if (this.hasChildElementStatus(item, Status.ACTIVE)) {
117
+ if (this.hasStatus(item, Status.ACTIVE)) {
94
118
  item.expanded = true;
95
119
  }
96
120
  });
97
121
  }
98
122
  }
99
123
  }
124
+ validateSize(newValue, oldValue) {
125
+ this.navigationButtonClassList.delete(`${this.navigationButton}--size-${oldValue}`);
126
+ this.navigationButtonClassList.add(`${this.navigationButton}--size-${newValue}`);
127
+ }
100
128
  validateHasChildren(newValue) {
101
129
  if (newValue && this.element.href !== undefined) {
102
130
  throw new Error(`<${this.name}> prop "href" is unauthorizied when element is a parent.`);
@@ -111,13 +139,14 @@ export class MgMenuItem {
111
139
  * @returns {void}
112
140
  */
113
141
  componentWillLoad() {
114
- // has children items that is NOT [slot="illustration"] || [slot="information"] element
142
+ // has children items that is NOT [slot='image' | 'information' | 'label' | 'metadata'] element
115
143
  // we store only matching elements
116
- this.hasChildren = Array.from(this.element.children).filter(child => !['illustration', 'information', 'label', 'metadata'].includes(child.getAttribute('slot'))).length > 0;
144
+ this.hasChildren = Array.from(this.element.children).some(child => !['image', 'information', 'label', 'metadata'].includes(child.getAttribute('slot')));
117
145
  // Validate props
118
146
  this.validateSize(this.size);
119
147
  this.validateStatus(this.status);
120
148
  this.validateExpanded(this.expanded);
149
+ this.badgeLabel = initLocales(this.element).messages.plusMenu.badgeLabel;
121
150
  }
122
151
  /**
123
152
  * Check if component slots configuration
@@ -141,49 +170,67 @@ export class MgMenuItem {
141
170
  // return a promise to process action only in the FIRST render().
142
171
  // https://stenciljs.com/docs/component-lifecycle#componentwillload
143
172
  return setTimeout(() => {
144
- var _a, _b;
173
+ var _a;
145
174
  // define menu-item context states
146
- if (this.element.parentElement.nodeName === 'MG-MENU') {
147
- this.direction = this.element.parentElement.direction;
148
- }
149
- this.isInMainMenu = this.element.parentElement.className.includes('mg-menu-item') === false;
150
- const hasNextMenuItem = ((_a = this.element.nextElementSibling) === null || _a === void 0 ? void 0 : _a.nodeName) === 'MG-MENU-ITEM';
151
- const hasPreviousMenuItem = ((_b = this.element.previousElementSibling) === null || _b === void 0 ? void 0 : _b.nodeName) === 'MG-MENU-ITEM';
152
- // manage last menu item
153
- if (!hasNextMenuItem && hasPreviousMenuItem && this.isdirection(Direction.HORIZONTAL)) {
154
- this.element.setAttribute('data-style-position-last', '');
155
- }
175
+ const menu = this.element.closest('mg-menu');
176
+ this.direction = this.element.getAttribute(OverflowBehaviorElements.MORE) !== null || menu === null ? Direction.HORIZONTAL : menu.direction;
177
+ this.size = menu === null || menu === void 0 ? void 0 : menu.size;
178
+ this.isInMainMenu = this.element.parentElement.closest('mg-menu-item') === null;
156
179
  // when main menu item contain an active item it will get the active style
157
180
  // AND if item is in vertical menu it will be expanded
158
- if (this.isInMainMenu && this.hasChildElementStatus(this.element, Status.ACTIVE)) {
181
+ const hasActiveChild = Array.from(this.element.children).some(element => this.hasStatus(element, Status.ACTIVE) && element.getAttribute('hidden') === null);
182
+ if (this.isInMainMenu && hasActiveChild) {
159
183
  this.status = Status.ACTIVE;
160
- this.expanded = this.direction === Direction.VERTICAL;
184
+ this.expanded = this.isDirection(Direction.VERTICAL);
161
185
  }
162
186
  // manage menu items style depending to parent menu horientation
163
187
  this.element.setAttribute(`data-style-direction-${this.direction}`, '');
164
188
  this.navigationButtonClassList.add(`${this.navigationButton}--${this.direction}`);
165
- // manage child items level
166
- const childItems = Array.from(this.element.querySelectorAll('mg-menu-item'));
167
- childItems.forEach(item => {
168
- if (this.direction === Direction.VERTICAL) {
189
+ this.updateDisplayNotificationBadge();
190
+ // manage all sub levels child menu-items level with data-level attribut
191
+ if (this.isDirection(Direction.VERTICAL)) {
192
+ Array.from(this.element.querySelectorAll('mg-menu-item')).forEach(item => {
169
193
  const itemLevel = Number(item.getAttribute('data-level')) || 1;
170
194
  item.setAttribute('data-level', `${itemLevel + 1}`);
171
- }
195
+ });
196
+ }
197
+ // manage first sub-level menu-items
198
+ const childItems = Array.from(((_a = this.element.querySelector('mg-menu')) === null || _a === void 0 ? void 0 : _a.children) || []).filter(item => item.nodeName === 'MG-MENU-ITEM');
199
+ childItems.forEach(item => {
200
+ // manage child menu listener
201
+ new MutationObserver(() => {
202
+ this.updateDisplayNotificationBadge();
203
+ }).observe(item, { attributes: true });
172
204
  });
173
205
  }, 0);
174
206
  }
175
207
  /**
176
- * Render
208
+ * Render ineractive element
177
209
  *
178
210
  * @returns {HTMLElement} HTML Element
179
211
  */
180
- render() {
212
+ renderInteractiveElement() {
181
213
  const TagName = this.href !== undefined ? 'a' : 'button';
182
- return (h(Host, { role: "menuitem", "aria-haspopup": this.hasChildren.toString() }, h(TagName, { href: this.href, class: this.navigationButtonClassList.join(), tabindex: [Status.DISABLED, Status.HIDDEN].includes(this.status) ? -1 : 0, disabled: this.status === Status.DISABLED, "aria-expanded": this.hasChildren && this.expanded.toString(), "aria-current": this.status === Status.ACTIVE && 'page', onClick: this.handleElementCLick }, h("slot", { name: "illustration" }), h("div", { class: `${this.navigationButton}-center` }, h("div", { class: `${this.navigationButton}-text-content` }, h("slot", { name: "label" }), h("slot", { name: "information" })), h("slot", { name: "metadata" })), this.hasChildren && this.href === undefined && (h("span", { class: {
214
+ return (h(TagName, { href: this.href, class: this.navigationButtonClassList.join(), tabindex: [Status.DISABLED, Status.HIDDEN].includes(this.status) ? -1 : 0, disabled: this.status === Status.DISABLED, hidden: this.status === Status.HIDDEN, "aria-expanded": this.hasChildren && this.expanded.toString(), "aria-current": this.status === Status.ACTIVE && 'page', onClick: this.handleElementCLick }, h("slot", { name: "image" }), h("div", { class: `${this.navigationButton}-center` }, h("div", { class: `${this.navigationButton}-text-content` }, h("slot", { name: "label" }), !this.displayNotificationBadge && h("slot", { name: "information" }), this.displayNotificationBadge && (h("span", { class: "mg-menu-item__navigation-button-text-content-notification" }, h("mg-badge", { label: this.badgeLabel, value: "!", variant: "info", slot: "information" })))), this.size !== 'regular' && h("slot", { name: "metadata" })), this.hasChildren && this.href === undefined && (h("span", { class: {
183
215
  [`${this.navigationButton}-chevron`]: true,
184
216
  [`${this.navigationButton}-chevron--rotate`]: this.expanded === true,
185
217
  'mg-a11y-animation': true,
186
- } }, h("mg-icon", { icon: "chevron-down" })))), h("div", { class: { [`${this.name}__collapse-container`]: true, [`${this.name}__collapse-container--first-level`]: this.isInMainMenu && this.isdirection(Direction.HORIZONTAL) }, hidden: !this.expanded }, h("slot", null))));
218
+ } }, h("mg-icon", { icon: "chevron-down" })))));
219
+ }
220
+ /**
221
+ * Render
222
+ *
223
+ * @returns {HTMLElement} HTML Element
224
+ */
225
+ render() {
226
+ const getContainerClasses = () => ({
227
+ [`${this.name}__collapse-container`]: true,
228
+ [`${this.name}__collapse-container--first-level`]: this.isInMainMenu && this.isDirection(Direction.HORIZONTAL),
229
+ });
230
+ return (h(Host, { role: "menuitem", "aria-haspopup": this.hasChildren.toString() }, this.isDirection(Direction.HORIZONTAL) && this.hasChildren && this.href === undefined ? (h("mg-popover", { display: this.expanded, placement: "bottom-start", arrowHide: true, "onDisplay-change": this.handlePopoverDisplay }, this.renderInteractiveElement(), h("div", { class: getContainerClasses(), slot: "content" }, this.renderSlot()))) : ([
231
+ this.renderInteractiveElement(),
232
+ h("div", { class: getContainerClasses(), hidden: !this.expanded }, this.renderSlot()),
233
+ ])));
187
234
  }
188
235
  static get is() { return "mg-menu-item"; }
189
236
  static get encapsulation() { return "shadow"; }
@@ -211,7 +258,7 @@ export class MgMenuItem {
211
258
  "optional": false,
212
259
  "docs": {
213
260
  "tags": [],
214
- "text": "Define menu-item badge\nwhen defined menu-item contain an anchor instead of button"
261
+ "text": "Define menu-item href\nwhen defined menu-item contain an anchor instead of button"
215
262
  },
216
263
  "attribute": "href",
217
264
  "reflect": false
@@ -239,29 +286,6 @@ export class MgMenuItem {
239
286
  "reflect": true,
240
287
  "defaultValue": "Status.VISIBLE"
241
288
  },
242
- "size": {
243
- "type": "string",
244
- "mutable": false,
245
- "complexType": {
246
- "original": "MenuItemSizeType",
247
- "resolved": "\"large\" | \"medium\" | \"regular\"",
248
- "references": {
249
- "MenuItemSizeType": {
250
- "location": "import",
251
- "path": "./mg-menu-item.conf"
252
- }
253
- }
254
- },
255
- "required": false,
256
- "optional": false,
257
- "docs": {
258
- "tags": [],
259
- "text": "Define menu-item size. Default: \"large\"."
260
- },
261
- "attribute": "size",
262
- "reflect": false,
263
- "defaultValue": "'large'"
264
- },
265
289
  "expanded": {
266
290
  "type": "boolean",
267
291
  "mutable": true,
@@ -284,23 +308,47 @@ export class MgMenuItem {
284
308
  }
285
309
  static get states() {
286
310
  return {
311
+ "size": {},
287
312
  "navigationButtonClassList": {},
288
313
  "direction": {},
289
314
  "isInMainMenu": {},
290
- "hasChildren": {}
315
+ "hasChildren": {},
316
+ "displayNotificationBadge": {}
291
317
  };
292
318
  }
319
+ static get events() {
320
+ return [{
321
+ "method": "statusChange",
322
+ "name": "status-change",
323
+ "bubbles": true,
324
+ "cancelable": true,
325
+ "composed": true,
326
+ "docs": {
327
+ "tags": [],
328
+ "text": "Emited event when status change"
329
+ },
330
+ "complexType": {
331
+ "original": "MgMenuItem['status']",
332
+ "resolved": "Status.ACTIVE | Status.DISABLED | Status.HIDDEN | Status.VISIBLE",
333
+ "references": {
334
+ "MgMenuItem": {
335
+ "location": "global"
336
+ }
337
+ }
338
+ }
339
+ }];
340
+ }
293
341
  static get elementRef() { return "element"; }
294
342
  static get watchers() {
295
343
  return [{
296
344
  "propName": "status",
297
345
  "methodName": "validateStatus"
298
- }, {
299
- "propName": "size",
300
- "methodName": "validateSize"
301
346
  }, {
302
347
  "propName": "expanded",
303
348
  "methodName": "validateExpanded"
349
+ }, {
350
+ "propName": "size",
351
+ "methodName": "validateSize"
304
352
  }, {
305
353
  "propName": "hasChildren",
306
354
  "methodName": "validateHasChildren"
@@ -15,13 +15,14 @@ export class MgIllustratedMessage {
15
15
  */
16
16
  componentDidLoad() {
17
17
  const headingTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
18
- const imageTags = ['img', 'svg'];
18
+ const slottedIllustrations = this.element.querySelectorAll('[slot="illustration"]');
19
19
  if (!isTagName(this.element.querySelector('[slot="title"]'), headingTags)) {
20
20
  throw new Error(`<mg-illustrated-message> Slotted title must be a heading: ${headingTags.join(', ')}`);
21
21
  }
22
- else if (!isTagName(this.element.querySelector('[slot="illustration"]'), imageTags)) {
23
- throw new Error(`<mg-illustrated-message> Slotted illustration must be an image: ${imageTags.join(', ')}`);
22
+ else if (slottedIllustrations.length !== 1) {
23
+ throw new Error('<mg-illustrated-message> Slotted illustration must be present and unique.');
24
24
  }
25
+ slottedIllustrations[0].setAttribute('aria-hidden', 'true');
25
26
  }
26
27
  /**
27
28
  * Render
@@ -81,6 +81,13 @@
81
81
  top: 0;
82
82
  right: 0;
83
83
  }
84
+ .mg-message ::slotted(*) {
85
+ --mg-card-border: var(--mg-card-border-default);
86
+ --mg-card-padding: var(--mg-card-padding-default);
87
+ --mg-card-border-radius: var(--mg-card-border-radius-default);
88
+ --mg-card-background: var(--mg-card-background-default);
89
+ --mg-card-box-shadow: var(--mg-card-box-shadow-default);
90
+ }
84
91
 
85
92
  .mg-message,
86
93
  mg-message {
@@ -13,22 +13,49 @@ export class MgMessage {
13
13
  this.closeButtonId = '';
14
14
  // Stored timer setted when hide action is run from setTimeOut
15
15
  this.storedTimer = null;
16
+ // Manage hover
17
+ this.isFocused = false;
18
+ this.isHovered = false;
16
19
  /**
17
- * Handle close button
20
+ * Set timer
21
+ *
22
+ * @returns {void}
18
23
  */
19
- this.handleClose = () => {
20
- this.hide = true;
24
+ this.setTimer = () => {
25
+ this.storedTimer = setTimeout(() => (this.hide = true), this.delay * 1000);
21
26
  };
22
27
  /**
23
- * Hide component whith delay
28
+ * Clear timer
29
+ *
30
+ * @returns {void}
24
31
  */
25
- this.hideWithDelay = () => {
26
- if (this.delay > 0 && this.hide !== true) {
27
- this.storedTimer = setTimeout(() => (this.hide = true), this.delay * 1000);
28
- }
29
- else if (this.storedTimer !== null) {
30
- clearTimeout(this.storedTimer);
31
- }
32
+ this.clearTimer = () => {
33
+ clearTimeout(this.storedTimer);
34
+ };
35
+ /**
36
+ * Event to add on element
37
+ *
38
+ * @param {MouseEvent | FocusEvent} event event
39
+ * @returns {void}
40
+ */
41
+ this.timerEvents = (event) => {
42
+ this.clearTimer();
43
+ const isMouseEvent = event.type === 'mouseenter';
44
+ // Needed to ensure we don't start the timer
45
+ this[isMouseEvent ? 'isHovered' : 'isFocused'] = true;
46
+ // Restart timer when loose focus AND mouse leave
47
+ this.element.addEventListener(isMouseEvent ? 'mouseleave' : 'focusout', eventOut => {
48
+ this[eventOut.type === 'mouseleave' ? 'isHovered' : 'isFocused'] = false;
49
+ // Start timer if needed
50
+ if (!this.isFocused && !this.isHovered)
51
+ this.setTimer();
52
+ }, { once: true });
53
+ };
54
+ /**
55
+ * Handle close button
56
+ */
57
+ this.handleClose = () => {
58
+ this.hide = true;
32
59
  };
33
60
  /**
34
61
  * Get icon corresponding to variant
@@ -83,12 +110,26 @@ export class MgMessage {
83
110
  if (newValue) {
84
111
  this.componentHide.emit();
85
112
  this.classList.add(this.classHide);
113
+ // Remove event Listener
114
+ ['focusin', 'mouseenter'].forEach(event => {
115
+ this.element.removeEventListener(event, this.timerEvents);
116
+ });
117
+ // Clear Timer
118
+ this.clearTimer();
86
119
  }
87
120
  else {
88
121
  this.componentShow.emit();
89
122
  this.classList.delete(this.classHide);
123
+ // If delay is set
124
+ if (this.delay > 1) {
125
+ // Start timer
126
+ this.setTimer();
127
+ // Stop timer when get focus or mouse enter
128
+ ['focusin', 'mouseenter'].forEach(event => {
129
+ this.element.addEventListener(event, this.timerEvents);
130
+ });
131
+ }
90
132
  }
91
- this.hideWithDelay();
92
133
  }
93
134
  /*************
94
135
  * Lifecycle *
@@ -15,7 +15,7 @@
15
15
  left: 0;
16
16
  z-index: 2000;
17
17
  padding: 2rem 0;
18
- background-color: hsla(var(--color-light), 85%);
18
+ background-color: hsl(var(--color-light), 0.85);
19
19
  }
20
20
  .mg-modal mg-card {
21
21
  display: flex;
@@ -55,4 +55,11 @@
55
55
  }
56
56
  .mg-modal.mg-modal--hide {
57
57
  display: none;
58
+ }
59
+ .mg-modal ::slotted(*) {
60
+ --mg-card-border: var(--mg-card-border-default);
61
+ --mg-card-padding: var(--mg-card-padding-default);
62
+ --mg-card-border-radius: var(--mg-card-border-radius-default);
63
+ --mg-card-background: var(--mg-card-background-default);
64
+ --mg-card-box-shadow: var(--mg-card-box-shadow-default);
58
65
  }
@@ -45,4 +45,11 @@
45
45
  flex-wrap: wrap;
46
46
  gap: 1rem;
47
47
  margin-left: auto;
48
+ }
49
+ .mg-panel ::slotted(*) {
50
+ --mg-card-border: var(--mg-card-border-default);
51
+ --mg-card-padding: var(--mg-card-padding-default);
52
+ --mg-card-border-radius: var(--mg-card-border-radius-default);
53
+ --mg-card-background: var(--mg-card-background-default);
54
+ --mg-card-box-shadow: var(--mg-card-box-shadow-default);
48
55
  }
@@ -1,5 +1,5 @@
1
1
  :host {
2
- --mg-card-padding: 1.5rem;
2
+ --mg-card-padding: var(--mg-popover-padding-vertical, 1.5rem) var(--mg-popover-padding-horizontal, var(--mg-popover-padding-vertical, 1.5rem));
3
3
  --mg-card-border: none;
4
4
  --mg-card-border-radius: 0.5rem;
5
5
  --mg-card-background: hsl(var(--mg-popover-background-color));
@@ -12,10 +12,12 @@
12
12
 
13
13
  .mg-popover {
14
14
  display: none;
15
+ padding: 1rem;
15
16
  z-index: 2000;
16
17
  color: hsl(var(--mg-popover-font-color));
17
18
  }
18
19
  .mg-popover mg-card {
20
+ position: relative;
19
21
  z-index: -1;
20
22
  }
21
23
  .mg-popover[data-show] {
@@ -27,35 +29,91 @@
27
29
  margin-top: calc(0rem - (var(--default-size) - var(--mg-popover-title-font-size) * var(--line-height)) / 2);
28
30
  margin-left: 3rem;
29
31
  }
30
- .mg-popover__arrow, .mg-popover__arrow::before {
31
- position: absolute;
32
- width: 2rem;
33
- height: 2rem;
34
- z-index: 2000;
35
- background: hsl(var(--mg-popover-background-color));
36
- }
37
32
  .mg-popover__arrow {
33
+ position: absolute;
38
34
  visibility: hidden;
35
+ width: calc(3rem + 2 * var(--mg-card-border-radius) + 2rem);
36
+ height: calc(3rem + 2 * var(--mg-card-border-radius) + 2rem);
39
37
  }
40
- .mg-popover__arrow::before {
38
+ .mg-popover__arrow:before {
41
39
  visibility: visible;
42
40
  content: "";
43
- transform: rotate(45deg);
41
+ position: absolute;
42
+ }
43
+ .mg-popover[data-popper-placement^=top] > .mg-popover__arrow, .mg-popover[data-popper-placement^=bottom] > .mg-popover__arrow {
44
+ height: 1rem;
45
+ }
46
+ .mg-popover[data-popper-placement^=top] > .mg-popover__arrow:before, .mg-popover[data-popper-placement^=bottom] > .mg-popover__arrow:before {
47
+ left: calc(var(--mg-card-border-radius) + 1rem);
48
+ border-right: calc(3rem / 2) solid transparent;
49
+ border-left: calc(3rem / 2) solid transparent;
44
50
  }
45
51
  .mg-popover[data-popper-placement^=top] > .mg-popover__arrow {
46
- bottom: -6px;
52
+ bottom: 0.1rem;
53
+ filter: drop-shadow(0 0.5rem 0.25rem hsl(var(--color-dark), 0.15));
54
+ }
55
+ .mg-popover[data-popper-placement^=top] > .mg-popover__arrow:before {
56
+ border-top: 1rem solid hsl(var(--mg-popover-background-color));
47
57
  }
48
58
  .mg-popover[data-popper-placement^=bottom] > .mg-popover__arrow {
49
- top: -6px;
59
+ top: 0.1rem;
60
+ filter: drop-shadow(0 -0.5rem 0.25rem hsl(var(--color-dark), 0.15));
61
+ }
62
+ .mg-popover[data-popper-placement^=bottom] > .mg-popover__arrow:before {
63
+ border-bottom: 1rem solid hsl(var(--mg-popover-background-color));
64
+ }
65
+ .mg-popover[data-popper-placement^=left] > .mg-popover__arrow, .mg-popover[data-popper-placement^=right] > .mg-popover__arrow {
66
+ width: 1rem;
67
+ }
68
+ .mg-popover[data-popper-placement^=left] > .mg-popover__arrow:before, .mg-popover[data-popper-placement^=right] > .mg-popover__arrow:before {
69
+ top: calc(var(--mg-card-border-radius) + 1rem);
70
+ border-top: calc(3rem / 2) solid transparent;
71
+ border-bottom: calc(3rem / 2) solid transparent;
50
72
  }
51
73
  .mg-popover[data-popper-placement^=left] > .mg-popover__arrow {
52
- right: -6px;
74
+ right: 0.1rem;
75
+ filter: drop-shadow(0.5rem 0 0.25rem hsl(var(--color-dark), 0.15));
76
+ }
77
+ .mg-popover[data-popper-placement^=left] > .mg-popover__arrow:before {
78
+ border-left: 1rem solid hsl(var(--mg-popover-background-color));
53
79
  }
54
80
  .mg-popover[data-popper-placement^=right] > .mg-popover__arrow {
55
- left: -6px;
81
+ left: 0.1rem;
82
+ filter: drop-shadow(-0.5rem 0 0.25rem hsl(var(--color-dark), 0.15));
83
+ }
84
+ .mg-popover[data-popper-placement^=right] > .mg-popover__arrow:before {
85
+ border-right: 1rem solid hsl(var(--mg-popover-background-color));
86
+ }
87
+ .mg-popover[data-popper-placement^=left-start], .mg-popover[data-popper-placement^=left-end], .mg-popover[data-popper-placement^=right-start], .mg-popover[data-popper-placement^=right-end] {
88
+ padding: 0 1rem;
89
+ }
90
+ .mg-popover[data-popper-placement^=left-start] > .mg-popover__arrow, .mg-popover[data-popper-placement^=left-end] > .mg-popover__arrow, .mg-popover[data-popper-placement^=right-start] > .mg-popover__arrow, .mg-popover[data-popper-placement^=right-end] > .mg-popover__arrow {
91
+ height: calc(3rem + 2 * var(--mg-card-border-radius));
92
+ }
93
+ .mg-popover[data-popper-placement^=left-start] > .mg-popover__arrow:before, .mg-popover[data-popper-placement^=left-end] > .mg-popover__arrow:before, .mg-popover[data-popper-placement^=right-start] > .mg-popover__arrow:before, .mg-popover[data-popper-placement^=right-end] > .mg-popover__arrow:before {
94
+ top: var(--mg-card-border-radius);
56
95
  }
57
96
  .mg-popover__title ::slotted([slot=title]) {
58
97
  margin: 0 0 1rem !important;
59
98
  font-size: var(--mg-popover-title-font-size) !important;
60
99
  font-weight: 600;
100
+ }
101
+ .mg-popover--arrow-hide.mg-popover[data-popper-placement^=top] {
102
+ padding-bottom: 0;
103
+ }
104
+ .mg-popover--arrow-hide.mg-popover[data-popper-placement^=bottom] {
105
+ padding-top: 0;
106
+ }
107
+ .mg-popover--arrow-hide.mg-popover[data-popper-placement$=end], .mg-popover--arrow-hide.mg-popover[data-popper-placement^=left] {
108
+ padding-right: 0;
109
+ }
110
+ .mg-popover--arrow-hide.mg-popover[data-popper-placement$=start], .mg-popover--arrow-hide.mg-popover[data-popper-placement^=right] {
111
+ padding-left: 0;
112
+ }
113
+ .mg-popover ::slotted(*) {
114
+ --mg-card-border: var(--mg-card-border-default);
115
+ --mg-card-padding: var(--mg-card-padding-default);
116
+ --mg-card-border-radius: var(--mg-card-border-radius-default);
117
+ --mg-card-background: var(--mg-card-background-default);
118
+ --mg-card-box-shadow: var(--mg-card-box-shadow-default);
61
119
  }