# Notification Center

> Frosted notification panel with a badged bell trigger, spring-animated rows that expand in place, live relative timestamps, and layout-animated add/read flows.

<demo-notification-center>



</demo-notification-center>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import { ref } from 'vue';
  import NotificationCenter from '~/components/ui/notification-center/NotificationCenter.vue';
  import type { NotificationCenterItem } from '~/components/ui/notification-center/types';

  const items = ref<NotificationCenterItem[]>([
    {
      id: 1,
      title: 'New Feature Available',
      message: 'Collaborative editing is now live!',
      icon: '💡',
      timestamp: Date.now(),
      unread: true,
    },
  ]);
</script>

<template>
  <NotificationCenter v-model="items" label="Notifications" align="right" />
</template>
```

The bell shows a spring-scaled unread badge. Opening reveals a frosted
panel; clicking a truncated row expands it in place (`layout` animation
reflows siblings) and marks it read. New items pushed to the front of the
`v-model` array drop in with a spring; timestamps re-render live every
second. Escape or clicking outside closes the panel.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        v-model
      </code>
    </td>
    
    <td>
      <code>
        NotificationCenterItem[]
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Notification list (mutable)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'Notifications'
      </code>
    </td>
    
    <td>
      Panel heading
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        align
      </code>
    </td>
    
    <td>
      <code>
        'left' | 'right'
      </code>
    </td>
    
    <td>
      <code>
        'right'
      </code>
    </td>
    
    <td>
      Side the panel grows from
    </td>
  </tr>
</tbody>
</table>

### NotificationCenterItem

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        id
      </code>
    </td>
    
    <td>
      <code>
        number | string
      </code>
    </td>
    
    <td>
      Unique key
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        title
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Row title (truncates until expanded)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        message
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Body text (truncates until expanded)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        icon
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Emoji in the icon square
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        timestamp
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      Epoch ms, rendered as live relative time
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        unread
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      Shows the red dot + counts toward badge
    </td>
  </tr>
</tbody>
</table>

## Events

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

<tbody>
  <tr>
    <td>
      <code>
        read
      </code>
    </td>
    
    <td>
      <code>
        NotificationCenterItem
      </code>
    </td>
    
    <td>
      Fired when a row is expanded
    </td>
  </tr>
</tbody>
</table>

## Credits

Ported from the notification panel interaction by
[@divv919](https://x.com/divv919/status/2076000393616830810).
