menydock update, dashboard page create
This commit is contained in:
@@ -4,57 +4,58 @@ import { Home, Briefcase, Calendar, Shield, Settings } from 'lucide-react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const defaultItems = [
|
||||
{ label: 'home', icon: Home },
|
||||
{ label: 'work', icon: Briefcase },
|
||||
{ label: 'calendar', icon: Calendar },
|
||||
{ label: 'security', icon: Shield },
|
||||
{ label: 'settings', icon: Settings },
|
||||
{ label: 'home', icon: Home },
|
||||
{ label: 'work', icon: Briefcase },
|
||||
{ label: 'calendar', icon: Calendar },
|
||||
{ label: 'security', icon: Shield },
|
||||
{ label: 'settings', icon: Settings },
|
||||
];
|
||||
|
||||
export const MenuDock = ({
|
||||
items,
|
||||
export const MenuDock = ({
|
||||
items,
|
||||
className,
|
||||
variant = 'default',
|
||||
orientation = 'horizontal',
|
||||
showLabels = true,
|
||||
animated = true
|
||||
animated = true,
|
||||
showIndicator = true
|
||||
}) => {
|
||||
|
||||
const finalItems = useMemo(() => {
|
||||
const isValid = items && Array.isArray(items) && items.length >= 2 && items.length <= 8;
|
||||
if (!isValid) {
|
||||
console.warn(
|
||||
"MenuDock: 'items' prop is invalid or missing. Using default items.",
|
||||
items
|
||||
);
|
||||
return defaultItems;
|
||||
}
|
||||
return items;
|
||||
const isValid = items && Array.isArray(items) && items.length >= 2 && items.length <= 8;
|
||||
if (!isValid) {
|
||||
console.warn(
|
||||
"MenuDock: 'items' prop is invalid or missing. Using default items.",
|
||||
items
|
||||
);
|
||||
return defaultItems;
|
||||
}
|
||||
return items;
|
||||
}, [items]);
|
||||
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
const [underlineWidth, setUnderlineWidth] = useState(0);
|
||||
const [underlineLeft, setUnderlineLeft] = useState(0);
|
||||
|
||||
|
||||
const textRefs = useRef([]);
|
||||
const itemRefs = useRef([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeIndex >= finalItems.length) {
|
||||
setActiveIndex(0);
|
||||
}
|
||||
if (activeIndex >= finalItems.length) {
|
||||
setActiveIndex(0);
|
||||
}
|
||||
}, [finalItems, activeIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
const updateUnderline = () => {
|
||||
const activeButton = itemRefs.current[activeIndex];
|
||||
const activeText = textRefs.current[activeIndex];
|
||||
|
||||
|
||||
if (activeButton && activeText && showLabels && orientation === 'horizontal') {
|
||||
const buttonRect = activeButton.getBoundingClientRect();
|
||||
const textRect = activeText.getBoundingClientRect();
|
||||
const containerRect = activeButton.parentElement?.getBoundingClientRect();
|
||||
|
||||
|
||||
if (containerRect) {
|
||||
setUnderlineWidth(textRect.width);
|
||||
setUnderlineLeft(
|
||||
@@ -122,6 +123,7 @@ export const MenuDock = ({
|
||||
className={cn(
|
||||
'relative flex flex-col items-center justify-center rounded-lg transition-all duration-200',
|
||||
'hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
||||
'select-none',
|
||||
styles.item,
|
||||
isActive && 'text-primary',
|
||||
!isActive && 'text-muted-foreground hover:text-foreground'
|
||||
@@ -153,7 +155,7 @@ export const MenuDock = ({
|
||||
);
|
||||
})}
|
||||
{/* Animated underline for horizontal orientation with labels */}
|
||||
{showLabels && orientation === 'horizontal' && (
|
||||
{showIndicator && showLabels && orientation === 'horizontal' && (
|
||||
<div
|
||||
className={cn(
|
||||
'absolute bottom-2 h-0.5 bg-primary rounded-full transition-all duration-300 ease-out',
|
||||
@@ -165,17 +167,17 @@ export const MenuDock = ({
|
||||
}} />
|
||||
)}
|
||||
{/* Active indicator for vertical orientation or no labels */}
|
||||
{(!showLabels || orientation === 'vertical') && (
|
||||
{showIndicator && (!showLabels || orientation === 'vertical') && (
|
||||
<div
|
||||
className={cn(
|
||||
'absolute bg-primary rounded-full transition-all duration-300',
|
||||
orientation === 'vertical'
|
||||
? 'left-1 w-1 h-6'
|
||||
orientation === 'vertical'
|
||||
? 'left-1 w-1 h-6'
|
||||
: 'bottom-0.5 h-0.5 w-6'
|
||||
)}
|
||||
style={{
|
||||
[orientation === 'vertical' ? 'top' : 'left']:
|
||||
orientation === 'vertical'
|
||||
[orientation === 'vertical' ? 'top' : 'left']:
|
||||
orientation === 'vertical'
|
||||
? `${(activeIndex * (variant === 'large' ? 64 : variant === 'compact' ? 56 : 60)) + (variant === 'large' ? 19 : variant === 'compact' ? 16 : 18)}px`
|
||||
: `${(activeIndex * (variant === 'large' ? 64 : variant === 'compact' ? 56 : 60)) + (variant === 'large' ? 19 : variant === 'compact' ? 16 : 18)}px`
|
||||
}} />
|
||||
|
||||
Reference in New Issue
Block a user