import {RadioGroup, TabProps} from "@headlessui/react";
import React, {FC, isValidElement, ReactElement, ReactNode} from "react";
import classNames from "classnames";
import {__} from "../../globals";
export type Tab = {
id: string,
label: string | ((isSelected: boolean) => ReactElement),
subLabel?: string,
tabDescription?: string[],
icon?: ReactNode,
showDescriptionOnlyWhenSelected?: boolean
isPreview?: boolean,
disabled?: boolean,
};
export type TabsProps = {
tabs: Tab[],
selectedTabId: TabsProps['multiple'] extends true ? string[] : string,
onTabSelect: (tabId: TabsProps['selectedTabId']) => void,
onTabHover?: (tabId: string) => void,
onTabUnhover?: () => void,
disabledTabs?: string[],
size?: 'extra-small' | 'normal',
direction?: 'horizontal' | 'vertical',
width?: 'auto' | 'full',
fixedHeight?: boolean,
dimUnselected?: boolean,
style?: 'transparent' | 'outline',
multiple?: boolean,
connectedToThe?: 'top' | 'bottom'
}
function DefaultTab(props: {
selected: boolean,
size: string,
label: string | React.ReactElement,
subLabel?: string,
isPreview?: boolean,
direction?: string
}) {
return <>
{props.selected ?
:
}
{props.label}
{props.isPreview && {__('Preview')} }
{props.subLabel && {props.subLabel} }
>;
}
function TabDescription(props: { description: string, label?: string }) {
return
{props.label && {props.label}: }
{props.description}
;
}
export const Tabs: FC = ({
tabs,
disabledTabs,
selectedTabId,
onTabSelect,
onTabHover,
onTabUnhover,
size = 'normal',
direction = 'horizontal',
width = 'full',
dimUnselected,
style = 'outline',
fixedHeight,
multiple,
connectedToThe
}) => {
const selectedTab = tabs.find(tab => tab.id === selectedTabId);
const onTabChange = id => {
let newValue: string | string[]
if (multiple) {
if (selectedTabId.includes(id)) {
newValue = selectedTabId.filter(tabId => tabId !== id)
} else {
newValue = [...selectedTabId, id]
}
} else {
newValue = id;
}
onTabSelect(newValue);
};
const atLeastOneTabHasSubLabel = tabs.some(tab => !!tab.subLabel);
return
{tabs.map(({
id,
label,
subLabel,
tabDescription,
showDescriptionOnlyWhenSelected = false,
disabled,
isPreview
}, index) => {
const isSelected = multiple ? selectedTabId.includes(id) : selectedTabId === id
disabled = disabled || (disabledTabs?.includes(id) === true);
const isFirst = index === 0;
const isLast = index === tabs.length - 1;
return (
onTabHover?.(id)} onMouseLeave={() => onTabUnhover?.()}
onMouseUp={() => {
if (multiple) {
return
}
/*
if (direction === 'vertical') {
return
}
*/
/**
* So there's a bug that it seems to come from headlessui in horizontal tabs,
* sometimes the onChange event on the RadioGroup.Option is not triggered on click.
* so we manually call the onTabChange function here.
*/
setTimeout(() => onTabChange(id), 100)
}}
>
{({checked: selected}) => typeof label == 'function' ? label(isSelected) :
{typeof label === 'function' ? label(isSelected) :
}
}
{subLabel && direction === 'horizontal' &&
{subLabel}
}
{multiple && tabDescription?.length && (showDescriptionOnlyWhenSelected ? isSelected : true) &&
{tabDescription.map((description) => )}
}
)
})}
{selectedTab?.tabDescription?.length &&
{selectedTab.tabDescription.map((description) => )}
}
}