@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.
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{mg-badge_27.cjs.entry.js → mg-badge_29.cjs.entry.js} +730 -242
- package/dist/cjs/mg-components.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +3 -1
- package/dist/collection/components/atoms/mg-badge/mg-badge.js +14 -19
- package/dist/collection/components/atoms/mg-button/mg-button.js +3 -3
- package/dist/collection/components/atoms/mg-icon/mg-icon.js +17 -7
- package/dist/collection/components/atoms/mg-tag/mg-tag.js +1 -1
- package/dist/collection/components/molecules/inputs/MgInput.js +3 -11
- package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.js +41 -20
- package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.js +50 -39
- package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.css +25 -6
- package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.js +42 -33
- package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.css +25 -6
- package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.js +36 -17
- package/dist/collection/components/molecules/inputs/mg-input-radio/mg-input-radio.js +35 -14
- package/dist/collection/components/molecules/inputs/mg-input-select/doc/mg-input-select.stories.js +2 -3
- package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.css +28 -6
- package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.js +36 -17
- package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.css +25 -6
- package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.js +38 -19
- package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.css +25 -6
- package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.js +37 -18
- package/dist/collection/components/molecules/inputs/mg-input-toggle/mg-input-toggle.js +1 -1
- package/dist/collection/components/molecules/menu/mg-menu/doc/mg-menu.stories.js +87 -0
- package/dist/collection/components/molecules/menu/mg-menu/mg-menu.conf.js +8 -0
- package/dist/collection/components/molecules/menu/mg-menu/mg-menu.css +10 -0
- package/dist/collection/components/molecules/menu/mg-menu/mg-menu.js +185 -0
- package/dist/collection/components/molecules/menu/mg-menu-item/doc/mg-menu-item.stories.js +32 -0
- package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.conf.js +22 -0
- package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.css +316 -0
- package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.js +324 -0
- package/dist/collection/components/molecules/mg-form/mg-form.js +73 -27
- package/dist/collection/components/molecules/mg-illustrated-message/doc/mg-illustrated-message.stories.js +6 -6
- package/dist/collection/components/molecules/mg-message/mg-message.js +1 -1
- package/dist/collection/components/molecules/mg-modal/mg-modal.js +0 -4
- package/dist/collection/components/molecules/mg-tabs/mg-tabs.conf.js +3 -0
- package/dist/collection/components/molecules/mg-tabs/mg-tabs.css +67 -17
- package/dist/collection/components/molecules/mg-tabs/mg-tabs.js +10 -4
- package/dist/collection/locales/index.js +3 -1
- package/dist/collection/utils/unit.test.utils.js +51 -0
- package/dist/collection/variables.css +29 -7
- package/dist/components/MgInput.js +4 -12
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/components/index2.js +3 -1
- package/dist/components/mg-badge2.js +1 -1
- package/dist/components/mg-button2.js +3 -3
- package/dist/components/mg-form.js +67 -26
- package/dist/components/mg-input-checkbox.js +36 -21
- package/dist/components/mg-input-date.js +44 -39
- package/dist/components/mg-input-numeric.js +37 -34
- package/dist/components/mg-input-password.js +32 -19
- package/dist/components/mg-input-radio.js +30 -15
- package/dist/components/mg-input-select2.js +32 -19
- package/dist/components/mg-input-text2.js +34 -21
- package/dist/components/mg-input-textarea.js +32 -19
- package/dist/components/mg-input-toggle.js +1 -1
- package/dist/components/mg-menu-item.d.ts +11 -0
- package/dist/components/mg-menu-item.js +273 -0
- package/dist/components/mg-menu.conf.js +10 -0
- package/dist/components/mg-menu.d.ts +11 -0
- package/dist/components/mg-menu.js +149 -0
- package/dist/components/mg-message.js +1 -1
- package/dist/components/mg-modal.js +0 -4
- package/dist/components/mg-tabs.js +6 -2
- package/dist/components/mg-tag.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{mg-badge_27.entry.js → mg-badge_29.entry.js} +729 -243
- package/dist/esm/mg-components.js +1 -1
- package/dist/mg-components/mg-components.css +1 -1
- package/dist/mg-components/mg-components.esm.js +1 -1
- package/dist/mg-components/p-204af46f.entry.js +1 -0
- package/dist/mg-components/variables.css +29 -7
- package/dist/types/components/atoms/mg-badge/doc/mg-badge.stories.d.ts +2 -2
- package/dist/types/components/atoms/mg-badge/mg-badge.conf.d.ts +5 -5
- package/dist/types/components/atoms/mg-badge/mg-badge.d.ts +8 -8
- package/dist/types/components/atoms/mg-button/mg-button.d.ts +2 -2
- package/dist/types/components/atoms/mg-icon/doc/mg-icon.stories.d.ts +2 -2
- package/dist/types/components/atoms/mg-icon/mg-icon.conf.d.ts +10 -2
- package/dist/types/components/atoms/mg-icon/mg-icon.d.ts +7 -6
- package/dist/types/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.d.ts +10 -8
- package/dist/types/components/molecules/inputs/mg-input-date/mg-input-date.d.ts +3 -8
- package/dist/types/components/molecules/inputs/mg-input-numeric/mg-input-numeric.d.ts +3 -8
- package/dist/types/components/molecules/inputs/mg-input-password/mg-input-password.d.ts +4 -3
- package/dist/types/components/molecules/inputs/mg-input-radio/mg-input-radio.d.ts +4 -2
- package/dist/types/components/molecules/inputs/mg-input-select/mg-input-select.d.ts +4 -3
- package/dist/types/components/molecules/inputs/mg-input-text/mg-input-text.d.ts +5 -4
- package/dist/types/components/molecules/inputs/mg-input-textarea/mg-input-textarea.d.ts +4 -3
- package/dist/types/components/molecules/menu/mg-menu/doc/mg-menu.stories.d.ts +17 -0
- package/dist/types/components/molecules/menu/mg-menu/mg-menu.conf.d.ts +7 -0
- package/dist/types/components/molecules/menu/mg-menu/mg-menu.d.ts +69 -0
- package/dist/types/components/molecules/menu/mg-menu-item/doc/mg-menu-item.stories.d.ts +11 -0
- package/dist/types/components/molecules/menu/mg-menu-item/mg-menu-item.conf.d.ts +24 -0
- package/dist/types/components/molecules/menu/mg-menu-item/mg-menu-item.d.ts +119 -0
- package/dist/types/components/molecules/mg-form/mg-form.d.ts +21 -1
- package/dist/types/components/molecules/mg-message/mg-message.d.ts +3 -0
- package/dist/types/components/molecules/mg-modal/mg-modal.d.ts +3 -0
- package/dist/types/components/molecules/mg-tabs/doc/mg-tabs.stories.d.ts +1 -1
- package/dist/types/components/molecules/mg-tabs/mg-tabs.conf.d.ts +12 -4
- package/dist/types/components/molecules/mg-tabs/mg-tabs.d.ts +6 -6
- package/dist/types/components.d.ts +91 -14
- package/dist/types/locales/index.d.ts +7 -1
- package/dist/types/stories/icons.stories.d.ts +1 -1
- package/package.json +7 -8
- package/dist/collection/utils/test.utils.js +0 -38
- package/dist/mg-components/p-e131701a.entry.js +0 -1
- 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
|
-
//
|
|
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
|
-
//
|
|
15
|
-
this.
|
|
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.
|
|
65
|
-
this.
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
*
|
|
103
|
+
* Set input error message
|
|
107
104
|
*
|
|
108
105
|
* @returns {void}
|
|
109
106
|
*/
|
|
110
|
-
this.
|
|
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
|
|
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.
|
|
178
|
-
this.
|
|
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 =>
|
|
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
|
-
//
|
|
10
|
+
// Classes
|
|
11
11
|
this.classFocus = 'is-focused';
|
|
12
12
|
this.classHasDisplayCharacterLeft = 'mg-input--has-display-character-left';
|
|
13
|
-
//
|
|
14
|
-
this.
|
|
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.
|
|
64
|
+
if (this.hasDisplayedError) {
|
|
65
65
|
this.checkValidity();
|
|
66
|
-
this.
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
*
|
|
105
|
+
* Set input error message
|
|
109
106
|
*/
|
|
110
|
-
this.
|
|
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.
|
|
154
|
-
this.
|
|
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 =>
|
|
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
|
-
//
|
|
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,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'];
|