@findify/react-components
Version:
Findify react UI components
55 lines (52 loc) • 2.17 kB
JSX
/**
* @module components/Tabs
*/
import { Children, cloneElement, useCallback, useMemo, useState } from 'react';
import cx from 'classnames';
import Dropdown from 'components/Dropdown';
import { fromJS } from 'immutable';
import styles from 'components/Tabs/styles.css';
import { useMobile } from 'helpers/useMobile';
export const Tab = () => null;
const Item = ({ onClick, label, theme, active, disabled, index }) => {
const _onClick = useCallback((e) => {
if (disabled)
return;
if (e)
e.preventDefault();
return onClick(index);
}, []);
return (<li className={cx(theme.tab, active && theme.active, disabled && theme.disabled)} onClick={_onClick}>
{label}
</li>);
};
const MobileDropdown = ({ children, selected, onChange, className }) => {
const _onChange = useCallback((item) => onChange(item.get('index')), []);
const items = useMemo(() => fromJS(Children.toArray(children).map((i, index) => ({
index,
label: i.props.label,
}))), [children]);
return (<Dropdown className={className} selectedItem={items.get(selected)} onChange={_onChange} items={items}/>);
};
export default ({ theme = styles, children, onTabClick, selectedIndex = 0, }) => {
const [selected, setSelected] = useState(selectedIndex);
const isMobile = useMobile();
const onSelect = useCallback((selectedIndex) => {
if (onTabClick)
onTabClick(selectedIndex);
setSelected(selectedIndex);
}, []);
const body = useMemo(() => {
const candidate = Children.toArray(children)[selected];
return cloneElement(candidate.props.children, {
changeTab: onSelect,
});
}, [selected]);
return (<>
<ul className={theme.list} display-if={!isMobile}>
{Children.map(children, (child, index) => (<Item {...child.props} index={index} key={index} active={index === selected} theme={theme} onClick={onSelect}/>))}
</ul>
<MobileDropdown display-if={isMobile} children={children} selected={selected} className={theme.dropdown} onChange={onSelect}/>
<div className={theme.body}>{body}</div>
</>);
};