-
Notifications
You must be signed in to change notification settings - Fork 462
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(HorizontalNavigation): new component (#1279)
- Loading branch information
1 parent
b76e761
commit b8007ba
Showing
12 changed files
with
321 additions
and
34 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
docs/components/content/examples/HorizontalNavigationExample.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<script setup> | ||
const route = useRoute() | ||
const links = [{ | ||
label: 'Profile', | ||
avatar: { | ||
src: 'https://avatars.githubusercontent.com/u/739984?v=4' | ||
}, | ||
badge: 100 | ||
}, { | ||
label: 'Installation', | ||
icon: 'i-heroicons-home', | ||
to: '/getting-started/installation' | ||
}, { | ||
label: 'Horizontal Navigation', | ||
icon: 'i-heroicons-chart-bar', | ||
to: `${route.path.startsWith('/dev') ? '/dev' : ''}/navigation/horizontal-navigation` | ||
}, { | ||
label: 'Command Palette', | ||
icon: 'i-heroicons-command-line', | ||
to: '/navigation/command-palette' | ||
}] | ||
</script> | ||
|
||
<template> | ||
<UHorizontalNavigation :links="links" class="border-b border-gray-200 dark:border-gray-800" /> | ||
</template> |
22 changes: 22 additions & 0 deletions
22
docs/components/content/examples/HorizontalNavigationExampleDefaultSlot.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<script setup> | ||
const route = useRoute() | ||
const links = [{ | ||
label: 'Horizontal Navigation', | ||
to: `${route.path.startsWith('/dev') ? '/dev' : ''}/navigation/horizontal-navigation` | ||
}, { | ||
label: 'Command Palette', | ||
to: '/navigation/command-palette' | ||
}, { | ||
label: 'Table', | ||
to: '/data/table' | ||
}] | ||
</script> | ||
|
||
<template> | ||
<UHorizontalNavigation :links="links"> | ||
<template #default="{ link }"> | ||
<span class="group-hover:text-primary relative">{{ link.label }}</span> | ||
</template> | ||
</UHorizontalNavigation> | ||
</template> |
29 changes: 29 additions & 0 deletions
29
docs/components/content/examples/HorizontalNavigationExampleSections.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<script setup> | ||
const route = useRoute() | ||
const links = [ | ||
[{ | ||
label: 'Installation', | ||
icon: 'i-heroicons-home', | ||
to: '/getting-started/installation' | ||
}, { | ||
label: 'Horizontal Navigation', | ||
icon: 'i-heroicons-chart-bar', | ||
to: `${route.path.startsWith('/dev') ? '/dev' : ''}/navigation/horizontal-navigation` | ||
}, { | ||
label: 'Command Palette', | ||
icon: 'i-heroicons-command-line', | ||
to: '/navigation/command-palette' | ||
}], [{ | ||
label: 'Examples', | ||
icon: 'i-heroicons-light-bulb' | ||
}, { | ||
label: 'Help', | ||
icon: 'i-heroicons-question-mark-circle' | ||
}] | ||
] | ||
</script> | ||
|
||
<template> | ||
<UHorizontalNavigation :links="links" class="border-b border-gray-200 dark:border-gray-800" /> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 26 additions & 32 deletions
58
docs/components/content/examples/VerticalNavigationExampleSections.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
--- | ||
title: HorizontalNavigation | ||
description: Display a list of horizontal links. | ||
links: | ||
- label: GitHub | ||
icon: i-simple-icons-github | ||
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/HorizontalNavigation.vue | ||
navigation: | ||
badge: New | ||
--- | ||
|
||
## Usage | ||
|
||
Pass an array to the `links` prop of the HorizontalNavigation component. Each link can have the following properties: | ||
|
||
- `label` - The label of the link. | ||
- `labelClass` - The class of the link label. | ||
- `icon` - The icon of the link. | ||
- `iconClass` - The class of the link icon. | ||
- `avatar` - The avatar of the link. You can pass all the props of the [Avatar](/elements/avatar) component. | ||
- `badge` - A badge to display next to the label. You can pass all the props of the [Badge](/elements/badge) component. | ||
- `click` - The click handler of the link. | ||
|
||
You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `to`, `exact`, etc. | ||
|
||
:component-example{component="horizontal-navigation-example"} | ||
|
||
## Sections | ||
|
||
Group your navigation links into distinct sections, they will be displayed apart thanks to a `justify-between` flexbox layout. | ||
|
||
You can do this by passing an array of arrays to the `links` prop of the HorizontalNavigation component. | ||
|
||
:component-example{component="horizontal-navigation-example-sections"} | ||
|
||
## Slots | ||
|
||
You can use slots to customize links display. | ||
|
||
### `default` | ||
|
||
Use the `#default` slot to customize the link label. You will have access to the `link` and `isActive` properties in the slot scope. | ||
|
||
:component-example{component="horizontal-navigation-example-default-slot"} | ||
|
||
### `avatar` | ||
|
||
Use the `#avatar` slot to customize the link avatar. You will have access to the `link` and `isActive` properties in the slot scope. | ||
|
||
### `icon` | ||
|
||
Use the `#icon` slot to customize the link icon. You will have access to the `link` and `isActive` properties in the slot scope. | ||
|
||
### `badge` | ||
|
||
Use the `#badge` slot to customize the link badge. You will have access to the `link` and `isActive` properties in the slot scope. | ||
|
||
## Props | ||
|
||
:component-props | ||
|
||
## Config | ||
|
||
:component-preset |
109 changes: 109 additions & 0 deletions
109
src/runtime/components/navigation/HorizontalNavigation.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<template> | ||
<nav :class="ui.wrapper" v-bind="attrs"> | ||
<ul v-for="(section, sectionIndex) of sections" :key="`section${sectionIndex}`" :class="ui.container"> | ||
<li v-for="(link, index) of section" :key="`section${sectionIndex}-${index}`"> | ||
<ULink | ||
v-slot="{ isActive }" | ||
v-bind="getULinkProps(link)" | ||
:class="[ui.base, ui.before, ui.after]" | ||
:active-class="ui.active" | ||
:inactive-class="ui.inactive" | ||
@click="link.click" | ||
@keyup.enter="$event.target.blur()" | ||
> | ||
<slot name="avatar" :link="link" :is-active="isActive"> | ||
<UAvatar | ||
v-if="link.avatar" | ||
v-bind="{ size: ui.avatar.size, ...link.avatar }" | ||
:class="[ui.avatar.base]" | ||
/> | ||
</slot> | ||
<slot name="icon" :link="link" :is-active="isActive"> | ||
<UIcon | ||
v-if="link.icon" | ||
:name="link.icon" | ||
:class="twMerge(twJoin(ui.icon.base, isActive ? ui.icon.active : ui.icon.inactive), link.iconClass)" | ||
/> | ||
</slot> | ||
<slot :link="link" :is-active="isActive"> | ||
<span v-if="link.label" :class="twMerge(ui.label, link.labelClass)"> | ||
<span v-if="isActive" class="sr-only"> | ||
Current page: | ||
</span> | ||
{{ link.label }} | ||
</span> | ||
</slot> | ||
<slot name="badge" :link="link" :is-active="isActive"> | ||
<UBadge | ||
v-if="link.badge" | ||
v-bind="{ | ||
size: ui.badge.size, | ||
color: ui.badge.color, | ||
variant: ui.badge.variant, | ||
...((typeof link.badge === 'string' || typeof link.badge === 'number') ? { label: link.badge } : link.badge) | ||
}" | ||
:class="ui.badge.base" | ||
/> | ||
</slot> | ||
</ULink> | ||
</li> | ||
</ul> | ||
</nav> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { toRef, defineComponent, computed } from 'vue' | ||
import type { PropType } from 'vue' | ||
import { twMerge, twJoin } from 'tailwind-merge' | ||
import UIcon from '../elements/Icon.vue' | ||
import UAvatar from '../elements/Avatar.vue' | ||
import UBadge from '../elements/Badge.vue' | ||
import ULink from '../elements/Link.vue' | ||
import { useUI } from '../../composables/useUI' | ||
import { mergeConfig, getULinkProps } from '../../utils' | ||
import type { HorizontalNavigationLink, Strategy } from '../../types' | ||
// @ts-expect-error | ||
import appConfig from '#build/app.config' | ||
import { horizontalNavigation } from '#ui/ui.config' | ||
const config = mergeConfig<typeof horizontalNavigation>(appConfig.ui.strategy, appConfig.ui.horizontalNavigation, horizontalNavigation) | ||
export default defineComponent({ | ||
components: { | ||
UIcon, | ||
UAvatar, | ||
UBadge, | ||
ULink | ||
}, | ||
inheritAttrs: false, | ||
props: { | ||
links: { | ||
type: Array as PropType<HorizontalNavigationLink[][] | HorizontalNavigationLink[]>, | ||
default: () => [] | ||
}, | ||
class: { | ||
type: [String, Object, Array] as PropType<any>, | ||
default: () => '' | ||
}, | ||
ui: { | ||
type: Object as PropType<Partial<typeof config> & { strategy?: Strategy }>, | ||
default: () => ({}) | ||
} | ||
}, | ||
setup (props) { | ||
const { ui, attrs } = useUI('horizontalNavigation', toRef(props, 'ui'), config, toRef(props, 'class')) | ||
const sections = computed(() => (Array.isArray(props.links[0]) ? props.links : [props.links]) as HorizontalNavigationLink[][]) | ||
return { | ||
// eslint-disable-next-line vue/no-dupe-keys | ||
ui, | ||
attrs, | ||
sections, | ||
getULinkProps, | ||
twMerge, | ||
twJoin | ||
} | ||
} | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import type { Link } from './link' | ||
import type { Avatar } from './avatar' | ||
import type { Badge } from './badge' | ||
|
||
export interface HorizontalNavigationLink extends Link { | ||
label: string | ||
labelClass?: string | ||
icon?: string | ||
iconClass?: string | ||
avatar?: Avatar | ||
click?: Function | ||
badge?: string | number | Badge | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
b8007ba
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
ui – ./
ui-nuxt-js.vercel.app
ui.nuxt.com
ui-git-dev-nuxt-js.vercel.app