Refactor & standardize modal tabs (#3864)

## Description:

Refactors tab handling out of the individual modal components and into
the base o-modal component. Tabs are now declared by passing tabs,
activeTab, and onTabChange props, and a new named header slot pins
consumer-supplied content above the tabs. This standardizes the modal
tab look.

<img width="1089" height="290" alt="Screenshot 2026-05-06 at 12 17
33 PM"
src="https://github.com/user-attachments/assets/08d5a039-0aef-4aa7-b972-1e43b8723685"
/>

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2026-05-06 12:47:11 -06:00
committed by GitHub
parent 94bab78d24
commit df84ee023e
8 changed files with 220 additions and 326 deletions
+9 -1
View File
@@ -101,6 +101,7 @@ beforeEach(() => {
);
});
import "../../src/client/components/baseComponents/Modal";
import { LeaderboardModal } from "../../src/client/LeaderboardModal";
describe("LeaderboardModal", () => {
@@ -334,7 +335,14 @@ describe("LeaderboardModal", () => {
}),
});
const tab = modal.querySelector("#clan-leaderboard-tab");
modal.inline = true;
await modal.updateComplete;
const oModal = modal.querySelector("o-modal");
await (oModal as unknown as { updateComplete: Promise<unknown> })
.updateComplete;
const tab = oModal!.shadowRoot!.querySelector(
'button[role="tab"][data-key="clans"]',
);
expect(tab).toBeTruthy();
tab!.dispatchEvent(new MouseEvent("click", { bubbles: true }));