@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
109 lines (106 loc) • 4.97 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { useState, useCallback } from 'react';
import { useI18n } from './i18n-context.js';
function FloatingChatButton({ onClick, isOpen = false, unreadCount = 0, position = "bottom-right", size = "md", color = "#3B82F6", className = "", disabled = false, ariaLabel, }) {
// Use i18n context
const { t } = useI18n();
// Use default aria label from translations if not provided
const displayAriaLabel = ariaLabel || t("openChat");
const [isHovered, setIsHovered] = useState(false);
const handleClick = useCallback(() => {
if (!disabled) {
onClick();
}
}, [onClick, disabled]);
const handleKeyDown = useCallback((event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
handleClick();
}
}, [handleClick]);
const getPositionClasses = () => {
switch (position) {
case "bottom-left":
return "bottom-6 left-6";
case "top-right":
return "top-6 right-6";
case "top-left":
return "top-6 left-6";
default:
return "bottom-6 right-6";
}
};
const getSizeClasses = () => {
switch (size) {
case "sm":
return "w-12 h-12 text-sm";
case "lg":
return "w-20 h-20 text-xl";
default:
return "w-16 h-16 text-lg";
}
};
const getIconSize = () => {
switch (size) {
case "sm":
return "w-6 h-6";
case "lg":
return "w-10 h-10";
default:
return "w-8 h-8";
}
};
const ChatIcon = () => (jsx("svg", { className: `${getIconSize()} transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: isOpen ? (jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })) : (jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" })) }));
return (jsxs("div", { className: `fixed z-50 ${getPositionClasses()}`, children: [jsxs("button", { onClick: handleClick, onKeyDown: handleKeyDown, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), disabled: disabled, "aria-label": displayAriaLabel, "aria-expanded": isOpen, role: "button", tabIndex: 0, className: `
${getSizeClasses()}
rounded-full
text-white
shadow-lg
transition-all
duration-300
ease-in-out
hover:shadow-xl
focus:outline-none
focus:ring-4
focus:ring-opacity-50
active:scale-95
disabled:opacity-50
disabled:cursor-not-allowed
${isHovered ? "scale-110" : "scale-100"}
${isOpen ? "rotate-45" : ""}
${className}
`, style: {
backgroundColor: color,
boxShadow: isHovered
? `0 20px 25px -5px ${color}33, 0 10px 10px -5px ${color}1a`
: `0 10px 15px -3px ${color}1a, 0 4px 6px -2px ${color}0d`,
}, children: [jsx(ChatIcon, {}), unreadCount > 0 && (jsx("div", { className: "absolute -top-2 -right-2 min-w-[1.25rem] h-5 bg-red-500 text-white text-xs rounded-full flex items-center justify-center font-medium animate-pulse", "aria-label": `${unreadCount} unread messages`, children: unreadCount > 99 ? "99+" : unreadCount })), !isOpen && !isHovered && (jsx("div", { className: "absolute inset-0 rounded-full animate-ping opacity-30", style: { backgroundColor: color } }))] }), isHovered && !isOpen && (jsxs("div", { className: `
absolute
${position.includes("right") ? "right-0 mr-20" : "left-0 ml-20"}
${position.includes("bottom") ? "bottom-0" : "top-0"}
bg-gray-900
text-white
text-sm
px-3
py-2
rounded-lg
whitespace-nowrap
shadow-lg
opacity-90
animate-in
fade-in-0
zoom-in-95
duration-200
`, children: [displayAriaLabel, jsx("div", { className: `
absolute
w-2
h-2
bg-gray-900
transform
rotate-45
${position.includes("right") ? "-right-1" : "-left-1"}
${position.includes("bottom") ? "bottom-3" : "top-3"}
` })] }))] }));
}
export { FloatingChatButton, FloatingChatButton as default };
//# sourceMappingURL=floating-chat-button.js.map