logo-icon
STWUI

Table

Table can be used to show a list of data in a table format.

Card Header
a 1 a 2 a 3 a 4 a 5
aa 1 aa 2 aa 3 aa 4 aa 5
ab 1 ab 2 ab 3 ab 4 ab 5
ac 1 ac 2 ac 3 ac 4 ac 5
ae 1 ae 2 ae 3 ae 4 ae 5
af 1 af 2 af 3 af 4 af 5
ag 1 ag 2 ag 3 ag 4 ag 5
ah 1 ah 2 ah 3 ah 4 ah 5
ai 1 ai 2 ai 3 ai 4 ai 5
aj 1 aj 2 aj 3 aj 4 aj 5
ak 1 ak 2 ak 3 ak 4 ak 5
al 1 al 2 al 3 al 4 al 5
am 1 am 2 am 3 am 4 am 5
an 1 an 2 an 3 an 4 an 5
ao 1 ao 2 ao 3 ao 4 ao 5
ap 1 ap 2 ap 3 ap 4 ap 5
aq 1 aq 2 aq 3 aq 4 aq 5
ar 1 ar 2 ar 3 ar 4 ar 5
as 1 as 2 as 3 as 4 as 5
at 1 at 2 at 3 at 4 at 5
au 1 au 2 au 3 au 4 au 5
av 1 av 2 av 3 av 4 av 5
aw 1 aw 2 aw 3 aw 4 aw 5

svelte
<script lang="ts">
   import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { encodeSearchParams } from 'stwui/utils';
   import { Table } from 'stwui';
   import type { TableColumn } from 'stwui/types';

   const plus = "svg-path";

   let baseUrl: string;
	let orderBy: string;
	let order: 'asc' | 'desc';
	let currentPage: string;

	$: {
		baseUrl = $page.url.pathname;
		orderBy = $page.url.searchParams.get('orderBy') || 'created_at';
		order = $page.url.searchParams.get('order') === 'desc' ? 'desc' : 'asc';
		currentPage = $page.url.searchParams.get('page') || '1';
	}

   const columns: TableColumn[] = [
      {
         column: 'project_name',
         label: 'Project Name',
         placement: 'left'
      },
      {
         column: 'status',
         label: 'Status',
         placement: 'left'
      },
      {
         column: 'city',
         label: 'City',
         placement: 'left'
      },
      {
         column: 'state',
         label: 'State',
         placement: 'left'
      },
      {
         column: 'created_at',
         label: 'Created',
         placement: 'right'
      }
   ];

   interface Item extends Record<string, string> {
      id: string;
      project_name: string;
      status: string;
      city: string;
      state: string;
      created_at: string;
   }

   export let data: { results: Item[]; start: number; end: number; total: number } = {
      results: [],
      start: 0,
      end: 0,
      total: 0
   };

   function onPreviousClick() {
		let newPage = parseInt(currentPage) - 1 + '';
		goto(`${baseUrl}` +
			encodeSearchParams({
				orderBy: orderBy,
				order: order,
				page: newPage
			})
		);
	}

	function onNextClick() {
		let newPage = parseInt(currentPage) + 1 + '';
		goto(`${baseUrl}` +
			encodeSearchParams({
				orderBy: orderBy,
				order: order,
				page: newPage
			})
		);
	}

	function onPageClick(page: number) {
		let newPage = page + '';
		goto(`${baseUrl}` +
			encodeSearchParams({
				orderBy: orderBy,
				order: order,
				page: newPage
			})
		);
	}

	function onColumnHeaderClick(column: string) {
		goto(`${baseUrl}` +
			encodeSearchParams({
				orderBy: column,
				order: column === orderBy && order === 'asc' ? 'desc' : 'asc',
				page: currentPage
			})
		);
	}
</script>

<Card bordered={false} class="h-[calc(100vh-14rem)]">
   <Card.Header slot="header" class="font-bold text-lg flex justify-between items-center py-3">
      Card Header
      <Button slot="extra" type="primary">
         <Button.Leading slot="leading" data={plus} />
         New Item
      </Button>
   </Card.Header>
   <Card.Content slot="content" class="p-0 sm:p-0" style="height: calc(100% - 64px);">
      <Table class="rounded-md overflow-hidden h-full" {columns}>
         <Table.Header slot="header" {order} {orderBy} {onColumnHeaderClick} />
         <Table.Body slot="body">
            {#each data.results as item}
               <Table.Body.Row id={item.id}>
                  <Table.Body.Row.Cell column={0}>{item.project_name}</Table.Body.Row.Cell>
                  <Table.Body.Row.Cell column={1}>{item.status}</Table.Body.Row.Cell>
                  <Table.Body.Row.Cell column={2}>{item.city}</Table.Body.Row.Cell>
                  <Table.Body.Row.Cell column={3}>{item.state}</Table.Body.Row.Cell>
                  <Table.Body.Row.Cell column={4}>{item.created_at}</Table.Body.Row.Cell>
               </Table.Body.Row>
            {/each}
         </Table.Body>
         <Table.Footer slot="footer">
         <Pagination
            start={data.start}
            end={data.end}
            total={data.total}
            currentPage={parseInt(currentPage)}
            {onPreviousClick}
            {onNextClick}
            {onPageClick}
         />
         </Table.Footer>
      </Table>
   </Card.Content>
</Card>

Table Props

columns TableColumn[] []

Table Slots

header <Table.Header slot="header" />
body <Table.Body slot="body" />
footer <Table.Footer slot="footer" />

Table.Header Props

order 'asc' | 'desc' asc
orderBy string
onColumnHeaderClick ((page: number) => void) | undefined

Table.Body Props

id string table-body

Table.Body Slots

default

Table.Body.Row Props

id string

Table.Body.Row Slots

default

Table.Body.Row.Cell Props

column number

Table.Body.Row.Cell Slots

default

Table.Footer Slots

default