owltide/components/SelectMultiEntity.vue

69 lines
1.4 KiB
Vue
Raw Permalink Normal View History

<!--
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div
class="select"
@focusin="dropdownComponent?.focusin()"
@focusout="dropdownComponent?.focusout()"
@keyup.esc="dropdownComponent?.esc()"
>
<div class="selected">
<div
v-for="id of selectedIds"
:key="id"
class="item"
>
{{ entities.get(id)?.name ?? id }}
<button
@click="selectedIds.delete(id)"
>x</button>
</div>
</div>
<SelectDropdown
ref="dropdown"
v-model="selectedIds"
:multi="true"
:entities
/>
</div>
</template>
<script lang="ts" setup>
import type { ApiEntity } from '~/shared/types/api';
import type { Id } from '~/shared/types/common';
import type { ClientEntity } from '~/utils/client-entity';
const selectedIds = defineModel<Set<Id>>({ required: true });
defineProps<{
entities: ClientMap<ClientEntity<ApiEntity> & { name?: string }>,
}>();
const dropdownComponent = useTemplateRef("dropdown");
</script>
<style scoped>
.select {
display: flex;
flex-wrap: wrap;
position: relative;
}
.selected {
display: flex;
flex-wrap: wrap;
gap: 0.2rem;
}
.item {
background-color: color-mix(in srgb, Canvas, CanvasText 10%);
border-radius: 0.3rem;
padding-inline: 0.2rem;
padding-block: 0.1rem;
margin-inline-end: 0.2rem;
white-space: pre-wrap;
}
.item button {
line-height: 0.7;
}
</style>