Skip to content

Commit

Permalink
add events and areas size
Browse files Browse the repository at this point in the history
  • Loading branch information
Kurtil committed Jun 16, 2020
1 parent 1360b58 commit 6302449
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 88 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,17 @@ this.$refs.areas.setMode(mode); // mode must be "split-vertical", "split-horizon

When the mode is different from `null`, overlays is displayed on areas. To change overlays style, use [corresponding css variables](#style).

## Events

Splitting, deletting and swapping fire events that can be listened on areas component.

| Name | Arguments |
| :--- | :--- |
| `area-splitted` | `{ areaId, newAreaId, way, percentage, insertNewAfter }` |
| `area-deletted` | `{ areaId }` |
| `areas-swapped` | `{ areaId1, areaId2 }` |


## Public Methods

Methods on Areas instance:
Expand Down Expand Up @@ -222,6 +233,28 @@ The `$area` object provides the following properties:
| onChange(handler) | A method that accepts a callback (handler) as parameter. The handler is called when area change (swap) with newAreaId and OldAreaId as parameters. |
| offChange(handler) | A method that accepts a callback (handler) as parameter to stop listening to area change with this handler. |

## Size

To know areas size (number of areas) :
```javascript
// The host component
{
data() {
return {
areasSize: null,
}
},
mounted() {
this.$watch(() => this.$refs.areas.size, size => { // ref="areas" must be placed on Areas component
this.areasSize = size;
}, {
immediate: true
});
},
// ...
}
```

# Development

Build on-change for development and serve:
Expand Down
219 changes: 132 additions & 87 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Areas</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Areas</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}

.areas {
/*
.areas {
/*
--areas-active-box-shadow: inset 0 0 10px red;
--areas-overlay-color: red;
--areas-overlay-outline-offset: 10px;
Expand Down Expand Up @@ -44,52 +43,51 @@
--areas-dragging-cursor: context-menu;
--areas-delete-cursor: cell;
*/
}
</style>
</head>
}
</style>
</head>

<body>
<div id="app"></div>
<script type="module">
import Vue from '../../node_modules/vue/dist/vue.esm.browser.js';
import Areas from "./dist/areas.esm.js";
<body>
<div id="app"></div>
<script type="module">
import Vue from "../../node_modules/vue/dist/vue.esm.browser.js";
import Areas from "./dist/areas.esm.js";

const dragImage = document.createElement("img");
dragImage.src = "https://media-exp1.licdn.com/dms/image/C4D0BAQHoCO5FSOrIGg/company-logo_200_200/0?e=1600300800&v=beta&t=apvq-bf2d87naZfhPleTxUoBOpN6QQ8_V-mNu6pxyCY"
const dragImage = document.createElement("img");
dragImage.src =
"https://media-exp1.licdn.com/dms/image/C4D0BAQHoCO5FSOrIGg/company-logo_200_200/0?e=1600300800&v=beta&t=apvq-bf2d87naZfhPleTxUoBOpN6QQ8_V-mNu6pxyCY";

let areas = null;
let areas = null;

const headerComponent = {
data() {
return {
optionsShown: false,
selectedOption: null,
}
},
props: {
areasSize: {
default: "not specified"
}
},
computed: {
mainButtonContent() {
return this.optionsShown ? "Hide options" : "Show options";
}
},
watch: {
optionsShown() {
if (!this.optionsShown && this.selectedOption !== null) {
this.selectedOption = null
}
const headerComponent = {
data() {
return {
optionsShown: false,
selectedOption: null,
};
},
selectedOption() {
areas.setMode(this.selectedOption);
}
},
methods: {

},
template: `
props: {
areasSize: {
default: "not specified",
},
},
computed: {
mainButtonContent() {
return this.optionsShown ? "Hide options" : "Show options";
},
},
watch: {
optionsShown() {
if (!this.optionsShown && this.selectedOption !== null) {
this.selectedOption = null;
}
},
selectedOption() {
areas.setMode(this.selectedOption);
},
},
methods: {},
template: `
<div style="margin:10px; display:flex; justify-content: space-between">
<div>
<button type="button" @click="optionsShown = !optionsShown">{{ mainButtonContent }}</button>
Expand All @@ -107,15 +105,26 @@
</template>
</div>
<div>Areas size : {{areasSize}}</div>
</div>`
}
</div>`,
};

const vm = new Vue({
render: function (h) {
return h("div", { style: "width: 80%; margin: auto; height: 80%;" }, [
h(headerComponent),
h(Areas,
{
const vm = new Vue({
data() {
return {
areasSize: null,
}
},
mounted() {
this.$watch(() => this.$refs.areas.size, size => {
this.areasSize = size;
}, {
immediate: true
});
},
render(h) {
return h("div", { style: "width: 80%; margin: auto; height: 80%;" }, [
h(headerComponent, {props: {areasSize: this.areasSize}}),
h(Areas, {
ref: "areas",
props: {
cfg: {
Expand All @@ -125,9 +134,21 @@
yOffset: 100,
},
components: [
{ render(h) { return h("div", "Content I") } },
{ render(h) { return h("div", "Content II") } },
{ render(h) { return h("pre", `d
{
render(h) {
return h("div", "Content I");
},
},
{
render(h) {
return h("div", "Content II");
},
},
{
render(h) {
return h(
"pre",
`d
d
d
d
Expand Down Expand Up @@ -189,8 +210,15 @@
d
d
d
d`) } },
{ render(h) { return h("div", "Content III") } },
d`
);
},
},
{
render(h) {
return h("div", "Content III");
},
},
],
layout: {
direction: "row",
Expand All @@ -207,23 +235,40 @@
componentIndex: 1,
},
{
componentIndex: 2
}
]
}
]
}
}
}
}
)])
},
}).$mount('#app');

areas = vm.$refs.areas;
// areas.getAreaContentByName("comp1").cfg.props.text = "Youhou ! =D"; // This is reactive !

</script>
</body>
componentIndex: 2,
},
],
},
],
},
},
},
on: {
"area-deletted"({ areaId }) {
console.log(`Area ${areaId} deleted.`);
},
"areas-swapped"({ areaId1, areaId2 }) {
console.log(`Areas ${areaId1} and ${areaId2} swapped.`);
},
"area-splitted"({
areaId,
newAreaId,
way,
percentage,
insertNewAfter,
}) {
console.log(
`Areas ${areaId} splitted. New area ${newAreaId} created. Way : ${way}. Percentage : ${percentage}. Inserted after : ${insertNewAfter}`
);
},
},
}),
]);
},
}).$mount("#app");

</html>
areas = vm.$refs.areas;
// areas.getAreaContentByName("comp1").cfg.props.text = "Youhou ! =D"; // This is reactive !
</script>
</body>
</html>
21 changes: 20 additions & 1 deletion src/Areas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export default {
};
},
computed: {
size() {
return this.areasContent && this.areasContent.filter(Boolean).length;
},
swapMode() {
return this.mode === "swap";
},
Expand Down Expand Up @@ -192,6 +195,9 @@ export default {
deleteArea(areaId) {
this.$refs.layout.deleteArea(areaId);
this.areasContent.splice(areaId, 1, undefined);
this.$emit("area-deletted", {
areaId
});
},
splitArea(areaId, way, percentage = 50, insertNewAfter = true) {
if (!["vertical", "horizontal"].includes(way)) {
Expand All @@ -211,6 +217,13 @@ export default {
this.$nextTick(() => {
// Wait for the layout to rerender
this.areasContent = Array.from(this.areasContent);
this.$emit("area-splitted", {
areaId,
newAreaId,
way,
percentage,
insertNewAfter
});
});
},
swapAreas(areaId1, areaId2) {
Expand All @@ -220,7 +233,13 @@ export default {
this.areasContent.splice(areaId2, 1, area1content);
this.areasContent.splice(areaId1, 1, area2content);
this.$nextTick(this.reattachTeleports);
this.$nextTick(() => {
this.reattachTeleports();
this.$emit("areas-swapped", {
areaId1,
areaId2
});
});
},
getAreaContentByName(name) {
return this.areasContent
Expand Down

0 comments on commit 6302449

Please sign in to comment.