diff --git a/packages/web/public/global.css b/packages/web/public/global.css index b063dff26..d3679ddf8 100644 --- a/packages/web/public/global.css +++ b/packages/web/public/global.css @@ -10,6 +10,24 @@ body { -moz-osx-font-smoothing: grayscale; } +.horizontal-split-handle { + background-color: var(--theme-border); + width: var(--dim-splitter-thickness); + cursor: col-resize; +} +.horizontal-split-handle:hover { + background-color: var(--theme-bg-2); +} + +.vertical-split-handle { + background-color: var(--theme-border); + height: var(--dim-splitter-thickness); + cursor: row-resize; +} +.vertical-split-handle:hover { + background-color: var(--theme-bg-2); +} + /* html, body { position: relative; width: 100%; diff --git a/packages/web/src/Screen.svelte b/packages/web/src/Screen.svelte index 6df2dd67c..4066e9359 100644 --- a/packages/web/src/Screen.svelte +++ b/packages/web/src/Screen.svelte @@ -1,11 +1,13 @@ -
@@ -24,6 +26,11 @@
+
leftPanelWidth.update(x => x + e.detail)} + /> {#if $visibleCommandPalette}
@@ -100,4 +107,11 @@ left: 0; right: 0; } + + .splitter { + position: absolute; + top: var(--dim-header-top); + bottom: var(--dim-statusbar-height); + left: calc(var(--dim-widget-icon-size) + var(--dim-left-panel-width)); + } diff --git a/packages/web/src/commands/CommandPalette.svelte b/packages/web/src/commands/CommandPalette.svelte index 419cddd18..63ac3c55b 100644 --- a/packages/web/src/commands/CommandPalette.svelte +++ b/packages/web/src/commands/CommandPalette.svelte @@ -21,7 +21,7 @@ import { derived } from 'svelte/store'; import { onMount } from 'svelte'; import { commands, visibleCommandPalette } from '../stores'; - import { clickOutside } from '../utility/clickOutside'; + import clickOutside from '../utility/clickOutside'; import keycodes from '../utility/keycodes'; import registerCommand from './registerCommand'; diff --git a/packages/web/src/stores.ts b/packages/web/src/stores.ts index 191ce5064..9568d61c5 100644 --- a/packages/web/src/stores.ts +++ b/packages/web/src/stores.ts @@ -34,8 +34,9 @@ export const commands = writable({}); export const currentTheme = writableWithStorage('theme-light', 'currentTheme'); export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid); export const visibleToolbar = writableWithStorage(1, 'visibleToolbar'); +export const leftPanelWidth = writable(300); subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel'); subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar'); +subscribeCssVariable(leftPanelWidth, x => `${x}px`, '--dim-left-panel-width'); -// export const leftPanelWidth = writable(300); diff --git a/packages/web/src/utility/clickOutside.ts b/packages/web/src/utility/clickOutside.ts index 0e694f066..4eefac8e6 100644 --- a/packages/web/src/utility/clickOutside.ts +++ b/packages/web/src/utility/clickOutside.ts @@ -1,7 +1,7 @@ -export function clickOutside(node) { +export default function clickOutside(node) { const handleClick = event => { if (node && !node.contains(event.target) && !event.defaultPrevented) { - node.dispatchEvent(new CustomEvent('clickOutside', node)); + node.dispatchEvent(new CustomEvent('clickOutside')); } }; diff --git a/packages/web/src/utility/splitterDrag.ts b/packages/web/src/utility/splitterDrag.ts new file mode 100644 index 000000000..b31585e22 --- /dev/null +++ b/packages/web/src/utility/splitterDrag.ts @@ -0,0 +1,38 @@ +export default function splitterDrag(node, axes) { + let resizeStart = null; + + const handleResizeDown = e => { + resizeStart = e[axes]; + document.addEventListener('mousemove', handleResizeMove, true); + document.addEventListener('mouseup', handleResizeEnd, true); + }; + + const handleResizeMove = e => { + e.preventDefault(); + const diff = e[axes] - resizeStart; + resizeStart = e[axes]; + node.dispatchEvent( + new CustomEvent('resizeSplitter', { + detail: diff, + }) + ); + }; + const handleResizeEnd = e => { + e.preventDefault(); + resizeStart = null; + document.removeEventListener('mousemove', handleResizeMove, true); + document.removeEventListener('mouseup', handleResizeEnd, true); + }; + + node.addEventListener('mousedown', handleResizeDown); + + return { + destroy() { + node.removeEventListener('mousedown', handleResizeDown); + if (resizeStart != null) { + document.removeEventListener('mousemove', handleResizeMove, true); + document.removeEventListener('mouseup', handleResizeEnd, true); + } + }, + }; +}