diff --git a/angular/src/directives/proxies.ts b/angular/src/directives/proxies.ts index 29362ba1a2..07af9c83f8 100644 --- a/angular/src/directives/proxies.ts +++ b/angular/src/directives/proxies.ts @@ -140,7 +140,7 @@ export class IonCardTitle { proxyInputs(IonCardTitle, ['color', 'mode']); export declare interface IonCheckbox extends StencilComponents<'IonCheckbox'> {} -@Component({ selector: 'ion-checkbox', changeDetection: 0, template: '', inputs: ['color', 'mode', 'name', 'checked', 'disabled', 'value'] }) +@Component({ selector: 'ion-checkbox', changeDetection: 0, template: '', inputs: ['color', 'mode', 'name', 'checked', 'indeterminate', 'disabled', 'value'] }) export class IonCheckbox { ionChange!: EventEmitter; ionFocus!: EventEmitter; @@ -152,7 +152,7 @@ export class IonCheckbox { proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']); } } -proxyInputs(IonCheckbox, ['color', 'mode', 'name', 'checked', 'disabled', 'value']); +proxyInputs(IonCheckbox, ['color', 'mode', 'name', 'checked', 'indeterminate', 'disabled', 'value']); export declare interface IonChip extends StencilComponents<'IonChip'> {} @Component({ selector: 'ion-chip', changeDetection: 0, template: '', inputs: ['color', 'mode', 'outline'] }) diff --git a/core/api.txt b/core/api.txt index 17c1b7f5fa..147c31f968 100644 --- a/core/api.txt +++ b/core/api.txt @@ -195,6 +195,7 @@ ion-checkbox,shadow ion-checkbox,prop,checked,boolean,false,false,false ion-checkbox,prop,color,string | undefined,undefined,false,false ion-checkbox,prop,disabled,boolean,false,false,false +ion-checkbox,prop,indeterminate,boolean,false,false,false ion-checkbox,prop,mode,"ios" | "md",undefined,false,false ion-checkbox,prop,name,string,this.inputId,false,false ion-checkbox,prop,value,string,'on',false,false diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 8e6b42d13f..89c497e3de 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -749,6 +749,10 @@ export namespace Components { */ 'disabled': boolean; /** + * If `true`, the checkbox will visually appear as indeterminate. + */ + 'indeterminate': boolean; + /** * The mode determines which platform styles to use. */ 'mode': Mode; @@ -775,6 +779,10 @@ export namespace Components { */ 'disabled'?: boolean; /** + * If `true`, the checkbox will visually appear as indeterminate. + */ + 'indeterminate'?: boolean; + /** * The mode determines which platform styles to use. */ 'mode'?: Mode; diff --git a/core/src/components/checkbox/checkbox.ios.scss b/core/src/components/checkbox/checkbox.ios.scss index 701e9b6edf..876eea67ba 100644 --- a/core/src/components/checkbox/checkbox.ios.scss +++ b/core/src/components/checkbox/checkbox.ios.scss @@ -16,8 +16,8 @@ // Size --size: #{$checkbox-ios-icon-size}; - width: var(--size); + width: var(--size); height: var(--size); } @@ -39,6 +39,7 @@ @include margin($checkbox-ios-item-end-margin-top, $checkbox-ios-item-end-margin-end, $checkbox-ios-item-end-margin-bottom, $checkbox-ios-item-end-margin-start); display: block; + position: static; } diff --git a/core/src/components/checkbox/checkbox.md.scss b/core/src/components/checkbox/checkbox.md.scss index a9dd694d22..ed49019846 100644 --- a/core/src/components/checkbox/checkbox.md.scss +++ b/core/src/components/checkbox/checkbox.md.scss @@ -13,23 +13,28 @@ // Background --background: #{$checkbox-md-icon-background-color-off}; + + // Transition --transition: #{background $checkbox-md-transition-duration $checkbox-md-transition-easing}; // Size --size: #{$checkbox-md-icon-size}; - width: var(--size); + width: var(--size); height: var(--size); } - .checkbox-icon path { stroke-dasharray: 30; stroke-dashoffset: 30; stroke-width: 3; } -:host(.checkbox-checked) .checkbox-icon path { +// Material Design Checkbox: Checked / Indeterminate +// -------------------------------------------------------- + +:host(.checkbox-checked) .checkbox-icon path, +:host(.checkbox-indeterminate) .checkbox-icon path { stroke-dashoffset: 0; transition: stroke-dashoffset 90ms linear 90ms; @@ -37,21 +42,23 @@ // Material Design Checkbox: Disabled -// ----------------------------------------- +// -------------------------------------------------------- // TODO .item-md.item-checkbox-disabled ion-label :host(.checkbox-disabled) { opacity: $checkbox-md-disabled-opacity; } + // Material Design Checkbox Within An Item -// ----------------------------------------- +// -------------------------------------------------------- :host(.in-item) { // end position by default @include margin($checkbox-md-item-end-margin-top, $checkbox-md-item-end-margin-end, $checkbox-md-item-end-margin-bottom, $checkbox-md-item-end-margin-start); display: block; + position: static; } diff --git a/core/src/components/checkbox/checkbox.scss b/core/src/components/checkbox/checkbox.scss index 01c29cd968..dd1156568d 100644 --- a/core/src/components/checkbox/checkbox.scss +++ b/core/src/components/checkbox/checkbox.scss @@ -6,14 +6,18 @@ :host { /** * @prop --size: Size of the checkbox icon + * * @prop --background: Background of the checkbox icon + * @prop --background-checked: Background of the checkbox icon when checked + * * @prop --border-color: Border color of the checkbox icon * @prop --border-radius: Border radius of the checkbox icon * @prop --border-width: Border width of the checkbox icon * @prop --border-style: Border style of the checkbox icon - * @prop --transition: Transition of the checkbox icon - * @prop --background-checked: Background of the checkbox icon when checked * @prop --border-color-checked: Border color of the checkbox icon when checked + * + * @prop --transition: Transition of the checkbox icon + * * @prop --checkmark-color: Color of the checkbox checkmark when checked */ --background-checked: #{ion-color(primary, base)}; @@ -67,19 +71,23 @@ button { opacity: 0; } -// Checked Checkbox + +// Checked / Indeterminate Checkbox // --------------------------------------------- -:host(.checkbox-checked) .checkbox-icon { +:host(.checkbox-checked) .checkbox-icon, +:host(.checkbox-indeterminate) .checkbox-icon { border-color: var(--border-color-checked); background: var(--background-checked); } -:host(.checkbox-checked) .checkbox-icon path { +:host(.checkbox-checked) .checkbox-icon path, +:host(.checkbox-indeterminate) .checkbox-icon path { opacity: 1; } + // Disabled Checkbox // --------------------------------------------- diff --git a/core/src/components/checkbox/checkbox.tsx b/core/src/components/checkbox/checkbox.tsx index 6fa1b725b9..a5c146fb51 100644 --- a/core/src/components/checkbox/checkbox.tsx +++ b/core/src/components/checkbox/checkbox.tsx @@ -41,6 +41,11 @@ export class Checkbox implements ComponentInterface { */ @Prop({ mutable: true }) checked = false; + /** + * If `true`, the checkbox will visually appear as indeterminate. + */ + @Prop({ mutable: true }) indeterminate = false; + /** * If `true`, the user cannot interact with the checkbox. */ @@ -101,6 +106,7 @@ export class Checkbox implements ComponentInterface { onClick() { this.setFocus(); this.checked = !this.checked; + this.indeterminate = false; } private setFocus() { @@ -134,6 +140,7 @@ export class Checkbox implements ComponentInterface { 'in-item': hostContext('ion-item', el), 'checkbox-checked': checked, 'checkbox-disabled': disabled, + 'checkbox-indeterminate': this.indeterminate, 'interactive': true } }; @@ -142,12 +149,19 @@ export class Checkbox implements ComponentInterface { render() { renderHiddenInput(true, this.el, this.name, (this.checked ? this.value : ''), this.disabled); + let path = this.indeterminate + ? + : ; + + if (this.mode === 'md') { + path = this.indeterminate + ? + : ; + } + return [ - { this.mode === 'md' - ? - : - } + {path} ,