forked from noxious/client
68 lines
1.9 KiB
Vue
68 lines
1.9 KiB
Vue
<template>
|
||
<div class="flex flex-wrap items-center input-cyan gap-1">
|
||
<div v-for="(chip, i) in internalValue" :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"
|
||
>
|
||
×
|
||
</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, watch } from 'vue'
|
||
import type { Ref } from 'vue'
|
||
|
||
interface Props {
|
||
modelValue?: string[]
|
||
}
|
||
|
||
const props = withDefaults(defineProps<Props>(), {
|
||
modelValue: () => []
|
||
})
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'update:modelValue', value: string[]): void
|
||
}>()
|
||
|
||
const currentInput: Ref<string> = ref('')
|
||
const internalValue = ref<string[]>([])
|
||
|
||
// Initialize internalValue with props.modelValue
|
||
watch(() => props.modelValue, (newValue) => {
|
||
internalValue.value = newValue ? [...newValue] : []
|
||
}, { immediate: true })
|
||
|
||
const addChip = () => {
|
||
const trimmedInput = currentInput.value.trim()
|
||
if (trimmedInput && !internalValue.value.includes(trimmedInput)) {
|
||
internalValue.value.push(trimmedInput)
|
||
emit('update:modelValue', internalValue.value)
|
||
currentInput.value = ''
|
||
}
|
||
}
|
||
|
||
const deleteChip = (index: number) => {
|
||
internalValue.value.splice(index, 1)
|
||
emit('update:modelValue', internalValue.value)
|
||
}
|
||
|
||
const handleBackspace = (event: KeyboardEvent) => {
|
||
if (event.key === 'Backspace' && currentInput.value === '' && internalValue.value.length > 0) {
|
||
internalValue.value.pop()
|
||
emit('update:modelValue', internalValue.value)
|
||
}
|
||
}
|
||
</script> |