-
-
Notifications
You must be signed in to change notification settings - Fork 148
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(tabs): prefer click for pointer interaction
- Loading branch information
1 parent
668ec62
commit bd7a2e4
Showing
9 changed files
with
234 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
"nuxt-ts", | ||
"preact-ts", | ||
"svelte-ts", | ||
"vanilla-ts", | ||
"website" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@zag-js/tabs": minor | ||
--- | ||
|
||
When using the pointer, prefer click based selection when using `activationMode=automatic` over focus triggering | ||
selection. For keyboard, selection follows focus as usual. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { expect, type Page } from "@playwright/test" | ||
import { a11y, testid } from "../_utils" | ||
import { Model } from "./model" | ||
|
||
export class TabsModel extends Model { | ||
constructor(public page: Page) { | ||
super(page) | ||
} | ||
|
||
checkAccessibility() { | ||
return a11y(this.page) | ||
} | ||
|
||
goto() { | ||
return this.page.goto("/tabs") | ||
} | ||
|
||
private getTabTrigger = (id: string) => { | ||
return this.page.locator(testid(`${id}-tab`)) | ||
} | ||
|
||
private getTabContent = (id: string) => { | ||
return this.page.locator(testid(`${id}-tab-panel`)) | ||
} | ||
|
||
clickTab = async (id: string) => { | ||
await this.getTabTrigger(id).click() | ||
} | ||
|
||
seeTabContent = async (id: string) => { | ||
await expect(this.getTabContent(id)).toBeVisible() | ||
} | ||
|
||
dontSeeTabContent = async (id: string) => { | ||
await expect(this.getTabContent(id)).not.toBeVisible() | ||
} | ||
|
||
setTabIsFocused = async (id: string) => { | ||
await expect(this.getTabTrigger(id)).toBeFocused() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,111 @@ | ||
import { expect, test } from "@playwright/test" | ||
import { a11y, testid } from "./_utils" | ||
import { test } from "@playwright/test" | ||
import { TabsModel } from "./models/tabs.model" | ||
|
||
const item = (id: string) => ({ | ||
tab: testid(`${id}-tab`), | ||
panel: testid(`${id}-tab-panel`), | ||
}) | ||
|
||
const nils = item("nils") | ||
const agnes = item("agnes") | ||
const joke = item("joke") | ||
let I: TabsModel | ||
|
||
test.describe("tabs", () => { | ||
test.beforeEach(async ({ page }) => { | ||
await page.goto("/tabs") | ||
I = new TabsModel(page) | ||
await I.goto() | ||
}) | ||
|
||
test("should have no accessibility violation", async () => { | ||
await I.checkAccessibility() | ||
}) | ||
|
||
test("should have no accessibility violation", async ({ page }) => { | ||
await a11y(page) | ||
test("on home key, select first tab", async () => { | ||
await I.clickTab("agnes") | ||
await I.pressKey("Home") | ||
|
||
await I.setTabIsFocused("nils") | ||
await I.seeTabContent("nils") | ||
}) | ||
|
||
test.describe("in automatic mode", () => { | ||
test("should select the correct tab on click", async ({ page }) => { | ||
await page.click(nils.tab) | ||
await expect(page.locator(nils.panel)).toBeVisible() | ||
test("on end key, select last tab", async () => { | ||
await I.clickTab("agnes") | ||
await I.pressKey("End") | ||
|
||
await I.setTabIsFocused("joke") | ||
await I.seeTabContent("joke") | ||
}) | ||
|
||
await page.click(agnes.tab) | ||
await expect(page.locator(agnes.panel)).toBeVisible() | ||
test("click tab, select tab", async () => { | ||
await I.clickTab("agnes") | ||
await I.seeTabContent("agnes") | ||
}) | ||
|
||
await page.click(joke.tab) | ||
await expect(page.locator(joke.panel)).toBeVisible() | ||
}) | ||
test("automatic: should select the correct tab on click", async () => { | ||
await I.clickTab("nils") | ||
await I.seeTabContent("nils") | ||
|
||
test("on `ArrowRight`: should select & focus the next tab", async ({ page }) => { | ||
await page.focus(nils.tab) | ||
await page.keyboard.press("ArrowRight") | ||
await I.clickTab("agnes") | ||
await I.seeTabContent("agnes") | ||
|
||
await expect(page.locator(agnes.tab)).toBeFocused() | ||
await expect(page.locator(agnes.panel)).toBeVisible() | ||
await I.clickTab("joke") | ||
await I.seeTabContent("joke") | ||
}) | ||
|
||
await page.keyboard.press("ArrowRight") | ||
await expect(page.locator(joke.tab)).toBeFocused() | ||
await expect(page.locator(joke.panel)).toBeVisible() | ||
test("automatic: on arrow right, select + focus next tab", async () => { | ||
await I.clickTab("nils") | ||
await I.pressKey("ArrowRight") | ||
|
||
await page.keyboard.press("ArrowRight") | ||
await expect(page.locator(nils.tab)).toBeFocused() | ||
await expect(page.locator(nils.panel)).toBeVisible() | ||
}) | ||
await I.setTabIsFocused("agnes") | ||
await I.seeTabContent("agnes") | ||
}) | ||
|
||
test("on `ArrowLeft`: should select & focus the previous tab", async ({ page }) => { | ||
await page.focus(nils.tab) | ||
await page.keyboard.press("ArrowLeft") | ||
test("automatic: on arrow right, loop focus + selection", async () => { | ||
await I.clickTab("nils") | ||
await I.pressKey("ArrowRight", 3) | ||
|
||
await expect(page.locator(joke.tab)).toBeFocused() | ||
await expect(page.locator(joke.panel)).toBeVisible() | ||
await I.setTabIsFocused("nils") | ||
await I.seeTabContent("nils") | ||
}) | ||
|
||
await page.keyboard.press("ArrowLeft") | ||
await expect(page.locator(agnes.tab)).toBeFocused() | ||
await expect(page.locator(agnes.panel)).toBeVisible() | ||
test("automatic: on arrow left, select + focus the previous tab", async () => { | ||
await I.clickTab("joke") | ||
await I.pressKey("ArrowLeft") | ||
|
||
await page.keyboard.press("ArrowLeft") | ||
await expect(page.locator(nils.tab)).toBeFocused() | ||
await expect(page.locator(nils.panel)).toBeVisible() | ||
}) | ||
await I.setTabIsFocused("agnes") | ||
await I.seeTabContent("agnes") | ||
}) | ||
|
||
test("on `Home` should select first tab", async ({ page }) => { | ||
await page.click(joke.tab) | ||
await page.keyboard.press("Home") | ||
test("manual: on arrow right, focus but not select tab", async () => { | ||
await I.controls.select("activationMode", "manual") | ||
|
||
await I.clickTab("nils") | ||
await I.pressKey("ArrowRight") | ||
|
||
await I.setTabIsFocused("agnes") | ||
await I.dontSeeTabContent("agnes") | ||
}) | ||
|
||
test("manual: on home key, focus but not select tab", async () => { | ||
await I.controls.select("activationMode", "manual") | ||
|
||
await I.clickTab("agnes") | ||
await I.pressKey("Home") | ||
|
||
await I.setTabIsFocused("nils") | ||
await I.dontSeeTabContent("nils") | ||
}) | ||
|
||
test("manual: on navigate, select on enter", async () => { | ||
await I.controls.select("activationMode", "manual") | ||
|
||
await I.clickTab("nils") | ||
await I.pressKey("ArrowRight") | ||
await I.pressKey("Enter") | ||
|
||
await I.setTabIsFocused("agnes") | ||
await I.seeTabContent("agnes") | ||
}) | ||
|
||
await expect(page.locator(nils.tab)).toBeFocused() | ||
await expect(page.locator(nils.panel)).toBeVisible() | ||
}) | ||
test("loopFocus=false", async () => { | ||
await I.controls.bool("loopFocus", false) | ||
|
||
test("on `End` should select last tab", async ({ page }) => { | ||
await page.focus(nils.tab) | ||
await page.keyboard.press("End") | ||
await I.clickTab("joke") | ||
await I.pressKey("ArrowRight") | ||
|
||
await expect(page.locator(joke.tab)).toBeFocused() | ||
await expect(page.locator(joke.panel)).toBeVisible() | ||
}) | ||
await I.setTabIsFocused("joke") | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"name": "vanilla", | ||
"name": "vanilla-ts", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
|
Oops, something went wrong.