Skip to content
Pinky UI

collections

List Detail Morph

A selected collection item becomes a larger detail surface while preserving its visual identity and return path.

  • collections
  • list
  • detail
  • morph
  • shared-layout
Related pattern

Source item morphs into inline detail; it is not a generic modal transition.

Live preview

Select a source · Escape returns to it

Quick usage

usage
import { ListDetailMorph } from "@pinky-ui/systems";

<ListDetailMorph items={items} label="Case studies" />

Presets

Default

Restrained production behaviour.

Default behaviour

Quiet

Reduced intensity for dense product screens.

disabled={true}

Install

Add @pinky-ui/systems as a dependency, or use the CLI to copy this component's source directly into your project — no dependency to manage, fully editable.

shell
npm install @pinky-ui/systems

Prefer to run the whole repository locally instead?

repository
git clone https://github.com/florash/Pinky-UI.git
cd Pinky-UI
npm install
npm run dev

Props

PropTypeDefaultDescription
itemsListDetailMorphItem[]Collection items with media, summary and detail content.
classNamestringStyles the outer interaction surface.

Accessibility

  • Keyboard and touch paths match the pointer interaction.
  • Stable labels and values remain available without motion.

Performance

  • Only the selected detail surface mounts; source identity uses stable layout ids.
  • Reduced motion skips travel while preserving the same source/detail relationship.

Reduced motion

Motion resolves immediately while semantics, focus and state remain unchanged.

When to use

  • Short portfolios and content indexes where the selected item should remain spatially recognisable

When not to use

  • Unrelated route changes or large feeds that need a full page

Skill

Purpose

Use a list-to-detail morph when selecting an item should make that same item become the larger reading surface. The media and title identity carry across the state.

Interaction anatomy

  • A compact list/card is the source state.
  • Selecting one item replaces the collection with its inline detail surface.
  • Back or Escape returns focus to the exact source item.

Good for

Short project indexes, portfolios and curated content collections.

Avoid

Unrelated route transitions, generic modals or feeds too large to keep in one reading context.

Usage

tsx
<ListDetailMorph
  label="Case studies"
  items={projects.map((project) => ({
    id: project.id,
    title: project.title,
    summary: project.summary,
    media: <ProjectCover project={project} />,
    detail: <ProjectDetail project={project} />,
  }))}
/>

Tune

Use stable ids for shared layout identity and keep the detail surface bounded. Provide a visible back control even when Escape is supported.

Accessibility and reduced motion

Use buttons for source selection, focus the detail heading on open and restore the source button on close. Reduced motion renders the same source/detail states without travel.

Open this skill on its own page