forked from noxious/client
47 lines
1.4 KiB
Vue
47 lines
1.4 KiB
Vue
<template>
|
|
<div class="flex flex-wrap items-center input-cyan gap-1">
|
|
<div v-for="(chip, i) in modelValue" :key="i" class="flex gap-2.5 items-center bg-cyan rounded py-1 px-2">
|
|
<span class="text-xs">{{ chip }}</span>
|
|
<button type="button" class="text-xs cursor-pointer text-white font-light font-default not-italic hover:text-gray-50" @click="deleteChip(i)" aria-label="Remove chip">X</button>
|
|
</div>
|
|
<input class="outline-none border-none p-1" placeholder="Tag name" v-model="currentInput" @keypress.enter.prevent="addChip" @keydown.backspace="handleBackspace" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import type { Ref } from 'vue'
|
|
|
|
interface Props {
|
|
modelValue: string[]
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:modelValue', value: string[]): void
|
|
}>()
|
|
|
|
const currentInput: Ref<string> = ref('')
|
|
|
|
const addChip = () => {
|
|
if (currentInput.value.trim() && !props.modelValue.includes(currentInput.value)) {
|
|
emit('update:modelValue', [...props.modelValue, currentInput.value.trim()])
|
|
currentInput.value = ''
|
|
}
|
|
}
|
|
|
|
const deleteChip = (index: number) => {
|
|
emit(
|
|
'update:modelValue',
|
|
props.modelValue.filter((_, i) => i !== index)
|
|
)
|
|
}
|
|
|
|
const handleBackspace = (event: KeyboardEvent) => {
|
|
if (event.key === 'Backspace' && currentInput.value === '' && props.modelValue.length > 0) {
|
|
emit('update:modelValue', props.modelValue.slice(0, -1))
|
|
}
|
|
}
|
|
</script>
|