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 🙏

© 2025 – Pkg Stats / Ryan Hefner

vi-grid-builder

v2.3.49

Published

The grid builder component dynamically generates tables based on the provided `rows` data and a JSON `columns` configuration.

Readme

Grid builder plugin for Vue 3

The grid builder component dynamically generates tables based on the provided rows data and a JSON columns configuration.

Key Features

1. Column Types

  • 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.

2. Data Handling

  • Accepts data in the rows prop to populate the table.
  • Supports cell-level customization for data formatting.

3. Pagination

  • Built-in pagination for handling large datasets.
  • Configurable to match specific requirements (e.g., rows per page).

4. Customizable Styles

  • Provides options to style the table (e.g., striped rows, borders).
  • Supports global configs and per-instance overrides.

Installation

npm install vi-grid-builder

Integrate plugin in Vue app

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";

Examples

If you want to see usage examples download the project and run

cd playgorund
npm run dev

Table options

| 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

Header options

| option | type | decsription | default value |--------|--------|---------------------|--------------- | title | String | title for the table | /

Header slots

| 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

Columns options

| 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 | / |

Aditional columsn options for sepcific fields

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'} |

Example config for columns

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'
            }
        ]
    },
]

Table body slots

| 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

Registering custom field type

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

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

Pagination otpions

| 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 | /

CSS CLASSES

| 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 |

GLOBAL SETTINGS

Grid props that can be set globally

  • 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')

Date field global settings

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'
});

Css variables and global overwriting of the variables

| 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',
        }
})

Steps for adding changes for contributors

  • git pull origin main
  • add and test your changes in playground
  • change the version in package.json
  • vite build
  • push to git
  • npm publish