mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
feat(components): add new content-top and content-bottom slots (#3886)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -90,6 +90,8 @@ export type ContextMenuSlots<
|
||||
'item-leading': SlotProps<T>
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
'content-top': (props?: {}) => any
|
||||
'content-bottom': (props?: {}) => any
|
||||
} & DynamicSlots<MergeTypes<T>, 'leading' | 'label' | 'trailing', { active?: boolean, index: number }>
|
||||
|
||||
</script>
|
||||
|
||||
@@ -107,6 +107,8 @@ const groups = computed<ContextMenuItem[][]>(() =>
|
||||
|
||||
<ContextMenu.Portal v-bind="portalProps">
|
||||
<component :is="sub ? ContextMenu.SubContent : ContextMenu.Content" :class="props.class" v-bind="contentProps">
|
||||
<slot name="content-top" />
|
||||
|
||||
<ContextMenu.Group v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: uiOverride?.group })">
|
||||
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
||||
<ContextMenu.Label v-if="item.type === 'label'" :class="ui.label({ class: uiOverride?.label })">
|
||||
@@ -171,6 +173,8 @@ const groups = computed<ContextMenuItem[][]>(() =>
|
||||
</ContextMenu.Group>
|
||||
|
||||
<slot />
|
||||
|
||||
<slot name="content-bottom" />
|
||||
</component>
|
||||
</ContextMenu.Portal>
|
||||
</template>
|
||||
|
||||
@@ -98,6 +98,8 @@ export type DropdownMenuSlots<
|
||||
'item-leading': SlotProps<T>
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
'content-top': (props?: {}) => any
|
||||
'content-bottom': (props?: {}) => any
|
||||
} & DynamicSlots<MergeTypes<T>, 'leading' | 'label' | 'trailing', { active?: boolean, index: number }>
|
||||
|
||||
</script>
|
||||
|
||||
@@ -113,6 +113,8 @@ const groups = computed<DropdownMenuItem[][]>(() =>
|
||||
|
||||
<DropdownMenu.Portal v-bind="portalProps">
|
||||
<component :is="sub ? DropdownMenu.SubContent : DropdownMenu.Content" :class="props.class" v-bind="contentProps">
|
||||
<slot name="content-top" />
|
||||
|
||||
<DropdownMenu.Group v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: uiOverride?.group })">
|
||||
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
||||
<DropdownMenu.Label v-if="item.type === 'label'" :class="ui.label({ class: uiOverride?.label })">
|
||||
@@ -179,6 +181,8 @@ const groups = computed<DropdownMenuItem[][]>(() =>
|
||||
</DropdownMenu.Group>
|
||||
|
||||
<slot />
|
||||
|
||||
<slot name="content-bottom" />
|
||||
</component>
|
||||
</DropdownMenu.Portal>
|
||||
</template>
|
||||
|
||||
@@ -162,6 +162,8 @@ export interface InputMenuSlots<
|
||||
'item-trailing': SlotProps<T>
|
||||
'tags-item-text': SlotProps<T>
|
||||
'tags-item-delete': SlotProps<T>
|
||||
'content-top': (props?: {}) => any
|
||||
'content-bottom': (props?: {}) => any
|
||||
'create-item-label'(props: { item: string }): any
|
||||
}
|
||||
</script>
|
||||
@@ -478,6 +480,8 @@ defineExpose({
|
||||
|
||||
<ComboboxPortal v-bind="portalProps">
|
||||
<ComboboxContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
||||
<slot name="content-top" />
|
||||
|
||||
<ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
|
||||
<slot name="empty" :search-term="searchTerm">
|
||||
{{ searchTerm ? t('inputMenu.noMatch', { searchTerm }) : t('inputMenu.noData') }}
|
||||
@@ -537,6 +541,8 @@ defineExpose({
|
||||
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'bottom'" />
|
||||
</ComboboxViewport>
|
||||
|
||||
<slot name="content-bottom" />
|
||||
|
||||
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
||||
</ComboboxContent>
|
||||
</ComboboxPortal>
|
||||
|
||||
@@ -123,6 +123,8 @@ export type NavigationMenuSlots<
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
'item-content': SlotProps<T>
|
||||
'list-leading': (props?: {}) => any
|
||||
'list-trailing': (props?: {}) => any
|
||||
} & DynamicSlots<MergeTypes<T>, 'leading' | 'label' | 'trailing' | 'content', { index: number, active?: boolean }>
|
||||
|
||||
</script>
|
||||
@@ -303,6 +305,8 @@ const lists = computed<NavigationMenuItem[][]>(() =>
|
||||
</DefineItemTemplate>
|
||||
|
||||
<NavigationMenuRoot v-bind="rootProps" :data-collapsed="collapsed" :class="ui.root({ class: [props.class, props.ui?.root] })">
|
||||
<slot name="list-leading" />
|
||||
|
||||
<template v-for="(list, listIndex) in lists" :key="`list-${listIndex}`">
|
||||
<NavigationMenuList :class="ui.list({ class: props.ui?.list })">
|
||||
<ReuseItemTemplate v-for="(item, index) in list" :key="`list-${listIndex}-${index}`" :item="item" :index="index" :class="ui.item({ class: props.ui?.item })" />
|
||||
@@ -311,6 +315,8 @@ const lists = computed<NavigationMenuItem[][]>(() =>
|
||||
<div v-if="orientation === 'vertical' && listIndex < lists.length - 1" :class="ui.separator({ class: props.ui?.separator })" />
|
||||
</template>
|
||||
|
||||
<slot name="list-trailing" />
|
||||
|
||||
<div v-if="orientation === 'horizontal'" :class="ui.viewportWrapper({ class: props.ui?.viewportWrapper })">
|
||||
<NavigationMenuIndicator v-if="arrow" :class="ui.indicator({ class: props.ui?.indicator })">
|
||||
<div :class="ui.arrow({ class: props.ui?.arrow })" />
|
||||
|
||||
@@ -126,6 +126,8 @@ export interface SelectSlots<
|
||||
'item-leading': SlotProps<T>
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
'content-top': (props?: {}) => any
|
||||
'content-bottom': (props?: {}) => any
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -264,6 +266,8 @@ function isSelectItem(item: SelectItem): item is SelectItemBase {
|
||||
|
||||
<SelectPortal v-bind="portalProps">
|
||||
<SelectContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
||||
<slot name="content-top" />
|
||||
|
||||
<SelectViewport :class="ui.viewport({ class: props.ui?.viewport })">
|
||||
<SelectGroup v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
||||
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
||||
@@ -313,6 +317,8 @@ function isSelectItem(item: SelectItem): item is SelectItemBase {
|
||||
</SelectGroup>
|
||||
</SelectViewport>
|
||||
|
||||
<slot name="content-bottom" />
|
||||
|
||||
<SelectArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
||||
</SelectContent>
|
||||
</SelectPortal>
|
||||
|
||||
@@ -156,6 +156,8 @@ export interface SelectMenuSlots<
|
||||
'item-leading': SlotProps<T>
|
||||
'item-label': SlotProps<T>
|
||||
'item-trailing': SlotProps<T>
|
||||
'content-top': (props?: {}) => any
|
||||
'content-bottom': (props?: {}) => any
|
||||
'create-item-label'(props: { item: string }): any
|
||||
}
|
||||
</script>
|
||||
@@ -401,6 +403,8 @@ function isSelectItem(item: SelectMenuItem): item is _SelectMenuItem {
|
||||
<ComboboxPortal v-bind="portalProps">
|
||||
<ComboboxContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
||||
<FocusScope trapped :class="ui.focusScope({ class: props.ui?.focusScope })">
|
||||
<slot name="content-top" />
|
||||
|
||||
<ComboboxInput v-if="!!searchInput" v-model="searchTerm" :display-value="() => searchTerm" as-child>
|
||||
<UInput autofocus autocomplete="off" v-bind="searchInputProps" :class="ui.input({ class: props.ui?.input })" />
|
||||
</ComboboxInput>
|
||||
@@ -463,6 +467,8 @@ function isSelectItem(item: SelectMenuItem): item is _SelectMenuItem {
|
||||
|
||||
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'bottom'" />
|
||||
</ComboboxViewport>
|
||||
|
||||
<slot name="content-bottom" />
|
||||
</FocusScope>
|
||||
|
||||
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
||||
|
||||
Reference in New Issue
Block a user