Swap Fields
NewCustomize
Vertical
Arc88px
Duration0.60s
Radius28px
Installation
npx shadcn@latest add https://uibrik.com/r/swap-fields.jsonInstall the packages
npm install @tabler/icons-react motionAdd the cn helper
Imports
cnfrom@/lib/utils, whichshadcn initcreates. Add it by hand without shadcn.Copy the source into your project
components/uibrik/swap-fields/swap-fields.tsx"use client"; import { IconArrowsUpDown } from "@tabler/icons-react"; import { animate, motion, useMotionValue, useReducedMotion, useTransform, type AnimationPlaybackControls, type MotionStyle, type MotionValue, } from "motion/react"; import { createContext, forwardRef, useContext, useEffect, useId, useLayoutEffect, useRef, useState, type InputHTMLAttributes, type ReactNode,
Adds the files to
components/uibrik/swap-fields and installs @tabler/icons-react and motion. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/swap-fields.Usage
import { SwapFields } from "@/components/uibrik/swap-fields/swap-fields";<SwapFields orientation="vertical" arc={88} duration={0.6} radius={28} labels={["From", "To"]} defaultSwapped={false} buttonLabel="Swap" // accents={…} // swapped={false} // onSwappedChange={(swapped) => {}}> [<SwapFieldInput defaultValue="London" />, <SwapFieldInput defaultValue="Paris" />]</SwapFields>Props
SwapFields- orientation
- Type "vertical" | "horizontal"
- "vertical"
- Stack the fields or set them side by side. Side by side stacks again in narrow containers.
- arc
- Type number
- 88
- Half-width of the ellipse the fields orbit on, one out each side. Narrow rows swing less. 0 slides them straight past each other.
- duration
- Type number
- 0.6
- Length of one swap.
- radius
- Type number
- 28
- Corner radius of each field.
- labels
- Type string[]
- ["From","To"]
- Labels for the two slots. They stay with the slot, not the field.
- childrenrequired
- Type [ReactNode, ReactNode]
- –
- The two fields in slot order. SwapFieldInput is a bare input that picks up the slot label.
- accents
- Type [string, string]
- –
- Optional tint for each field, in children order. It travels with the field. Neutral when left out.
- swapped / onSwappedChange
- Type boolean / (swapped) => void
- –
- Controlled swap state.
- defaultSwapped
- Type boolean
- false
- Swapped on mount when uncontrolled.
- buttonLabel
- Type string
- "Swap"
- Accessible name for the swap button.
- className
- Type string
- –
- Classes for the wrapper.