npm package: @jalzae/vue-table
Description: A flexible, native CSS Vue 3 table component with advanced features like filtering, sorting, and pagination
Author: Jalz
Latest version: 1.0.1

# Vue Table

A flexible, native CSS Vue 3 table component with advanced features like filtering, sorting, pagination, and search. Built without Tailwind CSS for maximum compatibility and customizability.

## ✨ Features

- **Native CSS** - No dependency on Tailwind or other CSS frameworks
- **Themeable** - 40+ CSS variables for easy customization
- **Responsive** - Mobile-friendly design with touch support
- **Search** - Built-in debounced search functionality
- **Sort** - Column sorting with visual indicators
- **Pagination** - Built-in pagination controls
- **Filter** - 10+ flexible filter components (Text, Number, Date, Select, Toggle, Amount, Day, Like, Submission, Comment)
- **Editable Filters** - Click to edit any applied filter and reapply
- **Zero Dependencies** - Only requires Vue 3
- **TypeScript** - Full TypeScript support with complete types
- **Dark Mode** - Built-in dark theme support
- **Advanced Filters** - Pre-built filters for common and advanced use cases
- **Nuxt 3 Support** - Full Nuxt 3 module support with auto-imports
- **Framework Agnostic** - Works with Vue 3, Nuxt 3, and other Vue-based frameworks

## 📦 Installation

### From npm

```bash
npm install @jalzae/vue-table
```

### For Nuxt 3

```bash
npm install @jalzae/vue-table
```

Then add to your `nuxt.config.ts`:

```typescript
export default defineNuxtConfig({
  modules: [
    '@jalzae/vue-table/nuxt'
  ]
})
```

The component will be auto-imported in your Nuxt app.

### From GitHub (Local Development)

```bash
# Clone the repository
git clone https://github.com/yourusername/jalz-table.git
cd jalz-table

# Install dependencies
npm install

# Start development server
npm run dev

# Build the library
npm run build

# Test the build
npm run preview
```

## 🚀 Quick Start

### Vue 3 Project

#### 1. Basic Setup

Install the package in your Vue 3 project:

```bash
npm install @jalzae/vue-table
```

#### 2. Import CSS

In your main.ts or App.vue:

```javascript
// Import component styles (required)
import '@jalzae/vue-table/dist/styles/variables.css'
import '@jalzae/vue-table/dist/styles/base.css'
```

#### 3. Use the Table Component

```vue
<template>
  <Table
    :columns="columns"
    :rows="rows"
    title="Users"
    show-header
    show-search
    show-pagination
    :total="100"
    :current-page="1"
    :per-page="10"
  />
</template>

<script setup lang="ts">
import { Table } from '@jalzae/vue-table'
import '@jalzae/vue-table/dist/styles/variables.css'
import '@jalzae/vue-table/dist/styles/base.css'

const columns = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { key: 'email', label: 'Email' },
]

const rows = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
]
</script>
```

### Nuxt 3 Project

#### 1. Install Package

```bash
npm install @jalzae/vue-table
```

#### 2. Configure Module

Add the module to your `nuxt.config.ts`:

```typescript
export default defineNuxtConfig({
  modules: [
    '@jalzae/vue-table/nuxt'
  ]
})
```

#### 3. Use in Your Pages

The `Table` component and CSS will be auto-imported. Just use it directly:

```vue
<template>
  <div>
    <Table
      :columns="columns"
      :rows="rows"
      title="Users"
      show-header
      show-search
      show-pagination
      enable-auto-fetch
      :total="total"
      :current-page="currentPage"
      :per-page="perPage"
      @filter="handleFilters"
      @search="handleSearch"
      @page-change="handlePageChange"
      @per-page-change="handlePerPageChange"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const columns = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { key: 'email', label: 'Email' },
]

const rows = ref([])
const total = ref(0)
const currentPage = ref(1)
const perPage = ref(10)

const fetchData = async (page = 1) => {
  const response = await fetch(`/api/users?page=${page}&perPage=${perPage.value}`)
  const data = await response.json()
  rows.value = data.rows
  total.value = data.total
}

const handleSearch = (query: string) => {
  currentPage.value = 1
  // Implement search logic
}

const handleFilters = (filters: any[]) => {
  currentPage.value = 1
  // Implement filter logic
}

const handlePageChange = (page: number) => {
  currentPage.value = page
  fetchData(page)
}

const handlePerPageChange = (per: number) => {
  perPage.value = per
  currentPage.value = 1
  fetchData(1)
}

onMounted(() => {
  fetchData()
})
</script>
```

## 📚 Documentation

For detailed documentation, see:

- [**QUICKSTART.md**](./QUICKSTART.md) - 5-minute quick start guide
- [**USAGE.md**](./USAGE.md) - Comprehensive usage guide with examples
- [**API.md**](./API.md) - Complete API reference
- [**RESOURCES.md**](./RESOURCES.md) - Learning paths and troubleshooting

## 📖 Examples

### Basic Usage

```vue
<template>
  <Table
    :columns="columns"
    :rows="rows"
    title="Users"
    show-header
    show-search
    show-pagination
    :show-pagination="true"
    :total="100"
    :current-page="1"
    :per-page="10"
  />
</template>

<script setup lang="ts">
import { Table } from '@jalzae/vue-table';

const columns = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { key: 'email', label: 'Email' },
  { key: 'role', label: 'Role' },
];

const rows = [
  { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
  // ... more rows
];
</script>

<style>
/* Import the CSS variables for theming */
@import '@jalzae/vue-table/dist/styles/variables.css';
@import '@jalzae/vue-table/dist/styles/base.css';
</style>
```

## Props

### Table Component

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `columns` | `TableColumn[]` | `[]` | Column definitions |
| `rows` | `TableRow[]` | `[]` | Table data rows |
| `title` | `string` | `''` | Table title |
| `showHeader` | `boolean` | `true` | Show table header |
| `showSearch` | `boolean` | `false` | Show search bar |
| `searchPlaceholder` | `string` | `'Search...'` | Search input placeholder |
| `showFilter` | `boolean` | `false` | Show filter controls |
| `loading` | `boolean` | `false` | Show loading state |
| `showPagination` | `boolean` | `false` | Show pagination |
| `total` | `number` | `0` | Total number of records |
| `currentPage` | `number` | `1` | Current page number |
| `perPage` | `number` | `10` | Records per page |
| `actions` | `TableAction[]` | `[]` | Row action buttons |
| `actionButtons` | `TableAction[]` | `[]` | Header action buttons |
| `sortBy` | `string` | `''` | Current sort field |
| `sortOrder` | `'asc' \| 'desc'` | `'asc'` | Sort order |
| `customClass` | `string` | `''` | Custom CSS class |
| `striped` | `boolean` | `false` | Striped rows |
| `hoverable` | `boolean` | `true` | Hover effect on rows |
| `compact` | `boolean` | `false` | Compact spacing |
| `enableAutoFetch` | `boolean` | `false` | Auto-fetch when filters change |

### Column Definition

```typescript
interface TableColumn {
  key: string;          // Data key
  label: string;        // Display label
  sortable?: boolean;   // Sortable column
  class?: string;       // Custom column CSS class
  type?: string;        // Column type ('text', 'date', 'boolean', etc.)
}
```

### Row Action Definition

```typescript
interface TableAction {
  id: string;           // Unique action ID
  label: string;        // Display label
  event: string;        // Event name to emit
  icon?: string;        // Icon name
  variant?: string;     // Button variant
}
```

## Filter Components

### Available Filters

1. **Text Filter** - Simple text search
2. **Number Filter** - Numeric comparison (equals, gt, lt, gte, lte)
3. **Date Filter** - Date range selection
4. **Select Filter** - Multi-select with search
5. **Toggle Filter** - Boolean status (Enabled/Disabled/Any)
6. **Amount Filter 💰** - Min/max amount range
7. **Day Filter 📅** - Select days of the week
8. **Like Filter ❤️** - Like/favorite status with count
9. **Submission Filter 📨** - Status with date range
10. **Comment Filter 💬** - Comment count with operators and text search

### Using Filters

All filters are clickable and editable:
- Click any applied filter to edit its values
- Modify and reapply without losing context
- Toggle filters on/off with the enable/disable button
- Remove filters with the X button

## Events

| Event | Payload | Description |
|-------|---------|-------------|
| `search` | `string` | Fired when search query changes |
| `filter` | `Filter[]` | Fired when filters change |
| `sort` | `{ field: string, order: 'asc' \| 'desc' }` | Fired when sorting changes |
| `page-change` | `number` | Fired when page changes |
| `per-page-change` | `number` | Fired when items per page changes |
| `row-click` | `TableRow` | Fired when row action is clicked |

## Theming

### CSS Variables

All colors and spacing use CSS custom properties that can be overridden:

```css
:root {
  /* Colors */
  --color-primary: #AD5160;
  --color-primary-light: #faeef0;
  --color-primary-dark: #8d4150;

  --color-bg: #ffffff;
  --color-bg-secondary: #f9fafb;
  --color-bg-tertiary: #f3f4f6;

  --color-border: #e5e7eb;
  --color-text: #1f2937;
  --color-text-secondary: #6b7280;

  /* Spacing */
  --spacing-xs: 0.25rem;
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;
  --spacing-lg: 1.5rem;
  --spacing-xl: 2rem;

  /* Border Radius */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;

  /* Other... */
}
```

### Dark Mode

```css
[data-theme="dark"] {
  --color-bg: #1f2937;
  --color-bg-secondary: #111827;
  --color-text: #f3f4f6;
  /* ... */
}
```

## Examples

### With Actions

```vue
<template>
  <Table
    :columns="columns"
    :rows="rows"
    :actions="[
      { id: 'edit', label: 'Edit', event: 'edit-row', icon: 'pencil' },
      { id: 'delete', label: 'Delete', event: 'delete-row', icon: 'trash' }
    ]"
    @edit-row="handleEdit"
    @delete-row="handleDelete"
  />
</template>

<script setup>
const handleEdit = (row) => {
  console.log('Edit:', row);
};

const handleDelete = (row) => {
  console.log('Delete:', row);
};
</script>
```

### With Search and Sort

```vue
<template>
  <Table
    :columns="columns"
    :rows="rows"
    show-search
    :sort-by="sortBy"
    :sort-order="sortOrder"
    @search="handleSearch"
    @sort="handleSort"
  />
</template>

<script setup>
import { ref } from 'vue';

const sortBy = ref('');
const sortOrder = ref('asc');

const handleSearch = (query) => {
  // Filter rows based on query
};

const handleSort = ({ field, order }) => {
  sortBy.value = field;
  sortOrder.value = order;
  // Sort rows
};
</script>
```

### Complete Example with API

```vue
<template>
  <Table
    :columns="columns"
    :rows="tableData"
    :loading="loading"
    :total="total"
    :current-page="currentPage"
    :per-page="perPage"
    title="Users"
    show-search
    show-filter
    show-pagination
    enable-auto-fetch
    :actions="actions"
    @search="search"
    @filter="applyFilters"
    @page-change="changePage"
    @per-page-change="changePerPage"
    @edit-row="editRow"
    @delete-row="deleteRow"
  />
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { Table } from '@jalzae/vue-table';

const columns = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { key: 'email', label: 'Email' },
];

const tableData = ref([]);
const loading = ref(false);
const total = ref(0);
const currentPage = ref(1);
const perPage = ref(10);

const actions = [
  { id: 'edit', label: 'Edit', event: 'edit-row', icon: 'pencil' },
  { id: 'delete', label: 'Delete', event: 'delete-row', icon: 'trash' },
];

const fetchData = async (page = 1, query = '', filters = []) => {
  loading.value = true;
  try {
    const response = await fetch(
      `/api/users?page=${page}&perPage=${perPage.value}&search=${query}&filters=${JSON.stringify(filters)}`
    );
    const data = await response.json();
    tableData.value = data.rows;
    total.value = data.total;
  } finally {
    loading.value = false;
  }
};

const search = (query) => {
  currentPage.value = 1;
  fetchData(1, query);
};

const applyFilters = (filters) => {
  currentPage.value = 1;
  fetchData(1, '', filters);
};

const changePage = (page) => {
  currentPage.value = page;
  fetchData(page);
};

const changePerPage = (per) => {
  perPage.value = per;
  currentPage.value = 1;
  fetchData(1);
};

const editRow = (row) => {
  // Handle edit
  console.log('Edit:', row);
};

const deleteRow = (row) => {
  // Handle delete
  console.log('Delete:', row);
};

onMounted(() => {
  fetchData();
});
</script>
```

## Components

### Base Components

All base components are available for use:

```typescript
import {
  Table,
  Button,
  Icon,
  Empty,
  Pagination,
  Toggle,
} from '@jalzae/vue-table';
```

### Icon Component

```vue
<Icon icon="search" size="16" color="currentColor" />
```

Available icons: `search`, `filter`, `chevrondown`, `chevronup`, `x`, `plus`, `trash`, `pencil`, `eye`, `download`, `upload`, `save`, `elipsisvertical`, and more.

### Button Component

```vue
<Button variant="primary" size="md" @click="handleClick">
  Click Me
</Button>
```

Variants: `primary`, `secondary`, `danger`, `success`, `warning`, `info`, `ghost`, `cancel`

Sizes: `sm`, `md`, `lg`

## Utilities

Helper functions are available:

```typescript
import {
  formatNumber,
  formatDecimal,
  formatDate,
  debounce,
  throttle,
  isEmpty,
  // ... more utilities
} from '@jalzae/vue-table';
```

## 🔧 Development

### Setup

Clone the repository and install dependencies:

```bash
git clone https://github.com/yourusername/jalz-table.git
cd jalz-table
npm install
```

### Development Server

Start the Vite development server with interactive demo:

```bash
npm run dev
```

This starts a local server at `http://localhost:5173` with a complete interactive demo showing:
- Basic table functionality
- All components (Button, Icon, Toggle, Pagination, etc.)
- All filter components with edit capabilities
- Theming and dark mode
- Complete documentation

### Nuxt 3 Integration

To test with Nuxt 3, create a Nuxt project and link this package:

```bash
# In your Nuxt project
npm install ../path-to-jalz-table

# Or using npm link
cd ../jalz-table
npm link
cd ../your-nuxt-project
npm link @jalzae/vue-table
```

Then add to your `nuxt.config.ts`:

```typescript
export default defineNuxtConfig({
  modules: [
    '@jalzae/vue-table/nuxt'
  ]
})
```

### Build

Build the library for production:

```bash
npm run build
```

This generates:
- `dist/index.js` - UMD bundle
- `dist/index.es.js` - ES module
- `dist/styles/` - CSS files
- `dist/types/` - TypeScript declarations

### Preview Build

Test the production build locally:

```bash
npm run preview
```

### Type Checking

Run TypeScript type checking:

```bash
npm run type-check
```

### Linting

Check and fix code style:

```bash
npm run lint
```

## 📁 Project Structure

```
jalz-table/
├── src/
│   ├── components/
│   │   ├── Table.vue              # Main table component
│   │   ├── base/                  # Base components
│   │   │   ├── Button.vue
│   │   │   ├── Icon.vue
│   │   │   ├── Empty.vue
│   │   │   ├── Pagination.vue
│   │   │   └── Toggle.vue
│   │   └── Filter/                # Filter components
│   │       ├── Text.vue
│   │       ├── Number.vue
│   │       ├── DateFilter.vue
│   │       ├── Select.vue
│   │       ├── Toggle.vue
│   │       ├── Amount.vue
│   │       ├── Day.vue
│   │       ├── Like.vue
│   │       ├── Submission.vue
│   │       └── Comment.vue
│   ├── styles/
│   │   ├── variables.css          # CSS custom properties
│   │   └── base.css               # Global styles
│   ├── types/
│   │   └── index.ts               # TypeScript types
│   ├── utils/
│   │   └── helpers.ts             # Utility functions
│   ├── App.vue                    # Demo app
│   ├── main.ts                    # Entry point for dev
│   └── index.ts                   # Library exports
├── index.html                     # Dev server entry
├── vite.config.ts
├── tsconfig.json
├── package.json
└── README.md
```

## 🎨 Customization

### CSS Variables

Override default CSS variables in your global CSS:

```css
:root {
  --color-primary: #your-color;
  --spacing-md: 1.2rem;
  --radius-lg: 1rem;
  /* ... more variables */
}
```

See [src/styles/variables.css](./src/styles/variables.css) for all available variables.

### Dark Mode

Enable dark mode by setting the `data-theme` attribute:

```javascript
document.documentElement.setAttribute('data-theme', 'dark')
```

Or with conditional rendering:

```html
<div :data-theme="isDarkMode ? 'dark' : null">
  <!-- Your app here -->
</div>
```

## 📝 License

MIT - See [LICENSE](./LICENSE) for details

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 💬 Support

For issues and questions, please visit [GitHub Issues](https://github.com/yourusername/jalz-table/issues)