@spaced-out/ui-design-system
Version:
Sense UI components library
122 lines (107 loc) • 3.08 kB
Flow
// @flow strict
import * as React from 'react';
import classify from '../../utils/classify';
import type {AnchorType} from '../ButtonDropdown';
import type {ElevationType} from '../Tooltip';
import {ButtonTabDropdown} from './ButtonTabDropdown';
import css from './ButtonTabs.module.css';
type ClassNames = $ReadOnly<{
wrapper?: string,
buttonTabDropdownWrapper?: string,
}>;
export type ButtonTabsProps = {
classNames?: ClassNames,
children: React.Node,
isFluid?: boolean,
size?: 'medium' | 'small',
disabled?: boolean,
selectedButtonTabId?: string,
onButtonTabSelect?: ?(id: string, e?: ?SyntheticEvent<HTMLElement>) => mixed,
wrapAfter?: number,
elevation?: ElevationType,
wrapTabTitle?: string,
anchorPosition?: AnchorType,
};
export const ButtonTabs: React$AbstractComponent<
ButtonTabsProps,
HTMLDivElement,
> = React.forwardRef<ButtonTabsProps, HTMLDivElement>(
(
{
classNames,
children,
isFluid,
size = 'medium',
disabled,
selectedButtonTabId,
onButtonTabSelect,
wrapAfter,
elevation = 'modal',
wrapTabTitle = 'more',
anchorPosition,
}: ButtonTabsProps,
ref,
): React.Node => {
const childrenArray = React.Children.toArray(children);
let unwrappedNodes = childrenArray;
let wrappedNodes = [];
if (typeof wrapAfter === 'number' && wrapAfter > -1) {
unwrappedNodes = childrenArray.slice(0, wrapAfter);
wrappedNodes = childrenArray.slice(wrapAfter);
if (wrappedNodes.length) {
unwrappedNodes.push(
<ButtonTabDropdown
id="more-tab"
title={wrapTabTitle}
iconName="ellipsis-vertical"
elevation={elevation}
anchorPosition={anchorPosition}
dropdownClass={classNames?.buttonTabDropdownWrapper}
>
{wrappedNodes}
</ButtonTabDropdown>,
);
}
}
const childrenWithProps = unwrappedNodes.map((child, index) => {
if (React.isValidElement(child)) {
const {disabled: disabledChild, classNames: classNamesChild} =
child.props;
const isFirst = index === 0;
const isLast = index === unwrappedNodes.length - 1;
return React.cloneElement(child, {
...child.props,
isFluid,
size,
isLeftCurved: isFirst,
isRightCurved: isLast,
disabled: disabledChild || disabled,
selectedButtonTabId,
onButtonTabSelect,
classNames: {
wrapper: classNamesChild?.wrapper,
},
});
}
return child;
});
return (
<div
data-testid="ButtonTabs"
ref={ref}
className={classify(
css.buttonTabsWrapper,
{
[css.medium]: size === 'medium',
[css.small]: size === 'small',
[css.isFluid]: isFluid,
[css.disabled]: disabled,
},
classNames?.wrapper,
)}
>
{childrenWithProps}
</div>
);
},
);