Preserve default index when starting out with no tabs (#2250)

* Preserve default index when starting out with no tabs

* Add test to Vue

* Add test for Vue

it already works here so… yeah
This commit is contained in:
Jordan Pittman
2023-02-03 10:58:18 -05:00
committed by GitHub
parent 0276231c31
commit 0d28d588c1
3 changed files with 282 additions and 0 deletions
@@ -804,6 +804,145 @@ describe('Rendering', () => {
assertTabs({ active: 2 })
})
)
it(
'should select first tab if no tabs were provided originally',
suppressConsoleLogs(async () => {
function Example({ defaultIndex = undefined }: { defaultIndex?: number } = {}) {
let [tabs, setTabs] = useState<string[]>([])
return (
<>
<Tab.Group defaultIndex={defaultIndex}>
<Tab.List>
{tabs.map((tab, index) => (
<Tab key={index}>{tab}</Tab>
))}
</Tab.List>
<Tab.Panels>
{tabs.map((tab, index) => (
<Tab.Panel key={index}>content: {tab}</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
<button onClick={() => setTabs(['tab 1', 'tab 2', 'tab 3'])}>change</button>
</>
)
}
render(<Example defaultIndex={0} />)
assertActiveElement(document.body)
// There are no tab initially
assertTabs({ active: -1 })
// There are not tabs so this should not change anything
await press(Keys.Tab)
assertTabs({ active: -1 })
// Add some tabs
await click(getByText('change'))
// When going from no tabs to some tabs, the tab based on defaultIndex should be selected
assertTabs({ active: 0 })
})
)
it(
'should select first tab if no tabs were provided originally (with a defaultIndex of 1)',
suppressConsoleLogs(async () => {
function Example({ defaultIndex = undefined }: { defaultIndex?: number } = {}) {
let [tabs, setTabs] = useState<string[]>([])
return (
<>
<Tab.Group defaultIndex={defaultIndex}>
<Tab.List>
{tabs.map((tab, index) => (
<Tab key={index}>{tab}</Tab>
))}
</Tab.List>
<Tab.Panels>
{tabs.map((tab, index) => (
<Tab.Panel key={index}>content: {tab}</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
<button onClick={() => setTabs(['tab 1', 'tab 2', 'tab 3'])}>change</button>
</>
)
}
render(<Example defaultIndex={1} />)
assertActiveElement(document.body)
// There are no tab initially
assertTabs({ active: -1 })
// There are not tabs so this should not change anything
await press(Keys.Tab)
assertTabs({ active: -1 })
// Add some tabs
await click(getByText('change'))
// When going from no tabs to some tabs, the tab based on defaultIndex should be selected
assertTabs({ active: 1 })
})
)
it(
'should select first tab if no tabs were provided originally (with a defaultIndex of 1)',
suppressConsoleLogs(async () => {
function Example({ defaultIndex = undefined }: { defaultIndex?: number } = {}) {
let [tabs, setTabs] = useState<string[]>([])
return (
<>
<Tab.Group defaultIndex={defaultIndex}>
<Tab.List>
{tabs.map((tab, index) => (
<Tab key={index}>{tab}</Tab>
))}
</Tab.List>
<Tab.Panels>
{tabs.map((tab, index) => (
<Tab.Panel key={index}>content: {tab}</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
<button onClick={() => setTabs(['tab 1', 'tab 2', 'tab 3'])}>change 1</button>
<button onClick={() => setTabs([])}>change 2</button>
<button onClick={() => setTabs(['tab 1', 'tab 2', 'tab 3'])}>change 3</button>
</>
)
}
render(<Example defaultIndex={1} />)
assertActiveElement(document.body)
// There are no tab initially
assertTabs({ active: -1 })
// There are not tabs so this should not change anything
await press(Keys.Tab)
assertTabs({ active: -1 })
// Add some tabs
await click(getByText('change 1'))
await click(getByText('change 2'))
await click(getByText('change 3'))
// When going from no tabs to some tabs, the tab based on defaultIndex should be selected
assertTabs({ active: 1 })
})
)
})
describe('`selectedIndex`', () => {
@@ -99,6 +99,15 @@ let reducers: {
[Ordering.Greater]: () => Direction.Forwards,
})
// If there are no focusable tabs then.
// We won't change the selected index
// because it's likely the user is
// lazy loading tabs and there's
// nothing to focus on yet
if (focusableTabs.length === 0) {
return nextState
}
return {
...nextState,
selectedIndex: match(direction, {
@@ -721,6 +721,140 @@ describe('Rendering', () => {
// Nothing should change...
assertTabs({ active: 2 })
})
it(
'should select first tab if no tabs were provided originally',
suppressConsoleLogs(async () => {
renderTemplate({
template: html`
<TabGroup :defaultIndex="0">
<TabList>
<Tab v-for="tab in tabs">{{ tab }}</Tab>
</TabList>
<TabPanels>
<TabPanel v-for="tab in tabs">content for: {{ tab }}</TabPanel>
</TabPanels>
</TabGroup>
<button>after</button>
<button @click="tabs.value = ['tab 1', 'tab 2', 'tab 3']">change</button>
`,
setup() {
let tabs = ref<string[]>([])
return {
tabs,
}
},
})
assertActiveElement(document.body)
// There are no tab initially
assertTabs({ active: -1 })
// There are not tabs so this should not change anything
await press(Keys.Tab)
assertTabs({ active: -1 })
// Add some tabs
await click(getByText('change'))
// When going from no tabs to some tabs, the tab based on defaultIndex should be selected
assertTabs({ active: 0 })
})
)
it(
'should select first tab if no tabs were provided originally (with a defaultIndex of 1)',
suppressConsoleLogs(async () => {
renderTemplate({
template: html`
<TabGroup :defaultIndex="1">
<TabList>
<Tab v-for="tab in tabs">{{ tab }}</Tab>
</TabList>
<TabPanels>
<TabPanel v-for="tab in tabs">content for: {{ tab }}</TabPanel>
</TabPanels>
</TabGroup>
<button>after</button>
<button @click="tabs.value = ['tab 1', 'tab 2', 'tab 3']">change</button>
`,
setup() {
let tabs = ref<string[]>([])
return {
tabs,
}
},
})
assertActiveElement(document.body)
// There are no tab initially
assertTabs({ active: -1 })
// There are not tabs so this should not change anything
await press(Keys.Tab)
assertTabs({ active: -1 })
// Add some tabs
await click(getByText('change'))
// When going from no tabs to some tabs, the tab based on defaultIndex should be selected
assertTabs({ active: 1 })
})
)
it(
'should select first tab if no tabs were provided originally (with a defaultIndex of 1)',
suppressConsoleLogs(async () => {
renderTemplate({
template: html`
<TabGroup :defaultIndex="1">
<TabList>
<Tab v-for="tab in tabs">{{ tab }}</Tab>
</TabList>
<TabPanels>
<TabPanel v-for="tab in tabs">content for: {{ tab }}</TabPanel>
</TabPanels>
</TabGroup>
<button>after</button>
<button @click="tabs.value = ['tab 1', 'tab 2', 'tab 3']">change 1</button>
<button @click="tabs.value = []">change 2</button>
<button @click="tabs.value = ['tab 1', 'tab 2', 'tab 3']">change 3</button>
`,
setup() {
let tabs = ref<string[]>([])
return {
tabs,
}
},
})
assertActiveElement(document.body)
// There are no tab initially
assertTabs({ active: -1 })
// There are not tabs so this should not change anything
await press(Keys.Tab)
assertTabs({ active: -1 })
// Add some tabs
await click(getByText('change 1'))
// Add some tabs
await click(getByText('change 2'))
// Add some tabs
await click(getByText('change 3'))
// When going from no tabs to some tabs, the tab based on defaultIndex should be selected
assertTabs({ active: 1 })
})
)
})
})