NavbarTop
The NavbarTop block is used as navigation. Usually it's at the top of a page and has elements like company logo, links to main categories or a menu button, search input and action buttons that can open a cart, wishlist or login modal.
NavbarTop with white background
<template>
<header class="flex justify-center w-full py-2 px-4 lg:py-5 lg:px-6 bg-white border-b border-neutral-200">
<div class="flex flex-wrap lg:flex-nowrap items-center flex-row justify-start h-full max-w-[1536px] w-full">
<a
href="#"
aria-label="SF Homepage"
class="inline-block mr-4 focus-visible:outline focus-visible:outline-offset focus-visible:rounded-sm shrink-0"
>
<picture>
<source srcset="https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/vsf_logo.svg" media="(min-width: 768px)" />
<img
src="https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/vsf_logo_sign.svg"
alt="Sf Logo"
class="w-8 h-8 md:h-6 md:w-[176px] lg:w-[12.5rem] lg:h-[1.75rem]"
/>
</picture>
</a>
<SfButton aria-label="Open categories" class="lg:hidden order-first lg:order-1 mr-4" square variant="tertiary">
<SfIconMenu />
</SfButton>
<SfButton class="hidden lg:flex lg:mr-4" type="button" variant="tertiary">
<template #suffix>
<SfIconExpandMore class="hidden lg:block" />
</template>
<span class="hidden lg:flex whitespace-nowrap">Browse products</span>
</SfButton>
<form
role="search"
class="flex flex-[100%] order-last lg:order-3 mt-2 lg:mt-0 pb-2 lg:pb-0"
@submit.prevent="search"
>
<SfInput
v-model="inputValue"
type="search"
class="[&::-webkit-search-cancel-button]:appearance-none"
placeholder="Search"
wrapper-class="flex-1 h-10 pr-0"
size="base"
>
<template #suffix>
<span class="flex items-center">
<SfButton
variant="tertiary"
square
aria-label="search"
type="submit"
class="rounded-l-none hover:bg-transparent active:bg-transparent"
>
<SfIconSearch />
</SfButton>
</span>
</template>
</SfInput>
</form>
<nav class="flex-1 flex justify-end lg:order-last lg:ml-4">
<div class="flex flex-row flex-nowrap">
<SfButton
v-for="actionItem in actionItems"
:key="actionItem.ariaLabel"
class="mr-2 -ml-0.5 rounded-md text-primary-700 hover:bg-primary-100 active:bg-primary-200 hover:text-primary-600 active:text-primary-700"
:aria-label="actionItem.ariaLabel"
variant="tertiary"
square
>
<template #prefix>
<Component :is="actionItem.icon" />
</template>
<span v-if="actionItem.role === 'login'" class="hidden xl:inline-flex whitespace-nowrap">{{
actionItem.label
}}</span>
</SfButton>
</div>
</nav>
</div>
</header>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {
SfButton,
SfIconShoppingCart,
SfIconFavorite,
SfIconPerson,
SfIconExpandMore,
SfInput,
SfIconSearch,
SfIconMenu,
} from '@storefront-ui/vue';
const actionItems = [
{
icon: SfIconShoppingCart,
ariaLabel: 'Cart',
role: 'button',
label: '',
},
{
icon: SfIconFavorite,
ariaLabel: 'Wishlist',
role: 'button',
label: '',
},
{
label: 'Log in',
icon: SfIconPerson,
ariaLabel: 'Log in',
role: 'login',
},
];
const inputValue = ref('');
const search = () => {
alert(`Successfully found 10 results for ${inputValue.value}`);
};
</script>
NavbarTop with filled background
<template>
<header class="flex justify-center w-full py-2 px-4 lg:py-5 lg:px-6 bg-primary-700 border-b border-neutral-200">
<div class="flex flex-wrap lg:flex-nowrap items-center flex-row justify-start h-full max-w-[1536px] w-full">
<a
href="#"
aria-label="SF Homepage"
class="inline-block mr-4 focus-visible:outline focus-visible:outline-offset focus-visible:rounded-sm shrink-0"
>
<picture>
<source srcset="https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/vsf_logo_white.svg" media="(min-width: 768px)" />
<img
src="https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/vsf_logo_sign_white.svg"
alt="Sf Logo"
class="w-8 h-8 md:h-6 md:w-[176px] lg:w-[12.5rem] lg:h-[1.75rem]"
/>
</picture>
</a>
<SfButton
aria-label="Open categories"
class="text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-900 lg:hidden order-first lg:order-1 mr-4"
square
variant="tertiary"
>
<SfIconMenu />
</SfButton>
<SfButton
class="hidden lg:flex text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-900 lg:mr-4"
variant="tertiary"
>
<template #suffix>
<SfIconExpandMore class="hidden lg:block" />
</template>
<span class="hidden lg:flex whitespace-nowrap">Browse products</span>
</SfButton>
<form
role="search"
class="flex flex-[100%] order-last lg:order-3 mt-2 lg:mt-0 pb-2 lg:pb-0"
@submit.prevent="search"
>
<SfInput
v-model="inputValue"
type="search"
class="[&::-webkit-search-cancel-button]:appearance-none"
placeholder="Search"
wrapper-class="flex-1 h-10 pr-0"
size="base"
>
<template #suffix>
<span class="flex items-center">
<SfButton
variant="tertiary"
square
aria-label="search"
type="submit"
class="rounded-l-none hover:bg-transparent active:bg-transparent"
>
<SfIconSearch />
</SfButton>
</span>
</template>
</SfInput>
</form>
<nav class="flex-1 flex justify-end lg:order-last lg:ml-4">
<div class="flex flex-row flex-nowrap">
<SfButton
v-for="actionItem in actionItems"
:key="actionItem.ariaLabel"
class="text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-900 mr-2 -ml-0.5 rounded-md"
:aria-label="actionItem.ariaLabel"
variant="tertiary"
square
>
<template #prefix>
<Component :is="actionItem.icon" />
</template>
<span v-if="actionItem.role === 'login'" class="hidden xl:inline-flex whitespace-nowrap">{{
actionItem.label
}}</span>
</SfButton>
</div>
</nav>
</div>
</header>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {
SfButton,
SfIconShoppingCart,
SfIconFavorite,
SfIconPerson,
SfIconExpandMore,
SfInput,
SfIconSearch,
SfIconMenu,
} from '@storefront-ui/vue';
const actionItems = [
{
icon: SfIconShoppingCart,
ariaLabel: 'Cart',
role: 'button',
label: '',
},
{
icon: SfIconFavorite,
ariaLabel: 'Wishlist',
role: 'button',
label: '',
},
{
label: 'Log in',
icon: SfIconPerson,
ariaLabel: 'Log in',
role: 'login',
},
];
const inputValue = ref('');
const search = () => {
alert(`Successfully found 10 results for ${inputValue.value}`);
};
</script>
NavbarTop with white background and simple mobile bar
The alternate NavbarTop variant designed to work seamlessly with the NavbarBottom, providing a cohesive mobile navigation experience.
By combining with the NavbarBottom, you can create a unified navigation structure that accommodates both top and bottom navigation elements on mobile devices. This ensures a smooth and intuitive user experience, allowing users to access important navigation options easily.
<template>
<header class="flex justify-center w-full py-2 px-4 lg:py-5 lg:px-6 bg-white border-b border-neutral-200">
<div
class="flex flex-wrap justify-between lg:flex-nowrap items-center flex-row md:justify-start h-full max-w-[1536px] w-full"
>
<SfButton variant="tertiary" square class="md:hidden" aria-label="Go back">
<SfIconArrowBack />
</SfButton>
<a
href="#"
aria-label="SF Homepage"
class="inline-block mr-4 focus-visible:outline focus-visible:outline-offset focus-visible:rounded-sm shrink-0"
>
<img
src="https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/vsf_logo.svg"
alt="Sf Logo"
class="w-[175px] md:h-6 md:w-[176px] lg:w-[12.5rem] lg:h-[1.75rem]"
/>
</a>
<SfButton variant="tertiary" class="md:hidden" square aria-label="Search">
<SfIconSearch />
</SfButton>
<SfButton
aria-label="Open categories"
class="hidden md:block lg:hidden order-first lg:order-1 mr-4"
square
variant="tertiary"
>
<SfIconMenu />
</SfButton>
<SfButton class="hidden lg:flex lg:mr-4" variant="tertiary">
<template #suffix>
<SfIconExpandMore class="hidden lg:block" />
</template>
<span class="hidden lg:flex whitespace-nowrap">Browse products</span>
</SfButton>
<form
role="search"
class="hidden md:flex flex-[100%] order-last lg:order-3 mt-2 lg:mt-0 pb-2 lg:pb-0"
@submit.prevent="search"
>
<SfInput
v-model="inputValue"
type="search"
class="[&::-webkit-search-cancel-button]:appearance-none"
placeholder="Search"
wrapper-class="flex-1 h-10 pr-0"
size="base"
>
<template #suffix>
<span class="flex items-center">
<SfButton
variant="tertiary"
square
aria-label="search"
type="submit"
class="rounded-l-none hover:bg-transparent active:bg-transparent"
>
<SfIconSearch />
</SfButton>
</span>
</template>
</SfInput>
</form>
<nav class="flex-1 hidden md:flex justify-end lg:order-last lg:ml-4">
<div class="flex flex-row flex-nowrap">
<SfButton
v-for="actionItem in actionItems"
:key="actionItem.ariaLabel"
class="mr-2 -ml-0.5 rounded-md text-primary-700 hover:bg-primary-100 active:bg-primary-200 hover:text-primary-600 active:text-primary-700"
:aria-label="actionItem.ariaLabel"
variant="tertiary"
square
>
<template #prefix>
<Component :is="actionItem.icon" />
</template>
<span v-if="actionItem.role === 'login'" class="hidden xl:inline-flex whitespace-nowrap">{{
actionItem.label
}}</span>
</SfButton>
</div>
</nav>
</div>
</header>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {
SfButton,
SfIconShoppingCart,
SfIconFavorite,
SfIconPerson,
SfIconExpandMore,
SfInput,
SfIconSearch,
SfIconMenu,
SfIconArrowBack,
} from '@storefront-ui/vue';
const actionItems = [
{
icon: SfIconShoppingCart,
ariaLabel: 'Cart',
role: 'button',
label: '',
},
{
icon: SfIconFavorite,
ariaLabel: 'Wishlist',
role: 'button',
label: '',
},
{
label: 'Log in',
icon: SfIconPerson,
ariaLabel: 'Log in',
role: 'login',
},
];
const inputValue = ref('');
const search = () => {
alert(`Successfully found 10 results for ${inputValue.value}`);
};
</script>
NavbarTop with filled background and simple mobile bar
<template>
<header class="flex justify-center w-full py-2 px-4 lg:py-5 lg:px-6 bg-primary-700 border-b border-neutral-200">
<div
class="flex flex-wrap justify-between lg:flex-nowrap items-center flex-row md:justify-start h-full max-w-[1536px] w-full"
>
<SfButton variant="tertiary" square class="md:hidden text-white" aria-label="Go back">
<SfIconArrowBack />
</SfButton>
<a
href="#"
aria-label="SF Homepage"
class="inline-block mr-4 focus-visible:outline focus-visible:outline-offset focus-visible:rounded-sm shrink-0"
>
<img
src="https://storage.googleapis.com/sfui_docs_artifacts_bucket_public/production/vsf_logo_white.svg"
alt="Sf Logo"
class="w-[175px] md:h-6 md:w-[176px] lg:w-[12.5rem] lg:h-[1.75rem]"
/>
</a>
<SfButton variant="tertiary" square class="md:hidden text-white" aria-label="Search">
<SfIconSearch />
</SfButton>
<SfButton
aria-label="Open categories"
class="hidden md:block text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-900 lg:hidden order-first lg:order-1 mr-4"
square
variant="tertiary"
>
<SfIconMenu />
</SfButton>
<SfButton
class="hidden lg:flex text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-900 lg:mr-4"
variant="tertiary"
>
<template #suffix>
<SfIconExpandMore class="hidden lg:block" />
</template>
<span class="hidden lg:flex whitespace-nowrap">Browse products</span>
</SfButton>
<form
role="search"
class="hidden md:flex flex-[100%] order-last lg:order-3 mt-2 lg:mt-0 pb-2 lg:pb-0"
@submit.prevent="search"
>
<SfInput
v-model="inputValue"
type="search"
class="[&::-webkit-search-cancel-button]:appearance-none"
placeholder="Search"
wrapper-class="flex-1 h-10 pr-0"
size="base"
>
<template #suffix>
<span class="flex items-center">
<SfButton
variant="tertiary"
square
aria-label="search"
type="submit"
class="rounded-l-none hover:bg-transparent active:bg-transparent"
>
<SfIconSearch />
</SfButton>
</span>
</template>
</SfInput>
</form>
<nav class="hidden md:flex flex-1 justify-end lg:order-last lg:ml-4">
<div class="flex flex-row flex-nowrap">
<SfButton
v-for="actionItem in actionItems"
:key="actionItem.ariaLabel"
class="text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-900 mr-2 -ml-0.5 rounded-md"
:aria-label="actionItem.ariaLabel"
variant="tertiary"
square
>
<template #prefix>
<Component :is="actionItem.icon" />
</template>
<span v-if="actionItem.role === 'login'" class="hidden xl:inline-flex whitespace-nowrap">{{
actionItem.label
}}</span>
</SfButton>
</div>
</nav>
</div>
</header>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {
SfButton,
SfIconShoppingCart,
SfIconFavorite,
SfIconPerson,
SfIconExpandMore,
SfInput,
SfIconSearch,
SfIconMenu,
SfIconArrowBack,
} from '@storefront-ui/vue';
const actionItems = [
{
icon: SfIconShoppingCart,
ariaLabel: 'Cart',
role: 'button',
label: '',
},
{
icon: SfIconFavorite,
ariaLabel: 'Wishlist',
role: 'button',
label: '',
},
{
label: 'Log in',
icon: SfIconPerson,
ariaLabel: 'Log in',
role: 'login',
},
];
const inputValue = ref('');
const search = () => {
alert(`Successfully found 10 results for ${inputValue.value}`);
};
</script>