Skip to content

Commit b250661

Browse files
Lipatadamyanpetev
authored andcommitted
feat(checkbox): add readonly prop #5675 (#5716)
* feat(checkbox): add readonly prop #5675 * remove fit * Apply suggestions from code review Co-Authored-By: Damyan Petev <[email protected]> * fix(chechbox): prevent chagning native state when checkbox is readonly #5675 * chore(checkbox): update comment text
1 parent 997751a commit b250661

File tree

5 files changed

+70
-3
lines changed

5 files changed

+70
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ For more information about the theming please read our [documentation](https://w
4545
- `IgxDrop`
4646
- Linking of drag and drop elements. This can be achieved by using the new provided `dropChannel` input, specifying each drop area to which channel it corresponds.
4747
- Drop strategies. Three new drop strategies have been provided - Append, Prepend and Insert. Also an input `dropStrategy` to the `igxDrop` which specify which strategy should be used when dropping an element inside the drop area. Custom one can be specified as well.
48+
- `IgxCheckbox`
49+
- introduced a new `readonly` property that doesn't allow user interaction to change the state, but keeps the default active style. Intended for integration in complex controls that handle the interaction and control the checkbox instead through binding.
4850

4951
### General
5052
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`

projects/igniteui-angular/src/lib/checkbox/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ To disable the ripple effect, do:
7575
| `@Input()` indeterminate | boolean | Specifies the indeterminate state of the checkbox. |
7676
| `@Input()` required | boolean | Specifies the required state of the checkbox. |
7777
| `@Input()` disabled | boolean | Specifies the disabled state of the checkbox. |
78+
| `@Input()` readonly | boolean | Specifies the readonly state of the checkbox. |
7879
| `@Input()` disableRipple | boolean | Specifies whether the ripple effect should be disabled for the checkbox. |
7980
| `@Input()` disableTransitions | boolean | Specifies whether CSS transitions should be disabled for the checkbox. |
8081
| `@Input()` labelPosition | string `|` enum LabelPosition | Specifies the position of the text label relative to the checkbox element. |

projects/igniteui-angular/src/lib/checkbox/checkbox.component.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('IgxCheckbox', () => {
1919
InitCheckboxComponent,
2020
CheckboxSimpleComponent,
2121
CheckboxDisabledComponent,
22+
CheckboxReadonlyComponent,
2223
CheckboxIndeterminateComponent,
2324
CheckboxRequiredComponent,
2425
CheckboxExternalLabelComponent,
@@ -158,6 +159,33 @@ describe('IgxCheckbox', () => {
158159
expect(testInstance.subscribed).toBe(false);
159160
});
160161

162+
it('Readonly state', () => {
163+
const fixture = TestBed.createComponent(CheckboxReadonlyComponent);
164+
const testInstance = fixture.componentInstance;
165+
const checkboxInstance = testInstance.cb;
166+
const nativeCheckbox = checkboxInstance.nativeCheckbox.nativeElement;
167+
const nativeLabel = checkboxInstance.nativeLabel.nativeElement;
168+
const placeholderLabel = checkboxInstance.placeholderLabel.nativeElement;
169+
fixture.detectChanges();
170+
expect(checkboxInstance.readonly).toBe(true);
171+
expect(testInstance.subscribed).toBe(false);
172+
173+
nativeCheckbox.dispatchEvent(new Event('change'));
174+
fixture.detectChanges();
175+
// Should not update
176+
expect(testInstance.subscribed).toBe(false);
177+
178+
nativeLabel.click();
179+
fixture.detectChanges();
180+
// Should not update
181+
expect(testInstance.subscribed).toBe(false);
182+
183+
placeholderLabel.click();
184+
fixture.detectChanges();
185+
// Should not update
186+
expect(testInstance.subscribed).toBe(false);
187+
});
188+
161189
it('Should be able to enable/disable CSS transitions', () => {
162190
const fixture = TestBed.createComponent(CheckboxDisabledTransitionsComponent);
163191
const testInstance = fixture.componentInstance;
@@ -282,6 +310,17 @@ class CheckboxDisabledComponent {
282310
public subscribed = false;
283311
}
284312

313+
@Component({
314+
template: `<igx-checkbox #cb
315+
[(ngModel)]="subscribed"
316+
[checked]="subscribed"
317+
[readonly]="true">Readonly</igx-checkbox>`})
318+
class CheckboxReadonlyComponent {
319+
@ViewChild('cb', { static: true }) public cb: IgxCheckboxComponent;
320+
321+
public subscribed = false;
322+
}
323+
285324
@Component({
286325
template: `<p id="my-label">{{label}}</p>
287326
<igx-checkbox #cb aria-labelledby="my-label"></igx-checkbox>`

projects/igniteui-angular/src/lib/checkbox/checkbox.component.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,24 @@ export class IgxCheckboxComponent implements ControlValueAccessor, EditorProvide
258258
* <igx-checkbox [disabled] = "true"></igx-checkbox>
259259
* ```
260260
* ```typescript
261-
* let isDesabled = this.checkbox.disabled;
261+
* let isDisabled = this.checkbox.disabled;
262262
* ```
263263
* @memberof IgxCheckboxComponent
264264
*/
265265
@HostBinding('class.igx-checkbox--disabled')
266266
@Input() public disabled = false;
267+
/**
268+
* Sets/gets whether the checkbox is readonly.
269+
* Default value is `false`.
270+
* ```html
271+
* <igx-checkbox [readonly]="true"></igx-checkbox>
272+
* ```
273+
* ```typescript
274+
* let readonly = this.checkbox.readonly;
275+
* ```
276+
* @memberof IgxCheckboxComponent
277+
*/
278+
@Input() public readonly = false;
267279
/**
268280
* Sets/gets whether the checkbox should disable all css transitions.
269281
* Default value is `false`.
@@ -297,7 +309,7 @@ export class IgxCheckboxComponent implements ControlValueAccessor, EditorProvide
297309
* @memberof IgxCheckboxComponent
298310
*/
299311
public toggle() {
300-
if (this.disabled) {
312+
if (this.disabled || this.readonly) {
301313
return;
302314
}
303315

@@ -326,6 +338,13 @@ export class IgxCheckboxComponent implements ControlValueAccessor, EditorProvide
326338
// as it gets triggered on label click
327339
event.stopPropagation();
328340

341+
if (this.readonly) {
342+
// readonly prevents the component from changing state (see toggle() method).
343+
// However, the native checkbox can still be activated through user interaction (focus + space, label click)
344+
// Prevent the native change so the input remains in sync
345+
event.preventDefault();
346+
}
347+
329348
if (isIE()) {
330349
this.nativeCheckbox.nativeElement.blur();
331350
}

src/app/input/input.sample.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,16 @@ <h4 class="sample-title">Checkbox sample</h4>
8181

8282
<igx-list-item>
8383
<igx-avatar igxListThumbnail src="assets/images/avatar/17.jpg" roundShape="true"></igx-avatar>
84-
<span igxListLineTitle>Brian Vaughan</span>
84+
<span igxListLineTitle>Brian Vaughan (disabled)</span>
8585
<igx-checkbox igxListAction [(ngModel)]="user.registered" [disabled]="true">Value</igx-checkbox>
8686
</igx-list-item>
8787

88+
<igx-list-item>
89+
<igx-avatar igxListThumbnail src="assets/images/avatar/17.jpg" roundShape="true"></igx-avatar>
90+
<span igxListLineTitle>Brian Vaughan (readonly)</span>
91+
<igx-checkbox igxListAction [(ngModel)]="user.registered" [readonly]="true">Value</igx-checkbox>
92+
</igx-list-item>
93+
8894
<igx-list-item>
8995
<igx-avatar igxListThumbnail src="assets/images/avatar/17.jpg" roundShape="true"></igx-avatar>
9096
<span igxListLineTitle>Brian Vaughan</span>

0 commit comments

Comments
 (0)