DataTable for Quasar

🇪🇸 Versión en español | 🇧🇷 Versão em português

npm version license Vue Quasar TypeScript Node

Quasar extension with a homologated DataTable: shell over QTable, unified client/server pagination, and cards on viewports < sm.

Table of contents

In 30 seconds

  1. Install the extension: quasar ext add @benjaminor-dev/datatable.
  2. Import DataTable in your Vue component.
  3. Pass rows, columns, row-key, and v-model:pagination.
  4. Add client-pagination for built-in client pagination (or server-pagination + emits when you control the backend).

The extension registers CSS and a defaults boot in the host automatically.

What it is and what it includes

DataTable is a presentation layer over Quasar QTable: optional bordered shell, pagination bar (TablePaginationBar), and card layout on mobile.

Requirements and compatibility

Item Value
Node >= 20.0.0
Quasar ^2.6.0
Vue ^3.4.18
Package format ES modules
Recommended CLI @quasar/app-vite ^2.x or ^3.x

Install in a Quasar app

quasar ext add @benjaminor-dev/datatable

After quasar ext add, the extension registers CSS and the defaults boot automatically. No extra steps for a normal npm install.

Remove:

quasar ext remove @benjaminor-dev/datatable

Removes the generated defaults boot and its quasar.config entry. Stylesheet injection may remain if another installed package registers the same CSS path.

What the extension adds to the host

Resource Host path
Styles ~@benjaminor-dev/quasar-app-extension-datatable/main.css
Host defaults boot src/boot/bor/bor-datatable-defaults.ts — created on install; Skip/Overwrite if it exists

Install (quasar ext add / invoke): creates src/boot/bor/bor-datatable-defaults.ts (or .js) and registers it in quasar.configboot: [] automatically. No manual editing needed in a normal install. main.css is injected on every dev/build (it does not appear as a short entry in quasar.config).

Remove (quasar ext remove): removes the defaults boot and its quasar.config entry when the extension created it.

Boot order (this extension):

1. bor/bor-datatable-defaults (host)
2. rest of your boots

In quasar.config you only see bor/bor-datatable-defaults; main.css is injected by the extension at compile time.

Global defaults (boot)

Edit src/boot/bor/bor-datatable-defaults.ts after install to pin locale or override pagination strings:

import { configureDataTableDefaults } from "@benjaminor-dev/quasar-app-extension-datatable";

configureDataTableDefaults({
  // locale: "es", // pin en | es | pt; omit to follow $q.lang
  // messages: { allRows: "Show all" },
});

configureDataTable is an alias of configureDataTableDefaults. Priority: boot locale$q.lang.isoNameen; boot messages merge over the built-in catalog.

Quick start

<script setup lang="ts">
import { ref } from "vue";
import DataTable from "@benjaminor-dev/quasar-app-extension-datatable";
import type { ClientTablePaginationState } from "@benjaminor-dev/quasar-app-extension-datatable/types";

const rows = [
  { id: 1, name: "Ana", role: "Admin" },
  { id: 2, name: "Luis", role: "Editor" },
];

const columns = [
  { name: "name", label: "Name", field: "name", align: "left" as const },
  { name: "role", label: "Role", field: "role", align: "left" as const },
];

const pagination = ref<ClientTablePaginationState>({
  sortBy: "name",
  descending: false,
  page: 1,
  rowsPerPage: 10,
});
</script>

<template>
  <DataTable
    v-model:pagination="pagination"
    :rows="rows"
    :columns="columns"
    row-key="id"
    :client-pagination="{ defaultPageSize: 10 }"
  />
</template>

Language (i18n)

Built-in en, es, and pt. By default the pagination bar follows Quasar language ($q.lang.isoName); if Quasar has no language, fallback is en.

Locale resolution: boot locale$q.lang.isoName prefix (es*es, pt*pt) → en.

Option When to use
framework.lang in quasar.config.ts Recommended — aligns DataTable with the rest of Quasar
locale: 'es' in boot Pin a specific language (en | es | pt); ignores $q.lang changes
messages: { allRows: '…' } in boot Change one string without setting locale

Quasar config example (Spanish for the whole app):

// quasar.config.ts
framework: {
  lang: "es",
},

Built-in message keys: navigation aria labels, rows-per-page labels, page indicator ({page}, {lastPage}), range format ({start}, {end}, {total}), and allRows.

TypeScript in your IDE

Do not memorize the API — let autocomplete guide you.

import DataTable, {
  useDataTableGridLayout,
  buildDynamicRowsPerPageOptions,
} from "@benjaminor-dev/quasar-app-extension-datatable";

import type {
  ClientTablePaginationState,
  DataTableServerPaginationConfig,
  DataTablePaginationPlacement,
} from "@benjaminor-dev/quasar-app-extension-datatable/types";

DataTable component API

Prop Type Default Description
rows readonly Record<string, unknown>[] Rows to display
columns QTableProps['columns'] Quasar columns
row-key string | fn Row key
grid boolean auto true = cards; false = table on mobile; omitted = cards below < sm
bordered boolean true Shell border
flat boolean true QTable flat
dense boolean true QTable dense
client-pagination DataTableClientPaginationConfig Built-in client pagination
server-pagination DataTableServerPaginationConfig Server state + bar
pagination-placement DataTablePaginationPlacement 'auto' Bar position
selection 'single' | 'multiple' Row selection
loading boolean false Loading state
hide-pagination boolean true Hides native QTable pagination

Emits (server mode): pageSizeChange, first, previous, next, last.

Slots: item (grid card), top, bottom, standard QTable column slots.

Client-side pagination

<DataTable
  v-model:pagination="pagination"
  :rows="rows"
  :columns="columns"
  row-key="id"
  :client-pagination="{
    defaultPageSize: 10,
    placement: 'auto',
    pageSizeLadder: [5, 10, 25, 50],
  }"
/>

Server-side pagination

The parent controls pagination and listens to emits. Pass derived state in server-pagination:

import type { DataTableServerPaginationConfig } from "@benjaminor-dev/quasar-app-extension-datatable/types";

const serverPagination = computed<DataTableServerPaginationConfig>(() => ({
  totalRows: store.total,
  pageSize: store.pageSize,
  lastPage: store.lastPage,
  pageSizeOptions: store.pageSizeOptions,
  rangeLabel: store.rangeLabel,
  enabled: store.hasSearched,
}));

The same helpers (buildDynamicRowsPerPageOptions, resolveDataTablePaginationPlacement, …) are exportable from this package.

Mobile layout (grid / cards)

By default, viewports ≤ 599px use grid layout (cards).

<script setup lang="ts">
import { computed } from "vue";
import { useDataTableGridLayout } from "@benjaminor-dev/quasar-app-extension-datatable";

const isMobileGridRef = useDataTableGridLayout();
const isMobileGrid = computed(() => isMobileGridRef.value);
</script>

<template>
  <DataTable :grid="isMobileGrid" ... />
</template>

Custom card via #item slot:

<template #item="props">
  <MyCard :row="props.row" :cols="props.cols" />
</template>

Compact reference

Symbol Entry Note
DataTable . Main component (default export)
TablePaginationBar . Standalone bar
useClientTablePagination . Client logic + handlers
useDataTableGridLayout . Mobile breakpoint (singleton)
buildDynamicRowsPerPageOptions . / /types Page-size selector options
resolveDataTablePaginationPlacement . / /types top / bottom from placement
shouldShowDataTablePaginationBar . / /types Show bar?
ClientTablePaginationState /types v-model:pagination
DataTableClientPaginationConfig /types client-pagination prop
DataTableServerPaginationConfig /types server-pagination prop
DataTablePaginationPlacement /types 'auto' | 'top' | 'bottom' | 'both'

| configureDataTableDefaults | . / /types | Global i18n / locale boot | | ExtensionLocale | /types | "en" \| "es" \| "pt" |

Full type list and reexports: import /types and use IDE autocomplete.

If something is missing from autocomplete, check the import (/types vs main entry) before searching the README.

Public entrypoints

Entrypoint Contents
@benjaminor-dev/quasar-app-extension-datatable DataTable, TablePaginationBar, composables, utils, i18n (configureDataTableDefaults, resolveDataTableMessages)
@benjaminor-dev/quasar-app-extension-datatable/types Types + typed helper reexports
@benjaminor-dev/quasar-app-extension-datatable/main.css Styles (registered in quasar.config on install)

Troubleshooting

Symptom Likely cause Fix
Table without styles Extension not installed or CSS missing quasar ext add @benjaminor-dev/datatable; check quasar.configcss
Pagination bar missing Few rows vs first ladder step Expected when totalRows ≤ minPageSizeStep
Narrow cards on mobile #item slot root not full width width: 100% on slot root or dt-data-table-grid-* classes
TS error Ref<boolean> on :grid Ref imported from external package computed(() => layoutRef.value) in the consumer
Pagination texts in English Quasar language not set or boot locale missing Set framework.lang in quasar.config or configureDataTableDefaults({ locale: 'es' }) in boot
Defaults boot missing after remove Partial uninstall or manual delete quasar ext add @benjaminor-dev/datatable again

MIT © Benjamín Olvera R.