Skip to content
Snippets Groups Projects
Commit 3b3446a8 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Merge branch '1-implement-basic-functionality' into 'main'

Resolve "Implement basic functionality"

Closes #1, #2, #3, #4, #5, and #6

See merge request !2
parents d9756577 977c170a
No related branches found
No related tags found
1 merge request!2Resolve "Implement basic functionality"
Pipeline #131113 failed
Showing
with 484 additions and 29 deletions
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"plugin:vue/essential",
"plugin:vue/strongly-recommended",
"eslint:recommended",
"prettier",
"@vue/eslint-config-prettier",
],
env: {
es2021: true,
},
parserOptions: {
ecmaVersion: "latest",
},
ignorePatterns: ["dist/*"],
};
...@@ -2,4 +2,4 @@ node_modules ...@@ -2,4 +2,4 @@ node_modules
dist dist
package-lock.json package-lock.json
docs/.vuepress/dist docs/.vuepress/dist
.idea .idea
\ No newline at end of file
image: node:latest
stages:
- test
lint-test-job:
stage: test
script:
- npm install
- npm run lint
dist/
docs/.vuepress/dist/
example/src/assets/base.css
.idea/
node_modules/
package-lock.json
module.exports = { module.exports = {
title: 'vue-draggable-grid', title: "vue-draggable-grid",
description: 'vue-draggable-grid component library for a draggable grid', description: "vue-draggable-grid component library for a draggable grid",
themeConfig: { themeConfig: {
sidebar: [ sidebar: [
{ {
title: 'Components', title: "Examples",
collapsable: false, collapsable: false,
children: [ children: [
'/components/component.md', "/examples/Generic.md",
] "/examples/TicTacToe.md",
} "/examples/Counters.md",
] "/examples/Lessons.md",
} "/examples/Colors.md",
} "/examples/Disabled.md",
\ No newline at end of file "/examples/DisabledItems.md",
"/examples/Responsive.md",
],
},
],
nav: [
{ text: "Home", link: "/" },
{ text: "Guide", link: "/guide/" },
{ text: "Examples", link: "/examples/Generic.md" },
{
text: "Repository",
link: "https://edugit.org/AlekSIS/libs/vue-draggable-grid/",
},
],
},
};
import draggableGrid from "../../src/index.js";
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData, // site metadata
isServer, // is this enhancement applied in server-rendering or client
}) => {
Vue.use(draggableGrid);
};
# vue-draggable-grid ---
home: true
Document the library here. heroText: vue-draggable-grid
tagline: A vueJS library to create grids with draggable data blocks.
### Installation actionText: Get Started →
actionLink: /guide/
$ npm install vue-draggable-grid footer: Copyright © 2023 Julian Leucker
\ No newline at end of file ---
# component
`Component` is a cool component. Here's how to use it...
<template>
<component />
</template>
\ No newline at end of file
# Example 5: Dynamic colors
This example showcases the `rawItem` with the custom method
`getColor`. Both grids on the outside call the method with
`"red"` while the one in the middle uses `"green"`.
We use arrays called `placedA`, `placedB` and
`placedC` to save which item is contained in which grid.
Notice: The third grid doesn't save the item positions, they are always
positioned automatically.
<ClientOnly>
<script setup>
import Example5Colors from "../../example/src/Example5Colors.vue";
</script>
<Example5Colors />
</ClientOnly>
# Example 3: Counters
Showcasing local and global state: The local state of the counter
components doesn't change when moved inside one grid, but is cleared when
moved to another. The global state is in the `data` attribute
of each item and gets transferred as well. Both grids also have custom
highlights.
<ClientOnly>
<script setup>
import Example3Counters from "../../example/src/Example3Counters.vue";
</script>
<Example3Counters />
</ClientOnly>
# Example 6: Disabled grid
This uses the same data as the tic-tac-toe but is completely disabled.
Notice how the items still move if the tic-tac-toe data
change. Uncheck the first checkbox to enable the grid.
The grid can also be in a loading state, in which it is disabled as well,
but it displays loading symbols everywhere. Check the second checkbox to
enable the loading state.
<ClientOnly>
<script setup>
import Example6Disabled from "../../example/src/Example6Disabled.vue";
</script>
<Example6Disabled />
</ClientOnly>
# Example 7: Disabled items and fields
This is a grid with disabled fields and items. Red items are disabled
and cannot be moved. Pink fields are disabled and items cannot be moved
to them. Green items are normal and enabled.
<ClientOnly>
<script setup>
import Example7DisabledItems from "../../example/src/Example7DisabledItems.vue";
</script>
<Example7DisabledItems />
</ClientOnly>
# Example 1: Generic Example
Grid with two programmatically blocked cells and one programmatically blocked item
<ClientOnly>
<script setup>
import Example1Generic from "../../example/src/Example1Generic.vue";
</script>
<Example1Generic />
</ClientOnly>
# Example 4: Dynamic lessons
These lessons are loaded from `computed` to simulate a
non-editable source like an API. they are changed using the method
`handleLessonMoved`. Try changing the sizes of Lesson1, the
grid and the texts of the items! The lesson container on the side doesn't
have a highlight and doesn't keep track of the item position. Try moving
`item3` back and forth, the text will change!
<ClientOnly>
<script setup>
import Example4Lessons from "../../example/src/Example4Lessons.vue";
</script>
<Example4Lessons />
</ClientOnly>
# Example 8: Responsive
The grid is responsive. Try resizing it below:
<ClientOnly>
<script setup>
import Example8Responsive from "../../example/src/Example8Responsive.vue";
</script>
<Example8Responsive />
</ClientOnly>
# Example 2: Tic-Tac-Toe
A grid functioning as a playing field and another functioning as a container for playing pieces. You can drag as many pieces as you want from the container to the field.
<ClientOnly>
<script setup>
import Example2TicTacToe from "../../example/src/Example2TicTacToe.vue";
</script>
<Example2TicTacToe />
</ClientOnly>
---
sidebar: auto
---
# Guide
## Quickstart
Install the package `vue-draggable-grid` via your favourite package manager.
Include the library in your project:
```javascript
import draggableGrid from "vue-draggable-grid";
Vue.use(draggableGrid);
// Now create your app as usual
```
An example usage could look like this:
```vue
<template>
<drag-grid v-model="items" :cols="4" :rows="4">
<template #item="item">
{{ item.data.text }}
</template>
</drag-grid>
</template>
<script>
export default {
name: "YourComponent",
data() {
return {
items: [
{
x: 1,
y: 3,
w: 2,
h: 2,
key: "item1",
data: { text: "Hello world 1" },
},
{
x: 2,
y: 2,
w: 2,
h: 1,
key: "item2",
data: { text: "Hello world 2" },
},
{
x: 3,
y: 1,
w: 1,
h: 1,
key: "item3",
data: { text: "Hello world 3" },
},
],
};
},
};
</script>
```
## Blocking fields
A field (or cell) can be blocked via the `disabledFields` prop. The prop receives an array of objects, containing the
coordinates of the blocked fields.
```javascript
disabledFields: [
{ x: 1, y: 1 },
{ x: 2, y: 3 },
];
```
## Prevent items from being dragged
To disable dragging of a specific item, simply set the attribute `disabled` of the item to `true`.
```javascript{4,5}
someDisabledItems: [
{ key: "key1", x: 1, y: 3, w: 1, h: 1, data: {} },
{ key: "key2", x: 2, y: 2, w: 1, h: 1, data: {} },
{ key: "key3", x: 3, y: 1, w: 1, h: 1, data: {}, disabled: true },
{ key: "key4", x: 1, y: 2, w: 1, h: 1, data: {}, disabled: true },
]
```
The highlighted items are not draggable.
## Disabling the grid
If the boolean property `disabled` is set for the whole grid, the grid itself is disabled,
and items can't be moved.
::: tip NOTICE
A disabled grid only prevents changing the data inside the grid. If the data changes from outside
of the grid, the grid _will_ rerender.
:::
## Programmatic validation of movements
It is also possible to supply a function to dynamically or programmatically hinder fields from being moved to,
and items from being moved. This can be done by supplying a function which takes the `x` and `y` coordinates of
the field as well as the key of the item. If `false` is returned, the movement is prohibited. The highlight which
appears when dragging an element is also disabled for this field.
Examples for such methods are the following:
```javascript
function blockField(x, y, key) {
// We won't move items with ID 'obj8' and nothing into (3, 3) and (4, 3)
if (x === 3 && y === 3) return false;
if (x === 4 && y === 3) return false;
return key !== "obj8";
}
function blockAllMoving() {
return false;
}
```
## Changing the highlight
The highlight is the grey-bordered rectangle which appears when dragging over a field.
### Custom highlight
To customize the highlight, use the `highlight` slot inside the grid component.
```html
<drag-grid v-model="items" :cols="3" :rows="2">
<template #highlight>
<div ref="highlight" class="custom-highlight">
This is a custom highlight with a custom style!
</div>
</template>
</drag-grid>
```
### Disabled highlight
To disable the highlight, use the `no-highlight` prop.
## Displaying the loading of items
If the grid is supplied with the `loading` prop, it will be in a loading status. In this status it is
disabled, like if `disabled` where true, but the grid is filled with elements inside the `loader` slot.
This provides the ability to do something like more realistic skeleton loaders.
## Changing items on move
It is possible to make changes to an item once it moved successfully. One can supply a function in the
`validate-element` prop which gets called on a moved item and can make (in place) changes to it. Such a
function could look like this:
```javascript
function randomKey(element) {
if (element.key.length !== 1) return;
element.key += Math.random().toString(36).replace("0.", "");
}
```
This method changes the key of a moved item to a random string if the key has a length of 1.
This is used inside example 2 (the tic-tac-toe game).
## Functional item properties
Properties of items don't have to be Numbers, Strings and Objects, they can also be functions
returning those types. They will automatically be called with a grid object containing the `gridId`
as well as the `context`.
A singular item could look like this:
```javascript
[
{
x: (grid) => {
return grid.gridId === "lesson-plan" ? this.lesson1X : 0;
},
y: (grid) => {
return grid.gridId === "lesson-plan" ? this.lesson1Y : 0;
},
w: 1,
h: this.lesson1Length,
key: "lesson1",
data: {
text: this.lessonData.lesson1,
},
},
];
```
Items can also have custom extra properties. They will however be reset after moving.
An example where these are used is Example 5.
## Listening to grid changes
There are two ways to process changes made by dragging and dropping items: the `input` event
and the `itemChanged` event.
The `input` event works together with the value prop so one can use `v-model` to supply the grid
and have changes made automatically. The event returns the grid how it would look if the item
moved to the specific location.
::: warning
Notice that this event is only possible if your item properties are basic types, functional items are not
supported and the properties will be reset to `undefined`.
:::
The `itemChanged` event returns the moved item with following attributes:
```javascript
let eventData = {
context: String, // Context of the origin grid (same as the target's)
data: Object, // Data Object of the item
gridId: String, // ID of the target grid
h: Number, // Height of the item
key: String, // Key of the item
mouseX: Number, // Mouse position on the element relative to
mouseY: Number, // the center of the top left rectangle
originGridId: String, // ID of the origin grid
w: Number, // Width of the item
x: Number, // New x position (col) of the item
y: Number, // New y position (row) of the item
};
```
This event doesn't change the grid, this change has to be made separately. This is
useful if e.g. a direct API request is needed.
## Multiple grids
To connect multiple grids they need to have the same context. If you supply the same string to the
`context` prop of two grids, the items can be moved interchangeably.
::: warning
Items are not deleted from the source grid if moved to a different one. You have to build a mechanism for this yourself.
Examples for such a mechanism can be found in Examples 4 and 5.
:::
To handle movements from one grid to another, the attributes `gridId` and `originGridId` of the event will help.
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue-Draggable-Grid Example App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
example/public/favicon.ico

4.19 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment