I have this table component and I'm facing an issue with the @click event not firing on safari while being working just fine on chrome
<table class="h-full w-full">
<thead class="sticky top-0 rounded bg-gray-100 shadow-sm">
<tr class="t-head">
<th
v-for="column in visibleCols"
:key="column.index"
class="min-w-fit whitespace-nowrap rounded border-r p-3 text-left font-medium text-gray-800 last:border-0"
@mouseenter="showSortIcon({ column })"
@mouseleave="hideSortIcon({ column })"
>
<div class="flex item-center gap-3">
<div>{{ column.displayName || "" }}</div>
<button
v-if="isSortEnabled && (column as Column).isSortable"
class="hover:text-indigo-600 transition-opacity duration-300 ease-in-out"
:class="[
activeSortColumn.column == column || (sortIconState.column == column && sortIconState.visible)
? 'opacity-100'
: 'opacity-0',
]"
@click="onSortIconClicked(column)"
>
<i
class="fa-solid fa-arrow-up transition-all duration-300 ease-in-out"
:class="[column == activeSortColumn.column && activeSortColumn.isDesc ? 'rotate-180' : 'rotate-0']"
/>
</button>
</div>
</th>
</tr>
</thead>
<tbody v-if="loading" class="bg-white">
<tr>
<td :colspan="visibleCols.length">
<div class="flex">
<i class="fa-solid fa-circle-notch m-auto animate-spin text-3xl text-indigo-600"></i>
</div>
</td>
</tr>
</tbody>
<tbody v-else-if="data && data.length !== 0 && visibleCols.length !== 0" class="bg-white">
<tr
v-for="(row, index) in data"
:key="index"
class="border-b last:border-0"
:class="{ 'cursor-pointer hover:bg-gray-100': areRowsClickable }"
@click="handleRowClick(row)"
>
<td
v-for="cell in visibleCols"
:key="cell.index"
class="min-w-fit whitespace-nowrap border-r px-3 py-2 text-left last:border-0"
:class="cell.class"
>
<component :is="cell.component(row, emit)" v-if="!('accessor' in cell) && cell.component !== undefined" />
<span v-else-if="'accessor' in cell && cell.component === undefined && row[cell.accessor] !== null">
{{ row[cell.accessor] }}
</span>
<component
:is="cell.component(row[cell.accessor])"
v-else-if="'accessor' in cell && cell.component !== undefined"
/>
<span v-else>---</span>
</td>
</tr>
</tbody>
<tbody v-else class="bg-white">
<tr>
<td :colspan="visibleCols.length">
<slot name="empty-state">
<div class="flex h-[200px]">
<span class="m-auto">No data to display</span>
</div>
</slot>
</td>
</tr>
</tbody>
</table>
Also the tailwind hover
effect is not showing as well.
I inspected the page and found out the following:
My solution was the following: I changed the whole table structure to use divs instead. I utilized the following Tailwind classes:
The final result looked something like this
<div class="table w-full table-auto" :class="gridCols">
<!-- HEADER -->
<div class="sticky top-0 table-row bg-gray-200">
<div
v-for="column in visibleCols"
:key="column.index"
class="table-cell whitespace-nowrap border-b border-r border-gray-300 p-3 text-left font-medium text-gray-800 last:border-r-0"
@mouseenter="showSortIcon({ column })"
@mouseleave="hideSortIcon({ column })"
>
<div class="item-center flex gap-3">
<div>{{ column.displayName || "" }}</div>
<button
v-if="isSortEnabled && (column as Column).isSortable"
class="transition-opacity duration-300 ease-in-out hover:text-indigo-600"
:class="[
activeSortColumn.column == column || (sortIconState.column == column && sortIconState.visible)
? 'opacity-100'
: 'opacity-0',
]"
@click="onSortIconClicked(column)"
>
<i
class="fa-solid fa-arrow-up transition-all duration-300 ease-in-out"
:class="[column == activeSortColumn.column && activeSortColumn.isDesc ? 'rotate-180' : 'rotate-0']"
/>
</button>
</div>
</div>
</div>
<!-- BODY -->
<div v-if="data?.length && !isLoading" class="table-row-group">
<div
v-for="row in data"
:key="row"
class="table-row border bg-white last:border-0"
:class="areRowsClickable ? 'cursor-pointer hover:bg-gray-100' : ''"
@click="handleRowClick(row)"
>
<div
v-for="cell in visibleCols"
:key="cell.displayName"
class="table-cell whitespace-nowrap border-b border-r px-3 py-2 last:border-r-0"
>
<!-- VIRTUAL COLUMN -->
<component :is="cell.component(row, emit)" v-if="!('accessor' in cell) && cell.component !== undefined" />
<!-- NORMAL COLUMN -->
<span v-else-if="'accessor' in cell && cell.component === undefined && row[cell.accessor] !== null">
{{ row[cell.accessor] }}
</span>
<!-- CUSTOM COLUMN -->
<component
:is="cell.component(row[cell.accessor])"
v-else-if="'accessor' in cell && cell.component !== undefined"
/>
<!-- EMPTY STATE -->
<span v-else>---</span>
</div>
</div>
</div>
</div>
Don't know why that worked tho! but it seems like Safari doesn't support <table>
tags to be clickable