initial: bootstrap from BukidBountyApp base
This commit is contained in:
130
resources/js/Components/Core/Search/SearchBar.vue
Normal file
130
resources/js/Components/Core/Search/SearchBar.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="box-search mt-3">
|
||||
<div class="input-field">
|
||||
<!-- Left icon - only show one -->
|
||||
<IconImage v-if="leftIcon" :src="leftIcon" :width="iconWidth" :height="iconHeight" />
|
||||
<i v-else class="fas fa-search search-icon"></i>
|
||||
|
||||
<input
|
||||
:id="id"
|
||||
class="search-field value_input"
|
||||
:placeholder="placeholder"
|
||||
type="text"
|
||||
:value="modelValue"
|
||||
@input="$emit('update:modelValue', $event.target.value)"
|
||||
/>
|
||||
<i
|
||||
v-if="modelValue"
|
||||
class="fas fa-times clear-icon"
|
||||
:id="`clear-${id}`"
|
||||
@click="$emit('update:modelValue', ''); $emit('clear')"
|
||||
></i>
|
||||
</div>
|
||||
<!-- Right icon -->
|
||||
<IconImage
|
||||
v-if="rightIcon"
|
||||
:src="rightIcon"
|
||||
:width="iconWidth"
|
||||
:height="iconHeight"
|
||||
:id="`${id}-rightsearchicon`"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import IconImage from '../IconImage.vue'
|
||||
|
||||
defineProps({
|
||||
id: { type: String, default: 'search' },
|
||||
placeholder: { type: String, default: 'Search' },
|
||||
modelValue: { type: String, default: '' },
|
||||
leftIcon: { type: String, default: '' },
|
||||
rightIcon: { type: String, default: '' },
|
||||
iconWidth: { type: [String, Number], default: 30 },
|
||||
iconHeight: { type: [String, Number], default: 30 },
|
||||
})
|
||||
|
||||
defineEmits(['update:modelValue', 'clear'])
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.box-search {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--bg-secondary, #f5f5f5);
|
||||
border-radius: 12px;
|
||||
padding: 10px 16px;
|
||||
gap: 10px;
|
||||
border: 1px solid var(--border-color, rgba(0, 0, 0, 0.08));
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.input-field:focus-within {
|
||||
border-color: var(--accent-color, #533dea);
|
||||
box-shadow: 0 0 0 3px var(--accent-soft, rgba(83, 61, 234, 0.1));
|
||||
}
|
||||
|
||||
.search-field {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-primary, #1e1e1e);
|
||||
outline: none;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.search-field::placeholder {
|
||||
color: var(--text-muted, #a0a0a0);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
color: var(--text-muted, #717171);
|
||||
font-size: 0.9rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.clear-icon {
|
||||
color: var(--text-muted, #717171);
|
||||
font-size: 0.85rem;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.clear-icon:hover {
|
||||
opacity: 1;
|
||||
color: var(--text-primary, #1e1e1e);
|
||||
}
|
||||
|
||||
/* Dark mode support */
|
||||
:global(.dark-mode) .input-field {
|
||||
background: var(--bg-secondary, #1a1c22);
|
||||
border-color: var(--border-color, rgba(255, 255, 255, 0.08));
|
||||
}
|
||||
|
||||
:global(.dark-mode) .search-field {
|
||||
color: var(--text-primary, #e0e0e0);
|
||||
}
|
||||
|
||||
:global(.dark-mode) .search-icon {
|
||||
color: var(--text-muted, #b0b0b0);
|
||||
}
|
||||
|
||||
:global(.dark-mode) .clear-icon {
|
||||
color: var(--text-muted, #b0b0b0);
|
||||
}
|
||||
|
||||
:global(.dark-mode) .clear-icon:hover {
|
||||
color: var(--text-primary, #e0e0e0);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user