Skip to main content
App.svelte
EditableCell.svelte
createSamples.js
<script>
import { writable } from 'svelte/store';
import { Render, Subscribe, createTable, createRender, DataBodyRow } from 'svelte-headless-table';
import { createSamples } from './createSamples';
import EditableCell from './EditableCell.svelte';

const data = writable(createSamples(100));
const updateData = (rowDataId, columnId, newValue) => {
if (['age', 'visits', 'progress'].includes(columnId)) {
newValue = parseInt(newValue);
if (isNaN(newValue)) {
// Refresh data to reset invalid values.
$data = $data;
return;
}
}
if (columnId === 'status') {
if (!['relationship', 'single', 'complicated'].includes(newValue)) {
// Refresh data to reset invalid values.
$data = $data;
return;
}
}
// In this case, the dataId of each item is its index in $data.
// You can also handle any server-synchronization necessary here.
const idx = parseInt(rowDataId);
const currentItem = $data[idx];
const key = columnId; // Cast as `keyof YourDataItem`
const newItem = {...currentItem, [key]: newValue};
console.log(newItem);
$data[idx] = newItem;
$data = $data;
// Handle any server-synchronization.
}

const table = createTable(data);
const EditableCellLabel /*: DataLabel<Sample>*/ = ({ column, row, value }) =>
createRender(EditableCell, {
row,
column,
value,
onUpdateValue: updateData,
})

const columns = table.createColumns([
table.group({
header: 'Name',
columns: [
table.column({
header: 'First Name',
cell: EditableCellLabel,
accessor: 'firstName',
}),
table.column({
header: () => 'Last Name',
cell: EditableCellLabel,
accessor: 'lastName',
}),
],
}),
table.group({
header: 'Info',
columns: [
table.column({
header: 'Age',
cell: EditableCellLabel,
accessor: 'age',
}),
table.column({
header: 'Status',
cell: EditableCellLabel,
id: 'status',
accessor: (item) => item.status,
}),
table.column({
header: 'Visits',
cell: EditableCellLabel,
accessor: 'visits',
}),
table.column({
header: 'Profile Progress',
cell: EditableCellLabel,
accessor: 'progress',
}),
],
}),
]);

const { headerRows, pageRows, tableAttrs, tableBodyAttrs } =
table.createViewModel(columns);
</script>

<div class="overflow-x-auto">
<table {...$tableAttrs} class="demo">
<thead>
{#each $headerRows as headerRow (headerRow.id)}
<Subscribe attrs={headerRow.attrs()} let:attrs>
<tr {...attrs}>
{#each headerRow.cells as cell (cell.id)}
<Subscribe attrs={cell.attrs()} let:attrs>
<th {...attrs}>
<div>
<Render of={cell.render()} />
</div>
</th>
</Subscribe>
{/each}
</tr>
</Subscribe>
{/each}
</thead>
<tbody {...$tableBodyAttrs}>
{#each $pageRows as row (row.id)}
<Subscribe attrs={row.attrs()} let:attrs>
<tr {...attrs}>
{#each row.cells as cell (cell.id)}
<Subscribe attrs={cell.attrs()} let:attrs>
<td {...attrs}>
<Render of={cell.render()} />
</td>
</Subscribe>
{/each}
</tr>
</Subscribe>
{/each}
</tbody>
</table>
</div>

<style>
table {
border-spacing: 0;
border-top: 1px solid black;
border-left: 1px solid black;
}
th, td {
border-bottom: 1px solid black;
border-right: 1px solid black;
padding: 0.5rem;
}
</style>

/* App.svelte generated by Svelte v3.49.0 */
import {
SvelteComponent,
append,
append_styles,
assign,
attr,
check_outros,
component_subscribe,
create_component,
destroy_component,
detach,
element,
empty,
get_spread_update,
group_outros,
init,
insert,
mount_component,
outro_and_destroy_block,
safe_not_equal,
set_attributes,
set_store_value,
space,
toggle_class,
transition_in,
transition_out,
update_keyed_each
} from "svelte/internal";

import { writable } from 'svelte/store';

import {
Render,
Subscribe,
createTable,
createRender,
DataBodyRow
} from 'svelte-headless-table';

import { createSamples } from './createSamples';
import EditableCell from './EditableCell.svelte';

function add_css(target) {
append_styles(target, "svelte-13nmc7k", "table.svelte-13nmc7k{border-spacing:0;border-top:1px solid black;border-left:1px solid black}th.svelte-13nmc7k,td.svelte-13nmc7k{border-bottom:1px solid black;border-right:1px solid black;padding:0.5rem}");
}

function get_each_context(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[14] = list[i];
return child_ctx;
}

function get_each_context_1(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[18] = list[i];
return child_ctx;
}

function get_each_context_2(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[21] = list[i];
return child_ctx;
}

function get_each_context_3(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[18] = list[i];
return child_ctx;
}

// (101:14) <Subscribe attrs={cell.attrs()} let:attrs>
function create_default_slot_3(ctx) {
let th;
let div;
let render;
let t;
let current;
render = new Render({ props: { of: /*cell*/ ctx[18].render() } });
let th_levels = [/*attrs*/ ctx[17]];
let th_data = {};

for (let i = 0; i < th_levels.length; i += 1) {
th_data = assign(th_data, th_levels[i]);
}

return {
c() {
th = element("th");
div = element("div");
result = svelte.compile(source, {
generate:
});
table.svelte-13nmc7k{border-spacing:0;border-top:1px solid black;border-left:1px solid black}th.svelte-13nmc7k,td.svelte-13nmc7k{border-bottom:1px solid black;border-right:1px solid black;padding:0.5rem}
		
			
				
  • {
    • {
      • type: "Script"
      • start: 0
      • end: 2600
      • context: "default"
      }
    • module:
    }
The AST is not public API and may change at any point in time