Skip to content

Commit

Permalink
Merge pull request #104 from cloudblue/LITE-30797-adjustments-in-auto…
Browse files Browse the repository at this point in the history
…complete

LITE-30797 Adjustments in autocomplete
  • Loading branch information
arnaugiralt authored Aug 22, 2024
2 parents bb0bdb7 + 52666db commit 06512c4
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 6 deletions.
18 changes: 18 additions & 0 deletions components/src/stories/Autocomplete.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
30 changes: 25 additions & 5 deletions components/src/widgets/autocomplete/widget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
:propValue="propValue"
:rules="rules"
:hint="hint"
:optionTextFn="optionTextFn"
:menuProps="menuProps"
@value-change="updateSelected"
>
<div
slot="search-input"
class="autocomplete__search"
:class="{ 'cancel-left-padding': !selected }"
>
<ui-textfield
:value="userInput"
Expand Down Expand Up @@ -65,10 +68,25 @@ const props = defineProps({
type: String,
default: '',
},
optionTextFn: {
type: Function,
default: null,
},
menuProps: {
type: Object,
default: () => ({
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);
Expand All @@ -89,6 +107,7 @@ const onUserInput = (e) => {
const updateSelected = (e) => {
selected.value = e.detail[0];
userInput.value = '';
emit('valueChange', selected.value);
};
</script>

Expand All @@ -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;
Expand All @@ -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;
}
}
</style>
26 changes: 26 additions & 0 deletions components/src/widgets/select/widget.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Select from './widget.vue';
import { nextTick } from 'vue';

describe('Select', () => {
let wrapper;
Expand Down Expand Up @@ -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' });
});
});
});
12 changes: 11 additions & 1 deletion components/src/widgets/select/widget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
</template>

<script setup>
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import Menu from '~widgets/menu/widget.vue';
import Icon from '~widgets/icon/widget.vue';
import { useFieldValidation } from '~composables/validation';
Expand Down Expand Up @@ -168,6 +168,16 @@ const getDisplayText = (item) => {
if (props.optionTextFn) return props.optionTextFn(item);
return item[props.propText];
};
watch(
model,
(newValue) => {
selectedOption.value = computedOptions.value.find(
(option) => option[props.propValue] === newValue,
);
},
{ immediate: true },
);
</script>

<style lang="stylus" scoped>
Expand Down

0 comments on commit 06512c4

Please sign in to comment.