# Popover

## Description

A floating popover component that displays content in an overlay positioned relative to a target element. Provides flexible positioning options, trigger actions, alignment controls, and accessibility features for creating tooltips, dropdown menus, contextual information panels, and interactive overlays.

## Aliases

- Popover
- Tooltip
- Dropdown
- Overlay
- FloatingPanel
- Callout

## Props Breakdown

**Extends:** Standalone interface (no HTML element inheritance)

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `content` | `ReactNode` | - | Yes | The content to display in the popover |
| `target` | `ReactNode` | - | Yes | The target element that triggers the popover |
| `container` | `HTMLElement \| React.RefObject<HTMLElement> \| null` | - | No | Container element for the popover to render in |
| `show` | `boolean` | `false` | No | Controls popover visibility |
| `action` | `'Click' \| 'Hover' \| 'DoubleClick'` | `'Click'` | No | Action type to trigger the popover |
| `direction` | `'Up' \| 'Down' \| 'Right' \| 'Left'` | `'Down'` | No | Direction in which the popover should open |
| `alignment` | `'Start' \| 'End' \| 'Center'` | `'Center'` | No | Alignment of the popover relative to target |
| `offset` | `Offset` | - | No | Offset for positioning the popover |
| `onOpen` | `() => void` | - | No | Callback function invoked when popover opens |
| `onHide` | `() => void` | - | No | Callback function invoked when popover hides |
| `hideOnClickAway` | `boolean` | `true` | No | Whether popover should hide on click away |
| `keepContentOnItemClick` | `boolean` | `false` | No | Whether content should stay on item click |
| `disabled` | `boolean` | `false` | No | Whether the popover is disabled |
| `flip` | `boolean` | `false` | No | Whether content should change placement to stay on screen |
| `contentPosition` | `'absolute' \| 'fixed'` | `'absolute'` | No | Position strategy for the popover |
| `contentProps` | `ContentProps` | - | No | Props for the content container |
| `className` | `string` | - | No | Additional CSS class names for the target |
| `overlayClassName` | `string` | - | No | Additional CSS class names for the overlay |

## Examples

### Basic Usage
```tsx
import { Popover, Button, Text } from '@delightui/components';

function BasicExample() {
  return (
    <Popover
      target={<Button>Show Popover</Button>}
      content={
        <div className="popover-content">
          <Text>This is a basic popover with simple content.</Text>
        </div>
      }
    />
  );
}
```

### Controlled Popover
```tsx
function ControlledExample() {
  const [showPopover, setShowPopover] = useState(false);

  return (
    <Popover
      target={
        <Button onClick={() => setShowPopover(!showPopover)}>
          Toggle Popover
        </Button>
      }
      content={
        <div className="controlled-popover">
          <Text type="Heading6">Controlled Popover</Text>
          <Text>This popover is controlled by state.</Text>
          <Button 
            size="Small" 
            onClick={() => setShowPopover(false)}
          >
            Close
          </Button>
        </div>
      }
      show={showPopover}
      onHide={() => setShowPopover(false)}
    />
  );
}
```

### Hover Trigger
```tsx
function HoverExample() {
  return (
    <Popover
      target={
        <div className="hover-target">
          <Icon icon="Info" />
          <Text>Hover for info</Text>
        </div>
      }
      content={
        <div className="info-popover">
          <Text type="Heading6">Additional Information</Text>
          <Text>
            This popover appears when you hover over the target element.
            It's perfect for tooltips and contextual help.
          </Text>
        </div>
      }
      action="Hover"
      direction="Up"
      alignment="Center"
    />
  );
}
```

### Dropdown Menu
```tsx
function DropdownMenuExample() {
  const handleMenuAction = (action) => {
    console.log(`Menu action: ${action}`);
  };

  const menuContent = (
    <div className="dropdown-menu">
      <button 
        className="menu-item"
        onClick={() => handleMenuAction('edit')}
      >
        <Icon icon="Edit" />
        <Text>Edit</Text>
      </button>
      <button 
        className="menu-item"
        onClick={() => handleMenuAction('copy')}
      >
        <Icon icon="Copy" />
        <Text>Copy</Text>
      </button>
      <button 
        className="menu-item destructive"
        onClick={() => handleMenuAction('delete')}
      >
        <Icon icon="Delete" />
        <Text>Delete</Text>
      </button>
    </div>
  );

  return (
    <Popover
      target={
        <Button type="Ghost">
          <Icon icon="MoreVertical" />
        </Button>
      }
      content={menuContent}
      direction="Down"
      alignment="End"
      hideOnClickAway={true}
    />
  );
}
```

### Form Popover
```tsx
function FormPopoverExample() {
  const [formData, setFormData] = useState({ name: '', email: '' });

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Form submitted:', formData);
  };

  const formContent = (
    <div className="form-popover">
      <Text type="Heading6">Quick Contact</Text>
      
      <form onSubmit={handleSubmit}>
        <FormField name="name" label="Name">
          <Input 
            value={formData.name}
            onChange={(e) => setFormData(prev => ({
              ...prev, 
              name: e.target.value
            }))}
            placeholder="Your name"
          />
        </FormField>
        
        <FormField name="email" label="Email">
          <Input 
            type="email"
            value={formData.email}
            onChange={(e) => setFormData(prev => ({
              ...prev, 
              email: e.target.value
            }))}
            placeholder="your@email.com"
          />
        </FormField>
        
        <div className="form-actions">
          <Button type="Outlined" size="Small">
            Cancel
          </Button>
          <Button actionType="submit" size="Small">
            Submit
          </Button>
        </div>
      </form>
    </div>
  );

  return (
    <Popover
      target={<Button>Contact Form</Button>}
      content={formContent}
      direction="Down"
      alignment="Start"
      keepContentOnItemClick={true}
      contentProps={{ width: '300px' }}
    />
  );
}
```

### User Profile Popover
```tsx
function UserProfileExample() {
  const user = {
    name: 'John Doe',
    email: 'john@example.com',
    avatar: '/avatars/john.jpg',
    role: 'Administrator'
  };

  const profileContent = (
    <div className="profile-popover">
      <div className="profile-header">
        <Image 
          src={user.avatar} 
          alt={user.name}
          className="profile-avatar"
        />
        <div className="profile-info">
          <Text type="Heading6">{user.name}</Text>
          <Text type="BodySmall" className="profile-email">
            {user.email}
          </Text>
          <Chip size="Small" style="Neutral">
            {user.role}
          </Chip>
        </div>
      </div>
      
      <div className="profile-actions">
        <Button type="Ghost" size="Small">
          <Icon icon="User" />
          View Profile
        </Button>
        <Button type="Ghost" size="Small">
          <Icon icon="Settings" />
          Settings
        </Button>
        <Button type="Ghost" size="Small">
          <Icon icon="Logout" />
          Sign Out
        </Button>
      </div>
    </div>
  );

  return (
    <Popover
      target={
        <Button type="Ghost" className="profile-trigger">
          <Image 
            src={user.avatar} 
            alt={user.name}
            className="trigger-avatar"
          />
        </Button>
      }
      content={profileContent}
      direction="Down"
      alignment="End"
      contentProps={{ width: '280px' }}
    />
  );
}
```

### Notification Popover
```tsx
function NotificationPopoverExample() {
  const [notifications, setNotifications] = useState([
    { id: 1, message: 'New message from Sarah', time: '2 min ago', read: false },
    { id: 2, message: 'Project deadline approaching', time: '1 hour ago', read: false },
    { id: 3, message: 'Weekly report generated', time: '3 hours ago', read: true }
  ]);

  const markAsRead = (id) => {
    setNotifications(prev => 
      prev.map(notif => 
        notif.id === id ? { ...notif, read: true } : notif
      )
    );
  };

  const unreadCount = notifications.filter(n => !n.read).length;

  const notificationContent = (
    <div className="notification-popover">
      <div className="notification-header">
        <Text type="Heading6">Notifications</Text>
        {unreadCount > 0 && (
          <Chip size="Small" style="Primary">
            {unreadCount} new
          </Chip>
        )}
      </div>
      
      <div className="notification-list">
        {notifications.map(notification => (
          <div 
            key={notification.id}
            className={`notification-item ${notification.read ? 'read' : 'unread'}`}
            onClick={() => markAsRead(notification.id)}
          >
            <Text type="BodySmall">{notification.message}</Text>
            <Text type="Caption" className="notification-time">
              {notification.time}
            </Text>
          </div>
        ))}
      </div>
      
      <div className="notification-footer">
        <Button type="Ghost" size="Small">
          View All
        </Button>
      </div>
    </div>
  );

  return (
    <Popover
      target={
        <Button type="Ghost" className="notification-trigger">
          <Icon icon="Bell" />
          {unreadCount > 0 && (
            <span className="notification-badge">{unreadCount}</span>
          )}
        </Button>
      }
      content={notificationContent}
      direction="Down"
      alignment="End"
      contentProps={{ width: '320px', maxHeight: '400px' }}
    />
  );
}
```

### Rich Content Popover
```tsx
function RichContentExample() {
  const productInfo = {
    name: 'Premium Wireless Headphones',
    price: '$299.99',
    rating: 4.8,
    image: '/products/headphones.jpg',
    features: ['Noise Cancellation', 'Wireless', '30hr Battery']
  };

  const richContent = (
    <div className="product-popover">
      <div className="product-image">
        <Image 
          src={productInfo.image} 
          alt={productInfo.name}
          fit="Cover"
        />
      </div>
      
      <div className="product-details">
        <Text type="Heading6">{productInfo.name}</Text>
        
        <div className="product-rating">
          <div className="stars">
            {[...Array(5)].map((_, i) => (
              <Icon 
                key={i}
                icon={i < Math.floor(productInfo.rating) ? 'StarFilled' : 'StarOutlined'} 
                className="star"
              />
            ))}
          </div>
          <Text type="BodySmall">({productInfo.rating})</Text>
        </div>
        
        <Text type="Heading5" className="product-price">
          {productInfo.price}
        </Text>
        
        <div className="product-features">
          {productInfo.features.map(feature => (
            <Chip key={feature} size="Small" style="Neutral">
              {feature}
            </Chip>
          ))}
        </div>
        
        <div className="product-actions">
          <Button size="Small">Add to Cart</Button>
          <Button type="Outlined" size="Small">
            <Icon icon="Heart" />
          </Button>
        </div>
      </div>
    </div>
  );

  return (
    <Popover
      target={
        <div className="product-preview">
          <Image 
            src={productInfo.image} 
            alt={productInfo.name}
            className="preview-image"
          />
          <Text>Hover for details</Text>
        </div>
      }
      content={richContent}
      action="Hover"
      direction="Right"
      alignment="Center"
      contentProps={{ width: '350px' }}
      flip={true}
    />
  );
}
```

### Multi-position Popover
```tsx
function MultiPositionExample() {
  const [position, setPosition] = useState('Down');
  const [alignment, setAlignment] = useState('Center');

  const positions = ['Up', 'Down', 'Left', 'Right'];
  const alignments = ['Start', 'Center', 'End'];

  const configContent = (
    <div className="config-popover">
      <Text type="Heading6">Popover Configuration</Text>
      
      <div className="config-section">
        <Text type="BodySmall">Position:</Text>
        <div className="button-group">
          {positions.map(pos => (
            <Button
              key={pos}
              size="Small"
              type={position === pos ? 'Primary' : 'Ghost'}
              onClick={() => setPosition(pos)}
            >
              {pos}
            </Button>
          ))}
        </div>
      </div>
      
      <div className="config-section">
        <Text type="BodySmall">Alignment:</Text>
        <div className="button-group">
          {alignments.map(align => (
            <Button
              key={align}
              size="Small"
              type={alignment === align ? 'Primary' : 'Ghost'}
              onClick={() => setAlignment(align)}
            >
              {align}
            </Button>
          ))}
        </div>
      </div>
      
      <Text type="Caption">
        Current: {position} / {alignment}
      </Text>
    </div>
  );

  return (
    <div className="center-container">
      <Popover
        target={<Button>Configure Popover</Button>}
        content={configContent}
        direction={position}
        alignment={alignment}
        keepContentOnItemClick={true}
        contentProps={{ width: '280px' }}
      />
    </div>
  );
}
```