lenso.ai-face-search / src /components /PluginSearchInput.vue
szafran98's picture
initial commit
8a1f4e2
<script setup lang="ts">
import { ref, defineProps, defineEmits } from 'vue';
import useSnackbar from "@plugin/composables/snackbar.ts";
const props = defineProps({
showButtonText: {
type: Boolean,
default: false,
},
modelValue: {
type: String,
default: '',
},
});
const emit = defineEmits(['update:modelValue', 'on-submit']);
const { createNotification } = useSnackbar();
const textInput = ref<HTMLInputElement | null>(null);
function updateValue(event: Event) {
const value = (event.target as HTMLInputElement)?.value;
validateTextLength(value);
validateTextIsNotUrl(value);
emit('update:modelValue', value);
}
const validateTextIsNotUrl = (value: string): Boolean => {
const urlPattern = /^(https?:\/\/)?([\w\-]+\.)+[\w\-]{2,}(\/[\w\-._~:/?#[\]@!$&'()*+,;=%]*)?$/i;
if (urlPattern.test(value)) {
createNotification({
message: 'Please use only keywords for text search. URLs are not allowed.',
type: 'error',
});
return false;
}
return true;
}
function validateTextLength(value: string): boolean {
if (value.length >= 256) {
createNotification({
message: 'You have reached the maximum number of allowed characters for text search (256).',
type: 'info',
})
return false;
}
return true;
}
function validateTextNotEmpty(value: string): boolean {
if (value.length === 0) {
createNotification({
message: 'Please type in the text search prompt to proceed',
type: 'warning',
});
return false;
}
return true;
}
const onEnter = (e: Event): void => {
if (!validateTextIsNotUrl(props.modelValue)) {
return;
}
if (!validateTextNotEmpty(props.modelValue)) {
return;
}
emit('on-submit');
}
</script>
<template>
<div class="search-input" >
<input
ref="textInput"
:value="modelValue"
@input="updateValue"
v-bind="$attrs"
@keydown.enter="onEnter"
placeholder="or type to search"
maxlength="256"
/>
<button @click="onEnter" :with-text="showButtonText">
<svg class="app-svg-icon" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.5 17.5L13.875 13.875M15.8333 9.16667C15.8333 12.8486 12.8486 15.8333 9.16667 15.8333C5.48477 15.8333 2.5 12.8486 2.5 9.16667C2.5 5.48477 5.48477 2.5 9.16667 2.5C12.8486 2.5 15.8333 5.48477 15.8333 9.16667Z" stroke="#8586AD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span v-if="showButtonText"> Search </span>
</button>
</div>
</template>
<style scoped lang="scss">
@import "@/assets/mixins";
@import '@plugin/assets/main.scss';
@import '@plugin/assets/_variables_override.scss';
.search-input {
display: flex;
height: 48px;
width: 100%;
color: $primary-400;
button {
padding: 0px;
@include tertiary-icon-only;
border: unset;
border-radius: 0px 6px 6px 0px;
border: 1px solid $main-50;
color: inherit;
&[with-text="true"] {
padding:12px 24px;
span {
color: inherit;
}
}
}
input {
@include input;
border: 1px solid $main-50;
border-radius: 6px 0px 0px 6px;
padding: 12px 16px;
&:disabled {
background-color: dimgrey;
color: linen;
opacity: 1;
}
}
}
</style>