UNPKG

aura-glass

Version:

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

160 lines (157 loc) 5.1 kB
'use client'; import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import { cn } from '../../lib/utilsComprehensive.js'; import { forwardRef } from 'react'; import { useReducedMotion } from '../../hooks/useReducedMotion.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 '../../primitives/motion/MotionFramer.js'; const GlassTypingIndicator = /*#__PURE__*/forwardRef(({ isTyping = true, users, showUsers = true, text, size = "md", elevation = "level1", variant = "bounce", dotColor = "primary", dotCount = 3, glass = true, className, ...props }, ref) => { useReducedMotion(); if (!isTyping) return null; const userList = Array.isArray(users) ? users : users ? [users] : []; const hasUsers = userList.length > 0; const getUserText = () => { if (!hasUsers || !showUsers) return null; if (userList.length === 1) { return `${userList[0]} is`; } else if (userList.length === 2) { return `${userList[0]} and ${userList[1]} are`; } else if (userList.length > 2) { return `${userList[0]}, ${userList[1]} and ${userList.length - 2} other${userList.length - 2 > 1 ? "s" : ""} are`; } return null; }; const displayText = text ? text.replace("{users}", userList.join(", ")).replace("{isAre}", userList.length === 1 ? "is" : "are") : null; const sizeClasses = { sm: { dot: "w-1.5 h-1.5", text: "glass-text-xs", gap: "gap-1", padding: "glass-px-2 glass-py-1" }, md: { dot: "w-2 h-2", text: "glass-text-sm", gap: "gap-1.5", padding: "glass-px-3 glass-py-2" }, lg: { dot: "w-2.5 h-2.5", text: "glass-text-base", gap: "gap-2", padding: "glass-px-4 glass-py-3" } }; const dotColorClasses = { primary: "bg-blue-500", secondary: "bg-purple-500", success: "bg-green-500", warning: "bg-yellow-500", danger: "bg-red-500", neutral: "glass-surface-subtle" }; const getAnimationStyle = index => { const delay = index * 150; const styles = { animationDelay: `${delay}ms` }; if (variant === "wave") { styles.animation = `wave 1.4s ease-in-out infinite`; styles.animationDelay = `${delay}ms`; } return styles; }; const dots = Array.from({ length: dotCount }, (_, index) => jsx("div", { className: cn(sizeClasses[size].dot, dotColorClasses[dotColor], "rounded-full", variant !== "wave" && animations[variant]), style: getAnimationStyle(index), "aria-hidden": "true" }, index)); const content = jsxs("div", { className: cn("inline-flex items-center", sizeClasses[size].gap, !glass && sizeClasses[size].padding), children: [showUsers && hasUsers && jsx("span", { className: cn(sizeClasses[size].text, "glass-text-secondary font-medium"), children: displayText || jsxs(Fragment, { children: [getUserText(), " typing", jsx("span", { className: 'glass-inline-flex ml-1 glass-gap-0.5', children: Array.from({ length: 3 }, (_, i) => jsx("span", { className: 'animate-pulse', style: { animationDelay: `${i * 200}ms` }, children: "." }, i)) })] }) }), (!showUsers || !hasUsers) && jsx("div", { className: cn("flex items-center", sizeClasses[size].gap), children: dots })] }); if (!glass) { return jsx("div", { "data-glass-component": true, ref: ref, className: cn("inline-flex", className), role: "status", "aria-live": "polite", "aria-label": hasUsers && showUsers ? `${userList.join(", ")} ${userList.length === 1 ? "is" : "are"} typing` : "Someone is typing", ...props, children: content }); } return jsx(OptimizedGlassCore, { ref: ref, elevation: elevation, className: cn("inline-flex glass-radius-full", sizeClasses[size].padding, className), role: "status", "aria-live": "polite", "aria-label": hasUsers && showUsers ? `${userList.join(", ")} ${userList.length === 1 ? "is" : "are"} typing` : "Someone is typing", ...props, children: content }); }); GlassTypingIndicator.displayName = "GlassTypingIndicator"; const animations = { bounce: "animate-bounce", pulse: "animate-pulse", wave: "", fade: "animate-pulse" }; if (typeof document !== "undefined" && !document.getElementById("typing-indicator-keyframes")) { const style = document.createElement("style"); style.id = "typing-indicator-keyframes"; style.textContent = ` @keyframes wave { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-8px); } } `; document.head.appendChild(style); } export { GlassTypingIndicator, GlassTypingIndicator as default }; //# sourceMappingURL=GlassTypingIndicator.js.map