https://github.com/asterics/vue-css-grid-layout
A grid layout for Vue.js using CSS Grid
https://github.com/asterics/vue-css-grid-layout
Last synced: about 2 months ago
JSON representation
A grid layout for Vue.js using CSS Grid
- Host: GitHub
- URL: https://github.com/asterics/vue-css-grid-layout
- Owner: asterics
- License: agpl-3.0
- Created: 2024-12-13T07:34:13.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-01-07T09:21:35.000Z (about 1 year ago)
- Last Synced: 2025-10-05T03:51:09.714Z (6 months ago)
- Language: JavaScript
- Size: 1.68 MB
- Stars: 0
- Watchers: 7
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Vue CSS Grid Layout
A grid layout for Vue.js using CSS Grid Layout.
## Features
This library was created since both [vue-grid-layout](https://github.com/jbaysolutions/vue-grid-layout) and [gridstack.js](https://github.com/gridstack/gridstack.js) didn't fit the requirements for the use in the [AAC application AsTeRICS Grid](https://github.com/asterics/AsTeRICS-Grid). The main features are:
* uses the native [CSS Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout) instead of absolute positioning
* automatically fills the whole container with same-sized grid elements ([not easily possible in gridstack.js](https://github.com/gridstack/gridstack.js/issues/2583))
* uses native [Vue List Move Transitions](https://v2.vuejs.org/v2/guide/transitions#List-Move-Transitions) for animations
* predictable collision handling: either swapping elements by dropping an element onto another element or move other elements to the right, by dropping it in-between two elements
* not moving other elements until dropping the moved element (not messing up of the layout while moving)
* easy way to move all elements
> [!NOTE]
> Currently only Vue `2.7` is supported, but it should be no problem to make the library compatible with Vue 3
## Examples
There are the following examples (see [folder examples](https://github.com/asterics/vue-css-grid-layout/tree/main/examples)):
* [minimum-example.html](https://asterics.github.io/vue-css-grid-layout/examples/minimum-example.html): minimum working example
* [basic-options.html](https://asterics.github.io/vue-css-grid-layout/examples/basic-options.html): try all options
* [responsive.html](https://asterics.github.io/vue-css-grid-layout/examples/responsive.html): responsive grid using full viewport size
* [different-element-types.html](https://asterics.github.io/vue-css-grid-layout/examples/different-element-types.html): render different types of elements
* [insert-new.html](https://asterics.github.io/vue-css-grid-layout/examples/insert-new.html): insert new elements at a specific location by click / tap
* [move-all.html](https://asterics.github.io/vue-css-grid-layout/examples/move-all.html): move all elements to top / right / bottom / left
* [switch-layouts.html](https://asterics.github.io/vue-css-grid-layout/examples/switch-layouts.html): switch between predefined layouts
## Use via npm in SFC
To use this library via npm and with Vue's Single-File Components (SFC), follow these steps:
First install via `npm install vue-css-grid-layout --save` or `yarn add vue-css-grid-layout`.
Create a custom component for rendering a single grid element like this, e.g. as `render-component.vue`:
```vue
{{ element.id }}
export default {
props: {
element: Object
}
}
.render-component {
border: 1px solid black;
display: flex;
flex-grow: 1;
}
```
Use `GridLayout` from this library in order to render a grid:
```vue
import { GridLayout } from 'vue-css-grid-layout';
import RenderComponent from './render-component.vue';
export default {
components: { GridLayout, RenderComponent},
data() {
return {
RenderComponent: RenderComponent,
elements: [
{ x: 0, y: 0, width: 1, height: 1, id: 1 },
{ x: 1, y: 1, width: 1, height: 1, id: 2 }
]
}
}
}
```
## Use from CDN
You can also use the files from CDN (or use the files from the `dist` folder of this repository).
Include the CSS:
```html
```
Create some HTML using the `grid-layout` element`:
```html
```
Import the `GridLayout` class in a script and use it:
```html
import { GridLayout } from 'https://unpkg.com/vue-css-grid-layout/dist/vue-css-grid-layout.es.js';
Vue.component('render-component', {
template: '<div class="render-component">{{ element.id }}</div>',
props: {
element: Object
}
});
new Vue({
el: '#app',
components: { GridLayout },
data() {
return {
elements: [
{ x: 0, y: 0, width: 1, height: 1, id: 1 },
{ x: 1, y: 1, width: 1, height: 1, id: 2 }
]
};
}
});
```
See [minimum-example.html](https://github.com/asterics/vue-css-grid-layout/blob/main/examples/minimum-example.html) for the full example.
## API
There are two components that can be used:
* `GridLayout`: the Vue component rendering a grid using CSS Grid
* `gridLayoutUtil`: a collection of utils for actions on the grid elements, e.g. collision handling or moving multiple elements. This component is used internally by `GridLayout`, but can also be used externally for manual collision handling or moving of multiple elements.
### GridLayout
The `GridLayout` Vue component has the following props and events.
#### Props
* `renderComponent: [Object, String]`: a Vue component that renders a single element of the grid. A prop `element` is passed to this component containing the data of the current element to render.
* `elements: Array`: an array of elements to render in the grid. Every element must have the properties `id, x, y, width, height` where the `id` must be unique. The single elements are passed to `renderComponent` as prop `element`.
* `rows: Number`: the minimum number of rows of the grid. Actual shown rows are the maximum of `rows` and `rows defined by given elements`.
* `columns: Number`: the minimum number of columns of the grid. Actual shown columns are the maximum of `columns` and `columns defined by given elements`.
* `backgroundColor: String`: the background color of the grid in any format valid in CSS (e.g. `lightblue` or `#f5f5f5`).
* `baseTag: String`: the name of the HTML tag the base element of the grid should have, e.g. `div`, defaults to an ordered list (`ol`).
* `elementTag: String`: the name of the HTML tag the grid elements should have, e.g. `div`, defaults to a list item (`li`).
* `editable: Boolean`: if `true` the grid can be edited, elements can be dragged and resized.
* `resizeHandleSelector: String`: a CSS selector for selecting resize handles (at the bottom right) of the elements which make it clearer / easier to resize elements. Resize handles have to be added to the `renderComponent`, if desired.
* `backgroundLines: Boolean`: if `true` the grid shows lines in the background indicating the rows and columns of the grid
* `animationDurationMs: Number`: the duration of the animations when elements are dragged / resized (`editable: true`), defaults to `200ms`.
Any additional props can be passed to `GridLayout` which are passed on to the `renderComponent`. So e.g. if passing some generic options to `grid-layout` like this:
```html
```
These options can be used within the `render-component` along with the `element` passed by default:
```javascript
props: {
element: Object,
genericOptions: Object
}
```
#### Events
Two events can be emitted by `GridLayout` with `editable: true`:
* `changed (newElements)`: the event `changed` is emitted after the layout has changed by dragging or resizing. In the handler the rendered elements should be set to the new elements like `this.elements = newElements`.
* `interacted (x,y)`: the event `interacted` is emitted after a click or tap anywhere on the grid returning the coordinates of this event. This makes it easily possible to create new elements at the position of the last user interaction.
### gridLayoutUtil
The component `gridLayoutUtil` can be used for manually doing actions on the grid elements like moving all elements or resolving conflicts.
Import it along with `GridLayout`, if needed:
```javascript
import { GridLayout, gridLayoutUtil } from 'vue-css-grid-layout';
// or
import { GridLayout, gridLayoutUtil } from 'https://unpkg.com/vue-css-grid-layout/dist/vue-css-grid-layout.es.js';
```
These are the most important methods, for more details look at the [JSDoc comments in the implementation](https://github.com/asterics/vue-css-grid-layout/blob/main/src/utils/gridLayoutUtil.js):
* `gridLayoutUtil.moveAsPossible = function(allElements = [], moveElements = [], direction, options = {})`
* moves elements in a specific direction as far as possible (without colliding with another element)
* `allElements`: array of all elements
* `moveElements`: the elements to move
* `direction`: the direction to move, see gridLayoutUtil.DIR_* or 1-4 (UP, RIGHT, DOWN, RIGHT)
* `options.gridWidth` standard width of the grid, can be overruled by given grid elements
* `options.gridHeight` standard height of the grid, can be overruled by given grid elements
* `gridLayoutUtil.resolveCollisions = function(gridElements, newElement, options = {})`
* resolves collisions based on given grid and a newly added / changed element
* `gridElements` array of all grid elements (including newElement)
* `newElement` element changed / added (already at new position)
## Acknowledgement
This library was initially developed within a [netidee project funding](https://www.netidee.at/asterics-grid).
This library uses [interact.js](https://interactjs.io/) as dependency.