mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-02-01 20:57:57 +01:00
@@ -134,7 +134,7 @@ extendDevtoolsMeta({ defaultProps: { items: ['Option 1', 'Option 2', 'Option 3']
|
|||||||
|
|
||||||
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false">
|
<script setup lang="ts" generic="T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false">
|
||||||
import { computed, toRef, toRaw } from 'vue'
|
import { computed, toRef, toRaw } from 'vue'
|
||||||
import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, useForwardPropsEmits, useFilter } from 'reka-ui'
|
import { ComboboxRoot, ComboboxArrow, ComboboxAnchor, ComboboxInput, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxViewport, ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxItem, ComboboxItemIndicator, FocusScope, useForwardPropsEmits, useFilter } from 'reka-ui'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { reactivePick, createReusableTemplate } from '@vueuse/core'
|
import { reactivePick, createReusableTemplate } from '@vueuse/core'
|
||||||
import { useAppConfig } from '#imports'
|
import { useAppConfig } from '#imports'
|
||||||
@@ -337,68 +337,70 @@ function onUpdateOpen(value: boolean) {
|
|||||||
|
|
||||||
<ComboboxPortal :disabled="!portal">
|
<ComboboxPortal :disabled="!portal">
|
||||||
<ComboboxContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
<ComboboxContent :class="ui.content({ class: props.ui?.content })" v-bind="contentProps">
|
||||||
<ComboboxInput v-if="!!searchInput" v-model="searchTerm" :display-value="() => searchTerm" as-child>
|
<FocusScope trapped :class="ui.focusScope({ class: props.ui?.focusScope })">
|
||||||
<UInput autofocus autocomplete="off" v-bind="searchInputProps" :class="ui.input({ class: props.ui?.input })" />
|
<ComboboxInput v-if="!!searchInput" v-model="searchTerm" :display-value="() => searchTerm" as-child>
|
||||||
</ComboboxInput>
|
<UInput autofocus autocomplete="off" v-bind="searchInputProps" :class="ui.input({ class: props.ui?.input })" />
|
||||||
|
</ComboboxInput>
|
||||||
|
|
||||||
<ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
|
<ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })">
|
||||||
<slot name="empty" :search-term="searchTerm">
|
<slot name="empty" :search-term="searchTerm">
|
||||||
{{ searchTerm ? t('selectMenu.noMatch', { searchTerm }) : t('selectMenu.noData') }}
|
{{ searchTerm ? t('selectMenu.noMatch', { searchTerm }) : t('selectMenu.noData') }}
|
||||||
</slot>
|
</slot>
|
||||||
</ComboboxEmpty>
|
</ComboboxEmpty>
|
||||||
|
|
||||||
<ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
|
<ComboboxViewport :class="ui.viewport({ class: props.ui?.viewport })">
|
||||||
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'top'" />
|
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'top'" />
|
||||||
|
|
||||||
<ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
<ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })">
|
||||||
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
<template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
|
||||||
<ComboboxLabel v-if="item?.type === 'label'" :class="ui.label({ class: props.ui?.label })">
|
<ComboboxLabel v-if="item?.type === 'label'" :class="ui.label({ class: props.ui?.label })">
|
||||||
{{ get(item, props.labelKey as string) }}
|
{{ get(item, props.labelKey as string) }}
|
||||||
</ComboboxLabel>
|
</ComboboxLabel>
|
||||||
|
|
||||||
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
||||||
|
|
||||||
<ComboboxItem
|
<ComboboxItem
|
||||||
v-else
|
v-else
|
||||||
:class="ui.item({ class: props.ui?.item })"
|
:class="ui.item({ class: props.ui?.item })"
|
||||||
:disabled="item.disabled"
|
:disabled="item.disabled"
|
||||||
:value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
|
:value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
|
||||||
@select="item.onSelect"
|
@select="item.onSelect"
|
||||||
>
|
>
|
||||||
<slot name="item" :item="(item as T)" :index="index">
|
<slot name="item" :item="(item as T)" :index="index">
|
||||||
<slot name="item-leading" :item="(item as T)" :index="index">
|
<slot name="item-leading" :item="(item as T)" :index="index">
|
||||||
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
<UIcon v-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: props.ui?.itemLeadingIcon })" />
|
||||||
<UAvatar v-else-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
<UAvatar v-else-if="item.avatar" :size="((props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
||||||
<UChip
|
<UChip
|
||||||
v-else-if="item.chip"
|
v-else-if="item.chip"
|
||||||
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
:size="((props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()) as ChipProps['size'])"
|
||||||
inset
|
inset
|
||||||
standalone
|
standalone
|
||||||
v-bind="item.chip"
|
v-bind="item.chip"
|
||||||
:class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
|
:class="ui.itemLeadingChip({ class: props.ui?.itemLeadingChip })"
|
||||||
/>
|
/>
|
||||||
</slot>
|
|
||||||
|
|
||||||
<span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
|
||||||
<slot name="item-label" :item="(item as T)" :index="index">
|
|
||||||
{{ typeof item === 'object' ? get(item, props.labelKey as string) : item }}
|
|
||||||
</slot>
|
</slot>
|
||||||
</span>
|
|
||||||
|
|
||||||
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
<span :class="ui.itemLabel({ class: props.ui?.itemLabel })">
|
||||||
<slot name="item-trailing" :item="(item as T)" :index="index" />
|
<slot name="item-label" :item="(item as T)" :index="index">
|
||||||
|
{{ typeof item === 'object' ? get(item, props.labelKey as string) : item }}
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
|
||||||
<ComboboxItemIndicator as-child>
|
<span :class="ui.itemTrailing({ class: props.ui?.itemTrailing })">
|
||||||
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
<slot name="item-trailing" :item="(item as T)" :index="index" />
|
||||||
</ComboboxItemIndicator>
|
|
||||||
</span>
|
|
||||||
</slot>
|
|
||||||
</ComboboxItem>
|
|
||||||
</template>
|
|
||||||
</ComboboxGroup>
|
|
||||||
|
|
||||||
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'bottom'" />
|
<ComboboxItemIndicator as-child>
|
||||||
</ComboboxViewport>
|
<UIcon :name="selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: props.ui?.itemTrailingIcon })" />
|
||||||
|
</ComboboxItemIndicator>
|
||||||
|
</span>
|
||||||
|
</slot>
|
||||||
|
</ComboboxItem>
|
||||||
|
</template>
|
||||||
|
</ComboboxGroup>
|
||||||
|
|
||||||
|
<ReuseCreateItemTemplate v-if="createItem && createItemPosition === 'bottom'" />
|
||||||
|
</ComboboxViewport>
|
||||||
|
</FocusScope>
|
||||||
|
|
||||||
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
<ComboboxArrow v-if="!!arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" />
|
||||||
</ComboboxContent>
|
</ComboboxContent>
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import select from './select'
|
|||||||
export default (options: Required<ModuleOptions>) => {
|
export default (options: Required<ModuleOptions>) => {
|
||||||
return defu({
|
return defu({
|
||||||
slots: {
|
slots: {
|
||||||
input: 'border-b border-(--ui-border)'
|
input: 'border-b border-(--ui-border)',
|
||||||
|
focusScope: 'flex flex-col min-h-0'
|
||||||
}
|
}
|
||||||
}, select(options))
|
}, select(options))
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user