@dcodegroup-au/vuetable-3
Version:
Datatable component for Vue 3.x built with Vite/ESM
264 lines (236 loc) • 6.25 kB
text/mdx
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";
({
name: "CustomCell",
components: {},
mixins: [VuetableFieldMixin]
})
export default class CustomCell extends mixins() {
/**
* Indicate whether Field Component should render the "header" or "data"
* template section.
*/
({ 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.
*/
({ default: "" })
title!: string;
({ default: () => null })
rowData!: string;
({ 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.
*/
({ 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" ="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" ="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>