@sapudex/web-components 2.36.0 → 2.38.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 (215) hide show
  1. package/cypress/specs/List.cy.tsx +38 -0
  2. package/cypress/specs/Pagination.cy.tsx +52 -0
  3. package/cypress/specs/PasswordField.cy.tsx +36 -0
  4. package/cypress/specs/Search.cy.tsx +265 -0
  5. package/cypress/specs/SelectBox.cy.tsx +19 -1
  6. package/cypress/specs/TabNavigation.cy.tsx +314 -0
  7. package/cypress/specs/Table.cy.tsx +170 -0
  8. package/cypress/support/component-imports.instrumented.ts +2 -0
  9. package/cypress/support/component-imports.src.ts +2 -0
  10. package/dist/CountrySelector.d.ts +2 -0
  11. package/dist/CountrySelector.js +12 -3
  12. package/dist/CountrySelector.js.map +1 -1
  13. package/dist/CountrySelectorTemplate.d.ts +2 -0
  14. package/dist/CountrySelectorTemplate.js +8 -0
  15. package/dist/CountrySelectorTemplate.js.map +1 -0
  16. package/dist/FilterMenu.d.ts +3 -3
  17. package/dist/FilterMenu.js +8 -9
  18. package/dist/FilterMenu.js.map +1 -1
  19. package/dist/FilterMenuTemplate.d.ts +2 -0
  20. package/dist/FilterMenuTemplate.js +27 -0
  21. package/dist/FilterMenuTemplate.js.map +1 -0
  22. package/dist/List.d.ts +1 -0
  23. package/dist/List.js +4 -0
  24. package/dist/List.js.map +1 -1
  25. package/dist/Pagination.js +1 -0
  26. package/dist/Pagination.js.map +1 -1
  27. package/dist/PasswordField.d.ts +16 -0
  28. package/dist/PasswordField.js +40 -0
  29. package/dist/PasswordField.js.map +1 -1
  30. package/dist/PasswordFieldTemplate.js +1 -1
  31. package/dist/PasswordFieldTemplate.js.map +1 -1
  32. package/dist/Search.d.ts +1 -0
  33. package/dist/Search.js +6 -0
  34. package/dist/Search.js.map +1 -1
  35. package/dist/SearchableListBaseTemplate.d.ts +2 -0
  36. package/dist/SearchableListBaseTemplate.js +32 -0
  37. package/dist/SearchableListBaseTemplate.js.map +1 -0
  38. package/dist/SecondaryNavigation.d.ts +2 -0
  39. package/dist/SecondaryNavigation.js +20 -0
  40. package/dist/SecondaryNavigation.js.map +1 -1
  41. package/dist/SelectBase.d.ts +7 -6
  42. package/dist/SelectBase.js +2 -2
  43. package/dist/SelectBase.js.map +1 -1
  44. package/dist/SelectBox.d.ts +2 -0
  45. package/dist/SelectBox.js +12 -3
  46. package/dist/SelectBox.js.map +1 -1
  47. package/dist/SelectBoxTemplate.d.ts +2 -0
  48. package/dist/SelectBoxTemplate.js +27 -0
  49. package/dist/SelectBoxTemplate.js.map +1 -0
  50. package/dist/Tab.d.ts +9 -0
  51. package/dist/Tab.js +6 -0
  52. package/dist/Tab.js.map +1 -1
  53. package/dist/TabNavigation.js +32 -12
  54. package/dist/TabNavigation.js.map +1 -1
  55. package/dist/TableGroupRowTemplate.js +1 -1
  56. package/dist/TableGroupRowTemplate.js.map +1 -1
  57. package/dist/TableTemplate.js +1 -1
  58. package/dist/TableTemplate.js.map +1 -1
  59. package/dist/TagTemplate.js +2 -4
  60. package/dist/TagTemplate.js.map +1 -1
  61. package/dist/TextField.js +1 -0
  62. package/dist/TextField.js.map +1 -1
  63. package/dist/Wizard.d.ts +2 -2
  64. package/dist/Wizard.js +7 -7
  65. package/dist/Wizard.js.map +1 -1
  66. package/dist/assets/{InputSuggestions-BIR_sdOv.js → InputSuggestions-BQp20KJM.js} +1 -1
  67. package/dist/assets/{ListItemStandardExpandableTextTemplate-5xOuY0en.js → ListItemStandardExpandableTextTemplate-D0w0u6f7.js} +1 -1
  68. package/dist/assets/{bundle.esm-C8GwJvJr.js → bundle.esm-DIFG6k5I.js} +240 -240
  69. package/dist/assets/messagebundle_bg-4ainC3nj.js +1 -0
  70. package/dist/assets/messagebundle_cs-CFtmLavu.js +1 -0
  71. package/dist/assets/messagebundle_en-BxjFAY2S.js +1 -0
  72. package/dist/css/themes/MastheadMenu.css +1 -1
  73. package/dist/css/themes/MastheadMobileMenu.css +1 -1
  74. package/dist/css/themes/MediaPlayer.css +1 -1
  75. package/dist/css/themes/RatingBar.css +1 -1
  76. package/dist/css/themes/RatingIndicator.css +1 -1
  77. package/dist/css/themes/SecondaryNavigationSubItem.css +1 -1
  78. package/dist/css/themes/Slider.css +1 -1
  79. package/dist/css/themes/TabNavigation.css +1 -1
  80. package/dist/css/themes/TableGroupRow.css +1 -1
  81. package/dist/css/themes/Wizard.css +1 -1
  82. package/dist/css/themes/WizardTab.css +1 -1
  83. package/dist/custom-elements-internal.json +65 -0
  84. package/dist/custom-elements.json +49 -0
  85. package/dist/features/SearchSuggestionsPopover.d.ts +4 -0
  86. package/dist/features/SearchSuggestionsPopover.js +56 -3
  87. package/dist/features/SearchSuggestionsPopover.js.map +1 -1
  88. package/dist/generated/assets/i18n/messagebundle_bg.json +1 -1
  89. package/dist/generated/assets/i18n/messagebundle_cs.json +1 -1
  90. package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
  91. package/dist/generated/i18n/i18n-defaults.d.ts +2 -3
  92. package/dist/generated/i18n/i18n-defaults.js +2 -3
  93. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  94. package/dist/generated/templates/ListTemplate.lit.js +1 -1
  95. package/dist/generated/templates/ListTemplate.lit.js.map +1 -1
  96. package/dist/generated/templates/TabHeaderTemplate.lit.js +4 -4
  97. package/dist/generated/templates/TabHeaderTemplate.lit.js.map +1 -1
  98. package/dist/generated/templates/TabInOverflowTemplate.lit.js +2 -2
  99. package/dist/generated/templates/TabInOverflowTemplate.lit.js.map +1 -1
  100. package/dist/generated/themes/MastheadMenu.css.d.ts +1 -1
  101. package/dist/generated/themes/MastheadMenu.css.js +1 -1
  102. package/dist/generated/themes/MastheadMenu.css.js.map +1 -1
  103. package/dist/generated/themes/MastheadMobileMenu.css.d.ts +1 -1
  104. package/dist/generated/themes/MastheadMobileMenu.css.js +1 -1
  105. package/dist/generated/themes/MastheadMobileMenu.css.js.map +1 -1
  106. package/dist/generated/themes/MediaPlayer.css.d.ts +1 -1
  107. package/dist/generated/themes/MediaPlayer.css.js +1 -1
  108. package/dist/generated/themes/MediaPlayer.css.js.map +1 -1
  109. package/dist/generated/themes/RatingBar.css.d.ts +1 -1
  110. package/dist/generated/themes/RatingBar.css.js +1 -1
  111. package/dist/generated/themes/RatingBar.css.js.map +1 -1
  112. package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
  113. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  114. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  115. package/dist/generated/themes/SecondaryNavigationSubItem.css.d.ts +1 -1
  116. package/dist/generated/themes/SecondaryNavigationSubItem.css.js +1 -1
  117. package/dist/generated/themes/SecondaryNavigationSubItem.css.js.map +1 -1
  118. package/dist/generated/themes/Slider.css.d.ts +1 -1
  119. package/dist/generated/themes/Slider.css.js +1 -1
  120. package/dist/generated/themes/Slider.css.js.map +1 -1
  121. package/dist/generated/themes/TabNavigation.css.d.ts +1 -1
  122. package/dist/generated/themes/TabNavigation.css.js +1 -1
  123. package/dist/generated/themes/TabNavigation.css.js.map +1 -1
  124. package/dist/generated/themes/TableGroupRow.css.d.ts +1 -1
  125. package/dist/generated/themes/TableGroupRow.css.js +1 -1
  126. package/dist/generated/themes/TableGroupRow.css.js.map +1 -1
  127. package/dist/generated/themes/Wizard.css.d.ts +1 -1
  128. package/dist/generated/themes/Wizard.css.js +1 -1
  129. package/dist/generated/themes/Wizard.css.js.map +1 -1
  130. package/dist/generated/themes/WizardTab.css.d.ts +1 -1
  131. package/dist/generated/themes/WizardTab.css.js +1 -1
  132. package/dist/generated/themes/WizardTab.css.js.map +1 -1
  133. package/dist/messagebundle.properties +1 -6
  134. package/dist/messagebundle_bg.properties +129 -2
  135. package/dist/messagebundle_cs.properties +126 -0
  136. package/dist/messagebundle_en.properties +3 -1
  137. package/dist/vscode.html-custom-data.json +6 -1
  138. package/dist/web-types.json +42 -4
  139. package/package.json +1 -1
  140. package/src/CountrySelector.ts +14 -3
  141. package/src/CountrySelectorTemplate.tsx +12 -0
  142. package/src/FilterMenu.ts +9 -10
  143. package/src/FilterMenuTemplate.tsx +104 -0
  144. package/src/List.hbs +1 -1
  145. package/src/List.ts +5 -0
  146. package/src/Pagination.ts +1 -0
  147. package/src/PasswordField.ts +55 -0
  148. package/src/PasswordFieldTemplate.tsx +3 -0
  149. package/src/Search.ts +7 -0
  150. package/src/SearchableListBaseTemplate.tsx +157 -0
  151. package/src/SecondaryNavigation.ts +20 -0
  152. package/src/SelectBase.ts +7 -6
  153. package/src/SelectBox.ts +14 -3
  154. package/src/SelectBoxTemplate.tsx +165 -0
  155. package/src/Tab.ts +14 -0
  156. package/src/TabHeader.hbs +6 -2
  157. package/src/TabInOverflow.hbs +2 -0
  158. package/src/TabNavigation.ts +34 -12
  159. package/src/TableGroupRowTemplate.tsx +26 -17
  160. package/src/TableTemplate.tsx +1 -1
  161. package/src/TagTemplate.tsx +2 -4
  162. package/src/TextField.ts +1 -0
  163. package/src/Wizard.ts +15 -14
  164. package/src/features/SearchSuggestionsPopover.ts +59 -3
  165. package/src/generated/i18n/i18n-defaults.ts +2 -2
  166. package/src/generated/templates/ListTemplate.lit.ts +1 -1
  167. package/src/generated/templates/TabHeaderTemplate.lit.ts +4 -4
  168. package/src/generated/templates/TabInOverflowTemplate.lit.ts +2 -2
  169. package/src/generated/themes/MastheadMenu.css.ts +1 -1
  170. package/src/generated/themes/MastheadMobileMenu.css.ts +1 -1
  171. package/src/generated/themes/MediaPlayer.css.ts +1 -1
  172. package/src/generated/themes/RatingBar.css.ts +1 -1
  173. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  174. package/src/generated/themes/SecondaryNavigationSubItem.css.ts +1 -1
  175. package/src/generated/themes/Slider.css.ts +1 -1
  176. package/src/generated/themes/TabNavigation.css.ts +1 -1
  177. package/src/generated/themes/TableGroupRow.css.ts +1 -1
  178. package/src/generated/themes/Wizard.css.ts +1 -1
  179. package/src/generated/themes/WizardTab.css.ts +1 -1
  180. package/src/i18n/messagebundle.properties +1 -6
  181. package/src/i18n/messagebundle_bg.properties +129 -2
  182. package/src/i18n/messagebundle_cs.properties +126 -0
  183. package/src/i18n/messagebundle_en.properties +3 -1
  184. package/src/themes/MastheadMenu.css +4 -2
  185. package/src/themes/MastheadMobileMenu.css +4 -2
  186. package/src/themes/MediaPlayer.css +12 -0
  187. package/src/themes/RatingBar.css +14 -5
  188. package/src/themes/SecondaryNavigationSubItem.css +1 -0
  189. package/src/themes/TabNavigation.css +6 -0
  190. package/src/themes/TableGroupRow.css +5 -0
  191. package/src/themes/Wizard.css +19 -15
  192. package/src/themes/WizardTab.css +43 -28
  193. package/dist/assets/messagebundle_bg-4X593TQq.js +0 -1
  194. package/dist/assets/messagebundle_cs-Bt8XtMib.js +0 -1
  195. package/dist/assets/messagebundle_en-iNqRB1VZ.js +0 -1
  196. package/dist/generated/templates/CountrySelectorTemplate.lit.d.ts +0 -3
  197. package/dist/generated/templates/CountrySelectorTemplate.lit.js +0 -8
  198. package/dist/generated/templates/CountrySelectorTemplate.lit.js.map +0 -1
  199. package/dist/generated/templates/FilterMenuTemplate.lit.d.ts +0 -3
  200. package/dist/generated/templates/FilterMenuTemplate.lit.js +0 -13
  201. package/dist/generated/templates/FilterMenuTemplate.lit.js.map +0 -1
  202. package/dist/generated/templates/SearchableListBaseTemplate.lit.d.ts +0 -3
  203. package/dist/generated/templates/SearchableListBaseTemplate.lit.js +0 -19
  204. package/dist/generated/templates/SearchableListBaseTemplate.lit.js.map +0 -1
  205. package/dist/generated/templates/SelectBoxTemplate.lit.d.ts +0 -3
  206. package/dist/generated/templates/SelectBoxTemplate.lit.js +0 -20
  207. package/dist/generated/templates/SelectBoxTemplate.lit.js.map +0 -1
  208. package/src/CountrySelector.hbs +0 -6
  209. package/src/FilterMenu.hbs +0 -88
  210. package/src/SearchableListBase.hbs +0 -148
  211. package/src/SelectBox.hbs +0 -138
  212. package/src/generated/templates/CountrySelectorTemplate.lit.ts +0 -12
  213. package/src/generated/templates/FilterMenuTemplate.lit.ts +0 -17
  214. package/src/generated/templates/SearchableListBaseTemplate.lit.ts +0 -23
  215. package/src/generated/templates/SelectBoxTemplate.lit.ts +0 -24
@@ -1613,6 +1613,320 @@ describe("Tab Navigation component", () => {
1613
1613
  });
1614
1614
  });
1615
1615
 
1616
+ // ── Disabled tab behaviour ──────────────────────────────────────────────────
1617
+
1618
+ describe("Disabled tab", () => {
1619
+ describe("Rendering", () => {
1620
+ it("renders aria-disabled='true' on a disabled tab button", () => {
1621
+ cy.mount(
1622
+ <UDExTabNavigation>
1623
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1624
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1625
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1626
+ </UDExTabNavigation>
1627
+ );
1628
+
1629
+ cy.get("[udex-tab-navigation]")
1630
+ .shadow()
1631
+ .find("button[role='tab']")
1632
+ .eq(1)
1633
+ .should("have.attr", "aria-disabled", "true");
1634
+ });
1635
+
1636
+ it("does not set native disabled attribute — tab remains in DOM for assistive technology", () => {
1637
+ cy.mount(
1638
+ <UDExTabNavigation>
1639
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1640
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1641
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1642
+ </UDExTabNavigation>
1643
+ );
1644
+
1645
+ cy.get("[udex-tab-navigation]")
1646
+ .shadow()
1647
+ .find("button[role='tab']")
1648
+ .eq(1)
1649
+ .should("not.have.attr", "disabled");
1650
+ });
1651
+
1652
+ it("applies disabled opacity style to the disabled tab button", () => {
1653
+ cy.mount(
1654
+ <UDExTabNavigation>
1655
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1656
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1657
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1658
+ </UDExTabNavigation>
1659
+ );
1660
+
1661
+ cy.get("[udex-tab-navigation]")
1662
+ .shadow()
1663
+ .find("button[role='tab'][aria-disabled='true']")
1664
+ .should("have.css", "opacity", "0.4");
1665
+ });
1666
+
1667
+ it("does not apply aria-disabled on enabled tabs", () => {
1668
+ cy.mount(
1669
+ <UDExTabNavigation>
1670
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1671
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1672
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1673
+ </UDExTabNavigation>
1674
+ );
1675
+
1676
+ cy.get("[udex-tab-navigation]")
1677
+ .shadow()
1678
+ .find("button[role='tab']")
1679
+ .eq(0)
1680
+ .should("not.have.attr", "aria-disabled");
1681
+
1682
+ cy.get("[udex-tab-navigation]")
1683
+ .shadow()
1684
+ .find("button[role='tab']")
1685
+ .eq(2)
1686
+ .should("not.have.attr", "aria-disabled");
1687
+ });
1688
+ });
1689
+
1690
+ describe("Interaction", () => {
1691
+ it("does not change the selected tab when a disabled tab is clicked", () => {
1692
+ cy.mount(
1693
+ <UDExTabNavigation>
1694
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1695
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1696
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1697
+ </UDExTabNavigation>
1698
+ );
1699
+
1700
+ // Force click because pointer-events: none prevents normal click
1701
+ cy.get("[udex-tab-navigation]")
1702
+ .shadow()
1703
+ .find("button[role='tab']")
1704
+ .eq(1)
1705
+ .click({ force: true });
1706
+
1707
+ // Tab 1 should remain selected
1708
+ cy.get("[udex-tab-navigation]")
1709
+ .shadow()
1710
+ .find("button[role='tab'][aria-selected='true']")
1711
+ .should("contain.text", "Tab 1");
1712
+
1713
+ // Tab 2 should NOT be selected
1714
+ cy.get("[udex-tab-navigation]")
1715
+ .shadow()
1716
+ .find("button[role='tab']")
1717
+ .eq(1)
1718
+ .should("have.attr", "aria-selected", "false");
1719
+ });
1720
+
1721
+ it("does not fire tab-select event when a disabled tab is clicked", () => {
1722
+ const tabSelectHandler = cy.stub().as("tabSelect");
1723
+
1724
+ cy.mount(
1725
+ <UDExTabNavigation onTabSelect={tabSelectHandler}>
1726
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1727
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1728
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1729
+ </UDExTabNavigation>
1730
+ );
1731
+
1732
+ cy.get("[udex-tab-navigation]")
1733
+ .shadow()
1734
+ .find("button[role='tab']")
1735
+ .eq(1)
1736
+ .click({ force: true });
1737
+
1738
+ cy.get("@tabSelect").should("not.have.been.called");
1739
+ });
1740
+ });
1741
+
1742
+ describe("Keyboard navigation", () => {
1743
+ it("disabled tab has tabindex='-1' even when it would otherwise be the roving-tabindex target", () => {
1744
+ cy.mount(
1745
+ <UDExTabNavigation>
1746
+ <UDExTab text="Tab 1" disabled selected><div>Content 1</div></UDExTab>
1747
+ <UDExTab text="Tab 2"><div>Content 2</div></UDExTab>
1748
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1749
+ </UDExTabNavigation>
1750
+ );
1751
+
1752
+ // The disabled tab should always have tabindex -1
1753
+ cy.get("[udex-tab-navigation]")
1754
+ .shadow()
1755
+ .find("button[role='tab'][aria-disabled='true']")
1756
+ .should("have.attr", "tabindex", "-1");
1757
+ });
1758
+
1759
+ it("arrow-key navigation skips disabled tab (ArrowRight)", () => {
1760
+ cy.mount(
1761
+ <UDExTabNavigation>
1762
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1763
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1764
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1765
+ </UDExTabNavigation>
1766
+ );
1767
+
1768
+ // Focus Tab 1 and press ArrowRight — should skip Tab 2 (disabled) and land on Tab 3
1769
+ cy.get("[udex-tab-navigation]")
1770
+ .shadow()
1771
+ .find("button[role='tab']")
1772
+ .eq(0)
1773
+ .focus()
1774
+ .realPress("ArrowRight");
1775
+
1776
+ cy.get("[udex-tab-navigation]")
1777
+ .shadow()
1778
+ .find("button[role='tab']")
1779
+ .eq(2)
1780
+ .should("be.focused");
1781
+ });
1782
+
1783
+ it("arrow-key navigation skips disabled tab (ArrowLeft)", () => {
1784
+ cy.mount(
1785
+ <UDExTabNavigation>
1786
+ <UDExTab text="Tab 1"><div>Content 1</div></UDExTab>
1787
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1788
+ <UDExTab text="Tab 3" selected><div>Content 3</div></UDExTab>
1789
+ </UDExTabNavigation>
1790
+ );
1791
+
1792
+ // Focus Tab 3 and press ArrowLeft — should skip Tab 2 (disabled) and land on Tab 1
1793
+ cy.get("[udex-tab-navigation]")
1794
+ .shadow()
1795
+ .find("button[role='tab']")
1796
+ .eq(2)
1797
+ .focus()
1798
+ .realPress("ArrowLeft");
1799
+
1800
+ cy.get("[udex-tab-navigation]")
1801
+ .shadow()
1802
+ .find("button[role='tab']")
1803
+ .eq(0)
1804
+ .should("be.focused");
1805
+ });
1806
+
1807
+ it("arrow-key navigation skips multiple consecutive disabled tabs", () => {
1808
+ cy.mount(
1809
+ <UDExTabNavigation>
1810
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1811
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1812
+ <UDExTab text="Tab 3" disabled><div>Content 3</div></UDExTab>
1813
+ <UDExTab text="Tab 4"><div>Content 4</div></UDExTab>
1814
+ </UDExTabNavigation>
1815
+ );
1816
+
1817
+ cy.get("[udex-tab-navigation]")
1818
+ .shadow()
1819
+ .find("button[role='tab']")
1820
+ .eq(0)
1821
+ .focus()
1822
+ .realPress("ArrowRight");
1823
+
1824
+ cy.get("[udex-tab-navigation]")
1825
+ .shadow()
1826
+ .find("button[role='tab']")
1827
+ .eq(3)
1828
+ .should("be.focused");
1829
+ });
1830
+
1831
+ it("arrow-key navigation skips disabled tabs in vertical mode (ArrowDown)", () => {
1832
+ cy.mount(
1833
+ <UDExTabNavigation orientation="Vertical">
1834
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1835
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1836
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1837
+ </UDExTabNavigation>
1838
+ );
1839
+
1840
+ cy.get("[udex-tab-navigation]")
1841
+ .shadow()
1842
+ .find("button[role='tab']")
1843
+ .eq(0)
1844
+ .focus()
1845
+ .realPress("ArrowDown");
1846
+
1847
+ cy.get("[udex-tab-navigation]")
1848
+ .shadow()
1849
+ .find("button[role='tab']")
1850
+ .eq(2)
1851
+ .should("be.focused");
1852
+ });
1853
+ });
1854
+
1855
+ describe("Default selection", () => {
1856
+ it("selects the first non-disabled tab when the first tab is disabled and none are explicitly selected", () => {
1857
+ cy.mount(
1858
+ <UDExTabNavigation>
1859
+ <UDExTab text="Tab 1" disabled><div>Content 1</div></UDExTab>
1860
+ <UDExTab text="Tab 2"><div>Content 2</div></UDExTab>
1861
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1862
+ </UDExTabNavigation>
1863
+ );
1864
+
1865
+ cy.get("[udex-tab-navigation]")
1866
+ .shadow()
1867
+ .find("button[role='tab'][aria-selected='true']")
1868
+ .should("contain.text", "Tab 2");
1869
+ });
1870
+
1871
+ it("selects the first non-disabled tab when multiple leading tabs are disabled", () => {
1872
+ cy.mount(
1873
+ <UDExTabNavigation>
1874
+ <UDExTab text="Tab 1" disabled><div>Content 1</div></UDExTab>
1875
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1876
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1877
+ <UDExTab text="Tab 4"><div>Content 4</div></UDExTab>
1878
+ </UDExTabNavigation>
1879
+ );
1880
+
1881
+ cy.get("[udex-tab-navigation]")
1882
+ .shadow()
1883
+ .find("button[role='tab'][aria-selected='true']")
1884
+ .should("contain.text", "Tab 3");
1885
+ });
1886
+
1887
+ it("ignores selected attribute on a disabled tab and falls back to first enabled tab", () => {
1888
+ cy.mount(
1889
+ <UDExTabNavigation>
1890
+ <UDExTab text="Tab 1" disabled selected><div>Content 1</div></UDExTab>
1891
+ <UDExTab text="Tab 2"><div>Content 2</div></UDExTab>
1892
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1893
+ </UDExTabNavigation>
1894
+ );
1895
+
1896
+ // The disabled tab cannot be selected, so the first enabled tab is chosen
1897
+ cy.get("[udex-tab-navigation]")
1898
+ .shadow()
1899
+ .find("button[role='tab'][aria-selected='true']")
1900
+ .should("contain.text", "Tab 2");
1901
+ });
1902
+ });
1903
+
1904
+ describe("Auto-play skips disabled tabs", () => {
1905
+ it("auto-play advances past disabled tabs", () => {
1906
+ cy.clock(0, ["setInterval", "clearInterval"]);
1907
+ cy.mount(
1908
+ <UDExTabNavigation
1909
+ orientation="Vertical"
1910
+ autoPlay
1911
+ autoPlayInterval={1000}
1912
+ >
1913
+ <UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
1914
+ <UDExTab text="Tab 2" disabled><div>Content 2</div></UDExTab>
1915
+ <UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
1916
+ </UDExTabNavigation>
1917
+ );
1918
+
1919
+ // After 1 tick, auto-play should skip disabled Tab 2 and select Tab 3
1920
+ cy.tick(1000);
1921
+
1922
+ cy.get("[udex-tab-navigation]")
1923
+ .shadow()
1924
+ .find("button[role='tab'][aria-selected='true']")
1925
+ .should("contain.text", "Tab 3");
1926
+ });
1927
+ });
1928
+ });
1929
+
1616
1930
  // ── Process Tab variant ──────────────────────────────────────────────────────
1617
1931
 
1618
1932
  describe("TabNavigation - Process Tab variant", () => {
@@ -269,6 +269,10 @@ describe("Table", () => {
269
269
  cy.get("#table").shadow().find(".udex-table").should("have.attr", "aria-label", "table devices")
270
270
  });
271
271
 
272
+ it("header holder has role presentation to be transparent in the ARIA tree", () => {
273
+ cy.get("#table").shadow().find(".udex-table__header-holder").should("have.attr", "role", "presentation");
274
+ });
275
+
272
276
  it("renders the right amount of header rows", () => {
273
277
  cy.get("#table").find("udex-table-header-row").should("have.length", 1)
274
278
  });
@@ -357,3 +361,169 @@ describe("Table", () => {
357
361
  })
358
362
  });
359
363
  });
364
+
365
+ const multipleGroupRowsTable = <UDExTable id="table-multi-group">
366
+ <UDExTableHeaderRow slot="headerRow">
367
+ <UDExTableHeaderCell>Product</UDExTableHeaderCell>
368
+ <UDExTableHeaderCell>Price</UDExTableHeaderCell>
369
+ </UDExTableHeaderRow>
370
+ <UDExTableGroupRow id="group-row-1" group-title="Group A" collapsible>
371
+ <UDExTableRow>
372
+ <UDExTableCell>Item A1</UDExTableCell>
373
+ <UDExTableCell>$100</UDExTableCell>
374
+ </UDExTableRow>
375
+ </UDExTableGroupRow>
376
+ <UDExTableGroupRow id="group-row-2" group-title="Group B" collapsible>
377
+ <UDExTableRow>
378
+ <UDExTableCell>Item B1</UDExTableCell>
379
+ <UDExTableCell>$200</UDExTableCell>
380
+ </UDExTableRow>
381
+ </UDExTableGroupRow>
382
+ <UDExTableGroupRow id="group-row-3" group-title="Group C" collapsible>
383
+ <UDExTableRow>
384
+ <UDExTableCell>Item C1</UDExTableCell>
385
+ <UDExTableCell>$300</UDExTableCell>
386
+ </UDExTableRow>
387
+ </UDExTableGroupRow>
388
+ </UDExTable>;
389
+
390
+ describe("TableGroupRow Accessibility", () => {
391
+ beforeEach(() => {
392
+ cy.mount(multipleGroupRowsTable);
393
+ });
394
+
395
+ it("generates unique button IDs for each collapsible group row", () => {
396
+ const ids: string[] = [];
397
+
398
+ cy.get("[udex-table-group-row]").each($groupRow => {
399
+ cy.wrap($groupRow).shadow().find(".udex-table-grow-btn").invoke("attr", "id").then(id => {
400
+ expect(id).to.match(/^udex-table-group-opener-/);
401
+ ids.push(id as string);
402
+ });
403
+ }).then(() => {
404
+ const uniqueIds = new Set(ids);
405
+ expect(uniqueIds.size).to.equal(ids.length, "All group row button IDs must be unique");
406
+ });
407
+ });
408
+
409
+ it("button aria-controls references an existing element in the shadow DOM", () => {
410
+ cy.get("#group-row-1").shadow().find(".udex-table-grow-btn").then($btn => {
411
+ const controlsId = $btn.attr("aria-controls");
412
+ expect(controlsId).to.match(/^udex-table-group-rows-/);
413
+ cy.get("#group-row-1").shadow().find(`#${controlsId}`).should("exist").and("have.class", "udex-table-grow-rows");
414
+ });
415
+ });
416
+
417
+ it("button aria-controls value matches the rows container ID on the same instance", () => {
418
+ cy.get("[udex-table-group-row]").each($groupRow => {
419
+ cy.wrap($groupRow).shadow().find(".udex-table-grow-btn").invoke("attr", "aria-controls").then(controlsValue => {
420
+ cy.wrap($groupRow).shadow().find(".udex-table-grow-rows").invoke("attr", "id").should("equal", controlsValue);
421
+ });
422
+ });
423
+ });
424
+
425
+ it("each rows container has a unique ID matching its group row instance", () => {
426
+ const containerIds: string[] = [];
427
+
428
+ cy.get("[udex-table-group-row]").each($groupRow => {
429
+ cy.wrap($groupRow).shadow().find(".udex-table-grow-rows").invoke("attr", "id").then(id => {
430
+ expect(id).to.match(/^udex-table-group-rows-/);
431
+ containerIds.push(id as string);
432
+ });
433
+ }).then(() => {
434
+ const uniqueIds = new Set(containerIds);
435
+ expect(uniqueIds.size).to.equal(containerIds.length, "All rows container IDs must be unique");
436
+ });
437
+ });
438
+ });
439
+
440
+ const nonCollapsibleGroupRowTable = <UDExTable id="table-non-collapsible-group">
441
+ <UDExTableHeaderRow slot="headerRow">
442
+ <UDExTableHeaderCell>Product</UDExTableHeaderCell>
443
+ <UDExTableHeaderCell>Price</UDExTableHeaderCell>
444
+ </UDExTableHeaderRow>
445
+ <UDExTableGroupRow id="non-collapsible-group" group-title="Static Group">
446
+ <UDExTableRow>
447
+ <UDExTableCell>Item 1</UDExTableCell>
448
+ <UDExTableCell>$50</UDExTableCell>
449
+ </UDExTableRow>
450
+ </UDExTableGroupRow>
451
+ </UDExTable>;
452
+
453
+ describe("TableGroupRow ARIA Structure", () => {
454
+ describe("Collapsible group row", () => {
455
+ beforeEach(() => {
456
+ cy.mount(multipleGroupRowsTable);
457
+ });
458
+
459
+ it("contains a div with role='row' and class 'udex-table-group-header-row'", () => {
460
+ cy.get("#group-row-1").shadow().find("div[role='row']")
461
+ .should("exist")
462
+ .and("have.class", "udex-table-group-header-row");
463
+ });
464
+
465
+ it("the row wrapper contains a div with role='rowheader'", () => {
466
+ cy.get("#group-row-1").shadow().find("div[role='row'] > div[role='rowheader']")
467
+ .should("exist")
468
+ .and("have.class", "udex-table-group-header-cell");
469
+ });
470
+
471
+ it("the rowheader contains the button with class 'udex-table-grow-btn'", () => {
472
+ cy.get("#group-row-1").shadow().find("div[role='rowheader'] > button.udex-table-grow-btn")
473
+ .should("exist");
474
+ });
475
+
476
+ it("the row and rowheader wrappers have display:contents", () => {
477
+ cy.get("#group-row-1").shadow().find(".udex-table-group-header-row").then($row => {
478
+ expect(window.getComputedStyle($row[0]).display).to.equal("contents");
479
+ });
480
+ cy.get("#group-row-1").shadow().find(".udex-table-group-header-cell").then($cell => {
481
+ expect(window.getComputedStyle($cell[0]).display).to.equal("contents");
482
+ });
483
+ });
484
+
485
+ it("all collapsible group rows have the row > rowheader > button structure", () => {
486
+ cy.get("[udex-table-group-row]").each($groupRow => {
487
+ cy.wrap($groupRow).shadow().find("div[role='row'] > div[role='rowheader'] > button.udex-table-grow-btn")
488
+ .should("exist");
489
+ });
490
+ });
491
+ });
492
+
493
+ describe("Non-collapsible group row", () => {
494
+ beforeEach(() => {
495
+ cy.mount(nonCollapsibleGroupRowTable);
496
+ });
497
+
498
+ it("contains a div with role='row' and class 'udex-table-group-header-row'", () => {
499
+ cy.get("#non-collapsible-group").shadow().find("div[role='row']")
500
+ .should("exist")
501
+ .and("have.class", "udex-table-group-header-row");
502
+ });
503
+
504
+ it("the row wrapper contains a div with role='rowheader'", () => {
505
+ cy.get("#non-collapsible-group").shadow().find("div[role='row'] > div[role='rowheader']")
506
+ .should("exist")
507
+ .and("have.class", "udex-table-group-header-cell");
508
+ });
509
+
510
+ it("the rowheader contains a div (not button) with class 'udex-table-grow-btn'", () => {
511
+ cy.get("#non-collapsible-group").shadow().find("div[role='rowheader'] > div.udex-table-grow-btn")
512
+ .should("exist");
513
+ });
514
+
515
+ it("the non-collapsible title div displays the group title", () => {
516
+ cy.get("#non-collapsible-group").shadow().find("div[role='rowheader'] .udex-table-grow-btn")
517
+ .should("have.text", "Static Group");
518
+ });
519
+
520
+ it("the row and rowheader wrappers have display:contents", () => {
521
+ cy.get("#non-collapsible-group").shadow().find(".udex-table-group-header-row").then($row => {
522
+ expect(window.getComputedStyle($row[0]).display).to.equal("contents");
523
+ });
524
+ cy.get("#non-collapsible-group").shadow().find(".udex-table-group-header-cell").then($cell => {
525
+ expect(window.getComputedStyle($cell[0]).display).to.equal("contents");
526
+ });
527
+ });
528
+ });
529
+ });
@@ -43,6 +43,7 @@ import UDExMessageStrip from "../../instrumented/MessageStrip.js";
43
43
  import UDExModal from "../../instrumented/Modal.js";
44
44
  import UDExSearch from "../../instrumented/Search.js";
45
45
  import UDExMediaPlayer from "../../instrumented/MediaPlayer.js";
46
+ import UDExPagination from "../../instrumented/Pagination.js";
46
47
  import UDExPasswordField from "../../instrumented/PasswordField.js";
47
48
  import UDExPhoneNumberField from "../../instrumented/PhoneNumberField.js";
48
49
  import UDExPromoTile from "../../instrumented/PromoTile.js";
@@ -128,6 +129,7 @@ export {
128
129
  UDExModal,
129
130
  UDExMediaPlayer,
130
131
  UDExSearch,
132
+ UDExPagination,
131
133
  UDExPasswordField,
132
134
  UDExPhoneNumberField,
133
135
  UDExPromoTile,
@@ -43,6 +43,7 @@ import UDExMessageStrip from "../../src/MessageStrip.js";
43
43
  import UDExModal from "../../src/Modal.js";
44
44
  import UDExSearch from "../../src/Search.js";
45
45
  import UDExMediaPlayer from "../../src/MediaPlayer.js";
46
+ import UDExPagination from "../../src/Pagination.js";
46
47
  import UDExPasswordField from "../../src/PasswordField.js";
47
48
  import UDExPhoneNumberField from "../../src/PhoneNumberField.js";
48
49
  import UDExPromoTile from "../../src/PromoTile.js";
@@ -128,6 +129,7 @@ export {
128
129
  UDExModal,
129
130
  UDExMediaPlayer,
130
131
  UDExSearch,
132
+ UDExPagination,
131
133
  UDExPasswordField,
132
134
  UDExPhoneNumberField,
133
135
  UDExPromoTile,
@@ -71,6 +71,8 @@ declare class UDExCountrySelector extends UDExSelectBase {
71
71
  prepareCountrySelectorItems(): void;
72
72
  getItemTemplate(country: Country): string | undefined;
73
73
  getCountryLabel(countryName?: string, localName?: string): string | null;
74
+ get countryFlag(): object;
75
+ get searchableList(): import("@ui5/webcomponents-base").JSX.Element;
74
76
  get selectedCountryName(): string | null;
75
77
  get flagAriaLabel(): string;
76
78
  get selectedCountryFlagX(): string | undefined;
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
8
- import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
8
+ import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
9
9
  import property from "@ui5/webcomponents-base/dist/decorators/property.js";
10
10
  import UI5Button from "@ui5/webcomponents/dist/Button.js";
11
11
  import "@ui5/webcomponents-icons/dist/navigation-down-arrow.js";
@@ -20,7 +20,9 @@ import UDExSelectBase from "./SelectBase.js";
20
20
  import UDExListItem from "./ListItem.js";
21
21
  import UDExTextField from "./TextField.js";
22
22
  import UDExStatusMessage from "./StatusMessage.js";
23
- import SelectBoxTemplate from "./generated/templates/SelectBoxTemplate.lit.js";
23
+ import SelectBoxTemplate from "./SelectBoxTemplate.js";
24
+ import CountrySelectorTemplate from "./CountrySelectorTemplate.js";
25
+ import SearchableListBaseTemplate from "./SearchableListBaseTemplate.js";
24
26
  // Styles
25
27
  import CountrySelectorCss from "./generated/themes/CountrySelector.css.js";
26
28
  import TextFieldCss from "./generated/themes/TextField.css.js";
@@ -143,6 +145,13 @@ let UDExCountrySelector = class UDExCountrySelector extends UDExSelectBase {
143
145
  getCountryLabel(countryName, localName) {
144
146
  return localName ? `${countryName} (${localName})` : countryName || null;
145
147
  }
148
+ get countryFlag() {
149
+ return CountrySelectorTemplate.call(this);
150
+ }
151
+ get searchableList() {
152
+ this.defaultAccessibleRole = this._listBoxRole;
153
+ return SearchableListBaseTemplate.call(this);
154
+ }
146
155
  get selectedCountryName() {
147
156
  return this._selectedCountry ? this.getCountryLabel(this._selectedCountry.countryName, this._selectedCountry.localName) : "";
148
157
  }
@@ -174,7 +183,7 @@ __decorate([
174
183
  UDExCountrySelector = __decorate([
175
184
  customElement({
176
185
  tag: "udex-country-selector",
177
- renderer: litRender,
186
+ renderer: jsxRenderer,
178
187
  styles: [
179
188
  TextFieldCss,
180
189
  SelectBaseCss,
@@ -1 +1 @@
1
- {"version":3,"file":"CountrySelector.js","sourceRoot":"","sources":["../src/CountrySelector.ts"],"names":[],"mappings":"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","sourcesContent":["import customElement from \"@ui5/webcomponents-base/dist/decorators/customElement.js\";\nimport litRender from \"@ui5/webcomponents-base/dist/renderer/LitRenderer.js\";\nimport property from \"@ui5/webcomponents-base/dist/decorators/property.js\";\nimport UI5Button from \"@ui5/webcomponents/dist/Button.js\";\nimport \"@ui5/webcomponents-icons/dist/navigation-down-arrow.js\";\nimport \"@ui5/webcomponents-icons/dist/navigation-up-arrow.js\";\nimport type { Country } from \"./data/CountryListISO3166.js\";\nimport { CountryListDB } from \"./data/CountryListISO3166.js\";\nimport IllustratedMessage from \"@ui5/webcomponents-fiori/dist/IllustratedMessage.js\";\nimport \"@ui5/webcomponents-fiori/dist/illustrations/NoSearchResults.js\";\nimport UDExSearch from \"./Search.js\";\nimport UDExDropdown from \"./Dropdown.js\";\nimport UDExList from \"./List.js\";\nimport UDExSelectBase from \"./SelectBase.js\";\nimport UDExListItem from \"./ListItem.js\";\nimport UDExTextField from \"./TextField.js\";\nimport UDExStatusMessage from \"./StatusMessage.js\";\nimport SelectBoxTemplate from \"./generated/templates/SelectBoxTemplate.lit.js\";\n\n// Styles\nimport CountrySelectorCss from \"./generated/themes/CountrySelector.css.js\";\nimport TextFieldCss from \"./generated/themes/TextField.css.js\";\nimport SelectBaseCss from \"./generated/themes/SelectBase.css.js\";\nimport SearchableListCss from \"./generated/themes/SearchableList.css.js\";\nimport getEffectiveScrollbarStyle from \"./utils/getEffectiveScrollbarStyle.js\";\n\ntype UDExCountrySelectorChangeSearchEventDetail = {\n value: string,\n}\n\n/**\n * @class\n *\n * <h3 class=\"comment-api-title\">Overview</h3>\n *\n *\n * <h3>Usage</h3>\n *\n * For the <code>udex-country-selector</code>\n * <h3>ES6 Module Import</h3>\n *\n * <code>import \"@sapudex/web-components/dist/CountrySelector.js\";</code>\n *\n * @constructor\n * @extends UDExSelectBase\n * @tagname udex-country-selector\n * @public\n */\n@customElement({\n tag: \"udex-country-selector\",\n renderer: litRender,\n styles: [\n TextFieldCss,\n SelectBaseCss,\n CountrySelectorCss,\n SearchableListCss,\n getEffectiveScrollbarStyle(),\n ],\n template: SelectBoxTemplate,\n dependencies: [\n UI5Button,\n UDExList,\n UDExSearch,\n UDExListItem,\n UDExDropdown,\n UDExTextField,\n UDExStatusMessage,\n IllustratedMessage,\n ],\n})\n\nclass UDExCountrySelector extends UDExSelectBase {\n /**\n * Allows to define the initially preselected country.\n *\n * @default \"\"\n * @public\n */\n @property({ type: String })\n preselectedCountry!: string;\n\n /**\n * Allows to define the list of blocked country.\n *\n * @default \"\"\n * @public\n */\n @property({ type: String })\n blockedCountryCodes?: string;\n\n /**\n * Allows to hide the flag images in the country selector.\n *\n * @default false\n * @public\n */\n @property({ type: Boolean })\n hideFlagImages?: boolean;\n\n /**\n * Indicates whether the country selector is enabled.\n *\n * @default true\n * @private\n */\n @property({ type: Boolean })\n _countrySelector: boolean = true;\n\n _countryList: Country[] = CountryListDB;\n _selectedCountry!: Country | undefined;\n\n onAfterRendering(): void {\n super.onAfterRendering();\n this.handleOutsideClick();\n }\n\n onBeforeRendering(): void {\n super.onBeforeRendering();\n this.filterBlockedCountries();\n this.setPreselectedCountry();\n this.prepareCountrySelectorItems();\n }\n\n handleItemPress(e: CustomEvent): void {\n this.handleItemSelection(e);\n this.selectCountryByElement(e.target as HTMLElement);\n }\n\n handleInputFocusIn(): void {\n this.inputFocusIn();\n }\n\n handleInputFocusOut(e: FocusEvent): void {\n const relatedTarget = e.relatedTarget as HTMLElement;\n const isInsideComponent = relatedTarget?.closest(`.${this._rootClass}`);\n\n if (!isInsideComponent) {\n this.closeDropdown();\n this.resetSearchState();\n this.updateImagePosition();\n }\n\n this._focused = false;\n }\n\n handleKeyDownSearch(e: KeyboardEvent): void {\n this.onKeyDownSearch(e);\n }\n\n handleDropdownBeforeOpen(): void {\n this.dropdownBeforeOpen();\n }\n\n handleDropdownClose(): void {\n this._open = false;\n this.fireEventDropdownClose();\n }\n\n handleOutsideClick(): void {\n document.addEventListener(\"click\", (e: Event) => {\n if (e.target !== this) {\n this._open = this._popover.open;\n }\n });\n }\n\n updateImagePosition(): void {\n const imagePlaceholder = this.shadowRoot!.querySelector<HTMLElement>(\".udex-text-field__input > .udex-text-field__image\");\n if (imagePlaceholder) {\n imagePlaceholder.style.backgroundPosition = this.selectedCountryFlagX || \"\";\n }\n }\n\n filterBlockedCountries(): void {\n if (this.blockedCountryCodes?.length) {\n const blockedCountryCodesArray = this.blockedCountryCodes.split(\",\").map(code => code.trim().toUpperCase());\n this._countryList = this._countryList.filter(country => !blockedCountryCodesArray.includes(country.iso.toUpperCase()));\n }\n }\n\n setPreselectedCountry(): void {\n if (!this._selectedCountry && this.preselectedCountry) {\n const preselectedISO = this.preselectedCountry.toUpperCase();\n this._selectedCountry = this._countryList.find(({ iso }) => iso.toUpperCase() === preselectedISO);\n }\n }\n\n selectCountryByElement(el: HTMLElement): void {\n const tokenId = el?.getAttribute(\"data-token-id\") || \"\";\n const itemObj = this.getItemFromList(tokenId);\n this._selectedCountry = this._countryList.find(country => country.iso === itemObj?._id);\n this._selectedOption = this.selectedCountryName || \"\";\n }\n\n prepareCountrySelectorItems(): void {\n this.items.length = 0;\n this._countryList.forEach(country => {\n const selected = country.iso.toUpperCase() === this._selectedCountry?.iso.toUpperCase();\n this.items.push({\n label: this.getCountryLabel(country.countryName, country.localName),\n innerHTML: this.getItemTemplate(country),\n selected,\n _id: country.iso.toUpperCase(),\n } as UDExListItem);\n });\n }\n\n getItemTemplate(country: Country) :string | undefined {\n return this.hideFlagImages ? undefined : `<span class=\"udex-text-field__image\" style=\"background-position:${country.flagX}\">`;\n }\n\n getCountryLabel(countryName?: string, localName?: string): string | null {\n return localName ? `${countryName} (${localName})` : countryName || null;\n }\n\n get selectedCountryName(): string | null {\n return this._selectedCountry ? this.getCountryLabel(this._selectedCountry.countryName, this._selectedCountry.localName) : \"\";\n }\n\n get flagAriaLabel(): string {\n return this.getCountryLabel(this._selectedCountry?.countryName, this._selectedCountry?.localName) || \"None\";\n }\n\n get selectedCountryFlagX(): string | undefined {\n return this._selectedCountry?.flagX;\n }\n\n get selectedCountryFlagY(): string | undefined {\n return this._selectedCountry?.flagY;\n }\n\n get showImageFlags(): boolean {\n return true;\n }\n}\n\nUDExCountrySelector.define();\n\nexport default UDExCountrySelector;\nexport type { UDExCountrySelectorChangeSearchEventDetail };\n"]}
1
+ {"version":3,"file":"CountrySelector.js","sourceRoot":"","sources":["../src/CountrySelector.ts"],"names":[],"mappings":"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","sourcesContent":["import customElement from \"@ui5/webcomponents-base/dist/decorators/customElement.js\";\nimport jsxRenderer from \"@ui5/webcomponents-base/dist/renderer/JsxRenderer.js\";\nimport property from \"@ui5/webcomponents-base/dist/decorators/property.js\";\nimport UI5Button from \"@ui5/webcomponents/dist/Button.js\";\nimport \"@ui5/webcomponents-icons/dist/navigation-down-arrow.js\";\nimport \"@ui5/webcomponents-icons/dist/navigation-up-arrow.js\";\nimport type { Country } from \"./data/CountryListISO3166.js\";\nimport { CountryListDB } from \"./data/CountryListISO3166.js\";\nimport IllustratedMessage from \"@ui5/webcomponents-fiori/dist/IllustratedMessage.js\";\nimport \"@ui5/webcomponents-fiori/dist/illustrations/NoSearchResults.js\";\nimport UDExSearch from \"./Search.js\";\nimport UDExDropdown from \"./Dropdown.js\";\nimport UDExList from \"./List.js\";\nimport UDExSelectBase from \"./SelectBase.js\";\nimport UDExListItem from \"./ListItem.js\";\nimport UDExTextField from \"./TextField.js\";\nimport UDExStatusMessage from \"./StatusMessage.js\";\nimport SelectBoxTemplate from \"./SelectBoxTemplate.js\";\nimport CountrySelectorTemplate from \"./CountrySelectorTemplate.js\";\nimport SearchableListBaseTemplate from \"./SearchableListBaseTemplate.js\";\n\n// Styles\nimport CountrySelectorCss from \"./generated/themes/CountrySelector.css.js\";\nimport TextFieldCss from \"./generated/themes/TextField.css.js\";\nimport SelectBaseCss from \"./generated/themes/SelectBase.css.js\";\nimport SearchableListCss from \"./generated/themes/SearchableList.css.js\";\nimport getEffectiveScrollbarStyle from \"./utils/getEffectiveScrollbarStyle.js\";\n\ntype UDExCountrySelectorChangeSearchEventDetail = {\n value: string,\n}\n\n/**\n * @class\n *\n * <h3 class=\"comment-api-title\">Overview</h3>\n *\n *\n * <h3>Usage</h3>\n *\n * For the <code>udex-country-selector</code>\n * <h3>ES6 Module Import</h3>\n *\n * <code>import \"@sapudex/web-components/dist/CountrySelector.js\";</code>\n *\n * @constructor\n * @extends UDExSelectBase\n * @tagname udex-country-selector\n * @public\n */\n@customElement({\n tag: \"udex-country-selector\",\n renderer: jsxRenderer,\n styles: [\n TextFieldCss,\n SelectBaseCss,\n CountrySelectorCss,\n SearchableListCss,\n getEffectiveScrollbarStyle(),\n ],\n template: SelectBoxTemplate,\n dependencies: [\n UI5Button,\n UDExList,\n UDExSearch,\n UDExListItem,\n UDExDropdown,\n UDExTextField,\n UDExStatusMessage,\n IllustratedMessage,\n ],\n})\n\nclass UDExCountrySelector extends UDExSelectBase {\n /**\n * Allows to define the initially preselected country.\n *\n * @default \"\"\n * @public\n */\n @property({ type: String })\n preselectedCountry!: string;\n\n /**\n * Allows to define the list of blocked country.\n *\n * @default \"\"\n * @public\n */\n @property({ type: String })\n blockedCountryCodes?: string;\n\n /**\n * Allows to hide the flag images in the country selector.\n *\n * @default false\n * @public\n */\n @property({ type: Boolean })\n hideFlagImages?: boolean;\n\n /**\n * Indicates whether the country selector is enabled.\n *\n * @default true\n * @private\n */\n @property({ type: Boolean })\n _countrySelector: boolean = true;\n\n _countryList: Country[] = CountryListDB;\n _selectedCountry!: Country | undefined;\n\n onAfterRendering(): void {\n super.onAfterRendering();\n this.handleOutsideClick();\n }\n\n onBeforeRendering(): void {\n super.onBeforeRendering();\n this.filterBlockedCountries();\n this.setPreselectedCountry();\n this.prepareCountrySelectorItems();\n }\n\n handleItemPress(e: CustomEvent): void {\n this.handleItemSelection(e);\n this.selectCountryByElement(e.target as HTMLElement);\n }\n\n handleInputFocusIn(): void {\n this.inputFocusIn();\n }\n\n handleInputFocusOut(e: FocusEvent): void {\n const relatedTarget = e.relatedTarget as HTMLElement;\n const isInsideComponent = relatedTarget?.closest(`.${this._rootClass}`);\n\n if (!isInsideComponent) {\n this.closeDropdown();\n this.resetSearchState();\n this.updateImagePosition();\n }\n\n this._focused = false;\n }\n\n handleKeyDownSearch(e: KeyboardEvent): void {\n this.onKeyDownSearch(e);\n }\n\n handleDropdownBeforeOpen(): void {\n this.dropdownBeforeOpen();\n }\n\n handleDropdownClose(): void {\n this._open = false;\n this.fireEventDropdownClose();\n }\n\n handleOutsideClick(): void {\n document.addEventListener(\"click\", (e: Event) => {\n if (e.target !== this) {\n this._open = this._popover.open;\n }\n });\n }\n\n updateImagePosition(): void {\n const imagePlaceholder = this.shadowRoot!.querySelector<HTMLElement>(\".udex-text-field__input > .udex-text-field__image\");\n if (imagePlaceholder) {\n imagePlaceholder.style.backgroundPosition = this.selectedCountryFlagX || \"\";\n }\n }\n\n filterBlockedCountries(): void {\n if (this.blockedCountryCodes?.length) {\n const blockedCountryCodesArray = this.blockedCountryCodes.split(\",\").map(code => code.trim().toUpperCase());\n this._countryList = this._countryList.filter(country => !blockedCountryCodesArray.includes(country.iso.toUpperCase()));\n }\n }\n\n setPreselectedCountry(): void {\n if (!this._selectedCountry && this.preselectedCountry) {\n const preselectedISO = this.preselectedCountry.toUpperCase();\n this._selectedCountry = this._countryList.find(({ iso }) => iso.toUpperCase() === preselectedISO);\n }\n }\n\n selectCountryByElement(el: HTMLElement): void {\n const tokenId = el?.getAttribute(\"data-token-id\") || \"\";\n const itemObj = this.getItemFromList(tokenId);\n this._selectedCountry = this._countryList.find(country => country.iso === itemObj?._id);\n this._selectedOption = this.selectedCountryName || \"\";\n }\n\n prepareCountrySelectorItems(): void {\n this.items.length = 0;\n this._countryList.forEach(country => {\n const selected = country.iso.toUpperCase() === this._selectedCountry?.iso.toUpperCase();\n this.items.push({\n label: this.getCountryLabel(country.countryName, country.localName),\n innerHTML: this.getItemTemplate(country),\n selected,\n _id: country.iso.toUpperCase(),\n } as UDExListItem);\n });\n }\n\n getItemTemplate(country: Country) :string | undefined {\n return this.hideFlagImages ? undefined : `<span class=\"udex-text-field__image\" style=\"background-position:${country.flagX}\">`;\n }\n\n getCountryLabel(countryName?: string, localName?: string): string | null {\n return localName ? `${countryName} (${localName})` : countryName || null;\n }\n\n override get countryFlag(): object {\n return CountrySelectorTemplate.call(this) as object;\n }\n\n override get searchableList() {\n this.defaultAccessibleRole = this._listBoxRole;\n return SearchableListBaseTemplate.call(this);\n }\n\n get selectedCountryName(): string | null {\n return this._selectedCountry ? this.getCountryLabel(this._selectedCountry.countryName, this._selectedCountry.localName) : \"\";\n }\n\n get flagAriaLabel(): string {\n return this.getCountryLabel(this._selectedCountry?.countryName, this._selectedCountry?.localName) || \"None\";\n }\n\n get selectedCountryFlagX(): string | undefined {\n return this._selectedCountry?.flagX;\n }\n\n get selectedCountryFlagY(): string | undefined {\n return this._selectedCountry?.flagY;\n }\n\n get showImageFlags(): boolean {\n return true;\n }\n}\n\nUDExCountrySelector.define();\n\nexport default UDExCountrySelector;\nexport type { UDExCountrySelectorChangeSearchEventDetail };\n"]}
@@ -0,0 +1,2 @@
1
+ import type UDExCountrySelector from "./CountrySelector.js";
2
+ export default function CountrySelectorTemplate(this: UDExCountrySelector): import("@ui5/webcomponents-base").JSX.Element;