feat: generic table implementation
This commit is contained in:
committed by
Joel Jacob Stephen
parent
d5e4211347
commit
a875ab1ca9
@@ -5,42 +5,36 @@
|
|||||||
<tr
|
<tr
|
||||||
class="text-secondary border-b border-dividerDark text-sm text-left"
|
class="text-secondary border-b border-dividerDark text-sm text-left"
|
||||||
>
|
>
|
||||||
<th v-for="title in headings" scope="col" class="px-6 py-3">
|
<th v-for="th in headings" scope="col" class="px-6 py-3">
|
||||||
{{ title }}
|
{{ th.label ?? th.key }}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody class="divide-y divide-divider">
|
<tbody class="divide-y divide-divider">
|
||||||
<tr
|
<tr
|
||||||
v-for="(item, rowIndex) in list"
|
v-for="(rowData, rowIndex) in list"
|
||||||
:key="rowIndex"
|
:key="rowIndex"
|
||||||
class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl"
|
class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl"
|
||||||
:class="yBorder ? 'divide-x divide-divider' : ''"
|
:class="yBorder ? 'divide-x divide-divider' : ''"
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
v-for="(data, colIndex) in item"
|
v-for="cellHeading in headings"
|
||||||
:key="colIndex"
|
:key="cellHeading.key"
|
||||||
@click="$emit('openRowContent', item)"
|
@click="onRowClicked(rowData)"
|
||||||
class="max-w-40"
|
class="max-w-40"
|
||||||
:class="cellStyles"
|
:class="cellStyles"
|
||||||
>
|
>
|
||||||
<!-- Custom implementation of the particular column -->
|
<!-- Dynamic column slot -->
|
||||||
|
<slot :name="cellHeading.key" :item="rowData">
|
||||||
<div v-if="modifyColNames?.includes(colIndex.toString())">
|
<!-- Generic implementation of the column -->
|
||||||
<slot :name="colIndex.toString()" :item="item"></slot>
|
<div class="flex flex-col truncate">
|
||||||
</div>
|
<span class="truncate">
|
||||||
|
{{ rowData[cellHeading.key] ?? "-" }}
|
||||||
<!-- Generic implementation of the column -->
|
</span>
|
||||||
<div v-else class="flex flex-col truncate">
|
</div>
|
||||||
<span v-if="data" class="truncate">
|
</slot>
|
||||||
{{ data }}
|
|
||||||
</span>
|
|
||||||
<span v-else class=""> - </span>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- <slot name="action" :item="item"></slot> -->
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -48,20 +42,24 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup generic="Item extends Record<string, unknown>">
|
<script lang="ts" setup generic="Item extends Record<string, unknown>">
|
||||||
|
export type CellHeading = { label?: string; key: string }
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
/** Whether to show the vertical border between columns */
|
/** Whether to show the vertical border between columns */
|
||||||
yBorder?: boolean
|
yBorder?: boolean
|
||||||
/** The list of items to be displayed in the table */
|
/** The list of items to be displayed in the table */
|
||||||
list: Item[]
|
list: Item[]
|
||||||
/** The headings of the table */
|
/** The headings of the table */
|
||||||
headings: string[]
|
headings: CellHeading[]
|
||||||
/** The styles to be applied to the table cells */
|
/** The styles to be applied to the table cells */
|
||||||
cellStyles?: string
|
cellStyles?: string
|
||||||
/** The names of the columns which have to modified using slots */
|
|
||||||
modifyColNames?: string[]
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "openRowContent", item: Item): void
|
(event: "onRowClicked", item: Item): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const onRowClicked = (item: Item) => {
|
||||||
|
emit("onRowClicked", item)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user