aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
175 lines (172 loc) • 6.29 kB
JavaScript
'use client';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { forwardRef } from 'react';
import { cn } from '../../lib/utilsComprehensive.js';
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 { useA11yId } from '../../utils/a11y.js';
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
/**
* GlassCardLink Component
*
* An enhanced card with 3D transform effects and link functionality.
* Features physics-inspired animations and intuitive hover states.
* Modernized to use OptimizedGlass architecture.
*/
const GlassCardLink = /*#__PURE__*/forwardRef(({
// TODO: Integrate ContrastGuard for table cells, list items, badges, card titles, and other text content for WCAG AA compliance
icon,
title,
description,
link,
buttonText = "Learn more",
className = "",
customPreview,
glassVariant = "frosted",
onClick,
children,
respectMotionPreference = true,
id,
"aria-label": ariaLabel,
...props
}, ref) => {
useReducedMotion();
const componentId = id || useA11yId("card-link");
const handleClick = e => {
if (onClick) {
onClick(e);
e.preventDefault();
}
};
const defaultAriaLabel = ariaLabel || `${title}. ${description}. ${buttonText}.`;
const ArrowIcon = () => jsxs("svg", {
className: 'w-4 h-4 glass-ml-1 transition-transform duration-300 group-hover:translate-x-1',
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
children: [jsx("line", {
x1: "5",
y1: "12",
x2: "19",
y2: "12"
}), jsx("polyline", {
points: "12 5 19 12 12 19"
})]
});
// Map glass variants to OptimizedGlass props
const variantMap = {
clear: {
intensity: "subtle",
tint: "neutral"
},
frosted: {
intensity: "medium",
tint: "neutral"
},
tinted: {
intensity: "medium",
tint: "cool"
},
luminous: {
intensity: "strong",
tint: "warm"
}
};
const variant = variantMap[glassVariant];
// Render card content
const renderCardContent = () => {
if (children) return children;
return jsxs(Fragment, {
children: [icon && jsx("div", {
className: 'relative z-10 mb-6 transition-all duration-300 group-hover:-translate-y-1 group-hover:scale-105',
children: jsxs("div", {
className: 'relative',
children: [icon, jsx("div", {
className: 'absolute inset-0 -inset-2 glass-radius-lg bg-gradient-radial glass-gradient-primary via-blue-500/10 glass-gradient-primary opacity-0 transition-opacity duration-400 group-hover:opacity-100'
})]
})
}), jsxs("div", {
className: 'relative z-10 mb-6',
children: [jsx("h3", {
className: 'mb-2 glass-text-xl font-semibold text-primary transition-colors duration-200',
children: title
}), jsx("p", {
className: 'mb-4 glass-text-sm text-primary/70 transition-colors duration-200',
children: description
}), customPreview && jsx("div", {
className: 'custom-preview-container',
children: customPreview
})]
}), jsx("div", {
className: 'relative z-10 mt-auto pt-4 glass-border-t glass-border-white/10',
children: jsx("div", {
className: "glass-flex glass-items-center glass-justify-between",
children: jsxs("div", {
className: 'glass-flex glass-items-center glass-text-sm font-medium text-primary/90 group transition-colors duration-300 group-hover:text-primary',
"aria-hidden": "true",
children: [jsx("span", {
children: buttonText
}), jsx(ArrowIcon, {})]
})
})
})]
});
};
return jsx(MotionFramer, {
preset: "fadeIn",
className: 'group block',
children: jsx("a", {
ref: ref,
id: componentId,
href: link,
onClick: handleClick,
"aria-label": defaultAriaLabel,
"aria-describedby": `${componentId}-description`,
className: 'block glass-focus glass-touch-target glass-contrast-guard glass-focus glass-touch-target glass-contrast-guard',
children: jsxs(OptimizedGlassCore, {
intent: "neutral",
elevation: "level2",
intensity: variant.intensity,
depth: 3,
tint: variant.tint,
border: "subtle",
animation: "float",
performanceMode: "medium",
liftOnHover: true,
press: true,
className: cn(
// Base styles
"group relative block overflow-hidden glass-radius-xl glass-p-6 text-decoration-none", "transform-gpu transition-all duration-500 ease-out", "perspective-1000 transform-style-preserve-3d",
// Hover effects
"hover:-translate-y-2 hover:scale-[1.01] hover:rotate-x-1", "hover:shadow-2xl hover:shadow-blue-500/20",
// Glass overlay effect
"before:absolute before:inset-0 before:z-0", "before:bg-gradient-to-br before:from-white/10 before:via-transparent before:to-transparent", "before:opacity-0 before:transition-opacity before:duration-500", "hover:before:opacity-100",
// Focus styles
"focus:outline-none focus:ring-2 focus:ring-white/30 focus:ring-offset-2 focus:ring-offset-transparent", className),
style: {
transformStyle: "preserve-3d"
},
...props,
children: [jsxs("div", {
id: `${componentId}-description`,
className: 'sr-only',
children: ["Interactive card link: ", title, ". ", description]
}), jsx("div", {
className: 'relative z-10 glass-flex glass-h-full min-h-[200px] glass-flex-col',
children: renderCardContent()
})]
})
})
});
});
GlassCardLink.displayName = "GlassCardLink";
export { GlassCardLink, GlassCardLink as default };
//# sourceMappingURL=GlassCardLink.js.map