Skip to content

Commit

Permalink
fix(kselect): fix double emits bug (#2156)
Browse files Browse the repository at this point in the history
  • Loading branch information
portikM authored Apr 24, 2024
1 parent d9fa2dc commit bcf23f4
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 20 deletions.
86 changes: 75 additions & 11 deletions src/components/KSelect/KSelect.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import KSelect from '@/components/KSelect/KSelect.vue'
describe('KSelect', () => {
it('renders props when passed', () => {
const labels = ['Label 1', 'Label 2', 'Label 3']
const vals = ['label1', 'label2', 'label3']
const vals = ['val1', 'val2', 'val3']

mount(KSelect, {
props: {
Expand Down Expand Up @@ -36,7 +36,7 @@ describe('KSelect', () => {

mount(KSelect, {
props: {
items: [{ label: selectedLabel, value: 'label1', selected: true }],
items: [{ label: selectedLabel, value: 'val1', selected: true }],
},
})

Expand All @@ -46,7 +46,7 @@ describe('KSelect', () => {
it('renders with disabled item', () => {
mount(KSelect, {
props: {
items: [{ label: 'Label 1', value: 'label1', disabled: true }],
items: [{ label: 'Label 1', value: 'val1', disabled: true }],
},
})

Expand Down Expand Up @@ -118,7 +118,7 @@ describe('KSelect', () => {

it('reacts to text change and select', () => {
const labels = ['Label 1', 'Label 2']
const vals = ['label1', 'label2']
const vals = ['val1', 'val2']

mount(KSelect, {
props: {
Expand Down Expand Up @@ -149,7 +149,7 @@ describe('KSelect', () => {

it('ignores clicks on disabled item', () => {
const labels = ['Label 1', 'Label 2']
const vals = ['label1', 'label2']
const vals = ['val1', 'val2']

mount(KSelect, {
props: {
Expand All @@ -173,7 +173,7 @@ describe('KSelect', () => {
it('allows slotting content into the items', async () => {
const itemSlotContent = 'I am slotted!'
const itemLabel = 'Label 1'
const itemValue = 'label1'
const itemValue = 'val1'

mount(KSelect, {
props: {
Expand All @@ -193,7 +193,7 @@ describe('KSelect', () => {
it('reuses item template slot for selected item element when prop is true', async () => {
const itemSlotContent = 'I am slotted!'
const itemLabel = 'Label 1'
const itemValue = 'label1'
const itemValue = 'val1'

mount(KSelect, {
props: {
Expand Down Expand Up @@ -266,7 +266,7 @@ describe('KSelect', () => {

it('renders dropdown footer text when prop is passed', () => {
const labels = ['Label 1', 'Label 2', 'Label 3']
const vals = ['label1', 'label2', 'label3']
const vals = ['val1', 'val2', 'val3']
const dropdownFooterText = 'Dropdown footer text'

mount(KSelect, {
Expand Down Expand Up @@ -349,7 +349,7 @@ describe('KSelect', () => {
it('allows slotting selected item content', async () => {
const selectedItemContent = 'I am slotted!'
const itemLabel = 'Label 1'
const itemValue = 'label1'
const itemValue = 'val1'

mount(KSelect, {
props: {
Expand Down Expand Up @@ -396,7 +396,7 @@ describe('KSelect', () => {

it('allows adding an item with enableItemCreation', () => {
const labels = ['Label 1', 'Label 2']
const vals = ['label1', 'label2']
const vals = ['val1', 'val2']
const newItem = 'Rock me'

mount(KSelect, {
Expand Down Expand Up @@ -444,7 +444,7 @@ describe('KSelect', () => {

it('updates selected status after items are mutated', () => {
const labels = ['Label 1', 'Label 2']
const vals = ['label1', 'label2']
const vals = ['val1', 'val2']

mount(KSelect, {
props: {
Expand Down Expand Up @@ -482,4 +482,68 @@ describe('KSelect', () => {
cy.get(`[data-testid="select-item-${vals[1]}"] button`).should('have.class', 'selected')
})
})

it('emits selected, input, change events when item selected', () => {
const labels = ['Label 1', 'Label 2']
const vals = ['val1', 'val2']

mount(KSelect, {
props: {
modelValue: '',
items: [{
label: labels[0],
value: vals[0],
}, {
label: labels[1],
value: vals[1],
}],
},
})

cy.get('.select-input input').click()
cy.getTestId(`select-item-${vals[0]}`).eq(0).click({ force: true }).then(() => {
cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'selected')
cy.wrap(Cypress.vueWrapper.emitted().selected).should('have.length', 1)

cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'input')
cy.wrap(Cypress.vueWrapper.emitted().input).should('have.length', 1)
// @ts-ignore
cy.wrap(Cypress.vueWrapper.emitted().input[0][0]).should('be.equal', vals[0])

cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'change')
cy.wrap(Cypress.vueWrapper.emitted().change).should('have.length', 1)
})
})

it('emits input, change events correctly when item is cleared', () => {
const labels = ['Label 1', 'Label 2']
const vals = ['val1', 'val2']

mount(KSelect, {
props: {
modelValue: 'val1',
items: [{
label: labels[0],
value: vals[0],
selected: true,
}, {
label: labels[1],
value: vals[1],
}],
clearable: true,
},
})

cy.getTestId('clear-selection-icon').trigger('click').then(() => {
cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'input')
cy.wrap(Cypress.vueWrapper.emitted().input).should('have.length', 1)
// @ts-ignore
cy.wrap(Cypress.vueWrapper.emitted().input[0][0]).should('be.equal', null)

cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'change')
cy.wrap(Cypress.vueWrapper.emitted().change).should('have.length', 1)
// @ts-ignore
cy.wrap(Cypress.vueWrapper.emitted().change[0][0]).should('be.equal', null)
})
})
})
26 changes: 17 additions & 9 deletions src/components/KSelect/KSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,6 @@ const handleItemSelect = (item: SelectItem, isNew?: boolean) => {
})
filterQuery.value = item.label
emit('selected', item)
// this 'input' event must be emitted for v-model binding to work properly
emit('input', item.value)
emit('change', item)
emit('update:modelValue', item.value)
}
const clearSelection = (): void => {
Expand All @@ -528,10 +523,6 @@ const clearSelection = (): void => {
})
selectedItem.value = null
filterQuery.value = ''
// this 'input' event must be emitted for v-model binding to work properly
emit('input', null)
emit('change', null)
emit('update:modelValue', null)
}
const triggerFocus = (evt: any, isToggled: Ref<boolean>):void => {
Expand Down Expand Up @@ -663,6 +654,23 @@ watch(filterQuery, (q: string) => {
emit('query-change', q)
})
watch(selectedItem, (newVal, oldVal) => {
if (newVal) {
if (newVal !== oldVal) {
emit('selected', newVal)
// this 'input' event must be emitted for v-model binding to work properly
emit('input', newVal.value)
emit('change', newVal)
emit('update:modelValue', newVal.value)
}
} else {
// this 'input' event must be emitted for v-model binding to work properly
emit('input', null)
emit('change', null)
emit('update:modelValue', null)
}
}, { deep: true })
onMounted(() => {
if (selectWrapperElement.value) {
resizeObserver.value = ResizeObserverHelper.create(() => { actualElementWidth.value = `${selectWrapperElement.value?.offsetWidth}px` })
Expand Down

0 comments on commit bcf23f4

Please sign in to comment.