Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/kiosion/svelte-breakpoints

Svelte component and helper functions for creating easy responsive layouts with CSS media queries.
https://github.com/kiosion/svelte-breakpoints

css-media-queries media-queries responsive svelte svelte-component svelte5 sveltejs sveltekit

Last synced: 20 days ago
JSON representation

Svelte component and helper functions for creating easy responsive layouts with CSS media queries.

Awesome Lists containing this project

README

        

# svelte-breakpoints
Svelte component and helper functions for creating easy dynamic layouts with CSS media queries.

> [!Important]
> Since this package relies on CSS Media Query Listeners, content outside the Default slot is *not* rendered server-side. If you need conditional layouts based on screen sizes, and need SSR compatibility, use CSS `@media` queries in your styles instead.

> [!Note]
> v1.0 is currently in progress, and includes a rewrite of the component and helper function for use with Svelte v5's Runes. This readme references new functionality not present in the current version - the current version can be found under the [`v0` branch](https://github.com/kiosion/svelte-breakpoints/tree/v0).

## Installation
Install using yarn / pnpm / npm:

```bash
yarn add -D svelte-breakpoints
```
```bash
pnpm add -D svelte-breakpoints
```
```bash
npm install --save-dev svelte-breakpoints
```

## Usage
### Helpers
Import `useMediaQuery` and provide a valid CSS media query. It will return a readable boolean store representing whether the media query matches.

```html

import { useMediaQuery } from 'svelte-breakpoints';

const isMobile: Readable<boolean> = useMediaQuery('(max-width: 600px)');

$effect(() => {
if ($isMobile) {
console.log('Not desktop!');
}
});

{#if $isMobile}

{/if}
```

It can be used for any valid CSS media queries.

```ts
import { useMediaQuery } from 'svelte-breakpoints';

const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
```

`subscribeToQueries` allows subscribing to the state of multiple MQLs, as well as updating them after the initial function call. It returns a Readable store containing the names of all matching queries in an array.

```html

import { subscribeToQueries } from 'svelte-breakpoints';

const mediaQueries = {
reduceMotion: '(prefers-reduced-motion: reduce)',
prefersDark: '(prefers-color-scheme: dark)'
};

const matches: Readable<string[]> = subscribeToQueries(mediaQueries);

$effect(() => {
if ($matches.includes('reduceMotion')) {
console.log('Reduced motion is enabled');
}
});

```

### Component
Import the component and pass in the media queries to use. By default, the component will only render the last matching snippet, or the 'default' snippet if no queries match, finally falling back to the Default Slot if no snippets are provided. Passing `renderAll` will render all matching snippets rather than the last matching.

```html

import Breakpoints from 'svelte-breakpoints';

const mediaQueries = {
small: '(min-width: 0px)',
medium: '(min-width: 768px)',
large: '(min-width: 1024px)',
};

{#snippet small()}

Screen is less than 768px wide


{/snippet}
{#snippet medium()}

Screen is at least 768px wide


{/snippet}
{#snippet large()}

Screen is at least 1024px wide


{/snippet}

{#snippet small()}

Screen is less than 768px wide


{/snippet}
{#snippet medium()}

Screen is at least 768px wide


{/snippet}
{#snippet large()}

Screen is at least 1024px wide


{/snippet}

```

You can also define snippets elsewhere and pass them in via the `content` prop.

`fallback` is reserved for fallback content if no snippets match. If no `fallback` is provided, the Default slot's content will be rendered.

```html
{#snippet fallback()}

I'm defined elsewhere!


{/snippet}
{#snippet small()}

I'm defined elsewhere too!


{/snippet}

```

Binding to `component.matches` returns a Readable store containing the names of all matching queries.

```html

let componentInstance: { matches: Readable<(string | number)[]> } = $state({ matches: readable([]) }),
{ matches } = $derived(componentInstance);

{#if $matches.includes('large')}

Screen is at least 1024px wide


{:else}

Screen is less than 1024px wide


{/if}

```

Since any valid CSS media queries can be used, you can also use queries such as `prefers-color-scheme`, `prefers-reduced-motion`, etc.

```html

import Breakpoints from 'svelte-breakpoints';

const mediaQueries = {
reducedMotion: '(prefers-reduced-motion: reduce)',
};

{#snippet reducedMotion()}

Reduced motion is enabled


{/snippet}
{#snippet default()}

Reduced motion is not enabled


{/snippet}

```

## Development
To build the package, install deps with `pnpm install`, then run `pnpm build`. This will output the compiled files to the `dist` directory. To run the demo app, use `pnpm dev`.

### Testing
To run all Playwright and Vitest tests, use `pnpm test`.

## Issues
If you find any issues, please [open a new issue](https://github.com/kiosion/svelte-breakpoints/issues/new), or submit a pull request!

## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.