Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add readonly property to checkbox and checkbox-group #7199

Merged
merged 8 commits into from
Apr 10, 2024
8 changes: 8 additions & 0 deletions packages/checkbox-group/src/vaadin-checkbox-group-mixin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,12 @@ export declare class CheckboxGroupMixinClass {
* creating a new array.
*/
value: string[];

/**
* When true, the user cannot modify the value of the checkbox group.
* The difference between `disabled` and `readonly` is that in the
* read-only checkbox group, all the checkboxes are also read-only,
* and therefore remain focusable and announced by screen readers.
*/
readonly: boolean;
}
26 changes: 26 additions & 0 deletions packages/checkbox-group/src/vaadin-checkbox-group-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ export const CheckboxGroupMixin = (superclass) =>
notify: true,
observer: '__valueChanged',
},

/**
* When true, the user cannot modify the value of the checkbox group.
* The difference between `disabled` and `readonly` is that in the
* read-only checkbox group, all the checkboxes are also read-only,
* and therefore remain focusable and announced by screen readers.
*/
readonly: {
type: Boolean,
value: false,
reflectToAttribute: true,
observer: '__readonlyChanged',
},
};
}

Expand Down Expand Up @@ -145,6 +158,10 @@ export const CheckboxGroupMixin = (superclass) =>
checkbox.disabled = true;
}

if (this.readonly) {
checkbox.readonly = true;
}

if (checkbox.checked) {
this.__addCheckboxToValue(checkbox.value);
} else if (this.value.includes(checkbox.value)) {
Expand Down Expand Up @@ -248,6 +265,15 @@ export const CheckboxGroupMixin = (superclass) =>
}
}

/** @private */
__readonlyChanged(readonly, oldReadonly) {
if (readonly || oldReadonly) {
this.__checkboxes.forEach((checkbox) => {
checkbox.readonly = readonly;
});
}
}

/**
* Override method inherited from `FocusMixin`
* to prevent removing the `focused` attribute
Expand Down
32 changes: 32 additions & 0 deletions packages/checkbox-group/test/checkbox-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,38 @@ describe('vaadin-checkbox-group', () => {
});
});

describe('readonly', () => {
beforeEach(async () => {
group = fixtureSync(`
<vaadin-checkbox-group readonly>
<vaadin-checkbox value="1" label="Checkbox 1"></vaadin-checkbox>
<vaadin-checkbox value="2" label="Checkbox 2"></vaadin-checkbox>
</vaadin-checkbox-group>
`);
await nextFrame();
checkboxes = [...group.querySelectorAll('vaadin-checkbox')];
});

it('should propagate readonly property to checkboxes', () => {
checkboxes.forEach((checkbox) => {
expect(checkbox.readonly).to.be.true;
});

group.readonly = false;
checkboxes.forEach((checkbox) => {
expect(checkbox.readonly).to.be.false;
});
});

it('should set disabled property to dynamically added checkboxes', async () => {
web-padawan marked this conversation as resolved.
Show resolved Hide resolved
const checkbox = document.createElement('vaadin-checkbox');
checkbox.value = '3';
group.appendChild(checkbox);
await nextFrame();
expect(checkbox.readonly).to.be.true;
});
});

describe('value', () => {
beforeEach(async () => {
group = fixtureSync(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,70 @@ snapshots["vaadin-checkbox-group host default"] =
`;
/* end snapshot vaadin-checkbox-group host default */

snapshots["vaadin-checkbox-group host label"] =
`<vaadin-checkbox-group
aria-labelledby="label-vaadin-checkbox-group-0"
has-label=""
role="group"
>
<vaadin-checkbox
has-label=""
has-value=""
label="Checkbox 1"
value="1"
>
<label
for="input-vaadin-checkbox-5"
id="label-vaadin-checkbox-3"
slot="label"
>
Checkbox 1
</label>
<input
id="input-vaadin-checkbox-5"
slot="input"
tabindex="0"
type="checkbox"
value="1"
>
</vaadin-checkbox>
<vaadin-checkbox
has-label=""
has-value=""
label="Checkbox 2"
value="2"
>
<label
for="input-vaadin-checkbox-6"
id="label-vaadin-checkbox-4"
slot="label"
>
Checkbox 2
</label>
<input
id="input-vaadin-checkbox-6"
slot="input"
tabindex="0"
type="checkbox"
value="2"
>
</vaadin-checkbox>
<label
id="label-vaadin-checkbox-group-0"
slot="label"
>
Label
</label>
<div
hidden=""
id="error-message-vaadin-checkbox-group-2"
slot="error-message"
>
</div>
</vaadin-checkbox-group>
`;
/* end snapshot vaadin-checkbox-group host label */

snapshots["vaadin-checkbox-group host disabled"] =
`<vaadin-checkbox-group
aria-disabled="true"
Expand Down Expand Up @@ -129,45 +193,16 @@ snapshots["vaadin-checkbox-group host disabled"] =
`;
/* end snapshot vaadin-checkbox-group host disabled */

snapshots["vaadin-checkbox-group shadow default"] =
`<div class="vaadin-group-field-container">
<div part="label">
<slot name="label">
</slot>
<span
aria-hidden="true"
part="required-indicator"
>
</span>
</div>
<div part="group-field">
<slot>
</slot>
</div>
<div part="helper-text">
<slot name="helper">
</slot>
</div>
<div part="error-message">
<slot name="error-message">
</slot>
</div>
</div>
<slot name="tooltip">
</slot>
`;
/* end snapshot vaadin-checkbox-group shadow default */

snapshots["vaadin-checkbox-group host label"] =
snapshots["vaadin-checkbox-group host readonly"] =
`<vaadin-checkbox-group
aria-labelledby="label-vaadin-checkbox-group-0"
has-label=""
readonly=""
role="group"
>
<vaadin-checkbox
has-label=""
has-value=""
label="Checkbox 1"
readonly=""
value="1"
>
<label
Expand All @@ -178,6 +213,7 @@ snapshots["vaadin-checkbox-group host label"] =
Checkbox 1
</label>
<input
aria-readonly="true"
id="input-vaadin-checkbox-5"
slot="input"
tabindex="0"
Expand All @@ -189,6 +225,7 @@ snapshots["vaadin-checkbox-group host label"] =
has-label=""
has-value=""
label="Checkbox 2"
readonly=""
value="2"
>
<label
Expand All @@ -199,6 +236,7 @@ snapshots["vaadin-checkbox-group host label"] =
Checkbox 2
</label>
<input
aria-readonly="true"
id="input-vaadin-checkbox-6"
slot="input"
tabindex="0"
Expand All @@ -210,7 +248,6 @@ snapshots["vaadin-checkbox-group host label"] =
id="label-vaadin-checkbox-group-0"
slot="label"
>
Label
</label>
<div
hidden=""
Expand All @@ -220,7 +257,7 @@ snapshots["vaadin-checkbox-group host label"] =
</div>
</vaadin-checkbox-group>
`;
/* end snapshot vaadin-checkbox-group host label */
/* end snapshot vaadin-checkbox-group host readonly */

snapshots["vaadin-checkbox-group host required"] =
`<vaadin-checkbox-group
Expand Down Expand Up @@ -419,3 +456,32 @@ snapshots["vaadin-checkbox-group host error"] =
`;
/* end snapshot vaadin-checkbox-group host error */

snapshots["vaadin-checkbox-group shadow default"] =
`<div class="vaadin-group-field-container">
<div part="label">
<slot name="label">
</slot>
<span
aria-hidden="true"
part="required-indicator"
>
</span>
</div>
<div part="group-field">
<slot>
</slot>
</div>
<div part="helper-text">
<slot name="helper">
</slot>
</div>
<div part="error-message">
<slot name="error-message">
</slot>
</div>
</div>
<slot name="tooltip">
</slot>
`;
/* end snapshot vaadin-checkbox-group shadow default */

5 changes: 5 additions & 0 deletions packages/checkbox-group/test/dom/checkbox-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ describe('vaadin-checkbox-group', () => {
await expect(group).dom.to.equalSnapshot();
});

it('readonly', async () => {
group.readonly = true;
await expect(group).dom.to.equalSnapshot();
});

it('required', async () => {
group.required = true;
await expect(group).dom.to.equalSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ describe('checkbox-group', () => {
await visualDiff(div, 'value');
});

it('readonly', async () => {
element.readonly = true;
element.value = ['a', 'c'];
await visualDiff(div, 'readonly');
});

it('required', async () => {
element.label = 'Label';
element.required = true;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ describe('checkbox-group', () => {
await visualDiff(div, 'value');
});

it('readonly', async () => {
element.readonly = true;
element.value = ['a', 'c'];
await visualDiff(div, 'readonly');
});

it('required', async () => {
element.label = 'Label';
element.required = true;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions packages/checkbox/src/vaadin-checkbox-mixin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@ export declare class CheckboxMixinClass {
* The name of the checkbox.
*/
name: string;

/**
* When true, the user cannot modify the value of the checkbox.
* The difference between `disabled` and `readonly` is that the
* read-only checkbox remains focusable, is announced by screen
* readers and its value can be submitted as part of the form.
*/
readonly: boolean;
}
Loading
Loading