Port "Ensure correct DOM node order when performing focus actions"
tailwindlabs/headlessui#1038 This test didn't actually fail for me but w/e.
This commit is contained in:
39
src/lib/components/tabs/tabs.test.ts
vendored
39
src/lib/components/tabs/tabs.test.ts
vendored
@@ -83,6 +83,45 @@ describe('Rendering', () => {
|
|||||||
assertTabs({ active: 0 })
|
assertTabs({ active: 0 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should guarantee the order of DOM nodes when performing actions', async () => {
|
||||||
|
render(svelte`
|
||||||
|
<script>
|
||||||
|
let hide = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={() => hide = !hide}>toggle</button>
|
||||||
|
<TabGroup>
|
||||||
|
<TabList>
|
||||||
|
<Tab>Tab 1</Tab>
|
||||||
|
{#if !hide}
|
||||||
|
<Tab>Tab 2</Tab>
|
||||||
|
{/if}
|
||||||
|
<Tab>Tab 3</Tab>
|
||||||
|
</TabList>
|
||||||
|
|
||||||
|
<TabPanels>
|
||||||
|
<TabPanel>Content 1</TabPanel>
|
||||||
|
{#if !hide}
|
||||||
|
<TabPanel>Content 2</TabPanel>
|
||||||
|
{/if}
|
||||||
|
<TabPanel>Content 3</TabPanel>
|
||||||
|
</TabPanels>
|
||||||
|
</TabGroup>
|
||||||
|
`)
|
||||||
|
|
||||||
|
await click(getByText('toggle')) // Remove Tab 2
|
||||||
|
await click(getByText('toggle')) // Re-add Tab 2
|
||||||
|
|
||||||
|
await press(Keys.Tab)
|
||||||
|
assertTabs({ active: 0 })
|
||||||
|
|
||||||
|
await press(Keys.ArrowRight)
|
||||||
|
assertTabs({ active: 1 })
|
||||||
|
|
||||||
|
await press(Keys.ArrowRight)
|
||||||
|
assertTabs({ active: 2 })
|
||||||
|
})
|
||||||
|
|
||||||
describe('`slot props`', () => {
|
describe('`slot props`', () => {
|
||||||
it('should expose the `selectedIndex` on the `TabGroup` component', async () => {
|
it('should expose the `selectedIndex` on the `TabGroup` component', async () => {
|
||||||
render(svelte`
|
render(svelte`
|
||||||
|
|||||||
@@ -1359,12 +1359,8 @@ export function assertTabs(
|
|||||||
expect(list).toHaveAttribute("role", "tablist");
|
expect(list).toHaveAttribute("role", "tablist");
|
||||||
expect(list).toHaveAttribute("aria-orientation", orientation);
|
expect(list).toHaveAttribute("aria-orientation", orientation);
|
||||||
|
|
||||||
let activeTab = tabs.find(
|
let activeTab = Array.from(list.querySelectorAll('[id^="headlessui-tabs-tab-"]'))[active]
|
||||||
(tab) => tab.dataset.headlessuiIndex === "" + active
|
let activePanel = panels.find(panel => panel.id === activeTab.getAttribute('aria-controls'))
|
||||||
);
|
|
||||||
let activePanel = panels.find(
|
|
||||||
(panel) => panel.dataset.headlessuiIndex === "" + active
|
|
||||||
);
|
|
||||||
|
|
||||||
for (let tab of tabs) {
|
for (let tab of tabs) {
|
||||||
expect(tab).toHaveAttribute("id");
|
expect(tab).toHaveAttribute("id");
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ let focusableSelector = [
|
|||||||
.map(
|
.map(
|
||||||
process.env.NODE_ENV === "test"
|
process.env.NODE_ENV === "test"
|
||||||
? // TODO: Remove this once JSDOM fixes the issue where an element that is
|
? // TODO: Remove this once JSDOM fixes the issue where an element that is
|
||||||
// "hidden" can be the document.activeElement, because this is not possible
|
// "hidden" can be the document.activeElement, because this is not possible
|
||||||
// in real browsers.
|
// in real browsers.
|
||||||
(selector) =>
|
(selector) =>
|
||||||
`${selector}:not([tabindex='-1']):not([style*='display: none'])`
|
`${selector}:not([tabindex='-1']):not([style*='display: none'])`
|
||||||
: (selector) => `${selector}:not([tabindex='-1'])`
|
: (selector) => `${selector}:not([tabindex='-1'])`
|
||||||
)
|
)
|
||||||
.join(",");
|
.join(",");
|
||||||
@@ -100,7 +100,13 @@ export function focusElement(element: HTMLElement | null) {
|
|||||||
|
|
||||||
export function focusIn(container: HTMLElement | HTMLElement[], focus: Focus) {
|
export function focusIn(container: HTMLElement | HTMLElement[], focus: Focus) {
|
||||||
let elements = Array.isArray(container)
|
let elements = Array.isArray(container)
|
||||||
? container
|
? container.slice().sort((a, b) => {
|
||||||
|
let position = a.compareDocumentPosition(b)
|
||||||
|
|
||||||
|
if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1
|
||||||
|
if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1
|
||||||
|
return 0
|
||||||
|
})
|
||||||
: getFocusableElements(container);
|
: getFocusableElements(container);
|
||||||
let active = document.activeElement as HTMLElement;
|
let active = document.activeElement as HTMLElement;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user