106 lines
3.1 KiB
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>
|