diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx
index a258dafa..71c369b8 100644
--- a/src/components/NoteList/index.tsx
+++ b/src/components/NoteList/index.tsx
@@ -18,7 +18,7 @@ import { useTranslation } from 'react-i18next'
import PullToRefresh from 'react-simple-pull-to-refresh'
import NoteCard, { NoteCardLoadingSkeleton } from '../NoteCard'
import { PictureNoteCardMasonry } from '../PictureNoteCardMasonry'
-import TabSwitcher from '../TabSwitch'
+import Tabs from '../Tabs'
const LIMIT = 100
const ALGO_LIMIT = 500
@@ -291,7 +291,7 @@ export default function NoteList({
return (
-
{
return (
-
void
-}
-
-export default function TabSwitcher({
- tabs,
- value,
- className,
- onTabChange,
- threshold = 800
-}: {
- tabs: TabDefinition[]
- value: string
- className?: string
- onTabChange?: (tab: string) => void
- threshold?: number
-}) {
- const { t } = useTranslation()
- const { deepBrowsing, lastScrollTop } = useDeepBrowsing()
- const activeIndex = tabs.findIndex((tab) => tab.value === value)
-
- return (
- threshold ? '-translate-y-[calc(100%+12rem)]' : '',
- className
- )}
- >
-
- {tabs.map((tab) => (
-
{
- tab.onClick?.()
- onTabChange?.(tab.value)
- }}
- >
- {t(tab.label)}
-
- ))}
-
-
-
= 0 ? activeIndex * (100 / tabs.length) : 0}%`
- }}
- >
-
-
-
-
- )
-}
diff --git a/src/components/Tabs/index.tsx b/src/components/Tabs/index.tsx
new file mode 100644
index 00000000..84b8c6fb
--- /dev/null
+++ b/src/components/Tabs/index.tsx
@@ -0,0 +1,76 @@
+import { cn } from '@/lib/utils'
+import { useDeepBrowsing } from '@/providers/DeepBrowsingProvider'
+import { useEffect, useRef, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+
+type TabDefinition = {
+ value: string
+ label: string
+}
+
+export default function Tabs({
+ tabs,
+ value,
+ onTabChange,
+ threshold = 800
+}: {
+ tabs: TabDefinition[]
+ value: string
+ onTabChange?: (tab: string) => void
+ threshold?: number
+}) {
+ const { t } = useTranslation()
+ const { deepBrowsing, lastScrollTop } = useDeepBrowsing()
+ const activeIndex = tabs.findIndex((tab) => tab.value === value)
+ const tabRefs = useRef<(HTMLDivElement | null)[]>([])
+ const [indicatorStyle, setIndicatorStyle] = useState({ width: 0, left: 0 })
+
+ useEffect(() => {
+ const handleResize = () => {
+ if (activeIndex >= 0 && tabRefs.current[activeIndex]) {
+ const activeTab = tabRefs.current[activeIndex]
+ const { offsetWidth, offsetLeft } = activeTab
+ const padding = 32 // 16px padding on each side
+ setIndicatorStyle({
+ width: offsetWidth - padding,
+ left: offsetLeft + padding / 2
+ })
+ }
+ }
+ window.addEventListener('resize', handleResize)
+ handleResize() // Initial call to set the indicator style
+ return () => {
+ window.removeEventListener('resize', handleResize)
+ }
+ }, [activeIndex])
+
+ return (
+ threshold ? '-translate-y-[calc(100%+12rem)]' : ''
+ )}
+ >
+ {tabs.map((tab, index) => (
+
(tabRefs.current[index] = el)}
+ className={cn(
+ `text-center w-full py-2 font-semibold clickable cursor-pointer rounded-lg`,
+ value === tab.value ? '' : 'text-muted-foreground'
+ )}
+ onClick={() => onTabChange?.(tab.value)}
+ >
+ {t(tab.label)}
+
+ ))}
+
+
+ )
+}
diff --git a/src/pages/primary/ExplorePage/index.tsx b/src/pages/primary/ExplorePage/index.tsx
index 530ebc6a..1d3616ad 100644
--- a/src/pages/primary/ExplorePage/index.tsx
+++ b/src/pages/primary/ExplorePage/index.tsx
@@ -1,6 +1,6 @@
import FollowingFavoriteRelayList from '@/components/FollowingFavoriteRelayList'
import RelayList from '@/components/RelayList'
-import TabSwitcher from '@/components/TabSwitch'
+import Tabs from '@/components/Tabs'
import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
import { Compass } from 'lucide-react'
import { forwardRef, useState } from 'react'
@@ -18,7 +18,7 @@ const ExplorePage = forwardRef((_, ref) => {
titlebar={}
displayScrollToTopButton
>
-