import { memo, useEffect, useRef, useState } from '../../lib/teact/teact'; import type { TabWithProperties } from './SquareTabList'; export type { TabWithProperties }; import buildClassName from '../../util/buildClassName'; import useHorizontalScroll from '../../hooks/useHorizontalScroll'; import useLastCallback from '../../hooks/useLastCallback'; import useResizeObserver from '../../hooks/useResizeObserver'; import CustomEmoji from '../common/CustomEmoji'; import Icon from '../common/icons/Icon'; import styles from './TabList.module.scss'; const EMOJI_SIZE = 20; type OwnProps = { tabs: readonly TabWithProperties[]; activeTab: number; className?: string; tabClassName?: string; indicatorClassName?: string; centered?: boolean; stretched?: boolean; itemAlignment?: 'vertical' | 'horizontal'; onSwitchTab: (index: number) => void; }; const TabList = ({ tabs, activeTab, className, tabClassName, indicatorClassName, centered, stretched, itemAlignment, onSwitchTab, }: OwnProps) => { const containerRef = useRef(); const clipPathContainerRef = useRef(); const [clipPath, setClipPath] = useState(''); useHorizontalScroll(containerRef, !tabs.length, true); const updateClipPath = useLastCallback(() => { const clipPathContainer = clipPathContainerRef.current; const activeTabEl = activeTab >= 0 && clipPathContainer?.childNodes[activeTab] as HTMLElement | undefined; if (clipPathContainer && activeTabEl && clipPathContainer.offsetWidth > 0) { const { offsetLeft, offsetWidth } = activeTabEl; const containerWidth = clipPathContainer.offsetWidth; const left = (offsetLeft / containerWidth * 100).toFixed(1); const right = ((containerWidth - (offsetLeft + offsetWidth)) / containerWidth * 100).toFixed(1); setClipPath(`inset(0.25rem ${right}% 0.25rem ${left}% round var(--tab-radius))`); } else if (activeTab < 0) { setClipPath('inset(0 100% 0 100%)'); } }); useEffect(() => { updateClipPath(); }, [activeTab, tabs]); useResizeObserver(clipPathContainerRef, updateClipPath); const handleTabClick = useLastCallback((index: number) => { onSwitchTab(index); }); if (!tabs.length) return undefined; const renderTab = (tab: TabWithProperties, index: number) => { const stringEmoticon = typeof tab.emoticon === 'string' ? tab.emoticon : undefined; const customEmoji = typeof tab.emoticon === 'object' ? tab.emoticon : undefined; return (
handleTabClick(index)} > {stringEmoticon && {stringEmoticon}} {customEmoji && ( )} {tab.icon && } {tab.title} {tab.isBlocked && }
); }; return (
{tabs.map(renderTab)}
{tabs.map(renderTab)}
); }; export default memo(TabList);