Skip to content

Instantly share code, notes, and snippets.

@adaptive-shield-matrix
Last active August 2, 2023 11:14
Show Gist options
  • Save adaptive-shield-matrix/fcaa56e69f0ec702252e4e0a79b89c91 to your computer and use it in GitHub Desktop.
Save adaptive-shield-matrix/fcaa56e69f0ec702252e4e0a79b89c91 to your computer and use it in GitHub Desktop.
svelte: creating generic/dynamic svelte table by generating svelte components
<script lang="ts">
import Table2 from "./Table2.svelte"
import { generateData } from "./generateData"
const { rows, columns } = generateData()
</script>
<Table2 {rows} {columns} />
<script lang="ts">
import type { Data } from "./generateData"
export let data: Data
</script>
{"edit:" + data.name}
import type { TableColumnDef } from "@/ui/table2/TableColumnDef.tsx"
import ActionMenu from "./ActionMenu.svelte"
import type { ComponentProps, ComponentType, SvelteComponent } from "svelte"
export type Data = {
pos: number
name: string
date: string
}
export function generateData() {
const rows = generateRows()
const columns: TableColumnDef<Data>[] = [
{
name: "Position",
data: (d: Data) => d.pos,
cell: (d: Data) => d.pos.toFixed(0),
},
{
name: "Name",
data: (d: Data) => d.name,
cell: (d: Data) => d.name,
},
{
name: "Datum",
data: (d: Data) => d.date,
cell: (d: Data) => d.date,
},
{
name: "null",
data: (d: Data) => 0,
cell: (d: Data) => null,
},
{
name: "Aktion",
data: (d: Data) => "",
cell: (()=>ActionMenu) as unknown as SvelteComponent,
},
]
return { rows, columns }
}
const names = [
"Axamer Lizum Mondi | 26.3. - 31.3.2023",
"Axamer Lizum Olympia | 26.3. - 31.3.2023",
"Gang Saalbach-Hinterglemm 0312-0912",
]
function generateRow(pos: number): Data {
return {
name: names[pos],
pos: pos,
date: getRandomDate().toISOString(),
}
}
function generateRows(): Data[] {
return arrCreate(names.length, (pos) => generateRow(pos))
}
function getRandomDate() {
const maxDate = Date.now()
const timestamp = Math.floor(Math.random() * maxDate)
return new Date(timestamp)
}
function arrCreate<T>(size: number, setElement: (index: number) => T): T[] {
return Array.from(Array(size).keys()).map((i) => setElement(i))
}

it works now

<script>
import Table from "flowbite-svelte"
import TableBody from "flowbite-svelte"
import TableBodyCell from "flowbite-svelte"
import TableBodyRow from "flowbite-svelte"
import TableHead from "flowbite-svelte"
import TableHeadCell from "flowbite-svelte"
// import type { TableColumnDef } from "./TableColumnDef"
import { SvelteComponent } from "svelte"
// type T = any
// export let rows: T[]
// export let columns: TableColumnDef<T>[]
export let rows
export let columns
</script>
<Table>
<TableHead>
{#each columns as column, x (x)}
<TableHeadCell>
{column.title ?? column.name}
</TableHeadCell>
{/each}
</TableHead>
<TableBody class="divide-y">
{#each rows as row, y (y)}
<TableBodyRow>
{#each columns as column, x (x)}
<TableBodyCell>
{#if typeof column.cell === "function" && column.cell(row) === null}
{" "}
{:else if typeof column.cell === "function" && typeof column.cell(row) === "string"}
{column.cell(row)}
{:else}
<svelte:component this={column.cell()} data={row} />
{/if}
</TableBodyCell>
{/each}
</TableBodyRow>
{/each}
</TableBody>
</Table>
export type TableColumnDef<T> = {
name: string
title?: string
data: (data: T) => string | number
cell: ((data: T) => string | null) | SvelteComponent
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment