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

Commit

Permalink
Add homepage content switcher (#2087)
Browse files Browse the repository at this point in the history
* Add the new homepage content switcher

* Remove focus outline when popover is open

* Use buttons instead of <a> for popover

* Remove VItem border to match the mockups

* Make the content switcher modal top rounded

* Fix popover width; modal tab button

* Add width prop to VPopover

* Simplify vertical spacing

* Fix search type button outer spacing
  • Loading branch information
obulat authored Jan 17, 2023
1 parent 8df7307 commit 7da02a7
Show file tree
Hide file tree
Showing 97 changed files with 272 additions and 67 deletions.
3 changes: 2 additions & 1 deletion src/components/VContentSwitcher/VSearchTypePopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
ref="contentMenuPopover"
:label="$t('search-type.label').toString()"
placement="bottom-end"
width="w-66"
:clippable="true"
>
<template #trigger="{ a11yProps }">
<VSearchTypeButton
id="search-type-button"
v-bind="{ ...a11yProps, ...searchTypeProps }"
:show-label="showLabel"
aria-controls="content-switcher-popover"
/>
</template>
<VSearchTypes
id="content-switcher-popover"
class="w-[260px] pt-2"
size="small"
:use-links="placement === 'header'"
@select="handleSelect"
Expand Down
14 changes: 3 additions & 11 deletions src/components/VContentSwitcher/VSearchTypes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@
:size="size"
:bordered="bordered"
type="radiogroup"
class="z-10"
:class="{ 'w-[260px]': size === 'small' }"
:class="{ 'w-66': size === 'small' }"
>
<div
v-for="(category, index) in contentTypeGroups"
:key="index"
class="flex flex-col"
:class="{
'mt-2': index > 0,
'border-t border-dark-charcoal-20 bg-dark-charcoal-06':
index > 0 && !bordered,
'gap-1': size === 'small',
'w-66 gap-1 py-2': size === 'small',
}"
>
<h4
v-if="index !== 0"
:class="bordered ? 'ps-0' : 'ps-6'"
class="category pt-6 pb-4 uppercase pe-6"
class="category pt-6 pb-4"
>
{{ $t(`search-type.${category.heading}`) }}
</h4>
Expand All @@ -33,12 +31,6 @@
:size="size"
:icon="content.icons[item]"
:use-links="useLinks"
:class="{
'mb-2':
idx === category.items.length - 1 &&
((contentTypeGroups.length > 1 && index !== 0) ||
contentTypeGroups.length === 1),
}"
:selected="isActive(item)"
@click="selectItem(item)"
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/VContentSwitcherOld/VMobileMenuModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
>
<VSearchTypesOld
ref="searchTypesRef"
size="small"
size="medium"
:active-item="content.activeType.value"
:use-links="true"
@select="selectItem"
Expand Down
3 changes: 2 additions & 1 deletion src/components/VContentSwitcherOld/VSearchTypePopoverOld.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
class="flex items-stretch"
:label="$t('search-type.label').toString()"
placement="bottom-end"
width="w-66"
:clippable="true"
>
<template #trigger="{ a11yProps }">
Expand All @@ -16,7 +17,7 @@
</template>
<VSearchTypesOld
id="content-switcher-popover"
size="medium"
size="small"
:active-item="activeItem"
:use-links="placement === 'header'"
@select="selectItem"
Expand Down
13 changes: 7 additions & 6 deletions src/components/VContentSwitcherOld/VSearchTypesOld.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
:size="size"
:bordered="bordered"
type="radiogroup"
class="z-10 max-w-full md:w-[260px]"
:class="{ 'w-66 pt-2': size === 'small' }"
>
<div
v-for="(category, index) in contentTypeGroups"
Expand All @@ -13,18 +13,19 @@
'mt-2': index > 0,
'border-t border-dark-charcoal-20 bg-dark-charcoal-06':
index > 0 && !bordered,
'w-66': size === 'small',
}"
>
<h4
:class="bordered ? 'ps-0' : 'ps-6'"
class="pt-6 pb-4 text-sr font-semibold uppercase pe-6"
class="category pt-6 pb-4 text-sr"
>
{{ $t(`search-type.${category.heading}`) }}
</h4>
<VSearchTypeItemOld
v-for="(item, idx) in category.items"
:key="item"
class="md:mb-1"
:class="{ 'mb-1': size === 'small' }"
:item="item"
:item-id="idx"
:icon="content.icons[item]"
Expand All @@ -50,8 +51,8 @@ export default defineComponent({
components: { VItemGroup, VSearchTypeItemOld },
props: {
/**
* 'Small' size for mobile screens,
* 'medium' size for larger screens.
* 'Small' size for popovers on larger screens,
* 'medium' size for modals on mobile screens.
*/
size: {
type: String as PropType<"small" | "medium">,
Expand Down Expand Up @@ -90,7 +91,7 @@ export default defineComponent({
return base
})
const bordered = computed(() => props.size === "small")
const bordered = computed(() => props.size === "medium")
const handleClick = (item) => {
emit("select", item)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
:hide-on-click-outside="true"
:hide="close"
:visible="visible"
variant="two-thirds"
:variant="showFilters ? 'two-thirds' : 'fit-content'"
class="flex items-center"
>
<VTabs
Expand All @@ -16,10 +16,21 @@
@change="changeSelectedTab"
>
<template #tabs>
<VTab id="content-settings" size="medium" class="category me-4">{{
$t("search-type.heading")
}}</VTab>
<VTab id="filters" size="medium" class="category">{{
<VTab
v-if="showFilters"
id="content-settings"
size="medium"
class="category me-4"
>{{ $t("search-type.heading") }}</VTab
>
<h2
v-else
class="label-regular relative my-2 flex h-12 items-center gap-x-2 px-2 me-4 after:absolute after:right-1/2 after:bottom-[-0.625rem] after:h-0.5 after:w-full after:translate-x-1/2 after:translate-y-[-50%] after:bg-dark-charcoal"
>
<VIcon :icon-path="searchType.icon" />
{{ $t("search-type.heading") }}
</h2>
<VTab v-if="showFilters" id="filters" size="medium" class="category">{{
$t("filters.title")
}}</VTab>
<VIconButton
Expand All @@ -30,16 +41,21 @@
/>
</template>
<VTabPanel id="content-settings">
<VSearchTypes size="medium" :use-links="true" />
<VSearchTypes
size="medium"
:use-links="useLinks"
@select="$emit('select', $event)"
/>
</VTabPanel>
<VTabPanel id="filters">
<VTabPanel v-if="showFilters" id="filters">
<VSearchGridFilter
:show-filter-header="false"
:change-tab-order="false"
/>
</VTabPanel>
</VTabs>
<footer
v-if="showFilters"
class="mt-auto flex h-20 flex-shrink-0 items-center justify-between border-t border-t-dark-charcoal-20 px-6 py-4"
>
<VButton
Expand All @@ -59,10 +75,12 @@ import { computed, defineComponent, ref } from "@nuxtjs/composition-api"
import { useSearchStore } from "~/stores/search"
import { useI18n } from "~/composables/use-i18n"
import useSearchType from "~/composables/use-search-type"
import VButton from "~/components/VButton.vue"
import VModalContent from "~/components/VModal/VModalContent.vue"
import VIcon from "~/components/VIcon/VIcon.vue"
import VIconButton from "~/components/VIconButton/VIconButton.vue"
import VModalContent from "~/components/VModal/VModalContent.vue"
import VSearchGridFilter from "~/components/VFilters/VSearchGridFilter.vue"
import VSearchTypes from "~/components/VContentSwitcher/VSearchTypes.vue"
import VShowResultsButton from "~/components/VHeader/VHeaderMobile/VShowResultsButton.vue"
Expand All @@ -75,6 +93,7 @@ import closeIcon from "~/assets/icons/close-small.svg"
export default defineComponent({
name: "VContentSettingsModalContent",
components: {
VIcon,
VModalContent,
VButton,
VIconButton,
Expand All @@ -98,10 +117,20 @@ export default defineComponent({
type: Boolean,
default: false,
},
showFilters: {
type: Boolean,
default: true,
},
useLinks: {
type: Boolean,
default: true,
},
},
setup() {
setup(props) {
const i18n = useI18n()
const searchStore = useSearchStore()
const content = useSearchType()
const selectedTab = ref<"content-settings" | "filters">("content-settings")
const changeSelectedTab = (tab: "content-settings" | "filters") => {
selectedTab.value = tab
Expand All @@ -110,24 +139,29 @@ export default defineComponent({
const areFiltersSelected = computed(() => searchStore.isAnyFilterApplied)
const showClearFiltersButton = computed(
() => selectedTab.value === "filters"
() => props.showFilters && selectedTab.value === "filters"
)
const isClearButtonDisabled = computed(
() => !searchStore.isAnyFilterApplied
)
const appliedFilterCount = computed(() => searchStore.appliedFilterCount)
const clearFiltersLabel = computed(() =>
searchStore.isAnyFilterApplied
? i18n.tc("filter-list.clear-numbered", appliedFilterCount.value)
? i18n.t("filter-list.clear-numbered", {
number: appliedFilterCount.value,
})
: i18n.t("filter-list.clear")
)
const searchType = computed(() => content.getSearchTypeProps())
const clearFilters = () => {
searchStore.clearFilters()
}
return {
closeIcon,
searchType,
selectedTab,
changeSelectedTab,
Expand Down
16 changes: 13 additions & 3 deletions src/components/VHeader/VSearchBar/VStandaloneSearchBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
@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 focus-within:pe-1.5px group-hover:bg-dark-charcoal-06"
:class="[isHomeRoute ? 'border-tx' : 'border-black']"
class="input-field search-field group flex h-full flex-grow items-center overflow-hidden rounded-sm border p-0.5px pe-2 rounded-e-none border-e-0 focus-within:border-1.5 focus-within:p-0 focus-within:pe-2 focus-within:border-e-0"
:class="[
isHomeRoute ? 'border-tx' : 'border-black',
hasPopover ? 'focus-within:border-tx' : 'focus-within:border-pink',
]"
>
<input
id="search-bar"
Expand Down Expand Up @@ -36,7 +39,7 @@
:variant="isHomeRoute ? 'primary' : 'plain'"
class="h-full w-14 flex-shrink-0 transition-none rounded-s-none sm:w-16"
:class="{
'search-button border-black p-0.5px ps-1.5px hover:bg-pink hover:text-white focus:border-tx focus-visible:bg-pink focus-visible:text-white group-focus-within:border-pink group-focus-within:border-tx group-focus-within:bg-pink group-focus-within:text-white group-focus-within:hover:bg-dark-pink group-hover:border-pink group-hover:border-tx group-hover:bg-pink group-hover:text-white group-focus:border-tx':
'search-button border-black p-0.5px ps-1.5px hover:bg-pink hover:text-white focus:border-tx focus-visible:bg-pink focus-visible:text-white group-focus-within:border-tx group-focus-within:bg-pink group-focus-within:text-white group-focus-within:hover:bg-dark-pink group-hover:border-tx group-hover:bg-pink group-hover:text-white group-focus:border-tx':
!isHomeRoute,
}"
>
Expand Down Expand Up @@ -75,6 +78,13 @@ export default defineComponent({
type: String as PropType<"home" | "404">,
default: "home",
},
/**
* Search bar should not have a focus box when a popover is open.
*/
hasPopover: {
type: Boolean,
default: false,
},
},
emits: {
submit: defineEvent<[string]>(),
Expand Down
6 changes: 3 additions & 3 deletions src/components/VHeader/meta/VContentSettingsModal.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ export const Template = (args) => ({
},
})

# VContentSettingsModal
# VContentSettingsModalContent

<Description of={VContentSettingsModal} />
<Description of={VContentSettingsModalContent} />

<ArgsTable of={VContentSettingsModal} />
<ArgsTable of={VContentSettingsModalContent} />

<Canvas>
<Story height="480px" name="Default">
Expand Down
Loading

0 comments on commit 7da02a7

Please sign in to comment.