added ability to resize panels (#3092)
Co-authored-by: Ivan Hrynevytskyi <ivan.hrynevytskyi@IHRYNEVYTSKYIL.local>
This commit is contained in:
parent
700d69cfc5
commit
c302478282
|
|
@ -2,6 +2,7 @@
|
|||
&.x6-graph-scroller-pannable[data-panning='false'] {
|
||||
cursor: default;
|
||||
}
|
||||
width: calc(100vw - var(--activity-editor-width) - var(--activity-picker-width)) !important;
|
||||
}
|
||||
|
||||
.x6-widget-selection-box {
|
||||
|
|
@ -22,4 +23,4 @@
|
|||
padding-bottom: 12px;
|
||||
border: 2px solid #34D399;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,4 +16,4 @@
|
|||
top: 0;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import {Component, Event, EventEmitter, h, Host, Prop, State} from '@stencil/core';
|
||||
import {PanelPosition, PanelStateChangedArgs} from './models';
|
||||
import { Component, Event, EventEmitter, h, Host, Prop, State } from '@stencil/core';
|
||||
import { PanelPosition, PanelStateChangedArgs } from './models';
|
||||
import { applyResize } from './resize';
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-panel',
|
||||
|
|
@ -9,10 +10,53 @@ export class Panel {
|
|||
@Prop() position: PanelPosition = PanelPosition.Left;
|
||||
@Event() expandedStateChanged: EventEmitter<PanelStateChangedArgs>;
|
||||
@State() isExpanded: boolean = true;
|
||||
dragging = false;
|
||||
|
||||
private onToggleClick = () => {
|
||||
if (this.isExpanded) {
|
||||
applyResize({ position: this.position, isHide: true });
|
||||
} else {
|
||||
applyResize({ position: this.position, isDefault: true });
|
||||
}
|
||||
this.isExpanded = !this.isExpanded;
|
||||
this.expandedStateChanged.emit({expanded: this.isExpanded});
|
||||
this.expandedStateChanged.emit({ expanded: this.isExpanded });
|
||||
};
|
||||
|
||||
onBodyMouseUp = () => {
|
||||
if (this.dragging) {
|
||||
this.clearJSEvents();
|
||||
}
|
||||
};
|
||||
|
||||
componentWillLoad() {
|
||||
document.addEventListener('mouseup', this.onBodyMouseUp);
|
||||
applyResize({ position: this.position, isDefault: true });
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
document.removeEventListener('mouseup', this.onBodyMouseUp);
|
||||
}
|
||||
|
||||
clearJSEvents() {
|
||||
const body = document.body;
|
||||
this.dragging = false;
|
||||
body.removeEventListener('mousemove', this.resize);
|
||||
}
|
||||
|
||||
resize = (e: MouseEvent) => {
|
||||
if (this.position === PanelPosition.Right) {
|
||||
applyResize({ position: PanelPosition.Right, width: document.body.clientWidth - e.pageX });
|
||||
}
|
||||
if (this.position === PanelPosition.Left) {
|
||||
applyResize({ position: PanelPosition.Left, width: e.pageX });
|
||||
}
|
||||
};
|
||||
|
||||
onDragBarMouseDown = (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
const body = document.body;
|
||||
this.dragging = true;
|
||||
body.addEventListener('mousemove', this.resize);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
|
@ -34,19 +78,32 @@ export class Panel {
|
|||
|
||||
const toggleCssClass = toggleClassMap[position];
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={`panel absolute transition-all duration-200 ease-in-out bg-white z-10 ${containerCssClass} ${stateClass}`}>
|
||||
const dragBarClass = position === PanelPosition.Left ? 'right-0' : 'left-0';
|
||||
|
||||
return (
|
||||
<Host class={`panel absolute bg-white z-10 ${containerCssClass} ${stateClass}`}>
|
||||
<div
|
||||
class={`absolute h-full opacity-0 cursor-col-resize w-1 bg-blue-400 transition ease-in-out duration-300 hover:opacity-100 z-10 ${dragBarClass}`}
|
||||
onMouseDown={this.onDragBarMouseDown}
|
||||
/>
|
||||
<div class="panel-content-container">
|
||||
<slot/>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<div class={`text-white ${toggleCssClass}`} onClick={() => this.onToggleClick()}>
|
||||
<svg class="h-6 w-6 text-gray-700" width="24" height="24" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z"/>
|
||||
<polyline points="9 6 15 12 9 18"/>
|
||||
<svg
|
||||
class="h-6 w-6 text-gray-700"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="2"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" />
|
||||
<polyline points="9 6 15 12 9 18" />
|
||||
</svg>
|
||||
</div>
|
||||
</Host>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import { PanelPosition } from './models';
|
||||
|
||||
type ApplyResizeParams = {
|
||||
position: PanelPosition;
|
||||
isDefault?: boolean;
|
||||
isHide?: boolean;
|
||||
width?: number;
|
||||
};
|
||||
|
||||
const positionToLocalStorage = {
|
||||
[PanelPosition.Right]: 'LS/rightPanelWidth',
|
||||
[PanelPosition.Left]: 'LS/leftPanelWidth',
|
||||
};
|
||||
|
||||
const positionToCssVariable = {
|
||||
[PanelPosition.Right]: '--activity-editor-width',
|
||||
[PanelPosition.Left]: '--activity-picker-width',
|
||||
};
|
||||
|
||||
const positionToDefaultWidth = {
|
||||
[PanelPosition.Right]: 580,
|
||||
[PanelPosition.Left]: 300,
|
||||
};
|
||||
|
||||
function getPanelDefaultWidth(position: PanelPosition) {
|
||||
return localStorage.getItem(positionToLocalStorage[position]) || positionToDefaultWidth[position];
|
||||
}
|
||||
|
||||
function updatePanelDefaultWidth(position: PanelPosition, width: number) {
|
||||
return localStorage.setItem(positionToLocalStorage[position], width.toString());
|
||||
}
|
||||
|
||||
export function applyResize({ position, isDefault, isHide, width }: ApplyResizeParams) {
|
||||
const root = document.querySelector<HTMLElement>(':root');
|
||||
|
||||
if (isHide) {
|
||||
root.style.setProperty(positionToCssVariable[position], '0');
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDefault) {
|
||||
root.style.setProperty(positionToCssVariable[position], `${getPanelDefaultWidth(position)}px`);
|
||||
return;
|
||||
}
|
||||
|
||||
root.style.setProperty(positionToCssVariable[position], `${width}px`);
|
||||
updatePanelDefaultWidth(position, width);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,19 +1,21 @@
|
|||
$activity-picker-width: 300px;
|
||||
$activity-editor-width: 580px;
|
||||
:root {
|
||||
--activity-editor-width: 580px;
|
||||
--activity-picker-width: 300px;
|
||||
}
|
||||
|
||||
elsa-canvas {
|
||||
left: $activity-picker-width;
|
||||
left: var(--activity-picker-width);
|
||||
top: 0;
|
||||
right: $activity-editor-width;
|
||||
right: var(--activity-editor-width);
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
elsa-panel.panel-state-expanded.elsa-activity-picker-container {
|
||||
width: $activity-picker-width;
|
||||
width: var(--activity-picker-width);
|
||||
}
|
||||
|
||||
elsa-panel.panel-state-expanded.elsa-activity-editor-container {
|
||||
width: $activity-editor-width;
|
||||
width: var(--activity-editor-width);
|
||||
right: 0;
|
||||
left: unset;
|
||||
}
|
||||
|
|
@ -38,4 +40,4 @@ elsa-panel.panel-state-expanded.elsa-activity-editor-container {
|
|||
elsa-canvas {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue