# Stacked List

> A media list that rests as an overlapping deck and fans into a full column on hover, with the first row anchoring the stack.

<demo-stacked-list>



</demo-stacked-list>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/stacked-list.json"
```

## Usage

```vue
<script setup lang="ts">
  import StackedList from '~/components/ui/stacked-list/StackedList.vue';
  import type { StackedListItem } from '~/components/ui/stacked-list/types';

  const items: StackedListItem[] = [
    { eyebrow: 'Feb 2, 2025', title: 'Wildflower Fields', image: '/img/1.jpg' },
    { eyebrow: 'Mar 14, 2025', title: 'Storm Rider', image: '/img/2.jpg' },
    { eyebrow: 'Apr 5, 2025', title: 'Golden Hour', image: '/img/3.jpg' },
  ];
</script>

<template>
  <StackedList :items="items" />
</template>
```

By default the deck expands on hover. Set `:expand-on-hover="false"` to make the
first row a click toggle instead. The first row anchors the stack and flips its
chevron up → down; the rest emit `select` with their index when clicked.

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        items
      </code>
    </td>
    
    <td>
      <code>
        StackedListItem[]
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Rows to render (<code>
        eyebrow
      </code>
      
      , <code>
        title
      </code>
      
      , <code>
        image
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        item-height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        72
      </code>
    </td>
    
    <td>
      Fixed row height in px
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gap
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      Vertical gap between rows when expanded, in px
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        peek
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        12
      </code>
    </td>
    
    <td>
      Sliver each stacked card peeks when collapsed, in px
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        expand-on-hover
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Expand on pointer hover. When <code>
        false
      </code>
      
      , the header toggles
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        stiffness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        320
      </code>
    </td>
    
    <td>
      Spring stiffness for the collapse/expand motion
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        damping
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        34
      </code>
    </td>
    
    <td>
      Spring damping for the collapse/expand motion
    </td>
  </tr>
</tbody>
</table>

## Events

<table>
<thead>
  <tr>
    <th>
      Event
    </th>
    
    <th>
      Payload
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        toggle
      </code>
    </td>
    
    <td>
      <code>
        expanded: boolean
      </code>
    </td>
    
    <td>
      Fired when the deck expands or collapses
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        select
      </code>
    </td>
    
    <td>
      <code>
        index: number
      </code>
    </td>
    
    <td>
      Fired when a non-anchor row is clicked
    </td>
  </tr>
</tbody>
</table>

## Credits

Inspired by the stacked-list interaction by [@moizarshi29](https://x.com/moizarshi29).
