@mgdis/mg-components 6.17.0 → 6.19.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 (127) hide show
  1. package/dist/cjs/{index-DCZEYvlH.js → index-Bp6wZzau.js} +5 -1
  2. package/dist/cjs/loader.cjs.js +2 -2
  3. package/dist/cjs/mg-action-more_37.cjs.entry.js +438 -212
  4. package/dist/cjs/mg-alert.cjs.entry.js +2 -2
  5. package/dist/cjs/mg-components.cjs.js +2 -2
  6. package/dist/cjs/mg-fieldset.cjs.entry.js +141 -0
  7. package/dist/cjs/mg-input-combobox.cjs.entry.js +93 -80
  8. package/dist/cjs/mg-input-rich-text-editor.cjs.entry.js +35 -26
  9. package/dist/cjs/{mg-input.conf-WTsvDfpC.js → mg-input.conf-D7jmj_lh.js} +7 -0
  10. package/dist/cjs/mg-loader.cjs.entry.js +2 -2
  11. package/dist/cjs/mg-progress.cjs.entry.js +2 -2
  12. package/dist/collection/assets/icons/index.js +1 -1
  13. package/dist/collection/collection-manifest.json +1 -0
  14. package/dist/collection/components/atoms/mg-icon/mg-icon.js +1 -1
  15. package/dist/collection/components/molecules/inputs/mg-input/mg-input.conf.js +5 -0
  16. package/dist/collection/components/molecules/inputs/mg-input/mg-input.js +178 -18
  17. package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox-paginated/mg-input-checkbox-paginated.js +1 -1
  18. package/dist/collection/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.js +36 -16
  19. package/dist/collection/components/molecules/inputs/mg-input-combobox/mg-input-combobox.js +98 -78
  20. package/dist/collection/components/molecules/inputs/mg-input-date/mg-input-date.js +41 -22
  21. package/dist/collection/components/molecules/inputs/mg-input-numeric/mg-input-numeric.js +32 -12
  22. package/dist/collection/components/molecules/inputs/mg-input-password/mg-input-password.js +30 -12
  23. package/dist/collection/components/molecules/inputs/mg-input-radio/mg-input-radio.js +31 -12
  24. package/dist/collection/components/molecules/inputs/mg-input-rich-text-editor/mg-input-rich-text-editor.js +41 -25
  25. package/dist/collection/components/molecules/inputs/mg-input-select/mg-input-select.js +31 -12
  26. package/dist/collection/components/molecules/inputs/mg-input-text/mg-input-text.js +60 -40
  27. package/dist/collection/components/molecules/inputs/mg-input-textarea/mg-input-textarea.js +35 -33
  28. package/dist/collection/components/molecules/inputs/mg-input-toggle/mg-input-toggle.js +36 -11
  29. package/dist/collection/components/molecules/internals/mg-item-more/mg-item-more.js +1 -1
  30. package/dist/collection/components/molecules/menus/mg-menu/mg-menu.js +5 -1
  31. package/dist/collection/components/molecules/mg-action-more/mg-action-more.js +2 -2
  32. package/dist/collection/components/molecules/mg-alert/mg-alert.js +1 -1
  33. package/dist/collection/components/molecules/mg-details/mg-details.js +1 -1
  34. package/dist/collection/components/molecules/mg-fieldset/mg-fieldset.js +404 -0
  35. package/dist/collection/components/molecules/mg-form/mg-form.js +13 -4
  36. package/dist/collection/components/molecules/mg-illustrated-message/mg-illustrated-message.js +1 -1
  37. package/dist/collection/components/molecules/mg-loader/mg-loader.js +1 -1
  38. package/dist/collection/components/molecules/mg-message/mg-message.js +2 -2
  39. package/dist/collection/components/molecules/mg-modal/mg-modal.js +2 -2
  40. package/dist/collection/components/molecules/mg-panel/mg-panel.js +40 -9
  41. package/dist/collection/components/molecules/mg-popover/mg-popover-content/mg-popover-content.js +1 -1
  42. package/dist/collection/components/molecules/mg-popover/mg-popover.js +1 -1
  43. package/dist/collection/components/molecules/mg-progress/mg-progress.js +1 -1
  44. package/dist/collection/components/molecules/mg-skip-links/mg-skip-links.js +1 -1
  45. package/dist/collection/components/molecules/mg-tabs/mg-tabs.js +1 -1
  46. package/dist/components/mg-action-more.js +1 -1
  47. package/dist/components/mg-alert.js +1 -1
  48. package/dist/components/mg-details.js +1 -1
  49. package/dist/components/mg-fieldset.d.ts +11 -0
  50. package/dist/components/mg-fieldset.js +209 -0
  51. package/dist/components/mg-form.js +4 -3
  52. package/dist/components/mg-icon2.js +1 -1
  53. package/dist/components/mg-illustrated-message.js +2 -2
  54. package/dist/components/mg-input-checkbox-paginated2.js +1 -1
  55. package/dist/components/mg-input-checkbox.js +29 -16
  56. package/dist/components/mg-input-combobox.js +92 -79
  57. package/dist/components/mg-input-date.js +34 -22
  58. package/dist/components/mg-input-numeric.js +25 -12
  59. package/dist/components/mg-input-password.js +23 -12
  60. package/dist/components/mg-input-radio.js +23 -11
  61. package/dist/components/mg-input-rich-text-editor.js +33 -24
  62. package/dist/components/mg-input-select2.js +24 -12
  63. package/dist/components/mg-input-text2.js +51 -39
  64. package/dist/components/mg-input-textarea.js +28 -33
  65. package/dist/components/mg-input-toggle.js +35 -10
  66. package/dist/components/mg-input2.js +119 -19
  67. package/dist/components/mg-item-more2.js +5 -1
  68. package/dist/components/mg-loader2.js +1 -1
  69. package/dist/components/mg-message2.js +2 -2
  70. package/dist/components/mg-modal.js +3 -3
  71. package/dist/components/mg-panel.js +37 -8
  72. package/dist/components/mg-popover-content2.js +2 -2
  73. package/dist/components/mg-popover2.js +2 -2
  74. package/dist/components/mg-progress.js +1 -1
  75. package/dist/components/mg-skip-links.js +1 -1
  76. package/dist/components/mg-tabs2.js +1 -1
  77. package/dist/esm/{index-T6kOJXP1.js → index-BluNKQ3L.js} +5 -1
  78. package/dist/esm/{index-WtiuOkLj.js → index-C7xjtdiw.js} +1 -1
  79. package/dist/esm/loader.js +3 -3
  80. package/dist/esm/mg-action-more_37.entry.js +439 -213
  81. package/dist/esm/mg-alert.entry.js +3 -3
  82. package/dist/esm/mg-components.js +3 -3
  83. package/dist/esm/mg-fieldset.entry.js +139 -0
  84. package/dist/esm/mg-input-combobox.entry.js +94 -81
  85. package/dist/esm/mg-input-rich-text-editor.entry.js +36 -27
  86. package/dist/esm/{mg-input.conf-CNgv8hc5.js → mg-input.conf-DDnrE1hD.js} +6 -1
  87. package/dist/esm/mg-loader.entry.js +3 -3
  88. package/dist/esm/mg-progress.entry.js +3 -3
  89. package/dist/mg-components/mg-components.css +1 -1
  90. package/dist/mg-components/mg-components.esm.js +1 -1
  91. package/dist/mg-components/p-016bd291.entry.js +1 -0
  92. package/dist/mg-components/{p-397bf67b.entry.js → p-186a6139.entry.js} +1 -1
  93. package/dist/mg-components/p-66a1cb83.entry.js +1 -0
  94. package/dist/mg-components/p-6efd819f.entry.js +1 -0
  95. package/dist/mg-components/{p-c5da335e.entry.js → p-916dfb6d.entry.js} +1 -1
  96. package/dist/mg-components/p-BluNKQ3L.js +2 -0
  97. package/dist/mg-components/{p-WtiuOkLj.js → p-C7xjtdiw.js} +1 -1
  98. package/dist/mg-components/p-DDnrE1hD.js +1 -0
  99. package/dist/mg-components/{p-0e6b40d6.entry.js → p-d2c72f09.entry.js} +1 -1
  100. package/dist/mg-components/{p-5dc3a1fb.entry.js → p-d5a276eb.entry.js} +1 -1
  101. package/dist/types/assets/icons/index.d.ts +9 -0
  102. package/dist/types/components/molecules/inputs/mg-input/mg-input.conf.d.ts +6 -0
  103. package/dist/types/components/molecules/inputs/mg-input/mg-input.d.ts +32 -1
  104. package/dist/types/components/molecules/inputs/mg-input-checkbox/mg-input-checkbox.d.ts +4 -3
  105. package/dist/types/components/molecules/inputs/mg-input-combobox/mg-input-combobox.conf.d.ts +1 -0
  106. package/dist/types/components/molecules/inputs/mg-input-combobox/mg-input-combobox.d.ts +8 -7
  107. package/dist/types/components/molecules/inputs/mg-input-date/mg-input-date.d.ts +4 -2
  108. package/dist/types/components/molecules/inputs/mg-input-numeric/mg-input-numeric.d.ts +4 -2
  109. package/dist/types/components/molecules/inputs/mg-input-password/mg-input-password.d.ts +4 -2
  110. package/dist/types/components/molecules/inputs/mg-input-radio/mg-input-radio.d.ts +4 -2
  111. package/dist/types/components/molecules/inputs/mg-input-rich-text-editor/mg-input-rich-text-editor.d.ts +4 -3
  112. package/dist/types/components/molecules/inputs/mg-input-select/mg-input-select.d.ts +4 -2
  113. package/dist/types/components/molecules/inputs/mg-input-text/mg-input-text.d.ts +5 -7
  114. package/dist/types/components/molecules/inputs/mg-input-textarea/mg-input-textarea.d.ts +4 -8
  115. package/dist/types/components/molecules/inputs/mg-input-toggle/mg-input-toggle.d.ts +4 -2
  116. package/dist/types/components/molecules/mg-fieldset/mg-fieldset.d.ts +105 -0
  117. package/dist/types/components/molecules/mg-form/mg-form.d.ts +1 -1
  118. package/dist/types/components/molecules/mg-panel/mg-panel.d.ts +8 -1
  119. package/dist/types/components.d.ts +168 -18
  120. package/ide/intellij/web-types.json +289 -22
  121. package/ide/vscode/css-custom-data.json +7 -3
  122. package/ide/vscode/html-custom-data.json +300 -8
  123. package/package.json +18 -18
  124. package/dist/mg-components/p-8a69175b.entry.js +0 -1
  125. package/dist/mg-components/p-CNgv8hc5.js +0 -1
  126. package/dist/mg-components/p-T6kOJXP1.js +0 -2
  127. package/dist/mg-components/p-d84d87ea.entry.js +0 -1
@@ -26,7 +26,7 @@ const isFetchmappings = (value) => {
26
26
  const { request, response } = value;
27
27
  if ([request, response].some(property => !isObject(property)))
28
28
  return false;
29
- const isValidRequest = typeof request.filter === 'string';
29
+ const isValidRequest = typeof request.filter === 'string' && (request.filterTransform === undefined || typeof request.filterTransform === 'function');
30
30
  const isValidResponse = typeof response === 'object' &&
31
31
  typeof response.total === 'string' &&
32
32
  typeof response.items === 'string' &&
@@ -41,13 +41,9 @@ const isFetchmappings = (value) => {
41
41
  };
42
42
  export class MgInputCombobox {
43
43
  constructor() {
44
- /************
45
- * Internal *
46
- ************/
47
- // Classes
48
- this.classFocus = 'mg-u-is-focused';
49
44
  // hasDisplayedError (triggered by blur event)
50
45
  this.hasDisplayedError = false;
46
+ this.customErrorMessage = { lock: false };
51
47
  /**
52
48
  * Input name
53
49
  * If not set the value equals the identifier
@@ -102,7 +98,7 @@ export class MgInputCombobox {
102
98
  * @param event - option element click event
103
99
  */
104
100
  this.handleOptionClick = (event) => {
105
- this.setValue(this.options.items.find(option => formatID(option.value) === event.target.id));
101
+ this.setValue(this.options.items.find(option => toString(option.value) === event.target.dataset.value));
106
102
  this.popoverDisplay = false;
107
103
  };
108
104
  /**
@@ -182,7 +178,7 @@ export class MgInputCombobox {
182
178
  // override keys actions
183
179
  switch (event.key) {
184
180
  case Keys.TAB:
185
- case Keys.ENTER:
181
+ case Keys.ENTER: {
186
182
  guard = event.key === Keys.ENTER;
187
183
  const option = (_a = this.option) !== null && _a !== void 0 ? _a : this.options.items.find(this.isCurrentOption);
188
184
  // Sets the value to the content of the focused option in the listbox.
@@ -192,12 +188,13 @@ export class MgInputCombobox {
192
188
  // Closes the popover.
193
189
  this.popoverDisplay = false;
194
190
  break;
191
+ }
195
192
  case Keys.DOWN:
196
193
  case Keys.ARROWDOWN:
197
194
  case Keys.UP:
198
- case Keys.ARROWUP:
195
+ case Keys.ARROWUP: {
199
196
  guard = true;
200
- if (this.isLoading || !(this.page.total > 0)) {
197
+ if (this.isLoading || this.page.total === 0) {
201
198
  this.popoverDisplay = true;
202
199
  break;
203
200
  }
@@ -228,12 +225,13 @@ export class MgInputCombobox {
228
225
  // open popover
229
226
  this.popoverDisplay = true;
230
227
  break;
228
+ }
231
229
  case Keys.LEFT:
232
230
  case Keys.ARROWLEFT:
233
231
  case Keys.HOME:
234
232
  case Keys.RIGHT:
235
233
  case Keys.ARROWRIGHT:
236
- case Keys.END:
234
+ case Keys.END: {
237
235
  // skip process if visual focus is not in popover
238
236
  if (!isItem(this.option))
239
237
  break;
@@ -253,8 +251,9 @@ export class MgInputCombobox {
253
251
  this.input.setSelectionRange(index, index);
254
252
  }
255
253
  break;
254
+ }
256
255
  case Keys.ESC:
257
- case Keys.ESCAPE:
256
+ case Keys.ESCAPE: {
258
257
  guard = true;
259
258
  if (this.popoverDisplay) {
260
259
  // If the popover is displayed, closes it.
@@ -268,10 +267,12 @@ export class MgInputCombobox {
268
267
  this.option = null;
269
268
  }
270
269
  break;
271
- default:
270
+ }
271
+ default: {
272
272
  // Remove visual focus from popover options
273
273
  this.option = null;
274
274
  break;
275
+ }
275
276
  }
276
277
  if (guard) {
277
278
  event.stopPropagation();
@@ -317,40 +318,41 @@ export class MgInputCombobox {
317
318
  };
318
319
  /**
319
320
  * Set input error message
320
- * @param errorMessage - errorMessage override
321
+ * @param fromSetErrorContext - context come from `setError` method
321
322
  */
322
- this.setErrorMessage = (errorMessage) => {
323
+ this.setErrorMessage = (fromSetErrorContext = false) => {
323
324
  // Set error message
324
325
  this.errorMessage = undefined;
325
- // Does have a custom error message
326
- if (!this.valid && errorMessage !== undefined) {
327
- this.errorMessage = errorMessage;
328
- }
329
- // required
330
- else if (!this.valid && this.input.validity.valueMissing) {
331
- this.errorMessage = this.messages.errors.required;
326
+ if (!this.valid) {
327
+ // Does have a new custom error message OR does have a custom error message locked
328
+ if (fromSetErrorContext || (this.customErrorMessage.lock && this.customErrorMessage.message !== undefined)) {
329
+ this.errorMessage = this.customErrorMessage.message;
330
+ }
331
+ // required
332
+ else if (this.input.validity.valueMissing) {
333
+ this.errorMessage = this.messages.errors.required;
334
+ }
332
335
  }
333
336
  };
334
337
  /**
335
- * Get filtered options from `filter` input value
336
- * @returns filtered options
338
+ * Get first page with filter applied
339
+ * @returns first page with filter applied
337
340
  */
338
- this.optionsFilter = (option) => (this.filter === '' ? true : option.title.toLocaleLowerCase().includes(this.filter.toLocaleLowerCase()));
341
+ this.getFirstPage = () => this.options.getPage(0, option => this.filter === '' || option.title.toLocaleLowerCase().includes(this.filter.toLocaleLowerCase()));
339
342
  /**
340
343
  * Loading wrapper with a given action
341
344
  * @param action - wrapped loading action
342
345
  * @returns promisified action
343
346
  */
344
347
  this.loadingWrapper = (action) => {
348
+ var _a;
345
349
  let promise;
346
350
  let index;
347
351
  // cache initial loading action if not defined
348
- if (!Boolean(this.loadingAction)) {
349
- this.loadingAction = action.name;
350
- }
352
+ (_a = this.loadingAction) !== null && _a !== void 0 ? _a : (this.loadingAction = action.name);
351
353
  // update index
352
354
  if (Boolean(this.option) && this.loadingAction !== 'load-more') {
353
- index = this.page.items.findIndex(option => option.value.toString() === this.option.value.toString());
355
+ index = this.page.items.findIndex(option => toString(option.value) === toString(this.option.value));
354
356
  }
355
357
  else if (this.loadingAction === 'load-more') {
356
358
  index = this.page.items.length - this.page.baseIndex;
@@ -380,7 +382,7 @@ export class MgInputCombobox {
380
382
  return promise()
381
383
  .then(() => {
382
384
  // parse full items list from options
383
- const options = this.options.items.filter(this.optionsFilter);
385
+ const options = this.filter === '' ? this.options.items : this.options.items.filter(option => option.title.includes(this.filter));
384
386
  // update visual focus
385
387
  if (action.name !== 'load-data') {
386
388
  index = this.page.getIndexFromCursor(action.cursor, this.loadingAction === 'load-more' && index >= 0 ? options[index] : this.option);
@@ -403,14 +405,14 @@ export class MgInputCombobox {
403
405
  */
404
406
  this.goToNextPage = () => {
405
407
  this.showMore.emit();
406
- if (Boolean(this.fetchurl)) {
408
+ if (this.fetchurl !== undefined) {
407
409
  return this.getOptions(typeof this.page.next === 'string' ? this.page.next : undefined).then(nextPage => {
408
- if (!Boolean(nextPage))
409
- return;
410
- // merge items from current page and next page
411
- const items = [...this.page.items, ...nextPage.items];
412
- // create new options pagination withe merged items
413
- this.options = new Paginate(items, { total: nextPage.total, next: nextPage.next, top: items.length });
410
+ if (nextPage !== undefined) {
411
+ // merge items from current page and next page
412
+ const items = [...this.page.items, ...nextPage.items];
413
+ // create new options pagination withe merged items
414
+ this.options = new Paginate(items, { total: nextPage.total, next: nextPage.next, top: items.length });
415
+ }
414
416
  });
415
417
  }
416
418
  else {
@@ -427,16 +429,16 @@ export class MgInputCombobox {
427
429
  * @returns promise
428
430
  */
429
431
  this.updatePage = async () => {
430
- if (Boolean(this.fetchurl)) {
432
+ if (this.fetchurl !== undefined) {
431
433
  return this.getOptions().then(page => {
432
- if (!Boolean(page))
433
- return;
434
- // reset current options pagination from API response
435
- this.options = new Paginate(page.items, { total: page.total, next: page.next, top: page.top });
434
+ if (page !== undefined) {
435
+ // reset current options pagination from API response
436
+ this.options = new Paginate(page.items, { total: page.total, next: page.next, top: page.top });
437
+ }
436
438
  });
437
439
  }
438
440
  else {
439
- this.page = this.options.getPage(0, this.optionsFilter);
441
+ this.page = this.getFirstPage();
440
442
  }
441
443
  };
442
444
  /**
@@ -445,8 +447,9 @@ export class MgInputCombobox {
445
447
  * @returns new page from url
446
448
  */
447
449
  this.getOptions = async (url = this.fetchurl) => {
448
- // add text filter
449
- const updateUrl = (typeof url === 'string' ? url : url.toString()).replaceAll(this.fetchmappings.request.filter, encodeURIComponent(this.filter));
450
+ // add text filter to url
451
+ const filter = typeof this.fetchmappings.request.filterTransform === 'function' ? this.fetchmappings.request.filterTransform(this.filter) : this.filter;
452
+ const updateUrl = (typeof url === 'string' ? url : url.toString()).replaceAll(this.fetchmappings.request.filter, encodeURIComponent(filter));
450
453
  try {
451
454
  const response = await fetch(updateUrl, this.fetchoptions);
452
455
  if (!response.ok) {
@@ -454,10 +457,13 @@ export class MgInputCombobox {
454
457
  return;
455
458
  }
456
459
  const json = await response.json();
457
- const items = getObjectValueFromKey(json, this.fetchmappings.response.items).map((item) => ({
458
- title: getObjectValueFromKey(item, this.fetchmappings.response.itemTitle),
459
- value: this.fetchmappings.response.itemValue !== undefined ? getObjectValueFromKey(item, this.fetchmappings.response.itemValue) : item,
460
- }));
460
+ const items = getObjectValueFromKey(json, this.fetchmappings.response.items).map((item) => {
461
+ var _a;
462
+ return ({
463
+ title: getObjectValueFromKey(item, this.fetchmappings.response.itemTitle),
464
+ value: (_a = getObjectValueFromKey(item, this.fetchmappings.response.itemValue)) !== null && _a !== void 0 ? _a : item,
465
+ });
466
+ });
461
467
  const total = Number(getObjectValueFromKey(json, this.fetchmappings.response.total, 0));
462
468
  let next = getObjectValueFromKey(json, this.fetchmappings.response.next);
463
469
  if (URL.canParse(updateUrl) && Boolean(next) && !URL.canParse(next)) {
@@ -478,11 +484,11 @@ export class MgInputCombobox {
478
484
  this.valueChange.emit(newValue);
479
485
  }
480
486
  watchItems(newValue) {
481
- if (Boolean(this.fetchurl) && !Boolean(newValue)) {
487
+ if (this.fetchurl !== undefined && newValue === undefined) {
482
488
  // skip newValue check
483
489
  return;
484
490
  }
485
- else if (Boolean(this.fetchurl) && Boolean(newValue)) {
491
+ else if (this.fetchurl !== undefined && newValue !== undefined) {
486
492
  throw new Error(`<mg-input-combobox> prop "items" values cannot be use with "fetchurl" prop defined. Passed value: ${toString(newValue)}.`);
487
493
  }
488
494
  // Empty options
@@ -502,7 +508,7 @@ export class MgInputCombobox {
502
508
  }
503
509
  }
504
510
  watchIdentifier(newValue) {
505
- if (Boolean(newValue)) {
511
+ if (isValidString(newValue)) {
506
512
  this.popoverId = `${newValue}-popover`;
507
513
  this.element.dataset.mgPopoverGuard = this.popoverId;
508
514
  }
@@ -542,7 +548,7 @@ export class MgInputCombobox {
542
548
  this.classCollection = new ClassList(this.classCollection.classes);
543
549
  }
544
550
  watchFetchUrl(newValue) {
545
- if (Boolean(newValue)) {
551
+ if (newValue !== undefined) {
546
552
  this.loadingWrapper({ name: 'load-data' });
547
553
  }
548
554
  }
@@ -550,20 +556,17 @@ export class MgInputCombobox {
550
556
  if (this.fetchurl && newValue && !isObject(newValue)) {
551
557
  throw new Error(`<mg-input-combobox> prop "fetchoptions" value must be a valid RequestInit. Passed value: ${toString(newValue)}.`);
552
558
  }
553
- else {
554
- new Request(this.fetchurl, newValue);
555
- }
556
559
  }
557
560
  watchFetchMappings(newValue) {
558
- if (Boolean(this.fetchurl) && !Boolean(newValue)) {
561
+ if (this.fetchurl !== undefined && !isObject(newValue)) {
559
562
  throw new Error(`<mg-input-combobox> prop "fetchmappings" is required with "fetchurl" prop.`);
560
563
  }
561
- else if (Boolean(newValue) && !isFetchmappings(newValue)) {
564
+ else if (newValue !== undefined && !isFetchmappings(newValue)) {
562
565
  throw new Error(`<mg-input-combobox> prop "fetchmappings" value must be { request: RequestMappingType, response: ResponseMappingType }. Passed value: ${toString(newValue)}.`);
563
566
  }
564
567
  }
565
- watchOptions(newValue) {
566
- this.page = newValue.getPage(0, Boolean(this.filter) ? this.optionsFilter : undefined);
568
+ watchOptions() {
569
+ this.page = this.getFirstPage();
567
570
  }
568
571
  watchFilter(newValue) {
569
572
  this.loadingWrapper({ name: 'load-data' });
@@ -571,7 +574,6 @@ export class MgInputCombobox {
571
574
  }
572
575
  watchPopoverDisplay(newValue) {
573
576
  if (newValue) {
574
- this.classCollection.add(this.classFocus);
575
577
  this.input.focus();
576
578
  }
577
579
  else {
@@ -579,7 +581,6 @@ export class MgInputCombobox {
579
581
  this.option = null;
580
582
  // reset filter with value
581
583
  this.filter = this.getValueTitle();
582
- this.classCollection.delete(this.classFocus);
583
584
  this.handlerInProgress = 'blur';
584
585
  this.displayError().finally(() => {
585
586
  // reset guard
@@ -620,17 +621,22 @@ export class MgInputCombobox {
620
621
  * When used to set validity to `false`, you should use this method again to reset the validity to `true`.
621
622
  * @param valid - value indicating the validity
622
623
  * @param errorMessage - the error message to display
624
+ * @param errorMessageLock - lock the error message and validity state
623
625
  */
624
- async setError(valid, errorMessage) {
626
+ async setError(valid, errorMessage, errorMessageLock = false) {
625
627
  if (typeof valid !== 'boolean') {
626
628
  throw new Error('<mg-input-combobox> method "setError()" param "valid" must be a boolean.');
627
629
  }
628
- else if (!isValidString(errorMessage)) {
630
+ else if (errorMessage !== undefined && !isValidString(errorMessage)) {
629
631
  throw new Error('<mg-input-combobox> method "setError()" param "errorMessage" must be a string.');
630
632
  }
631
633
  else {
634
+ this.customErrorMessage = {
635
+ lock: valid ? false : errorMessageLock,
636
+ message: valid ? undefined : errorMessage,
637
+ };
632
638
  this.setValidity(valid);
633
- this.setErrorMessage(valid ? undefined : errorMessage);
639
+ this.setErrorMessage(true);
634
640
  this.hasDisplayedError = this.invalid;
635
641
  }
636
642
  }
@@ -650,6 +656,8 @@ export class MgInputCombobox {
650
656
  // - Keep everything in sync both inside and outside the component
651
657
  return new Promise(resolve => {
652
658
  requestAnimationFrame(() => {
659
+ // unlock validity check by reseting customErrorMessage
660
+ this.customErrorMessage = { lock: false };
653
661
  this.checkValidity();
654
662
  this.errorMessage = undefined;
655
663
  this.hasDisplayedError = false;
@@ -678,11 +686,13 @@ export class MgInputCombobox {
678
686
  * @param newValue - valid new value
679
687
  */
680
688
  setValidity(newValue) {
681
- const oldValidValue = this.valid;
682
- this.valid = newValue;
689
+ const oldValue = this.valid;
690
+ if (!this.customErrorMessage.lock || (this.customErrorMessage.message !== undefined && !newValue)) {
691
+ this.valid = newValue;
692
+ }
683
693
  this.invalid = !this.valid;
684
694
  // We need to send valid event even if it is the same value
685
- if (this.handlerInProgress === undefined || (this.handlerInProgress === 'blur' && this.valid !== oldValidValue))
695
+ if (this.handlerInProgress === undefined || (this.handlerInProgress === 'blur' && this.valid !== oldValue))
686
696
  this.inputValid.emit(this.valid);
687
697
  }
688
698
  /*************
@@ -698,13 +708,13 @@ export class MgInputCombobox {
698
708
  // Validate
699
709
  this.watchIdentifier(this.identifier);
700
710
  this.watchItems(this.items);
701
- if (Boolean(this.fetchurl)) {
711
+ if (this.fetchurl !== undefined) {
702
712
  this.watchFetchOptions(this.fetchoptions);
703
713
  this.watchFetchMappings(this.fetchmappings);
704
714
  this.loadingWrapper({ name: 'load-data' });
705
715
  }
706
716
  this.watchValue(this.value);
707
- this.watchOptions(this.options);
717
+ this.watchOptions();
708
718
  this.watchMgWidth(this.mgWidth);
709
719
  this.watchReadonly(this.readonly);
710
720
  this.watchDisabled(this.disabled);
@@ -725,14 +735,17 @@ export class MgInputCombobox {
725
735
  const readonlyValue = this.getValueTitle();
726
736
  const withResetButton = this.value && !this.disabled;
727
737
  let popoverContent;
728
- if (((_a = this.page) === null || _a === void 0 ? void 0 : _a.items.length) > 0)
738
+ if (((_a = this.page) === null || _a === void 0 ? void 0 : _a.items.length) > 0) {
729
739
  popoverContent = 'list';
730
- else if (((_b = this.page) === null || _b === void 0 ? void 0 : _b.items.length) === 0 && Boolean(this.filter))
740
+ }
741
+ else if (((_b = this.page) === null || _b === void 0 ? void 0 : _b.items.length) === 0 && this.filter.length > 0) {
731
742
  popoverContent = 'notfound';
732
- else if (((_c = this.page) === null || _c === void 0 ? void 0 : _c.items.length) === 0)
743
+ }
744
+ else if (((_c = this.page) === null || _c === void 0 ? void 0 : _c.items.length) === 0) {
733
745
  popoverContent = 'notavailable';
746
+ }
734
747
  let activeDescendant;
735
- if (Boolean((_d = this.option) === null || _d === void 0 ? void 0 : _d.value)) {
748
+ if (((_d = this.option) === null || _d === void 0 ? void 0 : _d.value) !== undefined) {
736
749
  activeDescendant = this.option.value;
737
750
  }
738
751
  else if (typeof this.value === 'string') {
@@ -741,8 +754,8 @@ export class MgInputCombobox {
741
754
  else {
742
755
  activeDescendant = (_e = this.value) === null || _e === void 0 ? void 0 : _e.value;
743
756
  }
744
- return (h("mg-input", { key: '79e5263cd3b1c0fa0b3f386a547f2bdd48a33b28', 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: "bottom-start", display: this.popoverDisplay, "arrow-hide": true, style: {
745
- '--mg-c-input-list-width': Boolean((_f = this.input) === null || _f === void 0 ? void 0 : _f.offsetWidth) ? `${this.input.offsetWidth}px` : undefined,
757
+ return (h("mg-input", { key: 'fd5a59f1e0bf31342a3bf935a60a2877e5df1772', 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: "bottom-start", display: this.popoverDisplay, "arrow-hide": true, style: {
758
+ '--mg-c-input-list-width': ((_f = this.input) === null || _f === void 0 ? void 0 : _f.offsetWidth) > 0 ? `${this.input.offsetWidth}px` : undefined,
746
759
  }, "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) => {
747
760
  if (el !== null)
748
761
  this.input = el;
@@ -756,7 +769,7 @@ export class MgInputCombobox {
756
769
  'mg-c-input__input-list-item': true,
757
770
  'mg-c-input__input-list-item--focus-visible': JSON.stringify((_a = this.option) === null || _a === void 0 ? void 0 : _a.value) === JSON.stringify(option.value),
758
771
  'mg-c-input__input-list-item--selected': this.isCurrentOption(option),
759
- }, key: option.title, id: formatID(option.value), "aria-selected": this.isCurrentOption(option).toString(), onClick: this.handleOptionClick }, option.title, this.isCurrentOption(option) && h("mg-icon", { icon: "check" })));
772
+ }, key: option.title, id: formatID(option.value), "aria-selected": this.isCurrentOption(option).toString(), "data-value": toString(option.value), onClick: this.handleOptionClick }, option.title, this.isCurrentOption(option) && h("mg-icon", { icon: "check" })));
760
773
  })),
761
774
  this.isLoading && h("mg-loader", { key: "loader", message: this.messages.input.combobox.search, class: { 'mg-u-visually-hidden': Boolean(this.page.next) } }),
762
775
  this.page.next && (h("mg-button", { key: "load-more", variant: "flat", class: "mg-c-input__load-more", tabIndex: -1, disabled: this.isLoading, "full-width": true, "disable-on-click": true, onClick: this.handleLoadMoreButton, "aria-controls": listId, ref: (el) => {
@@ -1384,7 +1397,7 @@ export class MgInputCombobox {
1384
1397
  },
1385
1398
  "setError": {
1386
1399
  "complexType": {
1387
- "signature": "(valid: MgInputCombobox[\"valid\"], errorMessage: string) => Promise<void>",
1400
+ "signature": "(valid: MgInputCombobox[\"valid\"], errorMessage?: string, errorMessageLock?: boolean) => Promise<void>",
1388
1401
  "parameters": [{
1389
1402
  "name": "valid",
1390
1403
  "type": "boolean",
@@ -1393,6 +1406,10 @@ export class MgInputCombobox {
1393
1406
  "name": "errorMessage",
1394
1407
  "type": "string",
1395
1408
  "docs": "- the error message to display"
1409
+ }, {
1410
+ "name": "errorMessageLock",
1411
+ "type": "boolean",
1412
+ "docs": "- lock the error message and validity state"
1396
1413
  }],
1397
1414
  "references": {
1398
1415
  "Promise": {
@@ -1414,6 +1431,9 @@ export class MgInputCombobox {
1414
1431
  }, {
1415
1432
  "name": "param",
1416
1433
  "text": "errorMessage - the error message to display"
1434
+ }, {
1435
+ "name": "param",
1436
+ "text": "errorMessageLock - lock the error message and validity state"
1417
1437
  }]
1418
1438
  }
1419
1439
  },
@@ -8,6 +8,7 @@ export class MgInputDate {
8
8
  constructor() {
9
9
  // hasDisplayedError (triggered by blur event)
10
10
  this.hasDisplayedError = false;
11
+ this.customErrorMessage = { lock: false };
11
12
  /**
12
13
  * Input name
13
14
  * If not set the value equals the identifier
@@ -120,39 +121,41 @@ export class MgInputDate {
120
121
  */
121
122
  this.getInputError = () => {
122
123
  var _a;
124
+ let error;
123
125
  // bad input or pattern
124
126
  if (this.input.validity.badInput || (this.value && !this.isValidPattern(this.value))) {
125
- return 'badInput';
127
+ error = 'badInput';
126
128
  }
127
129
  // required
128
- if (this.input.validity.valueMissing) {
129
- return 'required';
130
+ else if (this.input.validity.valueMissing) {
131
+ error = 'required';
130
132
  }
131
133
  // min & max
132
- if ((this.input.validity.rangeUnderflow || this.input.validity.rangeOverflow) && ((_a = this.min) === null || _a === void 0 ? void 0 : _a.length) > 0 && this.max !== DEFAULT_MAX_DATE) {
133
- return 'minMax';
134
+ else if ((this.input.validity.rangeUnderflow || this.input.validity.rangeOverflow) && ((_a = this.min) === null || _a === void 0 ? void 0 : _a.length) > 0 && this.max !== DEFAULT_MAX_DATE) {
135
+ error = 'minMax';
134
136
  }
135
137
  // min
136
- if (this.input.validity.rangeUnderflow) {
137
- return 'min';
138
+ else if (this.input.validity.rangeUnderflow) {
139
+ error = 'min';
138
140
  }
139
141
  // max
140
- if (this.input.validity.rangeOverflow) {
141
- return 'max';
142
+ else if (this.input.validity.rangeOverflow) {
143
+ error = 'max';
142
144
  }
143
- return null;
145
+ return error;
144
146
  };
145
147
  /**
146
148
  * Check input errors
147
- * @param errorMessage - errorMessage override
149
+ * @param fromSetErrorContext - context come from `setError` method
148
150
  */
149
- this.setErrorMessage = (errorMessage) => {
151
+ this.setErrorMessage = (fromSetErrorContext = false) => {
150
152
  // Set error message
151
153
  this.errorMessage = undefined;
152
154
  if (!this.valid) {
153
155
  const inputError = this.getInputError();
154
- if (errorMessage !== undefined) {
155
- this.errorMessage = errorMessage;
156
+ // Does have a new custom error message OR does have a custom error message locked
157
+ if (fromSetErrorContext || (this.customErrorMessage.lock && this.customErrorMessage.message !== undefined)) {
158
+ this.errorMessage = this.customErrorMessage.message;
156
159
  }
157
160
  // required
158
161
  else if (inputError === 'required') {
@@ -264,17 +267,22 @@ export class MgInputDate {
264
267
  * When used to set validity to `false`, you should use this method again to reset the validity to `true`.
265
268
  * @param valid - value indicating the validity
266
269
  * @param errorMessage - the error message to display
270
+ * @param errorMessageLock - lock the error message and validity state
267
271
  */
268
- async setError(valid, errorMessage) {
272
+ async setError(valid, errorMessage, errorMessageLock = false) {
269
273
  if (typeof valid !== 'boolean') {
270
274
  throw new Error('<mg-input-date> method "setError()" param "valid" must be a boolean.');
271
275
  }
272
- else if (!isValidString(errorMessage)) {
276
+ else if (errorMessage !== undefined && !isValidString(errorMessage)) {
273
277
  throw new Error('<mg-input-date> method "setError()" param "errorMessage" must be a string.');
274
278
  }
275
279
  else {
280
+ this.customErrorMessage = {
281
+ lock: valid ? false : errorMessageLock,
282
+ message: valid ? undefined : errorMessage,
283
+ };
276
284
  this.setValidity(valid);
277
- this.setErrorMessage(valid ? undefined : errorMessage);
285
+ this.setErrorMessage(true);
278
286
  this.hasDisplayedError = this.invalid;
279
287
  }
280
288
  }
@@ -292,6 +300,8 @@ export class MgInputDate {
292
300
  // - Keep everything in sync both inside and outside the component
293
301
  return new Promise(resolve => {
294
302
  requestAnimationFrame(() => {
303
+ // unlock validity check by reseting customErrorMessage
304
+ this.customErrorMessage = { lock: false };
295
305
  this.checkValidity();
296
306
  this.errorMessage = undefined;
297
307
  this.hasDisplayedError = false;
@@ -305,11 +315,13 @@ export class MgInputDate {
305
315
  * @param newValue - valid new value
306
316
  */
307
317
  setValidity(newValue) {
308
- const oldValidValue = this.valid;
309
- this.valid = newValue;
318
+ const oldValue = this.valid;
319
+ if (!this.customErrorMessage.lock || (this.customErrorMessage.message !== undefined && !newValue)) {
320
+ this.valid = newValue;
321
+ }
310
322
  this.invalid = !this.valid;
311
323
  // We need to send valid event even if it is the same value
312
- if (this.handlerInProgress === undefined || (this.handlerInProgress === 'blur' && this.valid !== oldValidValue))
324
+ if (this.handlerInProgress === undefined || (this.handlerInProgress === 'blur' && this.valid !== oldValue))
313
325
  this.inputValid.emit(this.valid);
314
326
  }
315
327
  /*************
@@ -345,7 +357,7 @@ export class MgInputDate {
345
357
  * @returns HTML Element
346
358
  */
347
359
  render() {
348
- return (h("mg-input", { key: '31c223be6c69af4ffa89f74102c41a27040ad031', 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 === null ? 'label' : this.tooltipPosition, helpText: this.formatHelpText(this.helpText), errorMessage: this.errorMessage }, this.readonly ? (this.value && h("b", { class: "mg-c-input__readonly-value" }, localeDate(this.value, this.locale))) : (h("input", { type: "date", class: "mg-c-input__box", min: this.min, max: this.max, value: this.value, id: this.identifier, name: this.name, disabled: this.disabled, required: this.required, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, ref: (el) => {
360
+ return (h("mg-input", { key: '1428f0f9f11d829ec8d3ed507c8690d63839ff17', 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 === null ? 'label' : this.tooltipPosition, helpText: this.formatHelpText(this.helpText), errorMessage: this.errorMessage }, this.readonly ? (this.value && h("b", { class: "mg-c-input__readonly-value" }, localeDate(this.value, this.locale))) : (h("input", { type: "date", class: "mg-c-input__box", min: this.min, max: this.max, value: this.value, id: this.identifier, name: this.name, disabled: this.disabled, required: this.required, "aria-invalid": (this.invalid === true).toString(), onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, ref: (el) => {
349
361
  if (el !== null)
350
362
  this.input = el;
351
363
  } }))));
@@ -771,7 +783,7 @@ export class MgInputDate {
771
783
  },
772
784
  "setError": {
773
785
  "complexType": {
774
- "signature": "(valid: MgInputDate[\"valid\"], errorMessage: string) => Promise<void>",
786
+ "signature": "(valid: MgInputDate[\"valid\"], errorMessage?: string, errorMessageLock?: boolean) => Promise<void>",
775
787
  "parameters": [{
776
788
  "name": "valid",
777
789
  "type": "boolean",
@@ -780,6 +792,10 @@ export class MgInputDate {
780
792
  "name": "errorMessage",
781
793
  "type": "string",
782
794
  "docs": "- the error message to display"
795
+ }, {
796
+ "name": "errorMessageLock",
797
+ "type": "boolean",
798
+ "docs": "- lock the error message and validity state"
783
799
  }],
784
800
  "references": {
785
801
  "Promise": {
@@ -801,6 +817,9 @@ export class MgInputDate {
801
817
  }, {
802
818
  "name": "param",
803
819
  "text": "errorMessage - the error message to display"
820
+ }, {
821
+ "name": "param",
822
+ "text": "errorMessageLock - lock the error message and validity state"
804
823
  }]
805
824
  }
806
825
  },