Skip to content
← Inventory

CardFan

Three overlapping image cards arranged as a fan or stack, with optional mount/hover motion. Cards always render in the same order (left, center, right) with z-index controlling stacking. This enables smooth animations between variants.

Recently sampled · Earth collection

Usage

@desk/ui/components/card-fan

<Stack align="center" gap="base">
  <CardFan animateOnHover animateOnMount images={SAMPLES} variant="spread" />
  <Text className="text-muted-foreground" size="sm">
    Recently sampled · Earth collection
  </Text>
</Stack>

Best practices

  • Provide exactly three images (left/center/right) — the fan geometry, z-order, and variant morphing are built around that fixed trio; it's not an N-card carousel.

  • Needs ReducedMotionProvider; it already collapses the mount fan-out and hover nudge under reduced motion, so don't gate animateOnMount/animateOnHover yourself.

  • Cards always render in DOM order left→center→right with z-index doing the stacking — keep that so variant transitions ("stack"↔"spread") stay smooth.

Props

PropTypeDefaultDescription
animateOnHoverboolean

Subtle micro-animation on hover (cards breathe outward)

animateOnMountboolean

Animate cards fanning out on mount

cardBorderWidthnumber

Border width for each material card.

cardRadiusnumber

Corner radius for each material card.

cardShadowstring

Shadow applied to each material card.

classNamestring
rotationDegnumber

Side-card rotation in degrees.

hoveredboolean

Controlled hover/open state for parent-driven compositions.

hoverRotatenumber

Extra side-card rotation while hovered.

hoverShiftnumber

Extra outward shift for side cards while hovered.

images(required)CardFanImages
mountDelaynumber

Delay before the mount animation starts (seconds). Only applies when animateOnMount is true.

overlapnumber

Override the computed horizontal overlap between adjacent cards (px). Defaults to the value derived from the thumbnail size, so existing consumers are unaffected. Note: size is the bordered outer box (Thumbnail numeric sizes are border-box), which is what the fan geometry is built on.

renderImage(props: CardFanImageProps) => ReactNode
wrapperSizenumber

Override the computed square wrapper size for the rotated side cards (px). Defaults to the value derived from the thumbnail size.

sizeCardFanSize

Thumbnail size (default: "xl" = 96px)

variantCardFanVariant

Layout variant: "stack" horizontal fan with center prominent (default), "spread" tight fan

Also exports

  • interfaceCardFanImageProps
  • interfaceCardFanImages
  • interfaceCardFanProps
  • typeCardFanVariant

Composition