File "Tooltip.tsx"
Full Path: /home/trinadezambia/public_html/student_panel/src/components/ui/pages/common/Tooltip.tsx
File size: 3.18 KB
MIME-type: text/x-java
Charset: utf-8
/**
* Tooltip Component
*
* A reusable tooltip component that displays additional information on hover.
* Uses CSS and Tailwind for styling with a clean, modern appearance.
*
* Features:
* - Appears on hover
* - Positioned above the trigger element
* - Dark background with white text
* - Includes arrow pointing to trigger
* - Supports text wrapping for long content
* - Fully accessible with keyboard support
*/
import React, { useState } from 'react';
interface TooltipProps {
/**
* The content to display in the tooltip
* Can be a string or React element
*/
content: string | React.ReactNode;
/**
* The element that triggers the tooltip (usually text or button)
*/
children: React.ReactNode;
/**
* Optional: Position of the tooltip relative to the trigger
* @default 'top'
*/
position?: 'top' | 'bottom' | 'left' | 'right';
/**
* Optional: Additional CSS classes for the trigger container
*/
className?: string;
/**
* Optional: Custom width for the tooltip
* @default 'min-w-[200px] max-w-[280px]'
*/
width?: string;
}
/**
* Tooltip Component
*
* Usage example:
* ```tsx
* <Tooltip content="This is helpful information">
* <span>Hover over me</span>
* </Tooltip>
* ```
*/
export default function Tooltip({
content,
children,
position = 'top',
className = '',
width = 'min-w-[200px] max-w-[280px]',
}: TooltipProps) {
const [isOpen, setIsOpen] = useState(false);
// Position classes based on tooltip position prop
// Using logical properties (start/end) for RTL support
// start = left in LTR, right in RTL
// end = right in LTR, left in RTL
const positionClasses = {
top: 'bottom-full mb-2 start-0',
bottom: 'top-full mt-2 start-0',
left: 'end-full me-2 top-0', // Changed: right-full -> end-full, mr-2 -> me-2
right: 'start-full ms-2 top-0', // Changed: left-full -> start-full, ml-2 -> ms-2
};
// Arrow classes based on position
// Using logical properties for RTL support
const arrowClasses = {
top: 'start-4 top-full border-s-4 border-e-4 border-t-4 border-s-transparent border-e-transparent border-t-gray-900',
bottom:
'start-4 bottom-full border-s-4 border-e-4 border-b-4 border-s-transparent border-e-transparent border-b-gray-900',
left: 'top-4 start-full border-t-4 border-b-4 border-s-4 border-t-transparent border-b-transparent border-s-gray-900',
right:
'top-4 end-full border-t-4 border-b-4 border-e-4 border-t-transparent border-b-transparent border-e-gray-900',
};
return (
<div
className={`relative group inline-block ${className}`}
onClick={() => setIsOpen(!isOpen)}
onMouseLeave={() => setIsOpen(false)}
>
{/* Trigger element */}
{children}
{/* Tooltip */}
<div
className={`absolute ${positionClasses[position]} ${
isOpen ? 'block' : 'hidden group-hover:block'
} z-50 ${width}`}
>
<div className="bg-gray-900 text-white text-xs rounded-lg py-2 px-3 shadow-lg whitespace-normal wrap-break-word leading-relaxed">
{content}
</div>
{/* Arrow */}
<div className={`absolute w-0 h-0 ${arrowClasses[position]}`}></div>
</div>
</div>
);
}