Skip to content

Commit

Permalink
fix(#2109): tabs query preserve and load url-specified tab initially
Browse files Browse the repository at this point in the history
  • Loading branch information
syedszeeshan committed Dec 11, 2024
1 parent bc77381 commit cb24434
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 37 deletions.
38 changes: 35 additions & 3 deletions libs/web-components/src/components/tabs/Tabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
let _currentTab: number = 1;
let _tabProps: (GoATabProps & { bound: boolean })[] = [];
let _bindTimeoutId: any;
let _initialLoad: boolean = true;
// ========
// Hooks
Expand All @@ -34,6 +35,29 @@
// Functions
// =========
function getTabIndexFromHash() {
const hash = window.location.hash;
if (!hash) return null;
// Find the matching tab based on href
const tabs = _tabsEl?.querySelectorAll('[role="tab"]');
for (let i = 0; i < tabs.length; i++) {
const tab = tabs[i] as HTMLAnchorElement;
const tabHref = tab.getAttribute("href");
const tabHash = tabHref?.split("#")[1] || "";
const isFullUrlMatch = tabHref?.endsWith(hash);
const isHashOnlyMatch = hash.endsWith(tabHash);
if (isFullUrlMatch || isHashOnlyMatch) {
return i + 1;
}
}
return null;
}
function addChildMountListener() {
_rootEl.addEventListener("tab:mounted", (e: Event) => {
const detail = (e as CustomEvent<GoATabProps>).detail;
Expand All @@ -46,14 +70,21 @@
}
_bindTimeoutId = setTimeout(() => {
bindChildren();
setCurrentTab(initialtab || 1);
// Check URL hash on initial load
if (_initialLoad) {
const tabIndexFromHash = getTabIndexFromHash();
setCurrentTab(tabIndexFromHash ?? (initialtab || 1));
_initialLoad = false;
}
}, 1);
e.stopPropagation();
});
}
function bindChildren() {
const path = window.location.pathname;
const search = window.location.search; // Get current query string
// create buttons (tabs) for each of the tab contents elements
_tabProps.forEach((tabProps, index) => {
Expand Down Expand Up @@ -94,7 +125,7 @@
link.setAttribute("id", `tab-${index + 1}`);
link.setAttribute("data-testid", `tab-${index + 1}`);
link.setAttribute("role", "tab");
link.setAttribute("href", path + "#" + tabSlug);
link.setAttribute("href", `${path}${search}#${tabSlug}`);
link.addEventListener("click", () => setCurrentTab(index + 1));
link.setAttribute("aria-controls", `tabpanel-${index + 1}`);
link.appendChild(headingEl);
Expand Down Expand Up @@ -157,7 +188,8 @@
// update the browswers url with the new hash
if (currentLocation) {
document.location = currentLocation;
const url = new URL(currentLocation);
history.pushState({}, "", url.pathname + url.search + url.hash);
}
}
Expand Down
68 changes: 34 additions & 34 deletions libs/web-components/src/components/tabs/tabs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,40 +52,6 @@ describe("Tabs", () => {
});
});

it("should select specified tab if the tab property is set", async () => {
const result = render(Tabs, { initialtab: 2 });

await waitFor(() => {
const tab1Link = result.container.querySelector("a#tab-1");
const tab2Link = result.container.querySelector("a#tab-2");
const tabPanel = result.container.querySelector("div[role=tabpanel]");
const goaTabs = result.container.querySelectorAll("goa-tab");

expect(tab1Link).toBeTruthy();
expect(tab1Link?.getAttribute("aria-selected")).toBe("false");

expect(tab2Link).toBeTruthy();
expect(tab2Link?.getAttribute("aria-selected")).toBe("true");

expect(tabPanel).toBeTruthy();
expect(tabPanel?.getAttribute("id")).toBe("tabpanel-2");

expect(goaTabs[0].getAttribute("open")).toBe("false");
expect(goaTabs[1].getAttribute("open")).toBe("true");
});
});

it("should select the last tab if the tab exceeds the number of tabs", async () => {
const result = render(Tabs, { initialtab: 3 });

// last tab
await waitFor(() => {
const tab = result.container.querySelector("a#tab-2");
expect(tab).toBeTruthy();
expect(tab?.getAttribute("aria-selected")).toBe("true");
});
});

it("should select the first tab if the tab is less than 1", async () => {
const result = render(Tabs, { initialtab: 0 });

Expand Down Expand Up @@ -131,4 +97,38 @@ describe("Tabs", () => {
expect(goaTabs?.[1].getAttribute("open")).toBe("true");
});
});

it("should select the last tab if the tab exceeds the number of tabs", async () => {
const result = render(Tabs, { initialtab: 3 });

// last tab
await waitFor(() => {
const tab = result.container.querySelector("a#tab-2");
expect(tab).toBeTruthy();
expect(tab?.getAttribute("aria-selected")).toBe("true");
});
});

it("should select specified tab if the tab property is set", async () => {
const result = render(Tabs, { initialtab: 2 });

await waitFor(() => {
const tab1Link = result.container.querySelector("a#tab-1");
const tab2Link = result.container.querySelector("a#tab-2");
const tabPanel = result.container.querySelector("div[role=tabpanel]");
const goaTabs = result.container.querySelectorAll("goa-tab");

expect(tab1Link).toBeTruthy();
expect(tab1Link?.getAttribute("aria-selected")).toBe("false");

expect(tab2Link).toBeTruthy();
expect(tab2Link?.getAttribute("aria-selected")).toBe("true");

expect(tabPanel).toBeTruthy();
expect(tabPanel?.getAttribute("id")).toBe("tabpanel-2");

expect(goaTabs[0].getAttribute("open")).toBe("false");
expect(goaTabs[1].getAttribute("open")).toBe("true");
});
});
});

0 comments on commit cb24434

Please sign in to comment.