Skip to content

Commit

Permalink
component: Table
Browse files Browse the repository at this point in the history
  • Loading branch information
shyakadavis committed Aug 14, 2024
1 parent dce074a commit 888002f
Show file tree
Hide file tree
Showing 16 changed files with 394 additions and 2 deletions.
27 changes: 27 additions & 0 deletions src/lib/components/ui/table/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Body from './table-body.svelte';
import Caption from './table-caption.svelte';
import Cell from './table-cell.svelte';
import Footer from './table-footer.svelte';
import Head from './table-head.svelte';
import Header from './table-header.svelte';
import Row from './table-row.svelte';
import Root from './table.svelte';

export {
Body,
Caption,
Cell,
Footer,
Head,
Header,
Root,
Row,
Root as Table,
Body as TableBody,
Caption as TableCaption,
Cell as TableCell,
Footer as TableFooter,
Head as TableHead,
Header as TableHeader,
Row as TableRow
};
24 changes: 24 additions & 0 deletions src/lib/components/ui/table/table-body.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLTableSectionElement> & {
striped?: boolean;
interactive?: boolean;
};
let class_name: $$Props['class'] = undefined;
export { class_name as class };
export let striped: $$Props['striped'] = false;
export let interactive: $$Props['interactive'] = false;
</script>

<div aria-hidden="true" class="h-3"></div>
<tbody
data-striped={striped}
data-interactive={interactive}
class={cn('group', class_name)}
{...$$restProps}
>
<slot />
</tbody>
13 changes: 13 additions & 0 deletions src/lib/components/ui/table/table-caption.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLTableCaptionElement>;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<caption class={cn('mt-4 text-sm', class_name)} {...$$restProps}>
<slot />
</caption>
18 changes: 18 additions & 0 deletions src/lib/components/ui/table/table-cell.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLTdAttributes } from 'svelte/elements';
type $$Props = HTMLTdAttributes;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<td
class={cn('px-2 py-2.5 align-middle last:text-right [&:has([role=checkbox])]:pr-0', class_name)}
{...$$restProps}
on:click
on:keydown
>
<slot />
</td>
14 changes: 14 additions & 0 deletions src/lib/components/ui/table/table-footer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLTableSectionElement>;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<div aria-hidden="true" class="h-3"></div>
<tfoot class={cn('border-t font-medium text-gray-1000', class_name)} {...$$restProps}>
<slot />
</tfoot>
19 changes: 19 additions & 0 deletions src/lib/components/ui/table/table-head.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLThAttributes } from 'svelte/elements';
type $$Props = HTMLThAttributes;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<th
class={cn(
'h-12 border-gray-200 px-4 text-left align-middle font-medium last:text-right [&:has([role=checkbox])]:pr-0 [&_th]:border-b',
class_name
)}
{...$$restProps}
>
<slot />
</th>
14 changes: 14 additions & 0 deletions src/lib/components/ui/table/table-header.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLTableSectionElement>;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<thead class={cn('[&_tr]:border-b', class_name)} {...$$restProps} on:click on:keydown>
<slot />
</thead>
23 changes: 23 additions & 0 deletions src/lib/components/ui/table/table-row.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLAttributes } from 'svelte/elements';
type $$Props = HTMLAttributes<HTMLTableRowElement> & {
'data-state'?: unknown;
};
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<tr
class={cn(
'transition-colors data-[state=selected]:bg-background-200 odd:group-data-[striped=true]:bg-background-200 group-data-[interactive=true]:hover:bg-gray-100',
class_name
)}
{...$$restProps}
on:click
on:keydown
>
<slot />
</tr>
15 changes: 15 additions & 0 deletions src/lib/components/ui/table/table.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { cn } from '$lib/utils.js';
import type { HTMLTableAttributes } from 'svelte/elements';
type $$Props = HTMLTableAttributes;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
</script>

<div class="relative w-full overflow-auto">
<table class={cn('w-full caption-bottom text-sm text-gray-900', class_name)} {...$$restProps}>
<slot />
</table>
</div>
2 changes: 1 addition & 1 deletion src/lib/config/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export const aside_items: Aside = {
{
title: 'Table',
href: '/table',
status: 'soon'
status: 'new'
},
{
title: 'Tabs',
Expand Down
33 changes: 32 additions & 1 deletion src/routes/table/+page.svelte
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
<h1>table</h1>
<script lang="ts">
import Demo from '$lib/components/shared/demo.svelte';
import PageWrapper from '$lib/components/shared/page-wrapper.svelte';
import BasicTable from './basic-table.svelte';
import basic_table_code from './basic-table.svelte?raw';
import FullFeaturedTable from './full-featured-table.svelte';
import full_featured_table_code from './full-featured-table.svelte?raw';
import InteractiveTable from './interactive-table.svelte';
import interactive_table_code from './interactive-table.svelte?raw';
import StripedTable from './striped-table.svelte';
import striped_table_code from './striped-table.svelte?raw';
export let data;
</script>

<PageWrapper title={data.title} description={data.description}>
<Demo id="basic-table" code={basic_table_code}>
<BasicTable />
</Demo>

<Demo id="striped-table" code={striped_table_code}>
<StripedTable />
</Demo>

<Demo id="interactive-table" code={interactive_table_code}>
<InteractiveTable />
</Demo>

<Demo id="full-featured-table" code={full_featured_table_code}>
<FullFeaturedTable />
</Demo>
</PageWrapper>
21 changes: 21 additions & 0 deletions src/routes/table/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { MetaTagsProps } from 'svelte-meta-tags';

export function load() {
const title = 'Table';
const description = 'A semantic HTML table component';

const pageMetaTags = Object.freeze({
title,
description,
openGraph: {
title,
description
}
}) satisfies MetaTagsProps;

return {
pageMetaTags,
title,
description
};
}
30 changes: 30 additions & 0 deletions src/routes/table/basic-table.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts">
import * as Table from '$lib/components/ui/table/index.js';
</script>

<Table.Root>
<Table.Header>
<Table.Row>
<Table.Head>Col 1</Table.Head>
<Table.Head>Col 2</Table.Head>
<Table.Head>Col 3</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Value 1.1</Table.Cell>
<Table.Cell>Value 1.2</Table.Cell>
<Table.Cell>Value 1.3</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Value 2.1</Table.Cell>
<Table.Cell>Value 2.2</Table.Cell>
<Table.Cell>Value 2.3</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Value 3.1</Table.Cell>
<Table.Cell>Value 3.2</Table.Cell>
<Table.Cell>Value 3.3</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
83 changes: 83 additions & 0 deletions src/routes/table/full-featured-table.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<script lang="ts">
import * as Table from '$lib/components/ui/table/index.js';
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
maximumFractionDigits: 2,
currency: 'usd'
});
function format_currency(amount: number): string {
return formatter.format(amount);
}
const items = [
{
product: 'Brake Pads Set',
usage: '100 sets',
price: '$50 per set',
charge: 5000
},
{
product: 'Oil Filters',
usage: '200 filters',
price: '$10 per filter',
charge: 2000
},
{
product: 'Car Batteries',
usage: '50 batteries',
price: '$100 per battery',
charge: 5000
},
{
product: 'Headlight Bulbs',
usage: '300 bulbs',
price: '$15 per bulb',
charge: 4500
},
{
product: 'Windshield Wipers',
usage: '250 pairs',
price: '$20 per pair',
charge: 5000
},
{
product: 'Spark Plugs',
usage: '500 sets',
price: '$5 per set',
charge: 2500
}
];
</script>

<Table.Root>
<Table.Header>
<Table.Row>
<Table.Head class="w-[44%]">Product</Table.Head>
<Table.Head class="w-[22%]">Usage</Table.Head>
<Table.Head class="w-[22%]">Price</Table.Head>
<Table.Head class="w-[11%]">Charge</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body interactive striped>
{#each items as item, i (i)}
<Table.Row>
<Table.Cell>{item.product}</Table.Cell>
<Table.Cell>{item.usage}</Table.Cell>
<Table.Cell>{item.price}</Table.Cell>
<Table.Cell>{format_currency(item.charge)}</Table.Cell>
</Table.Row>
{/each}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.Cell>Subtotal</Table.Cell>
<Table.Cell aria-hidden></Table.Cell>
<Table.Cell aria-hidden></Table.Cell>
<Table.Cell>
{format_currency(items.reduce((sum, val) => sum + val.charge, 0))}
</Table.Cell>
</Table.Row>
</Table.Footer>
</Table.Root>
30 changes: 30 additions & 0 deletions src/routes/table/interactive-table.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts">
import * as Table from '$lib/components/ui/table/index.js';
</script>

<Table.Root>
<Table.Header>
<Table.Row>
<Table.Head>Col 1</Table.Head>
<Table.Head>Col 2</Table.Head>
<Table.Head>Col 3</Table.Head>
</Table.Row>
</Table.Header>
<Table.Body interactive>
<Table.Row>
<Table.Cell>Value 1.1</Table.Cell>
<Table.Cell>Value 1.2</Table.Cell>
<Table.Cell>Value 1.3</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Value 2.1</Table.Cell>
<Table.Cell>Value 2.2</Table.Cell>
<Table.Cell>Value 2.3</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Value 3.1</Table.Cell>
<Table.Cell>Value 3.2</Table.Cell>
<Table.Cell>Value 3.3</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
Loading

0 comments on commit 888002f

Please sign in to comment.