use-tab-searchparams.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import { usePathname, useSearchParams } from 'next/navigation'
  2. import { useState } from 'react'
  3. type UseTabSearchParamsOptions = {
  4. defaultTab: string
  5. routingBehavior?: 'push' | 'replace'
  6. searchParamName?: string
  7. disableSearchParams?: boolean
  8. }
  9. /**
  10. * Custom hook to manage tab state via URL search parameters in a Next.js application.
  11. * This hook allows for syncing the active tab with the browser's URL, enabling bookmarking and sharing of URLs with a specific tab activated.
  12. *
  13. * @param {UseTabSearchParamsOptions} options Configuration options for the hook:
  14. * - `defaultTab`: The tab to default to when no tab is specified in the URL.
  15. * - `routingBehavior`: Optional. Determines how changes to the active tab update the browser's history ('push' or 'replace'). Default is 'push'.
  16. * - `searchParamName`: Optional. The name of the search parameter that holds the tab state in the URL. Default is 'category'.
  17. * @returns A tuple where the first element is the active tab and the second element is a function to set the active tab.
  18. */
  19. export const useTabSearchParams = ({
  20. defaultTab,
  21. routingBehavior = 'push',
  22. searchParamName = 'category',
  23. disableSearchParams = false,
  24. }: UseTabSearchParamsOptions) => {
  25. const pathName = usePathname()
  26. const searchParams = useSearchParams()
  27. const [activeTab, setTab] = useState<string>(
  28. !disableSearchParams
  29. ? (searchParams.get(searchParamName) || defaultTab)
  30. : defaultTab,
  31. )
  32. const setActiveTab = (newActiveTab: string) => {
  33. setTab(newActiveTab)
  34. if (disableSearchParams)
  35. return
  36. history[`${routingBehavior}State`](null, '', `${pathName}?${searchParamName}=${newActiveTab}`)
  37. }
  38. return [activeTab, setActiveTab] as const
  39. }