feat(Link)!: rename from LinkCustom and add exact-query / exact-hash props

This commit is contained in:
Benjamin Canac
2023-07-30 19:46:27 +02:00
parent a9300db91e
commit cefe5a76e0
10 changed files with 72 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
<template>
<ULinkCustom :type="type" :disabled="disabled || loading" :class="buttonClass">
<ULink :type="type" :disabled="disabled || loading" :class="buttonClass">
<slot name="leading" :disabled="disabled" :loading="loading">
<UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
</slot>
@@ -13,7 +13,7 @@
<slot name="trailing" :disabled="disabled" :loading="loading">
<UIcon v-if="isTrailing && trailingIconName" :name="trailingIconName" :class="trailingIconClass" aria-hidden="true" />
</slot>
</ULinkCustom>
</ULink>
</template>
<script lang="ts">
@@ -21,7 +21,7 @@ import { computed, defineComponent, useSlots } from 'vue'
import type { PropType } from 'vue'
import { defu } from 'defu'
import UIcon from '../elements/Icon.vue'
import ULinkCustom from '../elements/LinkCustom.vue'
import ULink from '../elements/Link.vue'
import { classNames } from '../../utils'
import { useAppConfig } from '#imports'
// TODO: Remove
@@ -33,7 +33,7 @@ import appConfig from '#build/app.config'
export default defineComponent({
components: {
UIcon,
ULinkCustom
ULink
},
props: {
type: {

View File

@@ -20,7 +20,7 @@
<HMenuItems :class="[ui.base, ui.divide, ui.ring, ui.rounded, ui.shadow, ui.background, ui.height]" static>
<div v-for="(subItems, index) of items" :key="index" :class="ui.padding">
<HMenuItem v-for="(item, subIndex) of subItems" :key="subIndex" v-slot="{ active, disabled: itemDisabled }" :disabled="item.disabled">
<ULinkCustom
<ULink
v-bind="omit(item, ['label', 'slot', 'icon', 'iconClass', 'avatar', 'shortcuts', 'disabled', 'click'])"
:class="[ui.item.base, ui.item.padding, ui.item.size, ui.item.rounded, active ? ui.item.active : ui.item.inactive, itemDisabled && ui.item.disabled]"
@click="item.click"
@@ -35,7 +35,7 @@
<UKbd v-for="shortcut of item.shortcuts" :key="shortcut">{{ shortcut }}</UKbd>
</span>
</slot>
</ULinkCustom>
</ULink>
</HMenuItem>
</div>
</HMenuItems>
@@ -53,7 +53,7 @@ import { omit } from 'lodash-es'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import UKbd from '../elements/Kbd.vue'
import ULinkCustom from '../elements/LinkCustom.vue'
import ULink from '../elements/Link.vue'
import { usePopper } from '../../composables/usePopper'
import type { DropdownItem } from '../../types/dropdown'
import type { PopperOptions } from '../../types'
@@ -73,7 +73,7 @@ export default defineComponent({
UIcon,
UAvatar,
UKbd,
ULinkCustom
ULink
},
props: {
items: {

View File

@@ -1,10 +1,10 @@
<template>
<button v-if="!to" :type="type" :disabled="disabled" v-bind="$attrs" :class="inactiveClass">
<button v-if="!to" v-bind="$attrs" :class="inactiveClass">
<slot />
</button>
<NuxtLink
v-else
v-slot="{ href, target, rel, navigate, isActive, isExactActive, isExternal }"
v-slot="{ route, href, target, rel, navigate, isActive, isExactActive, isExternal }"
v-bind="$props"
custom
>
@@ -13,7 +13,7 @@
:href="href"
:rel="rel"
:target="target"
:class="resolveLinkClass({ isActive, isExactActive })"
:class="resolveLinkClass(route, { isActive, isExactActive })"
@click="(e) => !isExternal && navigate(e)"
>
<slot v-bind="{ isActive: exact ? isExactActive : isActive }" />
@@ -22,6 +22,7 @@
</template>
<script lang="ts">
import { isEqual } from 'lodash-es'
import { defineComponent } from 'vue'
import { NuxtLink } from '#components'
@@ -29,25 +30,32 @@ export default defineComponent({
inheritAttrs: false,
props: {
...NuxtLink.props,
type: {
type: String,
default: null
},
disabled: {
type: Boolean,
default: null
},
exact: {
type: Boolean,
default: false
},
exactQuery: {
type: Boolean,
default: false
},
exactHash: {
type: Boolean,
default: false
},
inactiveClass: {
type: String,
default: undefined
}
},
setup (props) {
function resolveLinkClass ({ isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }) {
function resolveLinkClass (route, { isActive, isExactActive }: { isActive: boolean, isExactActive: boolean }) {
if (props.exactQuery && !isEqual(route.query, useRoute().query)) {
return props.inactiveClass
}
if (props.exactHash && route.hash !== useRoute().hash) {
return props.inactiveClass
}
if (props.exact && isExactActive) {
return props.activeClass
}

View File

@@ -1,6 +1,6 @@
<template>
<nav :class="ui.wrapper">
<ULinkCustom
<ULink
v-for="(link, index) of links"
v-slot="{ isActive }"
:key="index"
@@ -33,7 +33,7 @@
{{ link.badge }}
</span>
</slot>
</ULinkCustom>
</ULink>
</nav>
</template>
@@ -44,7 +44,7 @@ import { defu } from 'defu'
import { omit } from 'lodash-es'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import ULinkCustom from '../elements/LinkCustom.vue'
import ULink from '../elements/Link.vue'
import type { VerticalNavigationLink } from '../../types/vertical-navigation'
import { useAppConfig } from '#imports'
// TODO: Remove
@@ -57,7 +57,7 @@ export default defineComponent({
components: {
UIcon,
UAvatar,
ULinkCustom
ULink
},
props: {
links: {

View File

@@ -1,4 +1,6 @@
export interface Button {
import type { Link } from './link'
export interface Button extends Link {
type?: string
block?: boolean
label?: string

View File

@@ -1,7 +1,7 @@
import type { NuxtLinkProps } from '#app'
import type { Link } from './link'
import type { Avatar } from './avatar'
export interface DropdownItem extends NuxtLinkProps {
export interface DropdownItem extends Link {
label: string
slot?: string
icon?: string

View File

@@ -4,6 +4,7 @@ export * from './button'
export * from './clipboard'
export * from './command-palette'
export * from './dropdown'
export * from './link'
export * from './notification'
export * from './popper'
export * from './tabs'

8
src/runtime/types/link.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import type { NuxtLinkProps } from '#app'
export interface Link extends NuxtLinkProps {
exact?: boolean
exactQuery?: boolean
exactMatch?: boolean
inactiveClass?: string
}

View File

@@ -1,7 +1,7 @@
import type { NuxtLinkProps } from '#app'
import type { Link } from './link'
import type { Avatar } from './avatar'
export interface VerticalNavigationLink extends NuxtLinkProps {
export interface VerticalNavigationLink extends Link {
label: string
icon?: string
iconClass?: string