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
- 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
paginationwithno-paginate-rows.
- 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. - Column Sorting (prop:
sortable): Columns are sortable, indicated by arrow icons. Sorting can be activated by clicking on the column header. - 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. - Customizable Page Size: Users can choose the number of items to display per page using a dropdown list.
- Loading Indicator (prop
loading): A loading indicator (MazLoadingBar) is displayed when data is being loaded. - Animated rows (props
animated-rows+row-key): rows slide to their new position when the order changes (FLIP animation). Respectsprefers-reduced-motion. - 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.
| # | Lastname | Firstname | Age |
|---|---|---|---|
| 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"
| # | Name | Code | Type | Area | Actions | |
|---|---|---|---|---|---|---|
| 1 | CL | CUP | Europe | |||
| 2 | PL | LEAGUE | England | |||
| 3 | SA | LEAGUE | Italy | |||
| 4 | WC | CUP | World | |||
| 5 | PPL | LEAGUE | Portugal | |||
| 6 | PD | LEAGUE | Spain | |||
| 7 | FL1 | LEAGUE | France | |||
| 8 | EC | CUP | Europe | |||
| 9 | DED | LEAGUE | Netherlands | |||
| 10 | ELC | LEAGUE | England |
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.
| # | Name | Score |
|---|---|---|
| 1 | John | 12 |
| 2 | Jane | 24 |
| 3 | Alice | 8 |
| 4 | Bob | 31 |
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.
| # | Name | Score |
|---|
Options
| Prop | Default | Description |
|---|---|---|
virtualized | false | Turns 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-height | 44 | Fixed 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). |
overscan | 10 | Rows rendered outside the viewport on each side. |
Good to know
- Set a
width(orminWidth) on your headers. Virtualization forcestable-layout: fixedso columns stay aligned across the rendered window; without widths the browser distributes them equally. - Accessibility: the table exposes
aria-rowcountand each rendered row anaria-rowindex, so screen readers still announce "row X of N". - Ignored (with a dev warning) when
animated-rowsis 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
| # | Lastname | Firstname | Age |
|---|---|---|---|
| 1 | John | Doe | 99 |
| 2 | Doe | John | 33 |
| 3 | Max | Simth | 66 |
Sizing
Available sizes: 'mini' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
| # | Lastname | Firstname | Age |
|---|---|---|---|
| 1 | John | Doe | 99 |
| # | Lastname | Firstname | Age |
|---|---|---|---|
| 1 | John | Doe | 99 |
| # | Lastname | Firstname | Age |
|---|---|---|---|
| 1 | John | Doe | 99 |
Types
Property row
The rows property is an array of Row: type Rows = Row[]
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[]
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 thescopeof the header). - A sortable column header exposes its state with
aria-sort(ascending,descendingornone), 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
| Name | Description | Type | Required | Default | Possible values |
|---|---|---|---|---|---|
| table-class | CSS class of the table element | ClassValue | No | - | - |
| table-style | CSS style of the table element | StyleValue | No | - | - |
| model-value | v-model List of selected rows | (string | number | boolean)[] | No | - | - |
| size | Size of the table | "xs" | "sm" | "md" | "lg" | "xl" | "mini" | No | md | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'mini' |
| input-size | Size of the search inputs | "xs" | "sm" | "md" | "lg" | "xl" | "mini" | No | - | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'mini' |
| title | Title of the table | string | No | - | - |
| headers | Headers of the table | MazTableHeader[] | No | - | - |
| sortable | Enable sort feature on all columns | boolean | No | false | - |
| headers-align | Align all headers | "left" | "right" | "justify" | "center" | "char" | No | "left" | 'left' | 'right' | 'justify' | 'center' | 'char' |
| rows | Rows of the table | T[] | No | - | - |
| hoverable | Add hover effect on rows | boolean | No | false | - |
| search | Enable search feature in table header | boolean | No | false | - |
| hide-search-in-row | Disable search in rows - useful to filter data yourself or make search request to server | boolean | No | false | - |
| hide-search-by | Disable search by column (remove select input "search by") | boolean | No | false | - |
| search-query | v-model:search-query Search query in input | string | No | - | - |
| background-odd | Add background color to odd rows | boolean | No | false | - |
| background-even | Add background color to even rows | boolean | No | false | - |
| elevation | Add shadow to the table | boolean | No | false | - |
| divider | add divider between rows | boolean | No | false | - |
| caption | Caption of the table | string | No | - | - |
| caption-side | Caption side | "bottom" | "top" | No | "bottom" | 'bottom' | 'top' |
| pagination | Add pagination in table footer | boolean | No | false | - |
| page | v-model:page Current page of pagination | number | No | 1 | - |
| page-size | v-model:page-size Number of items per page | number | No | 20 | - |
| total-pages | Total number of pages | number | No | - | - |
| paginate-rows | Don't paginate rows - useful to make pagination request with your server | boolean | No | true | - |
| total-items | Total number of items | number | No | - | - |
| loading | Loading state | boolean | No | false | - |
| selectable | Enable selection of rows | boolean | No | false | - |
| selected-key | Enable selection of rows - key of the selected row | string | No | - | - |
| table-layout | Table layout | "auto" | "fixed" | No | - | 'auto' | 'fixed' |
| color | Color of the component | "primary" | "secondary" | "accent" | "info" | "success" | "warning" | "destructive" | "contrast" | "transparent" | No | "primary" | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'destructive' | 'contrast' | 'transparent' |
| translations | Translations of the table | { noResults?: string | undefined; actionColumnTitle?: string | undefined; searchByInput?: { all?: string | undefined; placeholder?: string | undefined; } | undefined; searchInput?: { placeholder?: string | undefined; } | undefined; pagin... | No | Translations from | - |
| rounded-size | Size radius of the component's border | MazRoundedSize | No | md | 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full' |
| scrollable | Enable scrollable on table | boolean | No | false | - |
| row-key | Field 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. | string | No | - | - |
| animated-rows | Animate row reordering with a FLIP transition (rows slide to their new position). Provide a stable rowKey for meaningful results. Respects prefers-reduced-motion. | boolean | No | false | - |
| virtualized | Only 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. | boolean | No | false | - |
| max-height | Max height of the scroll viewport (any CSS length, e.g. '400px', '70vh'). Enables scrolling and, when virtualized, bounds the virtualized viewport. | string | No | - | - |
| estimated-row-height | Fixed 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). | number | No | 44 | - |
| overscan | Number of rows rendered outside the viewport on each side when virtualized. | number | No | 10 | - |
Events
| Event name | Payload | Description |
|---|---|---|
| update:model-value | (string | number | boolean | MazTableRow<T>)[] | undefined | Emitted when a row is selected |
| update:search-query | string | undefined | Emitted when entering a value in the search input |
| update:page | number | Emitted when the current page of pagination changes |
| update:page-size | number | Emitted when the page size of pagination changes |
Slots
| Name | Description | Bindings |
|---|---|---|
| title | Replace the title of the table | - |
| caption | Add caption on top or bottom of the table | - |
| thead | Content in thead element | - |
| header | Replace column header | header MazTableHeadersNormalized - Header datalabel string - Header label |
| actions-header | Replace text of actions header | - |
| default | - | |
| select | Replace checkbox component | row T - Row dataselected boolean - If selected or not |
| cell | Replace all row cells | row T - Row datavalue any - Cell value |
| actions | Add actions column | row T - Row data |
| no-results | Replace the no results element | - |
| no-results-text | replace no results test only | - |
| header-label- | One slot per key: #header-label-<key>. | - |
| cell- | One slot per key: #cell-<key>. Replace all row cells | row T - Row datavalue any - Cell value |
MazTableCell
Slots
| Name | Description | Bindings |
|---|---|---|
| default | - |
MazTableRow
Props
| Name | Description | Type | Required | Default | Possible values |
|---|---|---|---|---|---|
| hoverable | Override hoverable of table props | boolean | No | true | - |
| is-head | If true, the row is a head row | boolean | No | false | - |
Slots
| Name | Description | Bindings |
|---|---|---|
| default | - |
MazTableTitle
Slots
| Name | Description | Bindings |
|---|---|---|
| default | - |