Rodney Lab sveltekit-components Github banner

Rodney Lab logo

Sveltekit Components

sveltekit-components

Library of TypeScript friendly SvelteKit components for adding functionality to your SvelteKit apps.

Setup

To install the package run

pnpm add -D @rodneylab/sveltekit-components @rodneylab/sveltekit-map-component
pnpm add --save-peer leaflet

Components

Form Fields

Add accessible text, email and password inputs to your SvelteKit site forms. See full SvelteKit form examples or get started with extracts below:

<script lang="ts">
    import {
        EmailInputField,
        PasswordInputField,
        TextArea,
        TextInputField,
    } from '@rodneylab/sveltekit-components';
</script>

<form on:submit|preventDefault={handleSubmit}>
    <TextInputField
        value={name}
        id="form-name"
        placeholder="Blake Jones"
        title="Name"
        error={errors?.name ?? null}
        on:update={(event) => {
            name = event.detail;
        }}
        style="padding-bottom:1rem"
    />
    <EmailInputField
        value={email}
        id="form-email"
        placeholder="[email protected]"
        title="Email"
        error={errors?.email ?? null}
        on:update={(event) => {
            email = event.detail;
        }}
        style="padding-bottom:1rem"
    />
    <TextArea
        value={message}
        id="form-message"
        placeholder="Enter your message here"
        title="Message"
        error={errors?.message ?? null}
        on:update={(event) => {
            message = event.detail;
        }}
        style="padding-bottom:1rem"
    />
    <button type="submit" disabled={submitting}>Submit form</button>
</form>

<form on:submit|preventDefault={handleSubmit}>
    <EmailInputField
        value={email}
        id="login-email"
        placeholder="[email protected]"
        title="Email"
        error={errors?.email ?? null}
        on:update={(event) => {
            email = event.detail;
        }}
        style="padding-bottom:1rem"
    />
    <PasswordInputField
        value={password}
        id="login-password"
        placeholder="P@$sw0rD"
        title="Password"
        error={errors?.password ?? null}
        on:update={(event) => {
            password = event.detail;
        }}
        style="padding-bottom:1rem;border-style:none"
    />
    <button type="submit" disabled={submitting}>Submit form</button>
</form>

Image

Responsive image component with lazy loading support. Requires the vanilla-lazyload package for lazy loading and vite-imagetools for responsive image support:

pnpm install -D vanilla-lazyload vite-imagetools

You will also need to update svelte.config.js configuration to use vite-imagetools:

/** @type {import('@sveltejs/kit').Config} */
import { imagetools } from 'vite-imagetools';
...

const config = {
  kit: {
    // hydrate the <div id="svelte"> element in src/app.html
    target: '#svelte',
    vite: {
      plugins: [imagetools()],
    },
  },
};

export default config;

For lazyloading, load the vanilla-lazyload script into the document in a layout component (e.g. src/routes/__layout.svelte):

  import lazyload from 'vanilla-lazyload';
  import { browser } from '$app/environment';

  if (browser && !document.lazyloadInstance) {
    document.lazyloadInstance = new lazyload();
  }

Then use the Image component on a page:

<script>
    import { onMount } from 'svelte';
    import { browser } from '$app/environment';
    import { Image } from '@rodneylab/sveltekit-components';

    import meta from '$lib/assets/your-image.jpg?w=768&metadata';
    import srcsetJpeg from '$lib/assets/your-image.jpg?w=1536;1280;768;640&jpeg&srcset';
    import srcsetWebp from '$lib/assets/your-image.jpg?w=1536;1280;768;640&webp&srcset';

    export let imageData;

    onMount(() => {
        if (browser) {
            document.lazyloadInstance.update();
        }
    });

    const { width, height, src } = meta;
    const sources = [
        { srcset: srcsetWebp, type: 'image/webp' },
        { srcset: srcsetJpeg, type: 'image/jpeg' },
    ];

    const sizes = '(max-width: 672px) calc(100vw - 32px), 672px';
</script>

<Image {alt} {width} {height} {src} {sources} {placeholder} {sizes} style={'border-radius:12px'} />

The code in onMount only needs to be called once for each page, so if, for example, you have component A, B and C all containing an image and included in page Z, add the onMount code only to page Z and add the Image component (without onMount code) to A.svelte, B.svelte and C.svelte.

If you want to load the image eagerly use the loading prop to specify this:

<Image {alt} {width} loading="eager" {height} {src} {sources} {placeholder} {sizes} />

Best practise is to load the largest contentful paint above the fold eagerly. Typically this means eager loading for banner images.

Props

alt: string
Text describing the image for screen reader users.
width: number
Nominal image width, used to help reduced cumulative layout shift.
height: number
Nominal image height, used to help reduced cumulative layout shift.
src: string
Image source. This is the fallback for older browsers.
sources: { srcset: string; type: string }[]
Array of source and types for responsive images.
placeholder: string
Can be a Base64 encoded, low resolution placeholder which is displayed while the full resolution image is loading.
sizes: string
Media query like string which helps the browser choose the right image size.
loading: string
Can be eager or lazy. Default is lazy.

See article on SvelteKit images which provides much more background on what these props are and how you might update them.

Map

Add a map to your SvelteKit site using Mapbox with OpenStreetMap and LeafletJS. Requires a Mapbox access token, just add it your to the .env file in your project:

PUBLIC_MAPBOX_ACCESS_TOKEN=your.token

Add the component to a .svelte file in your project:

<script>
    import { Map } from '@rodneylab/sveltekit-map-component';
    const latitude = 51.50162;
    const longitude = -0.14115;
    const zoom = 16;
    const location = { latitude, longitude };
</script>

<Map
    id="my-map"
    {location}
    {zoom}
    importance="high"
    markerMarkup="<p>We are <strong>here</strong>!</p>"
/>

Further Info

To create your own SvelteKit component library see the video on creating a SvelteKit component library. Drop a comment on that page if you have a question.

Feel free to jump into the Rodney Lab matrix chat room.

Top categories

svelte logo

Need a Svelte website built?

Hire a professional Svelte developer today.
Loading Svelte Themes