Skip to content

Commit 866cda1

Browse files
Svelte Simple Datatables Guide (#2443)
Co-authored-by: endigo9740 <[email protected]>
1 parent 6c31f1b commit 866cda1

File tree

6 files changed

+623
-18
lines changed

6 files changed

+623
-18
lines changed

packages/skeleton/src/plugin/generated/generated-classes.cjs

+1
Large diffs are not rendered by default.

sites/skeleton.dev/src/lib/links.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ export const menuNavLinks: Record<string, Array<{ title: string; list: List }>>
4242
},
4343
{
4444
title: 'Integrations',
45-
list: [{ href: '/docs/tauri', label: 'Tauri', keywords: 'Tauri, desktop, setup, install' }] // , badge: 'New'
45+
list: [
46+
{ href: '/docs/tauri', label: 'Tauri', keywords: 'Tauri, desktop, setup, install' },
47+
{ href: '/docs/ssd', label: 'Datatables', keywords: 'datatables, tables, datagrid, simple', badge: 'New' }
48+
]
4649
}
4750
],
4851
'/elements': [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
<script lang="ts">
2+
import LayoutPage from '$lib/layouts/LayoutPage/LayoutPage.svelte';
3+
import { CodeBlock, TabGroup, Tab } from '@skeletonlabs/skeleton';
4+
5+
// Tabs
6+
let tabSelected: string = 'client';
7+
8+
//Local Components
9+
import Client from './ClientSSD.svelte';
10+
import Server from './ServerSSD.svelte';
11+
</script>
12+
13+
<LayoutPage>
14+
<!-- Header -->
15+
<header class="space-y-4">
16+
<h1 class="h1">Svelte Simple Datatables</h1>
17+
<p>
18+
The following guide will cover the basics of integrating Skeleton and <a
19+
class="anchor"
20+
href="https://vincjo.fr/datatables/home"
21+
target="_blank">Svelte Simple Datatables</a
22+
>.
23+
</p>
24+
</header>
25+
26+
<hr />
27+
28+
<!-- SSD Explanation -->
29+
<section class="space-y-4">
30+
<p class="text-xl">
31+
<a class="anchor" href="https://vincjo.fr/datatables/home" target="_blank">Svelte Simple Datatables</a>
32+
is a headless library for creating datatable components with Svelte. It provides a simple API to dynamically interact with iterable data
33+
on the client-side, allowing you to filter, paginate, sort, and select data. It can handle server-side data processing, supports Typescript,
34+
and has no other required dependencies.
35+
</p>
36+
</section>
37+
38+
<!-- Intro -->
39+
<section class="space-y-4">
40+
<h2 class="h2">Introduction</h2>
41+
<p>
42+
Skeleton provides a simple <a class="anchor" href="/components/tables">Table Component</a> for implementing tabular data for
43+
presentational purposes. However, this lacks more powerful features, such as search, sort, and filter. This is where Svelte Simple
44+
Datatables comes in. To integrate this, we'll opt for Skeleton's
45+
<a class="anchor" href="/elements/tables">Table Elements</a>, which provided themed styles to native HTML tables. The end result will
46+
be a new <code class="code">&lt;Datatable /&gt;</code> component, which you may use directly in your own application.
47+
</p>
48+
49+
<img
50+
class="rounded-lg"
51+
src="https://raw.githubusercontent.com/skeletonlabs/skeleton-datatables-integration/main/static/themes.gif"
52+
alt="themed datatables"
53+
/>
54+
55+
<p>
56+
Additionally, we'll also create a number of accessory components to handle search, filter, sort, and pagination features. These
57+
smaller components will help augment and extend the overall datatable component.
58+
</p>
59+
60+
<img
61+
src="https://raw.githubusercontent.com/skeletonlabs/skeleton-datatables-integration/main/static/components.png"
62+
alt="accessory components diagram"
63+
/>
64+
</section>
65+
66+
<!-- Starter Template -->
67+
<section class="space-y-4">
68+
<h2 class="h2">Starter Template</h2>
69+
<p>If you're looking for a quick start or reference project, please refer to our opinionated template on GitHub.</p>
70+
<div class="card variant-glass p-4 py-10 text-center">
71+
<a class="btn variant-filled" href="https://github.com/skeletonlabs/skeleton-datatables-integration" target="_blank">
72+
<i class="fa-brands fa-github" />
73+
<span>View Starter Template</span>
74+
<i class="fa-solid fa-up-right-from-square" />
75+
</a>
76+
</div>
77+
</section>
78+
79+
<!-- Getting Started -->
80+
<section class="space-y-4">
81+
<h2 class="h2">Getting Started</h2>
82+
<h3 class="h3">Install Depedencies</h3>
83+
<p>Add Svelte Simple Datables to your Skeleton project by running the following command.</p>
84+
<CodeBlock
85+
language="shell"
86+
code={`
87+
npm i @vincjo/datatables
88+
`}
89+
/>
90+
91+
<h3 class="h3">Project Structure</h3>
92+
<p>Next, let's plan out our overall project structure.</p>
93+
<CodeBlock
94+
language="shell"
95+
code={`
96+
src
97+
├── lib
98+
| ├── data
99+
| | └── data.ts / api.ts
100+
| └── components
101+
| ├── Pagination.svelte
102+
| ├── Search.svelte
103+
| ├── RowCount.svelte
104+
| ├── RowsPerPage.svelte
105+
| ├── ThFilter.svelte
106+
| └── ThSort.svelte
107+
└── routes
108+
├── Datatable.svelte
109+
└── +page.svelte
110+
`}
111+
/>
112+
113+
<dl class="list-dl">
114+
<div>
115+
<span class="badge-icon p-4 variant-soft-primary"><i class="fa-solid fa-code" /></span>
116+
<span class="flex-auto">
117+
<dt><code class="code">/lib/data</code></dt>
118+
<dd>
119+
Create <code class="code">data.ts</code> if you are loading data from the client or <code class="code">api.ts</code> if your data
120+
is coming from the server. This will be explained further on, but for now just create the blank Typescript file.
121+
</dd>
122+
</span>
123+
</div>
124+
<div>
125+
<span class="badge-icon p-4 variant-soft-primary"><i class="fa-solid fa-code" /></span>
126+
<span class="flex-auto">
127+
<dt><code class="code">/lib/components</code></dt>
128+
<dd>All of the files in this directory will be used for accessory components.</dd>
129+
</span>
130+
</div>
131+
<div>
132+
<span class="badge-icon p-4 variant-soft-primary"><i class="fa-solid fa-code" /></span>
133+
<span class="flex-auto">
134+
<dt><code class="code">/routes/Datatable.svelte</code></dt>
135+
<dd>
136+
This file will contain the
137+
<code class="code">&lt;Datatable /&gt;</code>
138+
component, the associated logic, and render the accessory components.
139+
</dd>
140+
</span>
141+
</div>
142+
<div>
143+
<span class="badge-icon p-4 variant-soft-primary"><i class="fa-solid fa-code" /></span>
144+
<span class="flex-auto">
145+
<dt><code class="code">/routes/+page.svelte</code></dt>
146+
<dd>
147+
This is where we'll render and access the
148+
<code class="code">&lt;Datatable /&gt;</code>
149+
component in this example.
150+
</dd>
151+
</span>
152+
</div>
153+
</dl>
154+
</section>
155+
156+
<!-- Creating the Components -->
157+
<section class="space-y-4">
158+
<h2 class="h2">Creating the Components</h2>
159+
<p>Each component will need to be configured based on the scope. Select your preference below.</p>
160+
<TabGroup>
161+
<Tab bind:group={tabSelected} name="tabClient" value="client">Client-Based</Tab>
162+
<Tab bind:group={tabSelected} name="tabServer" value="server">Server-Based</Tab>
163+
<!-- Tab Panels --->
164+
<svelte:fragment slot="panel">
165+
{#if tabSelected === 'client'}
166+
<Client />
167+
{:else if tabSelected === 'server'}
168+
<Server />
169+
{/if}
170+
</svelte:fragment>
171+
</TabGroup>
172+
<!-- Import Datatable -->
173+
<section class="space-y-4">
174+
<h3 class="h3" data-toc-ignore>4. Import Datatable Component</h3>
175+
<p>
176+
With our Datatable component now complete, let's import and add it to our <code class="code">+page.svelte</code>.
177+
</p>
178+
<CodeBlock language="ts" code={`import Datatable from '$lib/components/Datatable.svelte';`} />
179+
<CodeBlock language="html" code={`<Datatable />`} />
180+
</section>
181+
</section>
182+
183+
<!-- Responsive Design -->
184+
<section class="space-y-4">
185+
<h2 class="h2">Responsive Design</h2>
186+
<p>
187+
To ensure our datatables are visible on all screen sizes, make sure to utilize <a
188+
class="anchor"
189+
href="https://tailwindcss.com/docs/responsive-design"
190+
target="_blank">Tailwind's responsive design</a
191+
>
192+
best practices. You can also utilize the Tailwind Element <a href="/elements/tables" class="anchor">.table-container</a> class, which should
193+
be applied to a wrapping element.
194+
</p>
195+
</section>
196+
197+
<hr />
198+
199+
<!-- Attribution -->
200+
<section class="space-y-4">
201+
<h2 class="h2">Attribution</h2>
202+
<p>
203+
This guide has been provided courtesy of <a href="https://github.com/kmalloy24" class="anchor">Kyle Malloy</a>, username
204+
<code class="code">@spacecup</code> on Skeleton's Discord server.
205+
</p>
206+
</section>
207+
</LayoutPage>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<script lang="ts">
2+
import { CodeBlock } from '@skeletonlabs/skeleton';
3+
</script>
4+
5+
<div class="space-y-4">
6+
<!-- Loading Data -->
7+
<section class="space-y-4">
8+
<h3 class="h3" data-toc-ignore>1. Loading Data</h3>
9+
<p>
10+
To begin, let's add fake dataset in <code class="code">/src/lib/static/data.ts</code>. View a full reference
11+
<a class="anchor" href="https://vincjo.fr/datatables/tutorial/html-table" target="_blank"> under the data tab.</a>
12+
</p>
13+
<CodeBlock
14+
language="ts"
15+
code={`
16+
export default [
17+
{ id: 1, first_name: 'Tobie', last_name: 'Vint', email: '[email protected]' },
18+
{ id: 2, first_name: 'Zacharias', last_name: 'Cerman', email: '[email protected]' },
19+
{ id: 3, first_name: 'Gérianna', last_name: 'Bunn', email: '[email protected]' },
20+
{ id: 4, first_name: 'Bee', last_name: 'Saurin', email: '[email protected]' },
21+
{ id: 5, first_name: 'Méyère', last_name: 'Granulette', email: '[email protected]' }
22+
// ...
23+
];
24+
`}
25+
/>
26+
</section>
27+
28+
<!-- The Datatable Component -->
29+
<section class="space-y-4">
30+
<h3 class="h3" data-toc-ignore>2. The Datatable Component</h3>
31+
<p>
32+
Create the new Datatable component in <code class="code">/src/lib/comonents/Datatable.svelte</code>, import your custom dataset, as
33+
well as the
34+
<code class="code">DataHandler</code> from Svelte Simple Datatables. Then, intialize the <code class="code">handler</code> and
35+
<code class="code">rows</code>.
36+
</p>
37+
<CodeBlock
38+
language="ts"
39+
code={`
40+
import { DataHandler } from '@vincjo/datatables';
41+
import data from '$lib/static/data';
42+
43+
const handler = new DataHandler(data, { rowsPerPage: 5 });
44+
const rows = handler.getRows();
45+
`}
46+
/>
47+
<p>Take care to configure your the markup to match the dataset.</p>
48+
<CodeBlock
49+
language="html"
50+
code={`
51+
<div class="table-container space-y-4">
52+
<table class="table table-hover table-compact table-auto w-full">
53+
<thead>
54+
<tr>
55+
<td>First name</td>
56+
<td>Last name</td>
57+
<td>Email</td>
58+
</tr>
59+
</thead>
60+
<tbody>
61+
{#each $rows as row}
62+
<tr>
63+
<td>{row.first_name}</td>
64+
<td>{row.last_name}</td>
65+
<td>{row.email}</td>
66+
</tr>
67+
{/each}
68+
</tbody>
69+
</table>
70+
</div>
71+
`}
72+
/>
73+
</section>
74+
75+
<!-- Accessory Components -->
76+
<section class="space-y-4">
77+
<h3 class="h3" data-toc-ignore>3. Accessory Components</h3>
78+
<p>Let's create, import, and add our new accessory components. Note that these will not yet be functional.</p>
79+
<CodeBlock
80+
language="ts"
81+
code={`
82+
import Search from '$lib/components/Search.svelte';
83+
import ThFilter from '$lib/components/ThFilter.svelte';
84+
import ThSort from '$lib/components/ThSort.svelte';
85+
import RowCount from '$lib/components/RowCount.svelte';
86+
import RowsPerPage from '$lib/components/RowsPerPage.svelte';
87+
import Pagination from '$lib/components/Pagination.svelte';
88+
`}
89+
/>
90+
<CodeBlock
91+
language="html"
92+
code={`
93+
<div class=" overflow-x-auto space-y-2">
94+
<header class="flex justify-between gap-4">
95+
<!-- <Search {handler} /> -->
96+
<!-- <RowsPerPage {handler} /> -->
97+
</header>
98+
<table class="table table-hover table-compact table-auto w-full ">
99+
<thead>
100+
<tr>
101+
<!-- <ThSort {handler} orderBy="first_name">First name</ThSort>
102+
<ThSort {handler} orderBy="last_name">Last name</ThSort>
103+
<ThSort {handler} orderBy="email">Email</ThSort> -->
104+
</tr>
105+
<tr>
106+
<!-- <ThFilter {handler} filterBy="first_name" />
107+
<ThFilter {handler} filterBy="last_name" />
108+
<ThFilter {handler} filterBy="email" /> -->
109+
</tr>
110+
</thead>
111+
<tbody>
112+
{#each $rows as row}
113+
<tr>
114+
<td>{row.first_name}</td>
115+
<td>{row.last_name}</td>
116+
<td>{row.email}</td>
117+
</tr>
118+
{/each}
119+
</tbody>
120+
</table>
121+
<footer class="flex justify-between">
122+
<!-- <RowCount {handler} /> -->
123+
<!-- <Pagination {handler} /> -->
124+
</footer>
125+
</div>
126+
`}
127+
/>
128+
<p>
129+
For brevity, find the full source code for <code class="code">&lt;Datatable /&gt;</code> and all accessory components on GitHub.
130+
</p>
131+
<div class="card variant-glass p-4 py-10 flex justify-center items-center gap-4">
132+
<a
133+
class="btn variant-filled"
134+
href="https://github.com/skeletonlabs/skeleton-datatables-integration/tree/main/src/lib/components/client/Datatable.svelte"
135+
target="_blank"
136+
>
137+
<i class="fa-brands fa-github" />
138+
<span>Datatable</span>
139+
</a>
140+
<a
141+
class="btn variant-filled"
142+
href="https://github.com/skeletonlabs/skeleton-datatables-integration/tree/main/src/lib/components/client"
143+
target="_blank"
144+
>
145+
<i class="fa-brands fa-github" />
146+
<span>Accessories</span>
147+
</a>
148+
</div>
149+
</section>
150+
151+
<!-- NOTE: step 4 is outside this component -->
152+
</div>

0 commit comments

Comments
 (0)