Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Buttons

Free

Arrow Button for React

A button whose arrow slides in on hover, for actions that take people somewhere next. For React with Base UI, when the label alone doesn't say the page moves on.

Framework
UI library

An arrow slides in beside the label when the pointer arrives or the button takes keyboard focus, and slides back out when it leaves.

Use it for the actions that move someone forward: Get started, Learn more, Next, Continue to checkout. It wraps the Button, so every variant and size works and Base UI handles the press. The arrow is drawn on the button itself rather than added to its content, so the label stays the button's own and it becomes a link the way the Button does. The motion is CSS transitions, with no JavaScript and no animation library: the arrow's space and the button's gap open from nothing, so the button grows smoothly, while the arrow slides out from behind the label. When the system asks for reduced motion, the arrow fades in instead of sliding.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Usage

import { ArrowButton } from "@/components/ui/arrow-button";
<ArrowButton>Get started</ArrowButton>

Demos

Direction

direction="left" points the arrow back and slides it in before the label, for Previous, Back to results, or the first half of a pager. The forward button keeps the default. In a right-to-left layout both arrows mirror on their own, so forward still points the way the page reads.

Preview width

Always Visible

showArrow keeps the arrow out at rest, and hover still nudges it a step further. Use it where hover doesn't happen, on touch screens, or when the arrow is part of what the button says, as in Continue to checkout. It works at every size.

Preview width

Get started here is a real link with the arrow, for the calls to action that go to another page: sign up, pricing, the docs. A link shows where it goes, and people can open it in a new tab. The arrow is drawn on the link itself, so it slides in on hover and focus as on the button. The prop that makes it a link differs by library, and the link question in the FAQ names each one.

Preview width

Accessibility

The arrow is decoration: it's drawn by CSS, so assistive tech never reads it, and the label has to say where the button goes. It appears on keyboard focus as well as on hover, so people who tab through the page see the same cue. As a link, Enter follows it.

Enter
Activate the button.
Space
Activate the button.

FAQ

Can the arrow point back?

Yes. direction="left" flips the arrow and slides it in before the label, as in the Direction demo.

How do I keep the arrow visible on touch screens?

Pass showArrow. Touch screens have no hover, so without it the arrow only shows on a keyboard focus there. The Always Visible demo uses it.

Does the button get wider when the arrow appears?

Yes, by the arrow and the button's usual gap, and the growth is smooth: the arrow's space and the gap open from nothing together. At rest a text label is centered as on any Button; a label of several elements, such as an icon and text, keeps its gaps, so at rest it sits half a gap off center. In a row of buttons that must not move, use showArrow so the width is fixed from the start.

What happens with reduced motion?

The arrow still appears and disappears, but without the slide: its slot opens at once and the arrow fades in where it stands.

Does it need an animation library?

No. It's CSS transitions on the arrow's size, position and opacity and on the button's gap, so it adds nothing to your bundle beyond the Button: the arrow is Lucide's arrow-right drawn through a CSS mask, not an icon component, and nothing runs while it moves.

API Reference

ArrowButton

PropType
children?ReactNode

The label; the arrow goes after it, or before it when it points back.

direction?"left" | "right"

Which way the arrow points: forward for "Next" and "Learn more", back for "Previous". It also decides which side it slides in on.

Type
"left" | "right"
Default
"right"
focusableWhenDisabled?boolean

Whether the button should be focusable when disabled.

Default
false
nativeButton?boolean

Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).

Default
true
showArrow?boolean

Show the arrow at rest; hover still nudges it on.

Default
false
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

All 35 buttons