Skip to content

Commit 06512c4

Browse files
authored
Merge pull request #104 from cloudblue/LITE-30797-adjustments-in-autocomplete
LITE-30797 Adjustments in autocomplete
2 parents bb0bdb7 + 52666db commit 06512c4

File tree

4 files changed

+80
-6
lines changed

4 files changed

+80
-6
lines changed

components/src/stories/Autocomplete.stories.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ export const Validation = {
5353
},
5454
};
5555

56+
export const ExtraProps = {
57+
name: 'Customized options text',
58+
render: Basic.render,
59+
args: {
60+
...Basic.args,
61+
label: 'This implementation uses the "optionTextFn" and "menuProps"',
62+
options: [
63+
{ value: 'AR', label: 'Argentina' },
64+
{ value: 'AD', label: 'Andorra' },
65+
{ value: 'PL', label: 'Poland' },
66+
],
67+
propValue: 'value',
68+
propText: 'label',
69+
optionTextFn: (item) => `${item.label} (${item.value})`,
70+
menuProps: { fullWidth: false },
71+
},
72+
};
73+
5674
export default {
5775
title: 'Components/Autocomplete',
5876
component: Autocomplete,

components/src/widgets/autocomplete/widget.vue

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
:propValue="propValue"
1010
:rules="rules"
1111
:hint="hint"
12+
:optionTextFn="optionTextFn"
13+
:menuProps="menuProps"
1214
@value-change="updateSelected"
1315
>
1416
<div
1517
slot="search-input"
1618
class="autocomplete__search"
19+
:class="{ 'cancel-left-padding': !selected }"
1720
>
1821
<ui-textfield
1922
:value="userInput"
@@ -65,10 +68,25 @@ const props = defineProps({
6568
type: String,
6669
default: '',
6770
},
71+
optionTextFn: {
72+
type: Function,
73+
default: null,
74+
},
75+
menuProps: {
76+
type: Object,
77+
default: () => ({
78+
fullWidth: true,
79+
}),
80+
},
6881
});
6982
83+
const emit = defineEmits(['valueChange']);
84+
7085
let userInput = ref('');
71-
let selected = ref('');
86+
let selected = defineModel({
87+
type: String,
88+
required: true,
89+
});
7290
7391
const getOptionText = (option) => (typeof option === 'object' ? option[props.propText] : option);
7492
@@ -89,6 +107,7 @@ const onUserInput = (e) => {
89107
const updateSelected = (e) => {
90108
selected.value = e.detail[0];
91109
userInput.value = '';
110+
emit('valueChange', selected.value);
92111
};
93112
</script>
94113

@@ -97,9 +116,6 @@ const updateSelected = (e) => {
97116
98117
&__search {
99118
color: inherit;
100-
-webkit-appearance: none;
101-
-moz-appearance: none;
102-
appearance: none;
103119
line-height: 20px;
104120
font-size: 14px;
105121
border: 1px solid transparent;
@@ -111,7 +127,11 @@ const updateSelected = (e) => {
111127
width: 0;
112128
max-width: 100%;
113129
flex-grow: 1;
114-
z-index: 1;
130+
}
131+
132+
// there is too much padding coming from select + textfield
133+
.cancel-left-padding {
134+
margin-left: -11px;
115135
}
116136
}
117137
</style>

components/src/widgets/select/widget.spec.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { mount } from '@vue/test-utils';
22
import Select from './widget.vue';
3+
import { nextTick } from 'vue';
34

45
describe('Select', () => {
56
let wrapper;
@@ -154,4 +155,29 @@ describe('Select', () => {
154155
});
155156
});
156157
});
158+
159+
describe('watch', () => {
160+
beforeEach(() => {
161+
wrapper = mount(Select, {
162+
props: {
163+
modelValue: '1',
164+
options: [
165+
{ id: '1', value: 'Option 1' },
166+
{ id: '2', value: 'Option 2' },
167+
],
168+
propValue: 'id',
169+
},
170+
});
171+
});
172+
173+
it('should update selectedOption when model changes', async () => {
174+
// Initial check
175+
expect(wrapper.vm.selectedOption).toEqual({ id: '1', value: 'Option 1' });
176+
177+
await wrapper.setProps({ modelValue: '2' });
178+
await nextTick();
179+
180+
expect(wrapper.vm.selectedOption).toEqual({ id: '2', value: 'Option 2' });
181+
});
182+
});
157183
});

components/src/widgets/select/widget.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
</template>
7474

7575
<script setup>
76-
import { computed, ref } from 'vue';
76+
import { computed, ref, watch } from 'vue';
7777
import Menu from '~widgets/menu/widget.vue';
7878
import Icon from '~widgets/icon/widget.vue';
7979
import { useFieldValidation } from '~composables/validation';
@@ -168,6 +168,16 @@ const getDisplayText = (item) => {
168168
if (props.optionTextFn) return props.optionTextFn(item);
169169
return item[props.propText];
170170
};
171+
172+
watch(
173+
model,
174+
(newValue) => {
175+
selectedOption.value = computedOptions.value.find(
176+
(option) => option[props.propValue] === newValue,
177+
);
178+
},
179+
{ immediate: true },
180+
);
171181
</script>
172182

173183
<style lang="stylus" scoped>

0 commit comments

Comments
 (0)