Fix some WithDropdownMenu logic

This commit is contained in:
Henrik Giesel 2021-06-25 19:23:35 +02:00
parent 05120c79b0
commit 281985480d
5 changed files with 39 additions and 16 deletions

View file

@ -17,10 +17,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}); });
const menuId = Math.random().toString(36).substring(2); const menuId = Math.random().toString(36).substring(2);
let dropdown: Dropdown; let dropdown: Dropdown | undefined;
function activateDropdown(): void { function activateDropdown(): void {
if (!disabled) { if (dropdown && !disabled) {
dropdown.toggle(); dropdown.toggle();
} }
} }
@ -30,10 +30,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function createDropdown(element: HTMLElement): Dropdown { function createDropdown(element: HTMLElement): Dropdown {
/* Prevent focus on menu activation */ /* Prevent focus on menu activation */
const noop = () => {}; const noop = () => {};
Object.defineProperty(element, "focus", { value: noop }); Object.defineProperty(element, "focus", { value: noop, configurable: true });
const menu = (element.getRootNode() as Document) /* or shadow root */ const menu = (element.getRootNode() as Document | ShadowRoot).getElementById(
.getElementById(menuId); menuId
);
if (!menu) { if (!menu) {
console.log(`Could not find menu "${menuId}" for dropdown menu.`); console.log(`Could not find menu "${menuId}" for dropdown menu.`);
@ -44,7 +45,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
(dropdown as any)._menu = menu; (dropdown as any)._menu = menu;
} }
return dropdown; return dropdown as Dropdown;
} }
</script> </script>

View file

@ -41,7 +41,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<TagInput <TagInput
bind:name bind:name
bind:input bind:input
on:focusout={() => (active = false)} on:focus
on:blur={() => (active = false)}
on:tagupdate={updateTag} on:tagupdate={updateTag}
on:tagadd on:tagadd
on:tagjoinprevious on:tagjoinprevious

View file

@ -3,6 +3,8 @@ 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 type Dropdown from "bootstrap/js/dist/dropdown";
import WithDropdownMenu from "components/WithDropdownMenu.svelte"; import WithDropdownMenu from "components/WithDropdownMenu.svelte";
import DropdownMenu from "components/DropdownMenu.svelte"; import DropdownMenu from "components/DropdownMenu.svelte";
import DropdownItem from "components/DropdownItem.svelte"; import DropdownItem from "components/DropdownItem.svelte";
@ -12,6 +14,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let className: string = ""; let className: string = "";
export { className as class }; export { className as class };
let autocomplete: Dropdown | undefined;
function switchUpDown(event: KeyboardEvent): void { function switchUpDown(event: KeyboardEvent): void {
const target = event.currentTarget as HTMLButtonElement; const target = event.currentTarget as HTMLButtonElement;
if (event.code === "ArrowUp") { if (event.code === "ArrowUp") {
@ -28,14 +32,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
event.preventDefault(); event.preventDefault();
} }
} }
const createAutocomplete =
(createDropdown: (element: HTMLElement) => Dropdown) =>
(element: HTMLElement) => {
autocomplete = createDropdown(element);
autocomplete.show();
return autocomplete;
};
</script> </script>
<WithDropdownMenu let:menuId let:createDropdown let:activateDropdown> <WithDropdownMenu let:menuId let:createDropdown>
<slot {createDropdown} {activateDropdown} /> <slot createAutocomplete={createAutocomplete(createDropdown)} />
<DropdownMenu id={menuId} class={className}> <DropdownMenu id={menuId} class={className}>
{#each suggestions as tag} {#each suggestions as tag}
<DropdownItem on:keydown={switchUpDown}>{tag}</DropdownItem> <DropdownItem>{tag}</DropdownItem>
{/each} {/each}
</DropdownMenu> </DropdownMenu>
</WithDropdownMenu> </WithDropdownMenu>

View file

@ -22,6 +22,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let newName: string = ""; let newName: string = "";
function focusNewInput(): void { function focusNewInput(): void {
if (document.activeElement === newInput) {
// refocus
newInput.blur();
}
console.log("focus");
newInput.focus(); newInput.focus();
} }
@ -94,17 +100,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<StickyBottom> <StickyBottom>
<div class="row-gap"> <div class="row-gap">
<ButtonToolbar class="dropup d-flex flex-wrap align-items-center" {size}> <ButtonToolbar class="dropup d-flex flex-wrap align-items-center" {size}>
<AddTagBadge on:click={focusNewInput} />
<TagAutocomplete <TagAutocomplete
class="d-flex flex-column-reverse" class="d-flex flex-column-reverse"
{suggestions} {suggestions}
let:createDropdown let:createAutocomplete
let:activateDropdown
> >
<AddTagBadge on:click={focusNewInput} />
{#each tags as tag, index (tag.id)} {#each tags as tag, index (tag.id)}
<Tag <Tag
bind:name={tag.name} bind:name={tag.name}
on:keydown
on:focus={(event) => createAutocomplete(event.target)}
on:tagupdate={() => checkForDuplicateAt(index)} on:tagupdate={() => checkForDuplicateAt(index)}
on:tagadd={() => insertTagAt(index)} on:tagadd={() => insertTagAt(index)}
on:tagdelete={() => deleteTagAt(index)} on:tagdelete={() => deleteTagAt(index)}
@ -116,7 +123,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<TagInput <TagInput
bind:input={newInput} bind:input={newInput}
bind:name={newName} bind:name={newName}
on:focus={(event) => createDropdown(event.currentTarget)} on:focus={(event) => createAutocomplete(event.target)}
on:keydown
on:tagupdate={appendTag} on:tagupdate={appendTag}
on:tagadd={appendTag} on:tagadd={appendTag}
on:tagjoinprevious={joinWithLastTag} on:tagjoinprevious={joinWithLastTag}

View file

@ -51,6 +51,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onAccept(); onAccept();
event.preventDefault(); event.preventDefault();
} }
console.log("keydown");
} }
function onPaste(event: ClipboardEvent): void { function onPaste(event: ClipboardEvent): void {
@ -96,7 +97,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
size="1" size="1"
bind:value={name} bind:value={name}
on:focus on:focus
on:focusout on:blur
on:blur={onAccept} on:blur={onAccept}
on:keydown={onKeydown} on:keydown={onKeydown}
on:paste={onPaste} on:paste={onPaste}