aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
118 lines (115 loc) • 4.17 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';
/**
* GlassAvatar component
* A glassmorphism avatar with status indicators and fallbacks
*/
const GlassAvatar = /*#__PURE__*/forwardRef(({
// TODO: Integrate ContrastGuard for table cells, list items, badges, card titles, and other text content for WCAG AA compliance
variant = "circle",
size = "md",
status,
showStatus = false,
elevation = "level1",
fallback,
fallbackText,
"aria-label": ariaLabel,
className,
src,
alt,
onError,
...props
}, ref) => {
const avatarId = useA11yId("avatar");
const [hasError, setHasError] = React.useState(false);
const [isLoading, setIsLoading] = React.useState(!!src);
const sizeClasses = {
xs: "w-6 h-6 glass-text-xs",
sm: "w-8 h-8 glass-text-sm",
md: "w-10 h-10 glass-text-base",
lg: "w-12 h-12 glass-text-lg",
xl: "w-16 h-16 glass-text-xl",
"2xl": "w-20 h-20 glass-text-2xl"
};
const variantClasses = {
default: "glass-radius-md",
circle: "glass-radius-full",
square: "rounded-none",
"glass-radius-md": "glass-radius-lg"
};
const statusColors = {
online: "glass-surface-success",
offline: "glass-surface-primary",
away: "glass-surface-warning",
busy: "glass-surface-danger"
};
const handleError = e => {
setHasError(true);
setIsLoading(false);
onError?.(e);
};
const handleLoad = () => {
setIsLoading(false);
};
// Generate initials from fallback text
const getInitials = text => {
return text.split(" ").map(word => word[0]).join("").toUpperCase().slice(0, 2);
};
const showFallback = hasError || !src;
const fallbackContent = fallback || (fallbackText ? jsx("span", {
className: 'font-medium text-primary/80',
children: getInitials(fallbackText)
}) : jsx("div", {
className: 'w-4 h-4 glass-surface-subtle/30 glass-radius-md'
}));
return jsxs("div", {
"data-glass-component": true,
className: 'relative inline-block',
children: [jsxs(OptimizedGlassCore, {
elevation: elevation === 1 ? "level1" : elevation === 2 ? "level2" : elevation === 3 ? "level3" : "level1",
intensity: "medium",
depth: 2,
tint: "neutral",
border: "subtle",
animation: "none",
performanceMode: "medium",
id: avatarId,
className: cn("relative overflow-hidden", sizeClasses[size], variantClasses[variant], "glass-backdrop-blur-md bg-white/10 border border-white/20", className),
role: "img",
"aria-label": ariaLabel || alt || (fallbackText ? `Avatar for ${fallbackText}` : "Avatar"),
children: [showFallback ? jsx("div", {
className: "glass-flex glass-items-center glass-justify-center glass-w-full glass-h-full",
children: fallbackContent
}) : jsx("img", {
ref: ref,
src: src,
alt: alt || (ariaLabel ? "" : "Avatar image"),
onError: handleError,
onLoad: handleLoad,
className: 'glass-w-full glass-h-full object-cover',
...props
}), isLoading && !hasError && jsx("div", {
className: 'absolute inset-0 glass-flex glass-items-center glass-justify-center glass-surface-dark/20',
children: jsx("div", {
className: 'w-4 h-4 glass-border-2 glass-border-white/30 glass-border-t-white/60 glass-radius-full animate-spin'
})
})]
}), showStatus && status && jsx("div", {
className: cn("absolute bottom-0 right-0 w-3 h-3 glass-radius-full border-2 border-white", statusColors[status]),
role: "status",
"aria-label": `Status: ${status}`
})]
});
});
GlassAvatar.displayName = "GlassAvatar";
export { GlassAvatar };
//# sourceMappingURL=GlassAvatar.js.map