@sapudex/web-components 2.2.0 → 2.4.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 (273) hide show
  1. package/.eslintignore +3 -0
  2. package/bundle.esm.js +3 -0
  3. package/cypress/fixtures/contact-numbers.ts +10 -0
  4. package/cypress/fixtures/event-ribbon-links.ts +5 -0
  5. package/cypress/specs/Accordion.cy.tsx +25 -2
  6. package/cypress/specs/AccordionItem.cy.tsx +1 -1
  7. package/cypress/specs/Avatar.cy.tsx +1 -1
  8. package/cypress/specs/AvatarGroup.cy.tsx +1 -2
  9. package/cypress/specs/Badge.cy.tsx +1 -1
  10. package/cypress/specs/Contact.cy.tsx +92 -0
  11. package/cypress/specs/ContactItem.cy.tsx +56 -0
  12. package/cypress/specs/CountrySelector.cy.tsx +10 -4
  13. package/cypress/specs/EventRibbon.cy.tsx +110 -0
  14. package/cypress/specs/Footer.cy.tsx +1 -1
  15. package/cypress/specs/ListItem.cy.tsx +1 -1
  16. package/cypress/specs/PhoneNumberField.cy.tsx +4 -2
  17. package/cypress/specs/Review.cy.tsx +1 -3
  18. package/cypress/specs/ReviewItem.cy.tsx +1 -1
  19. package/cypress/specs/SecondaryNavigationDesktop.cy.tsx +123 -116
  20. package/cypress/specs/SecondaryNavigationMobile.cy.tsx +27 -38
  21. package/cypress/specs/SelectBox.cy.tsx +93 -88
  22. package/cypress/specs/Slider.cy.tsx +1 -1
  23. package/cypress/specs/StatusBadge.cy.tsx +1 -1
  24. package/cypress/specs/StatusMessage.cy.tsx +1 -1
  25. package/cypress/specs/Switch.cy.tsx +1 -2
  26. package/cypress/specs/Table.cy.tsx +1 -9
  27. package/cypress/specs/Tag.cy.tsx +1 -1
  28. package/cypress/specs/TagGroup.cy.tsx +1 -2
  29. package/cypress/specs/TextField.cy.tsx +1 -1
  30. package/cypress/specs/Textarea.cy.tsx +1 -1
  31. package/cypress/specs/Toast.cy.tsx +1 -1
  32. package/cypress/specs/Tooltip.cy.tsx +1 -2
  33. package/cypress/specs/TruncatedText.cy.tsx +2 -1
  34. package/cypress/specs/Upload.cy.tsx +1 -2
  35. package/cypress/specs/UploadItem.cy.tsx +1 -1
  36. package/cypress/specs/Wizard.cy.tsx +7 -4
  37. package/cypress/support/commands.ts +31 -2
  38. package/cypress/support/component-imports.instrumented.ts +95 -0
  39. package/cypress/support/component-imports.src.ts +95 -0
  40. package/cypress/support/component.ts +1 -1
  41. package/cypress.config.ts +6 -0
  42. package/dist/Accordion.d.ts +7 -1
  43. package/dist/Accordion.js +3 -3
  44. package/dist/Accordion.js.map +1 -1
  45. package/dist/Assets.js +31 -0
  46. package/dist/Assets.js.map +1 -1
  47. package/dist/AssetsVariables.js +4 -0
  48. package/dist/AssetsVariables.js.map +1 -1
  49. package/dist/Button.d.ts +7 -0
  50. package/dist/Button.js +3 -0
  51. package/dist/Button.js.map +1 -1
  52. package/dist/Contact.d.ts +102 -0
  53. package/dist/Contact.js +152 -0
  54. package/dist/Contact.js.map +1 -0
  55. package/dist/ContactItem.d.ts +67 -0
  56. package/dist/ContactItem.js +96 -0
  57. package/dist/ContactItem.js.map +1 -0
  58. package/dist/ContactItemTemplate.d.ts +2 -0
  59. package/dist/ContactItemTemplate.js +13 -0
  60. package/dist/ContactItemTemplate.js.map +1 -0
  61. package/dist/ContactTemplate.d.ts +4 -0
  62. package/dist/ContactTemplate.js +29 -0
  63. package/dist/ContactTemplate.js.map +1 -0
  64. package/dist/CountrySelector.d.ts +2 -4
  65. package/dist/CountrySelector.js +3 -5
  66. package/dist/CountrySelector.js.map +1 -1
  67. package/dist/DatePicker.js +2 -1
  68. package/dist/DatePicker.js.map +1 -1
  69. package/dist/EventRibbon.d.ts +80 -0
  70. package/dist/EventRibbon.js +111 -0
  71. package/dist/EventRibbon.js.map +1 -0
  72. package/dist/EventRibbonTemplate.d.ts +2 -0
  73. package/dist/EventRibbonTemplate.js +7 -0
  74. package/dist/EventRibbonTemplate.js.map +1 -0
  75. package/dist/Footer.d.ts +0 -1
  76. package/dist/Footer.js +7 -9
  77. package/dist/Footer.js.map +1 -1
  78. package/dist/HeroBanner.d.ts +1 -1
  79. package/dist/List.d.ts +1 -1
  80. package/dist/List.js +1 -1
  81. package/dist/List.js.map +1 -1
  82. package/dist/MastheadItem.d.ts +1 -3
  83. package/dist/MastheadItem.js +6 -11
  84. package/dist/MastheadItem.js.map +1 -1
  85. package/dist/MastheadMenu.d.ts +0 -1
  86. package/dist/MastheadMenu.js +2 -4
  87. package/dist/MastheadMenu.js.map +1 -1
  88. package/dist/MastheadProfileMenu.d.ts +0 -1
  89. package/dist/MastheadProfileMenu.js +2 -4
  90. package/dist/MastheadProfileMenu.js.map +1 -1
  91. package/dist/MastheadShell.d.ts +4 -1
  92. package/dist/MastheadShell.js +21 -5
  93. package/dist/MastheadShell.js.map +1 -1
  94. package/dist/Pagination.d.ts +17 -3
  95. package/dist/Pagination.js +33 -31
  96. package/dist/Pagination.js.map +1 -1
  97. package/dist/PhoneNumberField.d.ts +5 -5
  98. package/dist/PhoneNumberField.js +1 -1
  99. package/dist/PhoneNumberField.js.map +1 -1
  100. package/dist/SearchableListBase.d.ts +9 -0
  101. package/dist/SearchableListBase.js +15 -3
  102. package/dist/SearchableListBase.js.map +1 -1
  103. package/dist/SecondaryNavigation.d.ts +0 -1
  104. package/dist/SecondaryNavigation.js +2 -4
  105. package/dist/SecondaryNavigation.js.map +1 -1
  106. package/dist/TextField.d.ts +7 -0
  107. package/dist/TextField.js +3 -0
  108. package/dist/TextField.js.map +1 -1
  109. package/dist/Wizard.d.ts +20 -1
  110. package/dist/Wizard.js +22 -9
  111. package/dist/Wizard.js.map +1 -1
  112. package/dist/WizardTemplate.js +1 -1
  113. package/dist/WizardTemplate.js.map +1 -1
  114. package/dist/assets/{InputSuggestions-KGCQrV_T.js → InputSuggestions-CYW_6A8K.js} +1 -1
  115. package/dist/assets/{ListItemStandardExpandableTextTemplate-D4zLIdLd.js → ListItemStandardExpandableTextTemplate-BDrgWGjT.js} +1 -1
  116. package/dist/assets/{bundle.esm-Diw1zQ-o.js → bundle.esm-DRCvw6Ji.js} +235 -225
  117. package/dist/assets/messagebundle_en-BK8-Eyic.js +1 -0
  118. package/dist/css/themes/Accordion.css +1 -1
  119. package/dist/css/themes/Button.css +1 -1
  120. package/dist/css/themes/Contact.css +1 -0
  121. package/dist/css/themes/ContactItem.css +1 -0
  122. package/dist/css/themes/DatePickerPopover.css +1 -1
  123. package/dist/css/themes/EventRibbon.css +1 -0
  124. package/dist/css/themes/MastheadCountrySelector.css +1 -1
  125. package/dist/css/themes/MastheadItem.css +1 -1
  126. package/dist/css/themes/MastheadShell.css +1 -1
  127. package/dist/css/themes/Modal.css +1 -1
  128. package/dist/css/themes/Pagination.css +1 -1
  129. package/dist/css/themes/RatingIndicator.css +1 -1
  130. package/dist/css/themes/Slider.css +1 -1
  131. package/dist/css/themes/TextField.css +1 -1
  132. package/dist/custom-elements-internal.json +823 -99
  133. package/dist/custom-elements.json +783 -83
  134. package/dist/data/CountryListISO3166.d.ts +13 -4
  135. package/dist/data/CountryListISO3166.js +8 -0
  136. package/dist/data/CountryListISO3166.js.map +1 -1
  137. package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
  138. package/dist/generated/i18n/i18n-defaults.d.ts +3 -1
  139. package/dist/generated/i18n/i18n-defaults.js +3 -1
  140. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  141. package/dist/generated/templates/AccordionTemplate.lit.js +4 -2
  142. package/dist/generated/templates/AccordionTemplate.lit.js.map +1 -1
  143. package/dist/generated/templates/MastheadItemTemplate.lit.js +25 -22
  144. package/dist/generated/templates/MastheadItemTemplate.lit.js.map +1 -1
  145. package/dist/generated/templates/PaginationTemplate.lit.js +1 -1
  146. package/dist/generated/templates/PaginationTemplate.lit.js.map +1 -1
  147. package/dist/generated/templates/PhoneNumberFieldTemplate.lit.js +2 -2
  148. package/dist/generated/templates/PhoneNumberFieldTemplate.lit.js.map +1 -1
  149. package/dist/generated/themes/Accordion.css.d.ts +1 -1
  150. package/dist/generated/themes/Accordion.css.js +1 -1
  151. package/dist/generated/themes/Accordion.css.js.map +1 -1
  152. package/dist/generated/themes/Button.css.d.ts +1 -1
  153. package/dist/generated/themes/Button.css.js +1 -1
  154. package/dist/generated/themes/Button.css.js.map +1 -1
  155. package/dist/generated/themes/Contact.css.d.ts +2 -0
  156. package/dist/generated/themes/Contact.css.js +8 -0
  157. package/dist/generated/themes/Contact.css.js.map +1 -0
  158. package/dist/generated/themes/ContactItem.css.d.ts +2 -0
  159. package/dist/generated/themes/ContactItem.css.js +8 -0
  160. package/dist/generated/themes/ContactItem.css.js.map +1 -0
  161. package/dist/generated/themes/DatePickerPopover.css.d.ts +1 -1
  162. package/dist/generated/themes/DatePickerPopover.css.js +1 -1
  163. package/dist/generated/themes/DatePickerPopover.css.js.map +1 -1
  164. package/dist/generated/themes/EventRibbon.css.d.ts +2 -0
  165. package/dist/generated/themes/EventRibbon.css.js +8 -0
  166. package/dist/generated/themes/EventRibbon.css.js.map +1 -0
  167. package/dist/generated/themes/MastheadCountrySelector.css.d.ts +1 -1
  168. package/dist/generated/themes/MastheadCountrySelector.css.js +1 -1
  169. package/dist/generated/themes/MastheadCountrySelector.css.js.map +1 -1
  170. package/dist/generated/themes/MastheadItem.css.d.ts +1 -1
  171. package/dist/generated/themes/MastheadItem.css.js +1 -1
  172. package/dist/generated/themes/MastheadItem.css.js.map +1 -1
  173. package/dist/generated/themes/MastheadShell.css.d.ts +1 -1
  174. package/dist/generated/themes/MastheadShell.css.js +1 -1
  175. package/dist/generated/themes/MastheadShell.css.js.map +1 -1
  176. package/dist/generated/themes/Modal.css.d.ts +1 -1
  177. package/dist/generated/themes/Modal.css.js +1 -1
  178. package/dist/generated/themes/Modal.css.js.map +1 -1
  179. package/dist/generated/themes/Pagination.css.d.ts +1 -1
  180. package/dist/generated/themes/Pagination.css.js +1 -1
  181. package/dist/generated/themes/Pagination.css.js.map +1 -1
  182. package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
  183. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  184. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  185. package/dist/generated/themes/Slider.css.d.ts +1 -1
  186. package/dist/generated/themes/Slider.css.js +1 -1
  187. package/dist/generated/themes/Slider.css.js.map +1 -1
  188. package/dist/generated/themes/TextField.css.d.ts +1 -1
  189. package/dist/generated/themes/TextField.css.js +1 -1
  190. package/dist/generated/themes/TextField.css.js.map +1 -1
  191. package/dist/messagebundle.properties +5 -0
  192. package/dist/messagebundle_en.properties +3 -0
  193. package/dist/types/ContactItemIcon.d.ts +6 -0
  194. package/dist/types/ContactItemIcon.js +8 -0
  195. package/dist/types/ContactItemIcon.js.map +1 -0
  196. package/dist/types/EventRibbon.d.ts +37 -0
  197. package/dist/types/EventRibbon.js +43 -0
  198. package/dist/types/EventRibbon.js.map +1 -0
  199. package/dist/utils/parseArrayFromString.d.ts +2 -0
  200. package/dist/utils/parseArrayFromString.js +5 -0
  201. package/dist/utils/parseArrayFromString.js.map +1 -0
  202. package/dist/vscode.html-custom-data.json +183 -1
  203. package/dist/web-types.json +321 -2
  204. package/filter-coverage.js +58 -0
  205. package/package.json +8 -3
  206. package/src/Accordion.hbs +13 -9
  207. package/src/Accordion.ts +7 -4
  208. package/src/Assets.ts +29 -0
  209. package/src/AssetsVariables.ts +4 -0
  210. package/src/Button.ts +9 -0
  211. package/src/Contact.ts +200 -0
  212. package/src/ContactItem.ts +119 -0
  213. package/src/ContactItemTemplate.tsx +22 -0
  214. package/src/ContactTemplate.tsx +105 -0
  215. package/src/CountrySelector.ts +5 -8
  216. package/src/DatePicker.ts +2 -1
  217. package/src/EventRibbon.ts +143 -0
  218. package/src/EventRibbonTemplate.tsx +18 -0
  219. package/src/Footer.ts +7 -10
  220. package/src/List.ts +1 -1
  221. package/src/MastheadItem.hbs +8 -0
  222. package/src/MastheadItem.ts +8 -16
  223. package/src/MastheadMenu.ts +2 -5
  224. package/src/MastheadProfileMenu.ts +2 -5
  225. package/src/MastheadShell.ts +25 -5
  226. package/src/Pagination.hbs +7 -3
  227. package/src/Pagination.ts +48 -31
  228. package/src/PhoneNumberField.hbs +1 -1
  229. package/src/PhoneNumberField.ts +7 -2
  230. package/src/SearchableListBase.ts +24 -3
  231. package/src/SecondaryNavigation.ts +3 -5
  232. package/src/TextField.ts +9 -0
  233. package/src/Wizard.ts +39 -11
  234. package/src/WizardTemplate.tsx +5 -1
  235. package/src/data/CountryListISO3166.ts +10 -2
  236. package/src/generated/i18n/i18n-defaults.ts +2 -2
  237. package/src/generated/templates/AccordionTemplate.lit.ts +4 -2
  238. package/src/generated/templates/MastheadItemTemplate.lit.ts +25 -22
  239. package/src/generated/templates/PaginationTemplate.lit.ts +1 -1
  240. package/src/generated/templates/PhoneNumberFieldTemplate.lit.ts +1 -1
  241. package/src/generated/themes/Accordion.css.ts +1 -1
  242. package/src/generated/themes/Button.css.ts +1 -1
  243. package/src/generated/themes/Contact.css.ts +9 -0
  244. package/src/generated/themes/ContactItem.css.ts +9 -0
  245. package/src/generated/themes/DatePickerPopover.css.ts +1 -1
  246. package/src/generated/themes/EventRibbon.css.ts +9 -0
  247. package/src/generated/themes/MastheadCountrySelector.css.ts +1 -1
  248. package/src/generated/themes/MastheadItem.css.ts +1 -1
  249. package/src/generated/themes/MastheadShell.css.ts +1 -1
  250. package/src/generated/themes/Modal.css.ts +1 -1
  251. package/src/generated/themes/Pagination.css.ts +1 -1
  252. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  253. package/src/generated/themes/Slider.css.ts +1 -1
  254. package/src/generated/themes/TextField.css.ts +1 -1
  255. package/src/i18n/messagebundle.properties +5 -0
  256. package/src/i18n/messagebundle_en.properties +3 -0
  257. package/src/themes/Accordion.css +1 -0
  258. package/src/themes/Button.css +74 -26
  259. package/src/themes/Contact.css +184 -0
  260. package/src/themes/ContactItem.css +44 -0
  261. package/src/themes/DatePickerPopover.css +64 -6
  262. package/src/themes/EventRibbon.css +411 -0
  263. package/src/themes/MastheadCountrySelector.css +8 -5
  264. package/src/themes/MastheadItem.css +12 -4
  265. package/src/themes/MastheadShell.css +3 -1
  266. package/src/themes/Modal.css +8 -4
  267. package/src/themes/Pagination.css +19 -0
  268. package/src/themes/TextField.css +2 -13
  269. package/src/types/ContactItemIcon.ts +7 -0
  270. package/src/types/EventRibbon.ts +51 -0
  271. package/src/utils/parseArrayFromString.ts +5 -0
  272. package/swap-component-imports.js +18 -0
  273. package/dist/assets/messagebundle_en-CVKgy_9L.js +0 -1
package/src/Footer.ts CHANGED
@@ -16,6 +16,7 @@ import UDExLink from "./Link.js";
16
16
  import UDExDivider from "./Divider.js";
17
17
  import type { UDExTarget } from "./types/common.js";
18
18
  import { BreakpointUtils } from "./utils/Breakpoints.js";
19
+ import parseArrayFromString from "./utils/parseArrayFromString.js";
19
20
 
20
21
  // Template
21
22
  import FooterTemplate from "./generated/templates/FooterTemplate.lit.js";
@@ -394,36 +395,32 @@ class UDExFooter extends UI5Element {
394
395
  window.scrollTo(0, 0);
395
396
  }
396
397
 
397
- parseArrayFromString<T>(string: string): T[] {
398
- return string ? JSON.parse(string) as T[] : [];
399
- }
400
-
401
398
  get parsedRef(): string | undefined {
402
399
  return (this.logoLink && this.logoLink.length > 0) ? this.logoLink : undefined;
403
400
  }
404
401
 
405
402
  get quickLinksArray(): FooterLink[] {
406
- return this.parseArrayFromString<FooterLink>(this.quickLinks);
403
+ return parseArrayFromString<FooterLink>(this.quickLinks);
407
404
  }
408
405
 
409
406
  get trendingLinksArray(): FooterLink[] {
410
- return this.parseArrayFromString<FooterLink>(this.trendingLinks);
407
+ return parseArrayFromString<FooterLink>(this.trendingLinks);
411
408
  }
412
409
 
413
410
  get aboutLinksArray(): FooterLink[] {
414
- return this.parseArrayFromString<FooterLink>(this.aboutLinks);
411
+ return parseArrayFromString<FooterLink>(this.aboutLinks);
415
412
  }
416
413
 
417
414
  get siteInformationLinksArray(): FooterLink[] {
418
- return this.parseArrayFromString<FooterLink>(this.siteInformationLinks);
415
+ return parseArrayFromString<FooterLink>(this.siteInformationLinks);
419
416
  }
420
417
 
421
418
  get contactNumbersArray(): FooterContactNumber[] {
422
- return this.parseArrayFromString<FooterContactNumber>(this.contactNumbersList);
419
+ return parseArrayFromString<FooterContactNumber>(this.contactNumbersList);
423
420
  }
424
421
 
425
422
  get socialLinksArray(): FooterSocialLink[] {
426
- return this.parseArrayFromString<FooterSocialLink>(this.socialLinks);
423
+ return parseArrayFromString<FooterSocialLink>(this.socialLinks);
427
424
  }
428
425
 
429
426
  get isContactContainerVisible(): boolean {
package/src/List.ts CHANGED
@@ -42,7 +42,7 @@ type UDExListSelectionChangeEventDetail = {
42
42
  * @class
43
43
  *
44
44
  * <h3 class="comment-api-title">Overview</h3>
45
- *\e
45
+ *
46
46
  *
47
47
  * <h3>Usage</h3>
48
48
  *
@@ -65,8 +65,16 @@
65
65
  {{else if image}}
66
66
  <img
67
67
  class="udex-masthead-item__image"
68
+ id="{{this._id}}_image-alt"
68
69
  src="{{image}}"
69
70
  alt="{{imageAlt}}"/>
71
+ {{#if imageAlt}}
72
+ <span
73
+ id="image-desc"
74
+ class="udex-masthead-hidden-text">
75
+ {{imageAlt}}
76
+ </span>
77
+ {{/if}}
70
78
  {{else}}
71
79
  <span class="udex-masthead-item__text">
72
80
  <slot></slot>
@@ -20,6 +20,7 @@ import type UDExMastheadShell from "./MastheadShell.js";
20
20
  import MastheadItemTemplate from "./generated/templates/MastheadItemTemplate.lit.js";
21
21
  import { UDExTarget } from "./types/common.js";
22
22
  import { BreakpointUtils } from "./utils/Breakpoints.js";
23
+ import parseArrayFromString from "./utils/parseArrayFromString.js";
23
24
 
24
25
  // Styles
25
26
  import MastheadItemCss from "./generated/themes/MastheadItem.css.js";
@@ -31,7 +32,6 @@ export enum UDExMastheadDropdownItemAction {
31
32
  }
32
33
 
33
34
  export interface IMastheadItem {
34
- text?: string;
35
35
  selected?: boolean;
36
36
  icon?: string;
37
37
  avatar?: Array<HTMLElement>;
@@ -449,12 +449,8 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
449
449
  return this.shadowRoot?.querySelector(`${selector}`);
450
450
  }
451
451
 
452
- parseArrayFromString<T>(string: string): T[] {
453
- return string ? JSON.parse(string) as T[] : [];
454
- }
455
-
456
452
  getSubItems(): Array<MenuItem> {
457
- return this.parseArrayFromString(this.subItems);
453
+ return parseArrayFromString(this.subItems);
458
454
  }
459
455
 
460
456
  get mastheadShell(): UDExMastheadShell {
@@ -494,22 +490,18 @@ class UDExMastheadItem extends UI5Element implements IMastheadItem {
494
490
  return this.selected ? " udex-masthead-item__button--active" : "";
495
491
  }
496
492
 
497
- get ariaDescribedBy(): string {
493
+ get ariaDescribedBy(): string | undefined {
498
494
  const labels = [];
499
495
 
500
- if (this.text) {
501
- labels.push(`${this.__id}-text`);
502
- }
503
-
504
- if (this.icon) {
505
- labels.push(`${this.__id}-icon`);
506
- }
507
-
508
496
  if (this.isTargetBlank) {
509
497
  labels.push(`new-win-desc`);
510
498
  }
511
499
 
512
- return labels.join(" ").trim();
500
+ if (this.imageAlt) {
501
+ labels.push(`image-desc`);
502
+ }
503
+
504
+ return labels.length ? labels.join(" ").trim() : undefined;
513
505
  }
514
506
 
515
507
  get isDropdownOpened(): boolean {
@@ -11,6 +11,7 @@ import UDExBadge from "./Badge.js";
11
11
  import UDExMastheadMenuItem, { UDExItemType } from "./MastheadMenuItem.js";
12
12
  import UDExDivider from "./Divider.js";
13
13
  import MastheadMenuTemplate from "./generated/templates/MastheadMenuTemplate.lit.js";
14
+ import parseArrayFromString from "./utils/parseArrayFromString.js";
14
15
 
15
16
  // Styles
16
17
  import MastheadMenuCss from "./generated/themes/MastheadMenu.css.js";
@@ -154,10 +155,6 @@ class UDExMastheadMenu extends UI5Element {
154
155
  return this.links.indexOf(item);
155
156
  }
156
157
 
157
- parseArrayFromString<T>(string: string): T[] {
158
- return string ? JSON.parse(string) as T[] : [];
159
- }
160
-
161
158
  get links(): Array<UDExMastheadMenuItem> {
162
159
  const menuItems: Array<UDExMastheadMenuItem> = Array.from(this.shadowRoot!.querySelectorAll("[udex-masthead-menu-item]"));
163
160
  return menuItems.filter(({ url }) => url && url.length > 0);
@@ -165,7 +162,7 @@ class UDExMastheadMenu extends UI5Element {
165
162
 
166
163
  get itemsList(): Array<MenuItem> {
167
164
  let id = 1;
168
- const parsedItems: Array<MenuItem> = this.parseArrayFromString(this.subItems);
165
+ const parsedItems: Array<MenuItem> = parseArrayFromString(this.subItems);
169
166
  return parsedItems.map((mainItem: MenuItem) => {
170
167
  mainItem.subMenuLinkItems = mainItem.subMenuLinkItems.map((category: SubMenuLinkItem) => {
171
168
  category.categoryId = `${id++}`;
@@ -10,6 +10,7 @@ import { LOGOUT } from "./generated/i18n/i18n-defaults.js";
10
10
  import UDExMastheadMenu from "./MastheadMenu.js";
11
11
  import MastheadProfileMenuTemplate from "./generated/templates/MastheadProfileMenuTemplate.lit.js";
12
12
  import type UDExMastheadMenuItem from "./MastheadMenuItem.js";
13
+ import parseArrayFromString from "./utils/parseArrayFromString.js";
13
14
 
14
15
  // Styles
15
16
  import MastheadProfileMenuCss from "./generated/themes/MastheadProfileMenu.css.js";
@@ -135,10 +136,6 @@ class UDExMastheadProfileMenu extends UI5Element {
135
136
  });
136
137
  }
137
138
 
138
- parseArrayFromString<T>(string: string): T[] {
139
- return string ? JSON.parse(string) as T[] : [];
140
- }
141
-
142
139
  get linksList(): string {
143
140
  return this.links ? JSON.stringify([{
144
141
  subMenuLinkItems: JSON.parse(this.links),
@@ -146,7 +143,7 @@ class UDExMastheadProfileMenu extends UI5Element {
146
143
  }
147
144
 
148
145
  get userData(): UserData {
149
- return this.parseArrayFromString(this.loggedInUser) as UserData;
146
+ return parseArrayFromString(this.loggedInUser) as UserData;
150
147
  }
151
148
 
152
149
  get messageAvailable(): boolean {
@@ -387,6 +387,12 @@ class UDExMastheadShell extends UI5Element {
387
387
  this._handleResizeBound = this._handleResize.bind(this);
388
388
  }
389
389
 
390
+ onBeforeRendering() {
391
+ if (this.isMobileMenuMode) {
392
+ this.setMobileMenuHeight();
393
+ }
394
+ }
395
+
390
396
  onAfterRendering() {
391
397
  this._rootHolder = this.mastheadHolder;
392
398
  this._searchOpener = this.searchOpener;
@@ -414,7 +420,7 @@ class UDExMastheadShell extends UI5Element {
414
420
  this.handleMobileMode();
415
421
  }
416
422
 
417
- if (this.isBreakpointSizeM) {
423
+ if (this.isAtMostBreakpointSizeM) {
418
424
  this._isSearchOpened = false;
419
425
  }
420
426
 
@@ -424,6 +430,10 @@ class UDExMastheadShell extends UI5Element {
424
430
  return;
425
431
  }
426
432
 
433
+ if (this.isMobileMenuMode) {
434
+ this.setMobileMenuHeight();
435
+ }
436
+
427
437
  this._shouldHandleResize = true;
428
438
  }
429
439
 
@@ -713,6 +723,12 @@ class UDExMastheadShell extends UI5Element {
713
723
  });
714
724
  }
715
725
 
726
+ setMobileMenuHeight(): void {
727
+ const mastheadHeight = parseInt(window.getComputedStyle(this).getPropertyValue("--udex-masthead-shell-height"));
728
+ const mobileMenuHeight = `${window.innerHeight - mastheadHeight}px`;
729
+ this.style.setProperty("--udex-masthead-shell-mobile-menu-height", mobileMenuHeight);
730
+ }
731
+
716
732
  removeMobileMode(): void {
717
733
  this._isMobileMode = false;
718
734
  this.slottedItems.forEach((item: MastheadSlottedItem) => {
@@ -735,7 +751,7 @@ class UDExMastheadShell extends UI5Element {
735
751
  */
736
752
  openSearch(): void {
737
753
  const shouldPreventOpeningSearch = this._isSearchOpened
738
- || (this.isBreakpointSizeM && !this.showSearchByDefault)
754
+ || (this.isAtMostBreakpointSizeM && !this.showSearchByDefault)
739
755
  || this._isMobileMode
740
756
  || (this.isAtLeastBreakpointSizeM && this.showSearchByDefault);
741
757
 
@@ -758,7 +774,7 @@ class UDExMastheadShell extends UI5Element {
758
774
  * @public
759
775
  */
760
776
  openMobileMenu(): void {
761
- if (!this._isMobileMenuOpen && (this._isMobileMode || this.isBreakpointSizeM)) {
777
+ if (!this._isMobileMenuOpen && this.isMobileMenuMode) {
762
778
  this.mobileBtn?.handleSelectedChange();
763
779
  this.handleOpenMobileMenu();
764
780
  }
@@ -873,7 +889,7 @@ class UDExMastheadShell extends UI5Element {
873
889
  return !!this.mobileMenu.length;
874
890
  }
875
891
 
876
- get isBreakpointSizeM(): boolean {
892
+ get isAtMostBreakpointSizeM(): boolean {
877
893
  return BreakpointUtils.isAtMost("M");
878
894
  }
879
895
 
@@ -881,6 +897,10 @@ class UDExMastheadShell extends UI5Element {
881
897
  return BreakpointUtils.isAtLeast("M");
882
898
  }
883
899
 
900
+ get isMobileMenuMode(): boolean {
901
+ return this._isMobileMode || this.isAtMostBreakpointSizeM;
902
+ }
903
+
884
904
  get isMainMenuVisible(): boolean {
885
905
  return !this.showSearchByDefault && !this._isSearchOpened;
886
906
  }
@@ -890,7 +910,7 @@ class UDExMastheadShell extends UI5Element {
890
910
  }
891
911
 
892
912
  get shouldHandleMobileView(): boolean {
893
- return !this.isBreakpointSizeM && !this.showSearchByDefault;
913
+ return !this.isAtMostBreakpointSizeM && !this.showSearchByDefault;
894
914
  }
895
915
 
896
916
  get mainNavigationAriaLabel(): string {
@@ -3,13 +3,15 @@
3
3
  <ul class="udex-pagination__list">
4
4
  <li class="udex-pagination__item--prev udex-pagination__item">
5
5
  <udex-button
6
- ?disabled="{{prevButtonDisabled}}"
6
+ aria-disabled="{{effectivePrevButtonDisabled}}"
7
+ ?_aria-disabled="{{_prevButtonPseudoDisabled}}"
7
8
  accessible-name="{{previousPageAccessibleName}}"
8
9
  tooltip="{{previousBtnTooltip}}"
9
10
  size="Large"
10
11
  icon="navigation-left-arrow"
11
12
  design="Tertiary"
12
13
  @click="{{setPrevPage}}"
14
+ @focusout="{{handlePrevFocusOut}}"
13
15
  ></udex-button>
14
16
  </li>
15
17
  {{#if typeFull}}
@@ -17,7 +19,7 @@
17
19
  <li class="udex-pagination__item">
18
20
  <a class="udex-pagination__page" href="#"
19
21
  aria-label="{{accessibleName}}"
20
- @click="{{../onPageClick}}"
22
+ @click="{{../onPageClick}}"
21
23
  ?active="{{active}}"
22
24
  aria-current="{{ariaCurrent}}"
23
25
  index="{{index}}">
@@ -35,13 +37,15 @@
35
37
  {{/if}}
36
38
  <li class="udex-pagination__item--next udex-pagination__item">
37
39
  <udex-button
38
- ?disabled="{{nextButtonDisbled}}"
40
+ aria-disabled="{{effectiveNextButtonDisabled}}"
41
+ ?_aria-disabled="{{_nextButtonPseudoDisabled}}"
39
42
  tooltip="{{nextBtnTooltip}}"
40
43
  accessible-name="{{nextPageAccessibleName}}"
41
44
  size="Large"
42
45
  icon="navigation-right-arrow"
43
46
  design="Tertiary"
44
47
  @click="{{setNextPage}}"
48
+ @focusout="{{handleNextFocusOut}}"
45
49
  ></udex-button>
46
50
  </li>
47
51
  </ul>
package/src/Pagination.ts CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  PREVIOUS_PAGE,
17
17
  NEXT_PAGE,
18
18
  CURRENT_PAGE,
19
+ DISABLED,
19
20
  } from "./generated/i18n/i18n-defaults.js";
20
21
  import Button from "./Button.js";
21
22
  import "@ui5/webcomponents/dist/Icon.js";
@@ -124,6 +125,22 @@ class UDExPagination extends UI5Element {
124
125
  @property({ type: String })
125
126
  _direction?: string;
126
127
 
128
+ /**
129
+ * Defines if the previous button is in pseudo-disabled.
130
+ *
131
+ * @private
132
+ */
133
+ @property({ type: Boolean })
134
+ _nextButtonPseudoDisabled!: boolean;
135
+
136
+ /**
137
+ * Defines if the previous button is in pseudo-disabled.
138
+ *
139
+ * @private
140
+ */
141
+ @property({ type: Boolean })
142
+ _prevButtonPseudoDisabled!: boolean;
143
+
127
144
  @i18n("@sapudex/web-components")
128
145
  static i18nBundle: I18nBundle;
129
146
 
@@ -159,7 +176,7 @@ class UDExPagination extends UI5Element {
159
176
  this.setupPages(this.pages);
160
177
  }
161
178
 
162
- get nextButtonDisbled(): boolean {
179
+ get nextButtonDisabled(): boolean {
163
180
  return this.currentPageIndex + 1 === this.pages;
164
181
  }
165
182
 
@@ -230,8 +247,12 @@ class UDExPagination extends UI5Element {
230
247
  }
231
248
 
232
249
  get previousPageAccessibleName(): string {
233
- if (this.currentPageIndex === 0) { return UDExPagination.i18nBundle.getText(PREVIOUS_PAGE); }
234
- return `${UDExPagination.i18nBundle.getText(CURRENT_PAGE)} ${this.currentPageIndex + 1}. ${UDExPagination.i18nBundle.getText(PREVIOUS_PAGE)}. ${this.activatePageAccessibleText} ${this.currentPageIndex}`;
250
+ const currentPageText = `${UDExPagination.i18nBundle.getText(CURRENT_PAGE)} ${this.currentPageIndex + 1}.`;
251
+ if (this._prevButtonPseudoDisabled || this.prevButtonDisabled) {
252
+ const effectiveDisabledText = this._prevButtonPseudoDisabled ? `${UDExPagination.i18nBundle.getText(DISABLED)}` : "";
253
+ return `${currentPageText} ${UDExPagination.i18nBundle.getText(PREVIOUS_PAGE)} ${effectiveDisabledText}`;
254
+ }
255
+ return `${currentPageText} ${UDExPagination.i18nBundle.getText(PREVIOUS_PAGE)}. ${this.activatePageAccessibleText} ${this.currentPageIndex}`;
235
256
  }
236
257
 
237
258
  get previousBtnTooltip(): string {
@@ -239,12 +260,16 @@ class UDExPagination extends UI5Element {
239
260
  }
240
261
 
241
262
  get nextPageAccessibleName(): string {
242
- if (this.pages && this.currentPageIndex === (this.pages - 1)) { return UDExPagination.i18nBundle.getText(NEXT_PAGE); }
243
- return `${UDExPagination.i18nBundle.getText(CURRENT_PAGE)} ${this.currentPageIndex + 1}. ${UDExPagination.i18nBundle.getText(NEXT_PAGE)}. ${this.activatePageAccessibleText} ${this.currentPageIndex + 2}`;
263
+ const currentPageText = `${UDExPagination.i18nBundle.getText(CURRENT_PAGE)} ${this.currentPageIndex + 1}.`;
264
+ if (this._nextButtonPseudoDisabled || this.nextButtonDisabled) {
265
+ const effectiveDisabledText = this._nextButtonPseudoDisabled ? `${UDExPagination.i18nBundle.getText(DISABLED)}` : "";
266
+ return `${currentPageText} ${UDExPagination.i18nBundle.getText(NEXT_PAGE)} ${effectiveDisabledText}`;
267
+ }
268
+ return `${currentPageText} ${UDExPagination.i18nBundle.getText(NEXT_PAGE)}. ${this.activatePageAccessibleText} ${this.currentPageIndex + 2}`;
244
269
  }
245
270
 
246
271
  get nextBtnTooltip(): string {
247
- return !this.nextButtonDisbled ? `${UDExPagination.i18nBundle.getText(NEXT_PAGE)}` : "";
272
+ return !this.nextButtonDisabled ? `${UDExPagination.i18nBundle.getText(NEXT_PAGE)}` : "";
248
273
  }
249
274
 
250
275
  get pagination(): Page[] {
@@ -297,46 +322,38 @@ class UDExPagination extends UI5Element {
297
322
  this.currentPageIndex = currentPage + 1;
298
323
  this._pageFocusedManually = false;
299
324
 
325
+ this._nextButtonPseudoDisabled = this.currentPageIndex === (this.pages - 1);
326
+
300
327
  this.emitChangeEvent();
301
328
  }
302
329
 
303
- setPrevPage(e: Event): void {
304
- e.preventDefault();
305
- const currentPage = this.currentPageIndex ?? 1;
306
- if (this.pages && currentPage <= 0) {
307
- return;
308
- }
309
- this.currentPageIndex -= 1;
310
- this._pageFocusedManually = false;
311
-
312
- this.emitChangeEvent();
330
+ get effectiveNextButtonDisabled(): boolean {
331
+ return !this._nextButtonPseudoDisabled && this.nextButtonDisabled;
313
332
  }
314
333
 
315
- setFirstPage(e: Event): void {
316
- e.preventDefault();
317
- const currentPage = this.currentPageIndex ?? 1;
318
- if (currentPage === 0) {
319
- return;
320
- }
334
+ get effectivePrevButtonDisabled(): boolean {
335
+ return !this._prevButtonPseudoDisabled && this.prevButtonDisabled;
336
+ }
321
337
 
322
- this._firstPageIndex = 0;
323
- this._lastPageIndex = this.displayNumber;
338
+ handlePrevFocusOut(): void {
339
+ this._prevButtonPseudoDisabled = false;
340
+ }
324
341
 
325
- this.currentPageIndex = 0;
326
- this.emitChangeEvent();
342
+ handleNextFocusOut(): void {
343
+ this._nextButtonPseudoDisabled = false;
327
344
  }
328
345
 
329
- setLastPage(e: Event): void {
346
+ setPrevPage(e: Event): void {
330
347
  e.preventDefault();
331
348
  const currentPage = this.currentPageIndex ?? 1;
332
- if (!this.pages || currentPage >= this.pages - 1) {
349
+ if (this.pages && currentPage <= 0) {
333
350
  return;
334
351
  }
352
+ this.currentPageIndex -= 1;
353
+ this._pageFocusedManually = false;
335
354
 
336
- this._firstPageIndex = this.pages - this.displayNumber;
337
- this._lastPageIndex = this.pages;
355
+ this._prevButtonPseudoDisabled = this.currentPageIndex === 0;
338
356
 
339
- this.currentPageIndex = this._lastPageIndex - 1;
340
357
  this.emitChangeEvent();
341
358
  }
342
359
 
@@ -64,7 +64,7 @@
64
64
  <img
65
65
  class="udex-phone-number-field__flag"
66
66
  aria-label="{{selectedCountryName}}"
67
- style="{{selectedFlagBackgroundPosition}}">
67
+ style="background-position-x: {{selectedFlagBackgroundPosition.x}}; background-position-y: {{selectedFlagBackgroundPosition.y}}">
68
68
  </div>
69
69
  </udex-button>
70
70
  {{/unless}}
@@ -44,6 +44,11 @@ export enum UDExPhoneNumberFieldValueState {
44
44
  Success = "Success",
45
45
  }
46
46
 
47
+ export type BackgroundPosition = {
48
+ x?: string,
49
+ y?: string,
50
+ };
51
+
47
52
  const initialPlaceholder: string = "+X XXX-XXX-XXXX";
48
53
  /**
49
54
  * Maximum number of possible digits based on international standard https://en.wikipedia.org/wiki/E.164
@@ -564,7 +569,7 @@ class UDExPhoneNumberField extends UI5Element {
564
569
  || this.updatedCountriesList[0]?.countryName;
565
570
  }
566
571
 
567
- get selectedFlagBackgroundPosition() {
572
+ get selectedFlagBackgroundPosition(): BackgroundPosition {
568
573
  if (!this.countryIso) {
569
574
  return {};
570
575
  }
@@ -575,7 +580,7 @@ class UDExPhoneNumberField extends UI5Element {
575
580
  return {};
576
581
  }
577
582
 
578
- return { "backgroundPosition": `${selectedCountry.flagX} ${selectedCountry.flagY}` };
583
+ return { x: selectedCountry?.flagX, y: selectedCountry?.flagY };
579
584
  }
580
585
 
581
586
  get ariaInvalid(): string | null {
@@ -97,6 +97,15 @@ class UDExSearchableListBase extends UI5Element {
97
97
  @property({ type: Boolean })
98
98
  busy?: boolean;
99
99
 
100
+ /**
101
+ * Defines if the search input is visible.
102
+ *
103
+ * @default false
104
+ * @public
105
+ */
106
+ @property({ type: Boolean })
107
+ showSearchInput!: boolean;
108
+
100
109
  /**
101
110
  * Defines the delay in milliseconds, after which the busy indicator will show up for this component.
102
111
  *
@@ -324,7 +333,12 @@ class UDExSearchableListBase extends UI5Element {
324
333
  }
325
334
 
326
335
  addSearchTermTag(text: string, str: string): string {
327
- return text.replace(new RegExp(`(${str})`, "i"), "<b>$&</b>");
336
+ if (!str.length) {
337
+ return text;
338
+ }
339
+
340
+ const regex = new RegExp(`(${str})`, "i");
341
+ return text.replace(regex, "<b>$1</b>");
328
342
  }
329
343
 
330
344
  isIncludes(string: string, value: string): boolean {
@@ -502,8 +516,15 @@ class UDExSearchableListBase extends UI5Element {
502
516
  }
503
517
 
504
518
  get showSearch(): boolean {
505
- const items = this.getSlottedItems(this.items).filter(({ isGroup }) => !isGroup);
506
- return items.length > SHOW_SEARCH_AFTER_COUNT && !this.modeRadioGroup;
519
+ return this.showSearchInput || (this.isSearchActive && !this.modeRadioGroup);
520
+ }
521
+
522
+ get isSearchActive(): boolean {
523
+ return this.nonGroupItems.length > SHOW_SEARCH_AFTER_COUNT;
524
+ }
525
+
526
+ get nonGroupItems(): Array<UDExListItemBase> {
527
+ return this.getSlottedItems(this.items).filter(item => !item.isGroup);
507
528
  }
508
529
 
509
530
  get roleForGroupList(): string {
@@ -20,6 +20,8 @@ import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
20
20
  import { MORE } from "./generated/i18n/i18n-defaults.js";
21
21
  import SecondaryNavigationTemplate from "./generated/templates/SecondaryNavigationTemplate.lit.js";
22
22
  import { BreakpointUtils } from "./utils/Breakpoints.js";
23
+ import parseArrayFromString from "./utils/parseArrayFromString.js";
24
+
23
25
  // Styles
24
26
  import SecondaryNavigationCss from "./generated/themes/SecondaryNavigation.css.js";
25
27
 
@@ -424,10 +426,6 @@ class UDExSecondaryNavigation extends UI5Element {
424
426
  });
425
427
  }
426
428
 
427
- parseArrayFromString<T>(string: string): T[] {
428
- return string ? JSON.parse(string) as T[] : [];
429
- }
430
-
431
429
  resetTabIndex(): void {
432
430
  this.domNavItems.forEach((item, index) => {
433
431
  item._tabIndex = index === 0 ? "0" : "-1";
@@ -466,7 +464,7 @@ class UDExSecondaryNavigation extends UI5Element {
466
464
  }
467
465
 
468
466
  get parsedItems(): Array<NavItem> {
469
- return this.parseArrayFromString<NavItem>(this.navItems);
467
+ return parseArrayFromString<NavItem>(this.navItems);
470
468
  }
471
469
 
472
470
  get visibleItems(): Array<NavItem> {
package/src/TextField.ts CHANGED
@@ -224,6 +224,15 @@ class UDExTextField extends UI5Element {
224
224
  @property({ type: Boolean })
225
225
  active!: boolean;
226
226
 
227
+ /**
228
+ * Defines if dropdown associated with text-field trigger has opened dropdown. It indicates active state of control button.
229
+ *
230
+ * @default false
231
+ * @public
232
+ */
233
+ @property({ type: Boolean })
234
+ iconActive!: boolean;
235
+
227
236
  /**
228
237
  * Defines the behaviour of autocomplete.
229
238
  * @default "off"
package/src/Wizard.ts CHANGED
@@ -85,6 +85,30 @@ class UDExWizard extends UI5Wizard {
85
85
  @property({ type: Boolean })
86
86
  indeterminate!: boolean;
87
87
 
88
+ /**
89
+ * Defines aria-label of the wizard, read by screen readers with the first step.
90
+ *
91
+ * @public
92
+ */
93
+ @property({ type: String })
94
+ accessibleName!: string;
95
+
96
+ /**
97
+ * Defines the title of the current step.
98
+ *
99
+ * @private
100
+ */
101
+ @property({ type: String })
102
+ _currentStepTitle?: string;
103
+
104
+ /**
105
+ * Defines the subtitle of the current step.
106
+ *
107
+ * @private
108
+ */
109
+ @property({ type: String })
110
+ _currentStepSubTitle?: string;
111
+
88
112
  /**
89
113
  * Defines the current breakpoint.
90
114
  *
@@ -115,10 +139,6 @@ class UDExWizard extends UI5Wizard {
115
139
  ResizeHandler.deregister(this, this._handleResizeBound);
116
140
  }
117
141
 
118
- onAfterRendering(): void {
119
- this._calcCurrentBreakpoint();
120
- }
121
-
122
142
  _adjustHeaderOverflow = () => {
123
143
  const tabs = this.stepsInHeaderDOM;
124
144
  tabs.forEach(step => {
@@ -168,13 +188,9 @@ class UDExWizard extends UI5Wizard {
168
188
  return this.steps.map((step, idx) => {
169
189
  const pos = idx + 1;
170
190
  const hideSeparator = idx === stepsCount - 1 && !this.indeterminate;
171
- const stepStateText = step.disabled
172
- ? this.inactiveStepText
173
- : this.activeStepText;
174
- const ariaLabel = (
175
- step.titleText
176
- ? `${pos} ${step.titleText} ${stepStateText}`
177
- : `${this.navStepDefaultHeading} ${pos} ${stepStateText}`
191
+ const ariaLabel = (`${idx === 0 ? this.effectiveAccessibleName : ""} ${step.titleText
192
+ ? `${pos} ${step.titleText}`
193
+ : `${this.navStepDefaultHeading} ${pos}`}`
178
194
  ).trim();
179
195
  const isAfterCurrent = idx > selectedStepIndex;
180
196
  accInfo = {
@@ -209,6 +225,18 @@ class UDExWizard extends UI5Wizard {
209
225
  this._calcCurrentBreakpoint();
210
226
  }
211
227
 
228
+ onAfterRendering(): void {
229
+ this.attachStepsResizeObserver();
230
+ this._calcCurrentBreakpoint();
231
+ this.previouslySelectedStepIndex = this.selectedStepIndex;
232
+ this._currentStepTitle = this._steps[this.selectedStepIndex].titleText;
233
+ this._currentStepSubTitle = this._steps[this.selectedStepIndex].subtitleText;
234
+ }
235
+
236
+ get effectiveAccessibleName(): string {
237
+ return this.accessibleName || this.ariaLabelText;
238
+ }
239
+
212
240
  get slottedSteps(): UDExWizardStep[] {
213
241
  return this.getSlottedNodes("steps");
214
242
  }