Skip to content

Commit

Permalink
Fix unreliable input on SpellingVariantInput
Browse files Browse the repository at this point in the history
In the port from Wikit to Codex, the new implementation of
`SpellingVariantInput` was working, but was dropping some inputs
entered by users.

Remove the unused `search-input` attribute of the Codex Lookup
component in `SpellingVariantInput` and wire the `input-value`
property in the same way it has been connected in the `ItemLookup`
implementation.

Bug: T379595
  • Loading branch information
codders committed Nov 13, 2024
1 parent 7fd08f0 commit 258ce5d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
33 changes: 27 additions & 6 deletions src/components/SpellingVariantInput.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
<script setup lang="ts">
import { ref, computed } from 'vue';
import {
ref,
computed,
toRef,
} from 'vue';
import escapeRegExp from 'lodash/escapeRegExp';
import {
CdxLookup,
CdxField,
MenuItemData,
ValidationMessages,
ValidationStatusType,
useModelWrapper,
} from '@wikimedia/codex';
import RequiredAsterisk from '@/components/RequiredAsterisk.vue';
import { useMessages } from '@/plugins/MessagesPlugin/Messages';
Expand All @@ -15,7 +20,6 @@ import { useConfig } from '@/plugins/ConfigPlugin/Config';
import { useStore } from 'vuex';
interface Props {
modelValue: string | number | undefined;
searchInput: string;
}
Expand All @@ -40,14 +44,19 @@ languageCodesProvider.getLanguages().forEach(
const menuItems = ref( [] as MenuItemData[] );
const emit = defineEmits( {
'update:modelValue': ( selectedLang: Props['modelValue'] ) => {
return selectedLang === null ||
'update:modelValue': ( selectedLang ) => {
return selectedLang === null || selectedLang === undefined ||
typeof selectedLang === 'string' && selectedLang.length > 0;
},
'update:searchInput': null,
} );
const lastInput = ref( null as string|null );
const onInput = ( inputValue: string ) => {
if ( lastInput.value === inputValue ) {
return;
}
lastInput.value = inputValue;
emit( 'update:searchInput', inputValue );
if ( inputValue.trim() === '' ) {
menuItems.value = [];
Expand Down Expand Up @@ -89,6 +98,19 @@ const errorMessages = computed( (): ValidationMessages => {
store.state.perFieldErrors.spellingVariantErrors[ 0 ].messageKey,
) };
} );
/**
* We want to pass the searchInput property from the parent component
* to the child component. The searchInput property comes in read-only
* and receives updates from the parent (it is a ref / computed value).
* Use the `useModelWrapper` helper here to turn the read-only property
* into a computed value that emits updates on change.
*/
const searchInputWrapper = useModelWrapper(
toRef( props, 'searchInput' ),
emit,
'update:searchInput',
);
</script>

<script lang="ts">
Expand All @@ -106,13 +128,12 @@ export default {
:messages="errorMessages">
<cdx-lookup
v-model:selected="selection"
v-model:input-value="searchInputWrapper"
:placeholder="messages.getUnescaped(
'wikibaselexeme-newlexeme-lemma-language-placeholder-with-example',
config.placeholderExampleData.spellingVariant
)"
:search-input="searchInput"
:menu-items="menuItems"
:input-value="props.modelValue"
@input="onInput"
@update:selected="onOptionSelected"
>
Expand Down
5 changes: 1 addition & 4 deletions tests/unit/components/SpellingVariantInput.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,9 @@ describe( 'SpellingVariantInput', () => {
const lookup = createLookup();

await lookup.find( 'input' ).setValue( 'en' );
await lookup.setProps( {
modelValue: 'English (en)',
} );

expect( lookup.find( 'div.cdx-text-input' ).get( 'input' ).element.value )
.toStrictEqual( 'English (en)' );
.toStrictEqual( 'en' );
} );

it( ':menuItems - returned suggestions are provided to Codex Lookup', async () => {
Expand Down

0 comments on commit 258ce5d

Please sign in to comment.