feat(Input/InputMenu/Select/SelectMenu): handle avatar prop

This commit is contained in:
Benjamin Canac
2024-10-17 18:21:12 +02:00
parent df2013ca92
commit 53a3796d1b
42 changed files with 618 additions and 842 deletions

View File

@@ -17,14 +17,13 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
:loading="status === 'pending'"
icon="i-heroicons-user"
placeholder="Select user"
class="w-48"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>
</UInputMenu>

View File

@@ -23,14 +23,13 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
:filter="false"
icon="i-heroicons-user"
placeholder="Select user"
class="w-48"
>
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>
</UInputMenu>

View File

@@ -25,8 +25,8 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>

View File

@@ -1,11 +1,11 @@
<script setup lang="ts">
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
const value = ref('Backlog')
</script>
<template>
<UInputMenu
v-model="selected"
v-model="value"
:items="items"
:ui="{
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'

View File

@@ -25,18 +25,9 @@ const items = ref([
}
}
])
const selected = ref(items.value[0])
const value = ref(items.value[0])
</script>
<template>
<UInputMenu v-model="selected" :items="items" class="w-40">
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</UInputMenu>
<UInputMenu v-model="value" :avatar="value?.avatar" :items="items" />
</template>

View File

@@ -22,11 +22,11 @@ const items = ref([
}
}
])
const selected = ref(items.value[0])
const value = ref(items.value[0])
</script>
<template>
<UInputMenu v-model="selected" :items="items" class="w-40">
<UInputMenu v-model="value" :items="items">
<template #leading="{ modelValue, ui }">
<UChip
v-if="modelValue"

View File

@@ -21,9 +21,9 @@ const items = ref([
icon: 'i-heroicons-check-circle'
}
])
const selected = ref(items.value[0])
const value = ref(items.value[0])
</script>
<template>
<UInputMenu v-model="selected" :icon="selected?.icon" :items="items" class="w-40" />
<UInputMenu v-model="value" :icon="value?.icon" :items="items" />
</template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
const open = ref(false)
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
const value = ref('Backlog')
defineShortcuts({
o: () => open.value = !open.value
@@ -9,5 +9,5 @@ defineShortcuts({
</script>
<template>
<UInputMenu v-model="selected" v-model:open="open" :items="items" />
<UInputMenu v-model="value" v-model:open="open" :items="items" />
</template>

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
const searchTerm = ref('D')
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
const value = ref('Backlog')
</script>
<template>
<UInputMenu v-model="selected" v-model:search-term="searchTerm" :items="items" />
<UInputMenu v-model="value" v-model:search-term="searchTerm" :items="items" />
</template>

View File

@@ -23,8 +23,8 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>
</USelectMenu>

View File

@@ -29,8 +29,8 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>
</USelectMenu>

View File

@@ -25,8 +25,8 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>

View File

@@ -1,15 +1,15 @@
<script setup lang="ts">
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
const value = ref('Backlog')
</script>
<template>
<USelectMenu
v-model="selected"
v-model="value"
:items="items"
:ui="{
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
}"
class="w-40"
class="w-48"
/>
</template>

View File

@@ -25,18 +25,9 @@ const items = ref([
}
}
])
const selected = ref(items.value[0])
const value = ref(items.value[0])
</script>
<template>
<USelectMenu v-model="selected" :items="items" class="w-48">
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</USelectMenu>
<USelectMenu v-model="value" :avatar="value?.avatar" :items="items" class="w-48" />
</template>

View File

@@ -22,11 +22,11 @@ const items = ref([
}
}
])
const selected = ref(items.value[0])
const value = ref(items.value[0])
</script>
<template>
<USelectMenu v-model="selected" :items="items" class="w-40">
<USelectMenu v-model="value" :items="items" class="w-48">
<template #leading="{ modelValue, ui }">
<UChip
v-if="modelValue"

View File

@@ -21,9 +21,9 @@ const items = ref([
icon: 'i-heroicons-check-circle'
}
])
const selected = ref(items.value[0])
const value = ref(items.value[0])
</script>
<template>
<USelectMenu v-model="selected" :icon="selected?.icon" :items="items" class="w-40" />
<USelectMenu v-model="value" :icon="value?.icon" :items="items" class="w-48" />
</template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
const open = ref(false)
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
const value = ref('Backlog')
defineShortcuts({
o: () => open.value = !open.value
@@ -9,5 +9,5 @@ defineShortcuts({
</script>
<template>
<USelectMenu v-model="selected" v-model:open="open" :items="items" class="w-40" />
<USelectMenu v-model="value" v-model:open="open" :items="items" class="w-48" />
</template>

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
const searchTerm = ref('D')
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const selected = ref('Backlog')
const value = ref('Backlog')
</script>
<template>
<USelectMenu v-model="selected" v-model:search-term="searchTerm" :items="items" class="w-40" />
<USelectMenu v-model="value" v-model:search-term="searchTerm" :items="items" class="w-48" />
</template>

View File

@@ -27,8 +27,8 @@ function getUserAvatar(value: string) {
<UAvatar
v-if="modelValue"
v-bind="getUserAvatar(modelValue)"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
:size="ui.leadingAvatarSize()"
:class="ui.leadingAvatar()"
/>
</template>
</USelect>

View File

@@ -1,14 +1,15 @@
<script setup lang="ts">
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const value = ref('Backlog')
</script>
<template>
<USelect
default-value="Backlog"
v-model="value"
:items="items"
:ui="{
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
}"
class="w-40"
class="w-48"
/>
</template>

View File

@@ -25,21 +25,11 @@ const items = ref([
}
}
])
const value = ref(items.value[0]?.value)
function getAvatar(value: string) {
return items.value.find(item => item.value === value)?.avatar
}
const avatar = computed(() => items.value.find(item => item.value === value.value)?.avatar)
</script>
<template>
<USelect default-value="benjamincanac" :items="items" class="w-48">
<template #leading="{ modelValue, ui }">
<UAvatar
v-if="modelValue"
v-bind="getAvatar(modelValue)"
:size="ui.itemLeadingAvatarSize()"
:class="ui.itemLeadingAvatar()"
/>
</template>
</USelect>
<USelect v-model="value" :avatar="avatar" :items="items" class="w-48" />
</template>

View File

@@ -22,6 +22,7 @@ const items = ref([
}
}
])
const value = ref(items.value[0]?.value)
function getChip(value: string) {
return items.value.find(item => item.value === value)?.chip
@@ -29,7 +30,7 @@ function getChip(value: string) {
</script>
<template>
<USelect default-value="bug" :items="items" class="w-40">
<USelect v-model="value" :items="items" class="w-48">
<template #leading="{ modelValue, ui }">
<UChip
v-if="modelValue"

View File

@@ -1,5 +1,4 @@
<script setup lang="ts">
const selected = ref('backlog')
const items = ref([
{
label: 'Backlog',
@@ -22,10 +21,11 @@ const items = ref([
icon: 'i-heroicons-check-circle'
}
])
const value = ref(items.value[0]?.value)
const icon = computed(() => items.value.find(item => item.value === selected.value)?.icon)
const icon = computed(() => items.value.find(item => item.value === value.value)?.icon)
</script>
<template>
<USelect v-model="selected" :icon="icon" :items="items" class="w-40" />
<USelect v-model="value" :icon="icon" :items="items" class="w-48" />
</template>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
const open = ref(false)
const items = ref(['Backlog', 'Todo', 'In Progress', 'Done'])
const value = ref('Backlog')
defineShortcuts({
o: () => open.value = !open.value
@@ -8,5 +9,5 @@ defineShortcuts({
</script>
<template>
<USelect v-model:open="open" default-value="Backlog" :items="items" class="w-40" />
<USelect v-model="value" v-model:open="open" :items="items" class="w-48" />
</template>

View File

@@ -413,6 +413,32 @@ props:
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::
### Avatar
Use the `avatar` prop to show an [Avatar](/components/avatar) inside the InputMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
external:
- items
- modelValue
props:
modelValue: 'Nuxt'
avatar:
src: 'https://github.com/nuxt.png'
items:
- Nuxt
- NuxtHub
- NuxtLabs
- Nuxt Modules
- Nuxt Community
---
::
### Loading
Use the `loading` prop to show a loading icon on the InputMenu.
@@ -538,7 +564,7 @@ name: 'input-menu-items-icon-example'
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
You can also use the `#leading` slot to display the selected icon.
::
### With avatar in items
@@ -552,8 +578,8 @@ name: 'input-menu-items-avatar-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
::tip
You can also use the `#leading` slot to display the selected avatar.
::
### With chip in items

View File

@@ -136,6 +136,24 @@ props:
---
::
### Avatar
Use the `avatar` prop to show an [Avatar](/components/avatar) inside the Input.
::component-code
---
prettier: true
ignore:
- placeholder
props:
avatar:
src: 'https://github.com/nuxt.png'
size: md
variant: outline
placeholder: 'Search...'
---
::
### Loading
Use the `loading` prop to show a loading icon on the Input.

View File

@@ -43,7 +43,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -74,7 +74,7 @@ props:
- label: 'Todo'
- label: 'In Progress'
- label: 'Done'
class: 'w-40'
class: 'w-48'
---
::
@@ -107,7 +107,7 @@ props:
- Carrot
- Courgette
- Leek
class: 'w-40'
class: 'w-48'
---
::
@@ -138,7 +138,7 @@ props:
id: 'in_progress'
- label: 'Done'
id: 'done'
class: 'w-40'
class: 'w-48'
---
::
@@ -167,7 +167,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -194,7 +194,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -228,7 +228,7 @@ props:
icon: 'i-heroicons-arrow-up-circle'
- label: Done
icon: 'i-heroicons-check-circle'
class: 'w-40'
class: 'w-48'
---
::
@@ -271,7 +271,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -298,7 +298,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -330,7 +330,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -356,7 +356,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -383,7 +383,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -410,7 +410,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -441,7 +441,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -449,6 +449,34 @@ props:
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::
### Avatar
Use the `avatar` prop to display an [Avatar](/components/avatar) inside the SelectMenu.
::component-code
---
prettier: true
ignore:
- items
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Nuxt'
avatar:
src: 'https://github.com/nuxt.png'
items:
- Nuxt
- NuxtHub
- NuxtLabs
- Nuxt Modules
- Nuxt Community
class: 'w-48'
---
::
### Loading
Use the `loading` prop to show a loading icon on the SelectMenu.
@@ -472,7 +500,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -499,7 +527,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -528,7 +556,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -566,7 +594,7 @@ props:
- Carrot
- Courgette
- Leek
class: 'w-40'
class: 'w-48'
---
::
@@ -582,7 +610,7 @@ name: 'select-menu-items-icon-example'
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
You can also use the `#leading` slot to display the selected icon.
::
### With avatar in items
@@ -596,8 +624,8 @@ name: 'select-menu-items-avatar-example'
---
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
::tip
You can also use the `#leading` slot to display the selected avatar.
::
### With chip in items

View File

@@ -34,7 +34,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -68,7 +68,7 @@ props:
value: 'in_progress'
- label: 'Done'
value: 'done'
class: 'w-40'
class: 'w-48'
---
::
@@ -101,7 +101,7 @@ props:
- Carrot
- Courgette
- Leek
class: 'w-40'
class: 'w-48'
---
::
@@ -131,7 +131,7 @@ props:
id: 'in_progress'
- label: 'Done'
id: 'done'
class: 'w-40'
class: 'w-48'
---
::
@@ -154,7 +154,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -171,10 +171,11 @@ The `content.align`, `content.side`, etc. properties only apply when `content.po
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
items:
content.position:
- 'item-aligned'
@@ -189,6 +190,7 @@ items:
- top
- bottom
props:
modelValue: 'Todo'
content:
position: 'item-aligned'
align: center
@@ -199,8 +201,7 @@ props:
- Todo
- In Progress
- Done
defaultValue: 'Todo'
class: 'w-40'
class: 'w-48'
---
::
@@ -217,20 +218,21 @@ Use the `color` prop to change the ring color when the Select is focused.
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
color: neutral
highlight: true
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -247,21 +249,22 @@ Use the `variant` prop to change the variant of the Select.
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
color: neutral
variant: subtle
highlight: false
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -274,19 +277,20 @@ Use the `size` prop to change the size of the Select.
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
size: xl
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -299,20 +303,21 @@ Use the `icon` prop to show an [Icon](/components/icon) inside the Select.
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
icon: 'i-heroicons-magnifying-glass'
size: md
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -325,20 +330,21 @@ Use the `trailing-icon` prop to customize the trailing [Icon](/components/icon).
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
trailingIcon: 'i-heroicons-arrow-small-down-20-solid'
size: md
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -355,20 +361,21 @@ Use the `selected-icon` prop to customize the icon when an item is selected. Def
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
selectedIcon: 'i-heroicons-fire'
size: md
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -376,6 +383,34 @@ props:
You can customize this icon globally in your `app.config.ts` under `ui.icons.check` key.
::
### Avatar
Use the `avatar` prop to show an [Avatar](/components/avatar) inside the Select.
::component-code
---
prettier: true
ignore:
- items
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Nuxt'
avatar:
src: 'https://github.com/nuxt.png'
items:
- Nuxt
- NuxtHub
- NuxtLabs
- Nuxt Modules
- Nuxt Community
class: 'w-48'
---
::
### Loading
Use the `loading` prop to show a loading icon on the Select.
@@ -385,20 +420,21 @@ Use the `loading` prop to show a loading icon on the Select.
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
loading: true
trailing: false
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -411,20 +447,21 @@ Use the `loading-icon` prop to customize the loading icon. Defaults to `i-heroic
prettier: true
ignore:
- items
- defaultValue
- modelValue
- class
external:
- items
- modelValue
props:
modelValue: 'Backlog'
loading: true
loadingIcon: 'i-heroicons-arrow-path-rounded-square'
defaultValue: 'Backlog'
items:
- Backlog
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -453,7 +490,7 @@ props:
- Todo
- In Progress
- Done
class: 'w-40'
class: 'w-48'
---
::
@@ -491,7 +528,7 @@ props:
- Carrot
- Courgette
- Leek
class: 'w-40'
class: 'w-48'
---
::
@@ -511,7 +548,7 @@ In this example, the icon is computed from the `value` property of the selected
::
::tip
You can also use the `#leading` slot to display the selected icon, like in the next example.
You can also use the `#leading` slot to display the selected icon.
::
### With avatar in items
@@ -526,7 +563,11 @@ name: 'select-items-avatar-example'
::
::note
In this example, the `#leading` slot is used to display the selected avatar.
In this example, the avatar is computed from the `value` property of the selected item.
::
::tip
You can also use the `#leading` slot to display the selected avatar.
::
### With chip in items