mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 09:59:03 +08:00
## Problem Now that `docs` is the only place where we use the deprecated `ui/Tabs`, we can move this component and the related HOC from `ui-patterns` in `docs` ## Solution - Move `ui/Tabs`, `ui-patterns/ComplexTabs/withQueryParams` and `ui-patterns/ComplexTabs/withSticky` to `docs` - Refactor `ui-patterns/ComplexTabs/withQueryParams` and `ui-patterns/ComplexTabs/withSticky` HOCs as hooks to make them easier to understand - Refactor `Tabs` accordingly No visual nor functional changes. ## How to test On https://docs-git-chore-refactor-docs-tabs-supabase.vercel.app/docs/guides/auth/passwords (Tabs are driven by URL and the flow tabs should have sticky headers even though there's a CSS bug already reported) - check that by default, the first tab in each tabs is active - change the tabs in different groups and validate it works - refresh the page and check that previously selected tabs are active (URL based selection) - In a new tab, visit https://docs-git-chore-refactor-docs-tabs-supabase.vercel.app/docs/guides/auth/passwords again and check that previously selected tabs are active (LocalStorage based selection) Do the same on https://docs-git-chore-refactor-docs-tabs-supabase.vercel.app/docs/guides/database/database-advisors (This one is driven by URL but does not have sticky tab headers) Do the same on https://docs-git-chore-refactor-docs-tabs-supabase.vercel.app/docs/guides/deployment/terraform/reference (this one is not driven by URL nor has sticky tab headers) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Docs tabs now persist and restore the active tab via URL query parameters. * Added optional “sticky” tab behavior that keeps the active panel in view. * Enhanced keyboard interaction for selecting tabs. * **Bug Fixes** * Improved active-tab initialization and synchronization when the URL query changes. * **Chores** * Refreshed the tabs UI implementation and styling to improve consistency and remove deprecated tab exports from shared UI packages. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useMemo, type FC } from 'react'
|
|
|
|
import { useSticky } from './useStickyTabs.utils'
|
|
|
|
export type UseStickyTabsOptions = { scrollMarginTop?: string; style?: CSSStyleDeclaration }
|
|
|
|
export const useStickyTabs = (options?: UseStickyTabsOptions) => {
|
|
const enabled = !!options
|
|
const { scrollMarginTop, style } = options || {}
|
|
const { inView, observedRef, stickyRef } = useSticky<HTMLDivElement>({
|
|
enabled,
|
|
style,
|
|
})
|
|
|
|
const onTabSelected = useCallback(() => {
|
|
if (enabled && inView && stickyRef.current) {
|
|
let elem = stickyRef.current as Element | null
|
|
while (elem && !elem.matches('[role="tabpanel"][data-state="active"]')) {
|
|
elem = elem.nextElementSibling
|
|
}
|
|
if (!elem) return
|
|
|
|
const top = elem.getBoundingClientRect().top
|
|
;(elem as HTMLElement).style.scrollMarginTop = scrollMarginTop || '0px'
|
|
if (top < 0) {
|
|
elem.scrollIntoView({
|
|
behavior: window.matchMedia('(prefers-reduced-motion: no-preference)').matches
|
|
? 'smooth'
|
|
: 'instant',
|
|
})
|
|
}
|
|
}
|
|
}, [enabled, inView, scrollMarginTop, stickyRef])
|
|
|
|
return useMemo(
|
|
() => ({
|
|
observedRef,
|
|
stickyRef,
|
|
onTabSelected,
|
|
}),
|
|
[observedRef, stickyRef, onTabSelected]
|
|
)
|
|
}
|