Organisms
TsTableBuilder(DynamicTable)
Overview
The TsTableBuilder component is a dynamic and editable table solution for Builder.io. It allows users to seamlessly add or adjust rows and columns directly within the Builder editor, enabling flexible and customizable table layouts for content creation.
Component Code
<template>
<ClientOnly>
<div
:class="twMerge('ts-content overflow-hidden border rounded-xl border-natural-light-grey font-medium text-natural-black bg-ideal-white', props.appendClass)"
:data-testid="`${table_title}-table-container`"
>
<table
:class="twMerge(
'ts-table w-full border-collapse overflow-auto'
)"
:data-testid="`${table_title}-table`"
>
<thead
v-if="table_columns.length > 0"
class="bg-natural-soft-white"
:data-testid="`${table_title}-table-head`"
>
<tr
:data-testid="`${table_title}-table-head-row`"
>
<th
v-for="(cell, index) in table_columns"
:key="`head-cell-${index}`"
:data-testid="`${table_title}-table-head-cell-${index}`"
class="border-r last:border-r-0 "
:style="{
backgroundColor: cell.backgroundColor ? cell.backgroundColor : 'inherit',
width: cell.width ? cell.width : '',
textAlign: cell.textAlign ? cell.textAlign : 'left'
}"
>
<div
:data-testid="`${table_title}-table-head-cell-${index}-container`"
class="inline-flex items-center"
>
<NuxtImg
v-if="cell.image && cell.image.src"
:src="cell.image.src"
:data-testid="`${table_title}-table-head-cell-${index}-image`"
class="mr-2 max-w-max h-auto"
:height="`${cell.image.height || cell.image.size}`"
:width="`${cell.image.width || cell.image.size}`"
/>
<Icon
v-if="cell.icon && cell.icon.name"
:name="cell.icon.name"
class="mr-2 last:mr-0 text-idle-black"
:size="`${cell.icon.size}`"
:style="{
color: `${cell.icon.color}`
}"
/>
<div
v-if="cell.value"
v-html="cell.value"
:data-testid="`${table_title}-table-head-cell-${index}-value`"
/>
</div>
</th>
</tr>
</thead>
<tbody
v-if="table_rows.length"
class="bg-[#FAFAFA]"
:data-testid="`${table_title}-table-body`"
>
<tr
v-for="(row, row_index) in table_rows"
:key="`row-${row_index}`"
:data-testid="`${table_title}-table-body-row-${row_index}`"
class="border-b last:border-b-0"
:style="{
backgroundColor: row.backgroundColor ? row.backgroundColor : 'inherit'
}"
>
<template v-if="row.cells && row.cells.length">
<td
v-for="(cell, cell_index) in row.cells"
:key="`row-${row_index}-cell-${cell_index}`"
:data-testid="`${table_title}-table-body-row-${row_index}-cell-${cell_index}`"
class="max-h-fit border-r last:border-r-0"
:style="{
backgroundColor: cell.backgroundColor ? cell.backgroundColor : 'inherit',
textAlign: cell.textAlign ? cell.textAlign : 'left'
}"
>
<div
class="inline-flex items-center"
:data-testid="`${table_title}-table-body-row-${row_index}-cell-${cell_index}-container`"
>
<NuxtImg
v-if="cell.image && cell.image.src"
:data-testid="`${table_title}-table-body-row-${row_index}-cell-${cell_index}-image`"
:src="cell.image.src"
class="mr-2 last:mr-0"
:height="`${cell.image.height || cell.image.size}`"
:width="`${cell.image.width || cell.image.size}`"
/>
<Icon
v-if="cell.icon && cell.icon.name"
:name="cell.icon.name"
class="mr-2 last:mr-0 text-idle-black"
:size="`${cell.icon.size}`"
:style="{
color: cell.icon.color
}"
/>
<div
v-if="cell.value"
v-html="cell.value"
:data-testid="`${table_title}-table-body-row-${row_index}-cell-${cell_index}-value`"
/>
</div>
<div v-if="cell.link && cell.link.label">
<NuxtLinkWithLocale
v-if="cell.link.path"
:to="cell.link.path"
class="text-primary"
>
{{ cell.link.label }}
</NuxtLinkWithLocale>
<div v-else>
{{ cell.link.label }}
</div>
</div>
</td>
</template>
</tr>
</tbody>
</table>
</div>
</ClientOnly>
</template>
<script setup lang="ts">
import {twMerge} from "tailwind-merge";
type Cell = {
value: any;
backgroundColor?: string;
textAlign?: 'left' | 'center' | 'right';
image?: {
src?: string;
size?: string | number;
width?: string | number;
height?: string | number;
};
icon?: {
name?: string;
size?: string | number;
color?: string;
};
link?: {
label?: string;
path?: string;
}
}
type Row = {
cells: Cell[];
backgroundColor?: string;
}
type CommonStyles = {
backgroundColor: string;
}
type TableStyles = CommonStyles & {}
type ColumnStyles = CommonStyles & {
width: string;
}
type BodyStyles = CommonStyles & {}
type Props = {
title: string;
columns?: Cell[];
rows: Row[];
appendClass?: string;
tableStyles?: TableStyles;
columnStyles?: ColumnStyles;
bodyCellStyles?: BodyStyles;
}
const props = withDefaults(defineProps<Props>(), {});
const table_title = computed(() => {
if(props.title) {
return props.title.split(" ").join("-").toLowerCase();
}
})
const table_columns = computed(() => {
if(props.columns && props.columns.length) {
return props.columns;
}
return [];
})
const table_rows = computed(() => {
if(props.rows && props.rows.length) {
return props.rows;
}
return [];
})
const header_cell_styles = computed(() => {
if(props.columnStyles) {
return props.columnStyles;
}
return {};
})
const body_cell_styles = computed(() => {
return props.bodyCellStyles;
})
</script>
<style scoped>
table, thead, tbody, tr, th, td {
border-color: inherit;
}
th {
padding: 1rem 0.75rem;
font-size: 1rem;
}
td {
padding: 0.75rem;
background-color: #D1D5DB;
font-size: 0.875rem;
line-height: 1.25rem;
}
.payment-methods th,
.payment-methods td {
border-right-width: 0;
}
@media (min-width: 1024px) {
.payment-methods th,
.payment-methods td {
border-right-width: 1px;
}
}
</style>
Usage in Builder
- Go to the
inserttab. - Search
DynamicTablein search bar. - Hold
DynamicTablecomponent & drag where you want to use.
Props
| Name | Type | Default | Description |
|---|---|---|---|
| title* | string | "" | Title of table is required and it's should be unique for all table in a page. |
| columns | Cell[] | "" | Each column is a collection of cells in which each cell have same props which are: value, backgroundColor, textAlign, image, icon and link. |
| rows | Row[] | "" | Rows are collection of row in which each row have same props which are: Cell[] and backgroundColor. |
| appendClass | string | "" | appendClass is used to pass classes to the rootElement of TsTableBuilder |
| tableStyles | TableStyles | "" | In TableStyles user can edit the background color of whole table backgroundColor. |
| columnStyles | ColumnStyles | "" | In ColumnStyles user can edit the backgroundColor of column header and width of column. |
| bodyCellStyles | BodyStyles | "" | In BodyStyles user can edit the backgroundColor of body cell. |