Skip to content

MazTable ​

MazTable is designed to be a reusable data table with advanced features. Pagination, Search, Column Sorting, Row Selection, UI options, Loading and Slots.

Before use it, you should install the MazUi plugin in your project, follow instructions in Getting Started

Key Features ​

  1. Pagination (prop pagination)
    • The component supports pagination with buttons to go to the first, previous, next, and last page.
    • You can display only the pagination elements (input and buttons) and make API calls to your server to get elements by using the prop pagination with no-paginate-rows.
  2. Search (prop search): It includes a search feature with a search bar where users can enter a query to filter displayed data. You can choose the column where the search will be activated.
  3. Column Sorting (prop: sortable): Columns are sortable, indicated by arrow icons. Sorting can be activated by clicking on the column header.
  4. Row Selection (prop select-value="key"): There is a dedicated column for selection with a checkbox for each row. Users can individually or collectively select/deselect rows.
  5. Customizable Page Size: Users can choose the number of items to display per page using a dropdown list.
  6. Loading Indicator (prop loading): A loading indicator (MazLoadingBar) is displayed when data is being loaded.
  7. Animated rows (props animated-rows + row-key): rows slide to their new position when the order changes (FLIP animation). Respects prefers-reduced-motion.
  8. Virtualization (prop virtualized): render only the rows visible in the viewport (plus an overscan) so the table stays fast with thousands of rows.

Available models ​

  • v-model: (string | boolean | number)[] | undefined (list of selected key)
  • v-model:search-query: string | undefined
  • v-model:page: number
  • v-model:page-size: number

Basic usage ​

You can use MazTable and his child component to build a simple table and enjoy the style.

#LastnameFirstnameAge
1 John Doe 99
2 Doe John 30

Advanced data table ​

You can also provide all your data, the table is auto-generated and you can use the features listed on top


v-model="[ "0262672d-7c7a-4d30-866e-edb88b5a5336" ]"

v-model:search-query="undefined"

v-model:page="1"

v-model:page-size="10"

Competitions
#Name
Code
Type
Area
Actions
1
avatar image
UEFA Champions League
CLCUPEurope
2
avatar image
Premier League
PLLEAGUEEngland
3
avatar image
Serie A
SALEAGUEItaly
4
avatar image
FIFA World Cup
WCCUPWorld
5
avatar image
Primeira Liga
PPLLEAGUEPortugal
6
avatar image
Primera Division
PDLEAGUESpain
7
avatar image
Ligue 1
FL1LEAGUEFrance
8
avatar image
European Championship
ECCUPEurope
9
avatar image
Eredivisie
DEDLEAGUENetherlands
10
avatar image
Championship
ELCLEAGUEEngland

Animated rows ​

Enable animated-rows to make rows slide to their new position when the order changes (FLIP animation) - perfect for live leaderboards or sortable lists. Provide a stable row-key (a field uniquely identifying each row) so every row keeps its identity across reorders. The animation is automatically disabled when the user prefers reduced motion.



#NameScore
1John12
2Jane24
3Alice8
4Bob31

Virtualization ​

Enable virtualized to render only the rows inside the viewport (plus an overscan) instead of every row. This keeps the table fast and the DOM light even with tens of thousands of rows. It works in rows mode (data-driven), and @tanstack/vue-virtual is loaded on demand - pages that never virtualize a table never ship it.

The example below renders 10 000 rows but only keeps ~20 <tr> in the DOM at any time.

#NameEmailScore

Options ​

PropDefaultDescription
virtualizedfalseTurns virtualization on.
max-height-Required. Bounds the scroll viewport (any CSS length, e.g. '400px', '70vh'). Scrolling is enabled automatically and the header stays sticky.
estimated-row-height44Fixed row height (in px) used to place rows and size the spacers. Set it to your real row height; virtualized rows should be uniform (single line).
overscan10Rows rendered outside the viewport on each side.

Good to know ​

  • Set a width (or minWidth) on your headers. Virtualization forces table-layout: fixed so columns stay aligned across the rendered window; without widths the browser distributes them equally.
  • Accessibility: the table exposes aria-rowcount and each rendered row an aria-rowindex, so screen readers still announce "row X of N".
  • Ignored (with a dev warning) when animated-rows is enabled or when you provide a custom default slot - those paths render every row.
  • Rendered client-side: the virtualized body is empty during SSR and fills in on hydration.

Loading ​

Enable the loading state with the prop loading

#LastnameFirstnameAge
1 John Doe 99
2 Doe John 33
3 Max Simth 66

Sizing ​

Available sizes: 'mini' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'

#LastnameFirstnameAge
1 John Doe 99

#LastnameFirstnameAge
1 John Doe 99

#LastnameFirstnameAge
1 John Doe 99

Types ​

Property row ​

The rows property is an array of Row: type Rows = Row[]

ts
type Row =  Record<string, any> & {
  selected?: boolean
  action?: (row: Row) => unknown
  classes?: HTMLAttributes['class']
}

Property headers ​

The headers property has type: type Headers = string | HeadersEnriched[]

ts
export interface MazTableHeadersEnriched {
  label: string
  key?: string
  sortable?: boolean
  hidden?: boolean
  srOnly?: boolean
  width?: string
  maxWidth?: string
  minWidth?: string
  classes?: ThHTMLAttributes['class']
  scope?: ThHTMLAttributes['scope']
  align?: ThHTMLAttributes['align']
  rowspan?: ThHTMLAttributes['rowspan']
  colspan?: ThHTMLAttributes['colspan']
  headers?: ThHTMLAttributes['headers']
}

Accessibility ​

  • The column headers have scope="col" by default (override it with the scope of the header).
  • A sortable column header exposes its state with aria-sort (ascending, descending or none), is focusable and sorted with Enter or Space.
  • The selection checkboxes are labelled from @maz-ui/translations (aria.selectAll, aria.selectRow).

Props & Events emitted ​

Props ​

NameDescriptionTypeRequiredDefaultPossible values
table-classCSS class of the table elementClassValueNo--
table-styleCSS style of the table elementStyleValueNo--
model-valuev-model List of selected rows(string | number | boolean)[]No--
sizeSize of the table"xs" | "sm" | "md" | "lg" | "xl" | "mini"Nomd'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'mini'
input-sizeSize of the search inputs"xs" | "sm" | "md" | "lg" | "xl" | "mini"No-'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'mini'
titleTitle of the tablestringNo--
headersHeaders of the tableMazTableHeader[]No--
sortableEnable sort feature on all columnsbooleanNofalse-
headers-alignAlign all headers"left" | "right" | "justify" | "center" | "char"No"left"'left' | 'right' | 'justify' | 'center' | 'char'
rowsRows of the tableT[]No--
hoverableAdd hover effect on rowsbooleanNofalse-
searchEnable search feature in table headerbooleanNofalse-
hide-search-in-rowDisable search in rows - useful to filter data yourself or make search request to serverbooleanNofalse-
hide-search-byDisable search by column (remove select input "search by")booleanNofalse-
search-queryv-model:search-query Search query in inputstringNo--
background-oddAdd background color to odd rowsbooleanNofalse-
background-evenAdd background color to even rowsbooleanNofalse-
elevationAdd shadow to the tablebooleanNofalse-
divideradd divider between rowsbooleanNofalse-
captionCaption of the tablestringNo--
caption-sideCaption side"bottom" | "top"No"bottom"'bottom' | 'top'
paginationAdd pagination in table footerbooleanNofalse-
pagev-model:page Current page of paginationnumberNo1-
page-sizev-model:page-size Number of items per pagenumberNo20-
total-pagesTotal number of pagesnumberNo--
paginate-rowsDon't paginate rows - useful to make pagination request with your serverbooleanNotrue-
total-itemsTotal number of itemsnumberNo--
loadingLoading statebooleanNofalse-
selectableEnable selection of rowsbooleanNofalse-
selected-keyEnable selection of rows - key of the selected rowstringNo--
table-layoutTable layout"auto" | "fixed"No-'auto' | 'fixed'
colorColor of the component"primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent"No"primary"'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'destructive' | 'contrast' | 'transparent'
translationsTranslations of the table{ noResults?: string | undefined; actionColumnTitle?: string | undefined; searchByInput?: { all?: string | undefined; placeholder?: string | undefined; } | undefined; searchInput?: { placeholder?: string | undefined; } | undefined; pagin...NoTranslations from-
rounded-sizeSize radius of the component's borderMazRoundedSizeNomd'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'
scrollableEnable scrollable on tablebooleanNofalse-
row-keyField name used as a stable key for each row (e.g. an id). Gives every row a stable identity so reordering is tracked correctly - required for animatedRows to look right. Falls back to the row index when not provided.stringNo--
animated-rowsAnimate row reordering with a FLIP transition (rows slide to their new position). Provide a stable rowKey for meaningful results. Respects prefers-reduced-motion.booleanNofalse-
virtualizedOnly render the rows visible in the viewport (plus an overscan) using @tanstack/vue-virtual. Keeps the table fast on thousands of rows. Requires maxHeight to bound the scroll viewport. Ignored when animatedRows is on or when a custom default slot is provided. Rows render client-side only.booleanNofalse-
max-heightMax height of the scroll viewport (any CSS length, e.g. '400px', '70vh'). Enables scrolling and, when virtualized, bounds the virtualized viewport.stringNo--
estimated-row-heightFixed row height in pixels used by the virtualizer to place rows and size the spacers. Set it to your real row height (virtualized rows should be uniform).numberNo44-
overscanNumber of rows rendered outside the viewport on each side when virtualized.numberNo10-

Events ​

Event namePayloadDescription
update:model-value(string | number | boolean | MazTableRow<T>)[] | undefinedEmitted when a row is selected
update:search-querystring | undefinedEmitted when entering a value in the search input
update:pagenumberEmitted when the current page of pagination changes
update:page-sizenumberEmitted when the page size of pagination changes

Slots ​

NameDescriptionBindings
titleReplace the title of the table-
captionAdd caption on top or bottom of the table-
theadContent in thead element-
headerReplace column headerheader MazTableHeadersNormalized - Header data
label string - Header label
actions-headerReplace text of actions header-
default-
selectReplace checkbox componentrow T - Row data
selected boolean - If selected or not
cellReplace all row cellsrow T - Row data
value any - Cell value
actionsAdd actions columnrow T - Row data
no-resultsReplace the no results element-
no-results-textreplace no results test only-
header-label-One slot per key: #header-label-<key>.-
cell-One slot per key: #cell-<key>. Replace all row cellsrow T - Row data
value any - Cell value

MazTableCell ​

Slots ​

NameDescriptionBindings
default-

MazTableRow ​

Props ​

NameDescriptionTypeRequiredDefaultPossible values
hoverableOverride hoverable of table propsbooleanNotrue-
is-headIf true, the row is a head rowbooleanNofalse-

Slots ​

NameDescriptionBindings
default-

MazTableTitle ​

Slots ​

NameDescriptionBindings
default-