mirror of
https://github.com/hanzoai/calendar.git
synced 2026-10-30 14:46:43 +00:00
* refactor: Move classNames from @calcom/lib to @calcom/ui * Import fix * Removed extra import of classNames * Removed tailwind-merge from @calcom/lib
102 lines
3.2 KiB
TypeScript
102 lines
3.2 KiB
TypeScript
import { cva } from "class-variance-authority";
|
|
import { Fragment } from "react";
|
|
|
|
import classNames from "@calcom/ui/classNames";
|
|
|
|
import { ButtonOrLink } from "../dropdown";
|
|
import { Icon } from "../icon";
|
|
import type { IconName } from "../icon";
|
|
|
|
export type NavigationItemType = {
|
|
isLastChild?: boolean;
|
|
isExpanded?: boolean;
|
|
onToggle?: () => void;
|
|
name: string;
|
|
href?: string;
|
|
isLoading?: boolean;
|
|
badge?: React.ReactNode;
|
|
icon?: IconName;
|
|
child?: NavigationItemType[];
|
|
onlyMobile?: boolean;
|
|
onlyDesktop?: boolean;
|
|
moreOnMobile?: boolean;
|
|
isCurrent?: boolean;
|
|
};
|
|
|
|
const navigationItemStyles = cva(
|
|
"text-default group flex items-center rounded-[10px] p-2 text-sm font-medium transition hover:bg-subtle hover:text-emphasis",
|
|
{
|
|
variants: {
|
|
isChild: {
|
|
true: "[&[aria-current='page']]:text-emphasis [&[aria-current='page']]:bg-emphasis hidden h-8 ml-16 lg:flex lg:ml-10 relative before:absolute before:left-[-24px] before:top-[-0.5rem] before:h-[calc(100%+0.5rem)] before:w-0.5 before:bg-subtle before:content-[''] [&:first-child]:before:rounded-t-full [&:last-child]:before:rounded-b-full",
|
|
false: "[&[aria-current='page']]:text-emphasis mt-0.5 text-sm",
|
|
},
|
|
hasChild: {
|
|
true: "[&[aria-current='page']]:!bg-transparent relative after:absolute after:left-[-24px] after:top-[1.5rem] after:h-[calc(100%-1.5rem)] after:w-0.5 after:bg-subtle after:content-[''] [&:first-child]:after:rounded-t-full [&:last-child]:after:rounded-b-full",
|
|
false: "[&[aria-current='page']]:bg-subtle",
|
|
},
|
|
isFirstChild: {
|
|
true: "mt-0",
|
|
false: "mt-px",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
isChild: false,
|
|
hasChild: false,
|
|
isFirstChild: false,
|
|
},
|
|
}
|
|
);
|
|
|
|
const Label = ({ children }: { children: React.ReactNode }) => {
|
|
return <span className="text-default ml-3">{children}</span>;
|
|
};
|
|
|
|
const NavigationItemComponent = ({
|
|
item,
|
|
isChild,
|
|
index,
|
|
}: {
|
|
item: NavigationItemType;
|
|
isChild?: boolean;
|
|
index?: number;
|
|
}) => {
|
|
return (
|
|
<Fragment>
|
|
<ButtonOrLink
|
|
data-test-id={item.name}
|
|
href={item.href}
|
|
className={navigationItemStyles({
|
|
isChild,
|
|
hasChild: !!item.child,
|
|
isFirstChild: isChild && index === 0,
|
|
})}
|
|
aria-current={item.isCurrent ? "page" : undefined}
|
|
onClick={item.onToggle}>
|
|
{item.icon && (
|
|
<Icon
|
|
name={item.isLoading ? "rotate-cw" : item.icon}
|
|
className={classNames(
|
|
"text-subtle mr-2 h-4 w-4 flex-shrink-0 rtl:ml-2 md:ltr:mx-auto lg:ltr:mr-2",
|
|
item.isLoading && "animate-spin"
|
|
)}
|
|
aria-hidden="true"
|
|
aria-current={item.isCurrent ? "page" : undefined}
|
|
/>
|
|
)}
|
|
<span className="text-emphasis hidden w-full justify-between truncate text-ellipsis lg:flex">
|
|
{item.name}
|
|
{item.badge && item.badge}
|
|
</span>
|
|
</ButtonOrLink>
|
|
{item.child &&
|
|
item.isExpanded &&
|
|
item.child.map((childItem, childIndex) => (
|
|
<NavigationItem key={childItem.name} item={childItem} isChild index={childIndex} />
|
|
))}
|
|
</Fragment>
|
|
);
|
|
};
|
|
|
|
export const NavigationItem = Object.assign(NavigationItemComponent, { Label });
|