Repository: directus/directus
File: app/src/interfaces/tags/tags.vue (Vue)

Code before:
	if (!tag || tag === '') return;
	// Remove any leading / trailing whitespace from the value
	tag = tag.trim();
	// Convert the tag to lowercase
	selectedValsLocal.value.push(tag);
	emitValue();
}

function removeTag(tag: string) {
	selectedValsLocal.value = selectedValsLocal.value.filter((savedTag) => savedTag !== tag);
	emitValue();
}

function emitValue() {
	emit('input', selectedVals.value);
}

function clearVariable() {
	isVariableMode.value = false;
	emit('input', null);
}
</script>

<template>
	<div class="interface-tags">
		<VInput v-if="isVariableMode" :model-value="value as string" readonly>
			<template #append>
				<span class="remove-variable">
					<VIcon v-tooltip="$t('interfaces.tags.remove_variable')" name="close" clickable @click.stop="clearVariable" />
				</span>
			</template>
		</VInput>
		<VInput
			v-else-if="allowCustom"
			:placeholder="placeholder || $t('interfaces.tags.add_tags')"
			:disabled
			:non-editable
			:dir="direction"
			@keydown="onInput"
			@blur="onInput"
		>
			<template v-if="iconLeft" #prepend><VIcon :name="iconLeft" /></template>
			<template #append><VIcon :name="iconRight" /></template>
		</VInput>
		<div v-if="presetVals.length > 0 || customVals.length > 0" class="tags">
			<span v-if="presetVals.length > 0" class="presets tag-container">
				<VChip
					v-for="preset in presetVals"
					:key="preset"
					:class="['tag', { inactive: !selectedVals.includes(preset), 'non-editable': nonEditable }]"
					:disabled

Review comment (suggestion):
There is no readonly prop. Let’s ensure all properties we need are set.

```suggestion
		<VInput v-if="isVariableMode" :model-value="value" disabled non-editable :dir="direction">
```

Alternatively, we could set the condition on the props and templates directly instead of creating a separate VInput block. This way we avoid missing props and attributes.

Code after:
	// Remove any leading / trailing whitespace from the value
	tag = tag.trim();
	// Convert the tag to lowercase
	selectedValsLocal.value.push(tag);
	emitValue();
}

function removeTag(tag: string) {
	selectedValsLocal.value = selectedValsLocal.value.filter((savedTag) => savedTag !== tag);
	emitValue();
}

function emitValue() {
	emit('input', selectedVals.value);
}

function clearVariable() {
	emit('input', null);
}
</script>

<template>
	<div class="interface-tags">
		<VInput
			v-if="isVariableMode || allowCustom"
			:model-value="isVariableMode ? (value as string) : undefined"
			:placeholder="placeholder || $t('interfaces.tags.add_tags')"
			:disabled="isVariableMode || disabled"
			:non-editable="isVariableMode || nonEditable"
			:dir="direction"
			@keydown="onInput"
			@blur="onInput"
		>
			<template v-if="iconLeft" #prepend><VIcon :name="iconLeft" /></template>
			<template #append>
				<VIcon
					v-if="isVariableMode"
					v-tooltip="$t('clear_value')"
					class="remove-variable"
					name="close"
					clickable
					:disabled
					@click.stop="clearVariable"
				/>
				<VIcon v-else :name="iconRight" />
			</template>
		</VInput>
		<div v-if="presetVals.length > 0 || customVals.length > 0" class="tags">
			<span v-if="presetVals.length > 0" class="presets tag-container">
				<VChip
					v-for="preset in presetVals"