Skip to content

Commit e129e3d

Browse files
mmalerbaandrewseguin
authored andcommitted
docs(input, select): update docs and create more examples (#7673)
* update input docs * input examples * select docs & examples * add troubleshooting section for select * address comments * address more comments
1 parent 3041124 commit e129e3d

File tree

51 files changed

+714
-218
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+714
-218
lines changed

guides/creating-a-custom-form-field-control.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class MyTelInput {
7070
```
7171

7272
### Providing our component as a MatFormFieldControl
73+
7374
The first step is to provide our new component as an implementation of the `MatFormFieldControl`
7475
interface that the `<mat-form-field>` knows how to work with. To do this, we will have our class
7576
implement `MatFormFieldControl`. Since this is a generic interface, we'll need to include a type
@@ -89,18 +90,19 @@ class MyTelInput implements MatFormFieldControl<MyTel> {
8990

9091
This sets up our component so it can work with `<mat-form-field>`, but now we need to implement the
9192
various methods and properties declared by the interface we just implemented. To learn more about
92-
the `MatFormFieldControl` interface, see its
93-
[definition](https://github.com/angular/material2/blob/master/src/lib/form-field/form-field-control.ts).
94-
(Unfortunately generated API docs are not available yet, but we'll go through the methods and
95-
properties in this guide.)
93+
the `MatFormFieldControl` interface, see the
94+
[form field API documentation](https://material.angular.io/components/form-field/api).
9695

9796
### Implementing the methods and properties of MatFormFieldControl
97+
9898
#### `value`
99+
99100
This property allows someone to set or get the value of our control. Its type should be the same
100101
type we used for the type parameter when we implemented `MatFormFieldControl`. Since our component
101102
already has a value property, we don't need to do anything for this one.
102103

103104
#### `stateChanges`
105+
104106
Because the `<mat-form-field>` uses the `OnPush` change detection strategy, we need to let it know
105107
when something happens in the form field control that may require the form field to run change
106108
detection. We do this via the `stateChanges` property. So far the only thing the form field needs to
@@ -122,6 +124,7 @@ ngOnDestroy() {
122124
```
123125

124126
#### `id`
127+
125128
This property should return the ID of an element in the component's template that we want the
126129
`<mat-form-field>` to associate all of its labels and hints with. In this case, we'll use the host
127130
element and just generate a unique ID for it.
@@ -133,6 +136,7 @@ static nextId = 0;
133136
```
134137

135138
#### `placeholder`
139+
136140
This property allows us to tell the `<mat-form-field>` what to use as a placeholder. In this
137141
example, we'll do the same thing as `matInput` and `<mat-select>` and allow the user to specify it
138142
via an `@Input()`. Since the value of the placeholder may change over time, we need to make sure to
@@ -152,6 +156,7 @@ private _placeholder: string;
152156
```
153157

154158
#### `ngControl`
159+
155160
This property allows the form field control to specify the `@angular/forms` control that is bound to
156161
this component. Since we haven't set up our component to act as a `ControlValueAccessor`, we'll just
157162
set this to `null` in our component. In any real component, you would probably want to implement
@@ -170,6 +175,7 @@ constructor(..., @Optional() @Self() public ngControl: NgControl) { ... }
170175
```
171176

172177
#### `focused`
178+
173179
This property indicates whether or not the form field control should be considered to be in a
174180
focused state. When it is in a focused state, the form field is displayed with a solid color
175181
underline. For the purposes of our component, we want to consider it focused if any of the part
@@ -195,6 +201,7 @@ ngOnDestroy() {
195201
```
196202

197203
#### `empty`
204+
198205
This property indicates whether the form field control is empty. For our control, we'll consider it
199206
empty if all of the parts are empty.
200207

@@ -206,6 +213,7 @@ get empty() {
206213
```
207214

208215
#### `shouldPlaceholderFloat`
216+
209217
This property is used to indicate whether the placeholder should be in the floating position. We'll
210218
use the same logic as `matInput` and float the placeholder when the input is focused or non-empty.
211219
Since the placeholder will be overlapping our control when when it's not floating, we should hide
@@ -228,6 +236,7 @@ span {
228236
```
229237

230238
#### `required`
239+
231240
This property is used to indicate whether the input is required. `<mat-form-field>` uses this
232241
information to add a required indicator to the placeholder. Again, we'll want to make sure we run
233242
change detection if the required state changes.
@@ -245,6 +254,7 @@ private _required = false;
245254
```
246255

247256
#### `disabled`
257+
248258
This property tells the form field when it should be in the disabled state. In addition to reporting
249259
the right state to the form field, we need to set the disabled state on the individual inputs that
250260
make up our component.
@@ -269,6 +279,7 @@ private _disabled = false;
269279
```
270280

271281
#### `errorState`
282+
272283
This property indicates whether the associated `NgControl` is in an error state. Since we're not
273284
using an `NgControl` in this example, we don't need to do anything other than just set it to `false`.
274285

@@ -277,6 +288,7 @@ errorState = false;
277288
```
278289

279290
#### `controlType`
291+
280292
This property allows us to specify a unique string for the type of control in form field. The
281293
`<mat-form-field>` will add an additional class based on this type that can be used to easily apply
282294
special styles to a `<mat-form-field>` that contains a specific type of control. In this example
@@ -288,6 +300,7 @@ controlType = 'my-tel-input';
288300
```
289301

290302
#### `setAriaDescribedByIds(ids: string[])`
303+
291304
This method is used by the `<mat-form-field>` to specify the IDs that should be used for the
292305
`aria-describedby` attribute of your component. The method has one parameter, the list of IDs, we
293306
just need to apply the given IDs to our host element.
@@ -301,6 +314,7 @@ setDescribedByIds(ids: string[]) {
301314
```
302315

303316
#### `onContainerClick(event: MouseEvent)`
317+
304318
This method will be called when the form field is clicked on. It allows your component to hook in
305319
and handle that click however it wants. The method has one parameter, the `MouseEvent` for the
306320
click. In our case we'll just focus the first `<input>` if the user isn't about to click an
@@ -315,6 +329,7 @@ onContainerClick(event: MouseEvent) {
315329
```
316330

317331
### Trying it out
332+
318333
Now that we've fully implemented the interface, we're ready to try our component out! All we need to
319334
do is place it inside of a `<mat-form-field>`
320335

src/lib/form-field/form-field.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ In this document, "form field" refers to the wrapper component `<mat-form-field>
77
(e.g. the input, textarea, select, etc.)
88

99
The following Angular Material components are designed to work inside a `<mat-form-field>`:
10-
* [&lt;input matInput&gt; &amp; &lt;textarea matInput&gt;](https://material.angular.io/components/input/overview)
11-
* [&lt;mat-select&gt;](https://material.angular.io/components/select/overview)
12-
* [&lt;mat-chip-list&gt;](https://material.angular.io/components/chips/overview)
10+
* [`<input matInput>` &amp; `<textarea matInput>`](https://material.angular.io/components/input/overview)
11+
* [`<mat-select>`](https://material.angular.io/components/select/overview)
12+
* [`<mat-chip-list>`](https://material.angular.io/components/chips/overview)
1313

1414
<!-- example(form-field-overview) -->
1515

1616
### Floating placeholder
17+
1718
The floating placeholder is a text label displayed on top of the form field control when
1819
the control does not contain any text. By default, when text is present the floating placeholder
1920
floats above the form field control.
@@ -46,6 +47,7 @@ setting can be either `always`, `never`, or `auto`.
4647
```
4748

4849
### Hint labels
50+
4951
Hint labels are additional descriptive text that appears below the form field's underline. A
5052
`<mat-form-field>` can have up to two hint labels; one start-aligned (left in an LTR language, right
5153
in RTL), and one end-aligned.
@@ -60,6 +62,7 @@ raise an error.
6062
<!-- example(form-field-hint) -->
6163

6264
### Error messages
65+
6366
Error messages can be shown under the form field underline by adding `mat-error` elements inside the
6467
form field. Errors are hidden initially and will be displayed on invalid form fields after the user
6568
has interacted with the element or the parent form has been submitted. Since the errors occupy the
@@ -74,6 +77,7 @@ multiple errors is up to the user.
7477
<!-- example(form-field-error) -->
7578

7679
### Prefix & suffix
80+
7781
Custom content can be included before and after the input tag, as a prefix or suffix. It will be
7882
included within the visual container that wraps the form control as per the Material specification.
7983

@@ -83,12 +87,14 @@ the prefix. Similarly, adding `matSuffix` will designate it as the suffix.
8387
<!-- example(form-field-prefix-suffix) -->
8488

8589
### Custom form field controls
90+
8691
In addition to the form field controls that Angular Material provides, it is possible to create
8792
custom form field controls that work with `<mat-form-field>` in the same way. For additional
8893
information on this see the guide on
8994
[Creating Custom mat-form-field Controls](https://material.angular.io/guide/creating-a-custom-form-field-control).
9095

9196
### Theming
97+
9298
`<mat-form-field>` has a `color` property which can be set to `primary`, `accent`, or `warn`. This
9399
will set the color of the form field underline and floating placeholder based on the theme colors
94100
of your app.
@@ -105,24 +111,29 @@ mat-form-field.mat-form-field {
105111
<!-- example(form-field-theming) -->
106112

107113
### Accessibility
108-
If a floating placeholder is specified, it will be automatically used as the label for the form field
109-
control. If no floating placeholder is specified, the user should label the form field control
114+
115+
If a floating placeholder is specified, it will be automatically used as the label for the form
116+
field control. If no floating placeholder is specified, the user should label the form field control
110117
themselves using `aria-label`, `aria-labelledby` or `<label for=...>`.
111118

112119
Any errors and hints added to the form field are automatically added to the form field control's
113120
`aria-describedby` set.
114121

115122
### Troubleshooting
123+
116124
#### Error: Placeholder attribute and child element were both specified
125+
117126
This error occurs when you have specified two conflicting placeholders. Make sure that you haven't
118127
included both a `placeholder` property on your form field control and a `<mat-placeholder>`
119128
element.
120129

121130
#### Error: A hint was already declared for align="..."
131+
122132
This error occurs if you have added multiple hints for the same side. Keep in mind that the
123133
`hintLabel` property adds a hint to the start side.
124134

125135
#### Error: mat-form-field must contain a MatFormFieldControl
136+
126137
This error occurs when you have not added a form field control to your form field. If your form
127138
field contains a native `<input>` or `<textarea>` element, make sure you've added the `matInput`
128139
directive to it. Other components that can act as a form field control include `<mat-select>`,

0 commit comments

Comments
 (0)