mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-16 04:58:12 +01:00
chore(Link): add pickLinkProps util
This commit is contained in:
@@ -11,7 +11,7 @@ const appConfig = _appConfig as AppConfig & { ui: { breadcrumb: Partial<typeof t
|
||||
|
||||
const breadcrumb = tv({ extend: tv(theme), ...(appConfig.ui?.breadcrumb || {}) })
|
||||
|
||||
export interface BreadcrumbItem extends LinkProps {
|
||||
export interface BreadcrumbItem extends Omit<LinkProps, 'custom'> {
|
||||
label?: string
|
||||
icon?: string
|
||||
avatar?: AvatarProps
|
||||
@@ -41,7 +41,7 @@ import { computed } from 'vue'
|
||||
import { Primitive } from 'radix-vue'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { ULink, UIcon, UAvatar } from '#components'
|
||||
import { omit } from '#ui/utils'
|
||||
import { pickLinkProps } from '#ui/utils/link'
|
||||
|
||||
const props = defineProps<BreadcrumbProps<T>>()
|
||||
const slots = defineSlots<BreadcrumbSlots<T>>()
|
||||
@@ -56,7 +56,7 @@ const ui = computed(() => tv({ extend: breadcrumb, slots: props.ui })())
|
||||
<ol :class="ui.list()">
|
||||
<template v-for="(item, index) in items" :key="index">
|
||||
<li :class="ui.itemWrapper()">
|
||||
<ULink as="span" v-bind="omit(item, ['label', 'icon', 'avatar', 'slot'])" :aria-current="index === items!.length - 1 ? 'page' : undefined" :class="ui.item({ active: index === items!.length - 1, disabled: !!item.disabled, to: !!item.to })" raw>
|
||||
<ULink v-bind="pickLinkProps(item)" as="span" :aria-current="index === items!.length - 1 ? 'page' : undefined" :class="ui.item({ active: index === items!.length - 1, disabled: !!item.disabled, to: !!item.to })" raw>
|
||||
<slot :name="item.slot || 'item'" :item="item" :index="index">
|
||||
<slot :name="item.slot ? `${item.slot}-leading`: 'item-leading'" :item="item" :active="index === items!.length - 1" :index="index">
|
||||
<UAvatar v-if="item.avatar" size="2xs" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ active: index === items!.length - 1 })" />
|
||||
|
||||
@@ -12,7 +12,7 @@ const button = tv({ extend: tv(theme), ...(appConfig.ui?.button || {}) })
|
||||
|
||||
type ButtonVariants = VariantProps<typeof button>
|
||||
|
||||
export interface ButtonProps extends UseComponentIconsProps, LinkProps {
|
||||
export interface ButtonProps extends UseComponentIconsProps, Omit<LinkProps, 'custom'> {
|
||||
label?: string
|
||||
color?: ButtonVariants['color']
|
||||
variant?: ButtonVariants['variant']
|
||||
@@ -34,14 +34,14 @@ export interface ButtonSlots {
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useForwardProps } from 'radix-vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { useComponentIcons, useButtonGroup } from '#imports'
|
||||
import { UIcon, ULink } from '#components'
|
||||
import { pickLinkProps } from '#ui/utils/link'
|
||||
|
||||
const props = defineProps<ButtonProps>()
|
||||
const slots = defineSlots<ButtonSlots>()
|
||||
|
||||
const linkProps = useForwardProps(reactiveOmit(props, 'type', 'label', 'color', 'variant', 'size', 'icon', 'leading', 'leadingIcon', 'trailing', 'trailingIcon', 'loading', 'loadingIcon', 'square', 'block', 'disabled', 'truncate', 'class', 'ui'))
|
||||
const linkProps = useForwardProps(pickLinkProps(props))
|
||||
|
||||
const { orientation, size: buttonSize } = useButtonGroup<ButtonProps>(props)
|
||||
const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props)
|
||||
|
||||
@@ -11,7 +11,7 @@ const appConfig = _appConfig as AppConfig & { ui: { contextMenu: Partial<typeof
|
||||
|
||||
const contextMenu = tv({ extend: tv(theme), ...(appConfig.ui?.contextMenu || {}) })
|
||||
|
||||
export interface ContextMenuItem extends Omit<LinkProps, 'type'>, Pick<ContextMenuItemProps, 'disabled'> {
|
||||
export interface ContextMenuItem extends Omit<LinkProps, 'type' | 'custom'>, Pick<ContextMenuItemProps, 'disabled'> {
|
||||
label?: string
|
||||
icon?: string
|
||||
avatar?: AvatarProps
|
||||
|
||||
@@ -15,8 +15,6 @@ interface ContextMenuContentProps<T> extends Omit<RadixContextMenuContentProps,
|
||||
}
|
||||
|
||||
interface ContextMenuContentEmits extends RadixContextMenuContentEmits {}
|
||||
|
||||
type ContextMenuContentSlots<T extends { slot?: string }> = ContextMenuSlots<T>
|
||||
</script>
|
||||
|
||||
<script setup lang="ts" generic="T extends ContextMenuItem">
|
||||
@@ -27,14 +25,15 @@ import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { ULink } from '#components'
|
||||
import { omit } from '#ui/utils'
|
||||
import { pickLinkProps } from '#ui/utils/link'
|
||||
|
||||
const props = defineProps<ContextMenuContentProps<T>>()
|
||||
const emits = defineEmits<ContextMenuContentEmits>()
|
||||
const slots = defineSlots<ContextMenuContentSlots<T>>()
|
||||
const slots = defineSlots<ContextMenuSlots<T>>()
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'class', 'ui'), emits)
|
||||
const proxySlots = omit(slots, ['default']) as Record<string, ContextMenuContentSlots<T>[string]>
|
||||
const proxySlots = omit(slots, ['default']) as Record<string, ContextMenuSlots<T>[string]>
|
||||
|
||||
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate()
|
||||
|
||||
@@ -102,7 +101,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
||||
</UContextMenuContent>
|
||||
</ContextMenu.Sub>
|
||||
<ContextMenu.Item v-else as-child :disabled="item.disabled" :text-value="item.label" @select="item.select">
|
||||
<ULink v-slot="{ active, ...slotProps }" v-bind="omit((item as ContextMenuItem), ['label', 'icon', 'avatar', 'content', 'kbds', 'slot', 'open', 'defaultOpen', 'select', 'children', 'type'])" custom>
|
||||
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<ContextMenuItem, 'type'>)" custom>
|
||||
<ULinkBase v-bind="slotProps" :class="ui.item({ active })">
|
||||
<ReuseItemTemplate :item="item" :active="active" :index="index" />
|
||||
</ULinkBase>
|
||||
|
||||
@@ -11,7 +11,7 @@ const appConfig = _appConfig as AppConfig & { ui: { dropdownMenu: Partial<typeof
|
||||
|
||||
const dropdownMenu = tv({ extend: tv(theme), ...(appConfig.ui?.dropdownMenu || {}) })
|
||||
|
||||
export interface DropdownMenuItem extends Omit<LinkProps, 'type'>, Pick<DropdownMenuItemProps, 'disabled'> {
|
||||
export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'custom'>, Pick<DropdownMenuItemProps, 'disabled'> {
|
||||
label?: string
|
||||
icon?: string
|
||||
avatar?: AvatarProps
|
||||
|
||||
@@ -15,8 +15,6 @@ interface DropdownMenuContentProps<T> extends Omit<RadixDropdownMenuContentProps
|
||||
}
|
||||
|
||||
interface DropdownMenuContentEmits extends RadixDropdownMenuContentEmits {}
|
||||
|
||||
type DropdownMenuContentSlots<T extends { slot?: string }> = DropdownMenuSlots<T>
|
||||
</script>
|
||||
|
||||
<script setup lang="ts" generic="T extends DropdownMenuItem">
|
||||
@@ -27,14 +25,15 @@ import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { ULink } from '#components'
|
||||
import { omit } from '#ui/utils'
|
||||
import { pickLinkProps } from '#ui/utils/link'
|
||||
|
||||
const props = defineProps<DropdownMenuContentProps<T>>()
|
||||
const emits = defineEmits<DropdownMenuContentEmits>()
|
||||
const slots = defineSlots<DropdownMenuContentSlots<T>>()
|
||||
const slots = defineSlots<DropdownMenuSlots<T>>()
|
||||
|
||||
const appConfig = useAppConfig()
|
||||
const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'class', 'ui'), emits)
|
||||
const proxySlots = omit(slots, ['default']) as Record<string, DropdownMenuContentSlots<T>[string]>
|
||||
const proxySlots = omit(slots, ['default']) as Record<string, DropdownMenuSlots<T>[string]>
|
||||
|
||||
const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate()
|
||||
|
||||
@@ -105,7 +104,7 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
|
||||
</UDropdownMenuContent>
|
||||
</DropdownMenu.Sub>
|
||||
<DropdownMenu.Item v-else as-child :disabled="item.disabled" :text-value="item.label" @select="item.select">
|
||||
<ULink v-slot="{ active, ...slotProps }" v-bind="omit((item as DropdownMenuItem), ['label', 'icon', 'avatar', 'content', 'kbds', 'slot', 'open', 'defaultOpen', 'select', 'children', 'type'])" custom>
|
||||
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<DropdownMenuItem, 'type'>)" custom>
|
||||
<ULinkBase v-bind="slotProps" :class="ui.item({ active })">
|
||||
<ReuseItemTemplate :item="item" :active="active" :index="index" />
|
||||
</ULinkBase>
|
||||
|
||||
@@ -11,7 +11,7 @@ const appConfig = _appConfig as AppConfig & { ui: { navigationMenu: Partial<type
|
||||
|
||||
const navigationMenu = tv({ extend: tv(theme), ...(appConfig.ui?.navigationMenu || {}) })
|
||||
|
||||
export interface NavigationMenuItem extends LinkProps, Pick<NavigationMenuItemProps, 'value'> {
|
||||
export interface NavigationMenuItem extends Omit<LinkProps, 'custom'>, Pick<NavigationMenuItemProps, 'value'> {
|
||||
label?: string
|
||||
icon?: string
|
||||
avatar?: AvatarProps
|
||||
@@ -44,7 +44,7 @@ import { computed } from 'vue'
|
||||
import { NavigationMenuRoot, NavigationMenuList, NavigationMenuItem, NavigationMenuLink, useForwardPropsEmits } from 'radix-vue'
|
||||
import { reactivePick } from '@vueuse/core'
|
||||
import { UIcon, UAvatar, UBadge, ULink, ULinkBase } from '#components'
|
||||
import { omit } from '#ui/utils'
|
||||
import { pickLinkProps } from '#ui/utils/link'
|
||||
|
||||
const props = withDefaults(defineProps<NavigationMenuProps<T>>(), { orientation: 'horizontal' })
|
||||
const emits = defineEmits<NavigationMenuEmits>()
|
||||
@@ -62,7 +62,7 @@ const lists = computed(() => props.items?.length ? (Array.isArray(props.items[0]
|
||||
<template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
|
||||
<NavigationMenuList :class="ui.list()">
|
||||
<NavigationMenuItem v-for="(item, index) in list" :key="`list-${listIndex}-${index}`" :value="item.value || String(index)" :class="ui.itemWrapper()">
|
||||
<ULink v-slot="{ active, ...slotProps }" v-bind="omit(item, ['label', 'value', 'icon', 'avatar', 'badge', 'slot', 'select'])" custom>
|
||||
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
|
||||
<NavigationMenuLink as-child :active="active" @select="item.select">
|
||||
<ULinkBase v-bind="slotProps" :class="ui.item({ active, disabled: !!item.disabled })">
|
||||
<slot :name="item.slot || 'item'" :item="item" :index="index">
|
||||
|
||||
6
src/runtime/utils/link.ts
Normal file
6
src/runtime/utils/link.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { reactivePick } from '@vueuse/core'
|
||||
import type { LinkProps } from '#ui/types'
|
||||
|
||||
export function pickLinkProps(link: LinkProps) {
|
||||
return reactivePick(link, 'active', 'activeClass', 'ariaCurrentValue', 'as', 'disabled', 'exact', 'exactActiveClass', 'exactHash', 'exactQuery', 'external', 'href', 'inactiveClass', 'noPrefetch', 'noRel', 'prefetch', 'prefetchedClass', 'rel', 'replace', 'target', 'to', 'type')
|
||||
}
|
||||
Reference in New Issue
Block a user