This component no longer exists. It was in ericts-ui’s manifest when we first indexed it and is not there now — the registry served its inventory on 2026-08-15 and this item was not on it. The install command below will fail. It is kept here because a tutorial somewhere still tells people to run it.
Heartbeat Animation
ericts-ui/heartbeat-animationRemovedComponent
A Motion-powered heartbeat primitive with a projected shadow layer and reduced-motion support.
Live preview
live · rendered by the registry
Rendered by ericts-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.ericts.com/r/heartbeat-animation.jsonSource
1"use client";23import { motion, useReducedMotion, type HTMLMotionProps } from "motion/react";4import * as React from "react";56import { cn } from "@/lib/utils";78const heartbeatScale = [1, 1.24, 0.93, 1.19, 0.96, 1, 1];9const heartbeatLift = ["0%", "-4.2%", "1.1%", "-3.2%", "0.7%", "0%", "0%"];10const heartbeatRotate = [0, -1.15, 0.62, -0.85, 0.34, 0, 0];11const heartbeatTimes = [0, 0.055, 0.13, 0.23, 0.34, 0.5, 1];12const maxHeartbeatLift = Math.max(...heartbeatScale) - 1;13const heartbeatProjection = heartbeatScale.map((scale) =>14 Math.max(scale - 1, 0) / maxHeartbeatLift,15);16const heartbeatShadowScale = heartbeatScale.map(17 (scale, index) => scale + heartbeatProjection[index] * 0.055,18);1920const heartbeatAnimation = {21 rotate: heartbeatRotate,22 scale: heartbeatScale,23 y: heartbeatLift,24};2526const heartbeatShadowAnimation = {27 opacity: heartbeatProjection.map((distance) => 0.13 - distance * 0.04),28 scale: heartbeatShadowScale,29 x: heartbeatProjection.map((distance) => `${distance * -20}%`),30 y: heartbeatProjection.map((distance) => `${distance * -5}%`),31};3233const heartbeatTransition = {34 duration: 1.18,35 times: heartbeatTimes,36 ease: "easeOut" as const,37 repeat: Infinity,38 repeatDelay: 0.9,39};4041type HeartbeatTransition = NonNullable<HTMLMotionProps<"span">["transition"]>;4243export type HeartbeatProps = React.ComponentPropsWithoutRef<"span"> & {44 /** Classes applied to the visible animated child wrapper. */45 targetClassName?: string;46 /** Classes applied to the projected shadow layer. */47 shadowClassName?: string;48 /** Hide the projected shadow layer. */49 showShadow?: boolean;50 /** Override the default double-thump transition. */51 transition?: HeartbeatTransition;52};5354export function Heartbeat({55 className,56 children,57 shadowClassName,58 showShadow = true,59 targetClassName,60 transition = heartbeatTransition,61 ...props62}: HeartbeatProps) {63 const reduceMotion = useReducedMotion();64 const resolvedTransition = reduceMotion ? { duration: 0 } : transition;6566 return (67 <span68 data-slot="heartbeat"69 className={cn(70 "relative inline-flex items-center justify-center",71 className,72 )}73 {...props}74 >75 {showShadow ? (76 <motion.span77 aria-hidden="true"78 data-slot="heartbeat-shadow"79 className={cn(80 "pointer-events-none absolute inset-0 z-0 text-current blur-[5px]",81 shadowClassName,82 )}83// … truncated
What it pulls in
npm packages
Files it writes
More from ericts-ui
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Adaptive Draweradaptive-drawer | ericts-ui | Components | Free | 2 deps | |
| Adaptive Switchadaptive-switch | ericts-ui | Components | Free | 2 deps | |
| Check Markcheck-mark | ericts-ui | Components | Free | no deps · 2 files | |
| Context Cursorcontext-cursor | ericts-ui | Components | Free | 1 dep | |
| Copy Buttoncopy-button | ericts-ui | Components | Free | 2 deps | |
| Expandable Dialogexpandable-dialog | ericts-ui | Components | Free | 1 dep | |
| Expandable Panelexpandable-panel | ericts-ui | Components | Free | 2 deps | |
| Expandable Segmented Tabsexpandable-segmented-tabs | ericts-ui | Components | Free | 1 dep |
