-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
Blocked by:
Implement a compound Popover component for Video.js 10, providing the foundation for tooltips, menus, and other floating UI elements.
The Popover handles:
- Positioning: Anchor-based positioning with CSS Anchor Positioning (fallback to Floating UI)
- Interactions: Hover, focus, and click triggers with configurable delays
- Transitions/Animations: CSS-driven via data attributes, supports both
transitionand@keyframes - Safe polygons: Prevents accidental close when moving pointer from trigger to popup
- Collision avoidance: Keeps popup within specified boundaries
Usage
React
<Popover.Root openOnHover delay={200}>
<Popover.Trigger>
<button>Hover me</button>
</Popover.Trigger>
<Popover.Portal>
<Popover.Positioner placement="top" sideOffset={8}>
<Popover.Popup>
<Popover.Arrow />
Popover content
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>HTML
<button popovertarget="my-popover">Hover me</button>
<media-popover
id="my-popover"
open-on-hover
delay="200"
placement="top"
side-offset="8"
>
Popover content
</media-popover>API
Tasks
Core (@videojs/core)
- Implement
PopoverCoreextendingComponentCorebase class - Element ref setters using
ElementNodetype (React Native compatible subset of DOM) - Open/close/toggle methods with callback invocation
- Interaction handlers for pointer, focus, and keyboard events
- Position computation using Floating UI (
offset,flip,shift,hidemiddleware) - Transition state machine (
closed → initial → open → closing → closed) - Safe polygon calculation for hover intent (port from Floating UI)
- Timer management for hover delays
Callouts:
- Element refs stored on class instance, not in state
- No DOM APIs in core—use
ElementNodeinterface withgetBoundingClientRect()andcontains()notifyTransitionEnd()method for frameworks to call when CSS animations/transitions complete
DOM (@videojs/core/dom)
- Define data attributes and css vars interfaces for each part.
-
getPopoverTriggerProps()returning ARIA attrs and anchor styles -
getPopoverPopupProps()returning data attributes and positioning styles - Feature detection for CSS anchor positioning support
- Two style outputs: CSS anchor positioning (when supported) and Floating UI fallback
Callouts:
- Data attributes for CSS:
data-open,data-closed,data-starting-style,data-ending-style,data-side- Fallback required—CSS anchor positioning only ~75% browser support
React (@videojs/react)
- Context for sharing core instance and state across compound parts
-
Popover.Root— Provider, instantiates core, syncs props/callbacks -
Popover.Trigger— Clones child with trigger props and event handlers -
Popover.Portal— Optional portal rendering -
Popover.Positioner— Positioning wrapper, sets collision boundary -
Popover.Popup— Main popup element with animation detection - Animation/transition end detection hook that calls
core.notifyTransitionEnd()
Callouts:
- Support both controlled (
openprop) and uncontrolled (defaultOpen) modes- Must detect completion of both CSS transitions AND @Keyframes animations
HTML (@videojs/html)
-
<media-popover>custom element with observed attributes - Lifecycle management (create/destroy core, subscribe/unsubscribe)
- Trigger discovery via
[popovertarget="${id}"]selector - Collision boundary discovery via
closest('[data-media-container]') - Animation end listeners for transition completion
Testing
- Core unit tests
- Add conformance suite
- Add React conformance test
- Add HTML conformance test
Documentation
- Create
/docs/html/components/popoverdocs page. Include demos, anatomy, examples, and API reference. - Create
/docs/react/components/popoverdocs page. Include demos, anatomy, examples, and API reference.
Acceptance Criteria
- Opens/closes via click, hover, and focus
- Configurable delays work correctly
- Collision detection keeps popover within bounds
- CSS anchor positioning used when supported, Floating UI fallback otherwise
- Both CSS transitions and
@keyframesanimations work -
onOpenChangeCompletefires after animations finish - React and HTML produce identical DOM structure
- Safe polygon prevents accidental close
- Core has no DOM dependencies (uses
ElementNodeinterface)
References
- Base UI Popover - Primary API reference
- Popover Attribute
- CSS Anchor Positioning - ~75% support, progressive enhancement
- Floating UI - Positioning engine (fallback)
- Component Behavior Definitions & Hooks #198
- Notion: Core Design Doc
Metadata
Metadata
Assignees
Type
Projects
Status
No status