antoniandre / splitpanes

A Vue 3 (and 2) reliable, simple and touch-ready panes splitter / resizer.
https://antoniandre.github.io/splitpanes
MIT License
1.91k stars 169 forks source link

Allow sizes in pixels #84

Open cimpok opened 4 years ago

cimpok commented 4 years ago

Could you please add absolute sizes to panes? So we would be able to specify certain pane's initial widths not in percents of the parent but in absolute values, like px. And also disable resizing for certain panes would be welcome. Thanks.

nmearl commented 4 years ago

@antoniandre any thoughts on this?

antoniandre commented 4 years ago

Hi guys I am adding this in my to do list. It involves a big refactoring though.

carlosyan1807 commented 3 years ago

nice to have it

aendre commented 3 years ago

I'm also looking for this feature! Thx @antoniandre in advance!

rajithaeyee commented 3 years ago

any progress on this?? Coz im also waiting for this feature

Hextar commented 3 years ago

I'm also looking forward for this feature!

zzxxiinn commented 3 years ago

I'm also looking forward for this feature! too!

alectrocute commented 3 years ago

Would be a game changer

jloganolson commented 3 years ago

+1

jinrui-kooboo commented 3 years ago

any thoughts on this?

WhatzzUp commented 3 years ago

+1

zhangbaojia commented 2 years ago

+1

karukenert commented 2 years ago

+1

cihadturhan commented 2 years ago

I guess it will never be live :(

fulus06 commented 2 years ago

+10086

Ldkwewde01 commented 2 years ago

+1

enmotion commented 2 years ago

try this ...

<div ref="SplitPanesRef" class="flex flex-col grow-1">
  <splitpanes :horizontal="false">
    <pane class="xcol" 
      :min-size="20" 
      :size="100 - propEditorWidthPercent" 
      :max-size="100 - propEditorWidthPercent">
      <div class="flex flex-col  grow-1 bg-gray-100"></div>
    </pane>
    <pane class="flex flex-col p-10 bg-white" 
      :min-size="propEditorWidthPercent" 
      :size="propEditorWidthPercent" 
      :max-size="80">
      <span class="h-40 rounded bg-gray-50"></span>
    </pane>
  </splitpanes>
</div>

// Vue3 Code
...
setup(props, context){
    const SplitPanesRef = ref(null as any);
    const SplitPanesRefResizeObserver = ref(null as ResizeObserver|null); // add Observer 
    const propEditorWidthPercent = ref(0);
    onMounted(()=>{
      console.log(route.params,'params');
      SplitPanesRefResizeObserver.value = new ResizeObserver(() => {
        propEditorWidthPercent.value = Math.min(Math.round( 360 / SplitPanesRef.value.clientWidth * 100), 50);
      })
      SplitPanesRefResizeObserver.value.observe(SplitPanesRef.value); // remove Observer
    });
    onBeforeUnmount(()=>{
      SplitPanesRefResizeObserver.value && SplitPanesRefResizeObserver.value.disconnect()
    })
    return {
    SplitPanesRef,
      propEditorWidthPercent,
    }
}
mengdebiao commented 1 year ago

First of all, thank you very much for this project, it has been very helpful to me today. However, I noticed this historical issue while using it and it seems to have been around for quite some time. I was wondering if the author still plans to add this feature?

mengdebiao commented 1 year ago

First of all, thank you very much for this project, it has been very helpful to me today. However, I noticed this historical issue while using it and it seems to have been around for quite some time. I was wondering if the author still plans to add this feature?

try this ...

<template>
  <Splitpanes ref="splitpanesRef" class="chat-container" :dbl-click-splitter="false">
    <Pane class="left" :size="leftPaneSize" max-size="50"></Pane>
    <Pane class="right" :size="100 - leftPaneSize"></Pane>
  </Splitpanes>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useResizeObserver } from '@vueuse/core'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'

const DEFAULT_WIDTH = 270
const leftPaneSize = ref(30)
const splitpanesRef = ref()

const setLeftPaneSize = () => {
  const width = splitpanesRef.value.$el.clientWidth
  leftPaneSize.value = (DEFAULT_WIDTH / width) * 100
}
onMounted(() => {
  setLeftPaneSize()

  useResizeObserver(splitpanesRef, (entries) => {
    const entry = entries[0]
    const { width } = entry.contentRect
    leftPaneSize.value = (DEFAULT_WIDTH / width) * 100
  })
})
</script>
davestewart commented 4 months ago

Here's a composable which handles pixel widths and resizing.

// utils.ts
import { onUnmounted, ref } from 'vue'

export function useWidths (values: number[], el: HTMLElement = document.body) {
  // track client width
  const cw = ref(el.clientWidth)

  // track frame widths
  const widths = ref(values)

  // update frame widths
  const setWidths = (newValues?: number[]) => {
    if (newValues) {
      values = newValues
    }
    const total = values.reduce((a, b) => a + b)
    widths.value = [...values, cw.value - total].map(value => value / cw.value * 100)
  }

  // handle browser resizing
  const onResize = () => {
    cw.value = el.clientWidth
    setWidths()
  }
  window.addEventListener('resize', onResize)
  onUnmounted(() => {
    window.removeEventListener('resize', onResize)
  })

  // handle frame resizing
  const onResized = (frames: { size: number }[]) => {
    const values = []
    for (let i = 0; i < frames.length - 1; i++) {
      values[i] = Math.floor(frames[i].size / 100 * cw.value)
    }
    setWidths(values)
  }

  // start
  setWidths()
  return {
    widths,
    setWidths,
    onResized,
  }
}
<template>
  <splitpanes class="default-theme" style="height: 100%" @resized="onResized">
    <pane v-for="(frame, index) in frames"
          min-size="20"
          :size="widths[index]"
    >
      {{  frame }}
    </pane>
  </splitpanes>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import { useWidths } from './utils.ts'

const frames = ref([
  'a',
  'b',
  'c',
])

// should always be one less that frames, as the last frame will fill the space
const { widths, onResized } = useWidths([
  200,
  600,
])
</script>

<style lang="scss">
.splitpanes__pane {
  transition: none !important;
}
</style>

You'll also want to disable the splitpane CSS transition (see style block, above)