refactor: improve layout navbar

This commit is contained in:
moonrailgun 2024-04-02 21:55:20 +08:00
parent 3bb2cc8715
commit 6fbf316c5d
3 changed files with 121 additions and 71 deletions

View File

@ -1,22 +1,36 @@
import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"
import * as React from 'react';
import * as AvatarPrimitive from '@radix-ui/react-avatar';
import { cn } from "@/utils/style"
import { cn } from '@/utils/style';
import { VariantProps, cva } from 'class-variance-authority';
const avatarVariants = cva(
'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full',
{
variants: {
size: {
default: 'h-10 w-10',
sm: 'h-8 w-8',
lg: 'h-12 w-12',
},
},
}
);
interface AvatarProps
extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>,
VariantProps<typeof avatarVariants> {}
const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
AvatarProps
>(({ className, size, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className
)}
className={cn(avatarVariants({ size, className }))}
{...props}
/>
))
Avatar.displayName = AvatarPrimitive.Root.displayName
));
Avatar.displayName = AvatarPrimitive.Root.displayName;
const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
@ -24,11 +38,11 @@ const AvatarImage = React.forwardRef<
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
className={cn('aspect-square h-full w-full', className)}
{...props}
/>
))
AvatarImage.displayName = AvatarPrimitive.Image.displayName
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
@ -37,12 +51,12 @@ const AvatarFallback = React.forwardRef<
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
'bg-muted flex h-full w-full items-center justify-center rounded-full',
className
)}
{...props}
/>
))
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
export { Avatar, AvatarImage, AvatarFallback }
export { Avatar, AvatarImage, AvatarFallback };

View File

@ -12,6 +12,8 @@ import {
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuLabel,
} from '@/components/ui/dropdown-menu';
import { useEvent } from '@/hooks/useEvent';
import { useSettingsStore } from '@/store/settings';
@ -19,6 +21,7 @@ import { useUserInfo } from '@/store/user';
import { languages } from '@/utils/constants';
import { useTranslation, setLanguage } from '@i18next-toolkit/react';
import { useNavigate } from '@tanstack/react-router';
import { version } from '@tianji/shared';
import React from 'react';
import { LuMoreVertical } from 'react-icons/lu';
@ -38,7 +41,7 @@ export const UserConfig: React.FC<UserConfigProps> = React.memo((props) => {
});
const avatar = (
<Avatar>
<Avatar size={props.isCollapsed ? 'sm' : 'default'}>
<AvatarFallback>
{(userInfo?.username ?? '').substring(0, 2).toUpperCase()}
</AvatarFallback>
@ -134,6 +137,31 @@ export const UserConfig: React.FC<UserConfigProps> = React.memo((props) => {
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuSub>
<DropdownMenuSubTrigger>{t('Community')}</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem
onClick={() => window.open('https://discord.gg/8Vv47wAEej')}
>
{t('Join Discord')}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => window.open('https://twitter.com/moonrailgun')}
>
{t('Follow Twitter')}
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuLabel className="text-muted">
v{version}
</DropdownMenuLabel>
</DropdownMenuContent>
</DropdownMenu>
</div>

View File

@ -20,7 +20,7 @@ import { WorkspaceSwitcher } from '@/components/WorkspaceSwitcher';
import { UserConfig } from './Layout/UserConfig';
import { Outlet } from '@tanstack/react-router';
import { trpc } from '@/api/trpc';
import { useCurrentWorkspaceId, useUserStore } from '@/store/user';
import { useUserStore } from '@/store/user';
const defaultLayout: [number, number, number] = [265, 440, 655];
@ -48,39 +48,8 @@ export const LayoutV2: React.FC<LayoutProps> = React.memo((props) => {
}
);
return (
<TooltipProvider delayDuration={0}>
<ResizablePanelGroup
direction="horizontal"
onLayout={(sizes: number[]) => {
if (sizes.length === 3) {
setLayout(sizes as typeof defaultLayout);
} else if (sizes.length === 2) {
const listSize = layout[1];
const rest = 100 - sizes[0] - listSize;
setLayout([sizes[0], listSize, rest]);
}
}}
className="h-full items-stretch"
>
<ResizablePanel
defaultSize={layout[0]}
collapsedSize={4}
collapsible={true}
minSize={15}
maxSize={20}
onCollapse={() => {
setIsCollapsed(true);
}}
onExpand={() => {
setIsCollapsed(false);
}}
className={cn(
'flex flex-col',
isCollapsed &&
'min-w-[50px] transition-all duration-300 ease-in-out'
)}
>
const navbar = (
<>
<div
className={cn(
'flex h-[52px] items-center justify-center',
@ -129,7 +98,46 @@ export const LayoutV2: React.FC<LayoutProps> = React.memo((props) => {
<div className="flex-1" />
<Separator />
<div className={cn(isCollapsed && 'm-auto')}>
<UserConfig isCollapsed={isCollapsed} />
</div>
</>
);
return (
<TooltipProvider delayDuration={0}>
<ResizablePanelGroup
direction="horizontal"
onLayout={(sizes: number[]) => {
if (sizes.length === 3) {
setLayout(sizes as typeof defaultLayout);
} else if (sizes.length === 2) {
const listSize = layout[1];
const rest = 100 - sizes[0] - listSize;
setLayout([sizes[0], listSize, rest]);
}
}}
className="h-full items-stretch"
>
<ResizablePanel
defaultSize={layout[0]}
collapsedSize={1}
collapsible={true}
minSize={10}
maxSize={20}
onCollapse={() => {
setIsCollapsed(true);
}}
onExpand={() => {
setIsCollapsed(false);
}}
className={cn(
'flex flex-col',
isCollapsed &&
'min-w-[50px] transition-all duration-300 ease-in-out'
)}
>
{navbar}
</ResizablePanel>
{props.list && (