aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
159 lines (156 loc) • 5.35 kB
JavaScript
'use client';
import { jsx, jsxs } from 'react/jsx-runtime';
import { cn } from '../../lib/utilsComprehensive.js';
import React, { 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 '../../primitives/motion/MotionFramer.js';
import { useA11yId } from '../../utils/a11y.js';
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
/**
* GlassBreadcrumb component
* A glassmorphism breadcrumb navigation component
*/
const GlassBreadcrumb = /*#__PURE__*/forwardRef(({
separator = "/",
children,
maxItems,
showEllipsis = true,
ellipsisComponent = "...",
elevation = "level1",
size = "md",
respectMotionPreference = true,
className,
...props
}, ref) => {
// Accessibility and motion preferences
const navId = useA11yId("breadcrumb");
const prefersReducedMotion = useReducedMotion();
const shouldReduceMotion = respectMotionPreference && prefersReducedMotion;
const childArray = React.Children.toArray(children);
let itemsToRender = childArray;
// Handle max items with ellipsis
if (maxItems && (childArray?.length || 0) > maxItems) {
const startItems = childArray.slice(0, Math.ceil(maxItems / 2));
const endItems = childArray.slice(-Math.floor(maxItems / 2));
itemsToRender = [...startItems, ...(showEllipsis ? [ellipsisComponent] : []), ...endItems].filter(item => /*#__PURE__*/React.isValidElement(item) || typeof item === "string" || typeof item === "number");
}
const sizeClasses = {
sm: "glass-text-xs",
md: "glass-text-sm",
lg: "glass-text-base"
};
return jsx(OptimizedGlassCore, {
ref: ref,
elevation: elevation,
intensity: "medium",
depth: 2,
tint: "neutral",
border: "subtle",
animation: shouldReduceMotion ? "none" : "gentle",
performanceMode: "medium",
className: cn("inline-flex items-center glass-px-3 glass-py-1.5 glass-backdrop-blur-md ring-1 ring-white/10 bg-white/5", sizeClasses?.[size], className),
...props,
children: jsx("nav", {
"aria-label": "Breadcrumb",
id: navId,
children: jsx("ol", {
className: "glass-flex glass-items-center glass-gap-2",
children: itemsToRender.map((item, index) => jsxs("li", {
className: "glass-flex glass-items-center",
children: [index > 0 && jsx("span", {
className: 'glass-mx-2 text-primary/40',
"aria-hidden": "true",
children: separator
}), item]
}, index))
})
})
});
});
GlassBreadcrumb.displayName = "GlassBreadcrumb";
/**
* GlassBreadcrumbItem component
* Individual breadcrumb item
*/
const GlassBreadcrumbItem = /*#__PURE__*/forwardRef(({
isCurrentPage = false,
children,
respectMotionPreference = true,
className,
...props
}, ref) => {
const prefersReducedMotion = useReducedMotion();
const shouldReduceMotion = respectMotionPreference && prefersReducedMotion;
return jsx("span", {
ref: ref,
className: cn("glass-text-primary/80 transition-all duration-200", !isCurrentPage && !shouldReduceMotion && "hover:-translate-y-0.5", isCurrentPage && "glass-text-primary font-medium", className),
"aria-current": isCurrentPage ? "page" : undefined,
...props,
children: children
});
});
GlassBreadcrumbItem.displayName = "GlassBreadcrumbItem";
/**
* GlassBreadcrumbSeparator component
* Separator between breadcrumb items
*/
const GlassBreadcrumbSeparator = /*#__PURE__*/forwardRef(({
children = "/",
className,
...props
}, ref) => {
return jsx("span", {
ref: ref,
className: cn("glass-text-primary/60 glass-mx-2 select-none", className),
"aria-hidden": "true",
...props,
children: children
});
});
GlassBreadcrumbSeparator.displayName = "GlassBreadcrumbSeparator";
/**
* GlassBreadcrumbLink component
* Clickable breadcrumb link
*/
const GlassBreadcrumbLink = /*#__PURE__*/forwardRef(({
children,
href,
isCurrentPage = false,
respectMotionPreference = true,
className,
...props
}, ref) => {
const prefersReducedMotion = useReducedMotion();
const shouldReduceMotion = respectMotionPreference && prefersReducedMotion;
const linkClasses = cn("glass-text-primary/70 hover:glass-text-primary transition-all duration-200", "focus:outline-none glass-pulse-ring", "glass-radius-sm glass-px-1 glass-py-0.5 -glass-mx-1 -glass-my-0.5", !isCurrentPage && !shouldReduceMotion && "hover:-translate-y-0.5", isCurrentPage && "glass-text-primary font-medium cursor-default", className);
if (isCurrentPage) {
return jsx("span", {
className: linkClasses,
"aria-current": "page",
children: children
});
}
if (href) {
return jsx("a", {
ref: ref,
href: href,
className: linkClasses,
...props,
children: children
});
}
return jsx("button", {
ref: ref,
className: linkClasses,
onClick: props?.onClick,
...props,
children: children
});
});
GlassBreadcrumbLink.displayName = "GlassBreadcrumbLink";
export { GlassBreadcrumb, GlassBreadcrumbItem, GlassBreadcrumbLink, GlassBreadcrumbSeparator };
//# sourceMappingURL=GlassBreadcrumb.js.map