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

@pantanal/grid

v1.5.8

Published

Vue 3 data grid with Tailwind-friendly styling

Readme

Pantanal Grid (Vue 3 + Tailwind)

npm version GitHub tag (latest by date) npm downloads GitHub last commit GitHub stars GitHub forks License: MIT Tests Coverage Deploy Vue 3 TypeScript Node.js

A feature-rich data grid for Vue 3 applications. Pantanal Grid ships with a Vite/Tailwind playground, supports both client-side and server-side data flows, exposes a typed API, and includes quality-of-life features such as keyboard navigation, persisted state, virtual scrolling, grouping, and internationalization.

👉 Live demo: https://heberalmeida.github.io/pantanal-grid/
📚 Documentation: https://heberalmeida.github.io/pantanal-grid/docs/
📦 NPM Package: @pantanal/grid


Repository layout

pantanal-grid/
├─ packages/
│  └─ pantanal-grid       # source code of the published @pantanal/grid package
├─ playground/            # Vite + Vue 3 playground showcasing usage scenarios
└─ docs/                  # VitePress documentation site

Requirements

  • Node.js ≥ 18
  • Yarn Classic (v1) with workspaces enabled

Quick start (local development)

git clone https://github.com/heberalmeida/pantanal-grid.git
cd pantanal-grid
yarn                # install dependencies
yarn dev            # launches the playground at http://localhost:5173

The playground aliases @pantanal/grid to the local source, so every change you make to the package is reflected live.

Additional scripts

yarn test           # executes vitest on the library workspace
yarn build          # builds the library (vite) and type definitions (vue-tsc)
yarn playground:build  # builds the playground itself
yarn docs:dev       # starts VitePress dev server for documentation
yarn docs:build     # builds the documentation site
yarn docs:preview   # previews the built documentation
yarn validate       # runs all tests and builds (test, build, playground:build, docs:build)
yarn prepare        # installs Git hooks (runs automatically on yarn install)
yarn workspace @pantanal/grid lint              # run eslint (if configured)

Git Hooks

Git hooks are automatically installed when you run yarn install or yarn prepare. The pre-push hook validates all builds and tests before allowing a push. See .husky/README.md for details.


Consuming the library in your project

Install the package together with the required peer dependencies:

yarn add @pantanal/grid
yarn add vue@^3                                    # if Vue is not yet installed
yarn add -D tailwindcss postcss autoprefixer       # optional but recommended for styling

Import the default stylesheet once in your application entry point:

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import '@pantanal/grid/styles.css'

createApp(App).mount('#app')

Minimal usage example:

<script setup lang="ts">
import { PantanalGrid, type ColumnDef } from '@pantanal/grid'

const rows = [
  { id: 1, name: 'Alpha', price: 9.9 },
  { id: 2, name: 'Beta', price: 19.5 }
]

const columns: ColumnDef[] = [
  { field: 'id', title: 'ID', width: 80, sortable: true, filterable: true },
  { field: 'name', title: 'Name', sortable: true, filterable: true },
  { field: 'price', title: 'Price', sortable: true }
]
</script>

<template>
  <PantanalGrid :rows="rows" :columns="columns" key-field="id" />
</template>

Core capabilities

Data Operations

  • Sorting (multi-column) with ascending/descending cycles
  • Per-column filtering with multiple operators (equals, contains, starts with, ends with, etc.)
  • Row selection: single, multiple, or disabled with checkbox support
  • Inline cell and row editing with validation support
  • Copy to clipboard functionality
  • Export to Excel, PDF, CSV, and Word (DOCX) formats

Pagination & Scrolling

  • Client-side pagination + server-side mode (:serverSide="true")
  • Custom pagination variants (simple, pages, edges)
  • Virtual scrolling for large datasets (100,000+ rows)
  • Endless scrolling mode
  • Adaptive height with custom slots

Column Management

  • Column resize and reorder (drag & drop)
  • Pinned and locked columns (left/right) with optional sticky shadows
  • Multi-column headers support
  • Column menu with customizable actions
  • Foreign key columns with lookup support
  • Custom column templates (cell, header, footer)

Data Visualization

  • Grouping with drag-and-drop UI, aggregations and expandable tree nodes
  • Aggregates (sum, avg, min, max, count) with customizable templates
  • Image columns with loading states, placeholders, and error handling
  • Custom row heights
  • Cell, row, and column styling with conditional formatting
  • Grid styles customization (striped rows, hover effects, etc.)

User Experience

  • Keyboard navigation (arrow keys + focus outline)
  • Responsive design with automatic card layout for mobile devices
  • Internationalization (en, es, pt) with pluggable messages and custom locales
  • RTL (Right-to-Left) language support
  • Customizable messages for all UI elements
  • No records customization (message, template, or function)
  • Loading states with custom templates

State Management

  • Persisted state (sort, filter, page, order, widths) via persistStateKey
  • Grid events (rowClick, cellClick, sortChange, filterChange, etc.)
  • Custom commands (edit, update, destroy, cancel)

Data Binding

  • Flexible data binding: Local arrays, REST APIs, GraphQL, WebSocket, and offline mode
  • Data source adapters (Gantt, Scheduler, TreeList, Pivot, Hierarchical)
  • Custom data providers with async support

Styling & Theming

  • Flexible styling options with CSS variables
  • Tailwind CSS support
  • Custom styling props (gridStyles, rowHoverStyles, cellHoverStyles)
  • Template-based customization
  • Customizable toolbar and command buttons

Configuration

  • Configurable props for sortable, filterable, groupable, pageable features
  • Customizable column definitions with extensive options
  • TypeScript support with full type definitions

Internationalization

<PantanalGrid locale="pt" />
<PantanalGrid locale="en" />
<PantanalGrid locale="es" />

<PantanalGrid
  locale="en"
  :messages="{ next: 'Next »', previous: '« Prev', rowsPerPage: 'Rows per page' }"
/>

You can register additional locales by calling registerLocale(code, messages) from the package.


Virtual scrolling

Virtual scrolling is an alternative to paging and optimizes grid performance when displaying huge volumes of data. Enable it using scrollable-virtual, virtual, or scrollable: { virtual: true }:

<PantanalGrid
  :rows="items"
  :columns="columns"
  scrollable-virtual
  :height="600"
  :page-size="20"
  :row-height="44"
/>

Features:

  • Renders only visible rows (typically 20-50 rows)
  • Smooth scrolling performance with 100,000+ records
  • Works with both local and remote data
  • Compatible with sorting, filtering, and inline editing
  • Supports custom row heights

See Virtualization Examples for more details.


Grouping & aggregations

Pantanal Grid supports multi-level grouping with drag-and-drop UI, optional aggregations, and group footers.

Drag-and-Drop Grouping

Enable groupable to allow users to drag column headers to a drop zone for grouping:

<PantanalGrid
  :rows="rows"
  :columns="columns"
  groupable
  key-field="id"
/>

Features:

  • Drag column headers to drop zone to group by that column
  • Multiple column grouping support
  • Reorder groups by dragging badges
  • Remove groups with × button
  • Column-level control (groupable: false on specific columns)

Programmatic Grouping

You can also set groups programmatically:

<script setup lang="ts">
import { PantanalGrid, type GroupDescriptor, type AggregateName } from '@pantanal/grid'
import '@pantanal/grid/styles.css'

const rows = [
  { id: 1, title: 'Wireless Earbuds', brand: 'Aurora', category: 'audio', price: 129.99 },
  { id: 2, title: 'Desk Lamp', brand: 'Neon', category: 'lighting', price: 49.99 },
  // ...
]

const columns = [
  { field: 'id', title: 'ID', width: 80 },
  { field: 'title', title: 'Title', filterable: true },
  { field: 'brand', title: 'Brand', filterable: true },
  { field: 'category', title: 'Category', filterable: true },
  { field: 'price', title: 'Price', sortable: true, format: (v:number) => `$ ${v.toFixed(2)}` }
]

const group: GroupDescriptor[] = [
  { field: 'category', dir: 'asc' },
  { field: 'brand', dir: 'asc' }
]

const aggregates: Record<string, AggregateName[]> = {
  price: ['sum', 'avg'],
  id: ['count']
}
</script>

<template>
  <PantanalGrid
    :rows="rows"
    :columns="columns"
    :group="group"
    :aggregates="aggregates"
    :showGroupFooters="true"
    :pageSize="10"
    :height="520"
  />
</template>

Aggregates

Calculate aggregates (sum, avg, min, max, count) for grouped or ungrouped data:

<PantanalGrid
  :rows="rows"
  :columns="columns"
  :aggregates="{ price: ['sum', 'avg'], stock: ['sum'], id: ['count'] }"
/>

Features:

  • Multiple aggregate types per column
  • Custom aggregate templates
  • Group footers with aggregate values
  • Total aggregates when not grouped
  • Internationalized aggregate labels (pt, en, es)

Tips

  • Group headers render full-width rows with the field/value and aggregate count.
  • Use the built-in footer buttons (or toggleGroup event) to expand/collapse all groups at once.
  • For server-side grouping, compute aggregates on the backend and feed the grid with pre-grouped rows.
  • See Grouping Basics Examples and Aggregates Examples for more details.

Data Binding

Pantanal Grid supports flexible data binding to various data sources:

Local Data Arrays

The simplest way to provide data is using a local array. All operations are performed client-side:

<PantanalGrid
  :rows="rows"
  :columns="columns"
  key-field="id"
/>

Remote Data Services (REST)

Use the dataProvider prop to fetch data from REST APIs:

<PantanalGrid
  :rows="rows"
  :columns="columns"
  :data-provider="dataProvider"
  server-side
  key-field="id"
/>

GraphQL

Bind to GraphQL services with queries and mutations:

<PantanalGrid
  :rows="rows"
  :columns="columns"
  :data-provider="graphqlDataProvider"
  server-side
  key-field="productID"
/>

WebSocket (Real-time)

Connect to WebSocket servers for real-time updates:

<PantanalGrid
  :rows="wsRows"
  :columns="columns"
  key-field="id"
/>

Offline Mode

Work offline with localStorage persistence:

<PantanalGrid
  :rows="offlineRows"
  :columns="columns"
  key-field="id"
  editable="inline"
/>

See Data Binding Examples for complete examples.


Server-side mode

When :serverSide="true" is set (or a dataProvider is provided), the grid stops mutating its local rows and instead emits the current sort/filter/page model. Bind to those events and fetch data from your API:

<PantanalGrid
  :rows="rows"
  :columns="columns"
  :serverSide="true"
  :total="total"
  v-model:sort="sort"
  v-model:filter="filter"
  v-model:page="page"
  v-model:pageSize="pageSize"
  @loading="isLoading = $event"
/>

Alternatively, pass a dataProvider function that returns { rows, total } and Pantanal Grid will handle pagination requests and loading state automatically.


Events

Pantanal Grid emits the following events for integration with parent components:

  • update:sort, update:page, update:pageSize, update:filter — v-model bindings
  • selectionChange — array of key values for selected rows
  • columnResize{ field, width }
  • columnReorder{ from, to }
  • toggleGroup(key, expanded)
  • rowClick — emits the clicked row
  • loading — boolean flag around asynchronous data-provider calls

Contributing

| Task | Command | |--------------------------|--------------------------------------------------------| | Install dependencies | yarn | | Run playground | yarn dev | | Run docs locally | yarn docs:dev | | Build library | yarn build | | Build docs | yarn docs:build | | Run tests | yarn test | | Format / lint | yarn workspace @pantanal/grid lint | | Prepare release | yarn changeset then yarn changeset version |

Pull requests and issues are welcome. Please ensure code is linted and tested before submitting.


License

MIT