Skip to content

Commit 8983e37

Browse files
committed
main - 33795a1 fix(material/chips): implement disabledInteractive in chip input (#30665)
1 parent 2cdf5bc commit 8983e37

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

chips/index.d.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,10 @@ declare class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
837837
get disabled(): boolean;
838838
set disabled(value: boolean);
839839
private _disabled;
840+
/** Whether the input is readonly. */
841+
readonly: boolean;
842+
/** Whether the input should remain interactive when it is disabled. */
843+
disabledInteractive: boolean;
840844
/** Whether the input is empty. */
841845
get empty(): boolean;
842846
/** The native input element to which this directive is attached. */
@@ -859,10 +863,14 @@ declare class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
859863
setDescribedByIds(ids: string[]): void;
860864
/** Checks whether a keycode is one of the configured separators. */
861865
private _isSeparatorKey;
866+
/** Gets the value to set on the `readonly` attribute. */
867+
protected _getReadonlyAttribute(): string | null;
862868
static ɵfac: i0.ɵɵFactoryDeclaration<MatChipInput, never>;
863-
static ɵdir: i0.ɵɵDirectiveDeclaration<MatChipInput, "input[matChipInputFor]", ["matChipInput", "matChipInputFor"], { "chipGrid": { "alias": "matChipInputFor"; "required": false; }; "addOnBlur": { "alias": "matChipInputAddOnBlur"; "required": false; }; "separatorKeyCodes": { "alias": "matChipInputSeparatorKeyCodes"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "id": { "alias": "id"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "chipEnd": "matChipInputTokenEnd"; }, never, never, true, never>;
869+
static ɵdir: i0.ɵɵDirectiveDeclaration<MatChipInput, "input[matChipInputFor]", ["matChipInput", "matChipInputFor"], { "chipGrid": { "alias": "matChipInputFor"; "required": false; }; "addOnBlur": { "alias": "matChipInputAddOnBlur"; "required": false; }; "separatorKeyCodes": { "alias": "matChipInputSeparatorKeyCodes"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "id": { "alias": "id"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "disabledInteractive": { "alias": "matChipInputDisabledInteractive"; "required": false; }; }, { "chipEnd": "matChipInputTokenEnd"; }, never, never, true, never>;
864870
static ngAcceptInputType_addOnBlur: unknown;
865871
static ngAcceptInputType_disabled: unknown;
872+
static ngAcceptInputType_readonly: unknown;
873+
static ngAcceptInputType_disabledInteractive: unknown;
866874
}
867875

868876
declare class MatChipsModule {
@@ -877,6 +885,8 @@ interface MatChipsDefaultOptions {
877885
separatorKeyCodes: readonly number[] | ReadonlySet<number>;
878886
/** Whether icon indicators should be hidden for single-selection. */
879887
hideSingleSelectionIndicator?: boolean;
888+
/** Whether the chip input should be interactive while disabled by default. */
889+
inputDisabledInteractive?: boolean;
880890
}
881891
/** Injection token to be used to override the default options for the chips module. */
882892
declare const MAT_CHIPS_DEFAULT_OPTIONS: InjectionToken<MatChipsDefaultOptions>;

fesm2022/chips.mjs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,10 @@ class MatChipInput {
19931993
this._disabled = value;
19941994
}
19951995
_disabled = false;
1996+
/** Whether the input is readonly. */
1997+
readonly = false;
1998+
/** Whether the input should remain interactive when it is disabled. */
1999+
disabledInteractive;
19962000
/** Whether the input is empty. */
19972001
get empty() {
19982002
return !this.inputElement.value;
@@ -2004,6 +2008,7 @@ class MatChipInput {
20042008
const formField = inject(MAT_FORM_FIELD, { optional: true });
20052009
this.inputElement = this._elementRef.nativeElement;
20062010
this.separatorKeyCodes = defaultOptions.separatorKeyCodes;
2011+
this.disabledInteractive = defaultOptions.inputDisabledInteractive ?? false;
20072012
if (formField) {
20082013
this.inputElement.classList.add('mat-mdc-form-field-input-control');
20092014
}
@@ -2082,8 +2087,12 @@ class MatChipInput {
20822087
_isSeparatorKey(event) {
20832088
return !hasModifierKey(event) && new Set(this.separatorKeyCodes).has(event.keyCode);
20842089
}
2090+
/** Gets the value to set on the `readonly` attribute. */
2091+
_getReadonlyAttribute() {
2092+
return this.readonly || (this.disabled && this.disabledInteractive) ? 'true' : null;
2093+
}
20852094
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0-next.1", ngImport: i0, type: MatChipInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2086-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.0.0-next.1", type: MatChipInput, isStandalone: true, selector: "input[matChipInputFor]", inputs: { chipGrid: ["matChipInputFor", "chipGrid"], addOnBlur: ["matChipInputAddOnBlur", "addOnBlur", booleanAttribute], separatorKeyCodes: ["matChipInputSeparatorKeyCodes", "separatorKeyCodes"], placeholder: "placeholder", id: "id", disabled: ["disabled", "disabled", booleanAttribute] }, outputs: { chipEnd: "matChipInputTokenEnd" }, host: { listeners: { "keydown": "_keydown($event)", "blur": "_blur()", "focus": "_focus()", "input": "_onInput()" }, properties: { "id": "id", "attr.disabled": "disabled || null", "attr.placeholder": "placeholder || null", "attr.aria-invalid": "_chipGrid && _chipGrid.ngControl ? _chipGrid.ngControl.invalid : null", "attr.aria-required": "_chipGrid && _chipGrid.required || null", "attr.required": "_chipGrid && _chipGrid.required || null" }, classAttribute: "mat-mdc-chip-input mat-mdc-input-element mdc-text-field__input mat-input-element" }, exportAs: ["matChipInput", "matChipInputFor"], usesOnChanges: true, ngImport: i0 });
2095+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.0.0-next.1", type: MatChipInput, isStandalone: true, selector: "input[matChipInputFor]", inputs: { chipGrid: ["matChipInputFor", "chipGrid"], addOnBlur: ["matChipInputAddOnBlur", "addOnBlur", booleanAttribute], separatorKeyCodes: ["matChipInputSeparatorKeyCodes", "separatorKeyCodes"], placeholder: "placeholder", id: "id", disabled: ["disabled", "disabled", booleanAttribute], readonly: ["readonly", "readonly", booleanAttribute], disabledInteractive: ["matChipInputDisabledInteractive", "disabledInteractive", booleanAttribute] }, outputs: { chipEnd: "matChipInputTokenEnd" }, host: { listeners: { "keydown": "_keydown($event)", "blur": "_blur()", "focus": "_focus()", "input": "_onInput()" }, properties: { "id": "id", "attr.disabled": "disabled && !disabledInteractive ? \"\" : null", "attr.placeholder": "placeholder || null", "attr.aria-invalid": "_chipGrid && _chipGrid.ngControl ? _chipGrid.ngControl.invalid : null", "attr.aria-required": "_chipGrid && _chipGrid.required || null", "attr.aria-disabled": "disabled && disabledInteractive ? \"true\" : null", "attr.readonly": "_getReadonlyAttribute()", "attr.required": "_chipGrid && _chipGrid.required || null" }, classAttribute: "mat-mdc-chip-input mat-mdc-input-element mdc-text-field__input mat-input-element" }, exportAs: ["matChipInput", "matChipInputFor"], usesOnChanges: true, ngImport: i0 });
20872096
}
20882097
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0-next.1", ngImport: i0, type: MatChipInput, decorators: [{
20892098
type: Directive,
@@ -2100,10 +2109,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0-next.1",
21002109
'(focus)': '_focus()',
21012110
'(input)': '_onInput()',
21022111
'[id]': 'id',
2103-
'[attr.disabled]': 'disabled || null',
2112+
'[attr.disabled]': 'disabled && !disabledInteractive ? "" : null',
21042113
'[attr.placeholder]': 'placeholder || null',
21052114
'[attr.aria-invalid]': '_chipGrid && _chipGrid.ngControl ? _chipGrid.ngControl.invalid : null',
21062115
'[attr.aria-required]': '_chipGrid && _chipGrid.required || null',
2116+
'[attr.aria-disabled]': 'disabled && disabledInteractive ? "true" : null',
2117+
'[attr.readonly]': '_getReadonlyAttribute()',
21072118
'[attr.required]': '_chipGrid && _chipGrid.required || null',
21082119
},
21092120
}]
@@ -2126,6 +2137,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0-next.1",
21262137
}], disabled: [{
21272138
type: Input,
21282139
args: [{ transform: booleanAttribute }]
2140+
}], readonly: [{
2141+
type: Input,
2142+
args: [{ transform: booleanAttribute }]
2143+
}], disabledInteractive: [{
2144+
type: Input,
2145+
args: [{ alias: 'matChipInputDisabledInteractive', transform: booleanAttribute }]
21292146
}] } });
21302147

21312148
const CHIP_DECLARATIONS = [

fesm2022/chips.mjs.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fesm2022/chips/testing.mjs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ComponentHarness, HarnessPredicate, ContentContainerComponentHarness, TestKey, parallel } from '@angular/cdk/testing';
2+
import { coerceBooleanProperty } from '@angular/cdk/coercion';
23

34
/** Harness for interacting with a standard Material chip avatar in tests. */
45
class MatChipAvatarHarness extends ComponentHarness {
@@ -104,7 +105,12 @@ class MatChipInputHarness extends ComponentHarness {
104105
}
105106
/** Whether the input is disabled. */
106107
async isDisabled() {
107-
return (await this.host()).getProperty('disabled');
108+
const host = await this.host();
109+
const disabled = await host.getAttribute('disabled');
110+
if (disabled !== null) {
111+
return coerceBooleanProperty(disabled);
112+
}
113+
return (await host.getAttribute('aria-disabled')) === 'true';
108114
}
109115
/** Whether the input is required. */
110116
async isRequired() {

fesm2022/chips/testing.mjs.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)