@mgdis/mg-components 5.14.0 → 5.16.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 (85) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/{mg-action-more_32.cjs.entry.js → mg-action-more_34.cjs.entry.js} +342 -115
  3. package/dist/cjs/mg-components.cjs.js +1 -1
  4. package/dist/cjs/mg-item-more.cjs.entry.js +4 -2
  5. package/dist/collection/assets/icons/index.js +179 -0
  6. package/dist/collection/collection-manifest.json +2 -0
  7. package/dist/collection/components/atoms/mg-icon/mg-icon.js +1 -1
  8. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip-content/mg-tooltip-content.css +43 -0
  9. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip-content/mg-tooltip-content.js +49 -0
  10. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip.css +0 -43
  11. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip.js +57 -12
  12. package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.css +2 -2
  13. package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.js +1 -1
  14. package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.js +1 -1
  15. package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.js +35 -15
  16. package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.js +1 -1
  17. package/dist/collection/components/molecules/inputs/mg-input-radio/mg-input-radio.js +1 -1
  18. package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.js +1 -1
  19. package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.js +1 -1
  20. package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.js +1 -1
  21. package/dist/collection/components/molecules/menu/mg-menu-item/mg-menu-item.js +2 -2
  22. package/dist/collection/components/molecules/mg-action-more/mg-action-more.js +9 -2
  23. package/dist/collection/components/molecules/mg-details/mg-details.js +1 -1
  24. package/dist/collection/components/molecules/mg-form/mg-form.js +21 -8
  25. package/dist/collection/components/molecules/mg-item-more/mg-item-more.js +4 -2
  26. package/dist/collection/components/molecules/mg-modal/mg-modal.conf.js +4 -0
  27. package/dist/collection/components/molecules/mg-modal/mg-modal.js +37 -5
  28. package/dist/collection/components/molecules/mg-panel/mg-panel.js +1 -1
  29. package/dist/collection/components/molecules/mg-popover/mg-popover-content/mg-popover-content.css +135 -0
  30. package/dist/collection/components/molecules/mg-popover/mg-popover-content/mg-popover-content.js +100 -0
  31. package/dist/collection/components/molecules/mg-popover/mg-popover.css +0 -111
  32. package/dist/collection/components/molecules/mg-popover/mg-popover.js +42 -43
  33. package/dist/collection/utils/components.utils.js +8 -7
  34. package/dist/collection/utils/unit.test.utils.js +6 -5
  35. package/dist/components/components.utils.js +8 -7
  36. package/dist/components/index.d.ts +2 -0
  37. package/dist/components/index.js +2 -0
  38. package/dist/components/mg-action-more.js +29 -16
  39. package/dist/components/mg-details.js +1 -1
  40. package/dist/components/mg-form.js +21 -8
  41. package/dist/components/mg-icon2.js +77 -17
  42. package/dist/components/mg-input-checkbox-paginated2.js +18 -12
  43. package/dist/components/mg-input-checkbox.js +36 -24
  44. package/dist/components/mg-input-date.js +13 -7
  45. package/dist/components/mg-input-numeric.js +47 -21
  46. package/dist/components/mg-input-password.js +13 -7
  47. package/dist/components/mg-input-radio.js +13 -7
  48. package/dist/components/mg-input-select2.js +13 -7
  49. package/dist/components/mg-input-text2.js +15 -9
  50. package/dist/components/mg-input-textarea.js +15 -9
  51. package/dist/components/mg-input-toggle.js +12 -6
  52. package/dist/components/mg-item-more.js +24 -16
  53. package/dist/components/mg-menu-item2.js +18 -12
  54. package/dist/components/mg-modal.js +16 -3
  55. package/dist/components/mg-pagination2.js +16 -10
  56. package/dist/components/mg-panel.js +21 -15
  57. package/dist/components/mg-popover-content.d.ts +11 -0
  58. package/dist/components/mg-popover-content.js +6 -0
  59. package/dist/components/mg-popover-content2.js +88 -0
  60. package/dist/components/mg-popover2.js +54 -47
  61. package/dist/components/mg-tooltip-content.d.ts +11 -0
  62. package/dist/components/mg-tooltip-content.js +6 -0
  63. package/dist/components/mg-tooltip-content2.js +41 -0
  64. package/dist/components/mg-tooltip2.js +64 -15
  65. package/dist/esm/loader.js +1 -1
  66. package/dist/esm/{mg-action-more_32.entry.js → mg-action-more_34.entry.js} +341 -116
  67. package/dist/esm/mg-components.js +1 -1
  68. package/dist/esm/mg-item-more.entry.js +4 -2
  69. package/dist/mg-components/mg-components.css +1 -1
  70. package/dist/mg-components/mg-components.esm.js +1 -1
  71. package/dist/mg-components/p-3286bc46.entry.js +1 -0
  72. package/dist/mg-components/p-91f4a30d.entry.js +1 -0
  73. package/dist/types/components/atoms/mg-tooltip/mg-tooltip-content/mg-tooltip-content.d.ts +14 -0
  74. package/dist/types/components/atoms/mg-tooltip/mg-tooltip.d.ts +7 -1
  75. package/dist/types/components/molecules/inputs/mg-input-numeric/mg-input-numeric.d.ts +19 -0
  76. package/dist/types/components/molecules/mg-action-more/mg-action-more.d.ts +6 -1
  77. package/dist/types/components/molecules/mg-form/mg-form.d.ts +8 -0
  78. package/dist/types/components/molecules/mg-modal/mg-modal.conf.d.ts +8 -0
  79. package/dist/types/components/molecules/mg-modal/mg-modal.d.ts +8 -2
  80. package/dist/types/components/molecules/mg-popover/mg-popover-content/mg-popover-content.d.ts +47 -0
  81. package/dist/types/components/molecules/mg-popover/mg-popover.d.ts +8 -11
  82. package/dist/types/components.d.ts +59 -0
  83. package/package.json +18 -18
  84. package/dist/mg-components/p-4ae1130f.entry.js +0 -1
  85. package/dist/mg-components/p-aa298e17.entry.js +0 -1
@@ -2,6 +2,12 @@ import { h, Host } from '@stencil/core';
2
2
  import { createID, focusableElements, getWindows } from '../../../utils/components.utils';
3
3
  import { createPopper } from '@popperjs/core';
4
4
  import { Guard } from './mg-tooltip.conf';
5
+ /**
6
+ * HTMLMgButtonElement type guard
7
+ * @param element - element to check
8
+ * @returns return true if type is HTMLMgButtonElement
9
+ */
10
+ const isButton = (element) => typeof element === 'object' && ['MG-BUTTON', 'BUTTON'].includes(element.tagName);
5
11
  export class MgTooltip {
6
12
  constructor() {
7
13
  /**
@@ -9,7 +15,7 @@ export class MgTooltip {
9
15
  */
10
16
  this.show = () => {
11
17
  // Make the tooltip visible
12
- this.tooltip.dataset.show = '';
18
+ this.mgTooltipContent.dataset.show = '';
13
19
  // Enable the event listeners
14
20
  this.popper.setOptions(options => (Object.assign(Object.assign({}, options), { modifiers: [...options.modifiers, { name: 'eventListeners', enabled: true }] })));
15
21
  // hide when click outside
@@ -26,7 +32,7 @@ export class MgTooltip {
26
32
  */
27
33
  this.hide = () => {
28
34
  // Hide the tooltip
29
- this.tooltip.removeAttribute('data-show');
35
+ this.mgTooltipContent.removeAttribute('data-show');
30
36
  // Disable the event listeners
31
37
  this.popper.setOptions(options => (Object.assign(Object.assign({}, options), { modifiers: [...options.modifiers, { name: 'eventListeners', enabled: false }] })));
32
38
  // Remove event listener
@@ -113,8 +119,12 @@ export class MgTooltip {
113
119
  */
114
120
  this.initTooltip = (slotElement, interactiveElement) => {
115
121
  // Add tabindex to slotted element if we can't find any interactive element
116
- if (interactiveElement === null || interactiveElement === undefined)
122
+ if (!this.disabled && !Boolean(interactiveElement)) {
123
+ this.hasCustomTabIndex = true;
117
124
  slotElement.tabIndex = 0;
125
+ // Add role on non-interactive element to work with "aria-describedby" for screen readers
126
+ slotElement.setAttribute('role', 'button');
127
+ }
118
128
  // Set aria-describedby
119
129
  const ariaDescribedby = slotElement.getAttribute('aria-describedby');
120
130
  if (ariaDescribedby === null) {
@@ -125,7 +135,7 @@ export class MgTooltip {
125
135
  slotElement.setAttribute('aria-describedby', `${[...new Set([...ariaDescribedby.split(' '), this.identifier])].join(' ')}`);
126
136
  }
127
137
  // Create popperjs tooltip
128
- this.popper = createPopper(this.tooltipedElement, this.tooltip, {
138
+ this.popper = createPopper(this.tooltipedElement, this.mgTooltipContent, {
129
139
  placement: this.placement,
130
140
  strategy: 'fixed',
131
141
  modifiers: [
@@ -142,6 +152,12 @@ export class MgTooltip {
142
152
  this.guard = Guard.FOCUS;
143
153
  this.setDisplay(true);
144
154
  });
155
+ // as `click` event is the composition of `mousedown` and `mouseup` event,
156
+ // and `click` event trigger `focus` event after a success `mousedown` wich set the `guard` to `Guard.FOCUS`
157
+ // we reset the guard on `mouseup` event to unlock tooltip
158
+ this.tooltipedElement.addEventListener('mouseup', () => {
159
+ this.resetGuard();
160
+ });
145
161
  this.tooltipedElement.addEventListener('blur', () => {
146
162
  this.resetGuard();
147
163
  this.setDisplay(false);
@@ -151,7 +167,7 @@ export class MgTooltip {
151
167
  ['mouseenter', 'mouseleave'].forEach(eventType => {
152
168
  const isMouseenter = eventType === 'mouseenter';
153
169
  [
154
- { element: this.tooltip, action: () => this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIP_ELEMENT, isMouseenter, Guard.HOVER_TOOLTIPED_ELEMENT) },
170
+ { element: this.mgTooltipContent, action: () => this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIP_ELEMENT, isMouseenter, Guard.HOVER_TOOLTIPED_ELEMENT) },
155
171
  { element: this.tooltipedElement, action: () => this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIPED_ELEMENT, isMouseenter, Guard.HOVER_TOOLTIP_ELEMENT) },
156
172
  ].forEach(({ element, action }) => {
157
173
  element.addEventListener(eventType, () => {
@@ -170,6 +186,7 @@ export class MgTooltip {
170
186
  if (typeof newValue !== 'string' || newValue.trim() === '') {
171
187
  throw new Error('<mg-tooltip> prop "message" is required.');
172
188
  }
189
+ this.mgTooltipContent.message = newValue;
173
190
  }
174
191
  handleDisplay(newValue) {
175
192
  if (newValue) {
@@ -179,6 +196,28 @@ export class MgTooltip {
179
196
  this.hide();
180
197
  }
181
198
  }
199
+ validateDisabled(newValue) {
200
+ if (this.hasCustomTabIndex) {
201
+ if (newValue)
202
+ this.tooltipedElement.removeAttribute('tabindex');
203
+ else if (this.tooltipedElement.getAttribute('tabindex') === null)
204
+ this.tooltipedElement.setAttribute('tabindex', '0');
205
+ }
206
+ }
207
+ /**
208
+ * Render tooltip content element
209
+ */
210
+ renderTooltip() {
211
+ const mgTooltipContent = document.createElement('mg-tooltip-content');
212
+ mgTooltipContent.setAttribute('slot', 'content');
213
+ mgTooltipContent.setAttribute('id', this.identifier);
214
+ const arrow = document.createElement('div');
215
+ arrow.setAttribute('slot', 'arrow');
216
+ arrow.dataset.popperArrow = '';
217
+ mgTooltipContent.appendChild(arrow);
218
+ // append tooltip element to component
219
+ this.element.appendChild(mgTooltipContent);
220
+ }
182
221
  /*************
183
222
  * Lifecycle *
184
223
  *************/
@@ -188,6 +227,12 @@ export class MgTooltip {
188
227
  componentWillLoad() {
189
228
  // Get windows to attach events
190
229
  this.windows = getWindows(window);
230
+ // Get tooltip element
231
+ this.renderTooltip();
232
+ this.mgTooltipContent = this.element.querySelector(`#${this.identifier}`);
233
+ //validate properties
234
+ this.validateDisabled(this.disabled);
235
+ this.validateMessage(this.message);
191
236
  }
192
237
  /**
193
238
  * Get slotted element
@@ -196,17 +241,15 @@ export class MgTooltip {
196
241
  */
197
242
  componentDidLoad() {
198
243
  var _a;
199
- // Get tooltip element
200
- this.tooltip = this.element.shadowRoot.querySelector(`#${this.identifier}`);
201
- // get slotted element
202
- const slotElement = this.element.firstElementChild;
244
+ // get slotted element wich is not the tooltip
245
+ const slotElement = this.element.querySelector(`*:not(#${this.identifier})`);
203
246
  // Get interactive element
204
247
  const interactiveElement = slotElement.matches(focusableElements) ? slotElement : (_a = slotElement.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(focusableElements);
205
248
  // define selected element to become tooltip selector
206
249
  this.tooltipedElement = interactiveElement || slotElement;
207
250
  // Check if slotted element is a disabled mg-button
208
251
  // In this case we wrap the mg-button into a div to enable the tooltip
209
- if (['MG-BUTTON', 'BUTTON'].includes(slotElement.tagName)) {
252
+ if (isButton(slotElement)) {
210
253
  new MutationObserver(mutationList => {
211
254
  if (mutationList.some(mutation => ['aria-disabled', 'disabled'].includes(mutation.attributeName))) {
212
255
  this.setMgButtonWrapper(slotElement);
@@ -221,7 +264,6 @@ export class MgTooltip {
221
264
  // Init Tooltip
222
265
  this.initTooltip(slotElement, interactiveElement);
223
266
  this.handleDisplay(this.display);
224
- this.validateMessage(this.message);
225
267
  }
226
268
  /**
227
269
  * update popper position after props change on component did update hook to benefit from render ended
@@ -234,7 +276,7 @@ export class MgTooltip {
234
276
  * @returns HTML Element
235
277
  */
236
278
  render() {
237
- return (h(Host, null, h("slot", null), h("div", { role: "tooltip", id: this.identifier, class: "mg-tooltip" }, h("span", { innerHTML: this.message }), h("div", { class: "mg-tooltip__arrow", "data-popper-arrow": true }))));
279
+ return (h(Host, null, h("slot", null), h("slot", { name: "content" })));
238
280
  }
239
281
  static get is() { return "mg-tooltip"; }
240
282
  static get encapsulation() { return "shadow"; }
@@ -354,6 +396,9 @@ export class MgTooltip {
354
396
  }, {
355
397
  "propName": "display",
356
398
  "methodName": "handleDisplay"
399
+ }, {
400
+ "propName": "disabled",
401
+ "methodName": "validateDisabled"
357
402
  }];
358
403
  }
359
404
  }
@@ -254,13 +254,13 @@ fieldset.mg-input.mg-input--label-on-top .mg-input__input-group-container {
254
254
  --mg-popover-min-width: 7rem;
255
255
  --mg-card-padding: calc(0.4rem * 2);
256
256
  }
257
- .mg-input.mg-input--checkbox-multi mg-popover [slot=content] {
257
+ .mg-input.mg-input--checkbox-multi mg-popover-content [slot=content] {
258
258
  display: flex;
259
259
  flex-wrap: wrap;
260
260
  gap: calc(0.4rem * 2);
261
261
  flex-direction: column;
262
262
  }
263
- .mg-input.mg-input--checkbox-multi mg-popover [slot=content] .mg-input__input-group {
263
+ .mg-input.mg-input--checkbox-multi mg-popover-content [slot=content] .mg-input__input-group {
264
264
  margin-left: calc(0.4rem * 2);
265
265
  }
266
266
  .mg-input.mg-input--checkbox-multi mg-input-text {
@@ -335,7 +335,7 @@ export class MgInputCheckbox {
335
335
  renderCheckboxMulti() {
336
336
  const selectedValuesNb = this.checkboxItems.filter(({ value }) => value).length;
337
337
  const checkboxes = this.getDisplayItems();
338
- return (h("div", { class: { 'mg-input__input-container': true, 'mg-input__input-checkbox-multi': true, 'mg-input__input-checkbox-multi--with-values': this.displaySelectedValues } }, this.renderCheckboxMultiDisplaySelectedValues(selectedValuesNb), h("mg-popover", { arrowHide: true, identifier: this.getMgPopoverIdentifier(), "onDisplay-change": this.handleMgPopoverDisplayChange, ref: el => {
338
+ return (h("div", { class: { 'mg-input__input-container': true, 'mg-input__input-checkbox-multi': true, 'mg-input__input-checkbox-multi--with-values': this.displaySelectedValues } }, this.renderCheckboxMultiDisplaySelectedValues(selectedValuesNb), h("mg-popover", { arrowHide: true, identifier: this.getMgPopoverIdentifier(), "onDisplay-change": this.handleMgPopoverDisplayChange, ref: (el) => {
339
339
  if (Boolean(el))
340
340
  this.mgPopover = el;
341
341
  } }, h("mg-button", { variant: "secondary" }, h("mg-icon", { icon: "list" }), this.renderButtonText(selectedValuesNb)), h("div", { slot: "content" }, this.displaySearchInput && [
@@ -163,7 +163,7 @@ export class MgInputDate {
163
163
  * @returns HTML Element
164
164
  */
165
165
  render() {
166
- return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: undefined, disabled: this.disabled, value: this.value, readonlyValue: localeDate(this.value, this.locale), tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("input", { type: "date", class: "mg-input__box", min: this.min, max: this.max, value: this.value, id: this.identifier, name: this.name, disabled: this.disabled, required: this.required, onInput: this.handleInput, onBlur: this.handleBlur, ref: el => {
166
+ return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: undefined, disabled: this.disabled, value: this.value, readonlyValue: localeDate(this.value, this.locale), tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("input", { type: "date", class: "mg-input__box", min: this.min, max: this.max, value: this.value, id: this.identifier, name: this.name, disabled: this.disabled, required: this.required, onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
167
167
  if (el !== null)
168
168
  this.input = el;
169
169
  } })));
@@ -134,28 +134,48 @@ export class MgInputNumeric {
134
134
  // Split number and decimal
135
135
  const [integer, decimal = ''] = newValue.replace('-', '').split(/[\.,]/);
136
136
  // Regex
137
- const regex = this.type === 'integer' ? /^-?\d+$/ : /^-?\d+[.,]?\d*$/;
137
+ const regex = this.type === 'integer' ? /^-?\d+$/ : /^-?\d+(?:[.,]\d*)?$/;
138
138
  // Filter input
139
- if (['', '-'].includes(newValue) || (newValue.match(regex) && integer.length <= this.integerLength && decimal.length <= (this.type === 'integer' ? 0 : this.decimalLength))) {
139
+ if (this.isValidValue(newValue, regex, integer, decimal)) {
140
140
  this.storedValue = newValue;
141
141
  }
142
- else if (this.storedValue !== undefined) {
143
- newValue = this.storedValue;
144
- }
145
142
  else {
146
- newValue = null;
143
+ newValue = this.handleInvalidValue();
147
144
  }
148
145
  // Set value and input value
149
- this.value = newValue;
150
- if (this.input !== undefined)
151
- this.input.value = this.value;
152
- // emit numeric value
153
- this.numericValue = !['', null].includes(this.value) ? parseFloat(this.value.replace(',', '.')) : null;
154
- this.valueChange.emit(this.numericValue);
155
- // Set readonlyValue
156
- this.readonlyValue = this.numericValue !== null ? this.formatValue(this.numericValue) : '';
146
+ this.updateValues(newValue);
157
147
  }
158
148
  }
149
+ /**
150
+ * Checks if the given value is valid according to the defined rules.
151
+ * @param value - The input value to validate.
152
+ * @param regex - The regular expression for validation.
153
+ * @param integer - The integer part of the value.
154
+ * @param decimal - The decimal part of the value.
155
+ * @returns Returns true if the value is valid, otherwise false.
156
+ */
157
+ isValidValue(value, regex, integer, decimal) {
158
+ return ['', '-'].includes(value) || (value.match(regex) && integer.length <= this.integerLength && decimal.length <= (this.type === 'integer' ? 0 : this.decimalLength));
159
+ }
160
+ /**
161
+ * Handles invalid input values and returns a corrected value.
162
+ * @returns The corrected value.
163
+ */
164
+ handleInvalidValue() {
165
+ return this.storedValue !== undefined ? this.storedValue : null;
166
+ }
167
+ /**
168
+ * Updates the component values based on the validated input value.
169
+ * @param newValue - The validated input value.
170
+ */
171
+ updateValues(newValue) {
172
+ this.value = newValue;
173
+ if (this.input !== undefined)
174
+ this.input.value = this.value;
175
+ this.numericValue = !['', null].includes(this.value) ? parseFloat(this.value.replace(',', '.')) : null;
176
+ this.valueChange.emit(this.numericValue);
177
+ this.readonlyValue = this.numericValue !== null ? this.formatValue(this.numericValue) : '';
178
+ }
159
179
  handleValidityChange(newValue, _oldValue, prop) {
160
180
  if (this.input !== undefined) {
161
181
  this.input[prop] = newValue;
@@ -228,7 +248,7 @@ export class MgInputNumeric {
228
248
  * @returns HTML Element
229
249
  */
230
250
  render() {
231
- return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: this.mgWidth, disabled: this.disabled, value: this.value, readonlyValue: this.readonlyValue, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("input", { type: "text", class: "mg-input__box", value: this.displayValue(), id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: el => {
251
+ return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: this.mgWidth, disabled: this.disabled, value: this.value, readonlyValue: this.readonlyValue, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("input", { type: "text", class: "mg-input__box", value: this.displayValue(), id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, onInput: this.handleInput, onFocus: this.handleFocus, onBlur: this.handleBlur, ref: (el) => {
232
252
  if (el !== null)
233
253
  this.input = el;
234
254
  } }), h("slot", { name: "append-input" })));
@@ -104,7 +104,7 @@ export class MgInputPassword {
104
104
  * @returns HTML Element
105
105
  */
106
106
  render() {
107
- return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: this.mgWidth, disabled: this.disabled, value: this.value, readonlyValue: this.value !== undefined ? '•'.repeat(this.value.length) : undefined, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("input", { type: "password", class: "mg-input__box", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, onInput: this.handleInput, onBlur: this.handleBlur, ref: el => {
107
+ return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: this.mgWidth, disabled: this.disabled, value: this.value, readonlyValue: this.value !== undefined ? '•'.repeat(this.value.length) : undefined, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("input", { type: "password", class: "mg-input__box", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
108
108
  if (el !== null)
109
109
  this.input = el;
110
110
  } })));
@@ -141,7 +141,7 @@ export class MgInputRadio {
141
141
  * @returns HTML Element
142
142
  */
143
143
  render() {
144
- return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, disabled: this.disabled, readonly: this.readonly, mgWidth: undefined, value: this.value, readonlyValue: this.value, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: true }, h("ul", { class: { 'mg-input__input-group-container': true, 'mg-input__input-group-container--vertical': this.inputVerticalList }, role: "list" }, this.options.map((input, index) => (h("li", { key: input.title, class: { 'mg-input__input-group': true, 'mg-input__input-group--disabled': this.disabled || input.disabled } }, h("input", { type: "radio", id: this.identifier + '_' + index, name: this.identifier, value: index, checked: JSON.stringify(this.value) === JSON.stringify(this.options[index].value), disabled: this.disabled || input.disabled, required: this.required, onBlur: this.handleBlur, onInput: this.handleInput, ref: el => {
144
+ return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, disabled: this.disabled, readonly: this.readonly, mgWidth: undefined, value: this.value, readonlyValue: this.value, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: true }, h("ul", { class: { 'mg-input__input-group-container': true, 'mg-input__input-group-container--vertical': this.inputVerticalList }, role: "list" }, this.options.map((input, index) => (h("li", { key: input.title, class: { 'mg-input__input-group': true, 'mg-input__input-group--disabled': this.disabled || input.disabled } }, h("input", { type: "radio", id: this.identifier + '_' + index, name: this.identifier, value: index, checked: JSON.stringify(this.value) === JSON.stringify(this.options[index].value), disabled: this.disabled || input.disabled, required: this.required, onBlur: this.handleBlur, onInput: this.handleInput, ref: (el) => {
145
145
  if (el !== null)
146
146
  this.inputs[index] = el;
147
147
  } }), h("label", { htmlFor: this.identifier + '_' + index }, input.title)))))));
@@ -239,7 +239,7 @@ export class MgInputSelect {
239
239
  * @returns HTML Element
240
240
  */
241
241
  render() {
242
- return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: this.mgWidth, disabled: this.disabled, value: undefined, readonlyValue: this.readonlyValue, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("select", { class: "mg-input__box", id: this.identifier, name: this.name, title: this.placeholder, disabled: this.disabled, required: this.required, onInput: this.handleInput, onBlur: this.handleBlur, ref: el => {
242
+ return (h(MgInput, { identifier: this.identifier, classCollection: this.classCollection, ariaDescribedbyIDs: [], label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, readonly: this.readonly, mgWidth: this.mgWidth, disabled: this.disabled, value: undefined, readonlyValue: this.readonlyValue, tooltip: this.tooltip, helpText: this.helpText, errorMessage: this.errorMessage, isFieldset: false }, h("select", { class: "mg-input__box", id: this.identifier, name: this.name, title: this.placeholder, disabled: this.disabled, required: this.required, onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
243
243
  if (el !== null)
244
244
  this.input = el;
245
245
  } }, (!this.placeholderHide || !this.valueExist) && ( // In case passed value does not match any option we display the placeholder
@@ -179,7 +179,7 @@ export class MgInputText {
179
179
  '--mg-character-left-message-length': (this.displayCharacterLeft
180
180
  ? (this.maxlength - (this.value || '').length).toString().length + this.maxlength.toString().length + 1
181
181
  : 0).toString(),
182
- } }, 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 => {
182
+ } }, 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) => {
183
183
  if (el !== null)
184
184
  this.input = el;
185
185
  } }), this.displayCharacterLeft && this.maxlength > 0 && (h("mg-character-left", { identifier: this.characterLeftId, characters: this.value, maxlength: this.maxlength }))), h("slot", { name: "append-input" })));
@@ -166,7 +166,7 @@ export class MgInputTextarea {
166
166
  'mg-input__box--resizable': this.resizable === 'both',
167
167
  'mg-input__box--resizable-horizontal': this.resizable === 'horizontal',
168
168
  'mg-input__box--resizable-vertical': this.resizable === 'vertical',
169
- }, 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 => {
169
+ }, 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) => {
170
170
  if (el !== null)
171
171
  this.input = el;
172
172
  } }), this.displayCharacterLeft && this.maxlength > 0 && (h("mg-character-left", { identifier: this.characterLeftId, characters: this.value, maxlength: this.maxlength })))));
@@ -264,7 +264,7 @@ export class MgMenuItem {
264
264
  */
265
265
  renderInteractiveElement() {
266
266
  const TagName = this.href !== undefined ? 'a' : 'button';
267
- 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: "text-color", slot: "information" })))), this.size !== 'regular' && h("slot", { name: "metadata" })), this.hasChildren && this.href === undefined && (h("span", { class: {
267
+ return (h(TagName, { href: this.href, class: this.navigationButtonClassList.join(), tabindex: [Status.DISABLED, Status.HIDDEN].includes(this.status) ? -1 : undefined, 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: "text-color", slot: "information" })))), this.size !== 'regular' && h("slot", { name: "metadata" })), this.hasChildren && this.href === undefined && (h("span", { class: {
268
268
  [`${this.navigationButton}-chevron`]: true,
269
269
  [`${this.navigationButton}-chevron--rotate`]: this.expanded === true,
270
270
  'mg-a11y-animation': true,
@@ -279,7 +279,7 @@ export class MgMenuItem {
279
279
  [`${this.name}__collapse-container`]: true,
280
280
  [`${this.name}__collapse-container--first-level`]: (this.isInMainMenu || this.isItemMore) && this.isDirection(Direction.HORIZONTAL),
281
281
  });
282
- return (h(Host, { role: "listitem" }, this.displayPopover() ? (h("mg-popover", { display: this.expanded, placement: "bottom-start", arrowHide: true, "onDisplay-change": this.handlePopoverDisplay, identifier: this.getPopoverIdentifier() }, this.renderInteractiveElement(), h("div", { class: getContainerClasses(), slot: "content" }, this.renderSlot()))) : ([
282
+ return (h(Host, { role: this.isItemMore ? 'presentation' : 'listitem' }, this.displayPopover() ? (h("mg-popover", { display: this.expanded, placement: "bottom-start", arrowHide: true, "onDisplay-change": this.handlePopoverDisplay, identifier: this.getPopoverIdentifier() }, this.renderInteractiveElement(), h("div", { class: getContainerClasses(), slot: "content" }, this.renderSlot()))) : ([
283
283
  this.renderInteractiveElement(),
284
284
  h("div", { key: "vertical-container", class: getContainerClasses(), hidden: !this.expanded }, this.renderSlot()),
285
285
  ])));
@@ -38,7 +38,7 @@ export class MgActionMore {
38
38
  this.name = 'mg-action-more';
39
39
  this.mgPopoverIdentifier = createID(this.name);
40
40
  /************
41
- * Merthods *
41
+ * Methods *
42
42
  ***********/
43
43
  /**
44
44
  * Toogle expanded props
@@ -46,6 +46,13 @@ export class MgActionMore {
46
46
  this.toggleExpanded = () => {
47
47
  this.expanded = !this.expanded;
48
48
  };
49
+ /**
50
+ * Handle popover display change value
51
+ * @param event - display change updated value
52
+ */
53
+ this.handleDisplayChange = (event) => {
54
+ this.expanded = event.detail;
55
+ };
49
56
  /**
50
57
  * Button click handler
51
58
  */
@@ -114,7 +121,7 @@ export class MgActionMore {
114
121
  'mg-a11y-animation': true,
115
122
  } }, h("mg-icon", { icon: "chevron-down", size: "small" })));
116
123
  }
117
- return (h(Host, { "data-mg-popover-guard": this.mgPopoverIdentifier }, h("span", { class: "mg-action-more" }, h("mg-popover", { identifier: this.mgPopoverIdentifier, display: this.expanded }, h("mg-button", { variant: this.button.variant, isIcon: this.button.isIcon, type: "button", label: buttonLabel, onClick: this.handleButton }, h("mg-icon", Object.assign({}, this.icon)), !this.button.isIcon && buttonContent), h("div", { slot: "content" }, h("mg-menu", { direction: Direction.VERTICAL, label: this.messages.label }, this.items.map(item => {
124
+ return (h(Host, { "data-mg-popover-guard": this.mgPopoverIdentifier }, h("span", { class: "mg-action-more" }, h("mg-popover", { identifier: this.mgPopoverIdentifier, display: this.expanded, "onDisplay-change": this.handleDisplayChange }, h("mg-button", { variant: this.button.variant, isIcon: this.button.isIcon, type: "button", label: buttonLabel, onClick: this.handleButton }, h("mg-icon", Object.assign({}, this.icon)), !this.button.isIcon && buttonContent), h("div", { slot: "content" }, h("mg-menu", { direction: Direction.VERTICAL, label: this.messages.label }, this.items.map(item => {
118
125
  var _a;
119
126
  return (
120
127
  // eslint-disable-next-line react/jsx-no-bind
@@ -35,7 +35,7 @@ export class MgDetails {
35
35
  * @returns HTML Element
36
36
  */
37
37
  render() {
38
- return (h("details", { class: "mg-details", onToggle: this.handleToggle, open: this.expanded, ref: el => (this.details = el) }, h("summary", null, h("slot", { name: "summary" }), h("span", { class: "mg-details__toggle" }, h("mg-icon", { icon: "chevron-up", size: "small", class: { 'mg-details__toggle-icon': true, 'mg-details__toggle-icon--reverse': !this.expanded } }), h("span", { class: { 'sr-only': this.hideSummary } }, this.expanded ? this.toggleOpened : this.toggleClosed))), h("div", { class: "mg-details__details" }, h("slot", { name: "details" }))));
38
+ return (h("details", { class: "mg-details", onToggle: this.handleToggle, open: this.expanded, ref: (el) => (this.details = el) }, h("summary", null, h("slot", { name: "summary" }), h("span", { class: "mg-details__toggle" }, h("mg-icon", { icon: "chevron-up", size: "small", class: { 'mg-details__toggle-icon': true, 'mg-details__toggle-icon--reverse': !this.expanded } }), h("span", { class: { 'sr-only': this.hideSummary } }, this.expanded ? this.toggleOpened : this.toggleClosed))), h("div", { class: "mg-details__details" }, h("slot", { name: "details" }))));
39
39
  }
40
40
  static get is() { return "mg-details"; }
41
41
  static get encapsulation() { return "shadow"; }
@@ -14,21 +14,34 @@ export class MgForm {
14
14
  this.classCollection.delete(this.classAllRequired);
15
15
  // If the form is disabled or readonly none of them are required
16
16
  // Check if all fields are not editable (readonly or disabled)
17
- if (!this.disabled && !this.readonly && !this.mgInputs.every(input => input.disabled || input.readonly)) {
18
- // Get required fields
19
- const requiredInputs = this.mgInputs.filter(input => input.required && !input.disabled && !input.readonly);
20
- // All fields are required
17
+ const isEditable = input => !(input.disabled || input.readonly);
18
+ const isMgInputToggle = input => input.nodeName === 'MG-INPUT-TOGGLE';
19
+ if (!this.disabled && !this.readonly && this.mgInputs.some(input => isEditable(input) && !isMgInputToggle(input))) {
20
+ // Get editable inputs
21
+ const editableInputs = this.mgInputs.filter(isEditable);
22
+ // Get required inputs
21
23
  // mg-input-toggle can not be required
22
- if (requiredInputs.length > 0 && requiredInputs.length === this.mgInputs.filter(input => input.nodeName !== 'MG-INPUT-TOGGLE').length) {
23
- this.requiredMessage = requiredInputs.length === 1 ? this.messages.form.allRequiredSingle : this.messages.form.allRequired;
24
+ const requiredInputs = editableInputs.filter(input => !isMgInputToggle(input) && input.required);
25
+ // All inputs are required
26
+ if ([requiredInputs.length, editableInputs.length].every(length => length === 1) ||
27
+ (requiredInputs.length > 1 && requiredInputs.length === editableInputs.filter(input => !isMgInputToggle(input)).length)) {
28
+ this.requiredMessage = this.getRequiredMessageBasedOnCount(requiredInputs, 'allRequiredSingle', 'allRequired');
24
29
  this.classCollection.add(this.classAllRequired);
25
30
  }
26
31
  // Some fields are required
27
32
  else if (requiredInputs.length > 0) {
28
- this.requiredMessage = requiredInputs.length === 1 ? this.messages.form.requiredSingle : this.messages.form.required;
33
+ this.requiredMessage = this.getRequiredMessageBasedOnCount(requiredInputs, 'requiredSingle', 'required');
29
34
  }
30
35
  }
31
36
  };
37
+ /**
38
+ * Returns a required message based on the count of required inputs.
39
+ * @param requiredInputs - An array of required input elements.
40
+ * @param keySingle - The key for the singular message format.
41
+ * @param keyPlural - The key for the plural message format.
42
+ * @returns The appropriate required message based on the count of required inputs.
43
+ */
44
+ this.getRequiredMessageBasedOnCount = (requiredInputs, keySingle, keyPlural) => this.messages.form[requiredInputs.length === 1 ? keySingle : keyPlural];
32
45
  /**
33
46
  * Check if form is valid
34
47
  */
@@ -140,7 +153,7 @@ export class MgForm {
140
153
  * @returns HTML Element
141
154
  */
142
155
  render() {
143
- return (h("form", { class: this.classCollection.join(), id: this.identifier, name: this.name, ref: el => (this.form = el), onSubmit: this.handleFormSubmit }, this.requiredMessage && h("p", { innerHTML: this.requiredMessage }), h("slot", null), !this.readonly && !this.disabled && h("slot", { name: "actions" })));
156
+ return (h("form", { class: this.classCollection.join(), id: this.identifier, name: this.name, ref: (el) => (this.form = el), onSubmit: this.handleFormSubmit }, this.requiredMessage && h("p", { innerHTML: this.requiredMessage }), h("slot", null), !this.readonly && !this.disabled && h("slot", { name: "actions" })));
144
157
  }
145
158
  static get is() { return "mg-form"; }
146
159
  static get encapsulation() { return "shadow"; }
@@ -26,7 +26,9 @@ export class MgItemMore {
26
26
  // manage click on proxy to mirror it on initial element
27
27
  proxy.addEventListener('click', () => {
28
28
  // be carefull to use element.click() method instead of dispatchEvent to ensure bubbles outside shadowDom
29
- allMenuItem[index].shadowRoot.querySelector('a, button').click();
29
+ const navElement = allMenuItem[index].shadowRoot.querySelector('a, button');
30
+ if (navElement instanceof HTMLButtonElement || navElement instanceof HTMLAnchorElement)
31
+ navElement.click();
30
32
  });
31
33
  // add id suffix to prevent duplicate key. default html id is: '';
32
34
  if (proxy.id.trim() !== '')
@@ -90,7 +92,7 @@ export class MgItemMore {
90
92
  * @returns HTML Element
91
93
  */
92
94
  render() {
93
- return (h(Host, { role: "menuitem", "aria-haspopup": "true" }, h("mg-menu-item", { "data-overflow-more": true, "data-size": this.parentMenu.size }, h("mg-icon", { icon: this.icon.icon, slot: "image" }), h("span", { class: { 'sr-only': !this.slotlabel.display }, slot: "label" }, this.slotlabel.label), h("mg-menu", { direction: Direction.VERTICAL, label: this.messages.moreLabel, size: this.size }))));
95
+ return (h(Host, { role: "listitem" }, h("mg-menu-item", { "data-overflow-more": true, "data-size": this.parentMenu.size }, h("mg-icon", { icon: this.icon.icon, slot: "image" }), h("span", { class: { 'sr-only': !this.slotlabel.display }, slot: "label" }, this.slotlabel.label), h("mg-menu", { direction: Direction.VERTICAL, label: this.messages.moreLabel, size: this.size }))));
94
96
  }
95
97
  static get is() { return "mg-item-more"; }
96
98
  static get encapsulation() { return "shadow"; }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * List of all possibles dialog roles
3
+ */
4
+ export const dialogRoles = ['dialog', 'alertdialog'];
@@ -1,6 +1,7 @@
1
1
  import { h } from '@stencil/core';
2
2
  import { createID, ClassList, focusableElements } from '../../../utils/components.utils';
3
3
  import { initLocales } from '../../../locales';
4
+ import { dialogRoles } from './mg-modal.conf';
4
5
  export class MgModal {
5
6
  constructor() {
6
7
  /************
@@ -69,13 +70,18 @@ export class MgModal {
69
70
  this.hide = true;
70
71
  };
71
72
  this.identifier = createID('mg-modal');
73
+ this.dialogRole = dialogRoles[0];
72
74
  this.modalTitle = undefined;
73
75
  this.closeButton = false;
74
- this.hide = false;
76
+ this.hide = undefined;
75
77
  this.hasActions = false;
76
78
  this.hasContent = false;
77
79
  this.classCollection = new ClassList(['mg-modal']);
78
80
  }
81
+ validateDialogRole(newValue) {
82
+ if (!dialogRoles.includes(newValue))
83
+ throw new Error(`<mg-modal> prop "dialogRole" must be one of: ${dialogRoles.join(', ')}.`);
84
+ }
79
85
  validateModalTitle(newValue) {
80
86
  if (typeof newValue !== 'string' || newValue.trim() === '') {
81
87
  throw new Error('<mg-modal> prop "modalTitle" is required.');
@@ -92,7 +98,7 @@ export class MgModal {
92
98
  if (this.modalFocusableElements.length > 0)
93
99
  this.modalFocusableElements[0].removeEventListener('keydown', this.handleFirstFocusableElement);
94
100
  }
95
- else {
101
+ else if (newValue === false) {
96
102
  this.componentShow.emit();
97
103
  this.classCollection.delete(this.classHide);
98
104
  document.body.style.overflow = 'hidden';
@@ -126,6 +132,7 @@ export class MgModal {
126
132
  this.titleId = `${this.identifier}-title`;
127
133
  this.validateModalTitle(this.modalTitle);
128
134
  this.validateHide(this.hide);
135
+ this.validateDialogRole(this.dialogRole);
129
136
  }
130
137
  /**
131
138
  * Add observer on component to set focus when displayed
@@ -144,7 +151,7 @@ export class MgModal {
144
151
  * @returns HTML Element
145
152
  */
146
153
  render() {
147
- return (h("div", { role: "alertdialog", id: this.identifier, class: this.classCollection.join(), tabindex: "-1", "aria-labelledby": this.titleId, "aria-modal": "true", "aria-hidden": this.hide }, h("mg-card", null, h("div", { class: "mg-modal__dialog" }, h("header", { class: "mg-modal__header" }, this.closeButton && (h("span", { class: "mg-modal__close-button" }, h("mg-button", { identifier: `${this.identifier}-close-button`, "is-icon": true, variant: "flat", label: this.messages.modal.closeButton, onClick: this.handleClose, ref: el => {
154
+ return (h("div", { role: this.dialogRole, id: this.identifier, class: this.classCollection.join(), tabindex: "-1", "aria-labelledby": this.titleId, "aria-modal": "true", "aria-hidden": this.hide }, h("mg-card", null, h("div", { class: "mg-modal__dialog" }, h("header", { class: "mg-modal__header" }, this.closeButton && (h("span", { class: "mg-modal__close-button" }, h("mg-button", { identifier: `${this.identifier}-close-button`, "is-icon": true, variant: "flat", label: this.messages.modal.closeButton, onClick: this.handleClose, ref: (el) => {
148
155
  if (el !== null) {
149
156
  // store closeButton Element
150
157
  this.closeButtonElement = el;
@@ -185,6 +192,29 @@ export class MgModal {
185
192
  "reflect": false,
186
193
  "defaultValue": "createID('mg-modal')"
187
194
  },
195
+ "dialogRole": {
196
+ "type": "string",
197
+ "mutable": false,
198
+ "complexType": {
199
+ "original": "DialogRoleType",
200
+ "resolved": "\"alertdialog\" | \"dialog\"",
201
+ "references": {
202
+ "DialogRoleType": {
203
+ "location": "import",
204
+ "path": "./mg-modal.conf"
205
+ }
206
+ }
207
+ },
208
+ "required": false,
209
+ "optional": false,
210
+ "docs": {
211
+ "tags": [],
212
+ "text": "Modal dialog role."
213
+ },
214
+ "attribute": "dialog-role",
215
+ "reflect": false,
216
+ "defaultValue": "dialogRoles[0]"
217
+ },
188
218
  "modalTitle": {
189
219
  "type": "string",
190
220
  "mutable": false,
@@ -235,8 +265,7 @@ export class MgModal {
235
265
  "text": "Define if modal is hidden"
236
266
  },
237
267
  "attribute": "hide",
238
- "reflect": false,
239
- "defaultValue": "false"
268
+ "reflect": false
240
269
  }
241
270
  };
242
271
  }
@@ -283,6 +312,9 @@ export class MgModal {
283
312
  static get elementRef() { return "element"; }
284
313
  static get watchers() {
285
314
  return [{
315
+ "propName": "dialogRole",
316
+ "methodName": "validateDialogRole"
317
+ }, {
286
318
  "propName": "modalTitle",
287
319
  "methodName": "validateModalTitle"
288
320
  }, {
@@ -70,7 +70,7 @@ export class MgPanel {
70
70
  * Render input button
71
71
  * @returns edit title input
72
72
  */
73
- this.renderEditInput = () => (h("mg-input-text", { key: "edition-input", label: this.messages.panel.editLabel, "label-hide": true, value: this.panelTitle, "onValue-change": this.handleUpdateTitle, displayCharacterLeft: false, pattern: this.titlePattern, "pattern-error-message": this.titlePatternErrorMessage, identifier: `${this.identifier}-edition-input`, ref: el => (this.editInputElement = el) }, h("mg-button", { slot: "append-input", label: this.messages.general.cancel, "is-icon": true, variant: "secondary", onClick: this.handleCancelEditButton, identifier: `${this.identifier}-edition-button-cancel` }, h("mg-icon", { icon: "cross" })), h("mg-button", { slot: "append-input", label: this.messages.general.confirm, "is-icon": true, variant: "secondary", onClick: this.handleValidateEditButton, identifier: `${this.identifier}-edition-button-validate` }, h("mg-icon", { icon: "check" }))));
73
+ this.renderEditInput = () => (h("mg-input-text", { key: "edition-input", label: this.messages.panel.editLabel, "label-hide": true, value: this.panelTitle, "onValue-change": this.handleUpdateTitle, displayCharacterLeft: false, pattern: this.titlePattern, "pattern-error-message": this.titlePatternErrorMessage, identifier: `${this.identifier}-edition-input`, ref: (el) => (this.editInputElement = el) }, h("mg-button", { slot: "append-input", label: this.messages.general.cancel, "is-icon": true, variant: "secondary", onClick: this.handleCancelEditButton, identifier: `${this.identifier}-edition-button-cancel` }, h("mg-icon", { icon: "cross" })), h("mg-button", { slot: "append-input", label: this.messages.general.confirm, "is-icon": true, variant: "secondary", onClick: this.handleValidateEditButton, identifier: `${this.identifier}-edition-button-validate` }, h("mg-icon", { icon: "check" }))));
74
74
  /**
75
75
  * Render title
76
76
  * @returns title element