@shakibdshy/react-popover-pro v1.0.3
React Popover Pro
A modern, accessible, and highly customizable popover and tooltip library for React applications.
Demo
📚 Table of Contents
- Introduction
- Installation
- Getting Started
- Popover Component
- Tooltip Component
- Advanced Usage
- Accessibility
- Browser Support
- Contributing
- License
🚀 Introduction
React Popover Pro provides accessible and customizable popover and tooltip components for React applications. The library is designed with flexibility, performance, and accessibility in mind, making it suitable for a wide range of use cases from simple tooltips to complex dropdown menus.
Key Features
- 🌟 Fully accessible with proper ARIA attributes and keyboard navigation
- 🎯 Multiple placement options with automatic positioning
- 🎨 Customizable appearance with built-in variants and animation effects
- 🔄 Smart positioning that keeps popovers within viewport
- ⌨️ Keyboard navigation support for improved accessibility
- 🔍 Focus management for better user experience
- 🖼️ Portal support for proper stacking in complex layouts
- 📱 Responsive design that works on all screen sizes
📦 Installation
# Using npm
npm install @shakibdshy/react-popover-pro
# Using yarn
yarn add @shakibdshy/react-popover-pro
# Using pnpm
pnpm add @shakibdshy/react-popover-pro
# Using bun
bun add @shakibdshy/react-popover-pro
Import Styles
Make sure to import the CSS styles in your application:
// Import the styles in your main file (e.g., main.tsx, App.tsx, or layout.tsx)
import "@shakibdshy/react-popover-pro/style.css";
🏁 Getting Started
Basic Popover
Here's a simple example of how to use the Popover component:
import { Popover, PopoverTrigger, PopoverContent } from '@shakibdshy/react-popover-pro';
function MyComponent() {
return (
<Popover>
<PopoverTrigger>
<button>Click me</button>
</PopoverTrigger>
<PopoverContent>
<div>This is the popover content</div>
</PopoverContent>
</Popover>
);
}
Basic Tooltip
For simple hover tooltips, you can use the Tooltip component:
import { Tooltip } from '@shakibdshy/react-popover-pro';
function MyComponent() {
return (
<Tooltip content="This is a tooltip">
<button>Hover me</button>
</Tooltip>
);
}
🧩 Popover Component
The Popover component is a flexible and powerful component that can be used to create tooltips, dropdowns, menus, and more.
Component Structure
The Popover component uses a compound component pattern with three main parts:
<Popover>
- The main container component that manages state and context<PopoverTrigger>
- The element that triggers the popover<PopoverContent>
- The content that appears when the popover is triggered
Popover Props
Here are the main props for the <Popover>
component:
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | - | The trigger and content components |
placement | PopoverPlacement | 'bottom' | Where the popover should appear relative to the trigger |
offset | number | 8 | Distance between the popover and trigger (in pixels) |
defaultOpen | boolean | false | Whether the popover is open by default (uncontrolled mode) |
open | boolean | - | Controlled open state |
onOpenChange | function | - | Callback when open state changes |
triggerMode | 'click' | 'hover' | 'context-menu' | 'click' | How the popover is triggered |
animate | boolean | true | Whether to animate the popover |
animationDuration | number | 200 | Duration of animation in milliseconds |
animationEffect | AnimationEffect | 'fade' | Animation effect to use |
arrow | boolean | false | Whether to show an arrow pointing to the trigger |
portal | boolean | true | Whether to render in a portal |
autoPlacement | boolean | true | Whether to automatically adjust placement to fit viewport |
variant | 'primary' | 'info' | 'success' | 'warning' | 'danger' | - | Visual style variant |
Placement Options
The placement
prop accepts the following values:
- Basic placements:
'top'
,'right'
,'bottom'
,'left'
- Alignment variations:
'top-start'
,'top-end'
,'right-start'
,'right-end'
,'bottom-start'
,'bottom-end'
,'left-start'
,'left-end'
<Popover placement="top-start">
{/* ... */}
</Popover>
Trigger Modes
The triggerMode
prop determines how the popover is activated:
'click'
- Opens on click, closes on click outside or on trigger'hover'
- Opens on hover, closes when cursor leaves'context-menu'
- Opens on right-click (context menu)
<Popover triggerMode="hover" openDelay={200} closeDelay={150}>
{/* ... */}
</Popover>
Animation Effects
The animationEffect
prop accepts various animation types:
'fade'
- Simple opacity transition'scale'
,'scale-subtle'
,'scale-extreme'
- Grows/shrinks from origin point'shift-away'
,'shift-away-subtle'
,'shift-away-extreme'
- Slides away from origin'shift-toward'
,'shift-toward-subtle'
,'shift-toward-extreme'
- Slides toward origin'perspective'
,'perspective-subtle'
,'perspective-extreme'
- 3D rotation effect
<Popover
animate={true}
animationDuration={300}
animationEffect="scale"
>
{/* ... */}
</Popover>
Styling & Variants
The popover comes with built-in color variants:
- Default (no variant specified) - Neutral gray
'primary'
- Blue, suitable for primary actions'info'
- Cyan, suitable for informational content'success'
- Green, suitable for success messages'warning'
- Amber, suitable for warning messages'danger'
- Red, suitable for error messages
<Popover variant="primary" arrow={true}>
{/* ... */}
</Popover>
🎯 Tooltip Component
The Tooltip component is a simplified wrapper around the Popover component, optimized for hover tooltips.
Tooltip Props
The Tooltip component accepts all the same props as the Popover component, plus:
Prop | Type | Default | Description |
---|---|---|---|
content | ReactNode | - | The content to display in the tooltip |
maxWidth | number | string | 250 | Maximum width of the tooltip |
className | string | - | Additional CSS class for the tooltip |
Tooltip Examples
Basic Tooltip
<Tooltip content="This is a tooltip">
<button>Hover me</button>
</Tooltip>
Tooltip with Rich Content
<Tooltip
content={
<div>
<h3>Rich Content</h3>
<p>Tooltips can contain rich HTML content</p>
</div>
}
maxWidth={300}
>
<button>Hover for rich content</button>
</Tooltip>
Tooltip with Custom Placement and Animation
<Tooltip
content="This tooltip appears on the right with a scale animation"
placement="right"
animationEffect="scale"
animationDuration={300}
>
<button>Custom Tooltip</button>
</Tooltip>
Color Variants
<Tooltip
content="This is a success tooltip"
variant="success"
arrow={true}
>
<button>Success Tooltip</button>
</Tooltip>
🔧 Advanced Usage
Controlled Mode
You can control the open state of the popover manually:
import { useState } from 'react';
import { Popover, PopoverTrigger, PopoverContent } from '@shakibdshy/react-popover-pro';
function ControlledPopover() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(true)}>
Open popover from outside
</button>
<Popover
open={isOpen}
onOpenChange={setIsOpen}
>
<PopoverTrigger>
<button>Controlled Trigger</button>
</PopoverTrigger>
<PopoverContent>
<div>
<p>This is a controlled popover</p>
<button onClick={() => setIsOpen(false)}>Close</button>
</div>
</PopoverContent>
</Popover>
</>
);
}
Custom Hooks
React Popover Pro exports several hooks that you can use to build custom implementations:
import {
useHover,
useAnimation,
useAutoPlacement,
usePopoverPosition,
useArrowPosition,
useFocusManagement
} from '@shakibdshy/react-popover-pro';
function CustomImplementation() {
const triggerRef = useRef(null);
const isHovering = useHover(triggerRef, 200, 150);
// Use other hooks as needed for your custom implementation
return (
<div>
<button ref={triggerRef}>
Hover me for custom behavior
</button>
{isHovering && (
<div className="custom-popover">
Custom popover content
</div>
)}
</div>
);
}
Custom Animations
You can customize the animation timing and effect:
<Popover
animate={true}
animationDuration={400}
animationTiming="cubic-bezier(0.34, 1.56, 0.64, 1)"
animationEffect="perspective-extreme"
>
{/* ... */}
</Popover>
Nested Popovers
You can nest popovers inside each other:
<Popover>
<PopoverTrigger>
<button>Open first popover</button>
</PopoverTrigger>
<PopoverContent>
<div>
<p>First popover content</p>
<Popover>
<PopoverTrigger>
<button>Open nested popover</button>
</PopoverTrigger>
<PopoverContent>
<p>Nested popover content</p>
</PopoverContent>
</Popover>
</div>
</PopoverContent>
</Popover>
Virtual Elements
You can position a popover relative to a virtual element (like a cursor position):
import { useState, useCallback } from 'react';
import { Popover, PopoverContent } from '@shakibdshy/react-popover-pro';
function CursorPopover() {
const [position, setPosition] = useState({ x: 0, y: 0 });
const [isOpen, setIsOpen] = useState(false);
const handleMouseMove = useCallback((e) => {
setPosition({ x: e.clientX, y: e.clientY });
}, []);
const virtualRef = {
getBoundingClientRect: () => ({
width: 0,
height: 0,
top: position.y,
right: position.x,
bottom: position.y,
left: position.x,
x: position.x,
y: position.y,
}),
};
return (
<div
onMouseMove={handleMouseMove}
onContextMenu={(e) => {
e.preventDefault();
setIsOpen(true);
}}
style={{ height: '300px', border: '1px solid #ccc' }}
>
Right-click anywhere in this area
<Popover
open={isOpen}
onOpenChange={setIsOpen}
virtualRef={virtualRef}
triggerMode="context-menu"
>
<PopoverContent>
<div>Context menu content</div>
</PopoverContent>
</Popover>
</div>
);
}
Custom Positioning
You can use middleware functions to customize positioning:
import { Popover, PopoverTrigger, PopoverContent } from '@shakibdshy/react-popover-pro';
import { shift, offset } from '@shakibdshy/react-popover-pro/middleware';
function CustomPositionedPopover() {
return (
<Popover
middleware={[
offset(16), // 16px offset from trigger
shift({ padding: 8 }), // 8px padding from viewport edges
]}
>
<PopoverTrigger>
<button>Custom Positioned Popover</button>
</PopoverTrigger>
<PopoverContent>
<div>This popover has custom positioning</div>
</PopoverContent>
</Popover>
);
}
♿ Accessibility
React Popover Pro is built with accessibility in mind:
- Proper ARIA attributes (
role
,aria-expanded
,aria-haspopup
, etc.) - Keyboard navigation support (Tab, Escape, Arrow keys)
- Focus management (auto-focus, focus trap, return focus)
- Screen reader friendly
- High contrast mode support
🌐 Browser Support
React Popover Pro supports all modern browsers:
- Chrome (and Chromium-based browsers like Edge)
- Firefox
- Safari
- Opera
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.