From 9422e01fcbc098a557c392fa58b568f3910f15fa Mon Sep 17 00:00:00 2001 From: Michael Small Date: Mon, 28 Sep 2026 21:34:01 -0500 Subject: [PATCH 1/4] docs: add signal form example for `mat-select` --- .../material/select/index.ts | 1 + .../select-form-signal-form-example.html | 23 +++++++++++ .../select-form-signal-form-example.ts | 40 +++++++++++++++++++ .../select/select-form/select-form-example.ts | 2 +- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.html create mode 100644 src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.ts diff --git a/src/components-examples/material/select/index.ts b/src/components-examples/material/select/index.ts index 594bd086b375..f9855ac5ca4a 100644 --- a/src/components-examples/material/select/index.ts +++ b/src/components-examples/material/select/index.ts @@ -2,6 +2,7 @@ export {SelectCustomTriggerExample} from './select-custom-trigger/select-custom- export {SelectDisabledExample} from './select-disabled/select-disabled-example'; export {SelectErrorStateMatcherExample} from './select-error-state-matcher/select-error-state-matcher-example'; export {SelectFormExample} from './select-form/select-form-example'; +export {SelectFormSignalFormExample} from './select-form-signal-form/select-form-signal-form-example'; export {SelectHintErrorExample} from './select-hint-error/select-hint-error-example'; export {SelectMultipleExample} from './select-multiple/select-multiple-example'; export {SelectNoRippleExample} from './select-no-ripple/select-no-ripple-example'; diff --git a/src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.html b/src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.html new file mode 100644 index 000000000000..e33133c6dc4f --- /dev/null +++ b/src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.html @@ -0,0 +1,23 @@ +
+

mat-select

+ + Favorite food + + @for (food of foods; track food) { + {{food.viewValue}} + } + + +

Selected food: {{selectedValue().value()}}

+

native html select

+ + Favorite car + + +

Selected car: {{selectedCar().value()}}

+
diff --git a/src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.ts b/src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.ts new file mode 100644 index 000000000000..259d8ff11859 --- /dev/null +++ b/src/components-examples/material/select/select-form-signal-form/select-form-signal-form-example.ts @@ -0,0 +1,40 @@ +import {Component, signal} from '@angular/core'; +import {MatInputModule} from '@angular/material/input'; +import {MatSelectModule} from '@angular/material/select'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {form, FormField} from '@angular/forms/signals'; + +interface Food { + value: string; + viewValue: string; +} + +interface Car { + value: string; + viewValue: string; +} + +/** + * @title Select in a form (signal forms) + */ +@Component({ + selector: 'select-form-signal-form-example', + templateUrl: 'select-form-signal-form-example.html', + imports: [FormField, MatFormFieldModule, MatSelectModule, MatInputModule], +}) +export class SelectFormSignalFormExample { + protected selectedValue = form(signal('')); + protected selectedCar = form(signal('')); + + protected foods: Food[] = [ + {value: 'steak-0', viewValue: 'Steak'}, + {value: 'pizza-1', viewValue: 'Pizza'}, + {value: 'tacos-2', viewValue: 'Tacos'}, + ]; + + protected cars: Car[] = [ + {value: 'volvo', viewValue: 'Volvo'}, + {value: 'saab', viewValue: 'Saab'}, + {value: 'mercedes', viewValue: 'Mercedes'}, + ]; +} diff --git a/src/components-examples/material/select/select-form/select-form-example.ts b/src/components-examples/material/select/select-form/select-form-example.ts index 4adec595ab14..5ef030ca4004 100644 --- a/src/components-examples/material/select/select-form/select-form-example.ts +++ b/src/components-examples/material/select/select-form/select-form-example.ts @@ -15,7 +15,7 @@ interface Car { } /** - * @title Select in a form + * @title Select in a form (template-driven forms) */ @Component({ selector: 'select-form-example', From d20baa6ab8e61daa6894dd63f2565baf6ede0dd1 Mon Sep 17 00:00:00 2001 From: Michael Small Date: Wed, 30 Sep 2026 21:08:37 -0500 Subject: [PATCH 2/4] docs: add signal form example for "Form field features" --- .../material/select/index.ts | 1 + ...select-hint-error-signal-form-example.html | 32 ++++++++++++++++ .../select-hint-error-signal-form-example.ts | 37 +++++++++++++++++++ src/material/select/select.md | 4 +- 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.html create mode 100644 src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.ts diff --git a/src/components-examples/material/select/index.ts b/src/components-examples/material/select/index.ts index f9855ac5ca4a..98239a96c6d1 100644 --- a/src/components-examples/material/select/index.ts +++ b/src/components-examples/material/select/index.ts @@ -14,4 +14,5 @@ export {SelectValueBindingExample} from './select-value-binding/select-value-bin export {SelectReactiveFormExample} from './select-reactive-form/select-reactive-form-example'; export {SelectInitialValueExample} from './select-initial-value/select-initial-value-example'; export {SelectSelectableNullExample} from './select-selectable-null/select-selectable-null-example'; +export {SelectHintErrorSignalFormExample} from './select-hint-error-signal-form/select-hint-error-signal-form-example'; export {SelectHarnessExample} from './select-harness/select-harness-example'; diff --git a/src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.html b/src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.html new file mode 100644 index 000000000000..1cdd995d3eca --- /dev/null +++ b/src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.html @@ -0,0 +1,32 @@ +

mat select

+ + Favorite animal + + -- + @for (animal of animals; track animal) { + {{animal.name}} + } + + @if (animalControl().getError('required')) { + Please choose an animal + } + @if (animalSound(); as animalSound) { + {{animalSound}} + } + + +

native html select

+ + Select your car (required) + + @if (selectFormControl().getError('required')) { + This field is required + } + You can pick up your favorite car here + + diff --git a/src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.ts b/src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.ts new file mode 100644 index 000000000000..fa0955180deb --- /dev/null +++ b/src/components-examples/material/select/select-hint-error-signal-form/select-hint-error-signal-form-example.ts @@ -0,0 +1,37 @@ +import {Component, computed, signal} from '@angular/core'; +import {FormControl, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {MatInputModule} from '@angular/material/input'; +import {MatSelectModule} from '@angular/material/select'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {form, FormField, required} from '@angular/forms/signals'; + +interface Animal { + name: string; + sound: string; +} + +/** @title Select with form field features (signal forms) */ +@Component({ + selector: 'select-hint-error-signal-form-example', + templateUrl: 'select-hint-error-signal-form-example.html', + imports: [MatFormFieldModule, MatSelectModule, FormField, MatInputModule], +}) +export class SelectHintErrorSignalFormExample { + protected animalControl = form(signal(''), p => { + required(p); + }); + protected selectFormControl = form(signal(''), p => { + required(p); + }); + + protected animalSound = computed( + () => this.animals.find(a => a.name === this.animalControl().value())?.sound, + ); + + protected animals: Animal[] = [ + {name: 'Dog', sound: 'Woof!'}, + {name: 'Cat', sound: 'Meow!'}, + {name: 'Cow', sound: 'Moo!'}, + {name: 'Fox', sound: 'Wa-pa-pa-pa-pa-pa-pow!'}, + ]; +} diff --git a/src/material/select/select.md b/src/material/select/select.md index 27b591e1fc40..d9c39a5506ec 100644 --- a/src/material/select/select.md +++ b/src/material/select/select.md @@ -35,7 +35,7 @@ Including `FormField` (signal forms), `FormsModule` (`NgModel`) and `ReactiveFor `compareWith` function. (Additional information about using a custom `compareWith` function can be found in the [Angular forms documentation](https://angular.dev/api/forms/SelectControlValueAccessor#compareWith)). - + ### Form field features @@ -44,7 +44,7 @@ include error messages, hint text, prefix & suffix, and theming. For additional these features, see the [form field documentation](https://material.angular.dev/components/form-field/overview). - + ### Setting a static placeholder From 78397fcb23701ac6e2ec0161fc5cd6b7b6c390e1 Mon Sep 17 00:00:00 2001 From: Michael Small Date: Wed, 30 Sep 2026 21:50:01 -0500 Subject: [PATCH 3/4] docs: add signal form example for select disabling example --- .../material/select/index.ts | 1 + .../select-disabled-signal-form-example.html | 26 +++++++++++++++++++ .../select-disabled-signal-form-example.ts | 20 ++++++++++++++ src/material/select/select.md | 8 +++++- 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.html create mode 100644 src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.ts diff --git a/src/components-examples/material/select/index.ts b/src/components-examples/material/select/index.ts index 98239a96c6d1..61afb4de8fe3 100644 --- a/src/components-examples/material/select/index.ts +++ b/src/components-examples/material/select/index.ts @@ -1,5 +1,6 @@ export {SelectCustomTriggerExample} from './select-custom-trigger/select-custom-trigger-example'; export {SelectDisabledExample} from './select-disabled/select-disabled-example'; +export {SelectDisabledSignalFormExample} from './select-disabled-signal-form/select-disabled-signal-form-example'; export {SelectErrorStateMatcherExample} from './select-error-state-matcher/select-error-state-matcher-example'; export {SelectFormExample} from './select-form/select-form-example'; export {SelectFormSignalFormExample} from './select-form-signal-form/select-form-signal-form-example'; diff --git a/src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.html b/src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.html new file mode 100644 index 000000000000..a605f2d0eca4 --- /dev/null +++ b/src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.html @@ -0,0 +1,26 @@ +

+ Disable select +

+ +

mat-select

+ + Choose an option + + Option 1 + Option 2 (disabled) + Option 3 + + + +

native html select

+ + Choose an option + + + diff --git a/src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.ts b/src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.ts new file mode 100644 index 000000000000..595ebe764984 --- /dev/null +++ b/src/components-examples/material/select/select-disabled-signal-form/select-disabled-signal-form-example.ts @@ -0,0 +1,20 @@ +import {Component, signal} from '@angular/core'; +import {disabled, form, FormField} from '@angular/forms/signals'; +import {MatInputModule} from '@angular/material/input'; +import {MatSelectModule} from '@angular/material/select'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatCheckboxModule} from '@angular/material/checkbox'; + +/** @title Disabled select (signal forms) */ +@Component({ + selector: 'select-disabled-signal-form-example', + templateUrl: 'select-disabled-signal-form-example.html', + imports: [MatCheckboxModule, FormField, MatFormFieldModule, MatSelectModule, MatInputModule], +}) +export class SelectDisabledSignalFormExample { + // TODO - more distinct name? + protected form = form(signal({option: '', vehicle: '', disableField: false}), p => { + disabled(p.option, {when: ({valueOf}) => valueOf(p.disableField)}); + disabled(p.vehicle, {when: ({valueOf}) => valueOf(p.disableField)}); + }); +} diff --git a/src/material/select/select.md b/src/material/select/select.md index d9c39a5506ec..cd9bc78e73eb 100644 --- a/src/material/select/select.md +++ b/src/material/select/select.md @@ -58,11 +58,17 @@ In some cases that `` may use the placeholder as the label (see It is possible to disable the entire select or individual options in the select by using the disabled property on the `` or ``, and the disabled property should not be bound +to the selects in the template. However, individual `