Skip to content
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ All notable changes for each version of this project will be documented in this

### Behavioral Changes

- `IgxCheckboxComponent`, `IgxSwitchComponent`, `IgxRadioComponent` - the three components now use `ChangeDetectionStrategy.OnPush` instead of `Eager`. Their internal state is backed by Angular signals, so each component marks itself for check whenever that state is written, and is no longer re-checked on every application-wide change detection pass. The public `@Input()`/`@Output()` API is unchanged, and the components keep reflecting state written directly on the instance, e.g. `checkbox.checked = true`.
- **Theming** - Scrollbar arrow buttons cannot be styled or enabled through the standard properties, and `scrollbar-width: thin` removes them where the platform draws them.
- **Firefox** - The `scrollbar-color` and `scrollbar-width` properties are not supported on Firefox versions prior to 64, so the scrollbars in those versions will render with the platform default colors and size.

### Bug Fixes

- `IgxRadioGroupDirective`
- The group's subscriptions to a radio button's events are now released when that button itself is destroyed, instead of living until the whole group is destroyed. Previously, radio buttons added and removed dynamically - for example through `@for` - leaked a subscription per button for the lifetime of the group.
- `IgxCheckboxComponent`
- Fixed the tick-mark icon rendering with the Indigo shape (rounded rect + custom path) inside CSS-scoped subtrees that use a different design system than the application's global theme, e.g. a `material`-themed widget nested inside an `indigo`-themed app. Both tick-mark variants are now always rendered and toggled purely via CSS (`@container style(--ig-theme: indigo)`), removing the dependency on JS-side theme detection that could go stale in nested/multi-theme scenarios (#15021).
- **Ripple**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
<input #checkbox class="igx-checkbox__input"
type="checkbox"
[id]="inputId"
[name]="name"
[value]="value"
[tabindex]="tabindex"
[disabled]="disabled"
[indeterminate]="indeterminate"
[checked]="checked"
[name]="_name()"
[value]="_value()"
[tabindex]="_tabindex()"
[disabled]="_disabled()"
[indeterminate]="_indeterminate()"
[checked]="_checked()"
[required]="required"
[attr.aria-required]="required"
[attr.aria-invalid]="invalid"
[attr.aria-checked]="ariaChecked"
[attr.aria-labelledby]="ariaLabel ? null : ariaLabelledBy"
[attr.aria-label]="ariaLabel"
[attr.aria-invalid]="_invalid()"
[attr.aria-checked]="_ariaChecked()"
[attr.aria-labelledby]="_ariaLabel() ? null : _ariaLabelledBy()"
[attr.aria-label]="_ariaLabel()"
(change)="_onCheckboxChange($event)"
(blur)="onBlur()" />

<div
igxRipple
igxRippleTarget=".igx-checkbox__ripple"
[igxRippleDisabled]="disableRipple"
[igxRippleDisabled]="_disableRipple()"
[igxRippleCentered]="true"
[igxRippleDuration]="300"
class="igx-checkbox__composite-wrapper"
Expand All @@ -38,7 +38,7 @@
</div>

<span #placeholderLabel
[class]="labelClass"
[id]="labelId">
[class]="_labelClass()"
[id]="_labelId()">
<ng-content></ng-content>
</span>
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
Component,
HostBinding,
Input,
AfterViewInit,
booleanAttribute,
ChangeDetectionStrategy,
ViewEncapsulation
Component,
Input,
AfterViewInit,
booleanAttribute,
ChangeDetectionStrategy,
ViewEncapsulation,
signal
} from '@angular/core';
import { CheckboxBaseDirective, IgxRippleDirective } from 'igniteui-angular/directives';
import { ControlValueAccessor } from '@angular/forms';
Expand Down Expand Up @@ -46,12 +46,23 @@ import { EditorProvider, EDITOR_PROVIDER } from 'igniteui-angular/core';
templateUrl: 'checkbox.component.html',
styleUrl: 'checkbox.component.css',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.Eager,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [IgxRippleDirective],
host: {
'[class.igx-checkbox]': 'cssClass',
'[class.igx-checkbox--focused]': 'focused',
'[class.igx-checkbox--indeterminate]': 'indeterminate',
'[class.igx-checkbox--checked]': 'checked',
'[class.igx-checkbox--disabled]': 'disabled',
'[class.igx-checkbox--invalid]': 'invalid',
'[class.igx-checkbox--plain]': '_disableTransitions()',
},
})
export class IgxCheckboxComponent
extends CheckboxBaseDirective
implements AfterViewInit, ControlValueAccessor, EditorProvider {
protected readonly _disableTransitions = signal(false);

/**
* Returns the class of the checkbox component.
*
Expand All @@ -60,7 +71,6 @@ export class IgxCheckboxComponent
* let class = this.checkbox.cssClass;
* ```
*/
@HostBinding('class.igx-checkbox')
public override cssClass = 'igx-checkbox';

/**
Expand All @@ -75,8 +85,12 @@ export class IgxCheckboxComponent
* let isFocused = this.checkbox.focused;
* ```
*/
@HostBinding('class.igx-checkbox--focused')
public override focused = false;
public override get focused() {
return super.focused;
}
public override set focused(value: boolean) {
super.focused = value;
}

/**
* Sets/gets the checkbox indeterminate visual state.
Expand All @@ -90,9 +104,13 @@ export class IgxCheckboxComponent
* let isIndeterminate = this.checkbox.indeterminate;
* ```
*/
@HostBinding('class.igx-checkbox--indeterminate')
@Input({ transform: booleanAttribute })
public override indeterminate = false;
public override get indeterminate() {
return super.indeterminate;
}
public override set indeterminate(value: boolean) {
super.indeterminate = value;
}

/**
* Sets/gets whether the checkbox is checked.
Expand All @@ -106,7 +124,6 @@ export class IgxCheckboxComponent
* let isChecked = this.checkbox.checked;
* ```
*/
@HostBinding('class.igx-checkbox--checked')
@Input({ transform: booleanAttribute })
public override set checked(value: boolean) {
super.checked = value;
Expand All @@ -127,9 +144,13 @@ export class IgxCheckboxComponent
* let isDisabled = this.checkbox.disabled;
* ```
*/
@HostBinding('class.igx-checkbox--disabled')
@Input({ transform: booleanAttribute })
public override disabled = false;
public override get disabled() {
return super.disabled;
}
public override set disabled(value: boolean) {
super.disabled = value;
}

/**
* Sets/gets whether the checkbox is invalid.
Expand All @@ -143,9 +164,13 @@ export class IgxCheckboxComponent
* let isInvalid = this.checkbox.invalid;
* ```
*/
@HostBinding('class.igx-checkbox--invalid')
@Input({ transform: booleanAttribute })
public override invalid = false;
public override get invalid() {
return super.invalid;
}
public override set invalid(value: boolean) {
super.invalid = value;
}

/**
* Sets/gets whether the checkbox is readonly.
Expand All @@ -160,7 +185,12 @@ export class IgxCheckboxComponent
* ```
*/
@Input({ transform: booleanAttribute })
public override readonly = false;
public override get readonly() {
return super.readonly;
}
public override set readonly(value: boolean) {
super.readonly = value;
}

/**
* Sets/gets whether the checkbox should disable all css transitions.
Expand All @@ -174,7 +204,11 @@ export class IgxCheckboxComponent
* let disableTransitions = this.checkbox.disableTransitions;
* ```
*/
@HostBinding('class.igx-checkbox--plain')
@Input({ transform: booleanAttribute })
public disableTransitions = false;
public get disableTransitions() {
return this._disableTransitions();
}
public set disableTransitions(value: boolean) {
this._disableTransitions.set(value);
}
}
Loading
Loading