npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

flex-table-vue

v0.1.9

Published

A flexible, feature-rich Vue 3 data table component with sorting, virtual scrolling, and interactive column management. Ships a pre-built CSS bundle (flex-table-vue/style.css): Tailwind v4 utilities compiled in-repo, then @layer blocks flattened for compa

Readme

flex-table-vue

A flexible, feature-rich Vue 3 data table component with sorting, virtual scrolling, and interactive column management. Styles ship as a pre-built CSS file (Tailwind compiled in-repo); fully typed with TypeScript.

Repository: github.com/stenlitims/flexTable · npm: flex-table-vue

Features

  • Sorting — client-side and server-side sorting with configurable sort direction
  • Virtual scrolling — efficient rendering of large datasets with configurable row height and buffer
  • Column settings modal — drag-and-drop reordering, per-column visibility toggle, and width controls
  • LocalStorage persistence — user preferences (column order, visibility, width) saved per table via tableId
  • i18n-ready — all UI text labels customizable via the texts prop
  • Bundled styles — import flex-table-vue/style.css for all table/modal utilities (Tailwind is compiled inside the package; no need to add this library to your Tailwind content paths)
  • Named slotsheader-{value} and cell-{value} slots for custom rendering
  • TypeScript — complete type definitions included
  • Vue plugin — register globally with app.use()

Installation

npm install flex-table-vue

Requirements

  • Vue 3.5+
  • Styling: import flex-table-vue/style.css once (includes Tailwind Preflight and every utility class used by the components). You do not need Tailwind configured in the host app for the built-in table UI to look correct.
  • If the host app already uses Tailwind, you can keep your own setup for layouts and slot content; you typically do not need to add node_modules/flex-table-vue to Tailwind content for the library’s own markup.
  • Column reordering in the settings modal uses SortableJS, bundled in flex-table-vue.

Tailwind / PostCSS in the host app

From v0.1.8 onward, style.css is post-processed so @layer blocks are removed (rules stay the same). That avoids errors when the host app’s Tailwind v3 / PostCSS pipeline re-parses the file (e.g. @layer base is used but no matching @tailwind base). You can still import flex-table-vue/style.css like any global stylesheet.

Usage

Basic

<script setup>
import { ref } from 'vue'
import { FlexTable } from 'flex-table-vue'
import 'flex-table-vue/style.css'

const headers = [
  { text: 'Name', value: 'name', sortable: true, width: 200 },
  { text: 'Email', value: 'email', sortable: true, width: 250 },
  { text: 'Role', value: 'role', sortable: true, width: 120 },
]

const items = [
  { id: 1, name: 'Alice', email: '[email protected]', role: 'Admin' },
  { id: 2, name: 'Bob', email: '[email protected]', role: 'User' },
  { id: 3, name: 'Charlie', email: '[email protected]', role: 'Editor' },
]

const sort = ref({ by: undefined, dir: 'asc' })
</script>

<template>
  <FlexTable
    :headers="headers"
    :items="items"
    v-model:sort-table="sort"
    table-id="users-table"
  />
</template>

Global Registration

import { createApp } from 'vue'
import FlexTablePlugin from 'flex-table-vue'
import 'flex-table-vue/style.css'
import App from './App.vue'

const app = createApp(App)
app.use(FlexTablePlugin)
app.mount('#app')

After registration, use <FlexTable> anywhere without importing.

Custom Cell Rendering

Use named slots cell-{value} to customize cell content:

<FlexTable :headers="headers" :items="items">
  <template #cell-name="{ item }">
    <strong>{{ item.name }}</strong>
  </template>
  <template #cell-role="{ item }">
    <span class="badge">{{ item.role }}</span>
  </template>
</FlexTable>

Custom Header Rendering

Use named slots header-{value} to customize header content:

<FlexTable :headers="headers" :items="items">
  <template #header-name="{ header }">
    <i class="icon-user" /> {{ header.text }}
  </template>
</FlexTable>

Server-Side Sorting

<script setup>
const sort = ref({ by: 'name', dir: 'asc' })

function onServerSort(newSort) {
  // Fetch data from API with sort params
  fetchItems({ sortBy: newSort.by, sortDir: newSort.dir })
}
</script>

<template>
  <FlexTable
    :headers="headers"
    :items="items"
    v-model:sort-table="sort"
    :server-sort="true"
    @server-sort="onServerSort"
  />
</template>

Virtual Scrolling

For large datasets (1000+ rows), enable virtual scrolling:

<FlexTable
  :headers="headers"
  :items="largeDataset"
  :virtual-scroll="true"
  row-height="36"
  virtual-scroll-max-height="70vh"
  :virtual-scroll-buffer="5"
/>

i18n — Custom Text Labels

All text labels can be customized via the texts prop:

<FlexTable
  :headers="headers"
  :items="items"
  :texts="{
    emptyText: 'Немає даних',
    columnSettingsTitle: 'Налаштування колонок',
    showAllText: 'Показати всі',
    hideAllText: 'Приховати всі',
    resetWidthsText: 'Скинути ширину',
    resetAllText: 'Скинути налаштування',
    closeText: 'Закрити',
    noColumnsText: 'Немає колонок',
    widthLabel: 'px',
  }"
/>

API Reference

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | headers | TableHeader[] | [] | Column definitions (required) | | items | Record<string, unknown>[] | [] | Row data (required) | | sortTable | TableSort | { by: undefined, dir: 'asc' } | Current sort state (supports v-model) | | tableId | string | '' | Unique ID for localStorage persistence | | keyRow | string | 'id' | Property name used as row key | | serverSort | boolean | false | Disable client-side sorting, emit server-sort instead | | virtualScroll | boolean | false | Enable virtual scrolling | | rowHeight | number | 36 | Row height in pixels (for virtual scroll) | | virtualScrollMaxHeight | string | '70vh' | Max height of scrollable container | | virtualScrollBuffer | number | 5 | Extra rows rendered above/below viewport | | texts | FlexTableTexts | {} | Custom text labels for i18n |

TableHeader

interface TableHeader {
  text: string       // Display name
  value: string      // Data property key
  width?: number     // Column width in pixels (default: 100)
  sortable?: boolean // Enable sorting for this column
  visible?: boolean  // Initial visibility (default: true)
}

TableSort

interface TableSort {
  by?: string        // Sort field name
  dir?: 'asc' | 'desc'  // Sort direction
}

FlexTableTexts

| Prop | Default | Description | |------|---------|-------------| | emptyText | 'No data' | Text shown when table has no items | | columnSettingsTitle | 'Column Settings' | Title of the column settings modal | | showAllText | 'Show all' | Button text to show all columns | | hideAllText | 'Hide all' | Button text to hide all columns | | resetWidthsText | 'Reset widths' | Button text to reset column widths | | resetAllText | 'Reset all' | Button text to reset all settings | | closeText | 'Close' | Close button text | | noColumnsText | 'No columns to configure' | Text when no columns available | | widthLabel | 'px' | Width unit label |

Events

| Event | Payload | Description | |-------|---------|-------------| | update:sortTable | TableSort | Sort state changed (for v-model) | | update:headers | TableHeader[] | Headers changed (visibility, width, order) | | rowClick | Record<string, unknown> | Row was clicked | | server-sort | TableSort | Sort requested (only when serverSort is true) |

Slots

| Slot | Props | Description | |------|-------|-------------| | header-{value} | { header: TableHeader } | Custom header cell content | | cell-{value} | { item: Record, header: TableHeader } | Custom body cell content |

License

MIT