<scriptsetuplang="ts">import{IconX,typeIcon}from"@tabler/icons-vue";importFilterPillfrom"components/Filter/FilterPill.vue";import{ref}from"vue";constprops=defineProps<{modelValue:string[];label:string;placeholder?:string;title?:string;inputClass?:string;validateRegex?:RegExp;icon?:Icon;}>();constemit=defineEmits<{(e:"update:modelValue",value:string[]):void;(e:"change"):void;}>();constinputValue=ref("");consterror=ref(false);// This flag determines if we have ever errored, to start live checks
consterrorTriggered=ref(false);functioncheckError(){if(!props.validateRegex){error.value=false;return;}// check all current comma-separated parts for regex validity
constval=inputValue.value;constparts=val.split(",").map((s)=>s.trim()).filter(Boolean);if(parts.length===0){error.value=false;return;}error.value=!parts.every((p)=>props.validateRegex!.test(p));}functiononInputChange(){constval=inputValue.value;if(!val)return;constparts=val.split(",").map((s)=>s.trim()).filter(Boolean);if(props.validateRegex&&!parts.every((p)=>props.validateRegex!.test(p))){error.value=true;errorTriggered.value=true;return;}if(parts.length>0){emit("update:modelValue",[...newSet([...props.modelValue,...parts])]);emit("change");// Reset error validation after a valid input
error.value=false;errorTriggered.value=false;inputValue.value="";return;}error.value=false;inputValue.value="";}functionhandleInput(){if(errorTriggered.value){checkError();}if(inputValue.value.includes(",")){onInputChange();}}functionremoveValue(value:string){emit("update:modelValue",props.modelValue.filter((v)=>v!==value),);emit("change");}</script><template><divclass="flex items-center gap-2"><spanclass="filter-label"><component:is="icon"size="16"/>{{label}}:</span><divclass="relative flex items-center gap-1"><inputtype="text"v-model="inputValue"@input="handleInput"@keypress.enter="onInputChange"@blur="onInputChange":placeholder="placeholder":class="[inputClass || 'w-48 pr-5', { 'border-red-500': error }]"/><buttonv-if="inputValue.length > 0"@mousedown.prevent@click="inputValue = ''"class="absolute top-1 right-1 text-stone-500 hover:text-stone-300":title="`Clear ${label.toLowerCase()} input`"><IconXsize="16"/></button></div><divclass="flex flex-wrap items-center"v-if="modelValue.length > 0"><FilterPillv-for="value in modelValue":key="value":label="value"@click="removeValue(value)"/></div></div></template>