<script setup> import DragGrid from "../../src/DragGrid.vue"; import CircularCard from "./components/CircularCard.vue"; import NumberCounter from "./components/NumberCounter.vue"; </script> <template> <div id="app"> <DragGrid :rows="8" :cols="5" :pos-validation="blockField" v-model="items"> <div id="blocker"> This field is blocked because it's filled, the next one programmatically </div> <template #item="item"> <div class="container">{{ item }}</div> </template> </DragGrid> <div class="ttt-container"> <DragGrid :rows="3" :cols="3" v-model="ticTacToe1" class="tic-tac-toe" context="ticTacToe" :validate-element="randomKey" > <template #item="item"> <CircularCard> {{ item.key.startsWith("a") ? "X" : "O" }} </CircularCard> </template> </DragGrid> <div> <p> These two are two different grids but we can drag from right to left! </p> <p>Drag items from the container on the right to play on the left.</p> </div> <DragGrid :rows="1" :cols="2" v-model="ticTacToe2" class="tic-tac-toe" context="ticTacToe" :pos-validation="blockAllMoving" > <template #item="item"> <CircularCard> {{ item.data.text }} </CircularCard> </template> </DragGrid> </div> <div class="ttt-container"> <drag-grid v-model="counters" :cols="3" :rows="2" id="c-grid" @input="logInput" context="counter" > <template #item="item"> <number-counter v-model="item.data.num"></number-counter> </template> <template #highlight> <div ref="highlight" class="custom-highlight"> Das hier ist das Highlight </div> </template> </drag-grid> <span>← Drag here please →</span> <drag-grid v-model="counters2" :cols="3" :rows="2" context="counter"> <template #item="item"> <number-counter v-model="item.data.num"></number-counter> </template> </drag-grid> </div> <div class="ttt-container"> <div> <label> Lesson 1 has length: {{ lesson1Length }} <input type="range" v-model="lesson1Length" min="1" max="5" step="1" /> </label> <input type="text" v-model="lessonData.lesson1" /> </div> <div> <label> Lesson grid has width: {{ lesson1Cols }} <input type="range" v-model="lesson1Cols" min="2" max="5" step="1" /> </label> <input type="text" v-model="lessonData.lesson2" /> </div> <div> <label> Lesson grid has height: {{ lesson1Rows }} <input type="range" v-model="lesson1Rows" min="6" max="10" step="1" /> <input type="text" v-model="lessonData.lesson3.inside" /> <input type="text" v-model="lessonData.lesson3.outside" /> </label> </div> <drag-grid :value="lessons1" :cols="parseInt(lesson1Cols)" :rows="parseInt(lesson1Rows)" class="bordered" context="lesson" grid-id="lesson-plan" @itemChanged="handleLessonMoved" > <template #item="item"> <div class="container">{{ item }}</div> </template> </drag-grid> <drag-grid :value="lessons1" :cols="1" :rows="10" context="lesson" grid-id="lesson-storage" @itemChanged="handleLessonDropInContainer" no-highlight > <template #item="item"> <div class="container">{{ item }}</div> </template> </drag-grid> </div> </div> </template> <script> export default { name: "App", methods: { blockField(x, y, key) { // We won't move fields 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"; }, blockAllMoving() { return false; }, randomKey(element) { if (element.key.length !== 1) return; element.key += Math.random().toString(36).replace("0.", ""); }, 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; case "lesson3": this.lesson3X = lesson.x; this.lesson3Y = lesson.y; this.lesson3inPlan = true; break; default: console.error("Something is wrong here!"); } }, handleLessonDropInContainer(lesson) { if (lesson.key === "lesson3") this.lesson3inPlan = false; }, }, data() { return { items: [ { x: 1, y: 3, w: 1, h: 1, key: "obj1", data: {} }, { x: 2, y: 1, w: 1, h: 1, key: "obj2", data: {} }, { x: 3, y: 1, w: 2, h: 2, key: "obj3", data: {} }, { x: 5, y: 2, w: 1, h: 1, key: "obj4", data: {} }, { x: 1, y: 1, w: 1, h: 2, key: "obj5", data: {} }, { x: 5, y: 1, w: 1, h: 1, key: "obj6", data: {} }, { x: 2, y: 2, w: 1, h: 3, key: "obj7", data: {} }, { x: 1, y: 4, w: 1, h: 1, key: "obj8", data: { title: "I'm blocked from moving!" }, }, { x: 5, y: 3, w: 1, h: 1, key: "obj9", data: {} }, ], ticTacToe1: [ { x: 1, y: 1, w: 1, h: 1, key: "a1", data: { text: "X" } }, { x: 3, y: 3, w: 1, h: 1, key: "b1", data: { text: "O" } }, ], ticTacToe2: [ { x: 1, y: 1, w: 1, h: 1, key: "a", data: { text: "X" } }, { x: 2, y: 1, w: 1, h: 1, key: "b", data: { text: "O" } }, ], counters: [ { x: 1, y: 1, w: 1, h: 1, key: "a", data: { num: 1 } }, { x: 2, y: 1, w: 1, h: 1, key: "b", data: { num: 4 } }, { x: 3, y: 2, w: 1, h: 1, key: "c", data: { num: -1 } }, ], counters2: [ { 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, lesson3X: -1, lesson3Y: -1, lesson3inPlan: false, lessonData: { lesson1: "Nothing", lesson2: "Hallo", lesson3: { inside: "This is lesson 3 inside the plan", outside: "This is lesson3 outside of the plan", }, }, }; }, computed: { lessons1() { return [ { 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, }, }, { x: (grid) => { return grid.gridId === "lesson-plan" ? this.lesson2X : 0; }, y: (grid) => { return grid.gridId === "lesson-plan" ? this.lesson2Y : 0; }, w: 1, h: parseInt(this.lesson1Length) + 1, key: "lesson2", data: { text: this.lessonData.lesson2, }, }, { x: (grid) => { if (this.lesson3inPlan) { return grid.gridId === "lesson-plan" ? this.lesson3X : -1; } return grid.gridId === "lesson-plan" ? -1 : 0; }, y: (grid) => { if (this.lesson3inPlan) { return grid.gridId === "lesson-plan" ? this.lesson3Y : -1; } return grid.gridId === "lesson-plan" ? -1 : 0; }, w: 1, h: parseInt(this.lesson1Length) + 1, key: "lesson3", data: (grid) => { return { text: grid.gridId === "lesson-storage" ? this.lessonData.lesson3.outside : this.lessonData.lesson3.inside, }; }, }, ]; }, }, }; </script> <style scoped> #blocker { grid-row: 3 / span 1; grid-column: 3 / span 1; background-image: linear-gradient( 45deg, #edd85f 25%, #0f2b3d 25%, #0f2b3d 50%, #edd85f 50%, #edd85f 75%, #0f2b3d 75%, #0f2b3d 100% ); background-size: 56.57px 56.57px; color: white; font-size: large; font-weight: bold; text-shadow: 4px 4px 4px #2c3e50; } .container { background: lightcoral; width: 100%; height: 100%; } .tic-tac-toe { max-width: 400px; } .ttt-container { display: flex; justify-content: space-between; } .custom-highlight { display: flex; align-items: center; justify-content: center; background: aquamarine; width: 100%; height: 100%; } .bordered { border: 2px solid grey; } </style>