mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 16:02:23 -04:00
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:
parent
0a3d38125d
commit
f5abd3c6af
4 changed files with 79 additions and 29 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue