feat: add support for commenting and reacting on external content
This commit is contained in:
parent
5ba5c26fcd
commit
0bb62dd3fb
76 changed files with 1635 additions and 639 deletions
63
src/components/ExternalContentInteractions/Tabs.tsx
Normal file
63
src/components/ExternalContentInteractions/Tabs.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { cn } from '@/lib/utils'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useRef, useEffect, useState } from 'react'
|
||||
|
||||
export type TTabValue = 'replies' | 'reactions'
|
||||
const TABS = [
|
||||
{ value: 'replies', label: 'Replies' },
|
||||
{ value: 'reactions', label: 'Reactions' }
|
||||
] as { value: TTabValue; label: string }[]
|
||||
|
||||
export function Tabs({
|
||||
selectedTab,
|
||||
onTabChange
|
||||
}: {
|
||||
selectedTab: TTabValue
|
||||
onTabChange: (tab: TTabValue) => void
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const tabRefs = useRef<(HTMLDivElement | null)[]>([])
|
||||
const [indicatorStyle, setIndicatorStyle] = useState({ width: 0, left: 0 })
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
const activeIndex = TABS.findIndex((tab) => tab.value === selectedTab)
|
||||
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
|
||||
})
|
||||
}
|
||||
}, 20) // ensure tabs are rendered before calculating
|
||||
}, [selectedTab])
|
||||
|
||||
return (
|
||||
<div className="w-fit">
|
||||
<div className="flex relative">
|
||||
{TABS.map((tab, index) => (
|
||||
<div
|
||||
key={tab.value}
|
||||
ref={(el) => (tabRefs.current[index] = el)}
|
||||
className={cn(
|
||||
`text-center px-4 py-2 font-semibold clickable cursor-pointer rounded-lg`,
|
||||
selectedTab === tab.value ? '' : 'text-muted-foreground'
|
||||
)}
|
||||
onClick={() => onTabChange(tab.value)}
|
||||
>
|
||||
{t(tab.label)}
|
||||
</div>
|
||||
))}
|
||||
<div
|
||||
className="absolute bottom-0 h-1 bg-primary rounded-full transition-all duration-500"
|
||||
style={{
|
||||
width: `${indicatorStyle.width}px`,
|
||||
left: `${indicatorStyle.left}px`
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue