npm package: @linxs/toolkit-vue
Description: Vue 3 组合式函数 (Composables) 和指令 (Directives) 工具包
Author: Lin.xs
Latest version: 0.1.5

# @linxs/toolkit-vue

Vue 3 Composables and Directives toolkit for common use cases.

中文文档：[中文文档](./README-Zh.md)

## Features

- 🎣 **Composables** - Powerful and type-safe Vue 3 composable functions
  - `useEventListener` - Auto-managed event listeners with cleanup
  - `useScrollNavigation` - Scroll-based navigation with anchor highlighting
- ⚡ **Directives** - Essential Vue 3 directives for common scenarios
  - `v-trim` - Automatic input trimming with multiple modes
  - `v-auth` - Authentication and role-based visibility control
- 📦 Full TypeScript support with strict type safety
- 🔄 Reactive and auto-cleanup - No memory leaks
- 🛠️ Flexible configuration options
- 🎨 Works with Naive UI components (NScrollbar, etc.)

## Installation

```bash
# Using npm
npm install @linxs/toolkit-vue

# Using yarn
yarn add @linxs/toolkit-vue

# Using pnpm
pnpm add @linxs/toolkit-vue
```

## Documentation

📖 **Complete guides and API references:**

- [Directives Documentation](./docs/Directives.md) - `v-trim`, `v-auth`
- [Composables Documentation](./docs/Hooks.md) - `useEventListener`, `useScrollNavigation`

## Quick Start

### Composables

#### useEventListener

Auto-managed event listeners that cleanup on component unmount:

```vue
<script setup>
import { ref } from 'vue';
import { useEventListener } from '@linxs/toolkit-vue';

const buttonRef = ref(null);

// Window events
useEventListener(window, 'resize', () => {
  console.log('Window resized');
});

// Element events with ref
useEventListener(buttonRef, 'click', () => {
  console.log('Button clicked');
});

// Document events with options
useEventListener(
  document,
  'scroll',
  () => console.log('Scrolled'),
  { passive: true }
);
</script>

<template>
  <button ref="buttonRef">Click me</button>
</template>
```

#### useScrollNavigation

Scroll-based navigation with menu highlighting:

```vue
<script setup>
import { ref, onMounted } from 'vue';
import { useScrollNavigation } from '@linxs/toolkit-vue';

const menus = [
  { id: 1, name: 'Introduction' },
  { id: 2, name: 'Features' },
  { id: 3, name: 'Installation' }
];

const contentRef = ref(null);
const currentMenu = ref(1);

const { scrollToSection, calculateSectionPositions, handleScroll } =
  useScrollNavigation(contentRef, {
    menus,
    onScroll: (menuId) => {
      currentMenu.value = menuId;
    }
  });

onMounted(() => {
  setTimeout(() => calculateSectionPositions(), 100);
});
</script>

<template>
  <div class="container">
    <nav>
      <div
        v-for="menu in menus"
        :key="menu.id"
        :class="{ active: currentMenu === menu.id }"
        @click="scrollToSection(menu.id)"
      >
        {{ menu.name }}
      </div>
    </nav>

    <div ref="contentRef" @scroll="handleScroll">
      <section
        v-for="menu in menus"
        :key="menu.id"
        :id="`section-${menu.id}`"
      >
        <h2>{{ menu.name }}</h2>
        <p>Content...</p>
      </section>
    </div>
  </div>
</template>
```

### Directives

#### v-trim

Automatic input trimming with multiple modes:

```vue
<script setup>
import { createApp } from 'vue';
import { trimDirective } from '@linxs/toolkit-vue';

// Register directive
const app = createApp(App);
app.directive('trim', trimDirective);
</script>

<template>
  <!-- Default: trim start and end whitespace -->
  <input v-trim v-model="username" />

  <!-- Remove all whitespace -->
  <input v-trim.all v-model="username" />

  <!-- Collapse multiple spaces to single space -->
  <input v-trim.collapse v-model="realName" />

  <!-- Real-time trimming -->
  <input v-trim.all.realtime v-model="phone" />
</template>
```

#### v-auth

Role-based visibility control:

```vue
<script setup>
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { createAuthDirective } from '@linxs/toolkit-vue';
import { useUserStore } from './stores/user';

const app = createApp(App);
const pinia = createPinia();

app.use(pinia);

// Register auth directive
const authDirective = createAuthDirective(() => useUserStore(pinia));
app.directive('auth', authDirective);
</script>

<template>
  <!-- Show for authenticated users -->
  <div v-auth>Member Area</div>

  <!-- Show for guests only -->
  <div v-auth.guest>Please login</div>

  <!-- Require specific role -->
  <button v-auth="'admin'">Admin Panel</button>

  <!-- Require one of multiple roles -->
  <button v-auth="['admin', 'moderator']">Manage Content</button>

  <!-- Require all roles -->
  <div v-auth.all="['admin', 'vip']">VIP Admin Area</div>
</template>
```

## API Overview

### Composables

- `useEventListener(target, event, handler, options?)` - Auto-managed event listeners
- `useScrollNavigation(contentRef, options)` - Scroll navigation with highlighting

### Directives

- `v-trim` - Input trimming with modifiers: `.all`, `.collapse`, `.strict`, `.realtime`
- `v-auth` - Auth control with modifiers: `.guest`, `.all`

## Configuration

### useScrollNavigation Options

```typescript
interface ScrollNavigationOptions {
  menus: MenuItem[];                                    // Menu items
  onScroll: (menuId: string | number) => void;        // Scroll callback
  scrollContainerRef?: HTMLElement | Ref | string;     // Custom scroll container
  offset?: number;                                      // Trigger offset (default: 50px)
}
```

### v-auth Store Requirements

```typescript
interface UserStore {
  isAuthenticated: boolean;      // Required: login status
  roles?: string[];              // Optional: user roles
  $subscribe?: (callback) => void;  // Optional: for reactivity
}
```

## TypeScript

Fully typed with TypeScript. All types are exported:

```typescript
import type {
  // Hook types
  MenuItem,
  ScrollNavigationOptions,
  ScrollNavigationReturn,

  // Directive types
  TrimModifiers,
  AuthDirectiveOptions,
  UserStore
} from '@linxs/toolkit-vue';
```

## Browser Support

Supports Vue 3.4+ and all modern browsers.

---

## Why @linxs/toolkit-vue?

This toolkit provides battle-tested Vue 3 utilities that solve common pain points:

- **Auto Cleanup**: No more manual event listener cleanup or memory leaks
- **Type Safety**: Full TypeScript support with comprehensive type definitions
- **Flexible**: Works with standard HTML elements and UI libraries (Naive UI, etc.)
- **Developer Experience**: Clean APIs with sensible defaults
- **Production Ready**: Thoroughly tested and used in production applications

Perfect for Vue 3 applications that need reliable composables and directives without the overhead of full libraries.

## License

MIT © Lin.xs