A beautiful, draggable floating panel component for React with smart opacity and smooth animations
npm install @opengspace/react-hover-panel> A beautiful, draggable floating panel component for React with smart opacity, smooth animations, and modern design.



- 🎨 Modern Design - Clean, beautiful panel with rounded corners and subtle shadows
- 🎯 Draggable - Drag the panel freely in both X and Y axes using the iPhone X-style drag bar
- 👁️ Smart Opacity - Automatically fades when idle, becomes fully visible on hover/drag
- 📱 Responsive - Adapts to mobile devices with touch support
- 🎭 Icon Regions - 5 customizable icon regions with tooltips (top-left, top-center, top-right, bottom-left, bottom-right)
- ⚡ Smooth Animations - GPU-accelerated with 60fps performance using requestAnimationFrame
- 🔒 Boundary Control - Keeps panel within viewport with configurable edge margins
- 🎪 Portal Tooltips - Tooltips render outside the panel to prevent event interference
- ⚙️ Highly Customizable - Extensive props for customization
``bash`
npm install @opengspace/react-hover-panelor
yarn add @opengspace/react-hover-panelor
pnpm add @opengspace/react-hover-panel
`jsx
import React from 'react';
import FloatingPanel from '@opengspace/react-hover-panel';
function App() {
return (
onClose={() => console.log('Panel closed')}
topLeft={{ icon: ⌂, tooltip: 'Home' }}
bottomLeft={{ icon: ⚙, tooltip: 'Settings' }}
>
This is a draggable floating panel.
📖 Props
$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
width | number \| string | 360 | Width of the panel (px or CSS value) |
| topPadding | number | 20 | Top padding from window edge (px) |
| bottomPadding | number | 20 | Bottom padding from window edge (px) |
| edgeMargin | number | 20 | Minimum distance from window edges (px) |$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
draggable | boolean | true | Enable/disable dragging |
| defaultPosition | { x: number, y: number } | undefined | Initial position |
| boundary | 'window' \| 'parent' \| 'none' | 'window' | Boundary constraint for dragging |$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
idleOpacity | number | 0.7 | Opacity when panel is idle (0-1) |
| activeOpacity | number | 1.0 | Opacity when panel is active (0-1) |
| opacityTransitionDuration | number | 300 | Transition duration in ms |
| roundedCorners | boolean | true | Enable/disable rounded corners |
| shadow | boolean | true | Enable/disable shadow |
| zIndex | number | 1000 | z-index of the panel |$3
Each icon region accepts either:
- A React element (just the icon)
- An object
{ icon: ReactElement, tooltip: string }| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
topLeft | ReactElement \| { icon: ReactElement, tooltip: string } | - | Icon for top-left corner |
| topCenter | ReactElement \| { icon: ReactElement, tooltip: string } | - | Icon for top-center |
| topRight | ReactElement \| { icon: ReactElement, tooltip: string } | - | Icon for top-right corner |
| bottomLeft | ReactElement \| { icon: ReactElement, tooltip: string } | - | Icon for bottom-left corner |
| bottomRight | ReactElement \| { icon: ReactElement, tooltip: string } | - | Icon for bottom-right corner |$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
onClose | () => void | - | Callback when close button is clicked (replaces top-right icon) |$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
onDragStart | () => void | - | Callback when dragging starts |
| onDragEnd | (position: { x: number, y: number }) => void | - | Callback when dragging ends |
| onVisibilityChange | (isVisible: boolean) => void | - | Callback when visibility changes (hover/drag) |$3
| Prop | Type | Default | Description |
|------|------|---------|-------------|
|
className | string | '' | Additional CSS class names |
| style | CSSProperties | {} | Additional inline styles |
| ref | RefObject | - | Forwarded ref |💡 Usage Examples
$3
`jsx
width={400}
onClose={() => setShowPanel(false)}
>
Basic Panel
Drag the bar at the top to move this panel around!
`$3
`jsx
width={380}
topLeft={{ icon: 🏠, tooltip: 'Home' }}
topCenter={{ icon: ⋯, tooltip: 'Menu' }}
topRight={{ icon: ⋮, tooltip: 'More options' }}
bottomLeft={{ icon: ⚙️, tooltip: 'Settings' }}
bottomRight={{ icon: ℹ️, tooltip: 'Help' }}
>
Panel with Icons
Hover over the icons to see tooltips!
`$3
`jsx
width={420}
idleOpacity={0.3}
activeOpacity={1.0}
roundedCorners={true}
shadow={true}
zIndex={2000}
className="my-custom-panel"
style={{ border: '2px solid #667eea' }}
>
Custom Styled Panel
Customize opacity, corners, shadows, and more!
`$3
`jsx
const handleDragStart = () => {
console.log('Drag started');
};const handleDragEnd = (position) => {
console.log('Drag ended at:', position);
};
const handleVisibilityChange = (isVisible) => {
console.log('Panel is', isVisible ? 'visible' : 'idle');
};
width={380}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
onVisibilityChange={handleVisibilityChange}
>
Panel with Events
Check the console for event logs!
`$3
`jsx
width={400}
topLeft={{ icon: 👤, tooltip: 'Profile' }}
onClose={() => setShowPanel(false)}
>
User Profile
type="text"
placeholder="Username"
style={{
width: '100%',
padding: '10px',
marginBottom: '12px',
border: '1px solid #ddd',
borderRadius: '8px'
}}
/>
placeholder="Bio"
style={{
width: '100%',
padding: '10px',
border: '1px solid #ddd',
borderRadius: '8px',
minHeight: '100px'
}}
/>
style={{
width: '100%',
padding: '12px',
background: '#667eea',
color: 'white',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
marginTop: '12px'
}}
>
Save
`🎨 Customization
$3
The component uses the following CSS classes that you can override:
-
.floating-panel - Main panel container
- .floating-panel-header - Header area with drag bar
- .floating-panel-main - Main content area (scrollable)
- .floating-panel-footer - Footer area
- .drag-bar - iPhone X-style drag bar
- .panel-icon - Icon containers
- .tooltip - Tooltip elements$3
`css
/ Override drag bar color /
.floating-panel .drag-bar {
background: rgba(102, 126, 234, 0.3);
}/ Custom panel background /
.floating-panel {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
/ Custom scrollbar /
.floating-panel-main::-webkit-scrollbar {
width: 8px;
}
.floating-panel-main::-webkit-scrollbar-thumb {
background: #667eea;
border-radius: 4px;
}
`🌐 Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
📝 License
MIT © opengspace
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📧 Support
For issues and questions, please visit our GitHub Issues.
🔗 Links
- Live Demo: https://opengspace.github.io/react-hover-panel/
- GitHub Repository
- NPM Package
- Issues
🚀 Automatic Deployment
This project uses GitHub Actions to automatically deploy the demo to GitHub Pages on every push to the
main` branch. See DEPLOYMENT.md for details.---
Made with ❤️ by opengspace