'use client'
import { type JSX, forwardRef, useMemo, useRef } from 'react'
import * as React from 'react'
import { OpenInNewIcon } from '@channel.io/bezier-icons'
import * as TabsPrimitive from '@radix-ui/react-tabs'
import * as ToolbarPrimitive from '@radix-ui/react-toolbar'
import classNames from 'classnames'
import useElementTruncated from '~/src/hooks/useElementTruncated'
import { createContext } from '~/src/utils/react'
import { isNil } from '~/src/utils/type'
import { BaseButton } from '~/src/components/BaseButton'
import { Icon } from '~/src/components/Icon'
import {
type TabActionElement,
type TabActionProps,
type TabActionsProps,
type TabContentProps,
type TabItemProps,
type TabItemsProps,
type TabListContextValue,
type TabListProps,
type TabSize,
type TabsProps,
} from '~/src/components/Tabs/Tabs.types'
import { Text } from '~/src/components/Text'
import { Tooltip } from '~/src/components/Tooltip'
import styles from './Tabs.module.scss'
/**
* `Tabs` is a set of layered section of content.
*
* `Tabs` is a context of the Tab-related components and gives accessibility properties to Tab-related components.
* @example
*
* ```tsx
*
*
*
*
*
*
*
*
*
*
*
* ```
*/
export const Tabs = forwardRef(function Tabs(
{ className, activationMode = 'automatic', dir, children, ...rest },
forwardedRef
) {
return (
{children}
)
})
const [TabListContextProvider, useTabListContext] =
createContext({
size: 'm',
})
/**
* `TabList` gives size context to its children and decides the layout of `TabItems` and `TabActions`.
*/
export const TabList = forwardRef(
function TabList({ className, children, size = 'm', ...rest }, forwardedRef) {
const heightContextValue = useMemo(
() => ({
size,
}),
[size]
)
return (
{children}
)
}
)
/**
* `TabItems` is a flex container which has `TabItem` flex items.
*/
export const TabItems = forwardRef(
function TabItems({ className, children, ...rest }, forwardedRef) {
return (
{children}
)
}
)
function getButtonSizeBy(size: TabSize) {
return (
{
l: 'l',
m: 'm',
s: 's',
} as const
)[size]
}
function getTypography(size: TabSize) {
return (
{
s: '13',
m: '14',
l: '15',
} as const
)[size]
}
const TabItemButton = forwardRef(
function TabItemButton(
{ className, disabled, value, children, maxWidth, style, ...rest },
forwardedRef
) {
const contentRef = useRef(null)
const isTruncated = useElementTruncated(contentRef)
const { size } = useTabListContext()
return (
{children}
)
}
)
/**
* `TabItem` is a button that activates its associated content.
*/
export const TabItem = forwardRef(
function TabItem(
{ className, disabled, value, children, maxWidth, style, ...rest },
forwardedRef
) {
if (typeof children !== 'string') {
return null
}
return (
{children}
)
}
)
/**
* `TabContent` has content associated with `TabItem`.
*/
export const TabContent = forwardRef(
function TabContent({ children, value, ...rest }, forwardedRef) {
return (
{children}
)
}
)
/**
* `TabActions` is a flex container which has `TabAction` flex items.
* It also gives accessibility properties to its children.
*/
export const TabActions = forwardRef(
function TabActions({ className, dir, children, ...rest }, forwardedRef) {
return (
{children}
)
}
)
function getTypoBy(size: TabSize) {
return (
{
l: '14',
m: '14',
s: '13',
} as const
)[size]
}
function getIconSizeBy(size: TabSize) {
return (
{
l: 's',
m: 'xs',
s: 'xs',
} as const
)[size]
}
/**
* `TabAction` is a button for more action to open a new link or navigate to a different url.
* If it has `href` props, it should act as a link.
*/
export const TabAction = forwardRef<
TabActionElement,
TabActionProps
>(function TabAction(
{ className: classNameProp, href, children, onClick, ...rest },
forwardedRef
) {
const { size } = useTabListContext()
const className = classNames(
styles.TabAction,
styles[`size-${size}`],
classNameProp
)
return isNil(href) ? (
{children}
) : (
{children}
)
}) as (
props: TabActionProps & {
ref?: React.ForwardedRef>
}
) => JSX.Element