menydesk material-desgn 3

This commit is contained in:
IluaAir
2025-10-12 23:20:03 +03:00
parent 8ee524318c
commit be3181ca00
2 changed files with 91 additions and 40 deletions

View File

@@ -79,22 +79,22 @@ export const MenuDock = ({
switch (variant) { switch (variant) {
case 'compact': case 'compact':
return { return {
container: 'p-1', container: 'p-1 gap-1',
item: 'p-2 min-w-12', item: 'px-5 py-3',
icon: 'h-4 w-4', icon: 'h-4 w-4',
text: 'text-xs' text: 'text-xs'
}; };
case 'large': case 'large':
return { return {
container: 'p-3', container: 'p-3 gap-4',
item: 'p-3 min-w-16', item: 'px-6 py-4',
icon: 'h-6 w-6', icon: 'h-6 w-6',
text: 'text-base' text: 'text-base'
}; };
default: default:
return { return {
container: 'p-2', container: 'p-2 gap-3',
item: 'p-2 min-w-14', item: 'px-5 py-3.5',
icon: 'h-5 w-5', icon: 'h-5 w-5',
text: 'text-sm' text: 'text-sm'
}; };
@@ -106,7 +106,7 @@ export const MenuDock = ({
return ( return (
<nav <nav
className={cn( className={cn(
'relative inline-flex items-center rounded-xl bg-card border shadow-sm', 'relative inline-flex items-center rounded-3xl bg-transparent',
orientation === 'horizontal' ? 'flex-row' : 'flex-col', orientation === 'horizontal' ? 'flex-row' : 'flex-col',
styles.container, styles.container,
className className
@@ -117,15 +117,17 @@ export const MenuDock = ({
const IconComponent = item.icon; const IconComponent = item.icon;
return ( return (
<button <div
key={`${item.label}-${index}`} key={`${item.label}-${index}`}
className="flex flex-col items-center gap-1">
<button
ref={(el) => { itemRefs.current[index] = el; }} ref={(el) => { itemRefs.current[index] = el; }}
className={cn( className={cn(
'relative flex flex-col items-center justify-center rounded-lg transition-all duration-200', 'relative flex items-center justify-center rounded-full transition-all duration-300',
'hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', 'hover:bg-primary/10 focus-visible:outline-none',
'select-none', 'select-none active:scale-95',
styles.item, styles.item,
isActive && 'text-primary', isActive && 'text-primary bg-primary/15',
!isActive && 'text-muted-foreground hover:text-foreground' !isActive && 'text-muted-foreground hover:text-foreground'
)} )}
onClick={() => handleItemClick(index, item)} onClick={() => handleItemClick(index, item)}
@@ -134,24 +136,24 @@ export const MenuDock = ({
<div <div
className={cn( className={cn(
'flex items-center justify-center transition-all duration-200', 'flex items-center justify-center transition-all duration-200',
animated && isActive && 'animate-bounce', animated && isActive && 'animate-bounce'
orientation === 'horizontal' && showLabels ? 'mb-1' : '',
orientation === 'vertical' && showLabels ? 'mb-1' : ''
)}> )}>
<IconComponent className={cn(styles.icon, 'transition-colors duration-200')} /> <IconComponent className={cn(styles.icon, 'transition-colors duration-200')} />
</div> </div>
</button>
{showLabels && ( {showLabels && (
<span <span
ref={(el) => { textRefs.current[index] = el; }} ref={(el) => { textRefs.current[index] = el; }}
className={cn( className={cn(
'font-medium transition-colors duration-200 capitalize', 'font-medium transition-colors duration-200 capitalize',
styles.text, styles.text,
'whitespace-nowrap' 'whitespace-nowrap',
isActive ? 'text-primary' : 'text-muted-foreground'
)}> )}>
{item.label} {item.label}
</span> </span>
)} )}
</button> </div>
); );
})} })}
{/* Animated underline for horizontal orientation with labels */} {/* Animated underline for horizontal orientation with labels */}

View File

@@ -2,27 +2,76 @@
import { MenuDock } from '@/components/ui/shadcn-io/menu-dock'; import { MenuDock } from '@/components/ui/shadcn-io/menu-dock';
import { Home, Settings, Bell } from 'lucide-react'; import { Home, Settings, Bell } from 'lucide-react';
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
const menuItems = [ const menuItems = [
{ label: 'home', icon: Home, onClick: () => console.log('Home clicked') }, { label: 'home', icon: Home, onClick: () => console.log('Home clicked') },
{ label: 'notifications', icon: Bell, onClick: () => console.log('Notifications clicked') }, { label: 'notify', icon: Bell, onClick: () => console.log('Notifications clicked') },
{ label: 'settings', icon: Settings, onClick: () => console.log('Settings clicked') }, { label: 'settings', icon: Settings, onClick: () => console.log('Settings clicked') },
]; ];
export default function Dashboard() { export default function Dashboard() {
return ( return (
<div className="min-h-[180px] p-4 flex justify-start items-start"> <div className="flex min-h-screen bg-background">
<div className="flex flex-col items-center justify-center"> {/* Navigation Rail - Material Design 3 */}
<Avatar className="mb-2 size-10 justify-center items-center"> <aside className="w-20 bg-card/50 flex flex-col items-center py-4 gap-4">
{/* Avatar with large M3 container */}
<div className="mb-2">
<Avatar className="size-14 rounded-2xl">
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" /> <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback> <AvatarFallback className="rounded-2xl">CN</AvatarFallback>
</Avatar> </Avatar>
</div>
<MenuDock <MenuDock
items={menuItems} items={menuItems}
orientation="vertical" orientation="vertical"
showIndicator={false} showIndicator={false}
variant="default" showLabels={true}
variant="compact"
/> />
</aside>
{/* Main Content Area */}
<main className="flex-1 p-6 bg-background">
<div className="max-w-7xl mx-auto space-y-6">
<h1 className="text-3xl font-bold">Dashboard</h1>
{/* Material Design 3 Cards Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{/* Filled Card */}
<div className="bg-card p-6 rounded-3xl shadow-sm">
<h3 className="text-lg font-semibold mb-2">Filled Card</h3>
<p className="text-muted-foreground text-sm">
Material Design 3 filled container with large rounded corners.
</p>
</div> </div>
{/* Elevated Card */}
<div className="bg-card p-6 rounded-3xl shadow-lg hover:shadow-xl transition-shadow">
<h3 className="text-lg font-semibold mb-2">Elevated Card</h3>
<p className="text-muted-foreground text-sm">
Elevated surface with prominent shadow for hierarchy.
</p>
</div>
{/* Outlined Card */}
<div className="bg-background border-2 border-border p-6 rounded-3xl">
<h3 className="text-lg font-semibold mb-2">Outlined Card</h3>
<p className="text-muted-foreground text-sm">
Outlined container with subtle border emphasis.
</p>
</div>
</div>
{/* Example Section with M3 styling */}
<div className="bg-card/30 p-6 rounded-3xl">
<h2 className="text-xl font-semibold mb-4">Surface Container</h2>
<p className="text-muted-foreground">
Material Design 3 emphasizes larger border radius (rounded-3xl) and layered surfaces.
</p>
</div>
</div>
</main>
</div> </div>
); );
} }