Skip to content

Commit 3fe275a

Browse files
committed
Add support for opening / closing the collapse by drag
1 parent e1af1a1 commit 3fe275a

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/SplitPanel.vue

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,6 @@ const maxSizePercentage = computed(() => {
114114
return pixelsToPercentage(componentSize.value, props.maxSize);
115115
});
116116
117-
const maxSizePixels = computed(() => {
118-
if (props.maxSize === undefined) return;
119-
120-
if (props.sizeUnit === 'px') return props.maxSize;
121-
return percentageToPixels(componentSize.value, props.maxSize);
122-
});
123-
124117
let expandedSizePercentage = 0;
125118
126119
/** Whether the primary column is collapsed or not */
@@ -142,7 +135,9 @@ onMounted(() => {
142135
cachedSizePixels = sizePixels.value;
143136
});
144137
145-
const { x: dividerX, y: dividerY } = useDraggable(dividerEl, { containerElement: panelEl });
138+
const { x: dividerX, y: dividerY, isDragging } = useDraggable(dividerEl, { containerElement: panelEl });
139+
140+
let hasToggledDuringCurrentDrag = false;
146141
147142
watch([dividerX, dividerY], ([newX, newY]) => {
148143
if (props.disabled) return;
@@ -153,19 +148,27 @@ watch([dividerX, dividerY], ([newX, newY]) => {
153148
newPositionInPixels = componentSize.value - newPositionInPixels;
154149
}
155150
156-
// if (props.collapsible && props.minSize !== undefined && props.collapseThreshold !== undefined) {
157-
// const threshold = props.minSize - (props.collapseThreshold ?? 0);
158-
159-
// console.log(threshold, newPositionInPixels);
151+
if (props.collapsible && minSizePixels.value !== undefined && props.collapseThreshold !== undefined && hasToggledDuringCurrentDrag === false) {
152+
const collapseThreshold = minSizePixels.value - (props.collapseThreshold ?? 0);
153+
const expandThreshold = (props.collapseThreshold ?? 0);
160154
161-
// if (newPositionInPixels < threshold) {
162-
// collapsed.value = true;
163-
// }
164-
// }
155+
if (newPositionInPixels < collapseThreshold && collapsed.value === false) {
156+
collapsed.value = true;
157+
hasToggledDuringCurrentDrag = true;
158+
}
159+
else if (newPositionInPixels > expandThreshold && collapsed.value === true) {
160+
collapsed.value = false;
161+
hasToggledDuringCurrentDrag = true;
162+
}
163+
}
165164
166165
sizePercentage.value = clamp(pixelsToPercentage(componentSize.value, newPositionInPixels), 0, 100);
167166
});
168167
168+
watch(isDragging, (newDragging) => {
169+
if (newDragging === false) hasToggledDuringCurrentDrag = false;
170+
});
171+
169172
watch(sizePixels, (newPixels, oldPixels) => {
170173
if (newPixels === oldPixels) return;
171174
cachedSizePixels = newPixels;
@@ -216,7 +219,12 @@ const handleKeydown = (event: KeyboardEvent) => {
216219
};
217220
218221
const gridTemplate = computed(() => {
219-
const primary = `clamp(0%, clamp(${minSizePercentage.value}%, ${sizePercentage.value}%, ${maxSizePercentage.value}%), calc(100% - ${dividerSize.value}px))`;
222+
let primary = `clamp(0%, clamp(${minSizePercentage.value}%, ${sizePercentage.value}%, ${maxSizePercentage.value}%), calc(100% - ${dividerSize.value}px))`;
223+
224+
if (collapsed.value) {
225+
primary = '0';
226+
}
227+
220228
const secondary = 'auto';
221229
222230
if (!props.primary || props.primary === 'start') {
@@ -245,7 +253,7 @@ defineExpose({ collapse, expand, toggle });
245253
</script>
246254

247255
<template>
248-
<div ref="split-panel" class="split-panel" :class="[orientation, { collapsed }]">
256+
<div ref="split-panel" class="split-panel" :class="[orientation, { collapsed, dragging: isDragging }]">
249257
<div class="start">
250258
<slot name="start" />
251259
</div>
@@ -282,6 +290,10 @@ defineExpose({ collapse, expand, toggle });
282290
&.vertical {
283291
grid-template-rows: v-bind(gridTemplate);
284292
}
293+
294+
&.dragging {
295+
user-select: none;
296+
}
285297
}
286298
287299
.start, .end {

0 commit comments

Comments
 (0)