Table
table.svelteTables display data in rows and columns with optional reactive cell highlighting.
Demo
| Symbol | Name | Price |
|---|---|---|
| AAPL | Apple Inc. | $178.52 |
| GOOGL | Alphabet Inc. | $141.80 |
| MSFT | Microsoft Corp. | $378.91 |
| AMZN | Amazon.com Inc. | $178.25 |
| Total Portfolio Value | $877.48 | |
Usage
001 <script lang="ts">
002 import * as Table from '$lib/components/table/index.js';
003 import Button from '$lib/components/button.svelte';
004
005 let stocks = $state([
006 { symbol: 'AAPL', name: 'Apple Inc.', price: 178.52 },
007 { symbol: 'GOOGL', name: 'Alphabet Inc.', price: 141.8 },
008 { symbol: 'MSFT', name: 'Microsoft Corp.', price: 378.91 },
009 { symbol: 'AMZN', name: 'Amazon.com Inc.', price: 178.25 }
010 ]);
011
012 function randomizePrice(index: number) {
013 const change = (Math.random() - 0.5) * 20;
014 stocks[index].price = Math.round((stocks[index].price + change) * 100) / 100;
015 }
016
017 function randomizeAll() {
018 stocks.forEach((_, i) => randomizePrice(i));
019 }
020 </script>
021
022 <div class="flex flex-col gap-4">
023 <div class="flex gap-2">
024 <Button onclick={randomizeAll}>Update All Prices</Button>
025 </div>
026
027 <Table.Root>
028 <Table.Caption
029 >Live stock prices — click "Update All Prices" to see the flash effect.</Table.Caption
030 >
031 <Table.Header>
032 <Table.Row>
033 <Table.Head>Symbol</Table.Head>
034 <Table.Head>Name</Table.Head>
035 <Table.Head class="text-right">Price</Table.Head>
036 </Table.Row>
037 </Table.Header>
038 <Table.Body>
039 {#each stocks as stock (stock.symbol)}
040 <Table.Row>
041 <Table.Cell class="font-medium">{stock.symbol}</Table.Cell>
042 <Table.Cell>{stock.name}</Table.Cell>
043 <Table.Cell reactive value={stock.price} class="text-right">
044 ${stock.price.toFixed(2)}
045 </Table.Cell>
046 </Table.Row>
047 {/each}
048 </Table.Body>
049 <Table.Footer>
050 <Table.Row>
051 <Table.Cell colspan={2}>Total Portfolio Value</Table.Cell>
052 <Table.Cell class="text-right">
053 ${stocks.reduce((sum, s) => sum + s.price, 0).toFixed(2)}
054 </Table.Cell>
055 </Table.Row>
056 </Table.Footer>
057 </Table.Root>
058 </div>
059
table.svelte
001 <script lang="ts" module>
002 import type { HTMLTableAttributes } from 'svelte/elements';
003
004 export type TableProps = HTMLTableAttributes & {
005 class?: string;
006 ref?: HTMLTableElement | null;
007 };
008 </script>
009
010 <script lang="ts">
011 let {
012 class: className = '',
013 ref = $bindable(null),
014 children,
015 ...restProps
016 }: TableProps = $props();
017 </script>
018
019 <div class="table-wrapper">
020 <table class="table {className}" bind:this={ref} {...restProps}>
021 {@render children?.()}
022 </table>
023 </div>
024
025 <style lang="postcss">
026 .table-wrapper {
027 width: 100%;
028 overflow-x: auto;
029
030 &::-webkit-scrollbar {
031 display: none;
032 }
033 scrollbar-width: none;
034 }
035
036 .table {
037 width: 100%;
038 border-collapse: collapse;
039 border-spacing: 0;
040 text-align: left;
041 }
042 </style>
043