-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathNavigation.tsx
More file actions
95 lines (84 loc) · 2.96 KB
/
Copy pathNavigation.tsx
File metadata and controls
95 lines (84 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { NavLink } from '@remix-run/react';
import { cva } from 'class-variance-authority';
import clsx from 'clsx';
import { type Namespace, type ParseKeys } from 'i18next';
import { type IconProps } from 'packages/ui-icons/src/Icon';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
//TODO(split apps): refactor this to be translation agnostic: directly pass the translated string (it will help separate the navigation.json file per "app")
export const navigationI18n = ['navigation'] satisfies Namespace;
export interface SidebarLinkProps {
Icon: (props: Omit<IconProps, 'icon'>) => JSX.Element;
labelTKey: ParseKeys<['navigation']>;
to: string;
children?: React.ReactNode;
className?: string;
}
export const sidebarLink = cva(
'text-s flex flex-row items-center gap-2 rounded-xs p-2 font-medium w-full',
{
variants: {
isActive: {
true: 'bg-purple-96 text-purple-65',
false: 'text-grey-00 hover:bg-purple-96 hover:text-purple-65',
},
},
defaultVariants: {
isActive: false,
},
},
);
export function SidebarLink({ Icon, labelTKey, to, children, className }: SidebarLinkProps) {
const { t } = useTranslation(navigationI18n);
return (
<NavLink className={({ isActive }) => sidebarLink({ isActive, className })} to={to}>
<Icon className="size-6 shrink-0" />
<span className="line-clamp-1 text-start opacity-0 transition-opacity group-aria-expanded/nav:opacity-100">
{t(labelTKey)}
</span>
{children}
</NavLink>
);
}
export interface SidebarButtonProps
extends Omit<React.ComponentPropsWithoutRef<'button'>, 'children'> {
Icon: (props: Omit<IconProps, 'icon'>) => JSX.Element;
labelTKey: ParseKeys<['navigation']>;
}
export const SidebarButton = React.forwardRef<HTMLButtonElement, SidebarButtonProps>(
function SidebarButton({ Icon, labelTKey, className, ...props }, ref) {
const { t } = useTranslation(navigationI18n);
return (
<button ref={ref} className={sidebarLink({ className })} {...props}>
<Icon className="size-6 shrink-0" />
<span className="line-clamp-1 text-start opacity-0 transition-opacity group-aria-expanded/nav:opacity-100">
{t(labelTKey)}
</span>
</button>
);
},
);
export interface TabLinkProps {
Icon: (props: React.SVGProps<SVGSVGElement>) => JSX.Element;
labelTKey: ParseKeys<['navigation']>;
to: string;
}
export function TabLink({ Icon, labelTKey, to }: TabLinkProps) {
const { t } = useTranslation(navigationI18n);
return (
<NavLink
className={({ isActive }) =>
clsx(
'text-s flex flex-row items-center gap-2 rounded-sm px-4 py-2 font-medium',
isActive
? 'bg-purple-96 text-purple-65'
: 'text-grey-00 hover:bg-purple-96 hover:text-purple-65',
)
}
to={to}
>
<Icon className="size-6 shrink-0" />
<span className="first-letter:capitalize">{t(labelTKey)}</span>
</NavLink>
);
}