1.0.1 • Published 4 years ago

@thefootonline/vue-grid-designer v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

Vue Grid Designer

A Vue 2.x component for designing grid layouts using Sortable.js.

Vue CI Build GitHub release (latest by date) npm (scoped)

Design a responsive grid based on rows and blocks using HTML5 drag and drop. The JSON model can be used to generate an actual HTML grid using any CSS framework you choose or saved to a database for subsequent use. It can be decorated with any additional JSON properties to allow you to extend your grid in any way you need.

Screenshot

Table of Contents

Dependencies

vue-grid-designer has no external dependency requirements. The following dependencies are included in the exported ESM package:

{
    "@fortawesome/fontawesome-svg-core"  : "^1.2.30",
    "@fortawesome/free-solid-svg-icons"  : "^5.14.0",
    "@fortawesome/vue-fontawesome"       : "^2.0.0",
    "lodash-es"                          : "^4.17.15",
    "sortablejs"                         : "^1.10.2",
    "uuid"                               : "^8.3.0",
    "vue"                                : "^2.6.12"
}

Installation

npm i @thefootonline/vue-grid-designer --save

Usage

Either register vue-grid-designer as a global component in your main Vue application file:

import Vue             from 'vue';
import VueGridDesigner from '@thefootonline/vue-grid-designer';
Vue.component('vue-grid-designer', VueGridDesigner);

new Vue (
    {
        render: h => h ( App )
    }
).$mount ( '#app' );

or use locally (recommended) in your Vue component:

import VueGridDesigner from '@thefootonline/vue-grid-designer';

export default {
    ...
    components: { VueGridDesigner }
    ...
};

Then simply add the component to your template and bind your grid model to it:

<template>
    <div>
        <vue-grid-designer v-model="grid"></vue-grid-designer>
    </div>
</template>

<script>
    import VueGridDesigner from '@thefootonline/vue-grid-designer';
    export default { 
        components: { VueGridDesigner },
        data () {
            return {
                grid: []
            };
        }   
    };
</script>

You can even use it via a script tag:

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/@thefootonline/vue-grid-designer"></script>

Grid Data Model

The grid is a collection of row objects. row.blocks is a collection of block objects.

[
    {
        blocks: [
            { 
                span: 1,
                content: '<p>Foo</p>'
            }
        ]
    }
]

It is structured this way to allow rows and blocks to be decorated with additional properties. Use-cases are most likely to need additional data.

Internal model

Internally - VDG adds an _id property to each row and block (v4 UUID). Custom events include the ID, whereas the bound model only emits exactly what was passed in, including any custom properties. To retrieve the full internal model, including custom properties, call the getFullModel () component method.

Component Props

NameAttrTypeDefaultDescription
modemodeStringeditComponent mode - edit or view. View mode hides row and block controls, and displays any content passed in via block.content.
blocksPerRowblocks-per-rowNumber4Logical blocks per row. Each block can consume more than one logical block via span - like a table. But, like a responsive grid, you can exceed this number if you wish.
maxRowsmax-rowsNumber0Maximum number of rows. 0 to disable. If you pass in a grid that exceeds this number, it will still display all rows, however if you remove the rows, you cannot add them back.
rowClassrow-classStringPass in an additional CSS class for the grid row.
blockClassblock-classStringPass in an additional CSS class for the grid block.
minBlockHeightmin-block-heightNumber100Minimum block height in pixels.
blockMarginblock-marginNumber6Block margin in pixels.
enableMoveBlocksBetweenRowsenable-more-blocks-between-rowsBooleantrueAllow blocks to be moved between different rows. Setting to false restricts blocks to their own row.
sortableOptionssortable-optionsObject{}Native options passed directly through to the SortableJS constructor. Some options are overridden (see table below).
onNewRowon-new-rowFunctionCallback for creating a custom row object. No parameters. Return a new row object.
onNewBlockon-new-blockFunctionCallback for creating a custom block object. Receives ( row, span ) params. Return a new block object.

Overidden Sortable JS Options

PropAttrSortableJS OptionTypeDefaultDescription
sortableGhostClasssortable-ghost-classghostClassStringvgd__block--ghostCSS class applied to the ghost element.
sortableChosenClasssortable-chosen-classchosenClassStringvgd__block--chosenCSS class applied to the chosen element.
sortableDragClasssortable-drag-classdragClassStringvgd__block--dragCSS class applied to the dragged element.
sortableAnimationsortable-animationanimationNumber50Animation speed in ms. 0 to disable animations.
-disabledBoolean-Based on the mode prop. In view mode, the DnD functionality is disabled.
-groupStringvgdBased on the enableMoveBlocksBetweenRows prop.
-filterString.no-dragUsed to disable grid elements from being dragged (toolbars).
-preventOnFilterBooleantrueRelated to filter.
-onUpdateFunction-Used internally. See events table below.
-onRemoveFunction-Used internally. See events table below.
-onAddFunction-Used internally. See events table below.
-onStartFunction-Used internally. See events table below.
-onEndFunction-Used internally. See events table below.

Events

All events have a vgd property added to the original event (either SortableJS event or native event - whichever is relevant), and contain row and block properties.

NameDescriptionExample
readyFired when the grid is initialised and ready for use. No event data is emitted.
updateFired after a block has been moved. Only fired when a block is moved within a row. When block is moved between rows, remove-block and add-block events are fired.vue-grid-designer @update="updateHandler" />
remove-blockFired after a block has been removed.vue-grid-designer @remove-block="removeBlockHandler" />
remove-rowFired after a row has been removed.vue-grid-designer @remove-row="rowRemoveHandler" />
add-blockFired after a new block has been added.vue-grid-designer @add-block="addBlockHandler" />
add-rowFired after a new row has been added.vue-grid-designer @add-row="addRowHandler" />
drag-startFired when a drag action has started.vue-grid-designer @drag-start="dragStartHandler" />
drag-stopFired when a drag action has ended.vue-grid-designer @drag-stop="dragStopHandler" />
block-changedFired when a block has been expanded or collapsed.vue-grid-designer @block-changed="blockChangedHandler" />
inputFired by Vue implicitly for v-model support.-

Methods

Methods that receive an event parameter fire a custom event.

NameParamsDescription
getFullModel()Return the full internal model including custom properties.
addRow( event )Append a new row to the grid.
addBlock( event, row, span = 1 )Append a new block to a row.
deleteRow( event, row )Delete a row from the grid.
deleteBlock( event, row, block )Delete a block from a row.
expandBlock( event, row, block, num = 1 )Decrease the span for a given block.
collapseBlock( event, row, block, num = 1 )Increase the span for a given block.
getEventData( event, sourceRow = 'from' )Return a vgd info object for a given event. sourceRow can be from or to.
getBlockStyles( row, block )Return a style object for a given block. Can be used with :style="getBlockStyles(...)".
getAnimationStyle()Return the animation style object. Can be used with :style="getAnimationStyle()".
initGrid()Initialise the grid. Called from mounted().
initSortableRow( row )Initialise the SortableJS plugin for a given row.
fireChanged()Trigger the input event. Used for v-model support.

CSS and Styles

This component uses BEM methodology and naming convention.

CSS Classes Used

CSS ClassElementDescription
vgd__rowRow
vgd__blockBlock
vgd__block__toolbarBlock toolbar
vgd__block__toolbar__buttonBlock toolbar icon button
vgd__block__contentBlock content
vgd__row__toolbarRow toolbar
vgd__row__toolbar__buttonRow toolbar icon button
vgd__footer__buttonAdd row button
vgd__block--ghostBlock variant for the sortable ghost element.
vgd__block--chosenBlock variant for the sortable chosen element.
vgd__block--dragBlock variant for the sortable dragged element.
use-hoverRowSee note below on using :hover styles.

Specificity and Overriding Scoped Styles

For scoped styles, Vue uses a data attribute based on the component ID to isolate styles to the component. In order to override these styles you should prefix all style overrides using your main app or component selector. E.g.:

#demo {
    .vgd__row { ... }
}

For additional examples, please look at the Demo source code.

Using :hover styles

There is a known issue with :hover state in DnD elements in Chrome. The workaround is to scope any :hover styles. This scope is provided via the .use-hover class. E.g.:

.use-hover {
    .vgd__row:hover { ... }
}

Demo

Component Demo

Contributing

Contributions welcome, please read CONTRIBUTING and CODING-STANDARDS.

Credits

Author

Contributors

  • .

Licence

MIT