Base UITransitions
Popover
The origin chain falls back to the Base UI variable when the Radix one is absent, so one rule serves both libraries.
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-ending-style, data-side, --transform-origin
easeful matches
[data-motion][data-side] { transform-origin: <anchor origin> }
what runs
transition, origin from the trigger
you write
<Popover.Popup 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.PositionerPopover.Popupdata-motion="scale-fade"
Source
"use client"
import { Popover } from "@base-ui/react/popover"
import type { DemoProps } from "@/components/demos/props"
export function BaseUiPopover({ motion }: DemoProps) {
return (
<Popover.Root>
<Popover.Trigger className="btn">Open popover</Popover.Trigger>
<Popover.Portal>
<Popover.Positioner sideOffset={10} collisionPadding={16}>
<Popover.Popup className="panel" data-motion={motion}>
<p className="panel__title">Anchored</p>
<p className="panel__body">
Base UI publishes its own transform origin, which easeful falls back to when the
Radix one is absent.
</p>
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
)
}motion prop is the only difference between them.