Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Refactor VSearchButton #1961

Merged
merged 2 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 5 additions & 22 deletions src/components/VFourOhFour.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</template>
</i18n>
</p>
<VStandaloneSearchBarOld route="404" @submit="handleSearch" />
<VStandaloneSearchBar route="404" @submit="handleSearch" />
</div>
</main>

Expand All @@ -58,7 +58,7 @@ import { useFeatureFlagStore } from '~/stores/feature-flag'

import { ALL_MEDIA, searchPath } from '~/constants/media'

import VStandaloneSearchBarOld from '~/components/VHeaderOld/VSearchBar/VStandaloneSearchBarOld.vue'
import VStandaloneSearchBar from '~/components/VHeader/VSearchBar/VStandaloneSearchBar.vue'
import VLink from '~/components/VLink.vue'
import VBrand from '~/components/VBrand/VBrand.vue'
import VFooter from '~/components/VFooter/VFooter.vue'
Expand All @@ -69,7 +69,7 @@ export default defineComponent({
name: 'VFourOhFour',
components: {
VLink,
VStandaloneSearchBarOld,
VStandaloneSearchBar,
VBrand,
VFooter,
},
Expand All @@ -82,13 +82,13 @@ export default defineComponent({
const handleSearch = async (searchTerm) => {
if (!searchTerm) return

searchStore.setSearchTerm(searchTerm.value)
searchStore.setSearchTerm(searchTerm)
searchStore.setSearchType(ALL_MEDIA)

router.push(
app.localePath({
path: searchPath(ALL_MEDIA),
query: { q: searchTerm.value },
query: { q: searchTerm },
})
)
}
Expand All @@ -113,20 +113,3 @@ export default defineComponent({
},
})
</script>

<style>
/* Override the default search bar styles.
Maybe in the future this would warrant a
variant of the searchbar, but that seems
excessive for this one-off usage.
*/
.page-404 .search-bar > div:not(:focus):not(:focus-within) {
border-color: black;
}
.page-404
.search-bar:not(:hover)
button:not(:hover):not(:focus):not(:focus-within) {
border-color: black;
border-inline-start-color: transparent;
}
</style>
38 changes: 7 additions & 31 deletions src/components/VHeader/VSearchBar/VSearchBar.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
<template>
<div ref="searchBarEl" class="relative">
<form
class="search-bar group flex flex-row items-center rounded-sm border-tx bg-white"
:class="{ 'h-[57px] md:h-[69px]': size === 'standalone' }"
class="search-bar group flex h-12 flex-row items-center rounded-sm border-tx bg-white"
@submit.prevent="handleSearch"
>
<VInputField
ref="inputFieldRef"
v-bind="$attrs"
v-model="modelMedium"
:placeholder="placeholder || $t('hero.search.placeholder')"
class="search-field flex-grow focus:border-pink"
:class="[
route === 'home'
? 'border-tx'
: 'border-tx bg-dark-charcoal-10 text-dark-charcoal-70 focus-within:bg-white group-hover:bg-dark-charcoal-10 group-hover:text-dark-charcoal group-hover:focus-within:bg-white',
]"
class="search-field flex-grow border-tx bg-dark-charcoal-10 text-dark-charcoal-70 focus-within:bg-white focus:border-pink group-hover:bg-dark-charcoal-10 group-hover:text-dark-charcoal group-hover:focus-within:bg-white"
:label-text="
$t('search.search-bar-label', { openverse: 'Openverse' }).toString()
"
Expand All @@ -41,7 +35,7 @@
<VSearchButton
type="submit"
:size="size"
:route="route"
route="search"
@keydown.tab="handleSearchBlur"
/>
</form>
Expand Down Expand Up @@ -70,7 +64,6 @@ import {

import { onClickOutside } from '@vueuse/core'

import { useMatchHomeRoute } from '~/composables/use-match-routes'
import { defineEvent } from '~/types/emits'

import { useSearchStore } from '~/stores/search'
Expand All @@ -87,6 +80,10 @@ import VSearchButton from '~/components/VHeader/VSearchBar/VSearchButton.vue'
import VRecentSearches from '~/components/VRecentSearches/VRecentSearches.vue'

/**
* The search bar displayed on the search page.
* TODO: remove the next line after new header is set as default
* Only on the search page with `new_header` flag on.
*
* Displays a text field for a search query and is attached to an action button
* that fires a search request. The loading state and number of hits are also
* displayed in the bar itself.
Expand All @@ -111,10 +108,6 @@ export default defineComponent({
type: String,
required: false,
},
is404: {
type: Boolean,
default: false,
},
},
emits: {
input: defineEvent<[string]>(),
Expand All @@ -124,12 +117,6 @@ export default defineComponent({
const searchBarEl = ref<HTMLElement | null>(null)
const inputFieldRef = ref<InstanceType<typeof VInputField> | null>(null)

const { matches: isHomeRoute } = useMatchHomeRoute()

const route = computed(() => {
return isHomeRoute?.value ? 'home' : props.is404 ? '404' : undefined
})

const modelMedium = computed<string>({
get: () => props.value ?? '',
set: (value: string) => {
Expand Down Expand Up @@ -253,7 +240,6 @@ export default defineComponent({
inputFieldRef,

handleSearch,
route,
modelMedium,

showRecentSearches,
Expand All @@ -273,13 +259,3 @@ export default defineComponent({
},
})
</script>

<style>
/* Removes the cross icon to clear the field */
.search-field input[type='search']::-webkit-search-decoration,
.search-field input[type='search']::-webkit-search-cancel-button,
.search-field input[type='search']::-webkit-search-results-button,
.search-field input[type='search']::-webkit-search-results-decoration {
-webkit-appearance: none;
}
</style>
76 changes: 33 additions & 43 deletions src/components/VHeader/VSearchBar/VSearchButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
v-bind="$attrs"
:aria-label="$t('search.search')"
size="disabled"
:variant="isIcon ? 'plain' : 'primary'"
class="flex-shrink-0 text-2xl font-semibold transition-none rounded-s-none hover:bg-pink hover:text-white focus-visible:ring focus-visible:ring-pink"
:variant="route === 'home' ? 'primary' : 'plain'"
class="heading-6 h-full flex-shrink-0 transition-none rounded-s-none"
:class="[
isIcon
? 'search-button ps-[1.5px] p-[0.5px] focus-visible:bg-pink focus-visible:text-white'
: 'h-full whitespace-nowrap py-6 px-10',
sizeClasses,
route === 'home'
? 'border-b border-tx border-b-pink bg-pink text-white group-hover:border-pink group-hover:bg-pink group-hover:text-white'
: 'border-tx bg-dark-charcoal-10 group-focus-within:bg-pink group-focus-within:text-white group-focus-within:hover:bg-dark-pink',
? 'w-[57px] whitespace-nowrap md:w-auto md:py-6 md:px-10'
: 'search-button p-0.5px ps-1.5px hover:bg-pink hover:text-white focus-visible:bg-pink focus-visible:text-white group-focus-within:border-pink group-focus-within:bg-pink group-focus-within:text-white group-focus-within:hover:bg-dark-pink group-hover:border-pink group-hover:bg-pink group-hover:text-white',
{
'w-10 bg-dark-charcoal-10 md:w-12': route === 'search',
'border-black focus:border-tx group-focus-within:border-tx group-hover:border-tx group-focus:border-tx':
route === '404',
},
sizeClasses,
]"
v-on="$listeners"
>
Expand All @@ -36,7 +38,11 @@ import VButton from '~/components/VButton.vue'
import type { FieldSize } from '~/components/VInputField/VInputField.vue'

import searchIcon from '~/assets/icons/search.svg'

/**
* The search button used in the search bar on the homepage and on the 404 page,
* and on the search page.
* TODO: remove when `new_header` is default: only on the search page with the `new_header`.
*/
export default defineComponent({
name: 'VSearchButton',
components: { VIcon, VButton },
Expand All @@ -47,57 +53,41 @@ export default defineComponent({
required: true,
},
route: {
type: String as PropType<'home' | '404'>,
validator: (v: string) => ['home', '404'].includes(v),
type: String as PropType<'home' | '404' | 'search'>,
validator: (v: string) => ['home', '404', 'search'].includes(v),
},
},
setup(props) {
const isMobile = useBrowserIsMobile()

const isMinScreenMd = isMinScreen('md', { shouldPassInSSR: !isMobile })

const isIcon = computed(() => {
// split the evaluation of the isMinScreenMd ref
// out to prevent short-circuiting from creating
// problems with `computed`'s dependency detection
const currentIsMinScreenMd = isMinScreenMd.value
/**
* The search button has a text label on the homepage on screen larger than `md`,
* everywhere else it has an icon.
*/
const isIcon = computed(
() => !(props.route === 'home' && isMinScreenMd.value)
)

return (
props.route === '404' ||
props.size !== 'standalone' ||
(props.size === 'standalone' && !currentIsMinScreenMd)
)
})

const sizeClasses = computed(() => {
return isIcon.value
const sizeClasses = computed(() =>
isIcon.value
? {
small: 'w-10 md:w-12 h-10 md:h-12',
medium: 'w-12 h-12',
large: 'w-14 h-14',
standalone: 'w-[57px] md:w-[69px] h-[57px] md:h-[69px]',
small: 'w-10 md:w-12',
medium: 'w-12',
large: 'w-14',
standalone: 'w-[57px] md:w-[69px]',
}[props.size]
: undefined
})
)

return { isMinScreenMd, searchIcon, sizeClasses, isIcon }
return { searchIcon, sizeClasses, isIcon }
},
})
</script>

<style scoped>
.search-button {
/* Negative margin removes a tiny gap between the button and the input borders */
margin-inline-start: -1px;
border-inline-start-color: transparent;
border-width: 1px;
}
.search-button.search-button:not(:hover):not(:focus):not(:focus-within) {
border-inline-start-color: transparent;
border-width: 1px;
}
.search-button.search-button:hover {
border-inline-start-color: rgba(214, 212, 213, 1);
border-width: 1px;
border-inline-start-width: 0;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
@submit.prevent="handleSearch"
>
<div
class="input-field search-field group flex h-full flex-grow items-center overflow-hidden rounded-sm border p-0.5px pe-1.5px rounded-e-none border-e-0 focus-within:border-1.5 focus-within:border-pink focus-within:bg-dark-charcoal-06 focus-within:p-0 group-hover:bg-dark-charcoal-06"
:class="[isHomeRoute ? 'border-tx' : 'border-dark-charcoal-20']"
class="input-field search-field group flex h-full flex-grow items-center overflow-hidden rounded-sm border p-0.5px pe-1.5px rounded-e-none border-e-0 focus-within:border-1.5 focus-within:border-pink focus-within:bg-dark-charcoal-06 focus-within:p-0 focus-within:pe-1.5px group-hover:bg-dark-charcoal-06"
:class="[isHomeRoute ? 'border-tx' : 'border-black']"
>
<input
id="search-bar"
Expand All @@ -29,7 +29,7 @@
<!-- @slot Extra information goes here -->
<slot />
</div>
<VSearchButtonOld type="submit" size="standalone" :route="route" />
<VSearchButton type="submit" size="standalone" :route="route" />
</form>
</template>

Expand All @@ -43,7 +43,7 @@ import {

import { defineEvent } from '~/types/emits'

import VSearchButtonOld from '~/components/VHeaderOld/VSearchBar/VSearchButtonOld.vue'
import VSearchButton from '~/components/VHeader/VSearchBar/VSearchButton.vue'

/**
* Displays a search input for a search query and is attached to an action button
Expand All @@ -53,23 +53,26 @@ import VSearchButtonOld from '~/components/VHeaderOld/VSearchBar/VSearchButtonOl
* is not removed.
*/
export default defineComponent({
name: 'VStandaloneSearchBarOld',
components: { VSearchButtonOld },
name: 'VStandaloneSearchBar',
components: { VSearchButton },
props: {
route: {
type: String as PropType<'home' | '404'>,
default: 'home',
},
},
emits: {
submit: defineEvent(),
submit: defineEvent<[string]>(),
},
setup(props, { emit }) {
const inputRef = ref<HTMLInputElement | null>(null)

// Only emit `submit` if the input value is not blank
const handleSearch = () => {
const searchTerm = inputRef.value?.value.trim()
emit('submit', searchTerm)
if (searchTerm) {
emit('submit', searchTerm)
}
}

const isHomeRoute = computed(() => props.route === 'home')
Expand All @@ -82,3 +85,8 @@ export default defineComponent({
},
})
</script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a blank line. Maybe we should add a lint rule that ensures this.

<style scoped>
.input-field {
border-inline-end-width: 0;
}
</style>
6 changes: 1 addition & 5 deletions src/components/VHeaderOld/VSearchBar/VSearchBarOld.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@
<!-- @slot Extra information such as loading message or result count goes here. -->
<slot />
</VInputFieldOld>
<VSearchButtonOld
type="submit"
:size="size"
:route="is404 ? '404' : undefined"
/>
<VSearchButtonOld type="submit" :size="size" />
</form>
</template>

Expand Down
Loading