@mgdis/mg-components 6.25.0 → 6.27.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 (95) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/mg-action-more_36.cjs.entry.js +217 -95
  3. package/dist/cjs/mg-components.cjs.js +1 -1
  4. package/dist/cjs/mg-illustration.cjs.entry.js +1 -1
  5. package/dist/cjs/mg-input-combobox.cjs.entry.js +25 -7
  6. package/dist/cjs/mg-input-file.cjs.entry.js +1 -1
  7. package/dist/cjs/mg-input-rich-text-editor.cjs.entry.js +1595 -637
  8. package/dist/cjs/mg-loader.cjs.entry.js +1 -1
  9. package/dist/cjs/mg-progress.cjs.entry.js +1 -1
  10. package/dist/collection/assets/illustrations/index.js +1 -1
  11. package/dist/collection/assets/jodit/jodit.css +5834 -0
  12. package/dist/collection/components/atoms/mg-tooltip/mg-tooltip.js +103 -55
  13. package/dist/collection/components/molecules/inputs/mg-input/mg-input.js +39 -4
  14. package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.js +2 -4
  15. package/dist/collection/components/molecules/inputs/mg-input-combobox/mg-input-combobox.js +24 -6
  16. package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.js +3 -2
  17. package/dist/collection/components/molecules/inputs/mg-input-rich-text-editor/editor/custom-properties.css +50 -0
  18. package/dist/collection/components/molecules/inputs/mg-input-rich-text-editor/mg-input-rich-text-editor.js +3 -3
  19. package/dist/collection/components/molecules/mg-details/mg-details.js +5 -1
  20. package/dist/collection/components/molecules/mg-form/mg-form.js +10 -2
  21. package/dist/collection/components/molecules/mg-illustrated-message/mg-illustrated-message.conf.js +4 -0
  22. package/dist/collection/components/molecules/mg-illustrated-message/mg-illustrated-message.js +51 -2
  23. package/dist/collection/components/molecules/mg-loader/mg-loader.js +1 -1
  24. package/dist/collection/components/molecules/mg-message/mg-message.js +3 -3
  25. package/dist/collection/components/molecules/mg-modal/mg-modal.js +2 -2
  26. package/dist/collection/components/molecules/mg-panel/mg-panel.js +1 -1
  27. package/dist/collection/components/molecules/mg-popover/mg-popover-content/mg-popover-content.js +1 -1
  28. package/dist/collection/components/molecules/mg-popover/mg-popover.js +4 -1
  29. package/dist/collection/components/molecules/mg-progress/mg-progress.js +1 -1
  30. package/dist/collection/components/molecules/mg-skip-links/mg-skip-links.js +1 -1
  31. package/dist/collection/components/molecules/mg-tabs/mg-tabs.js +1 -1
  32. package/dist/components/mg-button2.js +1 -1
  33. package/dist/components/mg-card2.js +1 -1
  34. package/dist/components/mg-details.js +1 -1
  35. package/dist/components/mg-form.js +1 -1
  36. package/dist/components/mg-illustrated-message.js +1 -1
  37. package/dist/components/mg-illustration.js +1 -1
  38. package/dist/components/mg-input-checkbox.js +1 -1
  39. package/dist/components/mg-input-combobox.js +1 -1
  40. package/dist/components/mg-input-date.js +1 -1
  41. package/dist/components/mg-input-file.js +1 -1
  42. package/dist/components/mg-input-numeric.js +1 -1
  43. package/dist/components/mg-input-password.js +1 -1
  44. package/dist/components/mg-input-radio.js +1 -1
  45. package/dist/components/mg-input-rich-text-editor.js +282 -282
  46. package/dist/components/mg-input-select2.js +1 -1
  47. package/dist/components/mg-input-text2.js +1 -1
  48. package/dist/components/mg-input-textarea.js +1 -1
  49. package/dist/components/mg-input-toggle.js +1 -1
  50. package/dist/components/mg-input2.js +1 -1
  51. package/dist/components/mg-loader2.js +1 -1
  52. package/dist/components/mg-menu-item2.js +1 -1
  53. package/dist/components/mg-message2.js +1 -1
  54. package/dist/components/mg-modal.js +1 -1
  55. package/dist/components/mg-panel.js +1 -1
  56. package/dist/components/mg-popover-content2.js +1 -1
  57. package/dist/components/mg-popover2.js +1 -1
  58. package/dist/components/mg-progress.js +1 -1
  59. package/dist/components/mg-skip-links.js +1 -1
  60. package/dist/components/mg-tabs2.js +1 -1
  61. package/dist/components/mg-tooltip2.js +1 -1
  62. package/dist/custom-elements.json +19 -0
  63. package/dist/esm/loader.js +1 -1
  64. package/dist/esm/mg-action-more_36.entry.js +217 -95
  65. package/dist/esm/mg-components.js +1 -1
  66. package/dist/esm/mg-illustration.entry.js +1 -1
  67. package/dist/esm/mg-input-combobox.entry.js +25 -7
  68. package/dist/esm/mg-input-file.entry.js +1 -1
  69. package/dist/esm/mg-input-rich-text-editor.entry.js +1595 -637
  70. package/dist/esm/mg-loader.entry.js +1 -1
  71. package/dist/esm/mg-progress.entry.js +1 -1
  72. package/dist/mg-components/mg-components.esm.js +1 -1
  73. package/dist/mg-components/{p-3ad7441c.entry.js → p-32a55ddb.entry.js} +1 -1
  74. package/dist/mg-components/p-6f492676.entry.js +1667 -0
  75. package/dist/mg-components/p-813d69c7.entry.js +1 -0
  76. package/dist/mg-components/p-85ebacd6.entry.js +1 -0
  77. package/dist/mg-components/p-a2445605.entry.js +1 -0
  78. package/dist/mg-components/{p-96fc508e.entry.js → p-c2beff2c.entry.js} +1 -1
  79. package/dist/mg-components/p-f308e2e4.entry.js +1 -0
  80. package/dist/types/components/atoms/mg-tooltip/mg-tooltip.d.ts +33 -6
  81. package/dist/types/components/molecules/inputs/mg-input/mg-input.d.ts +2 -1
  82. package/dist/types/components/molecules/inputs/mg-input-combobox/mg-input-combobox.d.ts +11 -0
  83. package/dist/types/components/molecules/mg-form/mg-form.d.ts +4 -0
  84. package/dist/types/components/molecules/mg-illustrated-message/mg-illustrated-message.conf.d.ts +8 -0
  85. package/dist/types/components/molecules/mg-illustrated-message/mg-illustrated-message.d.ts +9 -1
  86. package/dist/types/components.d.ts +13 -2
  87. package/ide/intellij/web-types.json +12 -2
  88. package/ide/vscode/html-custom-data.json +26 -1
  89. package/package.json +20 -20
  90. package/dist/collection/components/molecules/inputs/mg-input-rich-text-editor/editor/custom-properties.scss +0 -212
  91. package/dist/mg-components/p-4693077a.entry.js +0 -1
  92. package/dist/mg-components/p-5dff879a.entry.js +0 -1
  93. package/dist/mg-components/p-b20f3698.entry.js +0 -1
  94. package/dist/mg-components/p-ec4bd337.entry.js +0 -1667
  95. package/dist/mg-components/p-f8e58181.entry.js +0 -1
@@ -30,6 +30,13 @@ export class MgTooltip {
30
30
  * Disable tooltip
31
31
  */
32
32
  this.disabled = false;
33
+ /**
34
+ * Toggle the popper scroll and resize listeners, only needed while the tooltip is visible
35
+ * @param enabled - listeners state to apply
36
+ */
37
+ this.setPopperEventListeners = (enabled) => {
38
+ this.popper.setOptions((options) => (Object.assign(Object.assign({}, options), { modifiers: [...options.modifiers, { name: 'eventListeners', enabled }] })));
39
+ };
33
40
  /**
34
41
  * Show tooltip
35
42
  */
@@ -37,7 +44,7 @@ export class MgTooltip {
37
44
  // Make the tooltip visible
38
45
  this.mgTooltipContent.dataset.show = '';
39
46
  // Enable the event listeners
40
- this.popper.setOptions((options) => (Object.assign(Object.assign({}, options), { modifiers: [...options.modifiers, { name: 'eventListeners', enabled: true }] })));
47
+ this.setPopperEventListeners(true);
41
48
  // hide when click outside on nextTick to prevent event to trigger after creation
42
49
  nextTick(() => {
43
50
  this.windows.forEach((localWindow) => {
@@ -53,7 +60,7 @@ export class MgTooltip {
53
60
  // Hide the tooltip
54
61
  this.mgTooltipContent.removeAttribute('data-show');
55
62
  // Disable the event listeners
56
- this.popper.setOptions((options) => (Object.assign(Object.assign({}, options), { modifiers: [...options.modifiers, { name: 'eventListeners', enabled: false }] })));
63
+ this.setPopperEventListeners(false);
57
64
  // Remove event listener
58
65
  this.windows.forEach((localWindow) => {
59
66
  localWindow.removeEventListener('click', this.handleClickOutside, false);
@@ -117,6 +124,47 @@ export class MgTooltip {
117
124
  this.resetGuard = () => {
118
125
  this.guard = undefined;
119
126
  };
127
+ /**
128
+ * Display tooltip when the tooltiped element takes focus
129
+ */
130
+ this.handleTooltipedElementFocus = () => {
131
+ this.guard = Guard.FOCUS;
132
+ this.setDisplay(true);
133
+ };
134
+ /**
135
+ * Hide tooltip when the tooltiped element loses focus
136
+ */
137
+ this.handleTooltipedElementBlur = () => {
138
+ this.resetGuard();
139
+ this.setDisplay(false);
140
+ };
141
+ /**
142
+ * Display tooltip when the tooltiped element is hovered
143
+ */
144
+ this.handleTooltipedElementMouseenter = () => {
145
+ this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIPED_ELEMENT, 'mouseenter', Guard.HOVER_TOOLTIP_ELEMENT);
146
+ };
147
+ /**
148
+ * Hide tooltip when the tooltiped element is not hovered anymore
149
+ */
150
+ this.handleTooltipedElementMouseleave = () => {
151
+ this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIPED_ELEMENT, 'mouseleave', Guard.HOVER_TOOLTIP_ELEMENT);
152
+ };
153
+ /**
154
+ * Manage all tooltiped element listeners
155
+ * @param element - element to bind or unbind
156
+ * @param action - process to apply on element listeners
157
+ */
158
+ this.manageTooltipedElementListeners = (element, action) => {
159
+ element[action]('focus', this.handleTooltipedElementFocus);
160
+ // as `click` event is the composition of `mousedown` and `mouseup` event,
161
+ // and `click` event trigger `focus` event after a success `mousedown` wich set the `guard` to `Guard.FOCUS`
162
+ // we reset the guard on `mouseup` event to unlock tooltip
163
+ element[action]('mouseup', this.resetGuard);
164
+ element[action]('blur', this.handleTooltipedElementBlur);
165
+ element[action]('mouseenter', this.handleTooltipedElementMouseenter);
166
+ element[action]('mouseleave', this.handleTooltipedElementMouseleave);
167
+ };
120
168
  /**
121
169
  * Update slot content when it is a mg-button
122
170
  * @param mgButton - slotted mg-button
@@ -143,10 +191,11 @@ export class MgTooltip {
143
191
  }
144
192
  };
145
193
  /**
146
- * Set popper instance
147
- * @param strategy - popper strategy to apply on instance
194
+ * Set popper instance on the current tooltiped element
148
195
  */
149
- this.setPopper = (strategy) => {
196
+ this.setPopper = () => {
197
+ // mg-popover content is already `fixed`: position a nested tooltip relatively to it
198
+ const strategy = this.element.closest('mg-popover') !== null ? 'absolute' : 'fixed';
150
199
  // Create popperjs tooltip
151
200
  this.popper = createPopper(this.tooltipedElement, this.mgTooltipContent, {
152
201
  placement: this.placement,
@@ -172,29 +221,20 @@ export class MgTooltip {
172
221
  * @param element - tooltiped element
173
222
  */
174
223
  this.setTooltipedElement = (element) => {
224
+ // unbind the previous element so its listeners do not stack up on every `disabled` toggle
225
+ if (this.tooltipedElement !== undefined) {
226
+ this.manageTooltipedElementListeners(this.tooltipedElement, 'removeEventListener');
227
+ }
175
228
  this.tooltipedElement = element;
176
- // Manage tooltipedElement focus events
177
- this.tooltipedElement.addEventListener('focus', () => {
178
- this.guard = Guard.FOCUS;
179
- this.setDisplay(true);
180
- });
181
- // as `click` event is the composition of `mousedown` and `mouseup` event,
182
- // and `click` event trigger `focus` event after a success `mousedown` wich set the `guard` to `Guard.FOCUS`
183
- // we reset the guard on `mouseup` event to unlock tooltip
184
- this.tooltipedElement.addEventListener('mouseup', () => {
185
- this.resetGuard();
186
- });
187
- this.tooltipedElement.addEventListener('blur', () => {
188
- this.resetGuard();
189
- this.setDisplay(false);
190
- });
191
- // manage tooltipElement & tooltipedElement mouseenter/mouseleave events
192
- this.tooltipedElement.addEventListener('mouseenter', () => {
193
- this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIPED_ELEMENT, 'mouseenter', Guard.HOVER_TOOLTIP_ELEMENT);
194
- });
195
- this.tooltipedElement.addEventListener('mouseleave', () => {
196
- this.tooltipMouseListenerAction(Guard.HOVER_TOOLTIPED_ELEMENT, 'mouseleave', Guard.HOVER_TOOLTIP_ELEMENT);
197
- });
229
+ this.manageTooltipedElementListeners(this.tooltipedElement, 'addEventListener');
230
+ // popper freezes its reference element, so re-create it to follow the new one.
231
+ // The initial instance comes from `componentDidLoad`.
232
+ if (this.popper !== undefined) {
233
+ this.popper.destroy();
234
+ this.setPopper();
235
+ // a fresh instance has its listeners enabled, realign them
236
+ this.setPopperEventListeners(this.display);
237
+ }
198
238
  };
199
239
  /**
200
240
  * Set button mutation observer
@@ -222,17 +262,36 @@ export class MgTooltip {
222
262
  }).observe(mgButton, { attributes: true });
223
263
  };
224
264
  /**
225
- * Set tooltiped element aria-describedby
226
- * @param element - element to update
265
+ * Reconcile the tooltiped element a11y: the tooltip is restituted — `aria-describedby` exposed, and a
266
+ * non-interactive element made focusable (`tabindex` + `role`) — unless it is disabled and not displayed.
267
+ * Pre-existing `aria-describedby` ids are preserved.
227
268
  */
228
- this.setAriaDescribedby = (element) => {
229
- // Set aria-describedby
230
- if (!element.hasAttribute('aria-describedby')) {
231
- this.tooltipedElement.setAttribute('aria-describedby', this.identifier);
269
+ this.updateTooltipedElementA11y = () => {
270
+ const restitute = !this.disabled || this.display;
271
+ const currentValue = this.tooltipedElement.getAttribute('aria-describedby');
272
+ const ids = new Set(currentValue !== null ? currentValue.split(' ') : []);
273
+ if (restitute) {
274
+ ids.add(this.identifier);
275
+ }
276
+ else {
277
+ ids.delete(this.identifier);
278
+ }
279
+ if (ids.size > 0) {
280
+ this.tooltipedElement.setAttribute('aria-describedby', [...ids].join(' '));
232
281
  }
233
282
  else {
234
- // We ensure to have uniq ids
235
- element.setAttribute('aria-describedby', `${[...new Set([...element.getAttribute('aria-describedby').split(' '), this.identifier])].join(' ')}`);
283
+ this.tooltipedElement.removeAttribute('aria-describedby');
284
+ }
285
+ if (this.hasCustomTabIndex) {
286
+ if (restitute) {
287
+ this.tooltipedElement.setAttribute('role', 'button');
288
+ if (!this.tooltipedElement.hasAttribute('tabindex'))
289
+ this.tooltipedElement.setAttribute('tabindex', '0');
290
+ }
291
+ else {
292
+ this.tooltipedElement.removeAttribute('role');
293
+ this.tooltipedElement.removeAttribute('tabindex');
294
+ }
236
295
  }
237
296
  };
238
297
  }
@@ -257,14 +316,11 @@ export class MgTooltip {
257
316
  else {
258
317
  this.hide();
259
318
  }
319
+ this.updateTooltipedElementA11y();
260
320
  }
261
- watchDisabled(newValue) {
262
- if (this.hasCustomTabIndex) {
263
- if (newValue)
264
- this.tooltipedElement.removeAttribute('tabindex');
265
- else if (!this.tooltipedElement.hasAttribute('tabindex'))
266
- this.tooltipedElement.setAttribute('tabindex', '0');
267
- }
321
+ watchDisabled() {
322
+ // Only fires on runtime changes; the initial reconcile is done in componentDidLoad via watchDisplay.
323
+ this.updateTooltipedElementA11y();
268
324
  }
269
325
  /**
270
326
  * Render tooltip content element and init listeners
@@ -304,7 +360,6 @@ export class MgTooltip {
304
360
  // Get tooltip element
305
361
  this.renderTooltipContent();
306
362
  //validate properties
307
- this.watchDisabled(this.disabled);
308
363
  this.watchMessage(this.message);
309
364
  this.watchIdentifier(this.identifier);
310
365
  }
@@ -333,20 +388,13 @@ export class MgTooltip {
333
388
  if (this.element.querySelector('mg-button[full-width]') !== null) {
334
389
  this.element.classList.add('mg-c-tooltip--full-width');
335
390
  }
336
- // Add tabindex to slotted element if we can't find any interactive element
337
- if (!this.disabled && [undefined, null].includes(interactiveElement)) {
338
- this.hasCustomTabIndex = true;
339
- slotElement.tabIndex = 0;
340
- // Add role on non-interactive element to work with "aria-describedby" for screen readers
341
- slotElement.setAttribute('role', 'button');
342
- }
343
- // apply a11y aria
344
- this.setAriaDescribedby(slotElement);
391
+ // Non-interactive slotted element (no focusable element found): needs synthesized focus to be reachable.
392
+ this.hasCustomTabIndex = [undefined, null].includes(interactiveElement);
345
393
  // set Tooltip
346
- this.setPopper(this.element.closest('mg-popover') !== null ? 'absolute' : 'fixed');
394
+ this.setPopper();
347
395
  // add document keyboard handler
348
396
  document.addEventListener('keydown', this.handlePressEscape);
349
- // check props
397
+ // check props (also does the initial a11y reconcile)
350
398
  this.watchDisplay(this.display);
351
399
  }
352
400
  /**
@@ -371,7 +419,7 @@ export class MgTooltip {
371
419
  * @returns HTML Element
372
420
  */
373
421
  render() {
374
- return (h(Host, { key: '5cd926147c1b6723065c5334699764f32a8a06c9' }, h("slot", { key: 'a1b208798c79e34a207f3bedb2ad9662e02e83e2' }), h("slot", { key: '4f332961968fd3541caf47c2fd9072720fa2ee71', name: "content" })));
422
+ return (h(Host, { key: '1e9cfc59c335510c21d159253e3f8e1b4256a465' }, h("slot", { key: 'c52d57e3302d4865a2365ac62c931af2948bdf03' }), h("slot", { key: '527b5d8ae562ed1f5faed74356f10be5aca10ac4', name: "content" })));
375
423
  }
376
424
  static get is() { return "mg-tooltip"; }
377
425
  static get encapsulation() { return "shadow"; }
@@ -14,7 +14,38 @@ export class MgInput {
14
14
  // helpText/errorMessage are injected via innerHTML and may contain HTML: when block content
15
15
  // is detected we fall back to <div> to keep the markup valid (RGAA 8.2), otherwise we use a
16
16
  // semantic <p> for the (textual) message (RGAA 8.9).
17
- this.blockLevelContentRegExp = /<(address|article|aside|blockquote|details|dialog|div|dl|fieldset|figure|figcaption|footer|form|h[1-6]|header|hr|main|nav|ol|p|pre|section|table|ul)[\s/>]/i;
17
+ this.blockLevelTags = new Set([
18
+ 'address',
19
+ 'article',
20
+ 'aside',
21
+ 'blockquote',
22
+ 'details',
23
+ 'dialog',
24
+ 'div',
25
+ 'dl',
26
+ 'fieldset',
27
+ 'figure',
28
+ 'figcaption',
29
+ 'footer',
30
+ 'form',
31
+ 'h1',
32
+ 'h2',
33
+ 'h3',
34
+ 'h4',
35
+ 'h5',
36
+ 'h6',
37
+ 'header',
38
+ 'hr',
39
+ 'main',
40
+ 'nav',
41
+ 'ol',
42
+ 'p',
43
+ 'pre',
44
+ 'section',
45
+ 'table',
46
+ 'ul',
47
+ ]);
48
+ this.openingTagRegExp = /<([a-z1-6]+)[\s/>]/gi;
18
49
  // style
19
50
  this.classInput = 'mg-c-input';
20
51
  this.classHasError = 'mg-c-input--has-error';
@@ -292,7 +323,11 @@ export class MgInput {
292
323
  * @returns the tag name to use
293
324
  */
294
325
  getSlotMessageTagName(content) {
295
- return this.blockLevelContentRegExp.test(content) ? 'div' : 'p';
326
+ for (const [, tagName] of content.matchAll(this.openingTagRegExp)) {
327
+ if (this.blockLevelTags.has(tagName.toLowerCase()))
328
+ return 'div';
329
+ }
330
+ return 'p';
296
331
  }
297
332
  /**
298
333
  * Get the existing slotted element or (re)create it with the expected tag.
@@ -366,10 +401,10 @@ export class MgInput {
366
401
  */
367
402
  render() {
368
403
  const isGroup = this.isFieldset && !this.isReadonly;
369
- return (h(Host, { key: 'e5803717999bac5e4a08910008176baeb426f634', class: this.element.classList.toString(), role: isGroup ? 'group' : undefined, "aria-labelledby": isGroup ? `${this.identifier}-title` : undefined }, h("div", { key: '32b04b05e8a4352536965fcd792f3c206dad9270', class: { 'mg-c-input__title': true, 'mg-u-visually-hidden': this.labelHide } }, h("slot", { key: '2bb360ff8b4a86facb0b7f97fdf7dbbb49b5f6c0', name: this.slotLabel }), this.tooltip &&
404
+ return (h(Host, { key: '5a321d04d50aa63f86237a1dd72d2ac508b8d4cf', class: this.element.classList.toString(), role: isGroup ? 'group' : undefined, "aria-labelledby": isGroup ? `${this.identifier}-title` : undefined }, h("div", { key: '5d247500c19370d6ee1de79e14ef0c016fe38f7a', class: { 'mg-c-input__title': true, 'mg-u-visually-hidden': this.labelHide } }, h("slot", { key: 'cf56e42a0b56ab855a1b6089fbbd573ef5676b3d', name: this.slotLabel }), this.tooltip &&
370
405
  (this.tooltipPosition === 'label' || this.labelOnTop) &&
371
406
  !this.labelHide &&
372
- this.renderTooltip()), h("div", { key: '0c6751757d182029e1ac6ea4f8a4fcc7aeffb85e', class: "mg-c-input__input-container" }, this.inputContainerElements())));
407
+ this.renderTooltip()), h("div", { key: 'dfc9112bb933c1c536bdb4e9ef462e0f921a0b82', class: "mg-c-input__input-container" }, this.inputContainerElements())));
373
408
  }
374
409
  static get is() { return "mg-input"; }
375
410
  static get encapsulation() { return "shadow"; }
@@ -295,9 +295,7 @@ export class MgInputCheckbox {
295
295
  * Renders the readonly value of the input.
296
296
  * @returns The rendered readonly value.
297
297
  */
298
- this.renderReadonly = (readonlyValue) => {
299
- return this.inputVerticalList ? (h("ul", { class: "mg-c-input__readonly-value" }, readonlyValue.map((value) => (h("li", { key: value }, h("b", null, value)))))) : (h("b", { class: "mg-c-input__readonly-value" }, readonlyValue.join(', ')));
300
- };
298
+ this.renderReadonly = (readonlyValue) => (h("b", { class: "mg-c-input__readonly-value" }, readonlyValue.join(', ')));
301
299
  /**
302
300
  * Renders the MgInputCheckboxList component.
303
301
  * @returns The rendered MgInputCheckboxList component.
@@ -605,7 +603,7 @@ export class MgInputCheckbox {
605
603
  else {
606
604
  inputContent = this.renderCheckboxMulti();
607
605
  }
608
- return (h("mg-input", { key: '8e403fd79ca8a9bb2db5545e946a3763eb156551', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: !this.readonly ? this.required : undefined, tooltip: this.tooltip, tooltipPosition: this.readonly && readonlyValue.length === 0 ? 'label' : this.tooltipPosition, helpText: !this.readonly ? this.helpText : undefined, errorMessage: !this.readonly ? this.errorMessage : undefined }, inputContent));
606
+ return (h("mg-input", { key: 'e243244fb902cf960d112502e4627a787212db31', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: !this.readonly ? this.required : undefined, tooltip: this.tooltip, tooltipPosition: this.readonly && readonlyValue.length === 0 ? 'label' : this.tooltipPosition, helpText: !this.readonly ? this.helpText : undefined, errorMessage: !this.readonly ? this.errorMessage : undefined }, inputContent));
609
607
  }
610
608
  static get is() { return "mg-input-checkbox"; }
611
609
  static get encapsulation() { return "shadow"; }
@@ -352,11 +352,29 @@ export class MgInputCombobox {
352
352
  }
353
353
  }
354
354
  };
355
+ /**
356
+ * Check if an option matches the current filter
357
+ * @param option - option to match
358
+ * @returns true if the option matches the filter
359
+ */
360
+ this.matchFilter = (option) => this.filter === '' || option.title.toLocaleLowerCase().includes(this.filter.toLocaleLowerCase());
361
+ /**
362
+ * Get all the options matching the current filter
363
+ * @returns filtered options
364
+ */
365
+ this.getFilteredOptions = () => this.options.items.filter(this.matchFilter);
355
366
  /**
356
367
  * Get first page with filter applied
357
368
  * @returns first page with filter applied
358
369
  */
359
- this.getFirstPage = () => this.options.getPage(0, (option) => this.filter === '' || option.title.toLocaleLowerCase().includes(this.filter.toLocaleLowerCase()));
370
+ this.getFirstPage = () => {
371
+ const page = this.options.getPage(0, this.matchFilter);
372
+ // `Paginate` keeps the unfiltered total: realign it with the filtered options, except in
373
+ // `fetchurl` mode where the total counts the options left to load
374
+ if (this.fetchurl === undefined)
375
+ page.total = this.getFilteredOptions().length;
376
+ return page;
377
+ };
360
378
  /**
361
379
  * Loading wrapper with a given action
362
380
  * @param action - wrapped loading action
@@ -400,9 +418,7 @@ export class MgInputCombobox {
400
418
  return promise()
401
419
  .then(() => {
402
420
  // parse full items list from options
403
- const options = this.filter === ''
404
- ? this.options.items
405
- : this.options.items.filter((option) => option.title.includes(this.filter));
421
+ const options = this.getFilteredOptions();
406
422
  // update visual focus
407
423
  if (action.name !== 'load-data') {
408
424
  index = this.page.getIndexFromCursor(action.cursor, this.loadingAction === 'load-more' && index >= 0 ? options[index] : this.option);
@@ -439,7 +455,9 @@ export class MgInputCombobox {
439
455
  return nextTick(() => {
440
456
  if (typeof this.page.next === 'function') {
441
457
  const nextPage = this.page.next();
442
- this.page = new Page(Object.assign(Object.assign({}, nextPage), { items: [...this.page.items, ...nextPage.items] }));
458
+ this.page = new Page(Object.assign(Object.assign({}, nextPage), { items: [...this.page.items, ...nextPage.items],
459
+ // `Paginate` keeps the unfiltered total, realign it as in `getFirstPage`
460
+ total: this.getFilteredOptions().length }));
443
461
  }
444
462
  });
445
463
  }
@@ -778,7 +796,7 @@ export class MgInputCombobox {
778
796
  else {
779
797
  activeDescendant = (_e = this.value) === null || _e === void 0 ? void 0 : _e.value;
780
798
  }
781
- return (h("mg-input", { key: 'c8cff9468c9bfdcc6dd5c96c1452ad81620e050c', label: this.label, identifier: this.identifier, class: this.classCollection.classes.join(' '), ariaDescribedbyIDs: popoverContent && popoverContent !== 'list' ? popoverContent : undefined, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (readonlyValue && h("b", { class: "mg-c-input__readonly-value" }, readonlyValue)) : (h("mg-popover", { identifier: this.popoverId, placement: this.popoverPlacement, display: this.popoverDisplay, style: {
799
+ return (h("mg-input", { key: '047c14310f70117e1aec89161d2261f175487be7', label: this.label, identifier: this.identifier, class: this.classCollection.classes.join(' '), ariaDescribedbyIDs: popoverContent && popoverContent !== 'list' ? popoverContent : undefined, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (readonlyValue && h("b", { class: "mg-c-input__readonly-value" }, readonlyValue)) : (h("mg-popover", { identifier: this.popoverId, placement: this.popoverPlacement, display: this.popoverDisplay, style: {
782
800
  '--mg-c-input-list-width': ((_f = this.input) === null || _f === void 0 ? void 0 : _f.offsetWidth) > 0 ? `${this.input.offsetWidth}px` : undefined,
783
801
  }, "data-fallback-placement": "bottom-end", "onDisplay-change": this.handlePopoverDisplay }, h("div", { class: "mg-c-input__input-group-container" }, h("mg-icon", { icon: "magnifying-glass" }), h("input", { type: "text", role: "combobox", class: "mg-c-input__box mg-c-input__box--width", value: this.filter, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, autocomplete: "off", "aria-autocomplete": "list", "aria-expanded": this.popoverDisplay.toString(), "aria-controls": listId, "aria-invalid": (this.invalid === true).toString(), "aria-activedescendant": formatID(activeDescendant), onInput: this.handleFilterInput, onBlur: this.handleFilterBlur, onFocus: this.handleFilterFocus, onKeyDown: this.handleFilterKeydown, ref: (el) => {
784
802
  if (el !== null)
@@ -250,10 +250,11 @@ export class MgInputPassword {
250
250
  * @returns HTML Element
251
251
  */
252
252
  render() {
253
- return (h("mg-input", { key: '0a59c7177c65ccb255164e4ef45945b1ade5ad70', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (this.value !== undefined && h("b", { class: "mg-c-input__readonly-value" }, '•'.repeat(this.value.length))) : (h("span", { class: "mg-c-input__input-group" }, h("input", { type: this.displayPassword ? 'text' : 'password', class: "mg-c-input__box mg-c-input__box--width", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, maxlength: this.maxlength, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
253
+ const displayPasswordIcon = this.displayPassword ? 'eye-slash' : 'eye';
254
+ return (h("mg-input", { key: '913d0653faad21f56cb930dfdc0947a0747f17ad', label: this.label, identifier: this.identifier, class: this.classCollection.join(), labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.readonly && this.value === undefined ? 'label' : this.tooltipPosition, helpText: this.helpText, errorMessage: this.errorMessage }, this.readonly ? (this.value !== undefined && h("b", { class: "mg-c-input__readonly-value" }, '•'.repeat(this.value.length))) : (h("span", { class: "mg-c-input__input-group" }, h("input", { type: this.displayPassword ? 'text' : 'password', class: "mg-c-input__box mg-c-input__box--width", value: this.value, id: this.identifier, name: this.name, placeholder: this.placeholder, title: this.placeholder, disabled: this.disabled, required: this.required, maxlength: this.maxlength, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, ref: (el) => {
254
255
  if (el !== null)
255
256
  this.input = el;
256
- } }), h("mg-button", { label: this.messages.input.password[this.displayPassword ? 'hide' : 'display'], disabled: this.disabled, variant: "flat", class: "mg-c-input__append-button", "is-icon": true, onClick: this.toggleDisplayPassword, "aria-controls": this.identifier }, h("mg-icon", { class: "mg-c-input__input-icon", icon: (this.displayPassword ? 'eye-slash' : 'eye') }))))));
257
+ } }), h("mg-button", { label: this.messages.input.password[this.displayPassword ? 'hide' : 'display'], disabled: this.disabled, variant: "flat", class: "mg-c-input__append-button", "is-icon": true, onClick: this.toggleDisplayPassword, "aria-controls": this.identifier }, h("mg-icon", { class: "mg-c-input__input-icon", icon: displayPasswordIcon }))))));
257
258
  }
258
259
  static get is() { return "mg-input-password"; }
259
260
  static get encapsulation() { return "shadow"; }
@@ -0,0 +1,50 @@
1
+ /* Jodit theming overrides
2
+ *
3
+ * Jodit's own defaults are provided by jodit.css (loaded with :root rewritten to :host).
4
+ * This layer only holds the values the design system intentionally overrides — mainly px
5
+ * sizes converted to rem for scalable UI, plus a few color adjustments. It must load after
6
+ * jodit.css so these win.
7
+ */
8
+ :host {
9
+ --jd-color-background-button-hover-opacity30: rgb(234 234 234 / 30%);
10
+ --jd-color-background-filebrowser-folders: rgb(248 249 250);
11
+ --jd-color-button-background-hover-opacity40: rgb(219 219 219 / 40%);
12
+ --jd-color-button-background-hover-opacity60: rgb(219 219 219 / 60%);
13
+ --jd-color-table-cell-background-hover: rgb(0 0 0 / 5%);
14
+ --jd-dark-text-color-opacity50: rgb(206 206 206 / 50%);
15
+ --jd-dark-text-color-opacity80: rgb(206 206 206 / 80%);
16
+ --jd-dark-toolbar-seperator-color3: rgb(105 105 105 / 75%);
17
+ --jd-dark-toolbar-seperator-color-opacity80: rgb(105 105 105 / 80%);
18
+ --jd-color-picker-cell-size: 2.4rem;
19
+ --jd-button-icon-size: 1.4rem;
20
+ --jd-button-trigger-size: 1.4rem;
21
+ --jd-button-df-size: calc((var(--jd-button-icon-size) - 0.4rem) * 2);
22
+ --jd-icon-size: 1.2rem;
23
+ --jd-icon-loader-size: 4.8rem;
24
+ --jd-height: 1.8rem;
25
+ --jd-height-element-default: 1.8rem;
26
+ --jd-height-search: 3rem;
27
+ --jd-input-height: 3.2rem;
28
+ --jd-switche-height: 3.2rem;
29
+ --jd-viewer-height: 2.4rem;
30
+ --jd-width-default: 18rem;
31
+ --jd-width-element-default: 1.8rem;
32
+ --jd-width-search: 32rem;
33
+ --jd-viewer-width: 7rem;
34
+ --jd-switche-width: 6rem;
35
+ --jd-col-size: 15rem;
36
+ --jd-padding-default: 0.8rem;
37
+ --jd-margin-v: 0.2rem;
38
+ --jd-switche-slider-margin: 0.4rem;
39
+ --jd-resizer-handle-size: 1rem;
40
+ --jd-border-radius-default: 0.3rem;
41
+ --jd-font-size-default: 1.4rem;
42
+ --jd-font-size-small: 1.1rem;
43
+ --jd-box-shadow-1: 0 0.8rem 1.6rem rgb(0 0 0 / 19%);
44
+ --jd-box-shadow-blur: 1.6rem;
45
+ --jd-box-shadow-tabs: 0 0.2rem 0.4rem rgb(0 0 0 / 10%);
46
+ --jd-popup-box-shadow: 0 0.4rem 0.1rem -0.2rem rgb(76 76 76 / 20%), 0 0.3rem 0.3rem 0 rgb(76 76 76 / 15%), 0 0.1rem 0.4rem 0 rgb(76 76 76 / 13%);
47
+ --jd-popup-max-height: max(50vh, 35rem);
48
+ --jd-focus-input-box-shadow: 0 0 0 0.05rem rgb(0 123 255 / 25%);
49
+ --jd-anl-handle-size: 2rem;
50
+ }
@@ -502,7 +502,7 @@ export class MgInputRichTextEditor {
502
502
  * @returns HTML mg-input Element
503
503
  */
504
504
  render() {
505
- return (h("mg-input", { key: '9197857a6c004416b96632c9009d110958c8eb15', identifier: this.identifier, class: this.classCollection.join(), label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.tooltipPosition, helpText: this.helpText, errorMessage: this.hasDisplayedError ? this.errorMessage : undefined }, this.readonly ? (h("div", { class: "mg-c-input__readonly-value", innerHTML: this.value })) : (h("div", { id: this.identifier, class: "mg-c-input__wrapper" }, h("textarea", { name: this.name, ref: (el) => {
505
+ return (h("mg-input", { key: 'c42ba3eb1eafa645fa0774d65090c7819168ffd7', identifier: this.identifier, class: this.classCollection.join(), label: this.label, labelOnTop: this.labelOnTop, labelHide: this.labelHide, required: this.required, tooltip: this.tooltip, tooltipPosition: this.tooltipPosition, helpText: this.helpText, errorMessage: this.hasDisplayedError ? this.errorMessage : undefined }, this.readonly ? (h("div", { class: "mg-c-input__readonly-value", innerHTML: this.value })) : (h("div", { id: this.identifier, class: "mg-c-input__wrapper" }, h("textarea", { name: this.name, ref: (el) => {
506
506
  if (el !== null)
507
507
  this.editorElement = el;
508
508
  } })))));
@@ -511,12 +511,12 @@ export class MgInputRichTextEditor {
511
511
  static get encapsulation() { return "shadow"; }
512
512
  static get originalStyleUrls() {
513
513
  return {
514
- "$": ["./editor/custom-properties.scss", "../../../../../node_modules/jodit/es2021/jodit.css", "../../../../../node_modules/@mgdis/styles/dist/components/mg-input-rich-text-editor.css"]
514
+ "$": ["../../../../assets/jodit/jodit.css", "./editor/custom-properties.css", "../../../../../node_modules/@mgdis/styles/dist/components/mg-input-rich-text-editor.css"]
515
515
  };
516
516
  }
517
517
  static get styleUrls() {
518
518
  return {
519
- "$": ["editor/custom-properties.css", "../../../../../node_modules/jodit/es2021/jodit.css", "../../../../../node_modules/@mgdis/styles/dist/components/mg-input-rich-text-editor.css"]
519
+ "$": ["../../../../assets/jodit/jodit.css", "editor/custom-properties.css", "../../../../../node_modules/@mgdis/styles/dist/components/mg-input-rich-text-editor.css"]
520
520
  };
521
521
  }
522
522
  static get properties() {
@@ -55,7 +55,11 @@ export class MgDetails {
55
55
  * @returns HTML Element
56
56
  */
57
57
  render() {
58
- return (h("details", { key: '78dbeab3b3e6c245bda8fad5900b70727fd47595', class: { 'mg-c-details': true, 'mg-c-details--empty-summary': this.isEmptySummary }, onToggle: this.handleToggle, open: this.expanded, ref: (el) => (this.details = el) }, h("summary", { key: '766e4756a66a1f8e6bc2159f30133a0702353f32' }, h("slot", { key: '3473dd0c0fc7de78c1d7ae6f9ee4a4d2fc7835ee', name: "summary" }), h("span", { key: '7c8d3da4df69d2802f104caaf568ac513f9f03b6', class: "mg-c-details__toggle" }, h("mg-icon", { key: '44da384780ab768bde20acb58885280e193de921', icon: "chevron-up", class: { 'mg-c-details__toggle-icon': true, 'mg-c-details__toggle-icon--reverse': !this.expanded } }), h("span", { key: '387de0caa5ae819c89449e5063e0b6e05b3df8fe', class: { 'mg-u-visually-hidden': this.hideSummary } }, this.expanded ? this.toggleOpened : this.toggleClosed))), h("div", { key: '48c1fe8df990a250f098594d9b50df947613955c', class: "mg-c-details__details" }, h("slot", { key: '95554b4d890750cc3b3008965be3e5954d49d810', name: "details" }))));
58
+ return (h("details", { key: '12eac25682e22d65ace61f6697656459d1494903', class: {
59
+ 'mg-c-details': true,
60
+ 'mg-c-details--hide-summary': this.hideSummary,
61
+ 'mg-c-details--empty-summary': this.isEmptySummary,
62
+ }, onToggle: this.handleToggle, open: this.expanded, ref: (el) => (this.details = el) }, h("summary", { key: 'd6d621db04bca17297f770a633fcb17711f99ecf' }, h("slot", { key: '245aad29a2f2cd93e3a5426ce1e010ab6f5b5e07', name: "summary" }), h("span", { key: 'ebfe3c80a00b9b7a38a670f536a3984420ec3945', class: "mg-c-details__toggle" }, h("mg-icon", { key: '73c4eb27b3d6aa9168bf6af9fa118afc51b8ee1a', icon: "chevron-up", class: { 'mg-c-details__toggle-icon': true, 'mg-c-details__toggle-icon--reverse': !this.expanded } }), h("span", { key: '96730ec386137f7f3aa463b76c20547a5922f294', class: { 'mg-u-visually-hidden': this.hideSummary } }, this.expanded ? this.toggleOpened : this.toggleClosed))), h("div", { key: '8ac6eee499e613a543fd2a2ea9d954719d48005d', class: "mg-c-details__details" }, h("slot", { key: '37af4674491d7857163dcc48424e652cfcefbed6', name: "details" }))));
59
63
  }
60
64
  static get is() { return "mg-details"; }
61
65
  static get encapsulation() { return "shadow"; }
@@ -39,6 +39,10 @@ export class MgForm {
39
39
  * Component classes
40
40
  */
41
41
  this.classCollection = new ClassList(['mg-c-form']);
42
+ /**
43
+ * Whether the form has slotted actions
44
+ */
45
+ this.hasActions = false;
42
46
  /**
43
47
  * Define required message based on mg-inputs required elements
44
48
  */
@@ -205,6 +209,8 @@ export class MgForm {
205
209
  this.validateAriaRole(this.ariaRole);
206
210
  this.validateRequiredMessage(this.requiredMessage);
207
211
  this.handlelabelOnTop(this.labelOnTop);
212
+ // Detect slotted actions
213
+ this.hasActions = this.element.querySelector('[slot="actions"]') !== null;
208
214
  // Get slotted mgButtons
209
215
  this.mgButtons = Array.from(this.element.querySelectorAll('mg-button'));
210
216
  // Set button form identifier
@@ -239,6 +245,7 @@ export class MgForm {
239
245
  if (mutations.some((mutation) => Object.keys(observerOptions).includes(mutation.type))) {
240
246
  this.setMgInputs();
241
247
  this.checkValidity();
248
+ this.hasActions = this.element.querySelector('[slot="actions"]') !== null;
242
249
  }
243
250
  }).observe(this.element, observerOptions);
244
251
  }
@@ -247,7 +254,7 @@ export class MgForm {
247
254
  * @returns HTML Element
248
255
  */
249
256
  render() {
250
- return (h("form", { key: '65d3e11931386af2dedd953f58505e2c71cd99ff', class: this.classCollection.join(), id: this.identifier, name: this.name, onSubmit: this.handleFormSubmit, role: this.ariaRole }, this.requiredMessageText && h("p", { key: '7546db3b8a4259fd7d092cc7b912b6593fab9d84', innerHTML: this.requiredMessageText }), h("slot", { key: '0023ed360230ea97395a249b230e02bb7a4bdbda' }), !this.readonly && !this.disabled && h("slot", { key: 'de84e088ff029eff487be1ed8b4766425c558c29', name: "actions" })));
257
+ return (h("form", { key: 'c851e6f19af32f28cad695daa1f42ddff10796a0', class: this.classCollection.join(), id: this.identifier, name: this.name, onSubmit: this.handleFormSubmit, role: this.ariaRole }, this.requiredMessageText && h("p", { key: '7f92b35872c938e87959acac8841937ad503d98f', innerHTML: this.requiredMessageText }), h("slot", { key: 'e75e90f1fe3076d93df82a7a426b17d82035e0cf' }), !this.readonly && !this.disabled && this.hasActions && (h("div", { key: 'a472cf024a61d6be1665d149749ce7d560a00473', class: "mg-c-form__actions" }, h("slot", { key: 'f9098c711cb2d2714057c4f14d6df295b75de774', name: "actions" })))));
251
258
  }
252
259
  static get is() { return "mg-form"; }
253
260
  static get encapsulation() { return "shadow"; }
@@ -458,7 +465,8 @@ export class MgForm {
458
465
  static get states() {
459
466
  return {
460
467
  "classCollection": {},
461
- "requiredMessageText": {}
468
+ "requiredMessageText": {},
469
+ "hasActions": {}
462
470
  };
463
471
  }
464
472
  static get events() {
@@ -6,3 +6,7 @@ export const sizes = ['small', 'medium', 'large'];
6
6
  * List of all possibles directions
7
7
  */
8
8
  export const directions = ['vertical', 'horizontal'];
9
+ /**
10
+ * List of all possibles horizontal alignments
11
+ */
12
+ export const aligns = ['left', 'center', 'right'];