svelte-grid-extended
⚠️ Package currently in alpha, please consider that it will be changed in the future.
Description
Svelte-Grid-Extended is a draggable, resizable and responsive grid layout. The package is created as extended verison of svelte-grid, and will implement all of its features in future releases.
Installation
With NPM:
npm install svelte-grid-extended
With Yarn:
yarn add svelte-grid-extended
With pnpm:
pnpm install svelte-grid-extended
Props
Main props
prop | description | type | default |
---|---|---|---|
cols | Grid columns count. If set to 0, grid will grow infinitly. Must be >= 0. | number | 0 |
rows | Grid rows count. If set to 0, grid will grow infinitly. Must be >= 0. | number | 0 |
itemSize | Size of the grid item. If not set, grid will calculate it based on container size. | { width?: number, height?: number } | {} |
items | Array of grid items. | Layout<T> | requried |
gap | Gap between grid items. | number | 10 |
bounds | Should grid items be bounded by the grid container. | boolean | false |
readonly | If true disables interaction with grid items. | boolean | false |
⚠️ ifcols
or/androws
are set to 0,itemSize.width
or/anditemSize.height
must be setted.
Layout
Layout<T>
are represented as an array of objects, items of which must have the following properties:
prop | description | type | default |
---|---|---|---|
id | Unique id of the item. Used to compare items during collision tests | string | requried |
x | X position of the item in grid units. | number | requried |
y | Y position of the item in grid units. | number | requried |
w | Width of the item in grid units. | number | requried |
h | Height of the item in grid units. | number | requried |
movable | If true, item can be moved by user. | boolean | true |
resizable | If true, item can be resized by user. | boolean | true |
data | Custom attributes. 🦌 | T | undefined |
Style related props:
Component can be styled with css framework of your choice or with global classes. To do so, you can use the following props:
class
- class name for grid container.itemClass
- class name for grid item.itemActiveClass
- class name that applies when item is currently being dragged or resized. By default, it is used to make active grid item transparent.itemPreviewClass
- class name for preview where item will be placed after interaction.resizerClass
- class name for item's resize handle.
To understand how to use these props, look at <Grid />
component simplified structure.
📄
active
is variable that indicates if grid item is currently being dragged or resized:
<!-- Grid -->
<div class={class}>
<!-- GridItem -->
<div class={itemClass} class:itemActiveClass={active}>
<slot />
<!-- Resizer -->
<div class={resizerClass} />
<!-- Resizer -->
</div>
{#if active}
<!-- GridItemGhost -->
<div class={itemPreviewClass} />
{/if}
<!-- /GridItem -->
</div>
<!-- /Grid -->
Events
Grid emits the following events:
event name | description | payload |
---|---|---|
change | Emitted when grid items are changed. | {item: LayoutItem} |
<script lang="ts">
import Grid, { type LayoutChangeDetail } from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 3, h: 1 }
];
function hanleGridChange(event: CustomEvent<LayoutChangeDetail>) {
console.log(event.detail.item);
}
</script>
<Grid {items} cols={10} rows={10} on:change={hanleGridChange}>
<div>Content</div>
</Grid>
Usage
Basic
✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 3, h: 1 }
];
</script>
<Grid {items} cols={10} rows={10}>
<div>Content</div>
</Grid>
Static grid
When cols
or rows
and itemsSize
are set, grid becomes static and ignores the size of the container.
It can be set to both dimensions or just one.
Both: ✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 1, h: 1 }
];
const itemSize = { width: 100, height: 40 };
</script>
<Grid {items} {itemSize} cols={10} rows={10}>
<div>Content</div>
</Grid>
Only rows: ✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 1, h: 1 }
];
const itemSize = { height: 40 };
</script>
<Grid {items} {itemSize} cols={10} rows={10}>
<div>Content</div>
</Grid>
Grid without bounds
When cols
or/and rows
set to 0, grid grows infinitly. The grid container adapts its width and height to fit all elements.
It can be set to both dimensions or just one.
✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 1, h: 1 }
];
const itemSize = { width: 100, height: 40 };
</script>
<Grid {items} {itemSize} cols={0} rows={0}>
<div>Content</div>
</Grid>
Styling
Grid can be styled with classes passed to various props. Check Style related props section for more info.
✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 1, h: 1 }
];
</script>
<Grid
{items}
class="grid-container"
itemClass="grid-item"
itemActiveClass="grid-item-active"
itemPreviewClass="bg-red-500 rounded"
>
<div>Content</div>
</Grid>
<style>
:global(.grid-container) {
opacity: 0.7;
}
:global(.grid-item) {
transition: width 4s, height 4s;
transition: transform 4s, opacity 4s;
}
:global(.grid-item-active) {
opacity: 0.1;
}
/* tailwind classes */
:global(.bg-red-500) {
background-color: rgb(202, 33, 33);
}
:global(.rounded) {
border-radius: 0.25rem;
}
</style>
Disable interactions
To disable interactions, set readOnly
prop to true
. Or set movable
and/or resizable
to false
on specific item.
Read Only grid: ✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1 },
{ id: '1', x: 0, y: 1, w: 1, h: 1 }
];
</script>
<Grid {items} cols={10} rows={10} readOnly>
<div>Content</div>
</Grid>
Make item non-interactive: ✨ repl
<script lang="ts">
import Grid from 'svelte-grid-extended';
const items = [
{ id: '0', x: 0, y: 0, w: 1, h: 1, movable: false },
{ id: '1', x: 0, y: 1, w: 1, h: 1, movable: false, resizable: false }
];
</script>
<Grid {items} cols={10} rows={10}>
<div>Content</div>
</Grid>