Skip to content

Commit 215c098

Browse files
authored
Merge pull request #8355 from nextcloud-libraries/backport/8324/stable8
[stable8] fix(NcCheckboxRadioSwitch): use reactive state for group checkbox toggle
2 parents 96959e9 + 23befe9 commit 215c098

2 files changed

Lines changed: 66 additions & 17 deletions

File tree

src/components/NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -708,26 +708,13 @@ export default {
708708
return
709709
}
710710
711-
// Dispatch the checked values as an array if multiple, or single value otherwise
712-
const values = this.getInputsSet()
713-
.filter((input) => input.checked)
714-
.map((input) => input.value)
715-
716-
if (values.includes(this.value)) {
717-
this.internalModelValue = values.filter((v) => v !== this.value)
711+
// Toggle this value in/out of the array
712+
if (this.isChecked) {
713+
this.internalModelValue = this.internalModelValue.filter((v) => v !== this.value)
718714
} else {
719-
this.internalModelValue = [...values, this.value]
715+
this.internalModelValue = [...this.internalModelValue, this.value]
720716
}
721717
},
722-
723-
/**
724-
* Get the input set based on this name
725-
*
726-
* @return {Node[]}
727-
*/
728-
getInputsSet() {
729-
return [...document.getElementsByName(this.name)]
730-
},
731718
},
732719
}
733720
</script>

tests/unit/components/NcCheckboxRadioSwitch/checkbox.spec.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,66 @@ describe('NcCheckboxRadioSwitch', () => {
8484
expect(descriptionElement.exists()).toBe(true)
8585
expect(descriptionElement.text()).toContain('My description')
8686
})
87+
88+
it('emits correct value on keyboard toggle for boolean checkbox', async () => {
89+
const wrapper = mount(NcCheckboxRadioSwitch, {
90+
propsData: {
91+
modelValue: false,
92+
},
93+
slots: {
94+
default: 'Toggle me',
95+
},
96+
})
97+
98+
await wrapper.find('input').trigger('change')
99+
expect(wrapper.emitted('update:modelValue')[0]).toEqual([true])
100+
})
101+
102+
it('emits correct value on keyboard toggle for checkbox group', async () => {
103+
const wrapper = mount(NcCheckboxRadioSwitch, {
104+
propsData: {
105+
modelValue: ['a'],
106+
value: 'b',
107+
name: 'test-group',
108+
},
109+
slots: {
110+
default: 'Option B',
111+
},
112+
attachTo: document.body,
113+
})
114+
115+
// Simulate keyboard spacebar: browser toggles input.checked BEFORE firing change
116+
const input = wrapper.find('input')
117+
const inputEl = input.element
118+
inputEl.checked = true // Browser would do this before firing change
119+
await input.trigger('change')
120+
121+
expect(wrapper.emitted('update:modelValue')[0]).toEqual([['a', 'b']])
122+
123+
wrapper.destroy()
124+
})
125+
126+
it('emits correct value on keyboard un-toggle for checkbox group', async () => {
127+
const wrapper = mount(NcCheckboxRadioSwitch, {
128+
propsData: {
129+
modelValue: ['a', 'b'],
130+
value: 'b',
131+
name: 'test-group',
132+
},
133+
slots: {
134+
default: 'Option B',
135+
},
136+
attachTo: document.body,
137+
})
138+
139+
// Simulate keyboard spacebar unchecking: browser sets checked=false before change
140+
const input = wrapper.find('input')
141+
const inputEl = input.element
142+
inputEl.checked = false
143+
await input.trigger('change')
144+
145+
expect(wrapper.emitted('update:modelValue')[0]).toEqual([['a']])
146+
147+
wrapper.destroy()
148+
})
87149
})

0 commit comments

Comments
 (0)