yansern / vue-multipane

Resizable split panes for Vue.js.
https://yansern.github.io/vue-multipane/
Other
588 stars 125 forks source link

Cannot combine vertical and horizontal panes #15

Open Haixing-Hu opened 6 years ago

Haixing-Hu commented 6 years ago

For example, the following code does not work.

<template>
    <multipane layout="vertical" class="container">
        <div class="left">
            <h6 class="title is-6">Pane 1</h6>
        </div>
        <multipane-resizer></multipane-resizer>
        <multipane layout="horizontal" class="right">
            <div class="top">
              <h6 class="title is-6">Pane 2</h6>
            </div>
            <multipane-resizer></multipane-resizer>
            <div class="bottom">
              <h6 class="title is-6">Pane 3</h6>
            </div>
        </multipane>
    </multipane>
</template>

<script>
import { Multipane, MultipaneResizer } from '@/src';

export default {
  components: {
    Multipane,
    MultipaneResizer,
  },
};
</script>

<style>
.container {
  height: 600px;
  width: 100%;
}

.left {
  width: 50%;
  min-width: 20%;
  max-width: 80%;
  height: 600px;
  border: 1px solid #ccc;
  background: #eee;
}

.right {
  flex-grow: 1;
  height: 600px;
  border: 1px solid #ccc;
  background: #eee;
}

.top {
  height: 300px;
  min-height: 20%;
  max-height: 80%;
  width: 100%;
  border: 1px solid #ccc;
  background: #eee;
}
.bottom {
  flex-grow: 1;
  width: 100%;
  border: 1px solid #ccc;
  background: #eee;
}
</style>

When resizing the horizontal resizer both the height and the width of the pane 2 will be change.

This is because the multipane component catch the mouse up and mouse down event on the whole component instead of the resizer.

I think this could be fixed by catching the event of the resizer instead of the whole component.

ignisphaseone commented 6 years ago

@Haixing-Hu I've been using your fixed version for a project, but I stumbled into an issue combining vertical and horizontal panes. If you set an initial width on the outer pane (50% resizing horizontally), and then adjust the vertical subpane inside of it, it will also set its width to be the initial width.

Haixing-Hu commented 6 years ago

@ignisphaseone Hi, can you show me some example codes?

ignisphaseone commented 6 years ago

@Haixing-Hu

<multipane class="editorBar" layout="vertical">
  <multipane class="queryWrap" :style="{width: '50%'}" layout="horizontal">
    <div class="query-editor"/>
    <multipane-resizer/> <!-- Inner Multipane Resizer. Changes `.variable-editor` height. BUG: Also sets `.queryWrap` width back to its initial 50% width.-->
    <div class="variable-editor" :style="{height: '15%'}">
      <div class="codemirrorWrap"/>
    </div>
  </multipane>
  <multipane-resizer/> <!-- Outer Multipane Resizer. Changes `.queryWrap` width.-->
  <div class="resultWrap" :style="{flexGrow: 1}">
    <div class="result-window"/>
  </div>
</multipane>

Sample code posted above. Using nested multipanes, my outer multipanes are split at horizontal 50%. If the outer resizer is used to change the width, everything works as expected. If the inner resizer is used to change the height of the .queryWrap multipane, its width defaults back to 50% and not what the outer resizer set it to.

Haixing-Hu commented 6 years ago

@ignisphaseone Hi, please try the following code. It works perfect. Note the CSS code.

<template>
    <multipane class="editorBar" layout="vertical">
        <multipane class="queryWrap" layout="horizontal">
            <div class="query-editor"/>
            <multipane-resizer/> <!-- Inner Multipane Resizer. Changes `.variable-editor` height. BUG: Also sets `.queryWrap` width back to its initial 50% width.-->
            <div class="variable-editor">
            <div class="codemirrorWrap"/>
            </div>
        </multipane>
        <multipane-resizer/> <!-- Outer Multipane Resizer. Changes `.queryWrap` width.-->
        <div class="resultWrap">
            <div class="result-window"/>
        </div>
    </multipane>
</template>

<script>
import { Multipane, MultipaneResizer } from '@/src';

export default {
  components: {
    Multipane,
    MultipaneResizer,
  },
};
</script>

<style scoped>
.editorBar {
    height: 600px;
    width: 100%;
}
.queryWrap {
    border: 1px solid #ccc;
    background: #eee;
    width: 50%;
}
.resultWrap {
    border: 1px solid #ccc;
    background: #eee;
    flex-grow: 1;
}
.query-editor {
    border: 1px solid #ccc;
    background: #eee;
    height: 200px;
}
.variable-editor {
    border: 1px solid #ccc;
    background: #eee;
    height: 15%;
}
.codemirrorWrap {
    border: 1px solid #ccc;
    background: #eee;
    flex-grow: 1;
}
</style>

The point is that, the pane on the one side of multipane-resizer must have a fixed width (either in px or in percent), and the pane on the other side of multipane-resizer must have flex-grow: 1.

ignisphaseone commented 6 years ago

@Haixing-Hu Ah ha! Thanks, I've fixed my code. +1 for merging the fix! =)

raphaeldisanto commented 4 years ago

Unfortunately, this still isn't a full fix. If I drag the horizontal reisizer left and right, it resizes the top window horizontally. I would have thought that because this is a horizontal resizer, It should ignore horizontal movement and only listen to vertical mouse deltas.