Skip to content
Compositions

SwatchFan

A fanned stack of {@link Swatch} tiles: a fixed three-card editorial fan or an interactive N-tile splay. Pass 3 items with interaction="breathe" for the editorial fan (Figma geometry, variant spread/stack, white 3px mount via bordered); pass N items with interaction="hover-fan" for the interactive splay-on-hover with pointer tilt. bordered={false} swaps the white mount for the 1px hairline tile.

Walnut
Terracotta
Sage

Recently sampled · Earth collection

Usage

@instruments/materia-ui/compositions/swatch-fan

<Stack align="center" gap="base">
  <SwatchFan animateOnMount items={SAMPLES} variant="spread" />
  <Text size="paragraph-sm" variant="muted">
    Recently sampled · Earth collection
  </Text>
</Stack>

Best practices

  • Feed 3 items for the breathe/none card engine - its Figma geometry, z-order, and variant morphing are built around a fixed left/center/right trio; the hover-fan engine is the N-tile path.

  • Needs ReducedMotionProvider; it already collapses the mount fan-out, hover nudge, and splay under reduced motion (snapping to the settled frame), so don't gate the interaction yourself.

  • bordered is the mount-as-a-prop: true = white 3px card mount, false = 1px hairline - don't hand-roll either border in a wrapper.

Props

PropTypeDefaultDescription
animateOnMountboolean

Animate cards fanning out on mount (card engine - breathe/none).

borderedbooleantrue

Mount as a prop. true (default) = white 3px card mount; false = 1px hairline.

cardBorderWidthnumber3

Border width for each material card (card engine).

cardRadiusnumber20

Corner radius for each material card (card engine).

cardShadowstring

Shadow applied to each material card (card engine).

classNamestring
fanOnHoverbooleantrue

Own the fan state via hover/focus (default) or drive it via fanned (hover-fan engine).

fannedboolean

Controlled fan state (hover-fan engine) - e.g. a sibling CTA triggers it.

hoveredboolean

Controlled hover/open state for parent-driven compositions (card engine).

hoverRotatenumber1

Extra side-card rotation while hovered (card engine).

hoverShiftnumber3

Extra outward shift for side cards while hovered (card engine).

interactionSwatchFanInteraction"breathe"

Motion/geometry engine: breathe (decorative micro-nudge, default), hover-fan (StackedSwatchFan splay + pointer tilt), or none (static).

items(required)SwatchFanItem[]

Tiles to fan. The card engine (breathe/none) maps the first three to left/center/right; the hover-fan engine stacks the first few (matching its motion transforms).

labelstring

Accessible label applied as the fan's aria-label (hover-fan engine).

mountDelaynumber

Delay before the mount fan-out starts, in seconds (card engine).

onFannedChange(fanned: boolean) => void

Fires when the hover-fan opens or closes, with the next fanned state.

overlapnumber

Override the horizontal overlap between adjacent cards, px (card engine).

renderImage(props: SwatchFanImageProps) => ReactNode

Escape hatch for framework-optimized images (e.g. next/image).

rotationDegnumber8

Side-card rotation in degrees (card engine).

sizeSwatchFanSize"xl"

Tile size - a SwatchTileSize scale step or pixel number.

styleCSSProperties

Inline styles applied to the hover-fan root.

wrapperSizenumber

Override the square wrapper size for rotated side cards, px (card engine).

variantSwatchFanVariant

Layout variant (card engine): stack (default) or spread.

Also exports

  • interfaceSwatchFanImageProps
  • typeSwatchFanInteraction
  • interfaceSwatchFanItem
  • interfaceSwatchFanProps
  • typeSwatchFanSize
  • typeSwatchFanVariant

Composition