UNPKG

@dcodegroup-au/vuetable-3

Version:

Datatable component for Vue 3.x built with Vite/ESM

264 lines (236 loc) 6.25 kB
import { Meta, ArgsTable, Story, Preview } from "@storybook/addon-docs/blocks"; import { action } from "@storybook/addon-actions"; import { linkTo } from "@storybook/addon-links"; import Vuetable from "../components/Vuetable.vue"; import CustomCell from "../components/cells/CustomCell.vue"; import CSS from "./vuetable-css.js"; <Meta title="custom-cells" component={Vuetable} /> # Custom Cells Vue components can be used as the cell template by importing one and replacing the name value with it. Below is an example of how a component needs to be set up to be useable with vuetable-3. ```html <script lang="ts"> import { Component, Prop } from "vue-property-decorator"; import { mixins } from "vue-class-component"; import VuetableFieldMixin from "../../components/VuetableFieldMixin.vue"; @Component({ name: "CustomCell", components: {}, mixins: [VuetableFieldMixin] }) export default class CustomCell extends mixins() { /** * Indicate whether Field Component should render the "header" or "data" * template section. */ @Prop({ default: false }) isHeader!: boolean; /** * The title option from field definition object is passed via title prop. * You can simply use title prop to render column title if there is no * special need other than display the column title. */ @Prop({ default: "" }) title!: string; @Prop({ default: () => null }) rowData!: string; @Prop({ default: -1 }) rowIndex!: number; /** * The field definition object of this field. Remember that you can use * field definition object to hold additional data, parameters, or results. */ @Prop({ default: () => null }) rowField!: object; /** * The click event needs to be bound on the header to have it bubble up for * sorting purposes. */ onHeaderClick(event: unknown) { this.$emit("click", event); } } </script> <template> <th v-if="isHeader" scope="col" @click="onHeaderClick">{{ title }}</th> <td v-else>{{ rowData.name }}</td> </template> ``` <Preview> <Story name="CellComponent"> {{ components: { Vuetable }, props: { fields: { default: () => [ { name: CustomCell, title: "Name" }, { name: "email", title: "Email Address" }, { name: "phone", titleClass: "center aligned", dataClass: "center aligned" } ] } }, template: ` <vuetable api-url="https://my-json-server.typicode.com/mannyyang/vuetable-3/users" pagination-path="" data-path="" :fields="fields" > </vuetable> ` }} </Story> </Preview> ## Using a cutom cell with sort <Preview> <Story name="CellComponentWithSort"> {{ components: { Vuetable }, props: { css: { default: () => CSS }, fields: { default: () => [ { name: CustomCell, title: "Name", sortField: "name" }, { name: "email", title: "Email Address" }, { name: "phone", titleClass: "center aligned", dataClass: "center aligned" } ] } }, template: ` <vuetable api-url="https://my-json-server.typicode.com/mannyyang/vuetable-3/users" :css="css.table" :query-params="{ page: '_page', sort: '_sort', perPage: '_limit', order: '_order' }" pagination-path="" data-path="" :fields="fields" > </vuetable> ` }} </Story> </Preview> In order to use Vue components as the sort icon, you'll need to update the css object that is passed to vuetable-3. ```js // Imported as `CSS` found in code example above. import SortIcon from "./SortIcon"; export default { table: { tableWrapper: "", tableHeaderClass: "fixed", tableBodyClass: "fixed", ..., // When using the `renderSortComp` to use a component for the sort icon, // the css strings needs to be cleared out or else it'll add the `<i>` as an // html string. renderIcon: () => "", // Vue component will automatically pass the current order through `order` // prop. renderSortComp: SortIcon }, pagination: { ... }, paginationInfo: { ... } }; ``` The custom cell component needs to insert a slot to indicate where the sort icon is going to be. ```html // CustomCell.vue <template> <th v-if="isHeader" @click="onHeaderClick"> {{ title }} <slot /> </th> <td v-else>Row cell data</td> </template> ``` ## Using an Initial Sort Order You set the initial sort and order through the sort order property. Although it takes an array as a property, we currently only support sorting by one column. <Preview> <Story name="CellComponentWithInitialSort"> {{ components: { Vuetable }, props: { css: { default: () => CSS }, fields: { default: () => [ { name: CustomCell, title: "Name", sortField: "name" }, { name: "email", title: "Email Address", sortField: "email" }, { name: "phone", titleClass: "center aligned", dataClass: "center aligned" } ] } }, template: ` <vuetable api-url="https://my-json-server.typicode.com/mannyyang/vuetable-3/users" :css="css.table" :query-params="{ page: '_page', sort: '_sort', perPage: '_limit', order: '_order' }" :sort-order="[ { sortField: 'email', direction: 'desc' } ]" pagination-path="" data-path="" :fields="fields" > </vuetable> ` }} </Story> </Preview>