Radix UIKeyframes
Popover
Origin resolves from the popper variable first, so the panel grows out of the trigger corner rather than its own centre.
Every value the manifest allows on this host, single presets and the pairs that compose. The first is what this component ships with. Both stages are the same component, so anything that changes between them is the attribute.
withoutno attribute
with easefuldata-motion="scale-fade"
host writes
data-state, data-side, --radix-popper-transform-origin
easeful matches
[data-motion][data-side] { transform-origin: <popper origin> }
what runs
animation + transform-origin from the trigger
you write
<Popover.Content data-motion="scale-fade" />
Where the attribute goes
The parts this demo composes, and the value each one carries. Everything inside an animated part is that part's content, so the tree stops there.
Popover.RootPopover.TriggerPopover.PortalPopover.Contentdata-motion="scale-fade"
Source
"use client"
import { Popover } from "radix-ui"
import type { DemoProps } from "@/components/demos/props"
export function RadixPopover({ motion }: DemoProps) {
return (
<Popover.Root>
<Popover.Trigger className="btn">Open popover</Popover.Trigger>
<Popover.Portal>
<Popover.Content className="panel" sideOffset={10} collisionPadding={16} data-motion={motion}>
<p className="panel__title">Anchored</p>
<p className="panel__body">
The origin follows the trigger edge, because Radix publishes a popper transform
origin and easeful reads it before its own default.
</p>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
)
}motion prop is the only difference between them.