@mgdis/mg-components 5.1.0 → 5.3.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 (108) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/{mg-badge_27.cjs.entry.js → mg-badge_29.cjs.entry.js} +730 -242
  3. package/dist/cjs/mg-components.cjs.js +1 -1
  4. package/dist/collection/collection-manifest.json +3 -1
  5. package/dist/collection/components/atoms/mg-badge/mg-badge.js +14 -19
  6. package/dist/collection/components/atoms/mg-button/mg-button.js +3 -3
  7. package/dist/collection/components/atoms/mg-icon/mg-icon.js +17 -7
  8. package/dist/collection/components/atoms/mg-tag/mg-tag.js +1 -1
  9. package/dist/collection/components/molecules/inputs/MgInput.js +3 -11
  10. package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.js +41 -20
  11. package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.js +50 -39
  12. package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.css +25 -6
  13. package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.js +42 -33
  14. package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.css +25 -6
  15. package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.js +36 -17
  16. package/dist/collection/components/molecules/inputs/mg-input-radio/mg-input-radio.js +35 -14
  17. package/dist/collection/components/molecules/inputs/mg-input-select/doc/mg-input-select.stories.js +2 -3
  18. package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.css +28 -6
  19. package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.js +36 -17
  20. package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.css +25 -6
  21. package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.js +38 -19
  22. package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.css +25 -6
  23. package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.js +37 -18
  24. package/dist/collection/components/molecules/inputs/mg-input-toggle/mg-input-toggle.js +1 -1
  25. package/dist/collection/components/molecules/menu/mg-menu/doc/mg-menu.stories.js +87 -0
  26. package/dist/collection/components/molecules/menu/mg-menu/mg-menu.conf.js +8 -0
  27. package/dist/collection/components/molecules/menu/mg-menu/mg-menu.css +10 -0
  28. package/dist/collection/components/molecules/menu/mg-menu/mg-menu.js +185 -0
  29. package/dist/collection/components/molecules/menu/mg-menu-item/doc/mg-menu-item.stories.js +32 -0
  30. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.conf.js +22 -0
  31. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.css +316 -0
  32. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.js +324 -0
  33. package/dist/collection/components/molecules/mg-form/mg-form.js +73 -27
  34. package/dist/collection/components/molecules/mg-illustrated-message/doc/mg-illustrated-message.stories.js +6 -6
  35. package/dist/collection/components/molecules/mg-message/mg-message.js +1 -1
  36. package/dist/collection/components/molecules/mg-modal/mg-modal.js +0 -4
  37. package/dist/collection/components/molecules/mg-tabs/mg-tabs.conf.js +3 -0
  38. package/dist/collection/components/molecules/mg-tabs/mg-tabs.css +67 -17
  39. package/dist/collection/components/molecules/mg-tabs/mg-tabs.js +10 -4
  40. package/dist/collection/locales/index.js +3 -1
  41. package/dist/collection/utils/unit.test.utils.js +51 -0
  42. package/dist/collection/variables.css +29 -7
  43. package/dist/components/MgInput.js +4 -12
  44. package/dist/components/index.d.ts +2 -0
  45. package/dist/components/index.js +2 -0
  46. package/dist/components/index2.js +3 -1
  47. package/dist/components/mg-badge2.js +1 -1
  48. package/dist/components/mg-button2.js +3 -3
  49. package/dist/components/mg-form.js +67 -26
  50. package/dist/components/mg-input-checkbox.js +36 -21
  51. package/dist/components/mg-input-date.js +44 -39
  52. package/dist/components/mg-input-numeric.js +37 -34
  53. package/dist/components/mg-input-password.js +32 -19
  54. package/dist/components/mg-input-radio.js +30 -15
  55. package/dist/components/mg-input-select2.js +32 -19
  56. package/dist/components/mg-input-text2.js +34 -21
  57. package/dist/components/mg-input-textarea.js +32 -19
  58. package/dist/components/mg-input-toggle.js +1 -1
  59. package/dist/components/mg-menu-item.d.ts +11 -0
  60. package/dist/components/mg-menu-item.js +273 -0
  61. package/dist/components/mg-menu.conf.js +10 -0
  62. package/dist/components/mg-menu.d.ts +11 -0
  63. package/dist/components/mg-menu.js +149 -0
  64. package/dist/components/mg-message.js +1 -1
  65. package/dist/components/mg-modal.js +0 -4
  66. package/dist/components/mg-tabs.js +6 -2
  67. package/dist/components/mg-tag.js +1 -1
  68. package/dist/esm/loader.js +1 -1
  69. package/dist/esm/{mg-badge_27.entry.js → mg-badge_29.entry.js} +729 -243
  70. package/dist/esm/mg-components.js +1 -1
  71. package/dist/mg-components/mg-components.css +1 -1
  72. package/dist/mg-components/mg-components.esm.js +1 -1
  73. package/dist/mg-components/p-204af46f.entry.js +1 -0
  74. package/dist/mg-components/variables.css +29 -7
  75. package/dist/types/components/atoms/mg-badge/doc/mg-badge.stories.d.ts +2 -2
  76. package/dist/types/components/atoms/mg-badge/mg-badge.conf.d.ts +5 -5
  77. package/dist/types/components/atoms/mg-badge/mg-badge.d.ts +8 -8
  78. package/dist/types/components/atoms/mg-button/mg-button.d.ts +2 -2
  79. package/dist/types/components/atoms/mg-icon/doc/mg-icon.stories.d.ts +2 -2
  80. package/dist/types/components/atoms/mg-icon/mg-icon.conf.d.ts +10 -2
  81. package/dist/types/components/atoms/mg-icon/mg-icon.d.ts +7 -6
  82. package/dist/types/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.d.ts +10 -8
  83. package/dist/types/components/molecules/inputs/mg-input-date/mg-input-date.d.ts +3 -8
  84. package/dist/types/components/molecules/inputs/mg-input-numeric/mg-input-numeric.d.ts +3 -8
  85. package/dist/types/components/molecules/inputs/mg-input-password/mg-input-password.d.ts +4 -3
  86. package/dist/types/components/molecules/inputs/mg-input-radio/mg-input-radio.d.ts +4 -2
  87. package/dist/types/components/molecules/inputs/mg-input-select/mg-input-select.d.ts +4 -3
  88. package/dist/types/components/molecules/inputs/mg-input-text/mg-input-text.d.ts +5 -4
  89. package/dist/types/components/molecules/inputs/mg-input-textarea/mg-input-textarea.d.ts +4 -3
  90. package/dist/types/components/molecules/menu/mg-menu/doc/mg-menu.stories.d.ts +17 -0
  91. package/dist/types/components/molecules/menu/mg-menu/mg-menu.conf.d.ts +7 -0
  92. package/dist/types/components/molecules/menu/mg-menu/mg-menu.d.ts +69 -0
  93. package/dist/types/components/molecules/menu/mg-menu-item/doc/mg-menu-item.stories.d.ts +11 -0
  94. package/dist/types/components/molecules/menu/mg-menu-item/mg-menu-item.conf.d.ts +24 -0
  95. package/dist/types/components/molecules/menu/mg-menu-item/mg-menu-item.d.ts +119 -0
  96. package/dist/types/components/molecules/mg-form/mg-form.d.ts +21 -1
  97. package/dist/types/components/molecules/mg-message/mg-message.d.ts +3 -0
  98. package/dist/types/components/molecules/mg-modal/mg-modal.d.ts +3 -0
  99. package/dist/types/components/molecules/mg-tabs/doc/mg-tabs.stories.d.ts +1 -1
  100. package/dist/types/components/molecules/mg-tabs/mg-tabs.conf.d.ts +12 -4
  101. package/dist/types/components/molecules/mg-tabs/mg-tabs.d.ts +6 -6
  102. package/dist/types/components.d.ts +91 -14
  103. package/dist/types/locales/index.d.ts +7 -1
  104. package/dist/types/stories/icons.stories.d.ts +1 -1
  105. package/package.json +7 -8
  106. package/dist/collection/utils/test.utils.js +0 -38
  107. package/dist/mg-components/p-e131701a.entry.js +0 -1
  108. package/dist/types/utils/test.utils.d.ts +0 -17
@@ -7,12 +7,12 @@ export class MgInputText {
7
7
  /************
8
8
  * Internal *
9
9
  ************/
10
- // classes
10
+ // Classes
11
11
  this.classFocus = 'is-focused';
12
12
  this.classIsInputGroupAppend = 'mg-input--is-input-group-append';
13
13
  this.classHasIcon = 'mg-input--has-icon';
14
- // hasError (triggered by blur event)
15
- this.hasError = false;
14
+ // hasDisplayedError (triggered by blur event)
15
+ this.hasDisplayedError = false;
16
16
  /**
17
17
  * Input name
18
18
  * If not set the value equals the identifier
@@ -61,8 +61,8 @@ export class MgInputText {
61
61
  */
62
62
  this.handleInput = () => {
63
63
  this.checkValidity();
64
- if (this.hasError) {
65
- this.checkError();
64
+ if (this.hasDisplayedError) {
65
+ this.setErrorMessage();
66
66
  }
67
67
  this.value = this.input.value;
68
68
  };
@@ -93,21 +93,18 @@ export class MgInputText {
93
93
  * @returns {void}
94
94
  */
95
95
  this.checkValidity = () => {
96
- if (!this.readonly && this.input !== undefined) {
97
- const validity = this.input.checkValidity();
98
- // Set validity
99
- this.valid = validity;
100
- this.invalid = !validity;
101
- //Send event
102
- this.inputValid.emit(validity);
103
- }
96
+ var _a;
97
+ this.valid = this.readonly || this.disabled || (((_a = this.input) === null || _a === void 0 ? void 0 : _a.checkValidity) !== undefined ? this.input.checkValidity() : true);
98
+ this.invalid = !this.valid;
99
+ // We need to send valid event even if it is the same value
100
+ this.inputValid.emit(this.valid);
104
101
  };
105
102
  /**
106
- * Check input errors
103
+ * Set input error message
107
104
  *
108
105
  * @returns {void}
109
106
  */
110
- this.checkError = () => {
107
+ this.setErrorMessage = () => {
111
108
  // Set error message
112
109
  this.errorMessage = undefined;
113
110
  // Does not match pattern
@@ -120,7 +117,7 @@ export class MgInputText {
120
117
  }
121
118
  };
122
119
  /**
123
- * Validate patern configuration
120
+ * Validate pattern configuration
124
121
  *
125
122
  * @returns {void}
126
123
  */
@@ -159,6 +156,16 @@ export class MgInputText {
159
156
  this.classList.delete(this.classHasIcon);
160
157
  }
161
158
  }
159
+ handleValidityChange(newValue, _oldValue, prop) {
160
+ if (this.input !== undefined) {
161
+ this.input[prop] = newValue;
162
+ this.checkValidity();
163
+ if (this.hasDisplayedError) {
164
+ this.setErrorMessage();
165
+ this.hasDisplayedError = false;
166
+ }
167
+ }
168
+ }
162
169
  /**
163
170
  * Public method to play input focus
164
171
  *
@@ -174,8 +181,8 @@ export class MgInputText {
174
181
  */
175
182
  async displayError() {
176
183
  this.checkValidity();
177
- this.checkError();
178
- this.hasError = this.invalid;
184
+ this.setErrorMessage();
185
+ this.hasDisplayedError = this.invalid;
179
186
  }
180
187
  /*************
181
188
  * Lifecycle *
@@ -210,7 +217,10 @@ export class MgInputText {
210
217
  '--mg-character-left-message-length': (this.displayCharacterLeft
211
218
  ? (this.maxlength - (this.value || '').length).toString().length + this.maxlength.toString().length + 1
212
219
  : 0).toString(),
213
- } }, this.icon !== undefined && h("mg-icon", { icon: this.icon }), h("input", { type: this.type, class: "mg-input__box", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, maxlength: this.maxlength, disabled: this.disabled, required: this.required, pattern: this.pattern, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: el => (this.input = el) }), this.displayCharacterLeft && this.maxlength > 0 && (h("mg-character-left", { identifier: this.characterLeftId, characters: this.value, maxlength: this.maxlength }))), h("slot", { name: "append-input" })));
220
+ } }, this.icon !== undefined && h("mg-icon", { icon: this.icon }), h("input", { type: this.type, class: "mg-input__box", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, maxlength: this.maxlength, disabled: this.disabled, required: this.required, pattern: this.pattern, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: el => {
221
+ if (el !== null)
222
+ this.input = el;
223
+ } }), this.displayCharacterLeft && this.maxlength > 0 && (h("mg-character-left", { identifier: this.characterLeftId, characters: this.value, maxlength: this.maxlength }))), h("slot", { name: "append-input" })));
214
224
  }
215
225
  static get is() { return "mg-input-text"; }
216
226
  static get encapsulation() { return "shadow"; }
@@ -688,6 +698,15 @@ export class MgInputText {
688
698
  }, {
689
699
  "propName": "icon",
690
700
  "methodName": "validateIcon"
701
+ }, {
702
+ "propName": "required",
703
+ "methodName": "handleValidityChange"
704
+ }, {
705
+ "propName": "readonly",
706
+ "methodName": "handleValidityChange"
707
+ }, {
708
+ "propName": "disabled",
709
+ "methodName": "handleValidityChange"
691
710
  }];
692
711
  }
693
712
  }
@@ -185,21 +185,40 @@
185
185
  .mg-input.mg-input--width-full:not(.mg-input--label-on-top) {
186
186
  justify-content: space-between;
187
187
  }
188
+ .mg-input.mg-input--width-full.mg-input--label-on-top .mg-input__box {
189
+ width: 100%;
190
+ }
188
191
  .mg-input.mg-input--width-full .mg-input__input-container {
189
192
  flex: auto;
190
193
  width: 100%;
191
194
  }
192
195
  .mg-input.mg-input--width-full .mg-input__input-container .mg-input__box {
196
+ max-width: 100%;
197
+ }
198
+ .mg-input:not(.mg-input--label-on-top) .mg-input__box {
199
+ width: 100%;
200
+ max-width: calc(17.7rem + var(--mg-inputs-spacer) * 2);
201
+ min-width: 5rem;
202
+ }
203
+ .mg-input.mg-input--width-16 .mg-input__input-container {
204
+ width: 100%;
205
+ }
206
+ .mg-input.mg-input--width-16 .mg-input__input-container .mg-input__input {
207
+ width: 100%;
208
+ max-width: 21rem;
209
+ }
210
+ .mg-input.mg-input--width-16 .mg-input__input-container .mg-input__with-character-left {
193
211
  width: 100%;
194
212
  }
195
- .mg-input.mg-input--width-16 .mg-input__box {
196
- width: 21rem;
213
+ .mg-input.mg-input--width-16 .mg-input__input-container .mg-input__box {
214
+ max-width: 21rem;
215
+ min-width: 100%;
197
216
  }
198
- .mg-input.mg-input--width-4 .mg-input__box {
199
- width: 7rem;
217
+ .mg-input.mg-input--width-4 .mg-input__input-container .mg-input__box {
218
+ max-width: 7rem;
200
219
  }
201
- .mg-input.mg-input--width-2 .mg-input__box {
202
- width: 5rem;
220
+ .mg-input.mg-input--width-2 .mg-input__input-container .mg-input__box {
221
+ max-width: 5rem;
203
222
  }
204
223
 
205
224
  /**
@@ -7,11 +7,11 @@ export class MgInputTextarea {
7
7
  /************
8
8
  * Internal *
9
9
  ************/
10
- // classes
10
+ // Classes
11
11
  this.classFocus = 'is-focused';
12
12
  this.classHasDisplayCharacterLeft = 'mg-input--has-display-character-left';
13
- // hasError (triggered by blur event)
14
- this.hasError = false;
13
+ // hasDisplayedError (triggered by blur event)
14
+ this.hasDisplayedError = false;
15
15
  /**
16
16
  * Input name
17
17
  * If not set the value equals the identifier
@@ -61,9 +61,9 @@ export class MgInputTextarea {
61
61
  * Handle input event
62
62
  */
63
63
  this.handleInput = () => {
64
- if (this.hasError) {
64
+ if (this.hasDisplayedError) {
65
65
  this.checkValidity();
66
- this.checkError();
66
+ this.setErrorMessage();
67
67
  }
68
68
  this.value = this.input.value;
69
69
  };
@@ -95,19 +95,16 @@ export class MgInputTextarea {
95
95
  * Check if input is valid
96
96
  */
97
97
  this.checkValidity = () => {
98
- if (!this.readonly && this.input !== undefined) {
99
- const validity = this.input.checkValidity && this.input.checkValidity() && this.getPatternValidity();
100
- // Set validity
101
- this.valid = validity;
102
- this.invalid = !validity;
103
- //Send event
104
- this.inputValid.emit(validity);
105
- }
98
+ var _a;
99
+ this.valid = this.readonly || this.disabled || (((_a = this.input) === null || _a === void 0 ? void 0 : _a.checkValidity) !== undefined && this.input.checkValidity() && this.getPatternValidity());
100
+ this.invalid = !this.valid;
101
+ // We need to send valid event even if it is the same value
102
+ this.inputValid.emit(this.valid);
106
103
  };
107
104
  /**
108
- * Check input errors
105
+ * Set input error message
109
106
  */
110
- this.checkError = () => {
107
+ this.setErrorMessage = () => {
111
108
  // Set error message
112
109
  this.errorMessage = undefined;
113
110
  // Does not match pattern
@@ -135,6 +132,16 @@ export class MgInputTextarea {
135
132
  this.checkValidity();
136
133
  this.valueChange.emit(newValue);
137
134
  }
135
+ handleValidityChange(newValue, _oldValue, prop) {
136
+ if (this.input !== undefined) {
137
+ this.input[prop] = newValue;
138
+ this.checkValidity();
139
+ if (this.hasDisplayedError) {
140
+ this.setErrorMessage();
141
+ this.hasDisplayedError = false;
142
+ }
143
+ }
144
+ }
138
145
  validateDisplayCharacterLeft(newValue) {
139
146
  if (newValue) {
140
147
  this.classList.add(this.classHasDisplayCharacterLeft);
@@ -150,8 +157,8 @@ export class MgInputTextarea {
150
157
  */
151
158
  async displayError() {
152
159
  this.checkValidity();
153
- this.checkError();
154
- this.hasError = this.invalid;
160
+ this.setErrorMessage();
161
+ this.hasDisplayedError = this.invalid;
155
162
  }
156
163
  /*************
157
164
  * Lifecycle *
@@ -186,7 +193,10 @@ export class MgInputTextarea {
186
193
  'mg-input__box--resizable': this.resizable === 'both',
187
194
  'mg-input__box--resizable-horizontal': this.resizable === 'horizontal',
188
195
  'mg-input__box--resizable-vertical': this.resizable === 'vertical',
189
- }, value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, rows: this.rows, maxlength: this.maxlength, disabled: this.disabled, required: this.required, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: el => (this.input = el) }), this.displayCharacterLeft && this.maxlength > 0 && (h("mg-character-left", { identifier: this.characterLeftId, characters: this.value, maxlength: this.maxlength })))));
196
+ }, value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, rows: this.rows, maxlength: this.maxlength, disabled: this.disabled, required: this.required, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: el => {
197
+ if (el !== null)
198
+ this.input = el;
199
+ } }), this.displayCharacterLeft && this.maxlength > 0 && (h("mg-character-left", { identifier: this.characterLeftId, characters: this.value, maxlength: this.maxlength })))));
190
200
  }
191
201
  static get is() { return "mg-input-textarea"; }
192
202
  static get encapsulation() { return "shadow"; }
@@ -643,6 +653,15 @@ export class MgInputTextarea {
643
653
  return [{
644
654
  "propName": "value",
645
655
  "methodName": "handleValue"
656
+ }, {
657
+ "propName": "required",
658
+ "methodName": "handleValidityChange"
659
+ }, {
660
+ "propName": "readonly",
661
+ "methodName": "handleValidityChange"
662
+ }, {
663
+ "propName": "disabled",
664
+ "methodName": "handleValidityChange"
646
665
  }, {
647
666
  "propName": "displayCharacterLeft",
648
667
  "methodName": "validateDisplayCharacterLeft"
@@ -15,7 +15,7 @@ export class MgInputToggle {
15
15
  /************
16
16
  * Internal *
17
17
  ************/
18
- // classes
18
+ // Classes
19
19
  this.classReadonly = 'mg-input--toggle-readonly';
20
20
  this.classDisabled = 'mg-input--toggle-disabled';
21
21
  this.classIsActive = 'mg-input--toggle-is-active';
@@ -0,0 +1,87 @@
1
+ import { h } from '@stencil/core';
2
+ import { filterArgs } from '../../../../../../.storybook/utils';
3
+ import { Status } from '../../mg-menu-item/mg-menu-item.conf';
4
+ import { Direction } from '../mg-menu.conf';
5
+ export default {
6
+ component: 'mg-menu',
7
+ title: 'Beta/menus/mg-menu',
8
+ argTypes: {
9
+ direction: {
10
+ options: [undefined, Direction.HORIZONTAL, Direction.VERTICAL],
11
+ control: { type: 'select' },
12
+ },
13
+ },
14
+ };
15
+ const getItemArgs = ({ size, label, direction, status, metadata, icon, badge, content, submenu }) => ({
16
+ size: size !== undefined ? size : direction === Direction.VERTICAL ? 'medium' : undefined,
17
+ status,
18
+ slot: {
19
+ label,
20
+ metadata,
21
+ icon,
22
+ badge,
23
+ content,
24
+ submenu,
25
+ },
26
+ });
27
+ const getMenuArgs = (direction, level = 0, isSubmenu = false) => ({
28
+ label: 'Batman menu',
29
+ direction,
30
+ slot: {
31
+ items: [
32
+ getItemArgs({
33
+ label: 'label 1',
34
+ direction,
35
+ }),
36
+ getItemArgs({
37
+ label: 'label 2',
38
+ direction,
39
+ status: Status.DISABLED,
40
+ }),
41
+ getItemArgs({
42
+ label: 'label 3 with long text',
43
+ direction,
44
+ badge: true,
45
+ icon: true,
46
+ }),
47
+ getItemArgs({
48
+ label: 'label 4',
49
+ direction,
50
+ badge: true,
51
+ icon: true,
52
+ status: Status.ACTIVE,
53
+ submenu: level,
54
+ }),
55
+ getItemArgs({
56
+ label: 'label 5',
57
+ direction,
58
+ icon: true,
59
+ metadata: 'my metadata',
60
+ content: true,
61
+ size: !isSubmenu && direction === Direction.HORIZONTAL ? 'regular' : undefined,
62
+ }),
63
+ ],
64
+ },
65
+ });
66
+ const menu = args => h("mg-menu", Object.assign({}, filterArgs(args, { direction: Direction.HORIZONTAL })), args.slot.items.map(item => menuItem(item)));
67
+ const menuItem = args => {
68
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
69
+ return (h("mg-menu-item", Object.assign({}, filterArgs(args)), ((_a = args.slot) === null || _a === void 0 ? void 0 : _a.label) && h("span", { slot: "label" }, (_b = args.slot) === null || _b === void 0 ? void 0 : _b.label), ((_c = args.slot) === null || _c === void 0 ? void 0 : _c.metadata) && h("span", { slot: "metadata" }, (_d = args.slot) === null || _d === void 0 ? void 0 : _d.metadata), ((_e = args.slot) === null || _e === void 0 ? void 0 : _e.icon) && h("mg-icon", { slot: "illustration", icon: "user" }), ((_f = args.slot) === null || _f === void 0 ? void 0 : _f.badge) && (h("mg-badge", { slot: "information", label: "information", value: "1" }, (_g = args.slot) === null || _g === void 0 ? void 0 : _g.icon)), ((_h = args.slot) === null || _h === void 0 ? void 0 : _h.content) && (h("div", null, h("h3", null, "Demo title"), h("p", null, "some content"))), ((_j = args.slot) === null || _j === void 0 ? void 0 : _j.submenu) && menu(getMenuArgs(Direction.VERTICAL, ((_k = args.slot) === null || _k === void 0 ? void 0 : _k.submenu) - 1, true))));
70
+ };
71
+ /**
72
+ * Template
73
+ *
74
+ * @param {any} args component arguments
75
+ * @returns {HTMLElement} HTMLElement
76
+ */
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ const Template = (args) => h("div", null, menu(args));
79
+ export const MgMenuHorizontal = Template.bind({});
80
+ MgMenuHorizontal.args = getMenuArgs(Direction.HORIZONTAL, 2);
81
+ export const MgMenuVertical = Template.bind({});
82
+ MgMenuVertical.args = getMenuArgs(Direction.VERTICAL, 2);
83
+ const TemplateSmallContainer = (args) => {
84
+ return h("div", { style: { width: '25rem', height: '20rem' } }, menu(args));
85
+ };
86
+ export const MgMenuVerticalSmallContainer = TemplateSmallContainer.bind({});
87
+ MgMenuVerticalSmallContainer.args = Object.assign({}, MgMenuVertical.args);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Menu direction type
3
+ */
4
+ export var Direction;
5
+ (function (Direction) {
6
+ Direction["VERTICAL"] = "vertical";
7
+ Direction["HORIZONTAL"] = "horizontal";
8
+ })(Direction || (Direction = {}));
@@ -0,0 +1,10 @@
1
+ :host {
2
+ display: flex;
3
+ background-color: hsl(var(--mg-menu-background-color-hsl, var(--color-light)));
4
+ }
5
+
6
+ :host(.mg-menu--vertical) {
7
+ flex-direction: column;
8
+ height: 100%;
9
+ overflow-y: auto;
10
+ }
@@ -0,0 +1,185 @@
1
+ import { h, Host } from '@stencil/core';
2
+ import { ClassList } from '../../../../utils/components.utils';
3
+ import { Direction } from './mg-menu.conf';
4
+ export class MgMenu {
5
+ constructor() {
6
+ /************
7
+ * Internal *
8
+ ************/
9
+ this.name = 'mg-menu';
10
+ this.focusedMenuItem = 0;
11
+ /**
12
+ * Component display direction. Default: "horizontal"
13
+ */
14
+ this.direction = Direction.HORIZONTAL;
15
+ /**
16
+ * Component classes
17
+ */
18
+ this.classList = new ClassList([this.name]);
19
+ /**
20
+ * Close matching menu-item
21
+ *
22
+ * @param {HTMLMgMenuItemElement} item menu-item to close
23
+ * @param {boolean} condition addionnal condition
24
+ * @returns {void}
25
+ */
26
+ this.closeMenuItem = (item, condition) => {
27
+ if (!this.isChildMenu && condition) {
28
+ item.expanded = false;
29
+ }
30
+ };
31
+ /**
32
+ * Store menu-items on component init and add listeners
33
+ */
34
+ this.initMenuItems = () => {
35
+ // store all menu-items
36
+ this.menuItems = Array.from(this.element.children).filter(child => child.nodeName === 'MG-MENU-ITEM');
37
+ // add listeners on menu item and edit index
38
+ this.menuItems.forEach((item, menuItemIndex) => {
39
+ ['click', 'focus'].forEach(trigger => {
40
+ (item.shadowRoot.querySelector('button') || item.shadowRoot.querySelector('a')).addEventListener(trigger, (event) => {
41
+ event.preventDefault();
42
+ event.stopPropagation();
43
+ this.focusedMenuItem = menuItemIndex;
44
+ // reset expanded on previous active menu item
45
+ this.menuItems.forEach((item, index) => {
46
+ this.closeMenuItem(item, index !== this.focusedMenuItem);
47
+ });
48
+ });
49
+ });
50
+ });
51
+ };
52
+ }
53
+ validateLabel(newValue) {
54
+ if (newValue === undefined) {
55
+ throw new Error(`<${this.name}> prop "label" is required.`);
56
+ }
57
+ }
58
+ validateDirection(newValue) {
59
+ if (newValue === Direction.VERTICAL) {
60
+ this.classList.add(`${this.name}--${Direction.VERTICAL}`);
61
+ }
62
+ else if (newValue === Direction.HORIZONTAL) {
63
+ this.classList.add(`${this.name}--${Direction.HORIZONTAL}`);
64
+ }
65
+ else {
66
+ throw new Error(`<${this.name}> prop "direction" must be one of : ${Direction.HORIZONTAL}, ${Direction.VERTICAL}.`);
67
+ }
68
+ }
69
+ /*************
70
+ * Lifecycle *
71
+ *************/
72
+ /**
73
+ * Validate props
74
+ *
75
+ * @returns {void}
76
+ */
77
+ componentWillLoad() {
78
+ this.validateDirection(this.direction);
79
+ this.validateLabel(this.label);
80
+ }
81
+ /**
82
+ * Check if component slots configuration
83
+ *
84
+ * @returns {ReturnType<typeof setTimeout>} timeout
85
+ */
86
+ componentDidLoad() {
87
+ this.initMenuItems();
88
+ // update props and states after componentDidLoad hook
89
+ // return a promise to process action only in the FIRST render().
90
+ // https://stenciljs.com/docs/component-lifecycle#componentwillload
91
+ return setTimeout(() => {
92
+ this.isChildMenu = this.element.closest('mg-menu-item') !== null;
93
+ // click outside management for child vertical menu
94
+ if (!this.isChildMenu && this.direction === Direction.HORIZONTAL) {
95
+ document.addEventListener('click', (event) => {
96
+ if (event.target.closest('mg-menu') === null) {
97
+ this.menuItems.forEach(item => {
98
+ this.closeMenuItem(item, this.direction === Direction.HORIZONTAL);
99
+ });
100
+ }
101
+ });
102
+ }
103
+ }, 0);
104
+ }
105
+ /**
106
+ * Render
107
+ *
108
+ * @returns {HTMLElement} HTML Element
109
+ */
110
+ render() {
111
+ return (h(Host, { role: this.isChildMenu ? 'menu' : 'menubar', "aria-label": this.label, classList: this.classList.join() }, h("slot", null)));
112
+ }
113
+ static get is() { return "mg-menu"; }
114
+ static get encapsulation() { return "shadow"; }
115
+ static get originalStyleUrls() {
116
+ return {
117
+ "$": ["mg-menu.scss"]
118
+ };
119
+ }
120
+ static get styleUrls() {
121
+ return {
122
+ "$": ["mg-menu.css"]
123
+ };
124
+ }
125
+ static get properties() {
126
+ return {
127
+ "label": {
128
+ "type": "string",
129
+ "mutable": false,
130
+ "complexType": {
131
+ "original": "string",
132
+ "resolved": "string",
133
+ "references": {}
134
+ },
135
+ "required": true,
136
+ "optional": false,
137
+ "docs": {
138
+ "tags": [],
139
+ "text": "Menu label. Include short menu description.\nRequired for accessibility"
140
+ },
141
+ "attribute": "label",
142
+ "reflect": false
143
+ },
144
+ "direction": {
145
+ "type": "string",
146
+ "mutable": false,
147
+ "complexType": {
148
+ "original": "Direction",
149
+ "resolved": "Direction.HORIZONTAL | Direction.VERTICAL",
150
+ "references": {
151
+ "Direction": {
152
+ "location": "import",
153
+ "path": "./mg-menu.conf"
154
+ }
155
+ }
156
+ },
157
+ "required": false,
158
+ "optional": false,
159
+ "docs": {
160
+ "tags": [],
161
+ "text": "Component display direction. Default: \"horizontal\""
162
+ },
163
+ "attribute": "direction",
164
+ "reflect": true,
165
+ "defaultValue": "Direction.HORIZONTAL"
166
+ }
167
+ };
168
+ }
169
+ static get states() {
170
+ return {
171
+ "isChildMenu": {},
172
+ "classList": {}
173
+ };
174
+ }
175
+ static get elementRef() { return "element"; }
176
+ static get watchers() {
177
+ return [{
178
+ "propName": "label",
179
+ "methodName": "validateLabel"
180
+ }, {
181
+ "propName": "direction",
182
+ "methodName": "validateDirection"
183
+ }];
184
+ }
185
+ }
@@ -0,0 +1,32 @@
1
+ import { h } from '@stencil/core';
2
+ import { filterArgs } from '../../../../../../.storybook/utils';
3
+ export default {
4
+ component: 'mg-menu-item',
5
+ title: 'Beta/menus/mg-menu-item',
6
+ };
7
+ /**
8
+ * Template
9
+ *
10
+ * @param {any} args component arguments
11
+ * @returns {HTMLElement} HTMLElement
12
+ */
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ const Template = (args) => h("mg-menu-item", Object.assign({}, filterArgs(args)), args.slot);
15
+ export const MgMenuItem = Template.bind({});
16
+ MgMenuItem.args = {
17
+ identifier: 'identifier',
18
+ slot: h("span", { slot: "label" }, "My label"),
19
+ };
20
+ export const MgMenuItemWhitIcon = Template.bind({});
21
+ MgMenuItemWhitIcon.args = Object.assign(Object.assign({}, MgMenuItem.args), { slot: [h("span", { slot: "label" }, "My label"), h("mg-icon", { icon: "user", slot: "illustration" })] });
22
+ export const MgMenuItemWhitBadge = Template.bind({});
23
+ MgMenuItemWhitBadge.args = Object.assign(Object.assign({}, MgMenuItem.args), { slot: [h("span", { slot: "label" }, "My label"), h("mg-badge", { value: "2", label: "hello", slot: "information" })] });
24
+ export const MgMenuItemWhitBadgeAndIcon = Template.bind({});
25
+ MgMenuItemWhitBadgeAndIcon.args = Object.assign(Object.assign({}, MgMenuItem.args), { slot: [h("span", { slot: "label" }, "My label"), h("mg-badge", { value: "2", label: "hello", slot: "information" }), h("mg-icon", { icon: "user", slot: "illustration" })] });
26
+ export const MgMenuItemWhitMetadata = Template.bind({});
27
+ MgMenuItemWhitMetadata.args = Object.assign(Object.assign({}, MgMenuItem.args), { slot: [h("span", { slot: "label" }, "My label"), h("span", { slot: "metadata" }, "My metadata")] });
28
+ export const MgMenuItemWhithSubmenu = Template.bind({});
29
+ MgMenuItemWhithSubmenu.args = Object.assign(Object.assign({}, MgMenuItem.args), { slot: [
30
+ h("span", { slot: "label" }, "My label"),
31
+ h("mg-menu-vertical", { label: "submenu" }, h("mg-menu-item", null, h("span", { slot: "label" }, "Subitem 1")), h("mg-menu-item", null, h("mg-icon", { icon: "user", slot: "illustration" }), h("span", { slot: "label" }, "Subitem 2")), h("mg-menu-item", null, h("span", { slot: "label" }, "Subitem 3"), h("mg-icon", { icon: "user", slot: "illustration" }), h("mg-badge", { value: "2", label: "hello", slot: "information" }))),
32
+ ] });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Available menu-item positions
3
+ */
4
+ export var ElementPosition;
5
+ (function (ElementPosition) {
6
+ ElementPosition["FIRST"] = "first";
7
+ ElementPosition["LAST"] = "last";
8
+ })(ElementPosition || (ElementPosition = {}));
9
+ /**
10
+ * Available menu item status
11
+ */
12
+ export var Status;
13
+ (function (Status) {
14
+ Status["VISIBLE"] = "visible";
15
+ Status["HIDDEN"] = "hidden";
16
+ Status["DISABLED"] = "disabled";
17
+ Status["ACTIVE"] = "active";
18
+ })(Status || (Status = {}));
19
+ /**
20
+ * List of all possibles sizes
21
+ */
22
+ export const sizes = ['regular', 'medium', 'large'];