Library of TypeScript friendly SvelteKit components for adding functionality to your SvelteKit apps.
To install the package run
pnpm add -D @rodneylab/sveltekit-components @rodneylab/sveltekit-map-component
pnpm add --save-peer leaflet
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>
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.
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
orlazy
. Default islazy
.
See article on SvelteKit images which provides much more background on what these props are and how you might update them.
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>"
/>
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.