‹ components

FollowButton

stablev1.0.0·open in canvas

Follow / Following toggle. Fill→outline morph; unfollow needs no confirm.

Installnpx shadcn add @cids/follow-button
Live demo

Motion · tap to replay

honors reduced-motion

`--motion-settle` (200ms) morphs background / border / color between the two states. Label swaps at the state change (no separate crossfade in v1). Reduced-motion: neutralized globally.

Brand chip remounts on tap · highlighted tokens are named in this component's doc · spring is budgeted to human feedback only.

import { FollowButton } from "@/design-system";

const [following, setFollowing] = useState(false);

<FollowButton
  following={following}
  onToggle={() => setFollowing((v) => !v)}  // flip optimistically; roll back on error
/>

Tokens · live

Resolves in the active theme — flip the toggle above to verify.

States · from doc

Parsed from the doc. Interact with the live demo for hover/active.

**Follow** — filled branddark on-brand text.**Following** — transparentoutline bordermuted text.**Press** — `scale `.revert on error.

Follow / Following toggle. Fill→outline morph; unfollow needs no confirm.

Anatomy

  Follow        →  tap  →   Following
┌──────────┐             ┌──────────────┐
│ bg-brand │             │ transparent  │
│ on-brand │             │ outline·muted│
└──────────┘             └──────────────┘
  filled                   morphs 200ms

Props

PropTypeDefaultNotes
followingboolean—Controlled state. Flip optimistically at the call site; roll back on failure.
onToggle() => void—Fired on tap.
classNamestring—Merged via cn.

Motion

--motion-settle (200ms) morphs background / border / color between the two states. Label swaps at the state change (no separate crossfade in v1). Reduced-motion: neutralized globally.

A11y

Self-contained: copy the folder into any Tailwind+React app, or use the install command above. Docs and this page render the same file on disk — they cannot drift.