Files
DistrictCentral/imports/ui/Table.svelte

106 lines
3.1 KiB
Svelte

<script>
import { createEventDispatcher } from "svelte";
import { onMount } from "svelte";
/** @type {Array<Object>} */
export let columns;
/** @type {Array<Object>} */
export let rows;
const dispatch = createEventDispatcher();
// Create a UUID for creating unique instance styles later.
const instanceId = Date.now().toString(36) + Math.random().toString(16).slice(2);
let columnByKey;
$: {
columnByKey = {};
columns.forEach(column => {
columnByKey[column.key] = column;
});
}
let columnClasses = [];
// Create a custom class (style) for each column so we can control the column sizes.
$: {
// Remove old classes.
if(columnClasses && columnClasses.length) {
columnClasses.forEach(cls => {
try {
document.getElementsByTagName('head')[0].removeChild(cls);
}
catch(e) {console.log(e);}
});
}
// Create a unique class for each column so we can manage column sizes.
columns.forEach((column, index) => {
try {
let cls = document.createElement('style');
cls.type = 'text/css';
column.customClassName = 'svelte-' + instanceId + '-column-' + index;
cls.innerHTML = column.customClassName + "{min-width: " + column.width + "; max-width: " + column.width + "; width: " + column.width + ";}";
columnClasses[index] = cls;
document.getElementsByTagName('head')[0].appendChild(cls);
} catch(e) {console.log(e);}
});
}
// Used to create a list of classes for tags.
const asStringArray = v => [].concat(v).filter(v => typeof v === "string" && v !== "").join(" ");
let section;
let table;
// onMount(async () => {
// //let hiddenHeaders = table.querySelectorAll("tbody tr:first-child td");
// let hiddenHeaders = table.querySelectorAll("th");
// section.querySelectorAll("th").forEach((th, index) => {
// hiddenHeaders[index].style.width = th.getBoundingClientRect().width + 'px';
// });
// });
</script>
<section bind:this={section}>
<thead>
<tr>
{#each columns as column}
<th class="{column.cls} cell" style="--width-{column.key}: {column.width}; min-width: var(--width-{column.key}); max-width: var(--width-{column.key}); width: var(--width-{column.key});">{column.title}</th>
{/each}
</tr>
</thead>
</section>
<table bind:this={table}>
<thead class="table-head">
<tr class="table-head">
{#each columns as column}
<th class="{column.cls} cell table-head" style="--width-{column.key}: {column.width}; min-width: var(--width-{column.key}); max-width: var(--width-{column.key}); width: var(--width-{column.key});" data-key="{column.key}">{column.title}</th>
{/each}
</tr>
</thead>
<tbody>
{#each rows as row}
<tr>
{#each columns as column}
<td class="{column.cls} cell" style="--width-{column.key}: {column.width}; min-width: var(--width-{column.key}); max-width: var(--width-{column.key}); width: var(--width-{column.key});">{column.value(row)}</td>
{/each}
</tr>
{/each}
</tbody>
</table>
<style>
section th:not(:last-child) {
border-right: 4px solid gray;
}
.table-head {
visibility: hidden;
line-height: 0;
margin: 0;
padding: 0;
}
.cell {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>