docs(SelectMenu): add slots examples

Resolves #557
This commit is contained in:
Benjamin Canac
2023-08-28 15:02:43 +02:00
parent b955f57084
commit 2e056fa3cf
4 changed files with 331 additions and 11 deletions

View File

@@ -0,0 +1,100 @@
<script setup>
const options = ref([
{ id: 1, name: 'bug', color: 'd73a4a' },
{ id: 2, name: 'documentation', color: '0075ca' },
{ id: 3, name: 'duplicate', color: 'cfd3d7' },
{ id: 4, name: 'enhancement', color: 'a2eeef' },
{ id: 5, name: 'good first issue', color: '7057ff' },
{ id: 6, name: 'help wanted', color: '008672' },
{ id: 7, name: 'invalid', color: 'e4e669' },
{ id: 8, name: 'question', color: 'd876e3' },
{ id: 9, name: 'wontfix', color: 'ffffff' }
])
const selected = ref([])
const labels = computed({
get: () => selected.value,
set: async (labels) => {
const promises = labels.map(async (label) => {
if (label.id) {
return label
}
// In a real app, you would make an API call to create the label
const response = {
name: label.name,
color: generateColorFromString(label.name)
}
options.value.push(response)
return response
})
selected.value = await Promise.all(promises)
}
})
function hashCode (str) {
let hash = 0
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash)
}
return hash
}
function intToRGB (i) {
const c = (i & 0x00FFFFFF)
.toString(16)
.toUpperCase()
return '00000'.substring(0, 6 - c.length) + c
}
function generateColorFromString (str) {
return intToRGB(hashCode(str))
}
</script>
<template>
<USelectMenu
v-model="labels"
by="id"
name="labels"
:options="options"
option-attribute="name"
multiple
searchable
creatable
>
<template #label>
<template v-if="labels.length">
<span class="flex items-center -space-x-1">
<span v-for="label of labels" :key="label.id" class="flex-shrink-0 w-2 h-2 mt-px rounded-full" :style="{ background: `#${label.color}` }" />
</span>
<span>{{ labels.length }} label{{ labels.length > 1 ? 's' : '' }}</span>
</template>
<template v-else>
<span class="text-gray-500 dark:text-gray-400 truncate">Select labels</span>
</template>
</template>
<template #option="{ option }">
<span
class="flex-shrink-0 w-2 h-2 mt-px rounded-full"
:style="{ background: `#${option.color}` }"
/>
<span class="truncate">{{ option.name }}</span>
</template>
<template #option-create="{ option }">
<span class="flex-shrink-0">New label:</span>
<span
class="flex-shrink-0 w-2 h-2 mt-px rounded-full -mx-1"
:style="{ background: `#${generateColorFromString(option.name)}` }"
/>
<span class="block truncate">{{ option.name }}</span>
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,13 @@
<script setup>
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
const selected = ref(people[0])
</script>
<template>
<USelectMenu v-model="selected" :options="people" searchable>
<template #option-empty="{ query }">
<q>{{ query }}</q> not found
</template>
</USelectMenu>
</template>

View File

@@ -0,0 +1,30 @@
<script setup>
const people = [
{ name: 'Wade Cooper', online: true },
{ name: 'Arlene Mccoy', online: false },
{ name: 'Devon Webb', online: false },
{ name: 'Tom Cook', online: true },
{ name: 'Tanya Fox', online: false },
{ name: 'Hellen Schmidt', online: true },
{ name: 'Caroline Schultz', online: true },
{ name: 'Mason Heaney', online: false },
{ name: 'Claudie Smitham', online: true },
{ name: 'Emil Schaefer', online: false }
]
const selected = ref(people[3])
</script>
<template>
<USelectMenu v-model="selected" :options="people" option-attribute="name">
<template #label>
<span :class="[selected.online ? 'bg-green-400' : 'bg-gray-200', 'inline-block h-2 w-2 flex-shrink-0 rounded-full']" aria-hidden="true" />
<span class="truncate">{{ selected.name }}</span>
</template>
<template #option="{ option: person }">
<span :class="[person.online ? 'bg-green-400' : 'bg-gray-200', 'inline-block h-2 w-2 flex-shrink-0 rounded-full']" aria-hidden="true" />
<span class="truncate">{{ person.name }}</span>
</template>
</USelectMenu>
</template>