feat(ContextMenu/DropdownMenu): handle checkbox items type

Resolves #2144
This commit is contained in:
Benjamin Canac
2024-10-15 17:06:17 +02:00
parent 0759e29c22
commit 8ef6e712ac
9 changed files with 451 additions and 336 deletions

View File

@@ -1,3 +1,4 @@
<!-- eslint-disable vue/block-tag-newline -->
<script lang="ts">
import { tv } from 'tailwind-variants'
import type { DropdownMenuContentProps as RadixDropdownMenuContentProps, DropdownMenuContentEmits as RadixDropdownMenuContentEmits } from 'radix-vue'
@@ -11,6 +12,7 @@ interface DropdownMenuContentProps<T> extends Omit<RadixDropdownMenuContentProps
portal?: boolean
sub?: boolean
labelKey: string
checkedIcon?: string
class?: any
ui: typeof _dropdownMenu
uiOverride?: any
@@ -21,6 +23,7 @@ interface DropdownMenuContentEmits extends RadixDropdownMenuContentEmits {}
type DropdownMenuContentSlots<T extends { slot?: string }> = Omit<DropdownMenuSlots<T>, 'default'> & {
default(props?: {}): any
}
</script>
<script setup lang="ts" generic="T extends DropdownMenuItem">
@@ -66,13 +69,17 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
<UIcon v-if="item.target === '_blank'" :name="appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, active })" />
</span>
<span v-if="item.children?.length || item.kbds?.length || !!slots[item.slot ? `${item.slot}-trailing`: 'item-trailing']" :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
<span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
<slot :name="item.slot ? `${item.slot}-trailing`: 'item-trailing'" :item="(item as T)" :active="active" :index="index">
<UIcon v-if="item.children?.length" :name="appConfig.ui.icons.chevronRight" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, active })" />
<span v-else-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: uiOverride?.itemTrailingKbds })">
<UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.uiOverride?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
</span>
</slot>
<DropdownMenu.ItemIndicator as-child>
<UIcon :name="checkedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon })" />
</DropdownMenu.ItemIndicator>
</span>
</slot>
</DefineItemTemplate>
@@ -115,7 +122,24 @@ const groups = computed(() => props.items?.length ? (Array.isArray(props.items[0
</template>
</UDropdownMenuContent>
</DropdownMenu.Sub>
<DropdownMenu.Item v-else as-child :disabled="item.disabled" :text-value="get(item, props.labelKey as string)" @select="item.onSelect">
<DropdownMenu.CheckboxItem
v-else-if="item.type === 'checkbox'"
:checked="item.checked"
:disabled="item.disabled"
:text-value="get(item, props.labelKey as string)"
:class="ui.item({ class: [uiOverride?.item, item.class] })"
@update:checked="item.onUpdateChecked"
@select="item.onSelect"
>
<ReuseItemTemplate :item="item" :index="index" />
</DropdownMenu.CheckboxItem>
<DropdownMenu.Item
v-else
as-child
:disabled="item.disabled"
:text-value="get(item, props.labelKey as string)"
@select="item.onSelect"
>
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<DropdownMenuItem, 'type'>)" custom>
<ULinkBase v-bind="slotProps" :class="ui.item({ class: [uiOverride?.item, item.class], active })">
<ReuseItemTemplate :item="item" :active="active" :index="index" />