diff --git a/example/src/App.vue b/example/src/App.vue
index e9a35c4f8ddcc5b570fcb364ba903522f35dd9fd..5750f67306b9a23690aea16d90ae3ffafa22af0f 100644
--- a/example/src/App.vue
+++ b/example/src/App.vue
@@ -70,6 +70,33 @@ import NumberCounter from "./components/NumberCounter.vue";
         </template>
       </drag-grid>
     </div>
+    <div class="ttt-container">
+      <label>
+        Lesson 1 has length: {{ lesson1Length }}
+        <input type="range" v-model="lesson1Length" min="1" max="5" step="1" />
+      </label>
+      <label>
+        Lesson grid has width: {{ lesson1Cols }}
+        <input type="range" v-model="lesson1Cols" min="2" max="5" step="1" />
+      </label>
+      <label>
+        Lesson grid has height: {{ lesson1Rows }}
+        <input type="range" v-model="lesson1Rows" min="6" max="10" step="1" />
+      </label>
+
+      <drag-grid
+        :value="lessons1"
+        :cols="parseInt(lesson1Cols)"
+        :rows="parseInt(lesson1Rows)"
+        class="bordered"
+        context="lesson"
+        @itemChanged="handleLessonMoved"
+      >
+        <template #item="item">
+          <div class="container">{{ item }}</div>
+        </template>
+      </drag-grid>
+    </div>
   </div>
 </template>
 
@@ -93,6 +120,21 @@ export default {
     logInput(input) {
       console.log("New movement detected:", input);
     },
+    handleLessonMoved(lesson) {
+      this.logInput(lesson);
+      switch (lesson.key) {
+        case "lesson1":
+          this.lesson1X = lesson.x;
+          this.lesson1Y = lesson.y;
+          break;
+        case "lesson2":
+          this.lesson2X = lesson.x;
+          this.lesson2Y = lesson.y;
+          break;
+        default:
+          console.error("Something is wrong here!");
+      }
+    },
   },
   data() {
     return {
@@ -131,8 +173,39 @@ export default {
         { x: 1, y: 2, w: 1, h: 1, key: "d", data: { num: 30 } },
         { x: 3, y: 1, w: 1, h: 1, key: "e", data: { num: 3 } },
       ],
+      lesson1Length: 1,
+      lesson1Cols: 4,
+      lesson1Rows: 6,
+      lesson1X: 1,
+      lesson1Y: 1,
+      lesson2X: 2,
+      lesson2Y: 1,
     };
   },
+  computed: {
+    lessons1() {
+      return [
+        {
+          x: this.lesson1X,
+          y: this.lesson1Y,
+          w: 1,
+          h: this.lesson1Length,
+          key: "lesson1",
+          data: {},
+        },
+        {
+          x: (grid) => {
+            return grid.context === "lesson" ? this.lesson2X : 1;
+          },
+          y: this.lesson2Y,
+          w: 1,
+          h: parseInt(this.lesson1Length) + 1,
+          key: "lesson2",
+          data: {},
+        },
+      ];
+    },
+  },
 };
 </script>
 
@@ -171,4 +244,8 @@ export default {
   display: flex;
   justify-content: space-between;
 }
+
+.bordered {
+  border: 2px solid grey;
+}
 </style>
diff --git a/src/DragGrid.vue b/src/DragGrid.vue
index 2882c87c028a0435886e102041bb579b90c4f3cd..93096c917e146468ff3e208cfff413c9e076b43f 100644
--- a/src/DragGrid.vue
+++ b/src/DragGrid.vue
@@ -11,10 +11,10 @@
       v-for="item in value"
       :key="item.key"
       :drag-i-d="item.key"
-      :x="item.x"
-      :y="item.y"
-      :w="item.w"
-      :h="item.h"
+      :x="get('x', item)"
+      :y="get('y', item)"
+      :w="get('w', item)"
+      :h="get('h', item)"
       :data="item.data"
       :context="context"
     >
@@ -44,7 +44,7 @@ export default {
   components: {
     DragContainer,
   },
-  emits: ["input"],
+  emits: ["input", "itemChanged"],
   props: {
     rows: {
       type: Number,
@@ -145,17 +145,30 @@ export default {
 
       if (!newPositionValid) return;
 
-      let valueCopy = structuredClone(this.value);
-
-      let index = valueCopy.findIndex((i) => {
-        return i.key === element.key;
-      });
-      if (index >= 0) valueCopy.splice(index, 1);
+      try {
+        let valueCopy = structuredClone(this.value);
+
+        let index = valueCopy.findIndex((i) => {
+          return i.key === element.key;
+        });
+        if (index >= 0) valueCopy.splice(index, 1);
+
+        valueCopy.push(element);
+        this.$emit("input", valueCopy);
+      } catch (e) {
+        if (e.code === DOMException.DATA_CLONE_ERR) {
+          // We use functions for properties → we can't clone; only emit `item-changed` event
+          console.debug(
+            "Grid couldn't be cloned, please listen to the `item-changed` event and handle changes yourself."
+          );
+        } else {
+          throw e;
+        }
+      }
 
       element.x = coords.x;
       element.y = coords.y;
-      valueCopy.push(element);
-      this.$emit("input", valueCopy);
+      this.$emit("itemChanged", element);
     },
     getCoords(x, y) {
       return {
@@ -163,6 +176,10 @@ export default {
         y: Math.ceil(y / (this.$el.offsetHeight / this.rows)),
       };
     },
+    get(property, item) {
+      let val = item[property] || 1;
+      return val instanceof Function ? val(this) : parseInt(val);
+    },
   },
 };
 </script>