added ability to resize panels (#3092)

Co-authored-by: Ivan Hrynevytskyi <ivan.hrynevytskyi@IHRYNEVYTSKYIL.local>
This commit is contained in:
Ivan Hrynevytskyi (FE-underwriting) 2022-05-31 16:01:22 +03:00 committed by GitHub
parent 700d69cfc5
commit c302478282
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 20 deletions

View file

@ -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;
}
}

View file

@ -16,4 +16,4 @@
top: 0;
display: none;
}
}
}

View file

@ -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>

View file

@ -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;
}

View file

@ -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;
}
}
}