@mediakular/gridcraft v0.2.7-beta
GridCraft: Svelte Data Grid
Demo
Comprehensive Data Grid for SvelteKit Apps 📊
@mediakular/gridcraft
is a powerful data grid package tailored for Sveltekit applications. It offers an array of features to elevate the presentation and interaction with tabular data.
Exciting Features ✨
- Paging: Navigate through large datasets effortlessly.
- Sorting: Arrange data in ascending or descending order with ease.
- Custom Filtering: Tailor data views to your specific needs.
- Grouping: Organize related data into logical groups.
- Row Selection: Select and manipulate individual or multiple rows.
- Custom Row edit: Integrate any custom or third-party components to edit your data.
- Customizable Output: Personalize grid appearance to match your style guide.
- Typesafe: Stay typesafe and use the types from your own business model.
- Tailwind CSS ready: Completely compatible with tailwind CSS and any other framework.
Installation
npm install @mediakular/gridcraft
or
yarn add @mediakular/gridcraft
or
pnpm add @mediakular/gridcraft
or
bun add @mediakular/gridcraft
Usage
Most basic usage. In this example GridCraft will automatically detect the properties of type Client
and generate a column for each property.
<script lang="ts">
import { Grid } from '@mediakular/gridcraft';
import { clients } from './clients.js';
</script>
<Grid data={clients} />
Example With Column Definition
Here an example with a simple custom column definition.
<script lang="ts">
import { Grid, type GridColumn } from "@mediakular/gridcraft";
import { clients } from './clients.js';
interface Client {
id: string;
firstname: string;
lastname: string;
age: number;
birthdate: Date;
}
let columns: GridColumn<Client>[] = [
{
key: 'firstname',
title: 'First Name'
},
{
key: 'lastname',
title: 'Last Name'
},
{
key: 'age',
title: 'Age'
},
{
key: 'birthdate',
title: 'Birthday'
}
];
</script>
<Grid
data={clients}
{columns} />
Use custom components to render column cells
GridCraft allows you to simply define your own custom svelte components to render column cells.
The following example shows you how to define a custom renderComponent
:
<script lang="ts">
import { Grid, type GridColumn } from "@mediakular/gridcraft";
import { clients } from './clients.js';
import ClientCell from "$lib/components/grid/cells/ClientCell.svelte";
import CurrencyCell from "$lib/components/grid/cells/CurrencyCell.svelte";
import DateCell from "$lib/components/grid/cells/DateCell.svelte";
interface Client {
id: string;
firstname: string;
lastname: string;
avatar: string;
email: string;
age: number;
birthdate: Date;
amount: number;
quantity: number;
}
let columns: GridColumn<Client>[] = [
{
key: 'name',
title: 'Name',
// Use an accessor to transform row data, which can be used in your custom renderComponent
accessor: (row: Client) => {
return {
avatar: row.avatar,
firstname: row.firstname,
lastname: row.lastname,
email: row.email
}
},
// as the default search will not work with our accessor data, we have to provide a sortValue which will be used for sorting
sortValue: (row: Client) => {
return `${row.firstname} ${row.lastname}`
},
renderComponent: ClientCell // Our custom column cell component to render a column with avatar, full name and email
},
{
key: 'age',
title: 'Age'
},
{
key: 'birthdate',
title: 'Birthday',
renderComponent: DateCell // Our custom column cell component to render a formatted date
},
{
key: 'total',
title: 'Total',
accessor: (row: Client) => { return row.amount * row.quantity },
renderComponent: CurrencyCell // Our custom column cell component to render a calculated cell and formatted currency
},
];
</script>
<Grid
data={clients}
bind:columns />
Here are the custom cell components used in the example above:
ClientCell.svelte
<script lang="ts">
export let avatar: string;
export let firstname: string;
export let lastname: string;
export let email: string;
let fullname = `${firstname} ${lastname}`;
</script>
<div class="my-client-cell">
<img src="{avatar}" alt="{fullname}" />
<div>
<span>{fullname}</span>
{#if email}
<span>{email}</span>
{/if}
</div>
</div>
DateCell.svelte
<script lang="ts">
export let value: Date;
let dateStr = value ? (new Date(value)).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }) : "-";
</script>
<div>{dateStr}</div>
CurrencyCell.svelte
<script lang="ts">
export let value: number;
let currency = new Intl.NumberFormat("en-US", { currency: "USD", style: 'currency', 2, 0 }).format(value);
</script>
<div>{currency ? currency : '-'}</div>
Example With Row Action Column
Here an example on how to integrate a column with custom row actions. This could be used for example to display links or buttons to delete or edit a row, or to show row details.
<script lang="ts">
import { Grid, type GridColumn } from "@mediakular/gridcraft";
import ActionsCell from "$lib/components/grid/cells/ActionsCell.svelte";
import { clients } from './clients.js';
let columns: GridColumn<Client>[] = [
{
key: 'firstname',
title: 'First Name',
},
{
key: 'lastname',
title: 'Last Name',
},
{
key: 'email',
title: 'E-Mail',
},
{
key: 'actions', // you can call it however you like
title: 'Row Actions',
sortable: false,
accessor: (row: Client) => {
return {
row: row,
editClicked: (row: Client) => {
// Implement your edit function here. You can for example open a modal window which shows the edit form for the row
},
deleteClicked: (row: Client) => {
// Implement your delete function here. You can for example open a dialoge window here to confirm that the user wants to delete the row
},
somethingElseClicked: (row: Client) => {
// ...
}
}
},
renderComponent: ActionsCell
}
];
</script>
<Grid
data={clients}
{columns} />
ActionsCell.svelte
<script lang="ts">
type T = $$Generic<any>;
export let row: T;
export let editClicked: (row: T) => void;
export let deleteClicked: (row: T) => void;
export let somethingElseClicked: (row: T) => void;
function handleEditClick() {
editClicked(row);
}
function handleDeleteClick() {
deleteClicked(row);
}
function handleSomethingElseClick() {
somethingElseClicked(row);
}
</script>
<button on:click|preventDefault={handleEditClick}>
Edit
</button>
<button on:click|preventDefault={handleDeleteClick}>
Delete
</button>
<a href="#" on:click|preventDefault={handleSomethingElseClick}>
Something Else
</a>
Example With Paging
Here a simple example with paging. If you are okay with the default values, you only need to define a variable of type PagingData
, which you need to set as attributes for the Grid
and GridFooter
components.
If you want to overwrite the defaults simply define them in the paging variable:
<script lang="ts">
import { Grid, type PagingData, GridFooter, type GridColumn } from "@mediakular/gridcraft";
import { clients } from './clients.js';
let columns: GridColumn<Client>[] = [];
// Define paging variables, if you want to overwrite the default
let paging = {
itemsPerPage: 5,
currentPage: 1,
itemsPerPageOptions: [5, 10, 20]
} as PagingData;
// Or: let paging:PagingData;
</script>
<Grid
data={clients}
{columns}
{paging} />
<GridFooter bind:paging />
Example With Grouping
<script lang="ts">
import { Grid, type GridColumn } from "@mediakular/gridcraft";
import { clients } from './clients.js';
interface Client {
id: string;
firstname: string;
lastname: string;
age: number;
}
let groupBy = "";
let columns: GridColumn<Client>[] = [
{
key: 'firstname',
title: 'First Name',
},
{
key: 'lastname',
title: 'First Name',
},
{
key: 'age',
title: 'Age'
}
];
</script>
<!-- Just for demonstration purposes -->
<select bind:value={groupBy} >
<option value="">Select Column to Group By</option>
{#each columns as col (col.key)}
<option value={col.key}>{col.title}</option>
{/each}
</select>
<!-- End: Just for demonstration purposes -->
<Grid
bind:data={clients}
{columns}
bind:groupby />
Example With Rows Selection
<script lang="ts">
import { Grid, type GridColumn } from "@mediakular/gridcraft";
import { clients } from './clients.js';
interface Client {
id: string;
firstname: string;
lastname: string;
age: number;
}
let showCheckboxes = true;
let selectedRows:Client[] = [];
let columns: GridColumn<Client>[] = [
{
key: 'firstname',
title: 'First Name',
},
{
key: 'lastname',
title: 'First Name',
},
{
key: 'age',
title: 'Age'
},
];
</script>
<!-- Just for demonstration purposes -->
<label for="showCheckboxes">
<input type="checkbox" bind:checked={showCheckboxes} id="showCheckboxes"> Show checkboxes
</label>
{#if showCheckboxes}
Selected Rows:
<pre>
{JSON.stringify(selectedRows, null, 2)}
</pre>
{/if}
<!-- End: Just for demonstration purposes -->
<Grid
data={clients}
{columns}
{showCheckboxes}
bind:selectedRows />
Example With Text Filter
<script lang="ts">
import { Grid, type GridColumn, type GridFilter } from "@mediakular/gridcraft";
import { clients } from './clients.js';
interface Client {
id: string;
firstname: string;
lastname: string;
age: number;
}
let textSearch = "";
let clientData = clients;
let filters: GridFilter[];
$: filters = [
{
key: "text-search", //can be chosen freely
columns: ["firstname", "lastname", "age"], // Define which columns you would like to use the filter for
filter: (row: any, colKey: string) => { // Actual filter function which will be called for each of the above defined columns. We return true for displaying the column and false for hiding it
const search = (val: string | null) => val != undefined && val.toString().toLocaleLowerCase().includes(textSearch.toLocaleLowerCase());
return search(row)
},
active: (textSearch && textSearch.length > 0) ? true : false // Here we return true when the filter should be active, when false the filter will be ignored
}
];
let columns: GridColumn<Client>[] = [
{
key: 'firstname',
title: 'Firstname',
},
{
key: 'lastname',
title: 'Lastname',
},
{
key: 'age',
title: 'Age'
},
];
</script>
<input type="text" placeholder="Enter Filter Term (Firstname, Lastname or Age)" bind:value={textSearch} />
<Grid
data={clientData}
{columns}
{filters} />
Example With Customized Appearance
Currently, gridcraft comes with three pre-defined themes: PlainTableCssTheme
, PlainTableTheme
and PrelineTheme
.
By default gridcraft uses PlainTableCssTheme
. While PlainTableCssTheme
is a fully styled theme and can be used as-is, PlainTableTheme
theme is a very basic table, without any styles or classes and serves mostly as a template for your own theme. You can copy PlainTableTheme
into your own project and transform it to fit your needs.
PrelineTheme
is inspired by preline.
There are currently three main components that can be themed: Grid
, GridFooter
and GridPaging
.
<script lang="ts">
import { Grid, type GridColumn, GridFooter, PrelineTheme, PlainTableCssTheme } from "@mediakular/gridcraft";
import { clients } from './clients.js';
let theme = PlainTableCssTheme;
let columns: GridColumn<Client>[] = [
...
];
</script>
<!-- Only for demonstration purposes -->
<button on:click={() => theme = PlainTableCssTheme}>Plain Css Theme</button>
<button on:click={() => theme = PrelineTheme}>Preline Theme</button>
<!-- End: Only for demonstration purposes -->
<Grid bind:data={clients} {columns} {theme} />
<GridFooter {theme}/>
When using PrelineTheme
you need to install tailwindcss and make sure to add this in your tailwind.config.js
:
export default {
content: [
...
'./node_modules/@mediakular/gridcraft/dist/themes/preline/**/*.svelte'
],
theme: {
extend: {},
},
plugins: [
...
],
}
Overwriting an existing theme
This can be usefull if you are satisfied with a certain theme, but you want to make only a few changes instead of creating a new custom theme.
<script lang="ts">
import { Grid, type GridColumn, GridFooter, PrelineTheme, PlainTableTheme } from "@mediakular/gridcraft";
import MyTableContainer from "$lib/components/grid/theme/MyTableContainer.svelte"
import { clients } from './clients.js';
let theme = PlainTableTheme;
theme.grid.container = MyTableContainer;
let columns: GridColumn<Client>[] = [
...
];
</script>
<Grid
bind:data={clients}
{columns}
{theme} />
<GridFooter {theme} />
MyTableContainer.svelte
<div class="my-custom-wrapper">
<table class="my-custom-table-class" id="custom-table-id">
<slot />
</table>
</div>
Find here the full theming documentation.
Full Documentation
Here you can find the full documentation of GridCraft
Something Missing?
Request new example codes which we can add in our documenatation: GitHub Discussion
New ideas you can post here so we can discuss them: GitHub Discussion
Here you can let us know about issues or bugs: GitHub Issues
Or ask the community in our Discord Channel
💚 Become A Sponsor
Support the development of GridCraft by becoming a sponsor:
Contribute & Become Part Of The Community
Join the community in our Discord Channel. There you can ask everything to get started.
Follow us on Twitter
Spread the Love 🤗💻
Sharing is appreciated. You've integrated GridCraft successfully in your project? - We would love to see it! Twitter it with mentioning @grid_craft or send us an email to gridcraft @ mediakular.com
Of course you can also share our website https://gridcraft.mediakular.com.
API Documentation
Grid API Column API Filter API
License
This package is licensed under the MIT License.
4 days ago
11 days ago
11 days ago
13 days ago
19 days ago
20 days ago
19 days ago
19 days ago
26 days ago
30 days ago
30 days ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago