Skip to content

Commit

Permalink
feat(VSelect): implement item slot
Browse files Browse the repository at this point in the history
also renamed InternalItem.originalItem to InternalItem.raw, and exposed
InternalItem on slots
  • Loading branch information
KaelWD committed Jun 16, 2022
1 parent 2185fe7 commit 9537787
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 116 deletions.
@@ -1,39 +1,23 @@
<template>
<v-card
color="blue-grey darken-1"
color="blue-grey-darken-1"
dark
:loading="isUpdating"
>
<template v-slot:progress>
<v-progress-linear
absolute
color="green lighten-3"
color="green-lighten-3"
height="4"
indeterminate
></v-progress-linear>
</template>
<v-img
height="200"
src="https://cdn.vuetifyjs.com/images/cards/dark-beach.jpg"
>
<v-img height="200" src="https://cdn.vuetifyjs.com/images/cards/dark-beach.jpg">
<v-row>
<v-col
class="text-right"
cols="12"
>
<v-menu
bottom
left
transition="slide-y-transition"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
icon
v-bind="attrs"
v-on="on"
>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
<v-col class="text-end" cols="12">
<v-menu location="bottom start" origin="overlap" transition="slide-y-transition">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" icon="mdi-dots-vertical" variant="text"></v-btn>
</template>
<v-list>
<v-list-item @click="isUpdating = true">
Expand All @@ -56,35 +40,29 @@
<h3 class="text-h5">
{{ name }}
</h3>
<span class="grey--text text--lighten-1">{{ title }}</span>
<span class="text-grey-lighten-1">{{ title }}</span>
</v-col>
</v-row>
</v-row>
</v-img>
<v-form>
<v-container>
<v-row>
<v-col
cols="12"
md="6"
>
<v-col cols="12" md="6">
<v-text-field
v-model="name"
:disabled="isUpdating"
filled
color="blue-grey lighten-2"
color="blue-grey-lighten-2"
label="Name"
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-col cols="12" md="6">
<v-text-field
v-model="title"
:disabled="isUpdating"
filled
color="blue-grey lighten-2"
color="blue-grey-lighten-2"
label="Title"
></v-text-field>
</v-col>
Expand All @@ -95,39 +73,29 @@
:items="people"
filled
chips
color="blue-grey lighten-2"
closable-chips
color="blue-grey-lighten-2"
label="Select"
item-title="name"
item-value="name"
multiple
>
<template v-slot:selection="data">
<template v-slot:chip="{ props, item }">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
close
@click="data.select"
@click:close="remove(data.item)"
>
<v-avatar left>
<v-img :src="data.item.avatar"></v-img>
</v-avatar>
{{ data.item.name }}
</v-chip>
v-bind="props"
:prepend-avatar="item.raw.avatar"
:text="item.raw.name"
></v-chip>
</template>
<template v-slot:item="data">
<template v-if="typeof data.item !== 'object'">
<v-list-item-content v-text="data.item"></v-list-item-content>
</template>
<template v-else>
<v-list-item-avatar>
<img :src="data.item.avatar">
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title v-html="data.item.name"></v-list-item-title>
<v-list-item-subtitle v-html="data.item.group"></v-list-item-subtitle>
</v-list-item-content>
</template>
<template v-slot:item="{ props, item }">
<v-list-item v-if="typeof item.raw !== 'object'" v-bind="props"></v-list-item>
<v-list-item
v-else
v-bind="props"
:prepend-avatar="item.raw.avatar"
:title="item.raw.name"
:subtitle="item.raw.group"
></v-list-item>
</template>
</v-autocomplete>
</v-col>
Expand All @@ -140,21 +108,18 @@
v-model="autoUpdate"
:disabled="isUpdating"
class="mt-0"
color="green lighten-2"
color="green-lighten-2"
hide-details
label="Auto Update"
></v-switch>
<v-spacer></v-spacer>
<v-btn
:disabled="autoUpdate"
:loading="isUpdating"
color="blue-grey darken-3"
depressed
color="blue-grey-lighten-3"
prepend-icon="mdi-update"
@click="isUpdating = true"
>
<v-icon start>
mdi-update
</v-icon>
Update Now
</v-btn>
</v-card-actions>
Expand Down
19 changes: 11 additions & 8 deletions packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx
Expand Up @@ -19,7 +19,7 @@ import { useLocale } from '@/composables/locale'
import { useProxiedModel } from '@/composables/proxiedModel'

// Utility
import { computed, nextTick, ref, watch } from 'vue'
import { computed, mergeProps, nextTick, ref, watch } from 'vue'
import { genericComponent, useRender, wrapInArray } from '@/util'

// Types
Expand Down Expand Up @@ -251,7 +251,10 @@ export const VAutocomplete = genericComponent<new <
<VListItem title={ t(props.noDataText) } />
)) }

{ filteredItems.value.map(({ item, matches }) => (
{ filteredItems.value.map(({ item, matches }) => slots.item?.({
item,
props: mergeProps(item.props, { onClick: () => select(item) }),
}) ?? (
<VListItem
{ ...item.props }
onClick={ () => select(item) }
Expand All @@ -271,12 +274,12 @@ export const VAutocomplete = genericComponent<new <
</VList>
</VMenu>

{ selections.value.map((selection, index) => {
{ selections.value.map((item, index) => {
function onChipClose (e: Event) {
e.stopPropagation()
e.preventDefault()

select(selection)
select(item)
}

const slotProps = {
Expand All @@ -292,21 +295,21 @@ export const VAutocomplete = genericComponent<new <
VChip: {
closable: props.closableChips,
size: 'small',
text: selection.props.title,
text: item.title,
},
}}
>
{ slots.chip
? slots.chip({ props: slotProps, item: selection.originalItem, index })
? slots.chip({ props: slotProps, item, index })
: (<VChip { ...slotProps } />)
}
</VDefaultsProvider>
) : (
slots.selection
? slots.selection({ item: selection.originalItem, index })
? slots.selection({ item, index })
: (
<span class="v-autocomplete__selection-text">
{ selection.props.title }
{ item.title }
{ props.multiple && (index < selections.value.length - 1) && (
<span class="v-autocomplete__selection-comma">,</span>
) }
Expand Down
19 changes: 11 additions & 8 deletions packages/vuetify/src/components/VCombobox/VCombobox.tsx
Expand Up @@ -20,7 +20,7 @@ import { useProxiedModel } from '@/composables/proxiedModel'
import { useTextColor } from '@/composables/color'

// Utility
import { computed, nextTick, ref, watch } from 'vue'
import { computed, mergeProps, nextTick, ref, watch } from 'vue'
import { genericComponent, useRender, wrapInArray } from '@/util'

// Types
Expand Down Expand Up @@ -333,7 +333,10 @@ export const VCombobox = genericComponent<new <
<VListItem title={ t(props.noDataText) } />
)) }

{ filteredItems.value.map(({ item, matches }) => (
{ filteredItems.value.map(({ item, matches }) => slots.item?.({
item,
props: mergeProps(item.props, { onClick: () => select(item) }),
}) ?? (
<VListItem
{ ...item.props }
onClick={ () => select(item) }
Expand All @@ -353,12 +356,12 @@ export const VCombobox = genericComponent<new <
</VList>
</VMenu>

{ selections.value.map((selection, index) => {
{ selections.value.map((item, index) => {
function onChipClose (e: Event) {
e.stopPropagation()
e.preventDefault()

select(selection)
select(item)
}

const slotProps = {
Expand All @@ -383,21 +386,21 @@ export const VCombobox = genericComponent<new <
VChip: {
closable: props.closableChips,
size: 'small',
text: selection.props.title,
text: item.title,
},
}}
>
{ slots.chip
? slots.chip({ props: slotProps, item: selection.originalItem, index })
? slots.chip({ props: slotProps, item, index })
: (<VChip { ...slotProps } />)
}
</VDefaultsProvider>
) : (
slots.selection
? slots.selection({ item: selection.originalItem, index })
? slots.selection({ item, index })
: (
<span class="v-combobox__selection-text">
{ selection.props.title }
{ item.title }
{ props.multiple && (index < selections.value.length - 1) && (
<span class="v-combobox__selection-comma">,</span>
) }
Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VList/VList.tsx
Expand Up @@ -52,7 +52,7 @@ function transformItem (props: ItemProps & { itemType: string }, item: any): Int
value: _props.value,
props: _props,
children: type === 'item' && children ? transformItems(props, children) : undefined,
originalItem: item,
raw: item,
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VList/VListChildren.tsx
Expand Up @@ -36,7 +36,7 @@ export const VListChildren = genericComponent<new <T extends InternalListItem>()
setup (props, { slots }) {
createList()

return () => slots.default?.() ?? props.items?.map(({ children, props: itemProps, type, originalItem: item }) => {
return () => slots.default?.() ?? props.items?.map(({ children, props: itemProps, type, raw: item }) => {
if (type === 'divider') return <VDivider {...itemProps} />

if (type === 'subheader') return <VListSubheader {...itemProps} v-slots={ slots } />
Expand Down
19 changes: 11 additions & 8 deletions packages/vuetify/src/components/VSelect/VSelect.tsx
Expand Up @@ -19,7 +19,7 @@ import { useProxiedModel } from '@/composables/proxiedModel'
import { IconValue } from '@/composables/icons'

// Utility
import { computed, ref } from 'vue'
import { computed, mergeProps, ref } from 'vue'
import { genericComponent, propsFactory, useRender, wrapInArray } from '@/util'

// Types
Expand Down Expand Up @@ -207,7 +207,10 @@ export const VSelect = genericComponent<new <
<VListItem title={ t(props.noDataText) } />
)) }

{ items.value.map(item => (
{ items.value.map(item => slots.item?.({
item,
props: mergeProps(item.props, { onClick: () => select(item) }),
}) ?? (
<VListItem
{ ...item.props }
onClick={ () => select(item) }
Expand All @@ -222,12 +225,12 @@ export const VSelect = genericComponent<new <
</VList>
</VMenu>

{ selections.value.map((selection, index) => {
{ selections.value.map((item, index) => {
function onChipClose (e: Event) {
e.stopPropagation()
e.preventDefault()

select(selection)
select(item)
}

const slotProps = {
Expand All @@ -243,21 +246,21 @@ export const VSelect = genericComponent<new <
VChip: {
closable: props.closableChips,
size: 'small',
text: selection.props.title,
text: item.title,
},
}}
>
{ slots.chip
? slots.chip({ props: slotProps, selection, index })
? slots.chip({ props: slotProps, item, index })
: (<VChip { ...slotProps } />)
}
</VDefaultsProvider>
) : (
slots.selection
? slots.selection({ item: selection.originalItem, index })
? slots.selection({ item, index })
: (
<span class="v-select__selection-text">
{ selection.props.title }
{ item.title }
{ props.multiple && (index < selections.value.length - 1) && (
<span class="v-select__selection-comma">,</span>
) }
Expand Down

0 comments on commit 9537787

Please sign in to comment.