Only render the FocusSentinel if required in the Tabs component (#1493)

* only render the `FocusSentinel` if required

Fixes: #1491

* update changelog
This commit is contained in:
Robin Malfait
2022-05-23 12:13:42 +02:00
committed by GitHub
parent e819c0a7b2
commit dafcc2d1c0
3 changed files with 30 additions and 23 deletions
+2
View File
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allow to override the `type` on the `ComboboxInput` ([#1476](https://github.com/tailwindlabs/headlessui/pull/1476))
- Ensure the the `<PopoverPanel focus>` closes correctly ([#1477](https://github.com/tailwindlabs/headlessui/pull/1477))
- Only render the `FocusSentinel` if required in the `Tabs` component ([#1493](https://github.com/tailwindlabs/headlessui/pull/1493))
### Added
@@ -22,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allow to override the `type` on the `Combobox.Input` ([#1476](https://github.com/tailwindlabs/headlessui/pull/1476))
- Ensure the the `<Popover.Panel focus>` closes correctly ([#1477](https://github.com/tailwindlabs/headlessui/pull/1477))
- Only render the `FocusSentinel` if required in the `Tabs` component ([#1493](https://github.com/tailwindlabs/headlessui/pull/1493))
### Added
@@ -144,6 +144,7 @@ function useData(component: string) {
}
return context
}
type _Data = ReturnType<typeof useData>
let TabsActionsContext = createContext<{
registerTab(tab: MutableRefObject<HTMLElement | null>): () => void
@@ -162,6 +163,7 @@ function useActions(component: string) {
}
return context
}
type _Actions = ReturnType<typeof useActions>
function stateReducer(state: StateDefinition, action: Actions) {
return match(action.type, reducers, state, action)
@@ -205,13 +207,13 @@ let Tabs = forwardRefWithAs(function Tabs<TTag extends ElementType = typeof DEFA
let onChangeRef = useLatestValue(onChange || (() => {}))
let stableTabsRef = useLatestValue(state.tabs)
let tabsData = useMemo<ContextType<typeof TabsDataContext>>(
let tabsData = useMemo<_Data>(
() => ({ orientation, activation, ...state }),
[orientation, activation, state]
)
let lastChangedIndex = useLatestValue(state.selectedIndex)
let tabsActions: ContextType<typeof TabsActionsContext> = useMemo(
let tabsActions: _Actions = useMemo(
() => ({
registerTab(tab) {
dispatch({ type: ActionTypes.RegisterTab, tab })
@@ -245,18 +247,20 @@ let Tabs = forwardRefWithAs(function Tabs<TTag extends ElementType = typeof DEFA
<TabsSSRContext.Provider value={SSRCounter}>
<TabsActionsContext.Provider value={tabsActions}>
<TabsDataContext.Provider value={tabsData}>
<FocusSentinel
onFocus={() => {
for (let tab of stableTabsRef.current) {
if (tab.current?.tabIndex === 0) {
tab.current?.focus()
return true
{tabsData.tabs.length <= 0 && (
<FocusSentinel
onFocus={() => {
for (let tab of stableTabsRef.current) {
if (tab.current?.tabIndex === 0) {
tab.current?.focus()
return true
}
}
}
return false
}}
/>
return false
}}
/>
)}
{render({
ourProps,
theirProps,
@@ -139,19 +139,20 @@ export let TabGroup = defineComponent({
let slot = { selectedIndex: selectedIndex.value }
return h(Fragment, [
h(FocusSentinel, {
onFocus: () => {
for (let tab of tabs.value) {
let el = dom(tab)
if (el?.tabIndex === 0) {
el.focus()
return true
tabs.value.length <= 0 &&
h(FocusSentinel, {
onFocus: () => {
for (let tab of tabs.value) {
let el = dom(tab)
if (el?.tabIndex === 0) {
el.focus()
return true
}
}
}
return false
},
}),
return false
},
}),
render({
props: {
...attrs,