Unlock the Power of Svelte: Building a Custom Component Library

Getting Started with SvelteKit

SvelteKit, the successor to Sapper or NextJS for Svelte, is packed with features like server-side rendering, routing, and code splitting. It uses Vite under the hood, making it a powerful tool for building component libraries. To get started, we’ll use a skeleton project as the base for our library.

npx degit sveltejs/kit my-component-library

Integrating Storybook

Storybook, an open-source tool for building UI components and pages in isolation, is essential for our component library development. It streamlines UI development and testing, allowing us to build components without worrying about configurations or development servers in SvelteKit.

npx sb init

Factors to Consider Before Building Components

Before we dive into building components, let’s consider a few essential factors:

  • Props usage: Props pass data to child components or enable component communication.
  • Slots and $$slots usage: Slots maintain reusability while allowing the parent component to control the content of the child.
  • Avoiding nested and global CSS: Avoid using nested and global CSS, as they will not be scoped and may leak through to all child components.
  • Handling events: Make sure to add or handle proper events using Svelte’s createEventDispatcher API.

Creating Components

Let’s create some components for our library! We’ll start with a button component, followed by a toggle component, and finally an input field component. Each component will have its own story file, allowing us to test and render them in isolation.

<script>
  export let label;
</script>

<button>{label}</button>
<script>
  let toggled = false;

  function toggle() {
    toggled =!toggled;
  }
</script>

<button on:click={toggle}>Toggle {#if toggled}on{/if}{:else}off{/else}</button>
<script>
  export let value = '';
  let input;

  function handleInput(event) {
    value = event.target.value;
  }
</script>

<input bind:value={value} on:input={handleInput} />

Testing with svelte-testing-library and Jest

Testing is a critical aspect of web development. With Svelte, we can use tools like Jest and Testing Library to write tests that mimic real user interactions. We’ll also use plugins like user-event and jest-dom to extend our testing capabilities.

import { render, fireEvent, waitFor } from '@testing-library/svelte';
import { Button } from './Button.svelte';

it('renders correctly', () => {
  const { getByText } = render(Button, { props: { label: 'Click me' } });
  expect(getByText('Click me')).toBeInTheDocument();
});

it('calls onClick when clicked', () => {
  const onClick = jest.fn();
  const { getByText } = render(Button, { props: { label: 'Click me', onClick } });
  const button = getByText('Click me');
  fireEvent.click(button);
  expect(onClick).toHaveBeenCalledTimes(1);
});

Packaging and Publishing to npm

Once we’ve built and tested our components, it’s time to package and publish them to npm. SvelteKit provides a built-in feature to export our components as a package. We’ll add a few configuration files and attributes to our package.json file, and then run a simple command to generate our package.

{
  "name": "my-component-library",
  "version": "1.0.0",
  "main": "index.js",
  "module": "index.mjs",
  "scripts": {
    "build": "svelte-kit build",
    "package": "svelte-kit package"
  }
}
npm run package

Publish your package to npm

Leave a Reply