Implement TagWithTooltip

This commit is contained in:
Henrik Giesel 2021-07-08 23:35:54 +02:00
parent 7058d14d25
commit 28b1c09cda
7 changed files with 99 additions and 75 deletions

View file

@ -19,15 +19,21 @@
export let tooltip: string;
export let trigger: TriggerType = "hover focus";
export let placement: "auto" | "top" | "bottom" | "left" | "right" = "top";
export let html = true;
export let offset: Tooltip.Offset = [0, 0];
export let showDelay = 0;
export let hideDelay = 0;
let tooltipObject: Tooltip;
function createTooltip(element: HTMLElement): void {
element.title = tooltip;
tooltipObject = new Tooltip(element, {
placement: "bottom",
html: true,
offset: [0, 20],
delay: { show: 250, hide: 0 },
placement,
html,
offset,
delay: { show: showDelay, hide: hideDelay },
trigger,
});
}

View file

@ -16,7 +16,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<span>
<Label for={forId}><slot /></Label>
<WithTooltip tooltip={marked(markdownTooltip)} let:createTooltip>
<WithTooltip
tooltip={marked(markdownTooltip)}
showDelay={250}
offset={[0, 20]}
placement="bottom"
let:createTooltip
>
<Badge
class="opacity-50"
on:mount={(event) => createTooltip(event.detail.span)}

View file

@ -1,38 +0,0 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { onDestroy } from "svelte";
import Tooltip from "bootstrap/js/dist/tooltip";
type TriggerType =
| "hover focus"
| "click"
| "hover"
| "focus"
| "manual"
| "click hover"
| "click focus"
| "click hover focus";
export let tooltip: string;
export let trigger: TriggerType = "hover focus";
let tooltipObject: Tooltip;
function createTooltip(element: HTMLElement): void {
element.title = tooltip;
tooltipObject = new Tooltip(element, {
placement: "bottom",
html: true,
offset: [0, 20],
delay: { show: 250, hide: 0 },
trigger,
});
}
onDestroy(() => tooltipObject?.dispose());
</script>
<slot {createTooltip} {tooltipObject} />

View file

@ -3,7 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import { getContext, createEventDispatcher } from "svelte";
import { onMount, getContext, createEventDispatcher } from "svelte";
import { nightModeKey } from "components/context-keys";
import Badge from "components/Badge.svelte";
import { deleteIcon } from "./icons";
@ -50,11 +50,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
const nightMode = getContext<boolean>(nightModeKey);
let button: HTMLButtonElement;
onMount(() => dispatch("mount", { button }));
</script>
<svelte:body on:keydown={setDeleteIcon} on:keyup={setDeleteIcon} />
<button
bind:this={button}
class={`tag btn d-inline-flex align-items-center text-nowrap rounded ps-2 pe-1 m-0 ${className}`}
class:selected
class:flashing

View file

@ -10,19 +10,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import StickyBottom from "components/StickyBottom.svelte";
import AddTagBadge from "./AddTagBadge.svelte";
import SelectedTagBadge from "./SelectedTagBadge.svelte";
import Tag from "./Tag.svelte";
import TagWithTooltip from "./TagWithTooltip.svelte";
import TagInput from "./TagInput.svelte";
import WithAutocomplete from "./WithAutocomplete.svelte";
import ButtonToolbar from "components/ButtonToolbar.svelte";
import { controlPressed } from "lib/keys";
import type { Tag as TagType } from "./tags";
import {
attachId,
getName,
delimChar,
replaceWithDelimChar,
replaceWithColon,
} from "./tags";
import { attachId, getName, replaceWithDelimChar, replaceWithColon } from "./tags";
export let size = isApplePlatform() ? 1.6 : 2.0;
@ -377,20 +371,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
// typically correct for rows < 7
$: assumedRows = Math.floor(height / badgeHeight);
$: shortenTags = shortenTags || assumedRows > 2;
function processTagName(name: string): string {
const parts = name.split(delimChar);
if (parts.length === 1) {
return name;
}
return `…${delimChar}` + parts[parts.length - 1];
}
function hasMultipleParts(name: string): boolean {
return name.split(delimChar).length > 1;
}
</script>
<Spacer --height={`${height}px`} />
@ -419,16 +399,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{#each tags as tag, index (tag.id)}
<div class="position-relative gap" class:hide-tag={index === active}>
<Tag
<TagWithTooltip
class="me-1"
name={index === active
? activeName
: shortenTags
? processTagName(tag.name)
: tag.name}
tooltip={shortenTags && hasMultipleParts(tag.name)
? tag.name
: undefined}
name={index === active ? activeName : tag.name}
tooltip={tag.name}
active={index === active}
shorten={shortenTags}
bind:flash={tag.flash}
bind:selected={tag.selected}
on:tagedit={() => {

View file

@ -0,0 +1,65 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import WithTooltip from "components/WithTooltip.svelte";
import Tag from "./Tag.svelte";
import { delimChar } from "./tags";
export let name: string;
let className: string = "";
export { className as class };
export let tooltip: string;
export let selected: boolean;
export let active: boolean;
export let shorten: boolean;
export let flash: () => void;
function processTagName(name: string): string {
const parts = name.split(delimChar);
if (parts.length === 1) {
return name;
}
return `…${delimChar}` + parts[parts.length - 1];
}
function hasMultipleParts(name: string): boolean {
return name.split(delimChar).length > 1;
}
</script>
{#if active}
<Tag class={className} {name} />
{:else if shorten && hasMultipleParts(name)}
<WithTooltip {tooltip} placement="auto" let:createTooltip>
<Tag
class={className}
name={processTagName(name)}
bind:flash
bind:selected
on:tagedit
on:tagselect
on:tagrange
on:tagdelete
on:mount={(event) => createTooltip(event.detail.button)}
/>
</WithTooltip>
{:else}
<Tag
class={className}
{name}
bind:flash
bind:selected
on:tagedit
on:tagselect
on:tagrange
on:tagdelete
/>
{/if}

View file

@ -7,3 +7,7 @@ $btn-disabled-opacity: 0.4;
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/button-group";
@import "bootstrap/scss/dropdown";
$tooltip-max-width: 600px;
@import "bootstrap/scss/tooltip";