The grid builder component dynamically generates tables based on the provided rows
data and a JSON columns
configuration.
- Predefined Types:
-
text
: Displays plain text and if sortabel sorted alphabetically. -
number
: Displays number that can be formtated with NumberFormatOptions and sorted numerically . -
image
: Renders an image. -
link
: Displays hyperlinks (with customizable text and URL behavior). -
badge
: Displays styled labels or badges. -
date
: Formats and displays dates. -
actions
: Includes buttons or action elements. - Custom Types:
- Register custom field types for unique cell content rendering.
- Accepts data in the
rows
prop to populate the table. - Supports cell-level customization for data formatting.
- Built-in pagination for handling large datasets.
- Configurable to match specific requirements (e.g., rows per page).
- Provides options to style the table (e.g., striped rows, borders).
- Supports global configs and per-instance overrides.
npm install vi-grid-builder
import ViGridBuilder from "vi-grid-builder";
import {createApp} from 'vue'
import App from './App.vue'
const app = createApp(App).use(ViGridBuilder)
Import the style
@import "vi-grid-builder/style.css";
If you want to see usage examples download the project and run
cd playgorund
npm run dev
option | type | description | default value |
---|---|---|---|
rows | Array | Data that needs to be displayed in the table | / |
row-key | String | Name of the field that is unique identifier for a single row | / |
columns | Array | Config for the column (in details below) | / |
title | String | Title for the table | / |
pagination | Object | Pagination config for the rows | in detilas under pagination section |
rowsNumber | Number | Total number of rows | / |
disable-pagination | Boolean | Option to hide pagination | false |
server-mode | Boolean | Is data fetched from server | true |
fetch-server-data | Function | Function that will fetch data from server | / |
fetch-on-init | Boolean | On initialisation make request to fetch data | true |
filter | fdf | fdf | fr |
loading | Boolean | For server side loading is handled, for client side you can you this prop | false |
no-data-label | String | Text to display when there is no data in the table | No data found |
no-cell-data-label | String | Text to display if there is no value for the cell | "/" is displayed by default |
clcikable-row | Boolean | emits rowClicked event with row as argumnet | false |
option | type | decsription | default value |
---|---|---|---|
title | String | title for the table | / |
name | description | props |
---|---|---|
title | slot for displaying title on top of the table | title |
vi-header-cell-[column_name] | slot for override default header cell for each column | column |
option | type | description | default value |
---|---|---|---|
label | String | Title for the column | / |
type | text, link, image, date, badge, actions | Type of the field | text |
name | String | Name of the field for which data will be presented | / |
sortable | Boolean | Is the column sortable? | false |
isVisible | Boolean | Is the column visible? | true |
transform | Function | Function to cange | format the data before display |
align | centre, left, right | How to align the content in the cells for this column | / |
sort | Function | Compare function for sorting data in this column | / |
field type | option | type | description | default value |
---|---|---|---|---|
date | mode | date,time, dateTime | what part of the date shoudl be displayed | dateTime |
date | format | object | format of date field | {date:"yyyy-MM-dd",dateTime:"yyyy-MM-dd HH:mm:ss",time:"HH:mm:ss",} date-fns is used for formtatiin |
actions | actions | Array of object | Option for field of type action | every object should have unique action field and name for the text displayed for the action |
actions | kebab | boolean | should action menu be 'kebab type' | false |
link | String | link field | If the link field is provided, it is used as the URL, and name is used as the link text. If the link field is not provided, both the URL and link text default to the name field value. | / |
number | format | object - NumberFormatOptions | format of number field | ex: {style: 'currency',currency: 'USD'} |
text | editable | boolean | if true it will show input to edit the field value, adn willl emit event rowValueUpdated | ex: {style: 'currency',currency: 'USD'} |
columns: [{
label: 'ID',
name: 'id',
type: 'number',
sortable: true,
},
{
label: 'Title',
name: 'title',
},
{
label: 'Link',
name: 'link',
type: 'link',
// link:'link'
},
{
label: 'Link with title',
name: 'title',
type: 'link',
link: 'link'
},
{
label: 'Price',
name: 'price',
type: 'number',
sortable: true,
format: {
style: 'currency',
currency: 'USD',
}
},
{
label: 'Image',
name: 'image',
type: 'image'
},
{
label: 'Status',
name: 'status',
type: 'badge'
},
{
label: 'Date',
name: 'date',
type: 'date',
mode: 'date'
},
{
label: 'Time',
name: 'date',
type: 'date',
},
{
label: 'Simple actions',
name: 'actions',
type: 'actions',
actions: [
{
action: 'edit',
name: 'Edit post'
},
{
action: 'remove',
name: 'Remove post'
}
]
},
{
label: 'Kebab type actions',
name: 'actions',
type: 'actions',
kebab: true,
actions: [
{
action: 'edit',
name: 'Edit post'
},
{
action: 'remove',
name: 'Remove post'
}
]
},
]
name | description | props |
---|---|---|
empty-data | slot for when no data in table | / |
loading | slot for displaying loading when data is fetching from server | / |
footer | slot for overriding footer of table | pagination |
By default the gird builder for displaying data in the cells supports the following types of fields : text, **link **, image, date , badge, actions and checkbox?. If this fields does not full-fill the needs for you application you can register your own type of fields. For example if we need an "avatar" field that will display the user's picture and if there is no picture for the user it will display the user's initials. First we need to create the component for the new field, and then we need to define it in the options for the plugin. Props that you will receive for the custom field are:
- field - all options for the column
- value - value for the field or '/' if no value
- original-value - original value for the field
- row - value for the whole row (ex if the table display name and id of a user, that row would be one user)
The component can look like this
<template>
<div class="avatar">
<img v-if="row.picture"
:src="row.picture" alt="User Avatar" class="avatar-img"/>
<div v-else class="avatar-initials">{{initials}}</div>
</div>
</template>
<script>
export default {
name: 'UserAvatar',
props: {
value: {},
originalValue: {},
row: {
type: Object,
}
},
computed: {
initials() {
if (this.row.name) {
const nameParts = this.row.name.split(' ');
return nameParts.map(part => part[0].toUpperCase()).join('');
}
return '';
}
}
};
</script>
Then we need to add this component as part of the settings for the plugin. See example:
import UserAvatar from "./components/user/UserAvatar.vue";
import ViGridBuilder from "vi-grid-builder";
const app = createApp(App)
.use(ViGridBuilder, {
fieldComponents: {
UserAvatar
}
})
After adding the component in the fieldComponents we can use the new field type in the definition for the columns, like this
columns: [
{
label: 'User',
type: 'user-avatar',
name: 'picture',
}]
Pagination is passed as object in table prop, the obejct should have this fields:
name | type | description | default value |
---|---|---|---|
page | Number | number for the current page | / |
rowsPerPage | Number | number of rows displayed per page | 10 |
rowsNumber | Number | number of total avaliable rows - only for server side | / |
sortBy | array of objects | sort by field and direction | null |
name | type | description | default value |
---|---|---|---|
disablePagination | Boolean | hide pagination | false |
compactPagination | Boolean | should the pagination be compact (no pages displayed) | false |
rowsPerPageOptions | Array of obecjts | Droprdown options for displayin how many rows per page | / |
class name | description |
---|---|
.vi-table-container | wrapper around table |
.vi-table-container.loading | classes for loading state of table |
.vi-table | class for the table tag |
.vi-table.stripped | class used to apply alternating background colors to table rows |
.vi-table.bordered | class used to apply borders on table cells |
.vi-table-head | class for the head tag |
.vi-table-body | class for the tbody tag |
.vi-table-row | class for all rows in table |
.vi-header-row | class for rows only in table header |
.vi-body-row | class for rows only in table body |
.vi-body-row.selected | class for selected row |
.vi-body-row.clickable | class for clickable row |
.vi-title-row | class for row that displays the table tite |
.vi-loading-row | class for row that holds the loading bar |
.vi-no-data-row | class for row that appears when no data is avaliable in table |
.vi-cell | class for all cells in table |
.vi-header-cell | class for header cells in table |
.vi-body-cell | class for body cells in table |
.vi-header-cell-content | class that wrapes content in header cells |
.vi-select-cell | class for cells that holds checkbox for selecting row or master select |
.vi-grid-field | wraaper clas for content in body cells |
.vi-footer-row | class for last row in table that holds usually pagination |
.vi-footer-cell | class for cell in last row |
- align:
center
,left
,right
- bordered: boolean
- stripped: boolean
- disablePagination: boolean
- noDataLabel: String
- noCellDataLabel: String
- compactPagination: boolean
- rowsPerPageOptions: Array
Example:
import {createApp} from 'vue'
import App from './App.vue'
const app = createApp(App);
app.use(ViGridBuilderPlugin, {
align: 'right',
compactPagination: true,
noDataLabel: 'emtpy table data',
noCellDataLabel: 'NA',
stripped: true,
bordered: true,
rowsPerPage: 30,
rowsPerPageOptions: [{
label: 15,
value: 15
}, {
label: 20,
value: 20
}, {
label: 30,
value: 30
}, {
label: 'all',
value: 0
}],
});
app.mount('#app')
You can globally set format for date field by passing dateFormats
in the plugin options
You can globally set mode for date field by passing dateMode
in the plugin options (one of date
, dateTime
,
time
by default is dateTime
)
const app = createApp(App);
app.use(ViGridBuilderPlugin, {
dateFormats: {
time: 'HH:mm',
date: "yyyy-MM-dd",
dateTime: "yyyy-MM-dd HH:mm:ss"
},
dateMode: 'date'
});
name | usage | default value |
---|---|---|
--vi-grid-primary-color | background color of header and used as backgorund for rows on hover | rgba(0, 0, 255, 0.65) |
--vi-grid-primary-text_color | text color of header and used as text color for rows on hover | rgb(255, 255, 255) |
--vi-grid-secondary-color | background color even rows in stripped table | rgb(243, 243, 243) |
--vi-grid-text-color | color of text in tabel body cells | rgb(0, 0, 0) |
--vi-grid-color | background color for table | rgb(255, 255, 255) |
You can override this values in the options when plugin is installed:
const app = createApp(App);
app.use(ViGridBuilderPlugin, {
style:
{
'color': 'white',
'text-color': 'black',
'secondary-color': 'lightgrey',
'primary-color': '#f18080',
'primary-text-color': 'white',
}
})
- git pull origin main
- add and test your changes in playground
- change the version in package.json
- vite build
- push to git
- npm publish