mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-19 06:21:46 +01:00
* chore: add local module for better dx developing nuxt/ui * up * up * up * feat(Kbd): new * chore(Badge): update * chore(Collapsible): remove content prop * chore(Container): clean * chore(Avatar): update root bg * chore(Link): clean * feat(Tooltip): handle shortcuts * playground(collapsible): update --------- Co-authored-by: Benjamin Canac <canacb1@gmail.com>
74 lines
2.2 KiB
Vue
74 lines
2.2 KiB
Vue
<script lang="ts">
|
|
import type { NuxtLinkProps } from '#app'
|
|
|
|
export interface LinkProps extends NuxtLinkProps {
|
|
as?: string
|
|
type?: string
|
|
disabled?: boolean
|
|
active?: boolean
|
|
exact?: boolean
|
|
exactQuery?: boolean
|
|
exactHash?: boolean
|
|
inactiveClass?: string
|
|
}
|
|
</script>
|
|
|
|
<script setup lang="ts">
|
|
import { isEqual } from 'ohash'
|
|
import { useForwardProps } from 'radix-vue'
|
|
import { reactiveOmit } from '@vueuse/core'
|
|
import type { RouteLocation } from '#vue-router'
|
|
|
|
defineOptions({ inheritAttrs: false })
|
|
|
|
const props = withDefaults(defineProps<LinkProps>(), { as: 'button', type: 'button' })
|
|
|
|
const forward = useForwardProps(reactiveOmit(props, 'as', 'type', 'disabled', 'active', 'exact', 'exactQuery', 'exactHash', 'inactiveClass'))
|
|
|
|
function resolveLinkClass (route: RouteLocation, currentRoute: RouteLocation, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }) {
|
|
if (props.exactQuery && !isEqual(route.query, currentRoute.query)) {
|
|
return props.inactiveClass
|
|
}
|
|
if (props.exactHash && route.hash !== currentRoute.hash) {
|
|
return props.inactiveClass
|
|
}
|
|
|
|
if (props.exact && isExactActive) {
|
|
return props.activeClass
|
|
}
|
|
|
|
if (!props.exact && isActive) {
|
|
return props.activeClass
|
|
}
|
|
|
|
return props.inactiveClass
|
|
}
|
|
</script>
|
|
|
|
<!-- eslint-disable vue/no-template-shadow -->
|
|
<template>
|
|
<component
|
|
:is="as"
|
|
v-if="!to"
|
|
:type="type"
|
|
:disabled="disabled"
|
|
v-bind="$attrs"
|
|
:class="active ? activeClass : inactiveClass"
|
|
>
|
|
<slot v-bind="{ isActive: active }" />
|
|
</component>
|
|
<NuxtLink v-else v-slot="{ route, href, target, rel, navigate, isActive, isExactActive, isExternal }" v-bind="forward" custom>
|
|
<a
|
|
v-bind="$attrs"
|
|
:href="!disabled ? href : undefined"
|
|
:aria-disabled="disabled ? 'true' : undefined"
|
|
:role="disabled ? 'link' : undefined"
|
|
:rel="rel"
|
|
:target="target"
|
|
:class="active !== undefined ? (active ? activeClass : inactiveClass) : resolveLinkClass(route, $route, { isActive, isExactActive })"
|
|
@click="(e: any) => (!isExternal && !disabled) && navigate(e)"
|
|
>
|
|
<slot v-bind="{ isActive: active !== undefined ? active : (exact ? isExactActive : isActive) }" />
|
|
</a>
|
|
</NuxtLink>
|
|
</template> |