Skip to content

Commit e7c7776

Browse files
authored
Disabled select input fixes (#355)
1 parent 9761351 commit e7c7776

File tree

1 file changed

+31
-40
lines changed

1 file changed

+31
-40
lines changed

client/components/forms/components/VSelect.vue

+31-40
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
<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">
33
<span class="inline-block w-full rounded-md">
44
<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 }">
119
<transition name="fade" mode="out-in">
1210
<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 }">
1412
<slot name="selected" :option="modelValue" />
1513
</div>
1614
<div v-else key="placeholder">
1715
<slot name="placeholder">
1816
<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 }">
2118
{{ placeholder }}
2219
</div>
2320
</slot>
@@ -32,38 +29,31 @@
3229
</button>
3330
</span>
3431
<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">
3833
<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 }">
4236
<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..." />
4638
</div>
4739
<div v-if="loading" class="w-full py-2 flex justify-center">
4840
<Loader class="h-6 w-6 text-nt-blue mx-auto" />
4941
</div>
5042
<template v-if="filteredOptions.length > 0">
5143
<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)">
5647
<slot name="option" :option="item" :selected="isSelected(item)" />
5748
</li>
5849
</template>
5950
<p v-else-if="!loading && !(allowCreation && searchTerm)" class="w-full text-gray-500 text-center py-2">
6051
{{ (allowCreation ? 'Type something to add an option' : 'No option available') }}.
6152
</p>
6253
<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)">
6757
Create <b class="px-1 bg-gray-300 rounded group-hover-text-black">{{ searchTerm }}</b>
6858
</li>
6959
</ul>
@@ -103,31 +93,31 @@ export default {
10393
allowCreation: { type: Boolean, default: false },
10494
disabled: { type: Boolean, default: false }
10595
},
106-
data () {
96+
data() {
10797
return {
10898
isOpen: false,
10999
searchTerm: '',
110100
defaultValue: this.modelValue ?? null
111101
}
112102
},
113103
computed: {
114-
optionStyle () {
104+
optionStyle() {
115105
return {
116106
'--bg-form-color': this.color
117107
}
118108
},
119-
inputStyle () {
109+
inputStyle() {
120110
return {
121111
'--tw-ring-color': this.color
122112
}
123113
},
124-
debouncedRemote () {
114+
debouncedRemote() {
125115
if (this.remote) {
126116
return debounce(this.remote, 300)
127117
}
128118
return null
129119
},
130-
filteredOptions () {
120+
filteredOptions() {
131121
if (!this.data) return []
132122
if (!this.searchable || this.remote || this.searchTerm === '') {
133123
return this.data
@@ -142,26 +132,26 @@ export default {
142132
return res.item
143133
})
144134
},
145-
isSearchable () {
135+
isSearchable() {
146136
return this.searchable || this.remote !== null || this.allowCreation
147137
}
148138
},
149139
watch: {
150-
searchTerm (val) {
140+
searchTerm(val) {
151141
if (!this.debouncedRemote) return
152142
if ((this.remote && val) || (val === '' && !this.modelValue) || (val === '' && this.isOpen)) {
153143
return this.debouncedRemote(val)
154144
}
155145
}
156146
},
157147
methods: {
158-
onClickAway (event) {
148+
onClickAway(event) {
159149
// Check that event target isn't children of dropdown
160150
if (this.$refs.select && !this.$refs.select.contains(event.target)) {
161151
this.isOpen = false
162152
}
163153
},
164-
isSelected (value) {
154+
isSelected(value) {
165155
if (!this.modelValue) return false
166156
167157
if (this.emitKey && value[this.emitKey]) {
@@ -173,16 +163,17 @@ export default {
173163
}
174164
return this.modelValue === value
175165
},
176-
toggleDropdown () {
166+
toggleDropdown() {
177167
if (this.disabled) {
178168
this.isOpen = false
169+
} else {
170+
this.isOpen = !this.isOpen
179171
}
180-
this.isOpen = !this.isOpen
181172
if (!this.isOpen) {
182173
this.searchTerm = ''
183174
}
184175
},
185-
select (value) {
176+
select(value) {
186177
if (!this.multiple) {
187178
// Close after select
188179
this.toggleDropdown()
@@ -215,7 +206,7 @@ export default {
215206
}
216207
}
217208
},
218-
createOption (newOption) {
209+
createOption(newOption) {
219210
if (newOption) {
220211
const newItem = {
221212
name: newOption,

0 commit comments

Comments
 (0)