Client Processing
The table sorts, filters, searches and pages your rows in the browser. Pass an array, and every control on the page works.
Hand over the rows
processing: 'client' means the table does the work.
Search, filters, sorting, grouping and paging all happen in the browser, on the array you
passed. The items prop is the short way to say it:
An array and some columns
Employee | Role | Department | Location |
|---|---|---|---|
Emma Wilson | Staff Engineer | Platform | Berlin |
Liam Chen | Product Designer | Design | Hamburg |
Sofia Martinez | Engineering Manager | Platform | Munich |
James Park | Frontend Developer | Product | Remote |
Aisha Patel | Data Scientist | Data | Berlin |
<script lang="ts">
import { Table } from '@urbicon-ui/table';
import { employees } from './data';
const columns = [
{ accessor: 'name', title: 'Employee', sortable: true, searchable: true },
{ accessor: 'role', title: 'Role', sortable: true, searchable: true },
{ accessor: 'department', title: 'Department', sortable: true, groupable: true },
{ accessor: 'location', title: 'Location', sortable: true }
];
</script>
<Table {columns} items={employees} viewDefaults={{ pageSize: 5 }} />You don't need source for this. Reach for it once a loading
or an error state comes into it.
Rows that arrive with the page are the same case. A SvelteKit load has them ready before the page renders, so the first
screen is server-rendered and the table takes over from there:
Rows from a SvelteKit load
// +page.server.ts
export const load = async () => ({ employees: await db.employees.findMany() });
// +page.svelte
<script lang="ts">
import { Table } from '@urbicon-ui/table';
import { columns } from './columns';
let { data } = $props();
</script>
<Table {columns} items={data.employees} />While the rows are loading
When you fetch the rows yourself, source carries the two
states the table renders for you:
Your fetch, the table's states
<script lang="ts">
import { Table } from '@urbicon-ui/table';
let items = $state<Employee[]>([]);
let loading = $state(true);
let error = $state<string | null>(null);
fetchEmployees()
.then((rows) => (items = rows))
.catch((e) => (error = e.message))
.finally(() => (loading = false));
</script>
<Table {columns} source={{ processing: 'client', items, loading, error }} />The table shows its loading row while loading is
true, and its error state with whatever error holds as
the message. You decide when each applies. The rows keep being sorted, filtered and paged in the
browser throughout.
source wins over items
Both props reach the same rows. When you pass both, the table readssource and the items prop does nothing.When the browser runs out
The whole set sits in memory, and every sort touches all of it. A few thousand rows is comfortable. A hundred thousand is a tab that stops responding.
Two ways out, and they answer different questions. If the rows still fit and only the rendering hurts, keep client processing and draw fewer of them: Virtual Scrolling. If the set is too large to send at all, the backend sorts and pages it instead: Server Processing.