Monday | 11 NOV 2024
[ previous ]
[ next ]

SvelteKit and Carbon Design

Title:
Date: 2024-02-15
Tags:  sveltekit

Table of Contents

  1. Quick Start
  2. Datatable Example

The Carbon Design System is a design system made by IBM. It is a set of components and patterns that they have made opensource. I've given it a shot for a small but complex application at work and I'm quite happy with it. The components are well designed and have all the major features that I want.

The Datatable component is the big one and it has sorting, pagining, and custom display options as well.

The design system works quite well but I'm worried that it will be a pain to migrate to Svelte 5 in the future.

Quick Start

Install carbon:

npm install carbon-components-svelte
npm install carbon-icons-svelte

Next add the carbon css by updating src/routes/layout.svelte:

import "carbon-components-svelte/css/g10.css"

Now we can use the carbon components:

<script>
   import { Button } from "carbon-components-svelte";
</script>

<Button>Primary</Button>

Most components properly forward things and have events coming back and it intuitively makes sense the svelte way.

Datatable Example

The DataTable component is an important one as most of my work requires showing information in tables. Getting a component with a nice look and that also gets pagining and sorting is a huge plus. We had already handrolled our own table but the logic looked like it could be made into a component easily and it looks like that is precisely what IBM had already done.

They even added in the ability to have custom displays per cell and custom sorts per column which is something I had been looking for.

There is one thing that I wish the component handled natively but it doesn't appear to be the case. I want to make the table have a sticky header but also have custom widths for the columns. This required a bit of massaging as the two options don't play nice by default. I was able to get it to work by adding some extra css.

An example:

<DataTable
   size="compact"
   zebra
   sortable
   stickyHeader
   headers={[
      { key: "id", value: "Item" },
      { key: "weight", value: "Weight", display: (w) =>  `${w} KG`},
      { key: "date", value: "Date", sort: (a,b) => new Date(b) - new Date(a) },
   ]}
   page={page}
   pageSize={pageSize}
   rows={rows}
   on:click:row={(e) => item = e.detail}
   >

This table is zebra striped with a fixed header and each column is sortable. There are custom sorts and displays and the table is paginated.

There is also a toolbar component where you can add buttons and search.

We also need to add some styling to be able to get the sticky header to work with the custom widths. I want the first 2 columns to be 125px while the 3rd column should get the full width.

To do this requires adding some styles.

<style>
   :global(#table tr td) { max-width: 125px; }
   :global(#table tr td:nth-child(3)) { max-width: 100%; }
   :global(#table th) { max-width: 125px; }
   :global(#table th:nth-child(3)) { max-width: 100%; }
</style>

We need to wrap the styles in :global because svelte will optimize them out as it doesn't see the raw tags during the compilation step.

Big fan of this component in particular but the entire system looks to be well thoughtout and it's easy to drop down to the raw code if needed.