UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

137 lines (134 loc) 4.9 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { cn } from '../../lib/utilsComprehensive.js'; import { forwardRef } from 'react'; import '../../primitives/GlassCore.js'; import '../../primitives/glass/GlassAdvanced.js'; import { OptimizedGlassCore } from '../../primitives/OptimizedGlassCore.js'; import '../../primitives/glass/OptimizedGlassAdvanced.js'; import '../../primitives/MotionNative.js'; import { MotionFramer } from '../../primitives/motion/MotionFramer.js'; import { GlassButton } from '../button/GlassButton.js'; import { GlassBadge } from '../data-display/GlassBadge.js'; import { HStack } from '../layout/GlassStack.js'; import { useA11yId } from '../../utils/a11y.js'; import { useReducedMotion } from '../../hooks/useReducedMotion.js'; /** * GlassBottomNav component * Mobile bottom navigation with glassmorphism design */ const GlassBottomNav = /*#__PURE__*/forwardRef(({ items, activeId, onActiveChange, variant = "default", elevation = "level2", showLabels = true, labelPosition = "below", size = "md", sticky = true, safeArea = true, renderItem, respectMotionPreference = true, className, ...props }, ref) => { // Accessibility and motion preferences const navId = useA11yId("bottom-nav"); const prefersReducedMotion = useReducedMotion(); const shouldReduceMotion = respectMotionPreference && prefersReducedMotion; const sizeClasses = { sm: { height: "h-14", padding: "glass-px-2 glass-py-2", iconSize: "glass-text-base", labelSize: "glass-text-xs" }, md: { height: "h-16", padding: "glass-px-4 glass-py-3", iconSize: "glass-text-lg", labelSize: "glass-text-xs" }, lg: { height: "h-20", padding: "glass-px-6 glass-py-4", iconSize: "glass-text-xl", labelSize: "glass-text-sm" } }; const variantClasses = { default: "border-t border-border/20", floating: "glass-mx-4 glass-mb-4 glass-radius-xl border border-border/20", minimal: "border-t border-border/10" }; const config = sizeClasses?.[size]; // Handle item click const handleItemClick = item => { if (item?.disabled) return; onActiveChange?.(item?.id); item?.onClick?.(); }; // Render navigation item const renderNavigationItem = item => { if (renderItem) { const active = activeId === item?.id; return renderItem(item, active); } const active = activeId === item?.id; const iconToShow = active && item?.activeIcon ? item?.activeIcon : item?.icon; return jsxs("div", { className: 'relative glass-flex-1', children: [jsxs(GlassButton, { variant: active ? "primary" : "ghost", size: "sm", disabled: item?.disabled, onClick: e => handleItemClick(item), role: "tab", "aria-selected": active, "aria-controls": `nav-panel-${item.id}`, tabIndex: active ? 0 : -1, className: cn("w-full h-full flex flex-col items-center justify-center glass-gap-1 relative", labelPosition === "beside" && "flex-row glass-gap-2", !showLabels && "glass-gap-0"), children: [jsx("div", { className: cn("flex-shrink-0 transition-all duration-200", config.iconSize, active && !shouldReduceMotion && "scale-110"), children: iconToShow }), showLabels && jsx("span", { className: cn("font-medium transition-all duration-200 truncate", config.labelSize, active ? "text-primary-foreground" : "glass-text-secondary"), children: item?.label }), active && !showLabels && jsx(MotionFramer, { preset: respectMotionPreference ? "scaleIn" : "none", className: 'absolute -bottom-0.5 left-1/2 -translate-x-1/2 w-1 h-1 glass-surface-primary glass-radius-full' })] }), item?.badge && jsx(GlassBadge, { variant: item?.badgeVariant || "error", size: "xs", className: 'absolute glass-top-1 -right-1 min-w-[1.25rem] h-5 glass-flex glass-items-center glass-justify-center', children: item?.badge })] }, item?.id); }; return jsx(OptimizedGlassCore, { intent: "neutral", elevation: "level2", intensity: "medium", depth: 2, tint: "neutral", border: "subtle", animation: shouldReduceMotion ? "none" : "gentle", performanceMode: "medium", ref: ref, className: cn("w-full flex items-center", config.height, config.padding, variantClasses?.[variant], sticky && "sticky bottom-0", safeArea && "pb-safe", className), role: "tablist", "aria-label": "Bottom navigation", id: navId, ...props, children: jsx(HStack, { space: "none", className: "glass-w-full", children: items.map(item => renderNavigationItem(item)) }) }); }); GlassBottomNav.displayName = "GlassBottomNav"; export { GlassBottomNav }; //# sourceMappingURL=GlassBottomNav.js.map