Make resizer snap to closest end and improve toggle (#2129)

* Make resizer snap to closest end and improve toggle

* Snap on window resize

* Remove event parameter

* Remove nested ternary expression
This commit is contained in:
Matthias Metelka 2022-10-13 02:13:19 +02:00 committed by GitHub
parent 0a3d38125d
commit f5abd3c6af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 29 deletions

View file

@ -3,6 +3,9 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { fly } from "svelte/transition";
import { on } from "../lib/events";
import { Callback, singleCallback } from "../lib/typing";
import IconConstrain from "./IconConstrain.svelte";
@ -12,8 +15,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let panes: ResizablePane[];
export let index = 0;
export let tip = "";
export let showIndicator = false;
export let clientHeight: number;
const rtl = window.getComputedStyle(document.body).direction == "rtl";
const dispatch = createEventDispatcher();
let destroy: Callback;
let before: ResizablePane;
@ -77,18 +85,31 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
destroy = singleCallback(
on(window, "pointermove", onMove),
on(window, "pointerup", releasePointer),
on(window, "pointerup", () => {
releasePointer.call(window);
dispatch("release");
}),
);
}
</script>
<div
class="horizontal-resizer"
class:rtl
title={tip}
bind:clientHeight={resizerHeight}
on:pointerdown|preventDefault={lockPointer}
on:dblclick
on:dblclick|preventDefault
>
{#if showIndicator}
<div
class="resize-indicator"
transition:fly={{ x: rtl ? 25 : -25, duration: 200 }}
>
<slot />
</div>
{/if}
<div class="drag-handle">
<IconConstrain iconSize={80}>{@html horizontalHandle}</IconConstrain>
</div>
@ -99,7 +120,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
width: 100%;
cursor: row-resize;
position: relative;
height: 10px;
height: 25px;
border-top: 1px solid var(--border);
z-index: 20;
@ -113,5 +134,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
&:hover .drag-handle {
opacity: 0.8;
}
.resize-indicator {
position: absolute;
font-size: small;
bottom: 0;
}
&.rtl .resize-indicator {
padding: 0.5rem 0 0 0.5rem;
right: 0;
}
}
</style>

View file

@ -59,5 +59,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.pane {
@include panes.resizable(column, true, true);
opacity: var(--opacity, 1);
}
</style>

View file

@ -355,12 +355,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: tagAmount = $tags.length;
let snapTags = $tagsCollapsed;
function collapseTags(): void {
lowerResizer.move([tagsPane, fieldsPane], tagsPane.minHeight);
$tagsCollapsed = snapTags = true;
}
function expandTags(): void {
lowerResizer.move([tagsPane, fieldsPane], tagsPane.maxHeight);
$tagsCollapsed = snapTags = false;
}
window.addEventListener("resize", () => snapResizer(snapTags));
function snapResizer(collapse: boolean): void {
if (collapse) {
collapseTags();
bridgeCommand("collapseTags");
} else {
expandTags();
bridgeCommand("expandTags");
}
}
</script>
@ -390,7 +406,9 @@ the AddCards dialog) should be implemented in the user of this component.
<Pane
bind:this={fieldsPane.resizable}
on:resize={(e) => (fieldsPane.height = e.detail.height)}
on:resize={(e) => {
fieldsPane.height = e.detail.height;
}}
>
<PaneContent>
<Fields>
@ -553,7 +571,17 @@ the AddCards dialog) should be implemented in the user of this component.
</PaneContent>
</Pane>
{#if $tagsCollapsed}
<HorizontalResizer
panes={[fieldsPane, tagsPane]}
showIndicator={$tagsCollapsed || snapTags}
tip={`Double click to ${$tagsCollapsed ? "expand" : "collapse"} tag editor`}
{clientHeight}
bind:this={lowerResizer}
on:dblclick={() => snapResizer(!$tagsCollapsed)}
on:release={() => {
snapResizer(snapTags);
}}
>
<div class="tags-expander">
<TagAddButton
on:tagappend={() => {
@ -564,36 +592,28 @@ the AddCards dialog) should be implemented in the user of this component.
{@html tagAmount > 0 ? `${tagAmount} Tags` : ""}
</TagAddButton>
</div>
{/if}
<HorizontalResizer
panes={[fieldsPane, tagsPane]}
tip={`Double click to ${$tagsCollapsed ? "expand" : "collapse"} tag editor`}
{clientHeight}
bind:this={lowerResizer}
on:dblclick={() => {
if ($tagsCollapsed) {
expandTags();
bridgeCommand("expandTags");
$tagsCollapsed = false;
} else {
collapseTags();
bridgeCommand("collapseTags");
$tagsCollapsed = true;
}
}}
/>
</HorizontalResizer>
<Pane
bind:this={tagsPane.resizable}
on:resize={(e) => {
tagsPane.height = e.detail.height;
$tagsCollapsed = tagsPane.height == 0;
if (tagsPane.maxHeight > 0) {
snapTags = tagsPane.height < tagsPane.maxHeight / 2;
}
}}
--opacity={(() => {
if (!$tagsCollapsed) {
return 1;
} else {
return snapTags ? tagsPane.height / tagsPane.maxHeight : 1;
}
})()}
>
<PaneContent scroll={false}>
<TagEditor
{tags}
--button-opacity={snapTags ? 0 : 1}
bind:this={tagEditor}
on:tagsupdate={saveTags}
on:tagsFocused={() => {
@ -617,7 +637,4 @@ the AddCards dialog) should be implemented in the user of this component.
flex-direction: column;
height: 100%;
}
.tags-expander {
margin-top: 0.5rem;
}
</style>

View file

@ -25,6 +25,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<style lang="scss">
.tag-options-button {
padding: 6px 3px 0;
transition: opacity 0.2s linear;
opacity: var(--button-opacity, 1);
}
</style>