1
1
<template >
2
- <div class =" v-select relative" :class =" [{'w-0': multiple, 'min-w-full':multiple}]" ref =" select" >
2
+ <div class =" v-select relative" :class =" [{ 'w-0': multiple, 'min-w-full': multiple }]" ref =" select" >
3
3
<span class =" inline-block w-full rounded-md" >
4
4
<button type =" button" aria-haspopup =" listbox" aria-expanded =" true" aria-labelledby =" listbox-label"
5
- class =" cursor-pointer"
6
- :style =" inputStyle"
7
- :class =" [theme.SelectInput.input,{'py-2': !multiple || loading,'py-1': multiple, '!ring-red-500 !ring-2 !border-transparent': hasError, '!cursor-not-allowed !bg-gray-200': disabled}, inputClass]"
8
- @click =" toggleDropdown"
9
- >
10
- <div :class =" {'h-6': !multiple, 'min-h-8': multiple && !loading}" >
5
+ class =" cursor-pointer" :style =" inputStyle"
6
+ :class =" [theme.SelectInput.input, { 'py-2': !multiple || loading, 'py-1': multiple, '!ring-red-500 !ring-2 !border-transparent': hasError, '!cursor-not-allowed !bg-gray-200': disabled }, inputClass]"
7
+ @click =" toggleDropdown" >
8
+ <div :class =" { 'h-6': !multiple, 'min-h-8': multiple && !loading }" >
11
9
<transition name =" fade" mode =" out-in" >
12
10
<Loader v-if =" loading" key =" loader" class =" h-6 w-6 text-nt-blue mx-auto" />
13
- <div v-else-if =" modelValue" key =" value" class =" flex" :class =" {'min-h-8': multiple}" >
11
+ <div v-else-if =" modelValue" key =" value" class =" flex" :class =" { 'min-h-8': multiple }" >
14
12
<slot name =" selected" :option =" modelValue" />
15
13
</div >
16
14
<div v-else key =" placeholder" >
17
15
<slot name =" placeholder" >
18
16
<div class =" text-gray-400 dark:text-gray-500 w-full text-left truncate pr-3"
19
- :class =" {'py-1': multiple && !loading}"
20
- >
17
+ :class =" { 'py-1': multiple && !loading }" >
21
18
{{ placeholder }}
22
19
</div >
23
20
</slot >
32
29
</button >
33
30
</span >
34
31
<collapsible v-model =" isOpen" @click-away =" onClickAway"
35
- class =" absolute mt-1 rounded-md bg-white dark:bg-notion-dark-light shadow-xl z-10"
36
- :class =" dropdownClass"
37
- >
32
+ class =" absolute mt-1 rounded-md bg-white dark:bg-notion-dark-light shadow-xl z-10" :class =" dropdownClass" >
38
33
<ul tabindex =" -1" role =" listbox"
39
- class =" rounded-md text-base leading-6 shadow-xs overflow-auto focus:outline-none sm:text-sm sm:leading-5 relative"
40
- :class =" {'max-h-42 py-1': !isSearchable,'max-h-48 pb-1': isSearchable}"
41
- >
34
+ class =" rounded-md text-base leading-6 shadow-xs overflow-auto focus:outline-none sm:text-sm sm:leading-5 relative"
35
+ :class =" { 'max-h-42 py-1': !isSearchable, 'max-h-48 pb-1': isSearchable }" >
42
36
<div v-if =" isSearchable" class =" px-2 pt-2 sticky top-0 bg-white dark-bg-notion-dark-light z-10" >
43
- <text-input v-model =" searchTerm" name =" search" :color =" color" :theme =" theme"
44
- placeholder =" Search..."
45
- />
37
+ <text-input v-model =" searchTerm" name =" search" :color =" color" :theme =" theme" placeholder =" Search..." />
46
38
</div >
47
39
<div v-if =" loading" class =" w-full py-2 flex justify-center" >
48
40
<Loader class =" h-6 w-6 text-nt-blue mx-auto" />
49
41
</div >
50
42
<template v-if =" filteredOptions .length > 0 " >
51
43
<li v-for =" item in filteredOptions" :key =" item[optionKey]" role =" option" :style =" optionStyle"
52
- :class =" {'px-3 pr-9': multiple, 'px-3': !multiple}"
53
- class =" text-gray-900 cursor-default select-none relative py-2 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus-text-white focus-nt-blue"
54
- @click =" select(item)"
55
- >
44
+ :class =" { 'px-3 pr-9': multiple, 'px-3': !multiple }"
45
+ class =" text-gray-900 cursor-default select-none relative py-2 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus-text-white focus-nt-blue"
46
+ @click =" select(item)" >
56
47
<slot name =" option" :option =" item" :selected =" isSelected(item)" />
57
48
</li >
58
49
</template >
59
50
<p v-else-if =" !loading && !(allowCreation && searchTerm)" class =" w-full text-gray-500 text-center py-2" >
60
51
{{ (allowCreation ? 'Type something to add an option' : 'No option available') }}.
61
52
</p >
62
53
<li v-if =" allowCreation && searchTerm" role =" option" :style =" optionStyle"
63
- :class =" {'px-3 pr-9': multiple, 'px-3': !multiple}"
64
- class =" text-gray-900 cursor-default select-none relative py-2 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus-text-white focus-nt-blue"
65
- @click =" createOption(searchTerm)"
66
- >
54
+ :class =" { 'px-3 pr-9': multiple, 'px-3': !multiple }"
55
+ class =" text-gray-900 cursor-default select-none relative py-2 cursor-pointer group hover:text-white hover:bg-form-color focus:outline-none focus-text-white focus-nt-blue"
56
+ @click =" createOption(searchTerm)" >
67
57
Create <b class =" px-1 bg-gray-300 rounded group-hover-text-black" >{{ searchTerm }}</b >
68
58
</li >
69
59
</ul >
@@ -103,31 +93,31 @@ export default {
103
93
allowCreation: { type: Boolean , default: false },
104
94
disabled: { type: Boolean , default: false }
105
95
},
106
- data () {
96
+ data () {
107
97
return {
108
98
isOpen: false ,
109
99
searchTerm: ' ' ,
110
100
defaultValue: this .modelValue ?? null
111
101
}
112
102
},
113
103
computed: {
114
- optionStyle () {
104
+ optionStyle () {
115
105
return {
116
106
' --bg-form-color' : this .color
117
107
}
118
108
},
119
- inputStyle () {
109
+ inputStyle () {
120
110
return {
121
111
' --tw-ring-color' : this .color
122
112
}
123
113
},
124
- debouncedRemote () {
114
+ debouncedRemote () {
125
115
if (this .remote ) {
126
116
return debounce (this .remote , 300 )
127
117
}
128
118
return null
129
119
},
130
- filteredOptions () {
120
+ filteredOptions () {
131
121
if (! this .data ) return []
132
122
if (! this .searchable || this .remote || this .searchTerm === ' ' ) {
133
123
return this .data
@@ -142,26 +132,26 @@ export default {
142
132
return res .item
143
133
})
144
134
},
145
- isSearchable () {
135
+ isSearchable () {
146
136
return this .searchable || this .remote !== null || this .allowCreation
147
137
}
148
138
},
149
139
watch: {
150
- searchTerm (val ) {
140
+ searchTerm (val ) {
151
141
if (! this .debouncedRemote ) return
152
142
if ((this .remote && val) || (val === ' ' && ! this .modelValue ) || (val === ' ' && this .isOpen )) {
153
143
return this .debouncedRemote (val)
154
144
}
155
145
}
156
146
},
157
147
methods: {
158
- onClickAway (event ) {
148
+ onClickAway (event ) {
159
149
// Check that event target isn't children of dropdown
160
150
if (this .$refs .select && ! this .$refs .select .contains (event .target )) {
161
151
this .isOpen = false
162
152
}
163
153
},
164
- isSelected (value ) {
154
+ isSelected (value ) {
165
155
if (! this .modelValue ) return false
166
156
167
157
if (this .emitKey && value[this .emitKey ]) {
@@ -173,16 +163,17 @@ export default {
173
163
}
174
164
return this .modelValue === value
175
165
},
176
- toggleDropdown () {
166
+ toggleDropdown () {
177
167
if (this .disabled ) {
178
168
this .isOpen = false
169
+ } else {
170
+ this .isOpen = ! this .isOpen
179
171
}
180
- this .isOpen = ! this .isOpen
181
172
if (! this .isOpen ) {
182
173
this .searchTerm = ' '
183
174
}
184
175
},
185
- select (value ) {
176
+ select (value ) {
186
177
if (! this .multiple ) {
187
178
// Close after select
188
179
this .toggleDropdown ()
@@ -215,7 +206,7 @@ export default {
215
206
}
216
207
}
217
208
},
218
- createOption (newOption ) {
209
+ createOption (newOption ) {
219
210
if (newOption) {
220
211
const newItem = {
221
212
name: newOption,
0 commit comments