Sora UI

Slot

A slot component that merges motion props into any child element, turning it into a Motion component. A primitive from Animate UI.

Made by Axyl

Slot is a primitive from Animate UI. It works like Radix's Slot, but for Motion: it wraps a single child element, converts it into a motion component (via motion.create), and merges class names, styles, refs, and all motion props onto it.

Installation

File Structure

slot.tsx

Usage

import { Slot } from '@/components/sora-ui/animate/slot';

<Slot whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
  <button type="button">Hover me</button>
</Slot>;

The child is rendered as a Motion component — if it already is one, it's reused as-is. Props defined on Slot win over the child's props, except className and style, which are merged.

Building asChild components

Use the exported WithAsChild helper type to add a Radix-style asChild prop to your own animated components:

import {
  Slot,
  type WithAsChild,
} from '@/components/sora-ui/animate/slot';
import { type HTMLMotionProps, motion } from 'motion/react';

type ButtonProps = WithAsChild<HTMLMotionProps<'button'>>;

function Button({ asChild = false, ...props }: ButtonProps) {
  if (asChild) {
    return <Slot {...props} />;
  }
  return <motion.button {...props} />;
}

Props

PropTypeDefault
children?
React.ReactElement
-
ref?
React.Ref<HTMLElement>
-
...props?
HTMLMotionProps
-

Credits

Adapted from Animate UI. Independent implementation for the Sora UI registry. Not affiliated with the original authors.

Built by Axyl. A motion-first component registry for React.

Last updated: 7/30/2026