expo-popcore-app/hooks/use-tab-navigation.ts

91 lines
2.5 KiB
TypeScript

import { useState, useMemo, useCallback, useEffect } from 'react'
import { CategoryTemplate } from '@repo/sdk'
export interface Category {
id: string
name: string
templates?: CategoryTemplate[]
}
export interface UseTabNavigationOptions {
categories: Category[]
initialCategoryId?: string | null
}
export interface UseTabNavigationReturn {
activeIndex: number
selectedCategoryId: string | null
currentCategory: Category | undefined
tabs: string[]
selectTab: (index: number) => void
selectCategoryById: (categoryId: string) => void
}
export function useTabNavigation(options: UseTabNavigationOptions): UseTabNavigationReturn {
const { categories, initialCategoryId } = options
// State for active tab index
const [activeIndex, setActiveIndex] = useState<number>(() => {
if (initialCategoryId) {
const index = categories.findIndex(c => c.id === initialCategoryId)
return index >= 0 ? index : 0
}
return 0
})
// State for selected category ID
const [selectedCategoryId, setSelectedCategoryId] = useState<string | null>(() => {
if (initialCategoryId) {
const exists = categories.some(c => c.id === initialCategoryId)
if (exists) {
return initialCategoryId
}
}
return categories.length > 0 ? categories[0].id : null
})
// Auto-select first category when categories change and no selection
useEffect(() => {
if (categories.length > 0 && !selectedCategoryId) {
setSelectedCategoryId(categories[0].id)
setActiveIndex(0)
}
}, [categories, selectedCategoryId])
// Generate tabs array from category names
const tabs = useMemo(() => {
return categories.map(category => category.name)
}, [categories])
// Get current category based on selectedCategoryId
const currentCategory = useMemo(() => {
return categories.find(c => c.id === selectedCategoryId)
}, [categories, selectedCategoryId])
// Select tab by index
const selectTab = useCallback((index: number) => {
if (index >= 0 && index < categories.length) {
setActiveIndex(index)
setSelectedCategoryId(categories[index].id)
}
}, [categories])
// Select category by ID
const selectCategoryById = useCallback((categoryId: string) => {
const index = categories.findIndex(c => c.id === categoryId)
if (index >= 0) {
setActiveIndex(index)
setSelectedCategoryId(categoryId)
}
}, [categories])
return {
activeIndex,
selectedCategoryId,
currentCategory,
tabs,
selectTab,
selectCategoryById,
}
}