@sapudex/web-components 0.231.4 → 0.231.6

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 (188) hide show
  1. package/dist/Assets.d.ts +1 -0
  2. package/dist/Assets.js +1 -0
  3. package/dist/Assets.js.map +1 -1
  4. package/dist/ControlButton.d.ts +3 -1
  5. package/dist/ControlButton.js +13 -3
  6. package/dist/ControlButton.js.map +1 -1
  7. package/dist/CountrySelector.d.ts +2 -2
  8. package/dist/CountrySelector.js +8 -5
  9. package/dist/CountrySelector.js.map +1 -1
  10. package/dist/DatePicker.js +2 -2
  11. package/dist/DatePicker.js.map +1 -1
  12. package/dist/FilterMenu.d.ts +23 -4
  13. package/dist/FilterMenu.js +70 -13
  14. package/dist/FilterMenu.js.map +1 -1
  15. package/dist/MastheadShell.d.ts +6 -3
  16. package/dist/MastheadShell.js +14 -4
  17. package/dist/MastheadShell.js.map +1 -1
  18. package/dist/Search.d.ts +3 -1
  19. package/dist/Search.js +1 -0
  20. package/dist/Search.js.map +1 -1
  21. package/dist/TextField.d.ts +19 -10
  22. package/dist/TextField.js +42 -29
  23. package/dist/TextField.js.map +1 -1
  24. package/dist/assets/ar-4f0abe88.js +1 -0
  25. package/dist/assets/ar_EG-33c30640.js +1 -0
  26. package/dist/assets/ar_SA-4fb0119e.js +1 -0
  27. package/dist/assets/bg-4dfbac34.js +1 -0
  28. package/dist/assets/{bundle.esm-1e0b0ef6.js → bundle.esm-1789a7c9.js} +191 -191
  29. package/dist/assets/ca-0adfb0a5.js +1 -0
  30. package/dist/assets/cnr-7b8ee13c.js +1 -0
  31. package/dist/assets/cs-7ce6fc77.js +1 -0
  32. package/dist/assets/da-d531cb4b.js +1 -0
  33. package/dist/assets/de-0956bb86.js +1 -0
  34. package/dist/assets/de_AT-1d4a673c.js +1 -0
  35. package/dist/assets/de_CH-b0aa3afe.js +1 -0
  36. package/dist/assets/el-087bca7a.js +1 -0
  37. package/dist/assets/el_CY-e2999371.js +1 -0
  38. package/dist/assets/en-5e51a9cc.js +1 -0
  39. package/dist/assets/en_AU-d8fe8569.js +1 -0
  40. package/dist/assets/en_GB-ba18957c.js +1 -0
  41. package/dist/assets/en_HK-95927212.js +1 -0
  42. package/dist/assets/en_IE-72dac8b7.js +1 -0
  43. package/dist/assets/en_IN-c51dcb94.js +1 -0
  44. package/dist/assets/en_NZ-799668bd.js +1 -0
  45. package/dist/assets/en_PG-322a9c1d.js +1 -0
  46. package/dist/assets/en_SG-e2817500.js +1 -0
  47. package/dist/assets/en_ZA-7a8893ed.js +1 -0
  48. package/dist/assets/es-a49e4234.js +1 -0
  49. package/dist/assets/es_AR-987273ce.js +1 -0
  50. package/dist/assets/es_BO-6407ce81.js +1 -0
  51. package/dist/assets/es_CL-bbd249e2.js +1 -0
  52. package/dist/assets/es_CO-5aadb676.js +1 -0
  53. package/dist/assets/es_MX-64ffbc24.js +1 -0
  54. package/dist/assets/es_PE-220c371e.js +1 -0
  55. package/dist/assets/es_UY-9608e924.js +1 -0
  56. package/dist/assets/es_VE-87def8b1.js +1 -0
  57. package/dist/assets/et-ed2e4c5e.js +1 -0
  58. package/dist/assets/fa-372c2ca8.js +1 -0
  59. package/dist/assets/fi-49cc59c4.js +1 -0
  60. package/dist/assets/fr-cb891f3c.js +1 -0
  61. package/dist/assets/fr_BE-49546add.js +1 -0
  62. package/dist/assets/fr_CA-de78fbe1.js +1 -0
  63. package/dist/assets/fr_CH-36c5581d.js +1 -0
  64. package/dist/assets/fr_LU-84ec0ca9.js +1 -0
  65. package/dist/assets/he-7010fec0.js +1 -0
  66. package/dist/assets/hi-011032b8.js +1 -0
  67. package/dist/assets/hr-cf6424f4.js +1 -0
  68. package/dist/assets/hu-de5c6410.js +1 -0
  69. package/dist/assets/id-d519ad13.js +1 -0
  70. package/dist/assets/it-7571a45f.js +1 -0
  71. package/dist/assets/it_CH-2d02acb4.js +1 -0
  72. package/dist/assets/ja-ed518694.js +1 -0
  73. package/dist/assets/kk-11548ca1.js +1 -0
  74. package/dist/assets/ko-ff650cea.js +1 -0
  75. package/dist/assets/lt-a55a76f9.js +1 -0
  76. package/dist/assets/lv-988dcda6.js +1 -0
  77. package/dist/assets/mk-6f2db893.js +1 -0
  78. package/dist/assets/ms-79ea2811.js +1 -0
  79. package/dist/assets/nb-d8116e03.js +1 -0
  80. package/dist/assets/nl-60ec308f.js +1 -0
  81. package/dist/assets/nl_BE-b51c75e9.js +1 -0
  82. package/dist/assets/pl-78f5b229.js +1 -0
  83. package/dist/assets/pt-a8c3a084.js +1 -0
  84. package/dist/assets/pt_PT-73b47e3d.js +1 -0
  85. package/dist/assets/ro-bb1a86ed.js +1 -0
  86. package/dist/assets/ru-3f49aae1.js +1 -0
  87. package/dist/assets/ru_UA-3eeb1b85.js +1 -0
  88. package/dist/assets/sk-e6cafcc8.js +1 -0
  89. package/dist/assets/sl-0bc16b8c.js +1 -0
  90. package/dist/assets/sr-08575b3a.js +1 -0
  91. package/dist/assets/sr_Latn-1440b74b.js +1 -0
  92. package/dist/assets/sv-f1bbb7c1.js +1 -0
  93. package/dist/assets/th-a4513b78.js +1 -0
  94. package/dist/assets/tr-f0f57c58.js +1 -0
  95. package/dist/assets/uk-f6e80b51.js +1 -0
  96. package/dist/assets/vi-52a2fc96.js +1 -0
  97. package/dist/assets/zh_CN-c4c6c916.js +1 -0
  98. package/dist/assets/zh_HK-e173672f.js +1 -0
  99. package/dist/assets/zh_SG-fcc2a69f.js +1 -0
  100. package/dist/assets/zh_TW-f1555202.js +1 -0
  101. package/dist/css/themes/CountrySelector.css +1 -1
  102. package/dist/css/themes/DatePicker.css +1 -1
  103. package/dist/css/themes/Dropdown.css +1 -1
  104. package/dist/css/themes/FilterMenu.css +1 -1
  105. package/dist/css/themes/MastheadItem.css +1 -1
  106. package/dist/css/themes/MastheadMenu.css +1 -1
  107. package/dist/css/themes/RatingIndicator.css +1 -1
  108. package/dist/css/themes/SelectBox.css +1 -1
  109. package/dist/css/themes/Slider.css +1 -1
  110. package/dist/css/themes/TextField.css +1 -1
  111. package/dist/custom-elements-internal.json +6 -6
  112. package/dist/custom-elements.json +6 -6
  113. package/dist/generated/templates/CountrySelectorTemplate.lit.js +1 -2
  114. package/dist/generated/templates/CountrySelectorTemplate.lit.js.map +1 -1
  115. package/dist/generated/templates/DatePickerTemplate.lit.js +1 -2
  116. package/dist/generated/templates/DatePickerTemplate.lit.js.map +1 -1
  117. package/dist/generated/templates/FilterMenuTemplate.lit.js +2 -2
  118. package/dist/generated/templates/FilterMenuTemplate.lit.js.map +1 -1
  119. package/dist/generated/templates/SearchableListBaseTemplate.lit.js +1 -1
  120. package/dist/generated/templates/SearchableListBaseTemplate.lit.js.map +1 -1
  121. package/dist/generated/templates/SelectBoxTemplate.lit.js +3 -3
  122. package/dist/generated/templates/SelectBoxTemplate.lit.js.map +1 -1
  123. package/dist/generated/templates/TextFieldTemplate.lit.js +1 -1
  124. package/dist/generated/templates/TextFieldTemplate.lit.js.map +1 -1
  125. package/dist/generated/themes/CountrySelector.css.js +1 -1
  126. package/dist/generated/themes/CountrySelector.css.js.map +1 -1
  127. package/dist/generated/themes/DatePicker.css.js +1 -1
  128. package/dist/generated/themes/DatePicker.css.js.map +1 -1
  129. package/dist/generated/themes/Dropdown.css.js +1 -1
  130. package/dist/generated/themes/Dropdown.css.js.map +1 -1
  131. package/dist/generated/themes/FilterMenu.css.js +1 -1
  132. package/dist/generated/themes/FilterMenu.css.js.map +1 -1
  133. package/dist/generated/themes/MastheadItem.css.js +1 -1
  134. package/dist/generated/themes/MastheadItem.css.js.map +1 -1
  135. package/dist/generated/themes/MastheadMenu.css.js +1 -1
  136. package/dist/generated/themes/MastheadMenu.css.js.map +1 -1
  137. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  138. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  139. package/dist/generated/themes/SelectBox.css.js +1 -1
  140. package/dist/generated/themes/SelectBox.css.js.map +1 -1
  141. package/dist/generated/themes/Slider.css.js +1 -1
  142. package/dist/generated/themes/Slider.css.js.map +1 -1
  143. package/dist/generated/themes/TextField.css.js +1 -1
  144. package/dist/generated/themes/TextField.css.js.map +1 -1
  145. package/dist/utils/debounce.d.ts +3 -1
  146. package/dist/utils/debounce.js +16 -4
  147. package/dist/utils/debounce.js.map +1 -1
  148. package/dist/web-types.json +4 -4
  149. package/package.json +2 -1
  150. package/src/Assets.ts +1 -0
  151. package/src/ControlButton.ts +16 -3
  152. package/src/CountrySelector.hbs +3 -9
  153. package/src/CountrySelector.ts +9 -6
  154. package/src/DatePicker.hbs +17 -27
  155. package/src/DatePicker.ts +2 -2
  156. package/src/FilterMenu.hbs +32 -36
  157. package/src/FilterMenu.ts +80 -17
  158. package/src/MastheadShell.ts +19 -7
  159. package/src/Search.ts +1 -0
  160. package/src/SearchableListBase.hbs +1 -1
  161. package/src/SelectBox.hbs +10 -12
  162. package/src/TextField.hbs +16 -14
  163. package/src/TextField.ts +86 -65
  164. package/src/generated/templates/CountrySelectorTemplate.lit.ts +1 -2
  165. package/src/generated/templates/DatePickerTemplate.lit.ts +1 -2
  166. package/src/generated/templates/FilterMenuTemplate.lit.ts +2 -2
  167. package/src/generated/templates/SearchableListBaseTemplate.lit.ts +1 -1
  168. package/src/generated/templates/SelectBoxTemplate.lit.ts +3 -3
  169. package/src/generated/templates/TextFieldTemplate.lit.ts +1 -1
  170. package/src/generated/themes/CountrySelector.css.ts +1 -1
  171. package/src/generated/themes/DatePicker.css.ts +1 -1
  172. package/src/generated/themes/Dropdown.css.ts +1 -1
  173. package/src/generated/themes/FilterMenu.css.ts +1 -1
  174. package/src/generated/themes/MastheadItem.css.ts +1 -1
  175. package/src/generated/themes/MastheadMenu.css.ts +1 -1
  176. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  177. package/src/generated/themes/SelectBox.css.ts +1 -1
  178. package/src/generated/themes/Slider.css.ts +1 -1
  179. package/src/generated/themes/TextField.css.ts +1 -1
  180. package/src/themes/CountrySelector.css +4 -0
  181. package/src/themes/DatePicker.css +0 -6
  182. package/src/themes/Dropdown.css +1 -1
  183. package/src/themes/FilterMenu.css +2 -2
  184. package/src/themes/MastheadItem.css +2 -1
  185. package/src/themes/MastheadMenu.css +4 -4
  186. package/src/themes/SelectBox.css +1 -2
  187. package/src/themes/TextField.css +0 -26
  188. package/src/utils/debounce.ts +19 -4
@@ -1,38 +1,38 @@
1
1
  <div>
2
2
  <button
3
- id="filterMenuTrigger"
4
- @click="{{handleTriggerClick}}"
5
- @keydown="{{handleTriggerKeydown}}"
6
- aria-label="{{triggerButtonAccessibleName}}"
7
- aria-labelledby="{{accessibleNameRef}}"
8
- aria-expanded="{{_open}}"
9
- aria-haspopup="true"
10
- role="{{triggerAccessibleRole}}"
11
- aria-controls="{{this._id}}_udex-filter-menu-dropdown"
12
- ?disabled="{{disabled}}"
13
- class="udex-filter-menu__trigger"
14
- tabindex="0">
15
- {{#if hasFilterNamePrefix}}
16
- <span class="udex-filter-menu__trigger-prefix">{{filterNamePrefix}}</span>
17
- {{/if}}
18
- <span class="udex-filter-menu__trigger-wrap" ?disabled="{{disabled}}">
19
- <span class="udex-filter-menu__trigger-name">{{filterName}}</span>
20
- {{#if badgeValue}}
21
- <udex-badge
22
- class="udex-filter-menu__badge"
23
- type="Number"
24
- design="Info"
25
- size="Small">
26
- {{badgeValue}}
27
- </udex-badge>
3
+ id="filterMenuTrigger"
4
+ @click="{{handleTriggerClick}}"
5
+ @keydown="{{handleTriggerKeydown}}"
6
+ aria-label="{{triggerButtonAccessibleName}}"
7
+ aria-labelledby="{{accessibleNameRef}}"
8
+ aria-expanded="{{_open}}"
9
+ aria-haspopup="true"
10
+ role="{{triggerAccessibleRole}}"
11
+ aria-controls="{{this._id}}_udex-filter-menu-dropdown"
12
+ ?disabled="{{disabled}}"
13
+ class="udex-filter-menu__trigger"
14
+ tabindex="0">
15
+ {{#if hasFilterNamePrefix}}
16
+ <span class="udex-filter-menu__trigger-prefix">{{filterNamePrefix}}</span>
28
17
  {{/if}}
29
- <ui5-icon
30
- class="udex-filter-menu__trigger-icon"
31
- name="navigation-down-arrow"
32
- accessible-name="{{_iconAccessibleNameText}}">
33
- </ui5-icon>
34
- </span>
35
- </button>
18
+ <span class="udex-filter-menu__trigger-wrap" ?disabled="{{disabled}}">
19
+ <span class="udex-filter-menu__trigger-name">{{filterName}}</span>
20
+ {{#if badgeValue}}
21
+ <udex-badge
22
+ class="udex-filter-menu__badge"
23
+ type="Number"
24
+ design="Info"
25
+ size="Small">
26
+ {{badgeValue}}
27
+ </udex-badge>
28
+ {{/if}}
29
+ <ui5-icon
30
+ class="udex-filter-menu__trigger-icon"
31
+ name="navigation-down-arrow"
32
+ accessible-name="{{_iconAccessibleNameText}}">
33
+ </ui5-icon>
34
+ </span>
35
+ </button>
36
36
  <ui5-popover
37
37
  id="{{this._id}}_udex-filter-menu-dropdown"
38
38
  hide-arrow
@@ -59,8 +59,6 @@
59
59
  </ui5-popover>
60
60
  </div>
61
61
 
62
-
63
-
64
62
  {{#*inline "buttons"}}
65
63
  {{#unless hideActionBar}}
66
64
  <div class="udex-filter-menu__footer" slot="footer" name="footer">
@@ -69,7 +67,6 @@
69
67
  class="udex-filter-menu__result-btn"
70
68
  size="Medium"
71
69
  design="Primary"
72
- ?disabled="{{disabledButtons}}"
73
70
  @keydown="{{handleKeyDownResultBtn}}"
74
71
  @click="{{handleResult}}">
75
72
  {{getResultLabelText}}
@@ -81,7 +78,6 @@
81
78
  size="Medium"
82
79
  design="Tertiary"
83
80
  @keydown="{{handleKeyDownResetBtn}}"
84
- ?disabled="{{disabledButtons}}"
85
81
  @click="{{handleReset}}">
86
82
  {{getResetLabelText}}
87
83
  </udex-button>
package/src/FilterMenu.ts CHANGED
@@ -27,6 +27,7 @@ import UDExFilterMenuSelectAll from "./FilterMenuSelectAll.js";
27
27
  import UDExListSelectAll from "./ListSelectAll.js";
28
28
  import UDExBadge from "./Badge.js";
29
29
  import UDExListItemBase from "./ListItemBase.js";
30
+ import type UDExListGroupHeaderBase from "./ListGroupHeaderBase.js";
30
31
 
31
32
  import { RESET, SHOW_RESULTS, SELECT_OPTIONS } from "./generated/i18n/i18n-defaults.js";
32
33
  import FilterMenuTemplate from "./generated/templates/FilterMenuTemplate.lit.js";
@@ -36,6 +37,11 @@ import SearchableListBaseTemplate from "./generated/templates/SearchableListBase
36
37
  import FilterMenuCss from "./generated/themes/FilterMenu.css.js";
37
38
  import SearchableListCss from "./generated/themes/SearchableList.css.js";
38
39
 
40
+ type initialItemState = {
41
+ id: string,
42
+ selected: boolean,
43
+ indeterminate?: boolean,
44
+ }
39
45
  /**
40
46
  * @class
41
47
  *
@@ -251,7 +257,6 @@ class UDExFilterMenu extends UDExSearchableListBase {
251
257
  * Hides the result button in the footer.
252
258
  *
253
259
  * @type {boolean}
254
- * @name sap.ui.webc.web-components.UDExFilterMenu.prototype.hideResultBtn
255
260
  * @defaultvalue false
256
261
  * @public
257
262
  */
@@ -262,7 +267,6 @@ class UDExFilterMenu extends UDExSearchableListBase {
262
267
  * Hides the reset button in the footer.
263
268
  *
264
269
  * @type {boolean}
265
- * @name sap.ui.webc.web-components.UDExFilterMenu.prototype.hideResetBtn
266
270
  * @defaultvalue false
267
271
  * @public
268
272
  */
@@ -303,10 +307,27 @@ class UDExFilterMenu extends UDExSearchableListBase {
303
307
  @property({ type: String, defaultValue: "combobox" })
304
308
  triggerAccessibleRole!: string;
305
309
 
310
+ /**
311
+ * Determines whether the filter should be applied.
312
+ * @default false
313
+ * @private
314
+ */
315
+ @property({ type: Boolean })
316
+ _shouldApplyFilter: boolean = false;
317
+
318
+ /**
319
+ * Internal flag to request a re-render of the component.
320
+ * @default false
321
+ * @private
322
+ */
323
+ @property({ type: Boolean, noAttribute: true })
324
+ _requestRender = false;
325
+
306
326
  _trigger!: UDExButton;
307
327
  _search!: UDExSearch;
308
328
  _popover!: Popover;
309
329
  _breakpointSizeXS = 640;
330
+ _initialState: Array<initialItemState> = [];
310
331
 
311
332
  onEnterDOM(): void {
312
333
  if (isDesktop()) {
@@ -355,6 +376,8 @@ class UDExFilterMenu extends UDExSearchableListBase {
355
376
  }
356
377
 
357
378
  handleReset(): void {
379
+ this._shouldApplyFilter = true;
380
+ this.onDropdownClose();
358
381
  this.fireEvent("reset-click", {
359
382
  restoredItems: this.selectedItems,
360
383
  });
@@ -362,12 +385,11 @@ class UDExFilterMenu extends UDExSearchableListBase {
362
385
  }
363
386
 
364
387
  handleResult(): void {
365
- if (!this.disabledButtons) {
366
- this._popover.close();
367
- this.fireEvent("result-click", {
368
- selectedItems: this.selectedItems,
369
- });
370
- }
388
+ this._shouldApplyFilter = true;
389
+ this.onDropdownClose();
390
+ this.fireEvent("result-click", {
391
+ selectedItems: this.selectedItems,
392
+ });
371
393
  }
372
394
 
373
395
  handleKeyDownList(e: KeyboardEvent): void {
@@ -443,6 +465,8 @@ class UDExFilterMenu extends UDExSearchableListBase {
443
465
  const content = this._popover.shadowRoot!.querySelector("[part=content]") as HTMLElement;
444
466
  content.style.maxHeight = this.height;
445
467
  }
468
+
469
+ this._initialState = this._getInitialState(this.items);
446
470
  this.fireEvent("before-open");
447
471
  }
448
472
 
@@ -459,11 +483,54 @@ class UDExFilterMenu extends UDExSearchableListBase {
459
483
  }
460
484
 
461
485
  _dropdownAfterClose(): void {
486
+ if (!this._shouldApplyFilter && this.modeMultiSelect && !this.modeSelectAll) {
487
+ this._setInitialState();
488
+ }
489
+
490
+ this._shouldApplyFilter = false;
462
491
  this._open = false;
463
492
  this._trigger.classList.remove("udex-filter-menu__trigger-active");
464
493
  this.fireEvent("after-close");
465
494
  }
466
495
 
496
+ _getInitialState(items: Array<UDExListItemBase | UDExListGroupHeaderBase>): Array<initialItemState> {
497
+ return items.flatMap(item => {
498
+ if (item.isGroup) {
499
+ const groupState: initialItemState = {
500
+ id: item._id,
501
+ selected: item.selected,
502
+ indeterminate: item.indeterminate,
503
+ };
504
+ const subItemsState = (item as UDExListGroupHeaderBase).getItems().map(subItem => ({
505
+ id: subItem._id,
506
+ selected: subItem.selected,
507
+ }));
508
+ return [groupState, ...subItemsState];
509
+ }
510
+ return {
511
+ id: item._id,
512
+ selected: item.selected,
513
+ };
514
+ });
515
+ }
516
+
517
+ _setInitialListState(): void {
518
+ this.getSlottedItems(this.items).forEach((item, index) => {
519
+ const initialState = this._initialState[index];
520
+ if (item._id === initialState?.id) {
521
+ item.selected = initialState.selected;
522
+ if (item.isGroup) {
523
+ item.indeterminate = initialState.indeterminate;
524
+ }
525
+ }
526
+ });
527
+ }
528
+
529
+ _setInitialState(): void {
530
+ this._setInitialListState();
531
+ this._requestRender = true;
532
+ }
533
+
467
534
  get disableAllowTargetOverlap(): boolean {
468
535
  return !this.disableTargetOverlap;
469
536
  }
@@ -482,10 +549,6 @@ class UDExFilterMenu extends UDExSearchableListBase {
482
549
  return hasLabel ? this.resetBtnLabel : UDExFilterMenu.i18nBundle.getText(RESET);
483
550
  }
484
551
 
485
- get disabledButtons(): boolean {
486
- return !this.selectedItems.length && !this.selectAll;
487
- }
488
-
489
552
  get _iconAccessibleNameText(): string {
490
553
  return UDExFilterMenu.i18nBundle.getText(SELECT_OPTIONS);
491
554
  }
@@ -503,17 +566,17 @@ class UDExFilterMenu extends UDExSearchableListBase {
503
566
  }
504
567
 
505
568
  get hasFooterButtons(): boolean {
506
- return (this.hasResultBtn || this.hasResetBtn) && !this.disabledButtons;
507
- }
508
-
509
- get hasResultBtn(): boolean {
510
- return !this.hideResultBtn && !this.disabledButtons;
569
+ return !!this.shadowRoot!.querySelector("[udex-button]");
511
570
  }
512
571
 
513
572
  get hasResetBtn(): boolean {
514
573
  return !this.hideResetBtn;
515
574
  }
516
575
 
576
+ get modeSelectAll(): boolean {
577
+ return !!this.querySelector<UDExFilterMenuSelectAll>("[udex-filter-menu-select-all]");
578
+ }
579
+
517
580
  getTriggerButton(): UDExButton {
518
581
  return this.shadowRoot!.querySelector<UDExButton>("#filterMenuTrigger")!;
519
582
  }
@@ -3,6 +3,7 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement
3
3
  import property from "@ui5/webcomponents-base/dist/decorators/property.js";
4
4
  import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
5
5
  import event from "@ui5/webcomponents-base/dist/decorators/event.js";
6
+ import type { ChangeInfo } from "@ui5/webcomponents-base/dist/UI5Element.js";
6
7
  import UI5Icon from "@ui5/webcomponents/dist/Icon.js";
7
8
  import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
8
9
  import ResizeHandler, { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
@@ -30,7 +31,7 @@ import AnalyticsName from "./types/AnalyticsName.js";
30
31
  // Styles
31
32
  import MastheadShellCss from "./generated/themes/MastheadShell.css.js";
32
33
 
33
- const canvasContentFont = "16px '72 Brand Variable'";
34
+ const canvasContentFont = "14px '72 Brand Variable'";
34
35
  type MastheadSlottedItem = UDExMastheadItem | UDExMastheadProfileMenu | UDExMastheadMenu | UDExMastheadCountrySelector | undefined | null;
35
36
  type MastheadItemType = UDExMastheadItem | null | undefined;
36
37
  export const MastheadOriginalEvent = {
@@ -48,6 +49,7 @@ export const AnalyticsNameEventDetail = {
48
49
  };
49
50
 
50
51
  export enum UDExMastheadVariable {
52
+ itemArrowIconMarginInlineStart = "--udex-masthead-item-arrow-margin-inline-start",
51
53
  mobileMenuHeight = "--udex-masthead-shell-mobile-menu-height",
52
54
  itemButtonIconSize = "--udex-masthead-item-button-icon-size",
53
55
  itemArrowIconSize = "--udex-masthead-item-arrow-icon-size",
@@ -262,7 +264,7 @@ class UDExMastheadShell extends UI5Element {
262
264
  /**
263
265
  * Defines overflow style for the body after clicking mobile menu opener button
264
266
  *
265
- * @default ""
267
+ * @default false
266
268
  * @public
267
269
  */
268
270
  @property({ type: Boolean })
@@ -271,7 +273,7 @@ class UDExMastheadShell extends UI5Element {
271
273
  /**
272
274
  * Defines the visibility of the Search by default.
273
275
  *
274
- * @default ""
276
+ * @default false
275
277
  * @public
276
278
  */
277
279
  @property({ type: Boolean })
@@ -280,7 +282,7 @@ class UDExMastheadShell extends UI5Element {
280
282
  /**
281
283
  * Defines sticky position for component
282
284
  *
283
- * @default ""
285
+ * @default false
284
286
  * @public
285
287
  */
286
288
  @property({ type: Boolean })
@@ -417,7 +419,9 @@ class UDExMastheadShell extends UI5Element {
417
419
  this.focusSearchBtn();
418
420
  }
419
421
 
420
- this.updateVisibility();
422
+ if (this.shouldHandleMobileView) {
423
+ this.updateVisibility();
424
+ }
421
425
  }
422
426
 
423
427
  onEnterDOM(): void {
@@ -503,6 +507,12 @@ class UDExMastheadShell extends UI5Element {
503
507
  }
504
508
  }
505
509
 
510
+ onInvalidation({ name }: ChangeInfo): void {
511
+ if (name === "default" && this.shouldHandleMobileView) {
512
+ this.handleMobileMode();
513
+ }
514
+ }
515
+
506
516
  handleRightArrow(e: KeyboardEvent): void {
507
517
  if (isRight(e)) {
508
518
  const currentItem = e.target as UDExMastheadItem;
@@ -685,7 +695,9 @@ class UDExMastheadShell extends UI5Element {
685
695
  }
686
696
 
687
697
  getItemArrowIconWidth(): number {
688
- return this.getItemIconSize(UDExMastheadVariable.itemArrowIconSize);
698
+ const arrowIconSize = this.getItemIconSize(UDExMastheadVariable.itemArrowIconSize);
699
+ const marginInlineStart = this.getItemIconSize(UDExMastheadVariable.itemArrowIconMarginInlineStart);
700
+ return arrowIconSize + marginInlineStart;
689
701
  }
690
702
 
691
703
  getMainMenuWidth(): number {
@@ -695,7 +707,7 @@ class UDExMastheadShell extends UI5Element {
695
707
  const mainItem = item as UDExMastheadItem;
696
708
  const hasArrowIcon = mainItem.hasArrowDown && !mainItem.hideArrowIcon;
697
709
  const arrowIconWidth = hasArrowIcon ? this.getItemArrowIconWidth() : 0;
698
- return accumulatedWidth + this.getItemWidth(mainItem) + (index && parseInt(gapItemVar) + arrowIconWidth);
710
+ return accumulatedWidth + this.getItemWidth(mainItem) + (index && parseInt(gapItemVar)) + arrowIconWidth;
699
711
  }, 0);
700
712
  }
701
713
 
package/src/Search.ts CHANGED
@@ -786,6 +786,7 @@ class UDExSearch extends UI5Element {
786
786
  }
787
787
 
788
788
  handleSubmitValue(): void {
789
+ this.handleDebounce.cancel();
789
790
  this.onClosePopover();
790
791
  this.fireEvent("submit-search-value", { value: this.value });
791
792
  }
@@ -16,7 +16,7 @@
16
16
  </span>
17
17
  {{/if}}
18
18
  {{#if isListEmpty}}
19
- <div class="udex-no-result"><span>{{getNoResultText}}&lrm;</span></div>
19
+ <div class="udex-no-result"><span>{{getNoResultText}}</span></div>
20
20
  {{else if busy}}
21
21
  <ui5-busy-indicator
22
22
  class="udex-busy-indicator"
package/src/SelectBox.hbs CHANGED
@@ -23,16 +23,17 @@
23
23
  aria-expanded="{{tokenizerExpanded}}"
24
24
  aria-activedescendant>
25
25
  {{#if label}}
26
- <span id="{{this._id}}-single-label" class="{{labelClass}}">
27
- {{label}}
28
- {{#if required}}
29
- *
30
- {{/if}}
31
- </span>
26
+ <span class="{{labelClass}}">
27
+ {{label}}
28
+ {{#if required}}
29
+ *
30
+ {{/if}}
31
+ </span>
32
+ <span class="hidden" id="{{this._id}}-single-label">{{accInfo.ariaLabel}}</span>
32
33
  {{/if}}
33
34
  {{#if showSingleSelectedOption}}
34
35
  <div class="udex-text-field__text-holder">
35
- <span class="udex-text-field__single-label">
36
+ <span class="udex-text-field__single-label" aria-hidden="true">
36
37
  {{{_singleSelectedOption}}}
37
38
  </span>
38
39
  </div>
@@ -66,15 +67,12 @@
66
67
  aria-expanded="{{accessibilityAttributes.expanded}}"
67
68
  aria-controls="{{accessibilityAttributes.controls}}"
68
69
  aria-haspopup="{{accessibilityAttributes.hasPopup}}"
69
- aria-label="{{accessibilityAttributes.ariaLabel}}"
70
70
  class="udex-text-field__trigger"
71
71
  tabindex="{{triggerTabIndex}}"
72
72
  @keydown="{{handleKeyDownTrigger}}"
73
73
  @click="{{getHandleMultiSelectOpen}}">
74
- <ui5-icon
75
- name="navigation-down-arrow"
76
- accessible-name="{{iconAccessibleNameText}}">
77
- </ui5-icon>
74
+ <ui5-icon name="navigation-down-arrow"></ui5-icon>
75
+ <span class="hidden">{{accessibilityAttributes.ariaLabel}}</span>
78
76
  </button>
79
77
  {{/if}}
80
78
  </div>
package/src/TextField.hbs CHANGED
@@ -39,20 +39,22 @@
39
39
  />
40
40
 
41
41
  {{#if icon}}
42
- <udex-control-button
43
- accessible-name="{{accessibleIconName}}"
44
- tooltip="{{showButtonTooltip}}"
45
- ?active="{{active}}"
46
- ?disabled="{{disabled}}"
47
- ?readonly="{{readonly}}"
48
- ?non-interactive="{{readonly}}"
49
- design="{{valueState}}"
50
- icon="{{icon}}"
51
- @click="{{handleIconClick}}"
52
- part="textfield-control-btn"
53
- size="Large"
54
- class="udex-text-field_icon-container"
55
- ></udex-control-button>
42
+ <udex-control-button
43
+ accessible-name="{{buttonAccessibleName}}"
44
+ accessible-description="{{buttonAccessibleDescription}}"
45
+ tooltip="{{showButtonTooltip}}"
46
+ ?active="{{active}}"
47
+ ?disabled="{{disabled}}"
48
+ ?readonly="{{readonly}}"
49
+ ?non-interactive="{{readonly}}"
50
+ ?_is-combobox-role="{{_isComboboxRole}}"
51
+ design="{{valueState}}"
52
+ icon="{{icon}}"
53
+ @click="{{handleIconClick}}"
54
+ part="textfield-control-btn"
55
+ size="Large"
56
+ class="udex-text-field_icon-container">
57
+ </udex-control-button>
56
58
  {{/if}}
57
59
  </div>
58
60
 
package/src/TextField.ts CHANGED
@@ -313,65 +313,42 @@ class UDExTextField extends UI5Element {
313
313
  @property({ type: Boolean })
314
314
  _isTouched!: boolean;
315
315
 
316
+ /**
317
+ * Determines Combobox role for the button.
318
+ * @default false
319
+ * @private
320
+ */
321
+ @property({ type: Boolean })
322
+ _isComboboxRole?: boolean;
323
+
316
324
  static i18nBundle: I18nBundle;
317
325
 
318
326
  static async onDefine(): Promise<void> {
319
327
  UDExTextField.i18nBundle = await getI18nBundle("@sapudex/web-components");
320
328
  }
321
329
 
322
- get valueStateTypeMappings(): Record<string, string> {
323
- return {
324
- "Success": UDExTextField.i18nBundle.getText(VALUE_STATE_SUCCESS),
325
- "Standard": UDExTextField.i18nBundle.getText(VALUE_STATE_INFORMATION),
326
- "Error": UDExTextField.i18nBundle.getText(VALUE_STATE_ERROR),
327
- "Warning": UDExTextField.i18nBundle.getText(VALUE_STATE_WARNING),
328
- };
329
- }
330
-
331
- get hasValueState(): boolean {
332
- return this.valueState !== ValueState.Standard;
333
- }
334
-
335
- get valueStateText(): string | undefined {
336
- return this.valueState !== ValueState.Standard ? this.valueStateTypeMappings[this.valueState] : undefined;
337
- }
338
-
339
- get readOnlyStateText(): string {
340
- return UDExTextField.i18nBundle.getText(READ_ONLY);
341
- }
342
-
343
- get ariaDescribedById(): string {
344
- return `${this.supportingTextId} ${this.valueStateTextId} ${this.readOnlyStateTextId}`.trim();
345
- }
346
-
347
- get supportingTextId(): string {
348
- return this.supportingText ? `${this._id}-supportingTextDesc` : "";
349
- }
350
-
351
- get valueStateTextId(): string {
352
- return this.hasValueState ? `${this._id}-valueStateDesc` : "";
353
- }
330
+ onBeforeRendering(): void {
331
+ if ((this.value || this.active) && this.labelActiveClass === "") {
332
+ this.labelActiveClass = this._labelActiveClassName;
333
+ } else if (!this.active && !this.value && this.labelActiveClass.length) {
334
+ this.labelActiveClass = "";
335
+ }
354
336
 
355
- get readOnlyStateTextId(): string {
356
- return this.readonly ? `${this._id}-stateReadOnlyDesc` : "";
357
- }
337
+ this.isInputReadonly = this.readonly || this.displayonly;
358
338
 
359
- get accInfo(): AccInfo {
360
- return {
361
- "ariaInvalid": this.valueState === ValueState.Error ? "true" : undefined,
362
- "ariaDescribedBy": this.ariaDescribedBy ? this.ariaDescribedBy : this.ariaDescribedById || undefined,
363
- "ariaLabelledBy": this.accessibleNameRef || undefined,
364
- "ariaLabel": this.accessibleName || undefined,
365
- "ariaHasPopup": this._ariaHasPopup || undefined,
366
- };
339
+ this.labelClasses = `udex-text-field__label ${this.labelActiveClass}`;
367
340
  }
368
341
 
369
- get inputRole(): string | undefined {
370
- return this.isAutoCompleteDisabled ? "presentation" : undefined;
371
- }
342
+ onAfterRendering(): void {
343
+ const directionStyles: string = window
344
+ .getComputedStyle(this)
345
+ .getPropertyValue("direction");
372
346
 
373
- get isAutoCompleteDisabled(): boolean {
374
- return this.autocomplete === "off" || this.autocomplete === "new-password";
347
+ if (!directionStyles) {
348
+ this.direction = "ltr";
349
+ } else {
350
+ this.direction = directionStyles;
351
+ }
375
352
  }
376
353
 
377
354
  handleKeydown(e: KeyboardEvent): void {
@@ -415,33 +392,77 @@ class UDExTextField extends UI5Element {
415
392
  this.fireEvent("click-icon");
416
393
  }
417
394
 
418
- onBeforeRendering(): void {
419
- if ((this.value || this.active) && this.labelActiveClass === "") {
420
- this.labelActiveClass = this._labelActiveClassName;
421
- } else if (!this.active && !this.value && this.labelActiveClass.length) {
422
- this.labelActiveClass = "";
423
- }
395
+ get _inputHolder(): HTMLElement {
396
+ return this.shadowRoot!.querySelector<HTMLElement>(".udex-text-field__wrap")!;
397
+ }
424
398
 
425
- this.isInputReadonly = this.readonly || this.displayonly;
399
+ get valueStateTypeMappings(): Record<string, string> {
400
+ return {
401
+ "Success": UDExTextField.i18nBundle.getText(VALUE_STATE_SUCCESS),
402
+ "Standard": UDExTextField.i18nBundle.getText(VALUE_STATE_INFORMATION),
403
+ "Error": UDExTextField.i18nBundle.getText(VALUE_STATE_ERROR),
404
+ "Warning": UDExTextField.i18nBundle.getText(VALUE_STATE_WARNING),
405
+ };
406
+ }
426
407
 
427
- this.labelClasses = `udex-text-field__label ${this.labelActiveClass}`;
408
+ get hasValueState(): boolean {
409
+ return this.valueState !== ValueState.Standard;
428
410
  }
429
411
 
430
- onAfterRendering(): void {
431
- const directionStyles: string = window
432
- .getComputedStyle(this)
433
- .getPropertyValue("direction");
412
+ get valueStateText(): string {
413
+ return this.valueState !== ValueState.Standard ? this.valueStateTypeMappings[this.valueState] : "";
414
+ }
434
415
 
435
- if (!directionStyles) {
436
- this.direction = "ltr";
437
- } else {
438
- this.direction = directionStyles;
439
- }
416
+ get readOnlyStateText(): string {
417
+ return UDExTextField.i18nBundle.getText(READ_ONLY);
418
+ }
419
+
420
+ get ariaDescribedById(): string {
421
+ return `${this.supportingTextId} ${this.valueStateTextId} ${this.readOnlyStateTextId}`.trim();
422
+ }
423
+
424
+ get supportingTextId(): string {
425
+ return this.supportingText ? `${this._id}-supportingTextDesc` : "";
426
+ }
427
+
428
+ get valueStateTextId(): string {
429
+ return this.hasValueState ? `${this._id}-valueStateDesc` : "";
430
+ }
431
+
432
+ get readOnlyStateTextId(): string {
433
+ return this.readonly ? `${this._id}-stateReadOnlyDesc` : "";
434
+ }
435
+
436
+ get accInfo(): AccInfo {
437
+ return {
438
+ "ariaInvalid": this.valueState === ValueState.Error ? "true" : undefined,
439
+ "ariaDescribedBy": this.ariaDescribedBy ? this.ariaDescribedBy : this.ariaDescribedById || undefined,
440
+ "ariaLabelledBy": this.accessibleNameRef || undefined,
441
+ "ariaLabel": this.accessibleName || undefined,
442
+ "ariaHasPopup": this._ariaHasPopup || undefined,
443
+ };
444
+ }
445
+
446
+ get inputRole(): string | undefined {
447
+ return this.isAutoCompleteDisabled ? "presentation" : undefined;
448
+ }
449
+
450
+ get isAutoCompleteDisabled(): boolean {
451
+ return this.autocomplete === "off" || this.autocomplete === "new-password";
440
452
  }
441
453
 
442
454
  get readonlyNotDisabled(): boolean {
443
455
  return this.isInputReadonly && !this.disabled;
444
456
  }
457
+
458
+ get buttonAccessibleName(): string {
459
+ return this._isComboboxRole ? this.label : this.accessibleIconName || this.icon;
460
+ }
461
+
462
+ get buttonAccessibleDescription(): string {
463
+ const label = this._isComboboxRole ? this.value : "";
464
+ return `${label} ${this.supportingText || ""} ${this.valueStateText}`;
465
+ }
445
466
  }
446
467
 
447
468
  UDExTextField.define();