Skip to content

Instantly share code, notes, and snippets.

@daronspence
Created August 24, 2022 19:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daronspence/3b9f852388c349b150fcbdc466569c7e to your computer and use it in GitHub Desktop.
Save daronspence/3b9f852388c349b150fcbdc466569c7e to your computer and use it in GitHub Desktop.
A table component to act as the base for larger table features.
<script>
const BaseTable = {
props: {
fields: {
type: Array,
default: [],
validator(fields) {
return fields.find(field => field?.key === undefined || field?.label === undefined) === undefined
},
},
rows: {
type: Array,
default: [],
},
emptyMessage: {
type: String,
default: 'No rows found.',
},
tableClass: {
default: 'm-0 table-fixed overflow-hidden rounded-lg',
},
headClass: {
default: 'bg-neutral_interactive_ui_bg',
},
headRowClass: {
default: 'uppercase',
},
headCellClass: {
default: 'p-2 text-xs font-bold text-ui_txt_secondary',
},
rowClass: {
default: '',
},
cellClass: {
default: 'p-2',
},
},
methods: {
getKey(row) {
return (row?.key || row?.id) ?? JSON.stringify(row)
},
},
computed: {
visibleFieldKeys() {
return Object.entries(this.fields).map(([_key, value]) => value.key)
},
},
}
export default BaseTable
</script>
<template>
<table :class="tableClass">
<slot name="thead" :css="headClass">
<thead :class="headClass">
<slot name="headRow" :css="headRowClass">
<tr :class="headRowClass">
<template v-for="field in fields">
<slot :name="`head(${field.key})`" :field="field" :value="field.label" :css="headCellClass">
<th :key="field.key" :class="field.class || headCellClass">
{{ field.label }}
</th>
</slot>
</template>
</tr>
</slot>
</thead>
</slot>
<tbody v-if="rows.length">
<template v-for="row in rows">
<slot :name="`row(${getKey(row)})`" :row="row" :css="rowClass">
<tr :key="getKey(row)" :class="rowClass">
<template v-for="objectKey in visibleFieldKeys">
<slot :name="`cell(${objectKey})`" :value="row[objectKey]" :row="row" :css="cellClass">
<td :class="cellClass" :key="objectKey">
{{ row[objectKey] }}
</td>
</slot>
</template>
</tr>
</slot>
</template>
</tbody>
<tbody v-else>
<slot name="no-data-row">
<tr :class="rowClass">
<slot name="no-data-cell">
<td :colspan="fields.length" :class="cellClass">{{ emptyMessage }}</td>
</slot>
</tr>
</slot>
</tbody>
</table>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment