0.2.7-beta • Published 4 days ago

@mediakular/gridcraft v0.2.7-beta

Weekly downloads
-
License
MIT
Repository
github
Last release
4 days ago

GridCraft: Svelte Data Grid

npm version License: MIT

Demo

DEMOS

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} />

Open in SvelteLab

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} />

Open in SvelteLab

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 />

Open in SvelteLab

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>

Open in SvelteLab

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 />

Simple paging example: Open in SvelteLab

Custom paging example: Open in SvelteLab

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 />

Open in SvelteLab

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 />

Open in SvelteLab

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 text filter: Open in SvelteLab

Example with checkbox filter: Open in SvelteLab

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: [
    ...
  ],
}

Open in SvelteLab

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:

Sponsor on GitHub

Sponsor on Patreon

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.

0.2.7-beta

4 days ago

0.2.6-beta

11 days ago

0.2.5-beta

11 days ago

0.2.4-beta

13 days ago

0.2.3-beta

19 days ago

0.2.0-beta

20 days ago

0.2.1-beta

19 days ago

0.2.2-beta

19 days ago

0.1.3

26 days ago

0.1.2

30 days ago

0.1.1

30 days ago

0.1.0

1 month ago

0.0.19

1 month ago

0.0.16

1 month ago

0.0.17

1 month ago

0.0.18

1 month ago

0.0.15

1 month ago

0.0.14

1 month ago

0.0.13

1 month ago

0.0.11

1 month ago

0.0.12

1 month ago

0.0.10

1 month ago