mirror of https://github.com/vizality/vizality
add __TabBar component and __TabBar.NavItem subcomponent
parent
e43678be5c
commit
f36088e7d7
@ -0,0 +1,86 @@
|
||||
import { AnimateSharedLayout, AnimatePresence, motion } from 'framer-motion';
|
||||
import { joinClassNames } from '@vizality/util/dom';
|
||||
import { getModule } from '@vizality/webpack';
|
||||
import { useToggle } from '@vizality/hooks';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
/**
|
||||
* Content sidebar that can be used as a side navigation or to hold content.
|
||||
* @component
|
||||
* @returns {React.MemoExoticComponent<function(): React.ReactElement>}
|
||||
*/
|
||||
export default memo(({ type, children, className }) => {
|
||||
const { side, top, topPill } = getModule('selected', 'item', 'topPill');
|
||||
const { tabBar } = getModule('tabBar', 'item');
|
||||
|
||||
/**
|
||||
* Check if type prop matches one of the available types, if it doesn't, set it
|
||||
* to topPill by default.
|
||||
*/
|
||||
switch (type) {
|
||||
case side:
|
||||
case 'side':
|
||||
type = side; break;
|
||||
case top:
|
||||
case 'top':
|
||||
type = top; break;
|
||||
case topPill:
|
||||
case 'top-pill':
|
||||
type = topPill; break;
|
||||
default:
|
||||
type = topPill;
|
||||
}
|
||||
|
||||
return (
|
||||
<AnimateSharedLayout>
|
||||
<AnimatePresence>
|
||||
<div className={joinClassNames('vz-tab-bar', tabBar, type, className)} role='tabbar'>
|
||||
{children}
|
||||
</div>
|
||||
</AnimatePresence>
|
||||
</AnimateSharedLayout>
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tab bar navigation item.
|
||||
* @component
|
||||
* @returns {React.MemoExoticComponent<function(): React.ReactElement>}
|
||||
*/
|
||||
export const NavItem = memo(({ icon, route, separator = false, disabled, iconOnly, selected, onClick, className, children, ...other }) => {
|
||||
selected = typeof selected === 'boolean' ? selected : vizality.api.routes.getLocation()?.pathname?.startsWith(route);
|
||||
const { item, themed, selected: _selected, disabled: _disabled } = getModule('selected', 'item', 'topPill');
|
||||
const { item: item2 } = getModule('tabBar', 'item');
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
{...other}
|
||||
className={joinClassNames('vz-tab-bar-item', className, item, item2, themed, { [_selected]: selected, [_disabled]: disabled })}
|
||||
role='tab'
|
||||
vz-selected={selected && ''}
|
||||
vz-disabled={disabled && ''}
|
||||
onClick={evt => {
|
||||
try {
|
||||
evt?.persist?.();
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
if (onClick) {
|
||||
return onClick(evt);
|
||||
} else if (route) {
|
||||
return vizality.api.routes.navigateTo(route);
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
{separator && (
|
||||
<div className={separator} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
Loading…
Reference in new issue