mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-16 12:12:15 +01:00
add focus trap to tag dropdown to fix focus management
This commit is contained in:
@@ -6,6 +6,7 @@ import TagCreateModal from '@/packages/ui/src/Tag/TagCreateModal.vue';
|
|||||||
import MultiselectDropdownItem from '@/packages/ui/src/Input/MultiselectDropdownItem.vue';
|
import MultiselectDropdownItem from '@/packages/ui/src/Input/MultiselectDropdownItem.vue';
|
||||||
import type { Tag } from '@/packages/api/src';
|
import type { Tag } from '@/packages/api/src';
|
||||||
import type { Placement } from '@floating-ui/vue';
|
import type { Placement } from '@floating-ui/vue';
|
||||||
|
import {UseFocusTrap} from "@vueuse/integrations/useFocusTrap/component";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
@@ -177,46 +178,50 @@ const showCreateTagModal = ref(false);
|
|||||||
<slot name="trigger"></slot>
|
<slot name="trigger"></slot>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<input
|
<UseFocusTrap
|
||||||
ref="searchInput"
|
v-if="open"
|
||||||
:value="searchValue"
|
:options="{ immediate: true, allowOutsideClick: true }">
|
||||||
data-testid="tag_dropdown_search"
|
<input
|
||||||
class="bg-card-background border-0 placeholder-muted text-sm text-white py-2.5 focus:ring-0 border-b border-card-background-separator focus:border-card-background-separator w-full"
|
ref="searchInput"
|
||||||
placeholder="Search for a Tag..."
|
:value="searchValue"
|
||||||
@input="updateSearchValue"
|
data-testid="tag_dropdown_search"
|
||||||
@keydown.enter="addTagIfNoneExists"
|
class="bg-card-background border-0 placeholder-muted text-sm text-white py-2.5 focus:ring-0 border-b border-card-background-separator focus:border-card-background-separator w-full"
|
||||||
@keydown.up.prevent="moveHighlightUp"
|
placeholder="Search for a Tag..."
|
||||||
@keydown.down.prevent="moveHighlightDown" />
|
@input="updateSearchValue"
|
||||||
<div ref="dropdownViewport" class="w-60 max-h-60 overflow-y-scroll">
|
@keydown.enter="addTagIfNoneExists"
|
||||||
<div
|
@keydown.up.prevent="moveHighlightUp"
|
||||||
v-for="tag in filteredTags"
|
@keydown.down.prevent="moveHighlightDown" />
|
||||||
:key="tag.id"
|
<div ref="dropdownViewport" class="w-60 max-h-60 overflow-y-scroll">
|
||||||
role="option"
|
<div
|
||||||
:value="tag.id"
|
v-for="tag in filteredTags"
|
||||||
:class="{
|
:key="tag.id"
|
||||||
|
role="option"
|
||||||
|
:value="tag.id"
|
||||||
|
:class="{
|
||||||
'bg-card-background-active':
|
'bg-card-background-active':
|
||||||
tag.id === highlightedItemId,
|
tag.id === highlightedItemId,
|
||||||
}"
|
}"
|
||||||
data-testid="tag_dropdown_entries"
|
data-testid="tag_dropdown_entries"
|
||||||
:data-tag-id="tag.id">
|
:data-tag-id="tag.id">
|
||||||
<MultiselectDropdownItem
|
<MultiselectDropdownItem
|
||||||
:selected="isTagSelected(tag.id)"
|
:selected="isTagSelected(tag.id)"
|
||||||
:name="tag.name"
|
:name="tag.name"
|
||||||
@click="toggleTag(tag.id)"></MultiselectDropdownItem>
|
@click="toggleTag(tag.id)"></MultiselectDropdownItem>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="hover:bg-card-background-active rounded-b-lg">
|
||||||
<div class="hover:bg-card-background-active rounded-b-lg">
|
<button
|
||||||
<button
|
class="text-white w-full flex space-x-3 items-center px-4 py-3 text-xs font-semibold border-t border-card-background-separator"
|
||||||
class="text-white w-full flex space-x-3 items-center px-4 py-3 text-xs font-semibold border-t border-card-background-separator"
|
@click="
|
||||||
@click="
|
|
||||||
open = false;
|
open = false;
|
||||||
showCreateTagModal = true;
|
showCreateTagModal = true;
|
||||||
">
|
">
|
||||||
<PlusCircleIcon
|
<PlusCircleIcon
|
||||||
class="w-5 flex-shrink-0 text-icon-default"></PlusCircleIcon>
|
class="w-5 flex-shrink-0 text-icon-default"></PlusCircleIcon>
|
||||||
<span>Create new Tag</span>
|
<span>Create new Tag</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</UseFocusTrap>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user