Skip to content

asterics/vue-css-grid-layout

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vue CSS Grid Layout

A grid layout for Vue.js using CSS Grid Layout.

Features

This library was created since both vue-grid-layout and gridstack.js didn't fit the requirements for the use in the AAC application AsTeRICS Grid. The main features are:

  • uses the native CSS Grid Layout instead of absolute positioning
  • automatically fills the whole container with same-sized grid elements (not easily possible in gridstack.js)
  • uses native Vue 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):

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:

<template>
    <div class="render-component">{{ element.id }}</div>
</template>

<script>
export default {
    props: {
        element: Object
    }
}
</script>

<style scoped>
.render-component {
    border: 1px solid black;
    display: flex;
    flex-grow: 1;
}
</style>

Use GridLayout from this library in order to render a grid:

<template>
    <grid-layout :elements="elements" :render-component="RenderComponent"/>
</template>

<script>
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 }
            ]
        }
    }
}
</script>

<style src="vue-css-grid-layout/dist/vue-css-grid-layout.css"></style>

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:

<link rel="stylesheet" href="https://unpkg.com/vue-css-grid-layout/dist/vue-css-grid-layout.css">

Create some HTML using the grid-layout element`:

<div id="app">
    <grid-layout :elements="elements" render-component="render-component"/>
</div>

Import the GridLayout class in a script and use it:

<script type="module">
    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 }
                ]
            };
        }
    });
</script>

See 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:

<grid-layout :elements="elements" render-component="render-component" :generic-options="{ color: 'green' }"/>

These options can be used within the render-component along with the element passed by default:

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:

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:

  • 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.

This library uses interact.js as dependency.

About

A grid layout for Vue.js using CSS Grid

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published