diff --git a/components/src/stories/Autocomplete.stories.js b/components/src/stories/Autocomplete.stories.js
index d0b3198e..76f729b3 100644
--- a/components/src/stories/Autocomplete.stories.js
+++ b/components/src/stories/Autocomplete.stories.js
@@ -53,6 +53,24 @@ export const Validation = {
},
};
+export const ExtraProps = {
+ name: 'Customized options text',
+ render: Basic.render,
+ args: {
+ ...Basic.args,
+ label: 'This implementation uses the "optionTextFn" and "menuProps"',
+ options: [
+ { value: 'AR', label: 'Argentina' },
+ { value: 'AD', label: 'Andorra' },
+ { value: 'PL', label: 'Poland' },
+ ],
+ propValue: 'value',
+ propText: 'label',
+ optionTextFn: (item) => `${item.label} (${item.value})`,
+ menuProps: { fullWidth: false },
+ },
+};
+
export default {
title: 'Components/Autocomplete',
component: Autocomplete,
diff --git a/components/src/widgets/autocomplete/widget.vue b/components/src/widgets/autocomplete/widget.vue
index c897559e..5ef2f6bd 100644
--- a/components/src/widgets/autocomplete/widget.vue
+++ b/components/src/widgets/autocomplete/widget.vue
@@ -9,11 +9,14 @@
:propValue="propValue"
:rules="rules"
:hint="hint"
+ :optionTextFn="optionTextFn"
+ :menuProps="menuProps"
@value-change="updateSelected"
>
({
+ fullWidth: true,
+ }),
+ },
});
+const emit = defineEmits(['valueChange']);
+
let userInput = ref('');
-let selected = ref('');
+let selected = defineModel({
+ type: String,
+ required: true,
+});
const getOptionText = (option) => (typeof option === 'object' ? option[props.propText] : option);
@@ -89,6 +107,7 @@ const onUserInput = (e) => {
const updateSelected = (e) => {
selected.value = e.detail[0];
userInput.value = '';
+ emit('valueChange', selected.value);
};
@@ -97,9 +116,6 @@ const updateSelected = (e) => {
&__search {
color: inherit;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
line-height: 20px;
font-size: 14px;
border: 1px solid transparent;
@@ -111,7 +127,11 @@ const updateSelected = (e) => {
width: 0;
max-width: 100%;
flex-grow: 1;
- z-index: 1;
+ }
+
+ // there is too much padding coming from select + textfield
+ .cancel-left-padding {
+ margin-left: -11px;
}
}
diff --git a/components/src/widgets/select/widget.spec.js b/components/src/widgets/select/widget.spec.js
index 881434f9..3d29205b 100644
--- a/components/src/widgets/select/widget.spec.js
+++ b/components/src/widgets/select/widget.spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Select from './widget.vue';
+import { nextTick } from 'vue';
describe('Select', () => {
let wrapper;
@@ -154,4 +155,29 @@ describe('Select', () => {
});
});
});
+
+ describe('watch', () => {
+ beforeEach(() => {
+ wrapper = mount(Select, {
+ props: {
+ modelValue: '1',
+ options: [
+ { id: '1', value: 'Option 1' },
+ { id: '2', value: 'Option 2' },
+ ],
+ propValue: 'id',
+ },
+ });
+ });
+
+ it('should update selectedOption when model changes', async () => {
+ // Initial check
+ expect(wrapper.vm.selectedOption).toEqual({ id: '1', value: 'Option 1' });
+
+ await wrapper.setProps({ modelValue: '2' });
+ await nextTick();
+
+ expect(wrapper.vm.selectedOption).toEqual({ id: '2', value: 'Option 2' });
+ });
+ });
});
diff --git a/components/src/widgets/select/widget.vue b/components/src/widgets/select/widget.vue
index 619758d1..0f7ac779 100644
--- a/components/src/widgets/select/widget.vue
+++ b/components/src/widgets/select/widget.vue
@@ -73,7 +73,7 @@