npm package: @staccats/sdk-vue
Description: Vue 3 components for integrating Staccats notifications into your Vue application.
Latest version: 0.1.9

# @staccats/sdk-vue

Vue 3 components for integrating Staccats notifications into your Vue application.

## Installation

```bash
npm install @staccats/sdk-vue @staccats/sdk-js
```

or with yarn:

```bash
yarn add @staccats/sdk-vue @staccats/sdk-js
```

or with bun:

```bash
bun add @staccats/sdk-vue @staccats/sdk-js
```

## Quick Start

### 1. Add Notification Components

```vue
<template>
	<div>
		<!-- Notification Bell -->
		<NotificationBell
			:userId="currentUserId"
			:apiKey="apiKey"
			@click="showDropdown = true" />

		<!-- Notification Dropdown -->
		<NotificationDropdown
			:userId="currentUserId"
			:apiKey="apiKey"
			@notification-click="handleNotificationClick" />

		<!-- Toast Container (for showing new notifications) -->
		<NotificationToastContainer
			:userId="currentUserId"
			:apiKey="apiKey" />
	</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import {
	NotificationBell,
	NotificationDropdown,
	NotificationToastContainer,
} from '@staccats/sdk-vue';

const currentUserId = 'user_123';
const apiKey = 'pk_your_public_key';
const showDropdown = ref(false);

const handleNotificationClick = (notification) => {
	console.log('Notification clicked:', notification);
	// Handle navigation, etc.
};
</script>
```

## Components

### NotificationBell

A simple bell icon with unread badge.

```vue
<NotificationBell
	:userId="userId"
	:apiKey="apiKey"
	:apiUrl="apiUrl"
	className="custom-class"
	@click="handleClick" />
```

**Props:**
- `userId` (string, required) - The user ID
- `apiKey` (string, required) - Your Staccats API key (public key for client-side)
- `apiUrl` (string, optional) - API URL (defaults to `https://api.staccats.com`)
- `className` (string, optional) - Additional CSS classes

**Slots:**
- `icon` - Custom icon component

**Events:**
- `click` - Emitted when bell is clicked

---

### NotificationDropdown

A dropdown menu showing all notifications.

```vue
<NotificationDropdown
	:userId="userId"
	:apiKey="apiKey"
	:apiUrl="apiUrl"
	position="bottom-right"
	@notification-click="handleClick" />
```

**Props:**
- `userId` (string, required) - The user ID
- `apiKey` (string, required) - Your Staccats API key
- `apiUrl` (string, optional) - API URL
- `position` (string, optional) - Dropdown position: `'bottom-right'` | `'bottom-left'` | `'top-right'` | `'top-left'` (default: `'bottom-right'`)
- `className` (string, optional) - Additional CSS classes

**Slots:**
- `trigger` - Custom trigger button
- `icon` - Custom icon component
- `empty` - Custom empty state message

**Events:**
- `notification-click` - Emitted when a notification is clicked

---

### NotificationToastContainer

Automatically shows toast notifications for new notifications.

```vue
<NotificationToastContainer
	:userId="userId"
	:apiKey="apiKey"
	:apiUrl="apiUrl"
	position="top-right"
	:duration="5000" />
```

**Props:**
- `userId` (string, required) - The user ID
- `apiKey` (string, required) - Your Staccats API key
- `apiUrl` (string, optional) - API URL
- `position` (string, optional) - Toast position (default: `'top-right'`)
- `duration` (number, optional) - Auto-dismiss duration in ms (default: `5000`, set to `0` to disable)

---

### NotificationToast

Individual toast notification (usually used via `NotificationToastContainer`).

```vue
<NotificationToast
	:notification="notification"
	position="top-right"
	:duration="5000"
	@dismiss="handleDismiss" />
```

## Composable

### useNotifications

Use the composable directly for custom implementations:

```vue
<script setup lang="ts">
import { useNotifications } from '@staccats/sdk-vue';

const { notifications, unreadCount, loading, markAsRead, markAllAsRead, refresh } = useNotifications(
	'user_123',
	{
		apiKey: 'pk_your_public_key',
		apiUrl: 'https://api.staccats.com', // optional
	}
);
</script>
```

**Returns:**
- `notifications` (ComputedRef<Notification[]>) - List of notifications
- `unreadCount` (ComputedRef<number>) - Number of unread notifications
- `loading` (ComputedRef<boolean>) - Loading state
- `markAsRead(notificationId: string)` - Mark a notification as read
- `markAllAsRead()` - Mark all notifications as read
- `refresh()` - Reload notifications from API

## Shared State

All components using the same `userId` share the same notification state. This means:

- When you mark a notification as read in the dropdown, the bell badge updates automatically
- When a new notification arrives via WebSocket, all components update simultaneously
- No duplicate API calls - state is shared across components

## WebSocket Connection

Components automatically connect via WebSocket for real-time updates. The connection is:

- **Shared** - One WebSocket connection per userId
- **Auto-reconnecting** - Reconnects automatically on disconnect
- **Efficient** - Only one connection regardless of how many components you use

## Styling

Components include default styles but can be customized:

### CSS Variables

```css
:root {
	--staccats-primary: #3b82f6;
	--staccats-danger: #ef4444;
	--staccats-border: #e5e7eb;
	--staccats-bg: #ffffff;
	--staccats-text: #111827;
}
```

### Custom Classes

All components accept a `className` prop for additional styling.

### Dark Mode

Components automatically support dark mode via `prefers-color-scheme: dark`.

## Examples

### Basic Setup

```vue
<template>
	<div>
		<NotificationDropdown :userId="userId" :apiKey="apiKey" />
		<NotificationToastContainer :userId="userId" :apiKey="apiKey" />
	</div>
</template>

<script setup lang="ts">
import { NotificationDropdown, NotificationToastContainer } from '@staccats/sdk-vue';

const userId = 'user_123';
const apiKey = import.meta.env.VITE_STACCATS_API_KEY;
</script>
```

### Custom Styling

```vue
<template>
	<NotificationBell
		:userId="userId"
		:apiKey="apiKey"
		className="my-custom-bell">
		<template #icon>
			<CustomIcon />
		</template>
	</NotificationBell>
</template>

<style>
.my-custom-bell {
	border-radius: 50%;
	background: #f3f4f6;
	padding: 12px;
}
</style>
```

### Using Composable Directly

```vue
<template>
	<div>
		<button @click="toggle">
			Notifications
			<span v-if="unreadCount > 0">{{ unreadCount }}</span>
		</button>
		<div v-if="isOpen">
			<div v-for="notification in notifications" :key="notification.id">
				<h4>{{ notification.title }}</h4>
				<p>{{ notification.message }}</p>
				<button @click="markAsRead(notification.id)">Mark as read</button>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useNotifications } from '@staccats/sdk-vue';

const isOpen = ref(false);
const { notifications, unreadCount, markAsRead } = useNotifications('user_123', {
	apiKey: 'pk_your_key',
});

const toggle = () => {
	isOpen.value = !isOpen.value;
};
</script>
```

## TypeScript Support

Full TypeScript support is included. All types are exported:

```typescript
import type { Notification, NotificationBellProps, NotificationDropdownProps } from '@staccats/sdk-vue';
```

## License

MIT