learningequality / learningequality/studio

[Remove Vuetify from Studio] Replace CountryField VAutocomplete with KDS KMultiSelect

Open
#6,139 2 comments 0 reactions 1 assignee View on GitHub

@LightCreator1007 is already working on this.

Since Sep 17, 2026.

community-contribution-in-progress DEV: frontend help wanted
Dominant language
Python
Stars
191
Forks
307
Avg merge
5d 6h
Merged PRs (30d)
10

Description

🙂 Looking for an issue? Welcome! This issue is open for contribution. If this is the first time you’re requesting an issue, please:

  • Read Contributing guidelines carefully. Pay extra attention to Using generative AI. Pull requests and comments that don’t follow the guidelines won’t be answered.
  • Confirm that you’ve read the guidelines in your comment.

Overview

CountryField uses the Vuetify component VAutocomplete. Replace it with KMultiSelect from the Kolibri Design System. It also unblocks four skipped tests in the account creation tests.

Complexity: Medium
Target branch: unstable

Context

File: contentcuration/contentcuration/frontend/shared/views/form/CountryField.vue

The component wraps VAutocomplete in DropdownWrapper. It validates with the Vuetify rules prop. For styling, it has overrides that use ::v-deep and sets its width with v-bind() in CSS, from the fullWidth prop.

Four files use this component:

File What it needs
accounts/pages/Create.vue Selects more than one country
settings/pages/Storage/RequestForm.vue Selects more than one country, with no border
channelEdit/components/sidePanels/SubmitToCommunityLibrarySidePanel/index.vue Turns the field off with disabled, and uses fullWidth
administration/pages/Users/UserTable.vue Selects one country, and reads the options list from the component with a template ref

Two things to know before you start:

  1. KMultiSelect uses the props invalid and invalidText. It does not use the Vuetify rules prop.
  2. VAutocomplete leaves the typed text in the field after a selection. The component clears it with a setTimeout in the locations setter. KMultiSelect manages its own search text, so this code can go.

Four tests in accounts/pages/__tests__/create.spec.js use it.skip, and a comment there names this component as the reason.

Two finished examples of the same change:

  • LanguageFilter.vue
  • CategoryOptions.vue
The Change
  • CountryField renders KMultiSelect. It keeps the props value, required, multiple, label and fullWidth, so the four files change as little as possible.
  • The options keep their current shape. The value stays the English country name, because the server needs it. The label should continue to be the translated country name.
  • The required prop works through invalid and invalidText, and keeps the "Field is required" message.
  • The accessibility strings in messages come from shared/strings/commonStrings.js.
  • Remove DropdownWrapper, the ::v-deep styles and the setTimeout that clears the search text. Set the field width with appearanceOverrides instead of v-bind() in CSS.
  • Remove the Vuetify props from the four files, such as box, outline, hide-details and menu-props. The disabled prop stays, because KMultiSelect has it too.
  • Turn the four skipped tests in create.spec.js back on, and remove the comment that names this component.
How to Get There
  • More than one country: Sign out, Create an account, Location.
  • No border: Settings, Storage, Request more space, Target regions.
  • Field turned off: Channel editor, options menu, Submit to community library, Countries.
  • One country: Administration, Users, Target location.
Out of Scope
  • Making changes to the countries utility module.
Acceptance Criteria
General
  • CountryField.vue renders KMultiSelect. It has no VAutocomplete and no DropdownWrapper.
  • Selection of one country and of more than one country both work. The input event sends the same value as before in all four files.
  • The search text clears after a selection, with no setTimeout.
  • disabled turns the field off in the community library side panel.
  • fullWidth still sets the field width, through appearanceOverrides.
  • Create.vue still shows its own "field required" message below the field when nothing is selected.
  • The location filter in UserTable still shows its options.
  • The four files no longer pass Vuetify props to the component.
Accessibility and i18n
  • messages has every key that KMultiSelect needs. Shared strings come from commonStrings.js.
  • The list shows translated country names. The value sent to the server stays the English name.
  • A keyboard user can open the list, type to filter it, move through the options, select an option, remove one selection and clear the field.
  • All colors come from theme tokens.
Testing
  • countryField.spec.js uses Vue Testing Library.
  • The four skipped tests in create.spec.js run and pass.
  • pnpm test passes, including SubmitToCommunityLibrarySidePanel.spec.js.
  • pre-commit run --all-files passes.
References
References

AI usage

I used Claude Code to draft this issue. It read the component, listed the files that use it, and traced the skipped tests in create.spec.js back to this component. I checked the file references, updated the context, and edited the issue for accuracy.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.