Rebuild website!

This commit is contained in:
Starystars67
2025-11-30 16:01:49 +00:00
parent 1671b775e4
commit 403489e43c
362 changed files with 77768 additions and 35940 deletions

View File

@@ -0,0 +1,121 @@
<script setup>
import { Github, Twitter, Facebook } from 'lucide-vue-next'
import { RouterLink } from 'vue-router'
</script>
<template>
<footer class="mt-auto py-8 border-t border-neutral-200 dark:border-neutral-800">
<div class="max-w-6xl mx-auto px-4">
<div class="flex flex-col md:flex-row items-center justify-between gap-6">
<!-- Social Media Links -->
<div class="flex items-center gap-4">
<a
href="https://www.reddit.com/r/BeamMP"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-beammp-blue transition-colors dark:text-neutral-400 dark:hover:text-blue-400"
aria-label="Reddit"
>
<svg
class="w-5 h-5"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z"
/>
</svg>
</a>
<a
href="https://twitter.com/BeamMP_Mod_Team"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-beammp-blue transition-colors dark:text-neutral-400 dark:hover:text-blue-400"
aria-label="Twitter"
>
<Twitter class="w-5 h-5" />
</a>
<a
href="https://www.facebook.com/BeamNGMP"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-beammp-blue transition-colors dark:text-neutral-400 dark:hover:text-blue-400"
aria-label="Facebook"
>
<Facebook class="w-5 h-5" />
</a>
<a
href="https://github.com/BeamMP"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-beammp-blue transition-colors dark:text-neutral-400 dark:hover:text-blue-400"
aria-label="GitHub"
>
<Github class="w-5 h-5" />
</a>
<a
href="https://discord.gg/beammp"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-beammp-blue transition-colors dark:text-neutral-400 dark:hover:text-blue-400"
aria-label="Discord"
>
<svg
class="w-5 h-5"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"
/>
</svg>
</a>
<span class="hidden md:inline text-neutral-300 dark:text-neutral-600">|</span>
<a
href="https://www.patreon.com/BeamMP"
target="_blank"
rel="noopener noreferrer"
class="text-xs text-orange-600 hover:text-orange-700 underline-offset-2 hover:underline dark:text-orange-400 dark:hover:text-orange-300"
>
Support on Patreon
</a>
</div>
<!-- Copyright and Legal -->
<div
class="flex flex-col items-center md:items-end gap-2 text-xs text-neutral-600 dark:text-neutral-500"
>
<p>&copy; 2019 - {{ new Date().getFullYear() }} | BeamMP Mod Team All Rights Reserved</p>
<div class="flex gap-3">
<RouterLink
to="/about"
class="text-neutral-700 hover:text-beammp-blue transition-colors dark:text-neutral-500 dark:hover:text-blue-400"
>
About
</RouterLink>
<span>&middot;</span>
<a
href="https://forum.beammp.com/topic/95/privacy-policy-v1-0"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-700 hover:text-beammp-blue transition-colors dark:text-neutral-500 dark:hover:text-blue-400"
>
Privacy Policy
</a>
<span>&middot;</span>
<a
href="https://forum.beammp.com/topic/94/terms-of-use-v1-0"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-700 hover:text-beammp-blue transition-colors dark:text-neutral-500 dark:hover:text-blue-400"
>
Terms &amp; Conditions
</a>
</div>
</div>
</div>
</div>
</footer>
</template>

View File

@@ -0,0 +1,261 @@
<script setup>
import { ref } from 'vue'
import { RouterLink } from 'vue-router'
import {
NavigationMenu,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
navigationMenuTriggerStyle,
} from '@/components/ui/navigation-menu'
import { cn } from '@/lib/utils'
import ThemeToggle from '@/components/ThemeToggle.vue'
import { Menu, X } from 'lucide-vue-next'
const mobileMenuOpen = ref(false)
function toggleMobileMenu() {
mobileMenuOpen.value = !mobileMenuOpen.value
}
function closeMobileMenu() {
mobileMenuOpen.value = false
}
</script>
<template>
<header
class="border-b border-neutral-200 dark:border-neutral-800 bg-white/80 dark:bg-neutral-900/70 backdrop-blur sticky top-0 z-20"
>
<nav class="max-w-6xl mx-auto px-4 h-16 flex items-center justify-between">
<RouterLink to="/" class="flex items-center gap-2 shrink-0" @click="closeMobileMenu">
<!-- Light mode logo -->
<img src="/beammp-logo.png" alt="BeamMP Logo" class="h-10 w-auto shrink-0 dark:hidden" />
<!-- Dark mode logo -->
<img
src="/beammp-logo-dark.png"
alt="BeamMP Logo"
class="h-10 w-auto shrink-0 hidden dark:block"
/>
</RouterLink>
<!-- Desktop Navigation -->
<!-- Switch to mobile earlier (avoid logo crowding) -->
<div class="hidden lg:flex items-center gap-4">
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<a
href="https://forum.beammp.com"
target="_blank"
rel="noopener noreferrer"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
Forum
</a>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<a
href="https://docs.beammp.com"
target="_blank"
rel="noopener noreferrer"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
Docs
</a>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<RouterLink
to="/communities"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
Communities
</RouterLink>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<RouterLink
to="/servers"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
Servers
</RouterLink>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<RouterLink
to="/stats"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
Statistics
</RouterLink>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<a
href="https://github.com/BeamMP/BeamMP"
target="_blank"
rel="noopener noreferrer"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
GitHub
</a>
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink as-child>
<a
href="https://www.patreon.com/BeamMP"
target="_blank"
rel="noopener noreferrer"
:class="
cn(
navigationMenuTriggerStyle(),
'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white'
)
"
>
Patreon
</a>
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
<ThemeToggle />
</div>
<!-- Mobile Menu Button and Theme Toggle -->
<div class="flex lg:hidden items-center gap-2">
<ThemeToggle />
<button
class="p-2 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
aria-label="Toggle menu"
@click="toggleMobileMenu"
>
<Menu v-if="!mobileMenuOpen" class="w-6 h-6" />
<X v-else class="w-6 h-6" />
</button>
</div>
</nav>
<!-- Mobile Menu -->
<Transition
enter-active-class="transition-all duration-200 ease-out"
enter-from-class="opacity-0 -translate-y-2"
enter-to-class="opacity-100 translate-y-0"
leave-active-class="transition-all duration-150 ease-in"
leave-from-class="opacity-100 translate-y-0"
leave-to-class="opacity-0 -translate-y-2"
>
<div
v-if="mobileMenuOpen"
class="md:hidden border-t border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900"
>
<div class="px-4 py-3 space-y-1">
<RouterLink
to="/about"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
About
</RouterLink>
<a
href="https://forum.beammp.com"
target="_blank"
rel="noopener noreferrer"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
Forum
</a>
<a
href="https://docs.beammp.com"
target="_blank"
rel="noopener noreferrer"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
Docs
</a>
<RouterLink
to="/communities"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
Communities
</RouterLink>
<RouterLink
to="/servers"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
Servers
</RouterLink>
<RouterLink
to="/stats"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
Statistics
</RouterLink>
<a
href="https://github.com/BeamMP/BeamMP"
target="_blank"
rel="noopener noreferrer"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
GitHub
</a>
<a
href="https://www.patreon.com/BeamMP"
target="_blank"
rel="noopener noreferrer"
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
@click="closeMobileMenu"
>
Patreon
</a>
</div>
</div>
</Transition>
</header>
</template>

View File

@@ -0,0 +1,78 @@
<script setup>
import { ref, onMounted } from 'vue'
import { Sun, Moon, Monitor } from 'lucide-vue-next'
const theme = ref('system')
const setTheme = (newTheme) => {
theme.value = newTheme
localStorage.setItem('theme', newTheme)
applyTheme(newTheme)
}
const applyTheme = (selectedTheme) => {
const root = document.documentElement
if (
selectedTheme === 'dark' ||
(selectedTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
root.classList.add('dark')
} else {
root.classList.remove('dark')
}
}
onMounted(() => {
const savedTheme = localStorage.getItem('theme') || 'system'
theme.value = savedTheme
applyTheme(savedTheme)
// Listen for system theme changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
if (theme.value === 'system') {
applyTheme('system')
}
})
})
</script>
<template>
<div class="flex items-center gap-1 bg-neutral-200 dark:bg-neutral-800/50 rounded-lg p-1">
<button
:class="[
'p-2 rounded transition-colors',
theme === 'light'
? 'bg-white shadow-sm text-neutral-900 dark:bg-neutral-700 dark:text-white'
: 'text-neutral-600 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-200',
]"
title="Light mode"
@click="setTheme('light')"
>
<Sun class="w-4 h-4" />
</button>
<button
:class="[
'p-2 rounded transition-colors',
theme === 'system'
? 'bg-white shadow-sm text-neutral-900 dark:bg-neutral-700 dark:text-white'
: 'text-neutral-600 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-200',
]"
title="System theme"
@click="setTheme('system')"
>
<Monitor class="w-4 h-4" />
</button>
<button
:class="[
'p-2 rounded transition-colors',
theme === 'dark'
? 'bg-white shadow-sm text-neutral-900 dark:bg-neutral-700 dark:text-white'
: 'text-neutral-600 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-200',
]"
title="Dark mode"
@click="setTheme('dark')"
>
<Moon class="w-4 h-4" />
</button>
</div>
</template>

View File

@@ -0,0 +1,23 @@
<script setup>
import { Primitive } from 'reka-ui'
import { cn } from '@/lib/utils'
import { buttonVariants } from '.'
const props = defineProps({
variant: { type: null, required: false },
size: { type: null, required: false },
class: { type: null, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false, default: 'button' },
})
</script>
<template>
<Primitive
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot />
</Primitive>
</template>

View File

@@ -0,0 +1,33 @@
import { cva } from 'class-variance-authority'
export { default as Button } from './Button.vue'
export const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
outline:
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2',
xs: 'h-7 rounded px-2',
sm: 'h-8 rounded-md px-3 text-xs',
lg: 'h-10 rounded-md px-8',
icon: 'h-9 w-9',
'icon-sm': 'size-8',
'icon-lg': 'size-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
)

View File

@@ -0,0 +1,38 @@
<script setup>
import { reactiveOmit } from '@vueuse/core'
import { NavigationMenuRoot, useForwardPropsEmits } from 'reka-ui'
import { cn } from '@/lib/utils'
import NavigationMenuViewport from './NavigationMenuViewport.vue'
const props = defineProps({
modelValue: { type: String, required: false },
defaultValue: { type: String, required: false },
dir: { type: String, required: false },
orientation: { type: String, required: false },
delayDuration: { type: Number, required: false },
skipDelayDuration: { type: Number, required: false },
disableClickTrigger: { type: Boolean, required: false },
disableHoverTrigger: { type: Boolean, required: false },
disablePointerLeaveClose: { type: Boolean, required: false },
unmountOnHide: { type: Boolean, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
})
const emits = defineEmits(['update:modelValue'])
const delegatedProps = reactiveOmit(props, 'class')
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<NavigationMenuRoot
v-bind="forwarded"
:class="cn('relative z-10 flex max-w-max flex-1 items-center justify-center', props.class)"
>
<slot />
<NavigationMenuViewport />
</NavigationMenuRoot>
</template>

View File

@@ -0,0 +1,38 @@
<script setup>
import { reactiveOmit } from '@vueuse/core'
import { NavigationMenuContent, useForwardPropsEmits } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps({
forceMount: { type: Boolean, required: false },
disableOutsidePointerEvents: { type: Boolean, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
})
const emits = defineEmits([
'escapeKeyDown',
'pointerDownOutside',
'focusOutside',
'interactOutside',
])
const delegatedProps = reactiveOmit(props, 'class')
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
<NavigationMenuContent
v-bind="forwarded"
:class="
cn(
'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
)
"
>
<slot />
</NavigationMenuContent>
</template>

View File

@@ -0,0 +1,30 @@
<script setup>
import { reactiveOmit } from '@vueuse/core'
import { NavigationMenuIndicator, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps({
forceMount: { type: Boolean, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
})
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<NavigationMenuIndicator
v-bind="forwardedProps"
: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',
props.class
)
"
>
<div class="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuIndicator>
</template>

View File

@@ -0,0 +1,15 @@
<script setup>
import { NavigationMenuItem } from 'reka-ui'
const props = defineProps({
value: { type: String, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
})
</script>
<template>
<NavigationMenuItem v-bind="props">
<slot />
</NavigationMenuItem>
</template>

View File

@@ -0,0 +1,18 @@
<script setup>
import { NavigationMenuLink, useForwardPropsEmits } from 'reka-ui'
const props = defineProps({
active: { type: Boolean, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
})
const emits = defineEmits(['select'])
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>
<NavigationMenuLink v-bind="forwarded">
<slot />
</NavigationMenuLink>
</template>

View File

@@ -0,0 +1,24 @@
<script setup>
import { reactiveOmit } from '@vueuse/core'
import { NavigationMenuList, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps({
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
})
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<NavigationMenuList
v-bind="forwardedProps"
:class="cn('group flex flex-1 list-none items-center justify-center gap-x-1', props.class)"
>
<slot />
</NavigationMenuList>
</template>

View File

@@ -0,0 +1,31 @@
<script setup>
import { reactiveOmit } from '@vueuse/core'
import { ChevronDown } from 'lucide-vue-next'
import { NavigationMenuTrigger, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
import { navigationMenuTriggerStyle } from '.'
const props = defineProps({
disabled: { type: Boolean, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
})
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<NavigationMenuTrigger
v-bind="forwardedProps"
:class="cn(navigationMenuTriggerStyle(), 'group', props.class)"
>
<slot />
<ChevronDown
class="relative top-px ml-1 h-3 w-3 transition duration-300 group-data-[state=open]:rotate-180"
aria-hidden="true"
/>
</NavigationMenuTrigger>
</template>

View File

@@ -0,0 +1,31 @@
<script setup>
import { reactiveOmit } from '@vueuse/core'
import { NavigationMenuViewport, useForwardProps } from 'reka-ui'
import { cn } from '@/lib/utils'
const props = defineProps({
forceMount: { type: Boolean, required: false },
align: { type: String, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
})
const delegatedProps = reactiveOmit(props, 'class')
const forwardedProps = useForwardProps(delegatedProps)
</script>
<template>
<div class="absolute left-0 top-full flex justify-center">
<NavigationMenuViewport
v-bind="forwardedProps"
:class="
cn(
'origin-top-center relative mt-1.5 h-[--reka-navigation-menu-viewport-height] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[--reka-navigation-menu-viewport-width] left-[var(--reka-navigation-menu-viewport-left)]',
props.class
)
"
/>
</div>
</template>

View File

@@ -0,0 +1,14 @@
import { cva } from 'class-variance-authority'
export { default as NavigationMenu } from './NavigationMenu.vue'
export { default as NavigationMenuContent } from './NavigationMenuContent.vue'
export { default as NavigationMenuIndicator } from './NavigationMenuIndicator.vue'
export { default as NavigationMenuItem } from './NavigationMenuItem.vue'
export { default as NavigationMenuLink } from './NavigationMenuLink.vue'
export { default as NavigationMenuList } from './NavigationMenuList.vue'
export { default as NavigationMenuTrigger } from './NavigationMenuTrigger.vue'
export { default as NavigationMenuViewport } from './NavigationMenuViewport.vue'
export const navigationMenuTriggerStyle = cva(
'group inline-flex h-9 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'
)