@sapudex/web-components 2.31.0 → 2.32.1
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.
- package/cypress/specs/Breadcrumbs.cy.tsx +26 -0
- package/cypress/specs/MediaPlayer.cy.tsx +209 -0
- package/cypress/specs/SecondaryNavigationDesktop.cy.tsx +74 -21
- package/cypress/specs/SecondaryNavigationMobile.cy.tsx +58 -1
- package/cypress/specs/SelectBox.cy.tsx +35 -0
- package/cypress/specs/StepInput.cy.tsx +507 -0
- package/cypress/specs/TabNavigation.cy.tsx +603 -39
- package/cypress/support/component-imports.instrumented.ts +4 -0
- package/cypress/support/component-imports.src.ts +7 -3
- package/dist/Breadcrumbs.d.ts +5 -0
- package/dist/Breadcrumbs.js +8 -1
- package/dist/Breadcrumbs.js.map +1 -1
- package/dist/HeroBanner.d.ts +0 -3
- package/dist/HeroBanner.js +0 -5
- package/dist/HeroBanner.js.map +1 -1
- package/dist/HeroBannerTemplate.d.ts +2 -0
- package/dist/HeroBannerTemplate.js +6 -1
- package/dist/HeroBannerTemplate.js.map +1 -1
- package/dist/MastheadItem.js +5 -4
- package/dist/MastheadItem.js.map +1 -1
- package/dist/MediaPlayer.d.ts +15 -0
- package/dist/MediaPlayer.js +28 -0
- package/dist/MediaPlayer.js.map +1 -1
- package/dist/SecondaryNavigation.d.ts +12 -2
- package/dist/SecondaryNavigation.js +59 -8
- package/dist/SecondaryNavigation.js.map +1 -1
- package/dist/SecondaryNavigationItem.d.ts +0 -1
- package/dist/SecondaryNavigationItem.js +0 -4
- package/dist/SecondaryNavigationItem.js.map +1 -1
- package/dist/SecondaryNavigationSubItem.js +1 -1
- package/dist/SecondaryNavigationSubItem.js.map +1 -1
- package/dist/SelectBase.js +2 -1
- package/dist/SelectBase.js.map +1 -1
- package/dist/StepInput.d.ts +3 -0
- package/dist/StepInput.js +17 -0
- package/dist/StepInput.js.map +1 -1
- package/dist/StepInputTemplate.js +1 -1
- package/dist/StepInputTemplate.js.map +1 -1
- package/dist/Tab.d.ts +1 -1
- package/dist/Tab.js +3 -3
- package/dist/Tab.js.map +1 -1
- package/dist/TabNavigation.d.ts +64 -0
- package/dist/TabNavigation.js +124 -1
- package/dist/TabNavigation.js.map +1 -1
- package/dist/assets/{InputSuggestions-i2kFpCfC.js → InputSuggestions-DeXhpK0F.js} +1 -1
- package/dist/assets/{ListItemStandardExpandableTextTemplate-C1ceDaxu.js → ListItemStandardExpandableTextTemplate-jMEdrC07.js} +1 -1
- package/dist/assets/{bundle.esm-DQ3cxywT.js → bundle.esm-CwJAt93x.js} +219 -219
- package/dist/assets/messagebundle_en-iNqRB1VZ.js +1 -0
- package/dist/css/themes/BreadcrumbsPopover.css +1 -1
- package/dist/css/themes/FilterMenu.css +1 -1
- package/dist/css/themes/HeroBanner.css +1 -1
- package/dist/css/themes/Modal.css +1 -1
- package/dist/css/themes/RatingIndicator.css +1 -1
- package/dist/css/themes/SecondaryNavigationItem.css +1 -1
- package/dist/css/themes/Slider.css +1 -1
- package/dist/css/themes/TabNavigation.css +1 -1
- package/dist/custom-elements-internal.json +221 -0
- package/dist/custom-elements.json +149 -0
- package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
- package/dist/generated/i18n/i18n-defaults.js +1 -1
- package/dist/generated/i18n/i18n-defaults.js.map +1 -1
- package/dist/generated/templates/SecondaryNavigationTemplate.lit.js +1 -1
- package/dist/generated/templates/SecondaryNavigationTemplate.lit.js.map +1 -1
- package/dist/generated/templates/TabNavigationTemplate.lit.js +10 -8
- package/dist/generated/templates/TabNavigationTemplate.lit.js.map +1 -1
- package/dist/generated/themes/BreadcrumbsPopover.css.d.ts +1 -1
- package/dist/generated/themes/BreadcrumbsPopover.css.js +1 -1
- package/dist/generated/themes/BreadcrumbsPopover.css.js.map +1 -1
- package/dist/generated/themes/FilterMenu.css.d.ts +1 -1
- package/dist/generated/themes/FilterMenu.css.js +1 -1
- package/dist/generated/themes/FilterMenu.css.js.map +1 -1
- package/dist/generated/themes/HeroBanner.css.d.ts +1 -1
- package/dist/generated/themes/HeroBanner.css.js +1 -1
- package/dist/generated/themes/HeroBanner.css.js.map +1 -1
- package/dist/generated/themes/Modal.css.d.ts +1 -1
- package/dist/generated/themes/Modal.css.js +1 -1
- package/dist/generated/themes/Modal.css.js.map +1 -1
- package/dist/generated/themes/RatingIndicator.css.d.ts +1 -1
- package/dist/generated/themes/RatingIndicator.css.js +1 -1
- package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
- package/dist/generated/themes/SecondaryNavigationItem.css.d.ts +1 -1
- package/dist/generated/themes/SecondaryNavigationItem.css.js +1 -1
- package/dist/generated/themes/SecondaryNavigationItem.css.js.map +1 -1
- package/dist/generated/themes/Slider.css.d.ts +1 -1
- package/dist/generated/themes/Slider.css.js +1 -1
- package/dist/generated/themes/Slider.css.js.map +1 -1
- package/dist/generated/themes/TabNavigation.css.d.ts +1 -1
- package/dist/generated/themes/TabNavigation.css.js +1 -1
- package/dist/generated/themes/TabNavigation.css.js.map +1 -1
- package/dist/messagebundle.properties +1 -1
- package/dist/messagebundle_en.properties +1 -1
- package/dist/vscode.html-custom-data.json +23 -3
- package/dist/web-types.json +64 -4
- package/package.json +1 -1
- package/src/Breadcrumbs.ts +9 -1
- package/src/HeroBanner.ts +0 -5
- package/src/HeroBannerTemplate.tsx +6 -1
- package/src/MastheadItem.ts +5 -4
- package/src/MediaPlayer.ts +35 -0
- package/src/SecondaryNavigation.hbs +1 -0
- package/src/SecondaryNavigation.ts +77 -9
- package/src/SecondaryNavigationItem.ts +0 -6
- package/src/SecondaryNavigationSubItem.ts +1 -1
- package/src/SelectBase.ts +2 -1
- package/src/StepInput.ts +20 -0
- package/src/StepInputTemplate.tsx +1 -1
- package/src/Tab.ts +4 -4
- package/src/TabNavigation.hbs +15 -0
- package/src/TabNavigation.ts +134 -1
- package/src/generated/i18n/i18n-defaults.ts +1 -1
- package/src/generated/templates/SecondaryNavigationTemplate.lit.ts +1 -1
- package/src/generated/templates/TabNavigationTemplate.lit.ts +10 -8
- package/src/generated/themes/BreadcrumbsPopover.css.ts +1 -1
- package/src/generated/themes/FilterMenu.css.ts +1 -1
- package/src/generated/themes/HeroBanner.css.ts +1 -1
- package/src/generated/themes/Modal.css.ts +1 -1
- package/src/generated/themes/RatingIndicator.css.ts +1 -1
- package/src/generated/themes/SecondaryNavigationItem.css.ts +1 -1
- package/src/generated/themes/Slider.css.ts +1 -1
- package/src/generated/themes/TabNavigation.css.ts +1 -1
- package/src/i18n/messagebundle.properties +1 -1
- package/src/i18n/messagebundle_en.properties +1 -1
- package/src/themes/BreadcrumbsPopover.css +2 -2
- package/src/themes/FilterMenu.css +5 -1
- package/src/themes/HeroBanner.css +93 -76
- package/src/themes/Modal.css +3 -2
- package/src/themes/SecondaryNavigationItem.css +4 -1
- package/src/themes/TabNavigation.css +27 -16
- package/dist/assets/messagebundle_en-DWAgV5VH.js +0 -1
- package/dist/generated/templates/HeroBannerTemplate.lit.d.ts +0 -3
- package/dist/generated/templates/HeroBannerTemplate.lit.js +0 -15
- package/dist/generated/templates/HeroBannerTemplate.lit.js.map +0 -1
- package/src/HeroBanner.hbs +0 -46
- package/src/generated/templates/HeroBannerTemplate.lit.ts +0 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import UDExTabNavigation from "../../src/TabNavigation.js";
|
|
1
|
+
import UDExTabNavigation, { UDExTabNavigationOrientation, UDExTabNavigationPlacement, UDExTabNavigationVerticalAlignment } from "../../src/TabNavigation.js";
|
|
2
2
|
import UDExTab from "../../src/Tab.js";
|
|
3
3
|
|
|
4
4
|
// Test fixtures
|
|
@@ -725,9 +725,7 @@ describe("Tab Navigation component", () => {
|
|
|
725
725
|
.should("not.exist");
|
|
726
726
|
});
|
|
727
727
|
|
|
728
|
-
it("does NOT show
|
|
729
|
-
// Note: The Tab component uses a `link` slot for adding links
|
|
730
|
-
// In horizontal mode, even with bodyText, the wrapper and links should not be shown
|
|
728
|
+
it("does NOT show tab wrapper in header for horizontal tabs", () => {
|
|
731
729
|
cy.mount(
|
|
732
730
|
<UDExTabNavigation orientation="Horizontal">
|
|
733
731
|
<UDExTab text="Settings" bodyText="Configure your preferences" selected>
|
|
@@ -739,12 +737,6 @@ describe("Tab Navigation component", () => {
|
|
|
739
737
|
</UDExTabNavigation>
|
|
740
738
|
);
|
|
741
739
|
|
|
742
|
-
// Link container should NOT be visible in the header for horizontal tabs
|
|
743
|
-
cy.get("[udex-tab-navigation]")
|
|
744
|
-
.shadow()
|
|
745
|
-
.find(".udex-tab-navigation__button-links")
|
|
746
|
-
.should("not.exist");
|
|
747
|
-
|
|
748
740
|
// Wrapper should NOT be used for horizontal tabs
|
|
749
741
|
cy.get("[udex-tab-navigation]")
|
|
750
742
|
.shadow()
|
|
@@ -804,35 +796,6 @@ describe("Tab Navigation component", () => {
|
|
|
804
796
|
.should("have.length", 2);
|
|
805
797
|
});
|
|
806
798
|
|
|
807
|
-
it("shows link slot in header for vertical tabs with link elements", () => {
|
|
808
|
-
// The Tab component uses a `link` slot for adding links in vertical mode
|
|
809
|
-
// When link slot elements are provided, they should be rendered in the tab header
|
|
810
|
-
cy.mount(
|
|
811
|
-
<UDExTabNavigation orientation="Vertical">
|
|
812
|
-
<UDExTab text="Settings" selected>
|
|
813
|
-
<a slot="link" href="https://example.com">Learn more</a>
|
|
814
|
-
<div>Settings content</div>
|
|
815
|
-
</UDExTab>
|
|
816
|
-
<UDExTab text="Account">
|
|
817
|
-
<a slot="link" href="https://example.com">View details</a>
|
|
818
|
-
<div>Account content</div>
|
|
819
|
-
</UDExTab>
|
|
820
|
-
</UDExTabNavigation>
|
|
821
|
-
);
|
|
822
|
-
|
|
823
|
-
// Wrapper should be used for vertical tabs with link slot
|
|
824
|
-
cy.get("[udex-tab-navigation]")
|
|
825
|
-
.shadow()
|
|
826
|
-
.find(".udex-tab-navigation__tab-wrapper")
|
|
827
|
-
.should("have.length", 2);
|
|
828
|
-
|
|
829
|
-
// Link container should exist for tabs with link slot
|
|
830
|
-
cy.get("[udex-tab-navigation]")
|
|
831
|
-
.shadow()
|
|
832
|
-
.find(".udex-tab-navigation__button-links")
|
|
833
|
-
.should("have.length", 2);
|
|
834
|
-
});
|
|
835
|
-
|
|
836
799
|
it("displays body text content correctly for each vertical tab", () => {
|
|
837
800
|
cy.mount(
|
|
838
801
|
<UDExTabNavigation orientation="Vertical">
|
|
@@ -898,6 +861,605 @@ describe("Tab Navigation component", () => {
|
|
|
898
861
|
});
|
|
899
862
|
});
|
|
900
863
|
|
|
864
|
+
describe("TabNavigation - Vertical Placement", () => {
|
|
865
|
+
const verticalTabItems = (
|
|
866
|
+
<>
|
|
867
|
+
<UDExTab text="Settings" selected><div>Settings content</div></UDExTab>
|
|
868
|
+
<UDExTab text="Account"><div>Account content</div></UDExTab>
|
|
869
|
+
</>
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
it("renders header before content by default (Start placement)", () => {
|
|
873
|
+
cy.mount(
|
|
874
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
875
|
+
{verticalTabItems}
|
|
876
|
+
</UDExTabNavigation>
|
|
877
|
+
);
|
|
878
|
+
|
|
879
|
+
cy.get("[udex-tab-navigation]").shadow().then($shadow => {
|
|
880
|
+
const header = $shadow[0].querySelector(".udex-tab-navigation__header") as HTMLElement;
|
|
881
|
+
const content = $shadow[0].querySelector(".udex-tab-navigation__content") as HTMLElement;
|
|
882
|
+
expect(header.getBoundingClientRect().left).to.be.lessThan(content.getBoundingClientRect().left);
|
|
883
|
+
});
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
it("renders header after content for End placement", () => {
|
|
887
|
+
cy.mount(
|
|
888
|
+
<UDExTabNavigation
|
|
889
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
890
|
+
placement={UDExTabNavigationPlacement.End}
|
|
891
|
+
>
|
|
892
|
+
{verticalTabItems}
|
|
893
|
+
</UDExTabNavigation>
|
|
894
|
+
);
|
|
895
|
+
|
|
896
|
+
cy.get("[udex-tab-navigation]").shadow().then($shadow => {
|
|
897
|
+
const header = $shadow[0].querySelector(".udex-tab-navigation__header") as HTMLElement;
|
|
898
|
+
const content = $shadow[0].querySelector(".udex-tab-navigation__content") as HTMLElement;
|
|
899
|
+
expect(header.getBoundingClientRect().left).to.be.greaterThan(content.getBoundingClientRect().left);
|
|
900
|
+
});
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
it("sets placement attribute on the host element", () => {
|
|
904
|
+
cy.mount(
|
|
905
|
+
<UDExTabNavigation
|
|
906
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
907
|
+
placement={UDExTabNavigationPlacement.End}
|
|
908
|
+
>
|
|
909
|
+
{verticalTabItems}
|
|
910
|
+
</UDExTabNavigation>
|
|
911
|
+
);
|
|
912
|
+
|
|
913
|
+
cy.get("[udex-tab-navigation]").should("have.attr", "placement", "End");
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
it("does not apply End placement in Horizontal orientation", () => {
|
|
917
|
+
cy.mount(
|
|
918
|
+
<UDExTabNavigation
|
|
919
|
+
orientation={UDExTabNavigationOrientation.Horizontal}
|
|
920
|
+
placement={UDExTabNavigationPlacement.End}
|
|
921
|
+
>
|
|
922
|
+
{verticalTabItems}
|
|
923
|
+
</UDExTabNavigation>
|
|
924
|
+
);
|
|
925
|
+
|
|
926
|
+
cy.get("[udex-tab-navigation]").shadow().then($shadow => {
|
|
927
|
+
const header = $shadow[0].querySelector(".udex-tab-navigation__header") as HTMLElement;
|
|
928
|
+
expect(getComputedStyle(header).order).to.equal("0");
|
|
929
|
+
});
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
it("tab switching works correctly with End placement", () => {
|
|
933
|
+
cy.mount(
|
|
934
|
+
<UDExTabNavigation
|
|
935
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
936
|
+
placement={UDExTabNavigationPlacement.End}
|
|
937
|
+
>
|
|
938
|
+
{verticalTabItems}
|
|
939
|
+
</UDExTabNavigation>
|
|
940
|
+
);
|
|
941
|
+
|
|
942
|
+
cy.get("[udex-tab-navigation]")
|
|
943
|
+
.shadow()
|
|
944
|
+
.find("button[role='tab']")
|
|
945
|
+
.contains("Account")
|
|
946
|
+
.click();
|
|
947
|
+
|
|
948
|
+
cy.get("[udex-tab-navigation]")
|
|
949
|
+
.shadow()
|
|
950
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
951
|
+
.should("contain.text", "Account");
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
describe("TabNavigation - Footer slot", () => {
|
|
956
|
+
it("renders footer slot content below the tablist in Vertical orientation", () => {
|
|
957
|
+
cy.mount(
|
|
958
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
959
|
+
<UDExTab text="Settings" selected><div>Settings content</div></UDExTab>
|
|
960
|
+
<UDExTab text="Account"><div>Account content</div></UDExTab>
|
|
961
|
+
<button slot="footer">Overview</button>
|
|
962
|
+
</UDExTabNavigation>
|
|
963
|
+
);
|
|
964
|
+
|
|
965
|
+
cy.get("[udex-tab-navigation]")
|
|
966
|
+
.shadow()
|
|
967
|
+
.find(".udex-tab-navigation__footer")
|
|
968
|
+
.should("exist");
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
it("does not render footer container when no footer slot content is provided", () => {
|
|
972
|
+
cy.mount(
|
|
973
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
974
|
+
<UDExTab text="Settings" selected><div>Settings content</div></UDExTab>
|
|
975
|
+
<UDExTab text="Account"><div>Account content</div></UDExTab>
|
|
976
|
+
</UDExTabNavigation>
|
|
977
|
+
);
|
|
978
|
+
|
|
979
|
+
cy.get("[udex-tab-navigation]")
|
|
980
|
+
.shadow()
|
|
981
|
+
.find(".udex-tab-navigation__footer")
|
|
982
|
+
.should("not.exist");
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
it("footer is below the tablist in the DOM order", () => {
|
|
986
|
+
cy.mount(
|
|
987
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
988
|
+
<UDExTab text="Settings" selected><div>Settings content</div></UDExTab>
|
|
989
|
+
<UDExTab text="Account"><div>Account content</div></UDExTab>
|
|
990
|
+
<button slot="footer">Overview</button>
|
|
991
|
+
</UDExTabNavigation>
|
|
992
|
+
);
|
|
993
|
+
|
|
994
|
+
cy.get("[udex-tab-navigation]").shadow().then($shadow => {
|
|
995
|
+
const tablist = $shadow[0].querySelector(".udex-tab-navigation__header-tabs") as HTMLElement;
|
|
996
|
+
const footer = $shadow[0].querySelector(".udex-tab-navigation__footer") as HTMLElement;
|
|
997
|
+
expect(tablist.getBoundingClientRect().bottom).to.be.lessThan(footer.getBoundingClientRect().top);
|
|
998
|
+
});
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
it("does not render footer slot for Horizontal orientation", () => {
|
|
1002
|
+
cy.mount(
|
|
1003
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Horizontal}>
|
|
1004
|
+
<UDExTab text="Settings" selected><div>Settings content</div></UDExTab>
|
|
1005
|
+
<UDExTab text="Account"><div>Account content</div></UDExTab>
|
|
1006
|
+
<button slot="footer">Overview</button>
|
|
1007
|
+
</UDExTabNavigation>
|
|
1008
|
+
);
|
|
1009
|
+
|
|
1010
|
+
cy.get("[udex-tab-navigation]")
|
|
1011
|
+
.shadow()
|
|
1012
|
+
.find(".udex-tab-navigation__footer")
|
|
1013
|
+
.should("not.exist");
|
|
1014
|
+
});
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
describe("TabNavigation - Link slot", () => {
|
|
1018
|
+
it("renders the links container inside the tab wrapper when link slot elements are provided in Vertical orientation", () => {
|
|
1019
|
+
cy.mount(
|
|
1020
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1021
|
+
<UDExTab text="Account" body-text="Privacy settings" selected>
|
|
1022
|
+
<udex-link slot="link" href="https://sap.com/" design="Default">Privacy Policy</udex-link>
|
|
1023
|
+
<div>Account content</div>
|
|
1024
|
+
</UDExTab>
|
|
1025
|
+
<UDExTab text="Settings">
|
|
1026
|
+
<div>Settings content</div>
|
|
1027
|
+
</UDExTab>
|
|
1028
|
+
</UDExTabNavigation>
|
|
1029
|
+
);
|
|
1030
|
+
|
|
1031
|
+
cy.get("[udex-tab-navigation]")
|
|
1032
|
+
.shadow()
|
|
1033
|
+
.find(".udex-tab-navigation__button-links")
|
|
1034
|
+
.should("exist");
|
|
1035
|
+
});
|
|
1036
|
+
|
|
1037
|
+
it("renders all slotted link elements inside the links container", () => {
|
|
1038
|
+
cy.mount(
|
|
1039
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1040
|
+
<UDExTab text="Account" selected>
|
|
1041
|
+
<udex-link slot="link" href="https://sap.com/privacy" design="Default">Privacy Policy</udex-link>
|
|
1042
|
+
<udex-link slot="link" href="https://sap.com/terms" design="Default">Terms of Service</udex-link>
|
|
1043
|
+
<div>Account content</div>
|
|
1044
|
+
</UDExTab>
|
|
1045
|
+
<UDExTab text="Settings">
|
|
1046
|
+
<div>Settings content</div>
|
|
1047
|
+
</UDExTab>
|
|
1048
|
+
</UDExTabNavigation>
|
|
1049
|
+
);
|
|
1050
|
+
|
|
1051
|
+
cy.get("[udex-tab-navigation]")
|
|
1052
|
+
.shadow()
|
|
1053
|
+
.find(".udex-tab-navigation__button-links udex-link")
|
|
1054
|
+
.should("have.length", 2);
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
it("links container is hidden on a non-selected tab and visible on the selected tab", () => {
|
|
1058
|
+
cy.mount(
|
|
1059
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1060
|
+
<UDExTab text="Account" selected>
|
|
1061
|
+
<udex-link slot="link" href="https://sap.com/" design="Default">Privacy Policy</udex-link>
|
|
1062
|
+
<div>Account content</div>
|
|
1063
|
+
</UDExTab>
|
|
1064
|
+
<UDExTab text="Settings">
|
|
1065
|
+
<udex-link slot="link" href="https://sap.com/" design="Default">Terms of Service</udex-link>
|
|
1066
|
+
<div>Settings content</div>
|
|
1067
|
+
</UDExTab>
|
|
1068
|
+
</UDExTabNavigation>
|
|
1069
|
+
);
|
|
1070
|
+
|
|
1071
|
+
// Selected tab's links container must be visible (display: flex via CSS sibling rule)
|
|
1072
|
+
cy.get("[udex-tab-navigation]")
|
|
1073
|
+
.shadow()
|
|
1074
|
+
.find(".udex-tab-navigation__button-tab--active ~ .udex-tab-navigation__button-links")
|
|
1075
|
+
.should("have.css", "display", "flex");
|
|
1076
|
+
|
|
1077
|
+
// Non-selected tab's links container must be hidden (display: none)
|
|
1078
|
+
cy.get("[udex-tab-navigation]")
|
|
1079
|
+
.shadow()
|
|
1080
|
+
.find(".udex-tab-navigation__tab-wrapper")
|
|
1081
|
+
.not(":has(.udex-tab-navigation__button-tab--active)")
|
|
1082
|
+
.find(".udex-tab-navigation__button-links")
|
|
1083
|
+
.should("have.css", "display", "none");
|
|
1084
|
+
});
|
|
1085
|
+
|
|
1086
|
+
it("links container becomes visible after switching to a tab that has link slot elements", () => {
|
|
1087
|
+
cy.mount(
|
|
1088
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1089
|
+
<UDExTab text="Account" selected>
|
|
1090
|
+
<div>Account content</div>
|
|
1091
|
+
</UDExTab>
|
|
1092
|
+
<UDExTab text="Settings">
|
|
1093
|
+
<udex-link slot="link" href="https://sap.com/" design="Default">Privacy Policy</udex-link>
|
|
1094
|
+
<div>Settings content</div>
|
|
1095
|
+
</UDExTab>
|
|
1096
|
+
</UDExTabNavigation>
|
|
1097
|
+
);
|
|
1098
|
+
|
|
1099
|
+
cy.get("[udex-tab-navigation]")
|
|
1100
|
+
.shadow()
|
|
1101
|
+
.find("button[role='tab']")
|
|
1102
|
+
.contains("Settings")
|
|
1103
|
+
.click();
|
|
1104
|
+
|
|
1105
|
+
cy.get("[udex-tab-navigation]")
|
|
1106
|
+
.shadow()
|
|
1107
|
+
.find(".udex-tab-navigation__button-tab--active ~ .udex-tab-navigation__button-links")
|
|
1108
|
+
.should("have.css", "display", "flex");
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
it("does not render the links container in Horizontal orientation", () => {
|
|
1112
|
+
cy.mount(
|
|
1113
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Horizontal}>
|
|
1114
|
+
<UDExTab text="Account" selected>
|
|
1115
|
+
<udex-link slot="link" href="https://sap.com/" design="Default">Privacy Policy</udex-link>
|
|
1116
|
+
<div>Account content</div>
|
|
1117
|
+
</UDExTab>
|
|
1118
|
+
<UDExTab text="Settings">
|
|
1119
|
+
<div>Settings content</div>
|
|
1120
|
+
</UDExTab>
|
|
1121
|
+
</UDExTabNavigation>
|
|
1122
|
+
);
|
|
1123
|
+
|
|
1124
|
+
// hasBodyTextOrLink requires _isVertical=true, so the wrapper branch is never entered
|
|
1125
|
+
cy.get("[udex-tab-navigation]")
|
|
1126
|
+
.shadow()
|
|
1127
|
+
.find(".udex-tab-navigation__button-links")
|
|
1128
|
+
.should("not.exist");
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
it("does not render links container when the link slot is empty", () => {
|
|
1132
|
+
cy.mount(
|
|
1133
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1134
|
+
<UDExTab text="Account" selected>
|
|
1135
|
+
<div>Account content</div>
|
|
1136
|
+
</UDExTab>
|
|
1137
|
+
<UDExTab text="Settings">
|
|
1138
|
+
<div>Settings content</div>
|
|
1139
|
+
</UDExTab>
|
|
1140
|
+
</UDExTabNavigation>
|
|
1141
|
+
);
|
|
1142
|
+
|
|
1143
|
+
cy.get("[udex-tab-navigation]")
|
|
1144
|
+
.shadow()
|
|
1145
|
+
.find(".udex-tab-navigation__button-links")
|
|
1146
|
+
.should("not.exist");
|
|
1147
|
+
});
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
describe("TabNavigation - Auto-play", () => {
|
|
1151
|
+
const autoPlayTabs = (
|
|
1152
|
+
<>
|
|
1153
|
+
<UDExTab text="Tab 1" selected><div>Content 1</div></UDExTab>
|
|
1154
|
+
<UDExTab text="Tab 2"><div>Content 2</div></UDExTab>
|
|
1155
|
+
<UDExTab text="Tab 3"><div>Content 3</div></UDExTab>
|
|
1156
|
+
</>
|
|
1157
|
+
);
|
|
1158
|
+
|
|
1159
|
+
it("renders play button when autoPlay is enabled on Vertical orientation", () => {
|
|
1160
|
+
cy.mount(
|
|
1161
|
+
<UDExTabNavigation
|
|
1162
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1163
|
+
autoPlay
|
|
1164
|
+
autoPlayInterval={5000}
|
|
1165
|
+
>
|
|
1166
|
+
{autoPlayTabs}
|
|
1167
|
+
</UDExTabNavigation>
|
|
1168
|
+
);
|
|
1169
|
+
|
|
1170
|
+
cy.get("[udex-tab-navigation]")
|
|
1171
|
+
.shadow()
|
|
1172
|
+
.find(".udex-tab-navigation__play-button")
|
|
1173
|
+
.should("exist");
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
it("does not render play button for Horizontal orientation", () => {
|
|
1177
|
+
cy.mount(
|
|
1178
|
+
<UDExTabNavigation
|
|
1179
|
+
orientation={UDExTabNavigationOrientation.Horizontal}
|
|
1180
|
+
autoPlay
|
|
1181
|
+
>
|
|
1182
|
+
{autoPlayTabs}
|
|
1183
|
+
</UDExTabNavigation>
|
|
1184
|
+
);
|
|
1185
|
+
|
|
1186
|
+
cy.get("[udex-tab-navigation]")
|
|
1187
|
+
.shadow()
|
|
1188
|
+
.find(".udex-tab-navigation__play-button")
|
|
1189
|
+
.should("not.exist");
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
it("does not render play button when autoPlay is false", () => {
|
|
1193
|
+
cy.mount(
|
|
1194
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1195
|
+
{autoPlayTabs}
|
|
1196
|
+
</UDExTabNavigation>
|
|
1197
|
+
);
|
|
1198
|
+
|
|
1199
|
+
cy.get("[udex-tab-navigation]")
|
|
1200
|
+
.shadow()
|
|
1201
|
+
.find(".udex-tab-navigation__play-button")
|
|
1202
|
+
.should("not.exist");
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
it("advances to next tab after interval", () => {
|
|
1206
|
+
cy.clock(0, ["setInterval", "clearInterval"]);
|
|
1207
|
+
cy.mount(
|
|
1208
|
+
<UDExTabNavigation
|
|
1209
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1210
|
+
autoPlay
|
|
1211
|
+
autoPlayInterval={1000}
|
|
1212
|
+
>
|
|
1213
|
+
{autoPlayTabs}
|
|
1214
|
+
</UDExTabNavigation>
|
|
1215
|
+
);
|
|
1216
|
+
|
|
1217
|
+
cy.get("[udex-tab-navigation]")
|
|
1218
|
+
.shadow()
|
|
1219
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1220
|
+
.should("contain.text", "Tab 1");
|
|
1221
|
+
|
|
1222
|
+
cy.tick(1000);
|
|
1223
|
+
|
|
1224
|
+
cy.get("[udex-tab-navigation]")
|
|
1225
|
+
.shadow()
|
|
1226
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1227
|
+
.should("contain.text", "Tab 2");
|
|
1228
|
+
});
|
|
1229
|
+
|
|
1230
|
+
it("loops back to first tab after the last tab", () => {
|
|
1231
|
+
cy.clock(0, ["setInterval", "clearInterval"]);
|
|
1232
|
+
cy.mount(
|
|
1233
|
+
<UDExTabNavigation
|
|
1234
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1235
|
+
autoPlay
|
|
1236
|
+
autoPlayInterval={1000}
|
|
1237
|
+
>
|
|
1238
|
+
{autoPlayTabs}
|
|
1239
|
+
</UDExTabNavigation>
|
|
1240
|
+
);
|
|
1241
|
+
|
|
1242
|
+
cy.tick(3000);
|
|
1243
|
+
|
|
1244
|
+
cy.get("[udex-tab-navigation]")
|
|
1245
|
+
.shadow()
|
|
1246
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1247
|
+
.should("contain.text", "Tab 1");
|
|
1248
|
+
});
|
|
1249
|
+
|
|
1250
|
+
it("pauses auto-play when play button is clicked", () => {
|
|
1251
|
+
cy.clock(0, ["setInterval", "clearInterval"]);
|
|
1252
|
+
cy.mount(
|
|
1253
|
+
<UDExTabNavigation
|
|
1254
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1255
|
+
autoPlay
|
|
1256
|
+
autoPlayInterval={1000}
|
|
1257
|
+
>
|
|
1258
|
+
{autoPlayTabs}
|
|
1259
|
+
</UDExTabNavigation>
|
|
1260
|
+
);
|
|
1261
|
+
|
|
1262
|
+
cy.get("[udex-tab-navigation]")
|
|
1263
|
+
.shadow()
|
|
1264
|
+
.find(".udex-tab-navigation__play-button")
|
|
1265
|
+
.click();
|
|
1266
|
+
|
|
1267
|
+
cy.tick(2000);
|
|
1268
|
+
|
|
1269
|
+
cy.get("[udex-tab-navigation]")
|
|
1270
|
+
.shadow()
|
|
1271
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1272
|
+
.should("contain.text", "Tab 1");
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
it("resumes auto-play when play button is clicked again after pause", () => {
|
|
1276
|
+
cy.clock(0, ["setInterval", "clearInterval"]);
|
|
1277
|
+
cy.mount(
|
|
1278
|
+
<UDExTabNavigation
|
|
1279
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1280
|
+
autoPlay
|
|
1281
|
+
autoPlayInterval={1000}
|
|
1282
|
+
>
|
|
1283
|
+
{autoPlayTabs}
|
|
1284
|
+
</UDExTabNavigation>
|
|
1285
|
+
);
|
|
1286
|
+
|
|
1287
|
+
cy.get("[udex-tab-navigation]")
|
|
1288
|
+
.shadow()
|
|
1289
|
+
.find(".udex-tab-navigation__play-button")
|
|
1290
|
+
.click();
|
|
1291
|
+
|
|
1292
|
+
cy.get("[udex-tab-navigation]")
|
|
1293
|
+
.shadow()
|
|
1294
|
+
.find(".udex-tab-navigation__play-button")
|
|
1295
|
+
.click();
|
|
1296
|
+
|
|
1297
|
+
cy.tick(1000);
|
|
1298
|
+
|
|
1299
|
+
cy.get("[udex-tab-navigation]")
|
|
1300
|
+
.shadow()
|
|
1301
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1302
|
+
.should("contain.text", "Tab 2");
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
it("respects custom autoPlayInterval", () => {
|
|
1306
|
+
cy.clock(0, ["setInterval", "clearInterval"]);
|
|
1307
|
+
cy.mount(
|
|
1308
|
+
<UDExTabNavigation
|
|
1309
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1310
|
+
autoPlay
|
|
1311
|
+
autoPlayInterval={3000}
|
|
1312
|
+
>
|
|
1313
|
+
{autoPlayTabs}
|
|
1314
|
+
</UDExTabNavigation>
|
|
1315
|
+
);
|
|
1316
|
+
|
|
1317
|
+
cy.tick(2000);
|
|
1318
|
+
|
|
1319
|
+
cy.get("[udex-tab-navigation]")
|
|
1320
|
+
.shadow()
|
|
1321
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1322
|
+
.should("contain.text", "Tab 1");
|
|
1323
|
+
|
|
1324
|
+
cy.tick(1000);
|
|
1325
|
+
|
|
1326
|
+
cy.get("[udex-tab-navigation]")
|
|
1327
|
+
.shadow()
|
|
1328
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1329
|
+
.should("contain.text", "Tab 2");
|
|
1330
|
+
});
|
|
1331
|
+
|
|
1332
|
+
it("resets interval timer when tab is manually selected", () => {
|
|
1333
|
+
cy.clock(0, ["setInterval", "clearInterval"]);
|
|
1334
|
+
cy.mount(
|
|
1335
|
+
<UDExTabNavigation
|
|
1336
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1337
|
+
autoPlay
|
|
1338
|
+
autoPlayInterval={1000}
|
|
1339
|
+
>
|
|
1340
|
+
{autoPlayTabs}
|
|
1341
|
+
</UDExTabNavigation>
|
|
1342
|
+
);
|
|
1343
|
+
|
|
1344
|
+
cy.tick(800);
|
|
1345
|
+
|
|
1346
|
+
cy.get("[udex-tab-navigation]")
|
|
1347
|
+
.shadow()
|
|
1348
|
+
.find("button[role='tab']")
|
|
1349
|
+
.contains("Tab 3")
|
|
1350
|
+
.click();
|
|
1351
|
+
|
|
1352
|
+
cy.tick(800);
|
|
1353
|
+
|
|
1354
|
+
cy.get("[udex-tab-navigation]")
|
|
1355
|
+
.shadow()
|
|
1356
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1357
|
+
.should("contain.text", "Tab 3");
|
|
1358
|
+
|
|
1359
|
+
cy.tick(200);
|
|
1360
|
+
|
|
1361
|
+
cy.get("[udex-tab-navigation]")
|
|
1362
|
+
.shadow()
|
|
1363
|
+
.find("button[role='tab'][aria-selected='true']")
|
|
1364
|
+
.should("contain.text", "Tab 1");
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
it("shows pause icon when playing and play icon when paused", () => {
|
|
1368
|
+
cy.mount(
|
|
1369
|
+
<UDExTabNavigation
|
|
1370
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1371
|
+
autoPlay
|
|
1372
|
+
autoPlayInterval={5000}
|
|
1373
|
+
>
|
|
1374
|
+
{autoPlayTabs}
|
|
1375
|
+
</UDExTabNavigation>
|
|
1376
|
+
);
|
|
1377
|
+
|
|
1378
|
+
cy.get("[udex-tab-navigation]")
|
|
1379
|
+
.shadow()
|
|
1380
|
+
.find(".udex-tab-navigation__play-button")
|
|
1381
|
+
.should("have.attr", "icon", "pause");
|
|
1382
|
+
|
|
1383
|
+
cy.get("[udex-tab-navigation]")
|
|
1384
|
+
.shadow()
|
|
1385
|
+
.find(".udex-tab-navigation__play-button")
|
|
1386
|
+
.click();
|
|
1387
|
+
|
|
1388
|
+
cy.get("[udex-tab-navigation]")
|
|
1389
|
+
.shadow()
|
|
1390
|
+
.find(".udex-tab-navigation__play-button")
|
|
1391
|
+
.should("have.attr", "icon", "play");
|
|
1392
|
+
});
|
|
1393
|
+
});
|
|
1394
|
+
|
|
1395
|
+
describe("TabNavigation - Vertical Alignment", () => {
|
|
1396
|
+
const alignmentTabs = (
|
|
1397
|
+
<>
|
|
1398
|
+
<UDExTab text="Tab 1" selected><div style={{ height: "200px" }}>Tall content 1</div></UDExTab>
|
|
1399
|
+
<UDExTab text="Tab 2"><div style={{ height: "200px" }}>Tall content 2</div></UDExTab>
|
|
1400
|
+
</>
|
|
1401
|
+
);
|
|
1402
|
+
|
|
1403
|
+
it("defaults to Top alignment when verticalAlignment is not set", () => {
|
|
1404
|
+
cy.mount(
|
|
1405
|
+
<UDExTabNavigation orientation={UDExTabNavigationOrientation.Vertical}>
|
|
1406
|
+
{alignmentTabs}
|
|
1407
|
+
</UDExTabNavigation>
|
|
1408
|
+
);
|
|
1409
|
+
|
|
1410
|
+
cy.get("[udex-tab-navigation]").should("not.have.attr", "vertical-alignment", "Center");
|
|
1411
|
+
cy.get("[udex-tab-navigation]")
|
|
1412
|
+
.shadow()
|
|
1413
|
+
.find(".udex-tab-navigation__header")
|
|
1414
|
+
.should("have.css", "align-self", "flex-start");
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1417
|
+
it("applies center alignment when verticalAlignment is Center", () => {
|
|
1418
|
+
cy.mount(
|
|
1419
|
+
<UDExTabNavigation
|
|
1420
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1421
|
+
verticalAlignment={UDExTabNavigationVerticalAlignment.Center}
|
|
1422
|
+
>
|
|
1423
|
+
{alignmentTabs}
|
|
1424
|
+
</UDExTabNavigation>
|
|
1425
|
+
);
|
|
1426
|
+
|
|
1427
|
+
cy.get("[udex-tab-navigation]")
|
|
1428
|
+
.shadow()
|
|
1429
|
+
.find(".udex-tab-navigation__header")
|
|
1430
|
+
.should("have.css", "align-self", "center");
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
it("reflects vertical-alignment attribute on the host element", () => {
|
|
1434
|
+
cy.mount(
|
|
1435
|
+
<UDExTabNavigation
|
|
1436
|
+
orientation={UDExTabNavigationOrientation.Vertical}
|
|
1437
|
+
verticalAlignment={UDExTabNavigationVerticalAlignment.Center}
|
|
1438
|
+
>
|
|
1439
|
+
{alignmentTabs}
|
|
1440
|
+
</UDExTabNavigation>
|
|
1441
|
+
);
|
|
1442
|
+
|
|
1443
|
+
cy.get("[udex-tab-navigation]").should("have.attr", "vertical-alignment", "Center");
|
|
1444
|
+
});
|
|
1445
|
+
|
|
1446
|
+
it("does not apply vertical-alignment styles in Horizontal orientation", () => {
|
|
1447
|
+
cy.mount(
|
|
1448
|
+
<UDExTabNavigation
|
|
1449
|
+
orientation={UDExTabNavigationOrientation.Horizontal}
|
|
1450
|
+
verticalAlignment={UDExTabNavigationVerticalAlignment.Center}
|
|
1451
|
+
>
|
|
1452
|
+
{alignmentTabs}
|
|
1453
|
+
</UDExTabNavigation>
|
|
1454
|
+
);
|
|
1455
|
+
|
|
1456
|
+
cy.get("[udex-tab-navigation]")
|
|
1457
|
+
.shadow()
|
|
1458
|
+
.find(".udex-tab-navigation__header")
|
|
1459
|
+
.should("not.have.css", "align-self", "center");
|
|
1460
|
+
});
|
|
1461
|
+
});
|
|
1462
|
+
|
|
901
1463
|
describe("TabNavigation - Additional Features", () => {
|
|
902
1464
|
it("applies tabWidth property to vertical tabs", () => {
|
|
903
1465
|
cy.mount(
|
|
@@ -990,6 +1552,8 @@ describe("Tab Navigation component", () => {
|
|
|
990
1552
|
});
|
|
991
1553
|
|
|
992
1554
|
it("handles tab selection in vertical mode with many tabs", () => {
|
|
1555
|
+
cy.viewport(1280, 1200);
|
|
1556
|
+
|
|
993
1557
|
const manyTabs = Array.from({ length: 10 }, (_, i) => (
|
|
994
1558
|
<UDExTab text={`Tab ${i + 1}`} selected={i === 0}>
|
|
995
1559
|
<div>Content {i + 1}</div>
|