11/**
2- * Copyright IBM Corp. 2016, 2023
2+ * Copyright IBM Corp. 2016, 2025
33 *
44 * This source code is licensed under the Apache-2.0 license found in the
55 * LICENSE file in the root directory of this source tree.
@@ -13,6 +13,16 @@ import { AILabel } from '../AILabel';
1313
1414const prefix = 'cds' ;
1515
16+ /**
17+ * @param element {Element}
18+ * @returns {Record<string, string> }
19+ */
20+ const getElementAttributes = ( { attributes } ) =>
21+ Array . from ( attributes ) . reduce (
22+ ( acc , { name, value } ) => ( { ...acc , [ name ] : value } ) ,
23+ { }
24+ ) ;
25+
1626describe ( 'CheckboxGroup' , ( ) => {
1727 it ( 'should support a custom `className` prop on the outermost element' , ( ) => {
1828 const { container } = render (
@@ -191,4 +201,89 @@ describe('CheckboxGroup', () => {
191201 `${ prefix } --checkbox-group--horizontal`
192202 ) ;
193203 } ) ;
204+
205+ describe ( 'prop inheritance' , ( ) => {
206+ it ( 'should pass props to child `Checkbox` components' , ( ) => {
207+ render (
208+ < CheckboxGroup legendText = "Checkbox heading" invalid readOnly warn >
209+ < Checkbox labelText = "Checkbox 1" id = "checkbox-1" />
210+ < Checkbox labelText = "Checkbox 2" id = "checkbox-2" />
211+ </ CheckboxGroup >
212+ ) ;
213+
214+ const checkbox1 = screen . getByLabelText ( 'Checkbox 1' ) ;
215+ const checkbox2 = screen . getByLabelText ( 'Checkbox 2' ) ;
216+ const attributes1 = getElementAttributes ( checkbox1 ) ;
217+ const attributes2 = getElementAttributes ( checkbox2 ) ;
218+
219+ expect ( attributes1 ) . toEqual ( {
220+ class : `${ prefix } --checkbox` ,
221+ id : 'checkbox-1' ,
222+ 'data-invalid' : 'true' ,
223+ 'aria-readonly' : 'true' ,
224+ type : 'checkbox' ,
225+ } ) ;
226+ expect ( attributes2 ) . toEqual ( {
227+ class : `${ prefix } --checkbox` ,
228+ id : 'checkbox-2' ,
229+ 'data-invalid' : 'true' ,
230+ 'aria-readonly' : 'true' ,
231+ type : 'checkbox' ,
232+ } ) ;
233+ } ) ;
234+
235+ it ( 'should not override individual `Checkbox` props' , ( ) => {
236+ render (
237+ < CheckboxGroup legendText = "Checkbox heading" readOnly >
238+ < Checkbox labelText = "Checkbox 1" id = "checkbox-1" readOnly = { false } />
239+ < Checkbox labelText = "Checkbox 2" id = "checkbox-2" />
240+ </ CheckboxGroup >
241+ ) ;
242+
243+ const checkbox1 = screen . getByLabelText ( 'Checkbox 1' ) ;
244+ const checkbox2 = screen . getByLabelText ( 'Checkbox 2' ) ;
245+ const attributes1 = getElementAttributes ( checkbox1 ) ;
246+ const attributes2 = getElementAttributes ( checkbox2 ) ;
247+
248+ expect ( attributes1 ) . toEqual ( {
249+ class : `${ prefix } --checkbox` ,
250+ id : 'checkbox-1' ,
251+ // Should not be read-only because it explicitly sets `readOnly` to
252+ // `false`.
253+ 'aria-readonly' : 'false' ,
254+ type : 'checkbox' ,
255+ } ) ;
256+ expect ( attributes2 ) . toEqual ( {
257+ class : `${ prefix } --checkbox` ,
258+ id : 'checkbox-2' ,
259+ // Should be read-only because it inherits from the group.
260+ 'aria-readonly' : 'true' ,
261+ type : 'checkbox' ,
262+ } ) ;
263+ } ) ;
264+
265+ it ( 'should not affect non-`Checkbox` children' , ( ) => {
266+ render (
267+ < CheckboxGroup legendText = "Checkbox heading" readOnly >
268+ < Checkbox labelText = "Checkbox label" id = "checkbox-1" />
269+ < div data-testid = "non-checkbox" > Not a checkbox</ div >
270+ </ CheckboxGroup >
271+ ) ;
272+
273+ const checkbox = screen . getByLabelText ( 'Checkbox label' ) ;
274+ const nonCheckbox = screen . getByTestId ( 'non-checkbox' ) ;
275+ const checkboxAttributes = getElementAttributes ( checkbox ) ;
276+ const nonCheckboxAttributes = getElementAttributes ( nonCheckbox ) ;
277+
278+ expect ( checkboxAttributes ) . toEqual ( {
279+ class : `${ prefix } --checkbox` ,
280+ id : 'checkbox-1' ,
281+ 'aria-readonly' : 'true' ,
282+ type : 'checkbox' ,
283+ } ) ;
284+ expect ( nonCheckboxAttributes ) . toEqual ( {
285+ 'data-testid' : 'non-checkbox' ,
286+ } ) ;
287+ } ) ;
288+ } ) ;
194289} ) ;
0 commit comments