mirror of
https://github.com/ankitects/anki.git
synced 2025-11-11 15:17:12 -05:00
Add SelectedTagBadge to offer context items for selected tags
This commit is contained in:
parent
00de99880b
commit
874a315f83
5 changed files with 107 additions and 3 deletions
|
|
@ -53,7 +53,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
/* Set custom menu without using common element with .dropdown */
|
/* Set custom menu without using common element with .dropdown */
|
||||||
(dropdown as any)._menu = menu;
|
(dropdown as any)._menu = menu;
|
||||||
Object.defineProperty(dropdown, "isVisible", { value: isVisible });
|
Object.defineProperty(dropdown, "isVisible", { value: isVisible });
|
||||||
|
|
||||||
return dropdown as Dropdown;
|
return dropdown as Dropdown;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,7 @@ copy_mdi_icons(
|
||||||
"tag-outline.svg",
|
"tag-outline.svg",
|
||||||
"tag.svg",
|
"tag.svg",
|
||||||
"tag-plus.svg",
|
"tag-plus.svg",
|
||||||
|
"dots-vertical.svg",
|
||||||
],
|
],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
64
ts/editor/SelectedTagBadge.svelte
Normal file
64
ts/editor/SelectedTagBadge.svelte
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<!--
|
||||||
|
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 Badge from "components/Badge.svelte";
|
||||||
|
import WithDropdownMenu from "components/WithDropdownMenu.svelte";
|
||||||
|
import WithShortcut from "components/WithShortcut.svelte";
|
||||||
|
import DropdownMenu from "components/DropdownMenu.svelte";
|
||||||
|
import DropdownItem from "components/DropdownItem.svelte";
|
||||||
|
|
||||||
|
import { withSpan, withButton } from "components/helpers";
|
||||||
|
import { appendInParentheses } from "./helpers";
|
||||||
|
import { dotsIcon } from "./icons";
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
const copyLabel = "Copy tags";
|
||||||
|
const removeLabel = "Remove tags";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<WithDropdownMenu let:menuId let:createDropdown>
|
||||||
|
<div class="dropdown">
|
||||||
|
<div class="more-icon">
|
||||||
|
<Badge class="me-1" on:mount={withSpan(createDropdown)}
|
||||||
|
>{@html dotsIcon}</Badge
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DropdownMenu id={menuId}>
|
||||||
|
<WithShortcut shortcut="C" let:createShortcut let:shortcutLabel>
|
||||||
|
<DropdownItem
|
||||||
|
on:click={() => dispatch("tagcopy")}
|
||||||
|
on:mount={withButton(createShortcut)}
|
||||||
|
>{appendInParentheses(copyLabel, shortcutLabel)}</DropdownItem
|
||||||
|
>
|
||||||
|
</WithShortcut>
|
||||||
|
<WithShortcut shortcut="Backspace" let:createShortcut let:shortcutLabel>
|
||||||
|
<DropdownItem
|
||||||
|
on:click={() => dispatch("tagdelete")}
|
||||||
|
on:mount={withButton(createShortcut)}
|
||||||
|
>{appendInParentheses(removeLabel, shortcutLabel)}</DropdownItem
|
||||||
|
>
|
||||||
|
</WithShortcut>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
</WithDropdownMenu>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.more-icon {
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
:global(svg) {
|
||||||
|
cursor: pointer;
|
||||||
|
fill: currentColor;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(svg:hover) {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -8,6 +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 StickyBottom from "components/StickyBottom.svelte";
|
import StickyBottom from "components/StickyBottom.svelte";
|
||||||
import AddTagBadge from "./AddTagBadge.svelte";
|
import AddTagBadge from "./AddTagBadge.svelte";
|
||||||
|
import SelectedTagBadge from "./SelectedTagBadge.svelte";
|
||||||
import Tag from "./Tag.svelte";
|
import Tag from "./Tag.svelte";
|
||||||
import TagInput from "./TagInput.svelte";
|
import TagInput from "./TagInput.svelte";
|
||||||
import WithAutocomplete from "./WithAutocomplete.svelte";
|
import WithAutocomplete from "./WithAutocomplete.svelte";
|
||||||
|
|
@ -322,6 +323,37 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
deselect();
|
deselect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO replace with navigator.clipboard once available */
|
||||||
|
function copyToClipboard(content: string): void {
|
||||||
|
const textarea = document.createElement("textarea");
|
||||||
|
textarea.value = content;
|
||||||
|
textarea.setAttribute("readonly", "");
|
||||||
|
textarea.style.position = "absolute";
|
||||||
|
textarea.style.left = "-9999px";
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
document.execCommand("copy");
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
}
|
||||||
|
|
||||||
|
function copySelectedTags() {
|
||||||
|
const content = tags
|
||||||
|
.filter((tag) => tag.selected)
|
||||||
|
.map((tag) => tag.name)
|
||||||
|
.join("\n");
|
||||||
|
copyToClipboard(content);
|
||||||
|
deselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteSelectedTags() {
|
||||||
|
tags.map((tag, index) => [tag.selected, index])
|
||||||
|
.filter(([selected]) => selected)
|
||||||
|
.reverse()
|
||||||
|
.forEach(([, index]) => deleteTagAt(index as number));
|
||||||
|
deselect();
|
||||||
|
saveTags();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<StickyBottom>
|
<StickyBottom>
|
||||||
|
|
@ -330,8 +362,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
{size}
|
{size}
|
||||||
on:focusout={deselectIfLeave}
|
on:focusout={deselectIfLeave}
|
||||||
>
|
>
|
||||||
<div class="pb-1">
|
<div class="pb-1" on:mousedown|preventDefault>
|
||||||
<AddTagBadge on:click={appendEmptyTag} />
|
{#if tags.some((tag) => tag.selected)}
|
||||||
|
<SelectedTagBadge
|
||||||
|
on:tagcopy={copySelectedTags}
|
||||||
|
on:tagdelete={deleteSelectedTags}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<AddTagBadge on:click={appendEmptyTag} />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#each tags as tag, index (tag.id)}
|
{#each tags as tag, index (tag.id)}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ export { default as xmlIcon } from "./xml.svg";
|
||||||
|
|
||||||
export { default as tagIcon } from "./tag.svg";
|
export { default as tagIcon } from "./tag.svg";
|
||||||
export { default as addTagIcon } from "./tag-plus.svg";
|
export { default as addTagIcon } from "./tag-plus.svg";
|
||||||
|
export { default as dotsIcon } from "./dots-vertical.svg";
|
||||||
export { default as deleteIcon } from "./x.svg";
|
export { default as deleteIcon } from "./x.svg";
|
||||||
|
|
||||||
export const arrowIcon =
|
export const arrowIcon =
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue