From 8624b08494b210e559e27daf743bb9cb34694154 Mon Sep 17 00:00:00 2001 From: Matt H Date: Tue, 24 Oct 2023 16:00:20 -0400 Subject: [PATCH] fix(Select): Only dispatch `populated` event when appropriate This fixes a problem where, when the Select's value is changed (by the user), the `change` and `populated` events are both dispatched, even if the list of options is unchanged. Those subsequent dispatches of the `populated` event make it too easy for consumers of this component to accidentally set the value of the Select back to what it was an instant before, effectively preventing the user's choice from "sticking" sometimes. --- components/mdc/Select/Select.svelte | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/components/mdc/Select/Select.svelte b/components/mdc/Select/Select.svelte index c8b5d62a..f0444bb2 100644 --- a/components/mdc/Select/Select.svelte +++ b/components/mdc/Select/Select.svelte @@ -21,12 +21,17 @@ const selectedTextID = generateRandomID('select-selected-text-') let element = {} let mdcSelect = {} +let previousOptionsIDsCSV = '' $: selectedIndex = options.findIndex((option) => option.id === selectedID) $: dispatch('change', options[selectedIndex] || {}) $: mdcSelect.disabled = disabled $: if (options && mdcSelect.layoutOptions) mdcSelect.layoutOptions() +const getIDsCSV = (options) => options.map(option => option.id).join(',') + +const optionsHaveChanged = (options) => previousOptionsIDsCSV !== getIDsCSV(options) + const recordSelectedID = (event) => (selectedID = event.detail.value) const isOptionSelected = (option) => option.id === selectedID @@ -43,10 +48,11 @@ afterUpdate(() => { // This makes sure the index is updated AFTER the select list contains the full list of options. mdcSelect.selectedIndex = selectedIndex - // If options have been provided, give the current processes time to finish + // If options have been provided or changed, give the current processes time to finish // what they're doing, then indicate that this Select is now populated with // options. At this point, it's safe for the selectedID to be initialized. - if (options.length > 0) { + if (options.length > 0 && optionsHaveChanged(options)) { + previousOptionsIDsCSV = getIDsCSV(options) setTimeout(() => { dispatch('populated') })