antoniandre / splitpanes

A Vue 2 & 3 reliable, simple and touch-ready panes splitter / resizer.

Home Page:https://antoniandre.github.io/splitpanes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Panes resized when added a new pane

elC0mpa opened this issue · comments

Hello, first of all I would like to thank you for this amazing Vue Component.
I am having a problem and I don´t know how to solve it.
The thing is that when I add a new pane to the component, the master pane (left pane) is resized and I would like to avoid this behavior.
Here I let you my code:

<splitpanes
        class="default-theme"
        @pane-remove="removed"
        @pane-add="added"
        @resized="resized"
      >
        <!-- Master -->
        <pane
          v-if="showMasterPanel"
          :min-size="masterPanelMinSize"
          :max-size="masterPanelMaxSize"
          :size="masterPanelSize"
          class="splitter-master-details__master"
        >
          <slot name="master-content"></slot>
        </pane>

        <!-- Detail -->
        <pane
          :min-size="detailsPanelMinSize"
          :max-size="detailsPanelMaxSize"
          :size="detailsPanelSize"
          class="splitter-master-details__detail"
        >
          <slot name="details-content"></slot>
        </pane>

        <!-- Extra -->
        <pane
          v-if="showExtraPanel"
          :min-size="extraPanelMinSize"
          :max-size="extraPanelMaxSize"
          class="splitter-master-details__extra"
        >
          <slot name="extra-content"></slot>
        </pane>
      </splitpanes>

In this code the variable showMasterPanel is always true but showExtraPanel is the one which changes its value and by changing this variable the events pane-add and pane-removed are fired.

I hope you could help me

Did you ever solve this problem?

I'm encountering the same thing using Vue2.

I'm using three panes. The middle one is always visible.
I can set the left pane size just fine (:size=15).

When I add the right pane (:size=15), the left and middle pane get split in two and the right pane is added at my desired width.

The paneResized event comes back with the new values [42.5, 42.5, 15]. I've tried overriding the values with the values I have saved in data for the left and center panes, but that doesn't work.

I found if I do a "v-show" instead of a "v-if", then the panes are displayed correctly....the problem then becomes the splitter is shown even though the value is false, allowing the user to resize a non-shown pane, which causes its own problems.

Is it possible to override the reassigning of pane sizes by splitpanes? i.e. Let the developer decide the best way to display a new pane rather than having splitplanes do it?

Thoughts?

commented

Having the same issue.

3 Panes.

  • Left sidebar
  • Right sidebar
  • Middle part

Left and right sidebars have :size="15 :min-size="15" :max-size="50" Middle pane does not have size restrictions.
As soon as toggle one sidebar pane, the other one gets resized to the max-size I think, instead of the size.

If all panes are visible I have L: 15, R:15, M: 70
I close the L pane, they get resized to R:50 M:50 instead of R:15 M:85

I think the desired behaviour would be to respect the set size before recalculating it.

commented

Well my use case is very specific, because I have two side panes, that have a size and I want to toggle them. And the main inner pane, should adjust the size then.
The problem is however, that equalizeAfterAddOrRemove is assuming that you want equal width panes and recalculates if you add or remove a pane.

For my use case where I want the panes as a toggleable and resizeable sidebar this behaviour is not wanted.
I want that only the mid pane is resizing (as it has no size set) and the side panel that is toggled should have the set size if visible and the other one should keep the size it currently has. Like if a user is resizing the left pane, and opens the right one, the left should keep the size, the right one should have the set size and the mid one should resize based on available space.

For anyone with the same requirements, heres the code:

<script>
import { Splitpanes } from 'splitpanes'

export default {
  name: 'ModSplitpanes',
  extends: Splitpanes,
  methods: {
    equalizeAfterAddOrRemove ({ addedPane, removedPane } = {}) {
      // 100 % available space
      let availableSpace = 100
      let leftToAllocate = 0
      const ungrowable = []
      const unshrinkable = []
      if (addedPane && addedPane.givenSize !== null) {
        // If added pane has a given size, substract it from the available space
        availableSpace -= addedPane.givenSize
      }
      // Check if pre-allocated space is 100%.
      this.panes.forEach(pane => {
        leftToAllocate -= pane.size
        // If a pane has a givenSize and is not the added pane
        // substract the currentsize from the available space
        // need pane.size here, if user changes the pane size
        if (pane.givenSize && pane.id !== addedPane?.id) {
          availableSpace -= pane.size
        }
        if (pane.size >= pane.max) ungrowable.push(pane.id)
        if (pane.size <= pane.min) unshrinkable.push(pane.id)
      })
      if (Math.abs(leftToAllocate) < 0.1) return // Ok.

      this.panes.forEach(pane => {
        // console.log('setting pane size', pane)
        if (addedPane && addedPane.givenSize !== null && addedPane.id === pane.id) {
          // console.log('addedPane null', addedPane)
        } else {
          // if a pane has a givenSize set the pane.size to size othzerwise use the available space
          pane.size = pane.givenSize !== null ? pane.size : Math.max(Math.min(availableSpace, pane.max), pane.min)
        }
        leftToAllocate -= pane.size
        if (pane.size >= pane.max) ungrowable.push(pane.id)
        if (pane.size <= pane.min) unshrinkable.push(pane.id)
      })

      if (leftToAllocate > 0.1) this.readjustSizes(leftToAllocate, ungrowable, unshrinkable)
    }
  }
}
</script>

You can then just use the extended component instead of the original one and it should work.

I won't create a PR because this is just a hotfix for a very specific behaviour and would break the normal behaviour of splitpanes (adding dynamic panes)

For anyone with the same requirements, heres the code:

I had the same needs, but found that my existing panels bounced around when adding new panels during the animated transition. This is because the new panel was inserted at the final size, but the unsized panel would then animate to its new smaller size.

After the transition completes, the sizes are correct, but during the transition, the panels are over 100% total width.

To fix this, I set the new panel's size to 0 at the beginning of equalizeAfterAddOrRemove, and then set to it the given width afterward, so that the new panel's width can animate in correctly.

equalizeAfterAddOrRemove ({ addedPane, removedPane } = {}) {
  if (addedPane && addedPane.givenSize != null) {
    addedPane.size = 0
  }
   
  /* 
   original modded equalize method here
   from https://github.com/antoniandre/splitpanes/issues/131#issuecomment-1450373726
  */
  
  if (addedPane && addedPane.givenSize != null) {
    setTimeout(() => {
      addedPane.size = addedPane.givenSize
    }, 0)
  }
}

There may be a cleaner way to set that size at the end, but nextTick didn't work. Haven't dug too deeply into that.