Skip to content
Back to skills

Lynx Ui Popover

ASecurity

`lynx-ui-popover` is a headless primitive for building accessible, positioned floating elements. It handles the complex logic of positioning, stacking context, and enter/exit animations via `usePresence`.

  • 119 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 5, 2026
code-qualitygodebugging

Works with

  • cli

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned June 5, 2026

npx -y skills add lynx-family/lynx-ui --skill lynx-ui-popover --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lynx Ui Popover?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Lynx Ui Popover
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lynx-family-lynx-ui-popover/badge)](https://www.skillsdirectory.com/skills/lynx-family-lynx-ui-popover)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Lynx UI Popover SKILL

`lynx-ui-popover` is a headless primitive for building accessible, positioned floating elements. It handles the complex logic of positioning, stacking context, and enter/exit animations via `usePresence`.

## 1. Core Capabilities

- **Headless & Composable**: Provides raw functional components (`Root`, `Trigger`, `Positioner`, `Content`) that you compose to build custom UIs.
- **Auto Positioning**: The `PopoverPositioner` automatically calculates coordinates to anchor the popover to the trigger.
- **Presence Animations**: Integrated with `usePresence` lifecycle. Components mount/unmount with `entering`/`leaving` states, allowing for CSS animations.
- **Robust Visibility Modes**: Supports **Controlled** (external state) and **Uncontrolled** (internal state) modes with predictable behavior.

## 2. Behavior Contract

### Visibility Modes

- **Controlled**: Parent passes `show` prop and handles `onVisibleChange` callback.
- **Uncontrolled**: Parent passes `defaultShow`; component manages internal state.

### Presence Lifecycle

- **States**: Transitions through `Entering` -> `DelayedEntering` -> `Entered` -> `Leaving` -> `Left`.
- **Animation Safety**: Handles animation/transition **start**, **end**, and **cancel** events to ensure state never stalls.
- **Debugging**: Enable `debugLog={true}` on `PopoverRoot` to trace lifecycle state changes in the console.

### Interactions

- **Trigger**: Toggles visibility on click/tap.
- **Backdrop**: Closes popover (sets visibility to `false`) on tap. Respects "busy" lifecycle states (e.g., won't close if already animating out).

## 3. AI Coding Guide

### Minimal Usable Example

**Crucial**: Wrap `Content` and `Arrow` inside `PopoverPositioner`. Apply layout/animation styles to `Positioner`, and visual styles (background, border) to `Content`.

```tsx
import {
  PopoverRoot,
  PopoverTrigger,
  PopoverPositioner,
  PopoverContent,
  PopoverArrow,
  PopoverBackdrop,
} from '@lynx-js/lynx-ui'
import './style.css'

export default function App() {
  return (
    <PopoverRoot>
      <PopoverTrigger className='trigger'>
        <text>Open Popover</text>
      </PopoverTrigger>

      {/* Positioner handles layout and animation */}
      <PopoverPositioner className='popover-positioner' placement='bottom'>
        <PopoverBackdrop className='popover-backdrop' />
        {/* Content handles visual appearance */}
        <PopoverContent className='popover-content'>
          <text>My Popover</text>
          <PopoverArrow className='popover-arrow' />
        </PopoverContent>
      </PopoverPositioner>
    </PopoverRoot>
  )
}
```

### Recommended Prompt Formula

> **Goal**: Build a lynx-ui Popover using [controlled|uncontrolled] mode.
> **Components**: Include [Trigger], [Positioner], [Content], and optional [Backdrop/Anchor/Arrow].
> **Behavior**: Define transition [name] and set [debugLog on/off].
> **Styling Requirements**:
>
> 1. **DO** set `opacity: 0` / `scale(0)` on `.ui-closed` class (prevents flashing after exit animation).
> 2. Use CSS keyframes or transitions for enter/exit.

## 4. Use Cases & Best Practices

### Scenario 1: Animation Best Practices (Prevent Flashing)

**Problem (Exit Flash)**: When the exit animation finishes, the `ui-leaving` class is removed immediately, but the element might remain visible for one frame before `visibility: hidden` is applied.
**Solution**: Explicitly hide the element in the `ui-closed` state.

```css
/* style.css */
.popover-positioner {
  display: flex;
}

/* Entering State: Mounted -> Visible */
.popover-positioner.ui-entering {
  animation: fade-in 0.2s ease-out forwards;
}

/* Leaving State: Visible -> Unmounted */
.popover-positioner.ui-leaving {
  animation: fade-out 0.2s ease-in forwards;
}

/* Closed State: Hidden */
/* Crucial: Prevents a flash of unstyled content after exit animation ends but before unmount */
.popover-positioner.ui-closed {
  opacity: 0;
  transform: scale(0);
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
    transform: scale(1);
  }
  to {
    opacity: 0;
    transform: scale(0.9);
  }
}
```

### Scenario 2: Synchronized Arrow Animation

**Problem**: If you animate `PopoverContent` but `PopoverArrow` is outside or has its own animation, they might detach or look disconnected during scale/fade.
**Solution**: Apply the animation class to their common parent, `PopoverPositioner`.

```tsx
<PopoverPositioner className='popover-anim-container'>
  <PopoverContent className='popover-visual-box'>
    <text>Content</text>
  </PopoverContent>
  <PopoverArrow />
</PopoverPositioner>
```

## 5. FAQ

**Q: Why doesn't the Arrow animate with the Content?**
A: Ensure you are animating the `PopoverPositioner` (which contains both), not just the `PopoverContent`.

**Q: Can I use CSS Transitions instead of Animations?**
A: Yes, and it is often smoother for simple fades because transitions interpolate from the _current_ value when interrupted, whereas animations reset.

## 6. Sub Components

- **PopoverRoot**: Context provider, manages visibility state.
- **PopoverTrigger**: The element that toggles the popover.
- **PopoverPositioner**: The floating container that positions itself relative to the trigger. **Apply animations here.**
- **PopoverContent**: The visual box for your content.
- **PopoverArrow**: The triangle pointing to the trigger.
- **PopoverBackdrop**: An overlay behind the popover (often used for dimming or click-outside).

Files in this skill

  • CHANGELOG.md2.8 KB
  • LICENSE11.1 KB
  • README.md1.7 KB
  • README_zh.md944 B
  • SKILL.md5.5 KB
  • docs/APIReference.mdx22.3 KB
  • docs/README.mdx260 B
  • docs/README.zh.mdx267 B
  • package.json1.3 KB
  • rslib.config.ts338 B
  • src/Popover.tsx14.7 KB
  • src/floating/arrow.tsx4.2 KB
  • src/floating/computeCoordsFromPlacement.tsx2.8 KB
  • src/floating/computeFloating.tsx1.1 KB
  • src/floating/computePosition.tsx2.6 KB
  • src/floating/detectOverflow.tsx1.8 KB
  • src/floating/floatingTypes.ts7.2 KB
  • src/floating/index.tsx433 B
  • src/floating/offset.tsx2.1 KB
  • src/floating/platform.tsx1.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.