feat: add scrollarea, nav menu
This commit is contained in:
parent
a0c08b2355
commit
56f473ccc1
|
|
@ -219,13 +219,11 @@ export const docsConfig: DocsConfig = {
|
|||
href: '/docs/components/menubar',
|
||||
items: [],
|
||||
},
|
||||
// {
|
||||
// title: "Navigation Menu",
|
||||
// href: "#",
|
||||
// label: "Soon",
|
||||
// disabled: true,
|
||||
// items: []
|
||||
// },
|
||||
{
|
||||
title: 'Navigation Menu',
|
||||
href: '/docs/components/navigation-menu',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Popover',
|
||||
href: '/docs/components/popover',
|
||||
|
|
@ -241,13 +239,11 @@ export const docsConfig: DocsConfig = {
|
|||
href: '/docs/components/radio-group',
|
||||
items: [],
|
||||
},
|
||||
// {
|
||||
// title: "Scroll Area",
|
||||
// href: "#",
|
||||
// label: "Soon",
|
||||
// disabled: true,
|
||||
// items: []
|
||||
// },
|
||||
{
|
||||
title: 'Scroll Area',
|
||||
href: '/docs/components/scroll-area',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Select',
|
||||
href: '/docs/components/select',
|
||||
|
|
|
|||
|
|
@ -138,26 +138,26 @@
|
|||
* Lists
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
.vp-doc ul,
|
||||
.vp-doc ol {
|
||||
.vp-doc ul:not(:where(.preview *)),
|
||||
.vp-doc ol:not(:where(.preview *)) {
|
||||
padding-left: 1.25rem;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.vp-doc ul {
|
||||
.vp-doc ul:not(:where(.preview *)) {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
.vp-doc ol {
|
||||
.vp-doc ol:not(:where(.preview *)) {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.vp-doc li + li {
|
||||
.vp-doc li + li:not(:where(.preview *)) {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.vp-doc li > ol,
|
||||
.vp-doc li > ul {
|
||||
.vp-doc li > ol:not(:where(.preview *)),
|
||||
.vp-doc li > ul:not(:where(.preview *)) {
|
||||
margin: 8px 0 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
61
apps/www/src/content/docs/components/navigation-menu.md
Normal file
61
apps/www/src/content/docs/components/navigation-menu.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
title: Navigation Menu
|
||||
description: A collection of links for navigating websites.
|
||||
source: https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/src/lib/registry/default/ui/navigation-menu
|
||||
primitive: https://www.radix-vue.com/components/navigation-menu.html
|
||||
---
|
||||
|
||||
<ComponentPreview name="NavigationMenuDemo" >
|
||||
|
||||
<<< ../../../lib/registry/default/examples/NavigationMenuDemo.vue
|
||||
|
||||
</ComponentPreview>
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npx shadcn-vue@latest add navigation-menu
|
||||
```
|
||||
|
||||
<ManualInstall>
|
||||
|
||||
1. Install `radix-vue`:
|
||||
|
||||
```bash
|
||||
npm install radix-vue
|
||||
```
|
||||
|
||||
2. Copy and paste the component source files linked at the top of this page into your project.
|
||||
</ManualInstall>
|
||||
|
||||
## Usage
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
NavigationMenu,
|
||||
NavigationMenuContent,
|
||||
NavigationMenuIndicator,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuList,
|
||||
NavigationMenuTrigger,
|
||||
NavigationMenuViewport,
|
||||
} from '@/lib/registry/default/ui/navigation-menu'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<NavigationMenuLink>Link</NavigationMenuLink>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
</template>
|
||||
```
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<script setup lang="ts">
|
||||
import ListItem from './NavigationMenuDemoItem.vue'
|
||||
import {
|
||||
NavigationMenu,
|
||||
NavigationMenuContent,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuList,
|
||||
NavigationMenuTrigger,
|
||||
navigationMenuTriggerStyle,
|
||||
} from '@/lib/registry/default/ui/navigation-menu'
|
||||
|
||||
const components: { title: string; href: string; description: string }[] = [
|
||||
{
|
||||
title: 'Alert Dialog',
|
||||
href: '/docs/primitives/alert-dialog',
|
||||
description:
|
||||
'A modal dialog that interrupts the user with important content and expects a response.',
|
||||
},
|
||||
{
|
||||
title: 'Hover Card',
|
||||
href: '/docs/primitives/hover-card',
|
||||
description:
|
||||
'For sighted users to preview content available behind a link.',
|
||||
},
|
||||
{
|
||||
title: 'Progress',
|
||||
href: '/docs/primitives/progress',
|
||||
description:
|
||||
'Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.',
|
||||
},
|
||||
{
|
||||
title: 'Scroll-area',
|
||||
href: '/docs/primitives/scroll-area',
|
||||
description: 'Visually or semantically separates content.',
|
||||
},
|
||||
{
|
||||
title: 'Tabs',
|
||||
href: '/docs/primitives/tabs',
|
||||
description:
|
||||
'A set of layered sections of content—known as tab panels—that are displayed one at a time.',
|
||||
},
|
||||
{
|
||||
title: 'Tooltip',
|
||||
href: '/docs/primitives/tooltip',
|
||||
description:
|
||||
'A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul class="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
|
||||
<li class="row-span-3">
|
||||
<NavigationMenuLink as-child>
|
||||
<a
|
||||
class="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
|
||||
href="/"
|
||||
>
|
||||
<img src="https://www.radix-vue.com/logo.svg" class="h-6 w-6">
|
||||
<div class="mb-2 mt-4 text-lg font-medium">
|
||||
shadcn/ui
|
||||
</div>
|
||||
<p class="text-sm leading-tight text-muted-foreground">
|
||||
Beautifully designed components built with Radix UI and
|
||||
Tailwind CSS.
|
||||
</p>
|
||||
</a>
|
||||
</NavigationMenuLink>
|
||||
</li>
|
||||
<ListItem href="/docs" title="Introduction">
|
||||
Re-usable components built using Radix UI and Tailwind CSS.
|
||||
</ListItem>
|
||||
<ListItem href="/docs/installation" title="Installation">
|
||||
How to install dependencies and structure your app.
|
||||
</ListItem>
|
||||
<ListItem href="/docs/primitives/typography" title="Typography">
|
||||
Styles for headings, paragraphs, lists...etc
|
||||
</ListItem>
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>Components</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul class="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
||||
<ListItem
|
||||
v-for="component in components"
|
||||
:key="component.title"
|
||||
:title="component.title"
|
||||
:href="component.href"
|
||||
>
|
||||
{{ component.description }}
|
||||
</ListItem>
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuLink href="/docs" :class="navigationMenuTriggerStyle()">
|
||||
Documentation
|
||||
</NavigationMenuLink>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import {
|
||||
NavigationMenuLink,
|
||||
} from '@/lib/registry/default/ui/navigation-menu'
|
||||
|
||||
defineProps<{ title?: string; href?: string }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li>
|
||||
<NavigationMenuLink as-child>
|
||||
<a
|
||||
:href="href"
|
||||
:class="cn(
|
||||
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground',
|
||||
$attrs.class ?? '',
|
||||
)"
|
||||
>
|
||||
<div class="text-sm font-medium leading-none">{{ title }}</div>
|
||||
<p class="line-clamp-2 text-sm leading-snug text-muted-foreground">
|
||||
<slot />
|
||||
</p>
|
||||
</a>
|
||||
</NavigationMenuLink>
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -3,8 +3,8 @@ import {
|
|||
NavigationMenuRoot,
|
||||
type NavigationMenuRootEmits,
|
||||
type NavigationMenuRootProps,
|
||||
NavigationMenuViewport,
|
||||
} from 'radix-vue'
|
||||
import NavigationMenuViewport from './NavigationMenuViewport.vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<NavigationMenuRootProps & { class?: string }>()
|
||||
|
|
@ -15,19 +15,10 @@ const emits = defineEmits<NavigationMenuRootEmits>()
|
|||
<template>
|
||||
<NavigationMenuRoot
|
||||
v-bind="props"
|
||||
:class="cn('relative z-10 flex w-full justify-center', props.class)"
|
||||
:class="cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)"
|
||||
@update:model-value="emits('update:modelValue', $event)"
|
||||
>
|
||||
<slot />
|
||||
<div class="absolute top-full left-0 flex w-full justify-center">
|
||||
<NavigationMenuViewport
|
||||
:class="
|
||||
cn(
|
||||
'data-[state=open]:animate-scaleIn data-[state=closed]:animate-scaleOut relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full origin-[top_center] overflow-hidden bg-background rounded-lg border border-border shadow-md transition-[width,_height] duration-300 sm:w-[var(--radix-navigation-menu-viewport-width)]',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<NavigationMenuViewport />
|
||||
</NavigationMenuRoot>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
type NavigationMenuContentEmits,
|
||||
type NavigationMenuContentProps,
|
||||
} from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { cn, useEmitAsProps } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<NavigationMenuContentProps & { class?: string }>()
|
||||
|
||||
|
|
@ -13,10 +13,10 @@ const emits = defineEmits<NavigationMenuContentEmits>()
|
|||
|
||||
<template>
|
||||
<NavigationMenuContent
|
||||
v-bind="props"
|
||||
v-bind="{ ...props, ...useEmitAsProps(emits) }"
|
||||
:class="
|
||||
cn(
|
||||
'data-[motion=from-start]:animate-enterFromLeft data-[motion=from-end]:animate-enterFromRight data-[motion=to-start]:animate-exitToLeft data-[motion=to-end]:animate-exitToRight absolute top-0 left-0 w-full sm:w-auto',
|
||||
'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<script setup lang="ts">
|
||||
import { NavigationMenuIndicator, type NavigationMenuIndicatorProps } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<NavigationMenuIndicatorProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavigationMenuIndicator
|
||||
v-bind="props"
|
||||
:class="cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in', $attrs.class ?? '')"
|
||||
>
|
||||
<div class="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
|
||||
</NavigationMenuIndicator>
|
||||
</template>
|
||||
|
|
@ -4,14 +4,14 @@ import {
|
|||
type NavigationMenuLinkEmits,
|
||||
type NavigationMenuLinkProps,
|
||||
} from 'radix-vue'
|
||||
import { useEmitAsProps } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<NavigationMenuLinkProps>()
|
||||
|
||||
const emits = defineEmits<NavigationMenuLinkEmits>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavigationMenuLink v-bind="props" @select="emits('select', $event)">
|
||||
<NavigationMenuLink v-bind="{ ...props, ...useEmitAsProps(emits) }">
|
||||
<slot />
|
||||
</NavigationMenuLink>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { NavigationMenuLink } from 'radix-vue'
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
href: String,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li>
|
||||
<NavigationMenuLink as-child>
|
||||
<a
|
||||
:href="props.href"
|
||||
v-bind="$attrs"
|
||||
class="focus:shadow-sm hover:bg-outline-hover block select-none rounded-sm p-3 text-sm leading-none no-underline outline-none transition-colors"
|
||||
>
|
||||
<div class="text-foreground mb-1 font-medium leading-4">
|
||||
{{ props.title }}
|
||||
</div>
|
||||
<p class="text-muted my-0 leading-5">
|
||||
<slot />
|
||||
</p>
|
||||
</a>
|
||||
</NavigationMenuLink>
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -3,27 +3,19 @@ import {
|
|||
NavigationMenuTrigger,
|
||||
type NavigationMenuTriggerProps,
|
||||
} from 'radix-vue'
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { ChevronDown } from 'lucide-vue-next'
|
||||
import { computed } from 'vue'
|
||||
import { navigationMenuTriggerStyle } from '.'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<NavigationMenuTriggerProps & { class?: string }>()
|
||||
|
||||
const navigationMenuTriggerStyle = computed(() => {
|
||||
return cva(
|
||||
'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-outline-hover hover:text-foreground focus:bg-outline-hover focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-outline-hover data-[state=open]:bg-outline-hover',
|
||||
)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavigationMenuTrigger
|
||||
:class="cn(navigationMenuTriggerStyle(), props.class)"
|
||||
:class="cn(navigationMenuTriggerStyle(), 'group', props.class)"
|
||||
v-bind="props"
|
||||
>
|
||||
<slot />
|
||||
{{ " " }}
|
||||
<ChevronDown
|
||||
class="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
|
||||
aria-hidden="true"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<script setup lang="ts">
|
||||
import {
|
||||
NavigationMenuViewport,
|
||||
type NavigationMenuViewportProps,
|
||||
} from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<NavigationMenuViewportProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="absolute left-0 top-full flex justify-center">
|
||||
<NavigationMenuViewport
|
||||
v-bind="props"
|
||||
:class="
|
||||
cn(
|
||||
'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]',
|
||||
$attrs.class ?? '',
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,7 +1,12 @@
|
|||
import { cva } from 'class-variance-authority'
|
||||
|
||||
export { default as NavigationMenu } from './NavigationMenu.vue'
|
||||
export { default as NavigationMenuList } from './NavigationMenuList.vue'
|
||||
export { default as NavigationMenuItem } from './NavigationMenuItem.vue'
|
||||
export { default as NavigationMenuTrigger } from './NavigationMenuTrigger.vue'
|
||||
export { default as NavigationMenuContent } from './NavigationMenuContent.vue'
|
||||
export { default as NavigationMenuLink } from './NavigationMenuLink.vue'
|
||||
export { default as NavigationMenuListItem } from './NavigationMenuListItem.vue'
|
||||
|
||||
export const navigationMenuTriggerStyle = cva(
|
||||
'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
import type { SelectRootEmits, SelectRootProps } from 'radix-vue'
|
||||
import { SelectRoot } from 'radix-vue'
|
||||
import { useEmitAsProps } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<SelectRootProps>()
|
||||
const emits = defineEmits<SelectRootEmits>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SelectRoot>
|
||||
<SelectRoot v-bind="{ ...props, ...useEmitAsProps(emits) }">
|
||||
<slot />
|
||||
</SelectRoot>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user