Skip to content

Commit

Permalink
improve SSR for Tabs in Vue
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Dec 5, 2022
1 parent ef3e154 commit 76d68ea
Showing 1 changed file with 46 additions and 2 deletions.
48 changes: 46 additions & 2 deletions packages/@headlessui-vue/src/components/tabs/tabs.ts
Expand Up @@ -58,6 +58,10 @@ function useTabsContext(component: string) {
return context
}

let TabsSSRContext = Symbol('TabsSSRContext') as InjectionKey<
Ref<{ tabs: string[]; panels: string[] } | null>
>

// ---

export let TabGroup = defineComponent({
Expand Down Expand Up @@ -116,6 +120,16 @@ export let TabGroup = defineComponent({

provide(TabsContext, api)

let SSRCounter = ref({ tabs: [], panels: [] })
let mounted = ref(false)
onMounted(() => {
mounted.value = true
})
provide(
TabsSSRContext,
computed(() => (mounted.value ? SSRCounter.value : null))
)

watchEffect(() => {
if (api.tabs.value.length <= 0) return
if (props.selectedIndex === null && selectedIndex.value !== null) return
Expand Down Expand Up @@ -231,7 +245,22 @@ export let Tab = defineComponent({
onMounted(() => api.registerTab(internalTabRef))
onUnmounted(() => api.unregisterTab(internalTabRef))

let myIndex = computed(() => api.tabs.value.indexOf(internalTabRef))
let SSRContext = inject(TabsSSRContext)!
let mySSRIndex = computed(() => {
if (SSRContext.value) {
let mySSRIndex = SSRContext.value.tabs.indexOf(props.id)
if (mySSRIndex === -1) return SSRContext.value.tabs.push(props.id) - 1
return mySSRIndex
}

return -1
})

let myIndex = computed(() => {
let myIndex = api.tabs.value.indexOf(internalTabRef)
if (myIndex === -1) return mySSRIndex.value
return myIndex
})
let selected = computed(() => myIndex.value === api.selectedIndex.value)

function activateUsing(cb: () => FocusResult) {
Expand Down Expand Up @@ -391,7 +420,22 @@ export let TabPanel = defineComponent({
onMounted(() => api.registerPanel(internalPanelRef))
onUnmounted(() => api.unregisterPanel(internalPanelRef))

let myIndex = computed(() => api.panels.value.indexOf(internalPanelRef))
let SSRContext = inject(TabsSSRContext)!
let mySSRIndex = computed(() => {
if (SSRContext.value) {
let mySSRIndex = SSRContext.value.panels.indexOf(props.id)
if (mySSRIndex === -1) return SSRContext.value.panels.push(props.id) - 1
return mySSRIndex
}

return -1
})

let myIndex = computed(() => {
let myIndex = api.panels.value.indexOf(internalPanelRef)
if (myIndex === -1) return mySSRIndex.value
return myIndex
})
let selected = computed(() => myIndex.value === api.selectedIndex.value)

return () => {
Expand Down

0 comments on commit 76d68ea

Please sign in to comment.