-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathcombobox-with-pure-tailwind.vue
141 lines (134 loc) · 4.55 KB
/
combobox-with-pure-tailwind.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<script>
import { ref, defineComponent, computed, onMounted, watch } from 'vue'
import {
Combobox,
ComboboxButton,
ComboboxInput,
ComboboxLabel,
ComboboxOption,
ComboboxOptions,
} from '@headlessui/vue'
let everybody = [
{ id: 1, name: 'Wade Cooper' },
{ id: 2, name: 'Arlene Mccoy' },
{ id: 3, name: 'Devon Webb' },
{ id: 4, name: 'Tom Cook' },
{ id: 5, name: 'Tanya Fox' },
{ id: 6, name: 'Hellen Schmidt' },
{ id: 7, name: 'Caroline Schultz' },
{ id: 8, name: 'Mason Heaney' },
{ id: 9, name: 'Claudie Smitham' },
{ id: 10, name: 'Emil Schaefer' },
]
export default defineComponent({
components: {
Combobox,
ComboboxButton,
ComboboxInput,
ComboboxLabel,
ComboboxOption,
ComboboxOptions,
},
setup() {
let query = ref('')
let activePerson = ref(null)
let filteredPeople = computed(() => {
return query.value === ''
? everybody
: everybody.filter((person) => {
return person.name.toLowerCase().includes(query.value.toLowerCase())
})
})
watch(activePerson, () => {
query.value = ''
})
return {
query,
activePerson,
filteredPeople,
}
},
})
</script>
<template>
<div class="flex h-full w-screen justify-center bg-gray-50 p-12">
<div class="mx-auto w-full max-w-xs">
<div class="py-8 font-mono text-xs">
Selected person: {{ activePerson?.name ?? 'Nobody yet' }}
</div>
<div class="space-y-1">
<Combobox v-model="activePerson" as="div" nullable :default-to-first-option="false">
<ComboboxLabel class="block text-sm font-medium leading-5 text-gray-700">
Assigned to
</ComboboxLabel>
<div class="relative">
<span class="relative inline-flex flex-row overflow-hidden rounded-md border shadow-sm">
<ComboboxInput
@change="query = $event.target.value"
:displayValue="(person) => person?.name ?? ''"
class="border-none px-3 py-1 outline-none"
/>
<ComboboxButton
class="cursor-default border-l bg-gray-100 px-1 text-indigo-600 focus:outline-none"
>
<span class="pointer-events-none flex items-center px-2">
<svg
class="h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="none"
stroke="currentColor"
>
<path
d="M7 7l3-3 3 3m0 6l-3 3-3-3"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</span>
</ComboboxButton>
</span>
<div class="absolute mt-1 w-full rounded-md bg-white shadow-lg">
<ComboboxOptions
class="shadow-xs max-h-60 overflow-auto rounded-md py-1 text-base leading-6 focus:outline-none sm:text-sm sm:leading-5"
>
<ComboboxOption
v-for="person in filteredPeople"
:key="person.id"
:value="person"
v-slot="{ active, selected }"
>
<div
:class="[
'relative cursor-default select-none py-2 pl-3 pr-9 focus:outline-none',
active ? 'bg-indigo-600 text-white' : 'text-gray-900',
]"
>
<span :class="['block truncate', selected ? 'font-semibold' : 'font-normal']">
{{ person.name }}
</span>
<span
v-if="selected"
:class="[
'absolute inset-y-0 right-0 flex items-center pr-4',
active ? 'text-white' : 'text-indigo-600',
]"
>
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
</span>
</div>
</ComboboxOption>
</ComboboxOptions>
</div>
</div>
</Combobox>
</div>
</div>
</div>
</template>