Implement nowrap mode

This commit is contained in:
Henrik Giesel 2021-07-09 01:33:06 +02:00
parent 28b1c09cda
commit 04b75859cc
4 changed files with 88 additions and 29 deletions

View file

@ -3,10 +3,10 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="typescript"> <script lang="typescript">
import { setContext } from "svelte"; import { getContext, setContext } from "svelte";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import Item from "./Item.svelte"; import Item from "./Item.svelte";
import { sectionKey } from "./context-keys"; import { sectionKey, nightModeKey } from "./context-keys";
import type { Identifier } from "./identifier"; import type { Identifier } from "./identifier";
import { insertElement, appendElement } from "./identifier"; import { insertElement, appendElement } from "./identifier";
import type { SvelteComponent, Registration } from "./registration"; import type { SvelteComponent, Registration } from "./registration";
@ -73,12 +73,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
toggleGroup, toggleGroup,
}); });
} }
const nightMode = getContext<boolean>(nightModeKey);
</script> </script>
<div <div
bind:this={buttonToolbarRef} bind:this={buttonToolbarRef}
{id} {id}
class={`btn-toolbar container wrap-variable ${className}`} class={`btn-toolbar container wrap-variable ${className}`}
class:overflow={!wrap}
class:nightMode
{style} {style}
role="toolbar" role="toolbar"
on:focusout on:focusout
@ -92,7 +96,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</div> </div>
<style lang="scss"> <style lang="scss">
@use 'ts/sass/scrollbar';
.nightMode {
@include scrollbar.night-mode;
}
.wrap-variable { .wrap-variable {
flex-wrap: var(--buttons-wrap); flex-wrap: var(--buttons-wrap);
} }
.overflow {
overflow-x: auto;
}
</style> </style>

View file

@ -10,21 +10,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { appendInParentheses } from "./helpers"; import { appendInParentheses } from "./helpers";
import { tagIcon, addTagIcon } from "./icons"; import { tagIcon, addTagIcon } from "./icons";
let theTagIcon = tagIcon;
const tooltip = "Add tag"; const tooltip = "Add tag";
</script> </script>
<WithShortcut shortcut="Control+Shift+T" let:createShortcut let:shortcutLabel> <WithShortcut shortcut="Control+Shift+T" let:createShortcut let:shortcutLabel>
<div class="add-icon"> <div class="add-icon">
<Badge <Badge
class="me-1" class="d-flex me-1"
tooltip={appendInParentheses(tooltip, shortcutLabel)} tooltip={appendInParentheses(tooltip, shortcutLabel)}
on:click on:click
on:mouseenter={() => (theTagIcon = addTagIcon)} on:mount={withSpan(createShortcut)}
on:mouseleave={() => (theTagIcon = tagIcon)}
on:mount={withSpan(createShortcut)}>{@html theTagIcon}</Badge
> >
{@html tagIcon}
{@html addTagIcon}
</Badge>
</div> </div>
</WithShortcut> </WithShortcut>
@ -32,6 +31,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.add-icon { .add-icon {
line-height: 1; line-height: 1;
:global(svg:last-child) {
display: none;
}
&:hover {
:global(svg:first-child) {
display: none;
}
:global(svg:last-child) {
display: block;
}
}
:global(svg) { :global(svg) {
cursor: pointer; cursor: pointer;
fill: currentColor; fill: currentColor;

View file

@ -8,8 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { bridgeCommand } from "lib/bridgecommand"; import { bridgeCommand } from "lib/bridgecommand";
import Spacer from "components/Spacer.svelte"; import Spacer from "components/Spacer.svelte";
import StickyBottom from "components/StickyBottom.svelte"; import StickyBottom from "components/StickyBottom.svelte";
import AddTagBadge from "./AddTagBadge.svelte"; import TagOptionsBadge from "./TagOptionsBadge.svelte";
import SelectedTagBadge from "./SelectedTagBadge.svelte";
import TagWithTooltip from "./TagWithTooltip.svelte"; import TagWithTooltip from "./TagWithTooltip.svelte";
import TagInput from "./TagInput.svelte"; import TagInput from "./TagInput.svelte";
import WithAutocomplete from "./WithAutocomplete.svelte"; import WithAutocomplete from "./WithAutocomplete.svelte";
@ -18,10 +17,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { Tag as TagType } from "./tags"; import type { Tag as TagType } from "./tags";
import { attachId, getName, replaceWithDelimChar, replaceWithColon } from "./tags"; import { attachId, getName, replaceWithDelimChar, replaceWithColon } from "./tags";
export let size = isApplePlatform() ? 1.6 : 2.0;
export let tags: TagType[] = []; export let tags: TagType[] = [];
export let size = isApplePlatform() ? 1.6 : 2.0;
export let wrap = true;
export function resetTags(names: string[]): void { export function resetTags(names: string[]): void {
tags = names.map(replaceWithDelimChar).map(attachId); tags = names.map(replaceWithDelimChar).map(attachId);
} }
@ -375,27 +375,35 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<Spacer --height={`${height}px`} /> <Spacer --height={`${height}px`} />
<StickyBottom bind:height> <StickyBottom class="d-flex" bind:height>
{#if !wrap}
<TagOptionsBadge
--button-size={`${size}rem`}
showSelectionsOptions={tags.some((tag) => tag.selected)}
bind:badgeHeight
on:tagselectall={selectAllTags}
on:tagcopy={copySelectedTags}
on:tagdelete={deleteSelectedTags}
on:click={appendEmptyTag}
/>
{/if}
<ButtonToolbar <ButtonToolbar
class="d-flex flex-wrap align-items-center mx-1" class="align-items-center mx-1"
{size} {size}
{wrap}
on:focusout={deselectIfLeave} on:focusout={deselectIfLeave}
> >
<div class="gap" bind:offsetHeight={badgeHeight} on:mousedown|preventDefault> {#if wrap}
{#if tags.some((tag) => tag.selected)} <TagOptionsBadge
<SelectedTagBadge showSelectionsOptions={tags.some((tag) => tag.selected)}
--badge-align="-webkit-baseline-middle" bind:badgeHeight
on:tagselectall={selectAllTags} on:tagselectall={selectAllTags}
on:tagcopy={copySelectedTags} on:tagcopy={copySelectedTags}
on:tagdelete={deleteSelectedTags} on:tagdelete={deleteSelectedTags}
/> on:click={appendEmptyTag}
{:else} />
<AddTagBadge {/if}
--badge-align="-webkit-baseline-middle"
on:click={appendEmptyTag}
/>
{/if}
</div>
{#each tags as tag, index (tag.id)} {#each tags as tag, index (tag.id)}
<div class="position-relative gap" class:hide-tag={index === active}> <div class="position-relative gap" class:hide-tag={index === active}>

View file

@ -0,0 +1,24 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import SelectedTagBadge from "./SelectedTagBadge.svelte";
import AddTagBadge from "./AddTagBadge.svelte";
export let badgeHeight: number;
export let showSelectionsOptions: boolean;
</script>
<div class="gap" bind:offsetHeight={badgeHeight} on:mousedown|preventDefault>
{#if showSelectionsOptions}
<SelectedTagBadge
--badge-align="-webkit-baseline-middle"
on:tagselectall
on:tagcopy
on:tagdelete
/>
{:else}
<AddTagBadge --badge-align="-webkit-baseline-middle" on:click />
{/if}
</div>