npm package: @itcroja/itc-table
Description: A flexible data table component for Vue 3 + Quasar applications
Author: ITC
Latest version: 1.0.0

# ITC Table

A flexible data table component for Vue 3 + Quasar applications. Built on top of Quasar's QTable with dynamic props, aliases, and slot passthrough for maximum reusability.

## Features

- ✅ **Vue 3** with Composition API
- ✅ **Quasar Framework** – Wraps QTable
- ✅ **TypeScript** for type safety
- ✅ **Vite** for fast builds
- ✅ **Path Aliases** – Import without relative paths (e.g., `src/consts`)
- ✅ **Dual Format Build** – ES Modules and CommonJS
- ✅ **Preserved Directory Structure** – Maintains `src/` structure in output
- ✅ **Dynamic Props** – Multiple aliases for rows, columns, pagination
- ✅ **Slot Passthrough** – All QTable slots supported
- ✅ **Server-side Pagination** – Built-in `@request` support

## Getting Started

### Prerequisites

- Node.js 20.19+ or 22.12+
- pnpm (recommended) or npm/yarn

### Installation

1. **Install the package:**

   ```bash
   pnpm add itc-table
   # or
   npm install itc-table
   ```

2. **Register the plugin (optional – for global components):**

   **Quasar projects** – Add to `quasar.config.js`:

   ```js
   boot: ['itc-table']
   ```

   **Vue projects** – In `main.ts`:

   ```typescript
   import { itcTable } from 'itc-table'
   app.use(itcTable)
   ```

3. **Or import directly:**

   ```vue
   <script setup>
   import { DataTable } from 'itc-table'
   </script>
   ```

## Usage

### Basic Example

```vue
<template>
  <DataTable
    :rows="rows"
    :columns="columns"
    row-key="id"
  />
</template>

<script setup>
import { ref } from 'vue'
import { DataTable } from 'itc-table'

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

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

### Prop Aliases

Use whichever prop names fit your project:

| Purpose        | Aliases                                      |
|----------------|-----------------------------------------------|
| Row data       | `rows`, `data`, `taskList`, `collectionData` |
| Visible columns| `visibleColumns`, `customColumns`             |
| Pagination     | `pagination`, `paginationData`               |

```vue
<!-- CardsTable style -->
<DataTable
  :task-list="tasks"
  :custom-columns="customColumns"
  :pagination-data="paginationData"
  :columns="columns"
  @request="onRequest"
/>

<!-- Simple style -->
<DataTable
  :data="items"
  :visible-columns="visibleColumns"
  :columns="columns"
/>
```

### Server-side Pagination

```vue
<DataTable
  :rows="rows"
  :columns="columns"
  :pagination-data="paginationData"
  @request="onRequest"
/>
```

```javascript
const paginationData = ref({
  page: 1,
  rowsPerPage: 25,
  rowsNumber: 100,  // Total rows from API
  sortBy: 'id',
  descending: true
})

const onRequest = ({ pagination }) => {
  paginationData.value = { ...paginationData.value, ...pagination }
  fetchData()
}
```

### Slots

All QTable slots are forwarded. Use any slot you need:

```vue
<DataTable :rows="rows" :columns="columns">
  <template #body-cell-name="props">
    <q-td :props="props">
      <strong>{{ props.value }}</strong>
    </q-td>
  </template>
</DataTable>
```

### Path Aliases

This package supports importing files using the `src/` prefix:

```typescript
// ✅ Good - Using path alias
import { DEFAULT_ROWS_PER_PAGE } from 'src/consts'
import DataTable from 'src/components/DataTable.vue'

// ❌ Avoid - Relative paths (still works, but not recommended)
import { DEFAULT_ROWS_PER_PAGE } from '../consts'
```

### Project Structure

```
├─ src/
│   ├─ components/
│   │   └─ DataTable.vue
│   ├─ consts.ts
│   ├─ plugin.ts
│   ├─ index.ts
│   └─ vue-shim.d.ts
├─ dist/                   # Build output (generated)
├─ package.json
├─ tsconfig.json
└─ vite.config.ts
```

## API Reference

### Props

| Prop               | Type     | Default | Description                          |
|--------------------|----------|---------|--------------------------------------|
| rows / data / taskList / collectionData | `any[]` | -       | Table data (first defined wins)      |
| columns            | `TableColumn[]` | -    | Column definitions                   |
| rowKey             | `string` | `'id'`  | Unique row key                       |
| pagination / paginationData | `TablePagination` | - | Pagination state                     |
| visibleColumns / customColumns | `string[]` | - | Column names to show                 |
| loading            | `boolean`| `false` | Loading state                        |
| flat               | `boolean`| `true`  | Flat style                           |
| bordered           | `boolean`| `false` | Show borders                         |
| separator          | `string` | `'horizontal'` | Cell separator                 |
| dense              | `boolean`| `false` | Dense mode                           |
| hidePagination     | `boolean`| `false` | Hide pagination                      |
| wrapCells          | `boolean`| `false` | Wrap cell content                   |
| selection          | `string` | `'none'`| `'single'` \| `'multiple'` \| `'none'` |
| selected           | `any[]`  | `[]`    | Selected rows (v-model:selected)     |

### Events

| Event              | Payload | Description                    |
|--------------------|---------|--------------------------------|
| request            | `{ pagination, filter?, getCellValue? }` | Server-side pagination/sort |
| update:pagination   | `TablePagination` | Pagination changed        |
| update:selected    | `any[]` | Selection changed              |

### Exports

```typescript
import {
  DataTable,
  itcTable,
  DEFAULT_ROWS_PER_PAGE_OPTIONS,
  DEFAULT_ROWS_PER_PAGE
} from 'itc-table'

import type { TableColumn, TablePagination } from 'itc-table'
```

## Building

### Build for Production

```bash
pnpm run build
# or
npm run build
```

This will:

- Compile TypeScript to JavaScript
- Bundle Vue components
- Generate both ES Modules (`.js`) and CommonJS (`.cjs`) formats
- Output to `dist/` directory with preserved `src/` structure
- Generate TypeScript declaration files

### Build Output Structure

```
dist/
└─ src/
   ├─ index.js              # ES Module entry
   ├─ index.cjs             # CommonJS entry
   ├─ index.d.ts            # Type declarations
   ├─ components/
   │   └─ DataTable.vue.js
   └─ ...
```

## Testing Locally

### Option 1: Using pnpm link (Recommended)

1. **In your itc-table directory:**

   ```bash
   pnpm link --global
   ```

2. **In your test project:**

   ```bash
   pnpm link --global itc-table
   ```

3. **Use in your project:**

   ```vue
   <script setup>
   import { DataTable } from 'itc-table'
   </script>
   ```

### Option 2: Using File Path

1. **In your test project's `package.json`:**

   ```json
   {
     "dependencies": {
       "itc-table": "file:../itc-table"
     }
   }
   ```

2. **Install:**

   ```bash
   pnpm install
   ```

3. **Use in your project:**

   ```vue
   <script setup>
   import { DataTable } from 'itc-table'
   </script>
   ```

### Unlinking After Local Development

When you're done with local development:

#### For Option 1 (pnpm/npm link):

1. **In your test project**, unlink the package:

   ```bash
   pnpm unlink --global itc-table
   ```

2. **Reinstall the package** from npm:

   ```bash
   pnpm install itc-table
   ```

#### For Option 2 (File Path):

1. **Remove the file path dependency** from your test project's `package.json`

2. **Reinstall:**

   ```bash
   pnpm install itc-table
   ```

### Development Workflow

For active development with auto-rebuild:

```bash
pnpm run dev
```

Changes will rebuild automatically. Restart your test project's dev server to pick up changes.

## Publishing to npm

### Before Publishing

1. **Update `package.json`:**

   - Set correct `name` (must be unique on npm)
   - Update `version` (follow [semver](https://semver.org/))
   - Add `description`, `keywords`, `author`, `license`
   - Verify `files` array: `["dist"]`

2. **Build the package:**

   ```bash
   pnpm run build
   ```

3. **Test the build locally** (see Testing Locally section above)

### Publishing Steps

1. **Login to npm:**

   ```bash
   npm login
   ```

2. **Verify you're logged in:**

   ```bash
   npm whoami
   ```

3. **Check what will be published:**

   ```bash
   npm pack --dry-run
   ```

4. **Publish:**

   ```bash
   npm publish
   ```

### Version Management

```bash
npm version patch   # 1.0.0 → 1.0.1
npm version minor   # 1.0.0 → 1.1.0
npm version major   # 1.0.0 → 2.0.0
npm publish
```

## Configuration

### Peer Dependencies

The package expects the consumer to provide:

- `vue` ^3.5.25
- `quasar` ^2.18.6

### External Dependencies

`vue` and `quasar` are externalized (not bundled). To add more, update `vite.config.ts`:

```typescript
rollupOptions: {
  external: (id) => {
    return (
      id === 'vue' ||
      id === 'quasar' ||
      id.startsWith('@quasar/') ||
      id.startsWith('quasar/')
    )
  }
}
```

## Troubleshooting

### TypeScript Errors

- **"Cannot find module 'src/...'"**: Restart TypeScript server
- **"Cannot find module 'path'"**: Ensure `@types/node` is installed
- **Path aliases not working**: Check both `tsconfig.json` and `vite.config.ts` have matching aliases

### Build Errors

- **"Rollup failed to resolve import"**: Add the package to `external` in `vite.config.ts`
- **QTable not rendering**: Ensure `quasar` is installed in the host project and Quasar CSS is loaded

### Import Errors in Test Project

- Ensure the package is built (`pnpm run build`)
- Check `package.json` exports are correct
- Verify the import path: `import { DataTable } from 'itc-table'`

## License

MIT

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Build and test locally
5. Submit a pull request

---

**Happy coding! 🚀**