iwe7 / iwe7-ui Goto Github PK
View Code? Open in Web Editor NEWangular组件搜集汇总
angular组件搜集汇总
mat-grid-list
is a two-dimensional list view that arranges cells into grid-based layout.
See Material Design spec here.
An mat-grid-list
must specify a cols
attribute which sets the number of columns in the grid. The
number of rows will be automatically determined based on the number of columns and the number of
items.
The height of the rows in a grid list can be set via the rowHeight
attribute. Row height for the
list can be calculated in three ways:
Fixed height: The height can be in px
, em
, or rem
. If no units are specified, px
units are assumed (e.g. 100px
, 5em
, 250
).
Ratio: This ratio is column-width:row-height, and must be passed in with a colon, not a
decimal (e.g. 4:3
).
Fit: Setting rowHeight
to fit
This mode automatically divides the available height by
the number of rows. Please note the height of the grid-list or its container must be set.
If rowHeight
is not specified, it defaults to a 1:1
ratio of width:height.
The gutter size can be set to any px
, em
, or rem
value with the gutterSize
property. If no
units are specified, px
units are assumed. By default the gutter size is 1px
.
It is possible to set the rowspan and colspan of each mat-grid-tile
individually, using the
rowspan
and colspan
properties. If not set, they both default to 1
. The colspan
must not
exceed the number of cols
in the mat-grid-list
. There is no such restriction on the rowspan
however, more rows will simply be added for it the tile to fill.
A header and footer can be added to an mat-grid-tile
using the mat-grid-tile-header
and
mat-grid-tile-footer
elements respectively.
By default, the grid-list assumes that it will be used in a purely decorative fashion and thus sets
no roles, ARIA attributes, or keyboard shortcuts. This is equivalent to having a sequence of <div>
elements on the page. Any interactive content within the grid-list should be given an appropriate
accessibility treatment based on the specific workflow of your application.
If the grid-list is used to present a list of non-interactive content items, then the grid-list
element should be given role="list"
and each tile should be given role="listitem"
.
Angular Material tabs organize content into separate views where only one view can be
visible at a time. Each tab's label is shown in the tab header and the active
tab's label is designated with the animated ink bar. When the list of tab labels exceeds the width
of the header, pagination controls appear to let the user scroll left and right across the labels.
The active tab may be set using the selectedIndex
input or when the user selects one of the
tab labels in the header.
The selectedTabChange
output event is emitted when the active tab changes.
The focusChange
output event is emitted when the user puts focus on any of the tab labels in
the header, usually through keyboard navigation.
If a tab's label is only text then the simple tab-group API can be used.
<mat-tab-group>
<mat-tab label="One">
<h1>Some tab content</h1>
<p>...</p>
</mat-tab>
<mat-tab label="Two">
<h1>Some more tab content</h1>
<p>...</p>
</mat-tab>
</mat-tab-group>
For more complex labels, add a template with the mat-tab-label
directive inside the mat-tab
.
<mat-tab-group>
<mat-tab>
<ng-template mat-tab-label>
The <em>best</em> pasta
</ng-template>
<h1>Best pasta restaurants</h1>
<p>...</p>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>thumb_down</mat-icon> The worst sushi
</ng-template>
<h1>Terrible sushi restaurants</h1>
<p>...</p>
</mat-tab>
</mat-tab-group>
By default, the tab group will not change its height to the height of the currently active tab. To
change this, set the dynamicHeight
input to true. The tab body will animate its height according
to the height of the active tab.
While <mat-tab-group>
is used to switch between views within a single route, <nav mat-tab-nav-bar>
provides a tab-like UI for navigating between routes.
<nav mat-tab-nav-bar>
<a mat-tab-link
*ngFor="let link of navLinks"
[routerLink]="link.path"
routerLinkActive #rla="routerLinkActive"
[active]="rla.isActive">
{{link.label}}
</a>
</nav>
<router-outlet></router-outlet>
The tab-nav-bar
is not tied to any particular router; it works with normal <a>
elements and uses
the active
property to determine which tab is currently active. The corresponding
<router-outlet>
can be placed anywhere in the view.
By default, the tab contents are eagerly loaded. Eagerly loaded tabs
will initalize the child components but not inject them into the DOM
until the tab is activated.
If the tab contains several complex child components or the tab's contents
rely on DOM calculations during initialization, it is advised
to lazy load the tab's content.
Tab contents can be lazy loaded by declaring the body in a ng-template
with the matTabContent
attribute.
<mat-tab-group>
<mat-tab label="First">
<ng-template matTabContent>
The First Content
</ng-template>
</mat-tab>
<mat-tab label="Second">
<ng-template matTabContent>
The Second Content
</ng-template>
</mat-tab>
</mat-tab-group>
Tabs without text or labels should be given a meaningful label via aria-label
or
aria-labelledby
. For MatTabNav
, the <nav>
element should have a label as well.
Shortcut | Action |
---|---|
LEFT_ARROW |
Move focus to previous tab |
RIGHT_ARROW |
Move focus to next tab |
HOME |
Move focus to first tab |
END |
Move focus to last tab |
SPACE or ENTER |
Switch to focused tab |
The MatBottomSheet
service can be used to open Material Design panels to the bottom of the screen.
These panels are intended primarily as an interaction on mobile devices where they can be used as an
alternative to dialogs and menus.
You can open a bottom sheet by calling the open
method with a component to be loaded and an
optional config object. The open
method will return an instance of MatBottomSheetRef
:
const bottomSheetRef = bottomSheet.open(SocialShareComponent, {
ariaLabel: 'Share on social media'
});
The MatBottomSheetRef
is a reference to the currently-opened bottom sheet and can be used to close
it or to subscribe to events. Note that only one bottom sheet can be open at a time. Any component
contained inside of a bottom sheet can inject the MatBottomSheetRef
as well.
bottomSheetRef.afterDismissed().subscribe(() => {
console.log('Bottom sheet has been dismissed.');
});
bottomSheetRef.dismiss();
If you want to pass in some data to the bottom sheet, you can do so using the data
property:
const bottomSheetRef = bottomSheet.open(HobbitSheet, {
data: { names: ['Frodo', 'Bilbo'] },
});
Afterwards you can access the injected data using the MAT_BOTTOM_SHEET_DATA
injection token:
import {Component, Inject} from '@angular/core';
import {MAT_BOTTOM_SHEET_DATA} from '@angular/material';
@Component({
selector: 'hobbit-sheet',
template: 'passed in {{ data.names }}',
})
export class HobbitSheet {
constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public data: any) { }
}
entryComponents
Similarly to MatDialog
, MatBottomSheet
instantiates components at run-time. In order for it to
work, the Angular compiler needs extra information to create the necessary ComponentFactory
for
your bottom sheet content component.
Any components that are include inside of a bottom sheet have to be added to the entryComponents
inside your NgModule
.
@NgModule({
imports: [
// ...
MatBottomSheetModule
],
declarations: [
AppComponent,
ExampleBottomSheetComponent
],
entryComponents: [
ExampleBottomSheetComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
By default, the bottom sheet has role="dialog"
on the root element and can be labelled using the
ariaLabel
property on the MatBottomSheetConfig
.
When a bottom sheet is opened, it will move focus to the first focusable element that it can find.
In order to prevent users from tabbing into elements in the background, the Material bottom sheet
uses a focus trap to contain focus
within itself. Once a bottom sheet is closed, it will return focus to the element that was focused
before it was opened.
By default, the first tabbable element within the bottom sheet will receive focus upon open.
This can be configured by setting the cdkFocusInitial
attribute on another focusable element.
By default pressing the escape key will close the bottom sheet. While this behavior can
be turned off via the disableClose
option, users should generally avoid doing so
as it breaks the expected interaction pattern for screen-reader users.
inputs | 说明 | 取值 |
---|---|---|
flex | display | "flex","inline-flex" |
direction | flex-direction | "row","row-reverse","column","column-reverse" |
wrap | flex-wrap | "nowrap", "wrap", "wrap-reverse" |
justify | justify-content | "flex-start","flex-end","center","space-between","space-around" |
align | align-items | "flex-start","flex-end","center", "baseline","stretch" |
alignContent | align-content | "flex-start","flex-end","center","space-between","space-around","stretch" |
inputs | 说明 | 取值 |
---|---|---|
order | order | number |
grow | flex-grow | number |
shrink | flex-shrink | number |
basis | flex-basis | string |
self | align-self | "auto", "flex-start", "flex-end","center","baseline","stretch" |
<mat-list>
is a container component that wraps and formats a series of line items. As the base
list component, it provides Material Design styling, but no behavior of its own.
An <mat-list>
element contains a number of <mat-list-item>
elements.
<mat-list>
<mat-list-item> Pepper </mat-list-item>
<mat-list-item> Salt </mat-list-item>
<mat-list-item> Paprika </mat-list-item>
</mat-list>
Use mat-nav-list
tags for navigation lists (i.e. lists that have anchor tags).
Simple navigation lists can use the mat-list-item
attribute on anchor tag elements directly:
<mat-nav-list>
<a mat-list-item href="..." *ngFor="let link of links"> {{ link }} </a>
</mat-nav-list>
For more complex navigation lists (e.g. with more than one target per item), wrap the anchor
element in an <mat-list-item>
.
<mat-nav-list>
<mat-list-item *ngFor="let link of links">
<a matLine href="...">{{ link }}</a>
<button mat-icon-button (click)="showInfo(link)">
<mat-icon>info</mat-icon>
</button>
</mat-list-item>
</mat-nav-list>
A selection list provides an interface for selecting values, where each list item is an option.
The options within a selection-list should not contain further interactive controls, such
as buttons and anchors.
For lists that require multiple lines per item, annotate each line with an matLine
attribute.
Whichever heading tag is appropriate for your DOM hierarchy should be used (not necessarily <h3>
as shown in the example).
<!-- two line list -->
<mat-list>
<mat-list-item *ngFor="let message of messages">
<h3 matLine> {{message.from}} </h3>
<p matLine>
<span> {{message.subject}} </span>
<span class="demo-2"> -- {{message.content}} </span>
</p>
</mat-list-item>
</mat-list>
<!-- three line list -->
<mat-list>
<mat-list-item *ngFor="let message of messages">
<h3 matLine> {{message.from}} </h3>
<p matLine> {{message.subject}} </p>
<p matLine class="demo-2"> {{message.content}} </p>
</mat-list-item>
</mat-list>
To add an icon to your list item, use the matListIcon
attribute.
<mat-list>
<mat-list-item *ngFor="let message of messages">
<mat-icon matListIcon>folder</mat-icon>
<h3 matLine> {{message.from}} </h3>
<p matLine>
<span> {{message.subject}} </span>
<span class="demo-2"> -- {{message.content}} </span>
</p>
</mat-list-item>
</mat-list>
To include an avatar image, add an image tag with an matListAvatar
attribute.
<mat-list>
<mat-list-item *ngFor="let message of messages">
<img matListAvatar src="..." alt="...">
<h3 matLine> {{message.from}} </h3>
<p matLine>
<span> {{message.subject}} </span>
<span class="demo-2"> -- {{message.content}} </span>
</p>
</mat-list-item>
</mat-list>
Lists are also available in "dense layout" mode, which shrinks the font size and height of the list
to suit UIs that may need to display more information. To enable this mode, add a dense
attribute
to the main mat-list
tag.
<mat-list dense>
<mat-list-item> Pepper </mat-list-item>
<mat-list-item> Salt </mat-list-item>
<mat-list-item> Paprika </mat-list-item>
</mat-list>
Subheader can be added to a list by annotating a heading tag with an matSubheader
attribute.
To add a divider, use <mat-divider>
.
<mat-list>
<h3 matSubheader>Folders</h3>
<mat-list-item *ngFor="let folder of folders">
<mat-icon matListIcon>folder</mat-icon>
<h4 matLine>{{folder.name}}</h4>
<p matLine class="demo-2"> {{folder.updated}} </p>
</mat-list-item>
<mat-divider></mat-divider>
<h3 matSubheader>Notes</h3>
<mat-list-item *ngFor="let note of notes">
<mat-icon matListIcon>note</mat-icon>
<h4 matLine>{{note.name}}</h4>
<p matLine class="demo-2"> {{note.updated}} </p>
</mat-list-item>
</mat-list>
The type of list used in any given situation depends on how the end-user will be interacting with
the it.
When the list-items navigate somewhere, <mat-nav-list>
should be used with <a mat-list-item>
elements as the list items. The nav-list will be rendered using role="navigation"
and can be
given an aria-label
to give context on the set of navigation options presented. Additional
interactive content, such as buttons, should not be added inside the anchors.
When the list is primarily used to select one or more values, a <mat-selection-list>
should be
used with <mat-list-option>
, which map to role="listbox"
and role="option"
, respectively. The
list should be given an aria-label
that describes the value or values being selected. Each option
should not contain any additional interactive elements, such as buttons.
By default, the list assumes that it will be used in a purely decorative fashion and thus sets no
roles, ARIA attributes, or keyboard shortcuts. This is equivalent to having a sequence of <div>
elements on the page. Any interactive content within the list should be given an appropriate
accessibility treatment based on the specific workflow of your application.
If the list is used to present a list of non-interactive content items, then the list element should
be given role="list"
and each list item should be given role="listitem"
.
The a11y
package provides a number of tools to improve accessibility, described below.
ListKeyManager
manages the active option in a list of items based on keyboard interaction.
Intended to be used with components that correspond to a role="menu"
or role="listbox"
pattern.
Any component that uses a ListKeyManager
will generally do three things:
@ViewChildren
query for the options being managed.ListKeyManager
, passing in the options.ListKeyManager
.Each option should implement the ListKeyManagerOption
interface:
interface ListKeyManagerOption {
disabled?: boolean;
getLabel?(): string;
}
Navigation through options can be made to wrap via the withWrap
method
this.keyManager = new FocusKeyManager(...).withWrap();
There are two varieties of ListKeyManager
, FocusKeyManager
and ActiveDescendantKeyManager
.
Used when options will directly receive browser focus. Each item managed must implement the
FocusableOption
interface:
interface FocusableOption extends ListKeyManagerOption {
focus(): void;
}
Used when options will be marked as active via aria-activedescendant
.
Each item managed must implement the
Highlightable
interface:
interface Highlightable extends ListKeyManagerOption {
setActiveStyles(): void;
setInactiveStyles(): void;
}
Each item must also have an ID bound to the listbox's or menu's aria-activedescendant
.
The cdkTrapFocus
directive traps Tab key focus within an element. This is intended to
be used to create accessible experience for components like
modal dialogs, where focus must be
constrained.
This directive is declared in A11yModule
.
<div class="my-inner-dialog-content" cdkTrapFocus>
<!-- Tab and Shift + Tab will not leave this element. -->
</div>
This directive will not prevent focus from moving out of the trapped region due to mouse
interaction.
Regions can be declared explicitly with an initial focus element by using
the cdkFocusRegionStart
, cdkFocusRegionEnd
and cdkFocusInitial
DOM attributes.
cdkFocusInitial
specifies the element that will receive focus upon initialization of the region.
cdkFocusRegionStart
and cdkFocusRegionEnd
define the region within which focus will be
trapped. When using the tab key, focus will move through this region and wrap around on either end.
For example:
<a mat-list-item routerLink cdkFocusRegionStart>Focus region start</a>
<a mat-list-item routerLink>Link</a>
<a mat-list-item routerLink cdkFocusInitial>Initially focused</a>
<a mat-list-item routerLink cdkFocusRegionEnd>Focus region end</a>
InteractivityChecker
is used to check the interactivity of an element, capturing disabled,
visible, tabbable, and focusable states for accessibility purposes. See the API docs for more
details.
LiveAnnouncer
is used to announce messages for screen-reader users using an aria-live
region.
See the W3C's WAI-ARIA
for more information on aria-live regions.
@Component({...})
export class MyComponent {
constructor(liveAnnouncer: LiveAnnouncer) {
liveAnnouncer.announce("Hey Google");
}
}
The FocusMonitor
is an injectable service that can be used to listen for changes in the focus
state of an element. It's more powerful than just listening for focus
or blur
events because it
tells you how the element was focused (via mouse, keyboard, touch, or programmatically). It also
allows listening for focus on descendant elements if desired.
To listen for focus changes on an element, use the monitor
method which takes an element to
monitor and an optional boolean flag checkChildren
. Passing true for checkChildren
will tell the
FocusMonitor
to consider the element focused if any of its descendants are focused. This option
defaults to false
if not specified. The monitor
method will return an Observable that emits the
FocusOrigin
whenever the focus state changes. The FocusOrigin
will be one of the following:
'mouse'
indicates the element was focused with the mouse'keyboard'
indicates the element was focused with the keyboard'touch'
indicates the element was focused by touching on a touchscreen'program'
indicates the element was focused programmaticallynull
indicates the element was blurredIn addition to emitting on the observable, the FocusMonitor
will automatically apply CSS classes
to the element when focused. It will add .cdk-focused
if the element is focused and will further
add .cdk-${origin}-focused
(with ${origin}
being mouse
, keyboard
, touch
, or program
) to
indicate how the element was focused.
Note: currently the FocusMonitor
emits on the observable outside of the Angular zone. Therefore
if you markForCheck
in the subscription you must put yourself back in the Angular zone.
focusMonitor.monitor(el).subscribe(origin => this.ngZone.run(() => /* ... */ ));
Any element that is monitored by calling monitor
should eventually be unmonitored by calling
stopMonitoring
with the same element.
It is possible to falsify the FocusOrigin
when setting the focus programmatically by using the
focusVia
method of FocusMonitor
. This method accepts an element to focus and the FocusOrigin
to use. If the element being focused is currently being monitored by the FocusMonitor
it will
report the FocusOrigin
that was passed in. If the element is not currently being monitored it will
just be focused like normal.
For convenience, the CDK also provides two directives that allow for easily monitoring an element.
cdkMonitorElementFocus
is the equivalent of calling monitor
on the host element with
checkChildren
set to false
. cdkMonitorSubtreeFocus
is the equivalent of calling monitor
on
the host element with checkChildren
set to true
. Each of these directives has an @Output()
cdkFocusChange
that will emit the new FocusOrigin
whenever it changes.
The <cdk-tree>
enables developers to build a customized tree experience for structured data. The
<cdk-tree>
provides a foundation to build other features such as filtering on top of tree.
For a Material Design styled tree, see <mat-tree>
which builds on top of the <cdk-tree>
.
There are two types of trees: flat tree and nested Tree. The DOM structures are different for
these two types of trees.
In a flat tree, the hierarchy is flattened; nodes are not rendered inside of each other, but instead
are rendered as siblings in sequence. An instance of TreeFlattener
is used to generate the flat
list of items from hierarchical data. The "level" of each tree node is read through the getLevel
method of the TreeControl
; this level can be used to style the node such that it is indented to
the appropriate level.
<cdk-tree>
<cdk-tree-node> parent node </cdk-tree-node>
<cdk-tree-node> -- child node1 </cdk-tree-node>
<cdk-tree-node> -- child node2 </cdk-tree-node>
</cdk-tree>
Flat trees are generally easier to style and inspect. They are also more friendly to scrolling
variations, such as infinite or virtual scrolling.
In nested tree, children nodes are placed inside their parent node in DOM. The parent node contains
a node outlet into which children are projected.
<cdk-tree>
<cdk-nested-tree-node>
parent node
<cdk-nested-tree-node> -- child node1 </cdk-nested-tree-node>
<cdk-nested-tree-node> -- child node2 </cdk-nested-tree-node>
</cdk-nested-tree-node>
</cdk-tree>
Nested trees are easier to work with when hierarchical relationships are visually represented in
ways that would be difficult to accomplish with flat nodes.
The only thing you need to define is the tree node template. There are two types of tree nodes,
<cdk-tree-node>
for flat tree and <cdk-tree-nested-node> for nested tree
. The tree node
template defines the look of the tree node, expansion/collapsing control and the structure for
nested children nodes.
A node definition is specified via any element with cdkNodeDef
. This directive exports the node
data to be used in any bindings in the node template.
<cdk-tree-node *cdkNodeDef=“let node”>
{{node.key}}: {{node.value}}
</cdk-tree-node>
Flat tree uses each node's level
to render the hierarchy of the nodes.
The "indent" for a given node is accomplished by adding spacing to each node based on its level.
Spacing can be added either by applying the cdkNodePadding
directive or by applying custom styles.
When using nested tree nodes, the node template must contain a cdkTreeNodeOutlet
, which marks
where the children of the node will be rendered.
<cdk-nested-tree-node *cdkNodeDef=“let node”>
{{node.value}}
<ng-container cdkTreeNodeOutlet></ng-container>
</cdk-nested-tree-node>
A cdkTreeNodeToggle
can be added in the tree node template to expand/collapse the tree node.
The toggle toggles the expand/collapse functions in TreeControl and is able to expand/collapse
a tree node recursively by setting [cdkTreeNodeToggleRecursive]
to true.
<cdk-tree-node *cdkNodeDef=“let node” cdkTreeNodeToggle [cdkTreeNodeToggleRecursive]="true">
{{node.value}}
</cdk-tree-node>
The toggle can be placed anywhere in the tree node, and is only toggled by click action.
For best accessibility, cdkTreeNodeToggle
should be on a button element and have an appropriate
aria-label
.
<cdk-tree-node *cdkNodeDef=“let node”>
<button cdkTreeNodeToggle aria-label="toggle tree node" [cdkTreeNodeToggleRecursive]="true">
<mat-icon>expand</mat-icon>
</button>
{{node.value}}
</cdk-tree-node>
The cdkTreeNodePadding can be placed in a flat tree's node template to display the level
information of a flat tree node.
<cdk-tree-node *cdkNodeDef=“let node” cdkNodePadding>
{{node.value}}
</cdk-tree-node>
Nested tree does not need this padding since padding can be easily added to the hierarchy structure
in DOM.
The tree may include multiple node templates, where a template is chosen
for a particular data node via the when
predicate of the template.
<cdk-tree-node *cdkNodeDef=“let node” cdkTreeNodePadding>
{{node.value}}
</cdk-tree-node>
<cdk-tree-node *cdkNodeDef=“let node; when: isSpecial” cdkTreeNodePadding>
[ A special node {{node.value}} ]
</cdk-tree-node>
Similar to cdk-table
, data is provided to the tree through a DataSource
. When the tree receives
a DataSource
it will call its connect()
method which returns an observable that emits an array
of data. Whenever the data source emits data to this stream, the tree will render an update.
Because the data source provides this stream, it bears the responsibility of toggling tree
updates. This can be based on anything: tree node expansion change, websocket connections, user
interaction, model updates, time-based intervals, etc.
The flat tree data source is responsible for the node expansion/collapsing events, since when
the expansion status changes, the data nodes feed to the tree are changed. A new list of visible
nodes should be sent to tree component based on current expansion status.
The data source for nested tree has an option to leave the node expansion/collapsing event for each
tree node component to handle.
trackBy
To improve performance, a trackBy
function can be provided to the tree similar to Angular’s
ngFor
trackBy
. This informs the
tree how to uniquely identify nodes to track how the data changes with each update.
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl" [trackBy]="trackByFn">
Angular Material's stepper provides a wizard-like workflow by dividing content into logical steps.
Material stepper builds on the foundation of the CDK stepper that is responsible for the logic
that drives a stepped workflow. Material stepper extends the CDK stepper and has Material Design
styling.
There are two stepper components: mat-horizontal-stepper
and mat-vertical-stepper
. They
can be used the same way. The only difference is the orientation of stepper.
mat-horizontal-stepper
selector can be used to create a horizontal stepper, and
mat-vertical-stepper
can be used to create a vertical stepper. mat-step
components need to be
placed inside either one of the two stepper components.
If a step's label is only text, then the label
attribute can be used.
<mat-vertical-stepper>
<mat-step label="Step 1">
Content 1
</mat-step>
<mat-step label="Step 1">
Content 2
</mat-step>
</mat-vertical-stepper>
For more complex labels, add a template with the matStepLabel
directive inside the
mat-step
.
<mat-vertical-stepper>
<mat-step>
<ng-template matStepLabel>...</ng-template>
...
</mat-step>
</mat-vertical-stepper>
There are two button directives to support navigation between different steps:
matStepperPrevious
and matStepperNext
.
<mat-horizontal-stepper>
<mat-step>
...
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
</mat-horizontal-stepper>
The linear
attribute can be set on mat-horizontal-stepper
and mat-vertical-stepper
to create
a linear stepper that requires the user to complete previous steps before proceeding to following
steps. For each mat-step
, the stepControl
attribute can be set to the top level
AbstractControl
that is used to check the validity of the step.
There are two possible approaches. One is using a single form for stepper, and the other is
using a different form for each step.
Alternatively, if you don't want to use the Angular forms, you can pass in the completed
property
to each of the steps which won't allow the user to continue until it becomes true
. Note that if
both completed
and stepControl
are set, the stepControl
will take precedence.
When using a single form for the stepper, matStepperPrevious
and matStepperNext
have to be
set to type="button"
in order to prevent submission of the form before all steps
are completed.
<form [formGroup]="formGroup">
<mat-horizontal-stepper formArrayName="formArray" linear>
<mat-step formGroupName="0" [stepControl]="formArray.get([0])">
...
<div>
<button mat-button matStepperNext type="button">Next</button>
</div>
</mat-step>
<mat-step formGroupName="1" [stepControl]="formArray.get([1])">
...
<div>
<button mat-button matStepperPrevious type="button">Back</button>
<button mat-button matStepperNext type="button">Next</button>
</div>
</mat-step>
...
</mat-horizontal-stepper>
</form>
<mat-vertical-stepper linear>
<mat-step [stepControl]="formGroup1">
<form [formGroup]="formGroup1">
...
</form>
</mat-step>
<mat-step [stepControl]="formGroup2">
<form [formGroup]="formGroup2">
...
</form>
</mat-step>
</mat-vertical-stepper>
If completion of a step in linear stepper is not required, then the optional
attribute can be set
on mat-step
.
By default, steps are editable, which means users can return to previously completed steps and
edit their responses. editable="true"
can be set on mat-step
to change the default.
By default, the completed
attribute of a step returns true
if the step is valid (in case of
linear stepper) and the user has interacted with the step. The user, however, can also override
this default completed
behavior by setting the completed
attribute as needed.
By default, the step headers will use the create
and done
icons from the Material design icon
set via <mat-icon>
elements. If you want to provide a different set of icons, you can do so
by placing a matStepperIcon
for each of the icons that you want to override. The index
,
active
, and optional
values of the individual steps are available through template variables:
<mat-vertical-stepper>
<ng-template matStepperIcon="edit">
<mat-icon>insert_drive_file</mat-icon>
</ng-template>
<ng-template matStepperIcon="done">
<mat-icon>done_all</mat-icon>
</ng-template>
<!-- Custom icon with a context variable. -->
<ng-template matStepperIcon="number" let-index="index">
{{index + 10}}
</ng-template>
<!-- Stepper steps go here -->
</mat-vertical-stepper>
Note that you aren't limited to using the mat-icon
component when providing custom icons.
Labels used by the stepper are provided through MatStepperIntl
. Localization of these messages
can be done by providing a subclass with translated values in your application root module.
@NgModule({
imports: [MatStepperModule],
providers: [
{provide: MatStepperIntl, useClass: MyIntl},
],
})
export class MyApp {}
The stepper is treated as a tabbed view for accessibility purposes, so it is given
role="tablist"
by default. The header of step that can be clicked to select the step
is given role="tab"
, and the content that can be expanded upon selection is given
role="tabpanel"
. aria-selected
attribute of step header and aria-expanded
attribute of
step content is automatically set based on step selection change.
The stepper and each step should be given a meaningful label via aria-label
or aria-labelledby
.
The portals
package provides a flexible system for rendering dynamic content into an application.
A Portal
is a piece of UI that can be dynamically rendered to an open slot on the page.
The "piece of UI" can be either a Component
or a TemplateRef
and the "open slot" is
a PortalOutlet
.
Portals and PortalOutlets are low-level building blocks that other concepts, such as overlays, are
built upon.
Portal<T>
Method | Description |
---|---|
attach(PortalOutlet): Promise<T> |
Attaches the portal to a host. |
detach(): Promise<void> |
Detaches the portal from its host. |
isAttached: boolean |
Whether the portal is attached. |
PortalOutlet
Method | Description |
---|---|
attach(Portal): Promise<void> |
Attaches a portal to the host. |
detach(): Promise<void> |
Detaches the portal from the host. |
dispose(): Promise<void> |
Permanently dispose the host. |
hasAttached: boolean |
Whether a portal is attached to the host. |
CdkPortal
Used to get a portal from an <ng-template>
. CdkPortal
is a Portal
.
Usage:
<ng-template cdkPortal>
<p>The content of this template is captured by the portal.</p>
</ng-template>
<!-- OR -->
<!-- This result here is identical to the syntax above -->
<p *cdkPortal>
The content of this template is captured by the portal.
</p>
A component can use @ViewChild
or @ViewChildren
to get a reference to a
CdkPortal
.
ComponentPortal
Used to create a portal from a component type. When a component is dynamically created using
portals, it must be included in the entryComponents
of its NgModule
.
Usage:
this.userSettingsPortal = new ComponentPortal(UserSettingsComponent);
CdkPortalOutlet
Used to add a portal outlet to a template. CdkPortalOutlet
is a PortalOutlet
.
Usage:
<!-- Attaches the `userSettingsPortal` from the previous example. -->
<ng-template [cdkPortalOutlet]="userSettingsPortal"></ng-template>
The mat-tree
provides a Material Design styled tree that can be used to display hierarchy
data.
This tree builds on the foundation of the CDK tree and uses a similar interface for its
data source input and template, except that its element and attribute selectors will be prefixed
with mat-
instead of cdk-
.
There are two types of trees: Flat tree and nested tree. The DOM structures are different for these
two types of trees.
In a flat tree, the hierarchy is flattened; nodes are not rendered inside of each other,
but instead are rendered as siblings in sequence. An instance of TreeFlattener
is
used to generate the flat list of items from hierarchical data. The "level" of each tree
node is read through the getLevel
method of the TreeControl
; this level can be
used to style the node such that it is indented to the appropriate level.
<mat-tree>
<mat-tree-node> parent node </mat-tree-node>
<mat-tree-node> -- child node1 </mat-tree-node>
<mat-tree-node> -- child node2 </mat-tree-node>
</mat-tree>
Flat trees are generally easier to style and inspect. They are also more friendly to
scrolling variations, such as infinite or virtual scrolling
In Nested tree, children nodes are placed inside their parent node in DOM. The parent node has an
outlet to keep all the children nodes.
<mat-tree>
<mat-nested-tree-node>
parent node
<mat-nested-tree-node> -- child node1 </mat-nested-tree-node>
<mat-nested-tree-node> -- child node2 </mat-nested-tree-node>
</mat-nested-tree-node>
</mat-tree>
Nested trees are easier to work with when hierarchical relationships are visually
represented in ways that would be difficult to accomplish with flat nodes.
The <mat-tree>
itself only deals with the rendering of a tree structure.
Additional features can be built on top of the tree by adding behavior inside node templates
(e.g., padding and toggle). Interactions that affect the
rendered data (such as expand/collapse) should be propagated through the table's data source.
The TreeControl
controls the expand/collapse state of tree nodes. Users can expand/collapse a tree
node recursively through tree control. For nested tree node, getChildren
function need to pass to
the NestedTreeControl
to make it work recursively. For flattened tree node, getLevel
and
isExpandable
functions need to pass to the FlatTreeControl
to make it work recursively.
A matTreeNodeToggle
can be added in the tree node template to expand/collapse the tree node. The
toggle toggles the expand/collapse functions in TreeControl
and is able to expand/collapse a
tree node recursively by setting [matTreeNodeToggleRecursive]
to true
.
The toggle can be placed anywhere in the tree node, and is only toggled by click
action.
The matTreeNodePadding
can be placed in a flat tree's node template to display the level
information of a flat tree node.
Nested tree does not need this padding since padding can be easily added to the hierarchy
structure in DOM.
Trees without text or labels should be given a meaningful label via aria-label
or
aria-labelledby
. The aria-readonly
defaults to true
if it's not set.
Tree's role is tree
.
Parent nodes are given role="group"
, while leaf nodes are given role="treeitem"
mat-tree
does not manage any focus/keyboard interaction on its own. Users can add desired
focus/keyboard interactions in their application.
<mat-expansion-panel>
provides an expandable details-summary view.
Each expansion-panel must include a header and may optionally include an action bar.
The <mat-expansion-panel-header>
shows a summary of the panel content and acts
as the control for expanding and collapsing. This header may optionally contain an
<mat-panel-title>
and an <mat-panel-description>
, which format the content of the
header to align with Material Design specifications.
By default, the expansion-panel header includes a toggle icon at the end of the
header to indicate the expansion state. This icon can be hidden via the
hideToggle
property.
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
This is the expansion title
</mat-panel-title>
<mat-panel-description>
This is a summary of the content
</mat-panel-description>
</mat-expansion-panel-header>
<p>This is the primary content of the panel.</p>
</mat-expansion-panel>
Actions may optionally be included at the bottom of the panel, visible only when the expansion
is in its expanded state.
<mat-expansion-panel>
<mat-expansion-panel-header>
This is the expansion title
</mat-expansion-panel-header>
<p>This is the primary content of the panel.</p>
<mat-action-row>
<button mat-button>Click me</button>
</mat-action-row>
</mat-expansion-panel>
Expansion panels can be disabled using the disabled
attribute. A disabled expansion panel can't
be toggled by the user, but can still be manipulated programmatically.
<mat-expansion-panel [disabled]="isDisabled">
<mat-expansion-panel-header>
This is the expansion title
</mat-expansion-panel-header>
<mat-panel-description>
This is a summary of the content
</mat-panel-description>
</mat-expansion-panel>
Multiple expansion-panels can be combined into an accordion. The multi="true"
input allows the
expansions state to be set independently of each other. When multi="false"
(default) just one
panel can be expanded at a given time:
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
This is the expansion 1 title
</mat-expansion-panel-header>
This the expansion 1 content
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
This is the expansion 2 title
</mat-expansion-panel-header>
This the expansion 2 content
</mat-expansion-panel>
</mat-accordion>
By default, the expansion panel content will be initialized even when the panel is closed.
To instead defer initialization until the panel is open, the content should be provided as
an ng-template
:
<mat-expansion-panel>
<mat-expansion-panel-header>
This is the expansion title
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
Some deferred content
</ng-template>
</mat-expansion-panel>
The expansion-panel aims to mimic the experience of the native <details>
and <summary>
elements.
The expansion panel header has role="button"
and also the attribute aria-controls
with the
expansion panel's id as value.
The expansion panel headers are buttons. Users can use the keyboard to activate the expansion panel
header to switch between expanded state and collapsed state. Because the header acts as a button,
additional interactive elements should not be put inside of the header.
<mat-toolbar>
is a container for headers, titles, or actions.
In the most situations, a toolbar will be placed at the top of your application and will only
have a single row that includes the title of your application.
<mat-toolbar>
<span>My Application</span>
</mat-toolbar>
The Material Design specifications describe that toolbars can also have multiple rows. Creating
toolbars with multiple rows in Angular Material can be done by placing <mat-toolbar-row>
elements
inside of a <mat-toolbar>
.
<mat-toolbar>
<mat-toolbar-row>
<span>First Row</span>
</mat-toolbar-row>
<mat-toolbar-row>
<span>Second Row</span>
</mat-toolbar-row>
</mat-toolbar>
Note: Placing content outside of a <mat-toolbar-row>
when multiple rows are specified is not
supported.
The toolbar does not perform any positioning of its content. This gives the user full power to
position the content as it suits their application.
A common pattern is to position a title on the left with some actions on the right. This can be
easily accomplished with display: flex
:
<mat-toolbar color="primary">
<span>Application Title</span>
<!-- This fills the remaining space of the current row -->
<span class="example-fill-remaining-space"></span>
<span>Right Aligned Text</span>
</mat-toolbar>
.example-fill-remaining-space {
/* This fills the remaining space, by using flexbox.
Every toolbar row uses a flexbox row layout. */
flex: 1 1 auto;
}
The color of a <mat-toolbar>
can be changed by using the color
property. By default, toolbars
use a neutral background color based on the current theme (light or dark). This can be changed to
'primary'
, 'accent'
, or 'warn'
.
By default, the toolbar assumes that it will be used in a purely decorative fashion and thus sets
no roles, ARIA attributes, or keyboard shortcuts. This is equivalent to having a sequence of <div>
elements on the page.
Generally, the toolbar is used as a header where role="heading"
would be appropriate.
Only if the use-case of the toolbar match that of role="toolbar", the user should add the role and
an appropriate label via aria-label
or aria-labelledby
.
Badges are small status descriptors for UI elements. A badge consists of a small circle,
typically containing a number or other short set of characters, that appears in proximity to
another object.
By default, the badge will be placed above after
. The direction can be changed by defining
the attribute matBadgePosition
follow by above|below
and before|after
.
<mat-icon matBadge="22" matBadgePosition="above after">home</mat-icon>
The overlap of the badge in relation to its inner contents can also be defined
using the matBadgeOverlap
tag. Typically, you want the badge to overlap an icon and not
a text phrase. By default it will overlap.
<h1 matBadge="11" matBadgeOverlap="false">
Email
</h1>
The badge has 3 sizes: small
, medium
and large
. By default, the badge is set to medium
.
You can change the size by adding matBadgeSize
to the host element.
<h1 matBadge="11" matBadgeSize="large">
Email
</h1>
The badge visibility can be toggled programmatically by defining matBadgeHidden
.
<h1 matBadge="11" [matBadgeHidden]="!visible">
Email
</h1>
Badges can be colored in terms of the current theme using the matBadgeColor
property to set the
background color to primary
, accent
, or warn
.
<mat-icon matBadge="22" matBadgeColor="accent">
home
</mat-icon>
Badges should be given a meaningful description via matBadgeDescription
. This description will be
applied, via aria-describedby
to the element decorated by matBadge
.
When applying a badge to a <mat-icon>
, it is important to know that the icon is marked as
aria-hidden
by default. If the combination of icon and badge communicates some meaningful
information, that information should be surfaced in another way. See the guidance on indicator
icons for more information.
Angular Material buttons are native <button>
or <a>
elements enhanced with Material Design
styling and ink ripples.
Native <button>
and <a>
elements are always used in order to provide the most straightforward
and accessible experience for users. A <button>
element should be used whenever some action
is performed. An <a>
element should be used whenever the user will navigate to another view.
There are several button variants, each applied as an attribute:
Attribute | Description |
---|---|
mat-button |
Rectangular text button w/ no elevation |
mat-raised-button |
Rectangular contained button w/ elevation |
mat-flat-button |
Rectangular contained button w/ no elevation |
mat-stroked-button |
Rectangular outlined button w/ no elevation |
mat-icon-button |
Circular button with a transparent background, meant to contain an icon |
mat-fab |
Circular button w/ elevation, defaults to theme's accent color |
mat-mini-fab |
Same as mat-fab but smaller |
Buttons can be colored in terms of the current theme using the color
property to set the
background color to primary
, accent
, or warn
.
According to the Material design spec button text has to be capitalized, however we have opted not
to capitalize buttons automatically via text-transform: uppercase
, because it can cause issues in
certain locales. It is also worth noting that using ALL CAPS in the text itself causes issues for
screen-readers, which will read the text character-by-character. We leave the decision of how to
approach this to the consuming app.
Angular Material uses native <button>
and <a>
elements to ensure an accessible experience by
default. The <button>
element should be used for any interaction that performs an action on the
current page. The <a>
element should be used for any interaction that navigates to another
view.
Buttons or links containing only icons (such as mat-fab
, mat-mini-fab
, and mat-icon-button
) should
be given a meaningful label via aria-label
or aria-labelledby
.
The matSort
and mat-sort-header
are used, respectively, to add sorting state and display
to tabular data.
To add sorting behavior and styling to a set of table headers, add the <mat-sort-header>
component
to each header and provide an id
that will identify it. These headers should be contained within a
parent element with the matSort
directive, which will emit an matSortChange
event when the user
triggers sorting on the header.
Users can trigger the sort header through a mouse click or keyboard action. When this happens, the
matSort
will emit an matSortChange
event that contains the ID of the header triggered and the
direction to sort (asc
or desc
).
By default, a sort header starts its sorting at asc
and then desc
. Triggering the sort header
after desc
will remove sorting.
To reverse the sort order for all headers, set the matSortStart
to desc
on the matSort
directive. To reverse the order only for a specific header, set the start
input only on the header
instead.
To prevent the user from clearing the sort sort state from an already sorted column, set
matSortDisableClear
to true
on the matSort
to affect all headers, or set disableClear
to
true
on a specific header.
If you want to prevent the user from changing the sorting order of any column, you can use the
matSortDisabled
binding on the mat-sort
, or the disabled
on an single mat-sort-header
.
When used on an mat-table
header, it is not required to set an mat-sort-header
id on because
by default it will use the id of the column.
The aria-label
for the sort button can be set in MatSortHeaderIntl
.
组件 | 说明 | 选择符 |
---|---|---|
AbcLineComponent | 分割线 | abc-line |
AbcLineYComponent | 垂直分割线 | abc-line-y |
AbcBlankComponent | 左右留白 | abc-blank |
AbcSpaceComponent | 上下留白 | abc-space |
<tabbar-outlet>
<ng-template tabbarBottom></ng-template>
<ng-template tabbarContent></ng-template>
<ng-template tabbarTop></ng-template>
</tabbar-outlet>
selector | desc |
---|---|
tabbar-outlet | outlet |
[tabbarBottom] | bottom |
[tabbarContent] | content |
[tabbarTop] | top |
Angular Material provides two sets of components designed to add collapsible side content (often
navigation, though it can be any content) alongside some primary content. These are the sidenav and
drawer components.
The sidenav components are designed to add side content to a fullscreen app. To set up a sidenav we
use three components: <mat-sidenav-container>
which acts as a structural container for our content
and sidenav, <mat-sidenav-content>
which represents the main content, and <mat-sidenav>
which
represents the added side content.
The drawer component is designed to add side content to a small section of your app. This is
accomplished using the <mat-drawer-container>
, <mat-drawer-content>
, and <mat-drawer>
components, which are analogous to their sidenav equivalents. Rather than adding side content to the
app as a whole, these are designed to add side content to a small section of your app. They support
almost all of the same features, but do not support fixed positioning.
Both the main and side content should be placed inside of the <mat-sidenav-container>
, content
that you don't want to be affected by the sidenav, such as a header or footer, can be placed outside
of the container.
The side content should be wrapped in a <mat-sidenav>
element. The position
property can be used
to specify which end of the main content to place the side content on. position
can be either
start
or end
which places the side content on the left or right respectively in left-to-right
languages. If the position
is not set, the default value of start
will be assumed. A
<mat-sidenav-container>
can have up to two <mat-sidenav>
elements total, but only one for any
given side.
The main content should be wrapped in a <mat-sidenav-content>
. If no <mat-sidenav-content>
is
specified for a <mat-sidenav-container>
, one will be created implicitly and all of the content
inside the <mat-sidenav-container>
other than the <mat-sidenav>
elements will be placed inside
of it.
The following are examples of valid sidenav layouts:
<!-- Creates a layout with a left-positioned sidenav and explicit content. -->
<mat-sidenav-container>
<mat-sidenav>Start</mat-sidenav>
<mat-sidenav-content>Main</mat-sidenav-content>
</mat-sidenav-container>
<!-- Creates a layout with a left and right sidenav and implicit content. -->
<mat-sidenav-container>
<mat-sidenav>Start</mat-sidenav>
<mat-sidenav position="end">End</mat-sidenav>
<section>Main</section>
</mat-sidenav-container>
<!-- Creates an empty sidenav container with no sidenavs and implicit empty content. -->
<mat-sidenav-container></mat-sidenav-container>
And these are examples of invalid sidenav layouts:
<!-- Invalid because there are two `start` position sidenavs. -->
<mat-sidenav-container>
<mat-sidenav>Start</mat-sidenav>
<mat-sidenav position="start">Start 2</mat-sidenav>
</mat-sidenav-container>
<!-- Invalid because there are multiple `<mat-sidenav-content>` elements. -->
<mat-sidenav-container>
<mat-sidenav-content>Main</mat-sidenav-content>
<mat-sidenav-content>Main 2</mat-sidenav-content>
</mat-sidenav-container>
<!-- Invalid because the `<mat-sidenav>` is outside of the `<mat-sidenav-container>`. -->
<mat-sidenav-container></mat-sidenav-container>
<mat-sidenav></mat-sidenav>
These same rules all apply to the drawer components as well.
A <mat-sidenav>
can be opened or closed using the open()
, close()
and toggle()
methods. Each
of these methods returns a Promise<boolean>
that will be resolved with true
when the sidenav
finishes opening or false
when it finishes closing.
The opened state can also be set via a property binding in the template using the opened
property.
The property supports 2-way binding.
<mat-sidenav>
also supports output properties for just open and just close events, The (opened)
and (closed)
properties respectively.
All of these properties and methods work on <mat-drawer>
as well.
The <mat-sidenav>
can render in one of three different ways based on the mode
property.
Mode | Description |
---|---|
over |
Sidenav floats over the primary content, which is covered by a backdrop |
push |
Sidenav pushes the primary content out of its way, also covering it with a backdrop |
side |
Sidenav appears side-by-side with the main content, shrinking the main content's width to make space for the sidenav. |
If no mode
is specified, over
is used by default.
The over
and push
sidenav modes show a backdrop by default, while the side
mode does not. This
can be customized by setting the hasBackdrop
property on mat-sidenav-container
. Explicitly
setting hasBackdrop
to true
or false
will override the default backdrop visibility setting for
all sidenavs regadless of mode. Leaving the property unset or setting it to null
will use the
default backdrop visibility for each mode.
<mat-drawer>
also supports all of these same modes and options.
Clicking on the backdrop or pressing the Esc key will normally close an open sidenav.
However, this automatic closing behavior can be disabled by setting the disableClose
property on
the <mat-sidenav>
or <mat-drawer>
that you want to disable the behavior for.
Custom handling for Esc can be done by adding a keydown listener to the <mat-sidenav>
.
Custom handling for backdrop clicks can be done via the (backdropClick)
output property on
<mat-sidenav-container>
.
By default, Material will only measure and resize the drawer container in a few key moments
(on open, on window resize, on mode change) in order to avoid layout thrashing, however there
are cases where this can be problematic. If your app requires for a drawer to change its width
while it is open, you can use the autosize
option to tell Material to continue measuring it.
Note that you should use this option at your own risk, because it could cause performance
issues.
The <mat-sidenav>
and <mat-drawer>
will, by default, fit the size of its content. The width can
be explicitly set via CSS:
mat-sidenav {
width: 200px;
}
Try to avoid percent based width as resize
events are not (yet) supported.
For <mat-sidenav>
only (not <mat-drawer>
) fixed positioning is supported. It can be enabled by
setting the fixedInViewport
property. Additionally, top and bottom space can be set via the
fixedTopGap
and fixedBottomGap
. These properties accept a pixel value amount of space to add at
the top or bottom.
A sidenav often needs to behave differently on a mobile vs a desktop display. On a desktop, it may
make sense to have just the content section scroll. However, on mobile you often want the body to be
the element that scrolls; this allows the address bar to auto-hide. The sidenav can be styled with
CSS to adjust to either type of device.
To react to scrolling inside the <mat-sidenav-container>
, you can get a hold of the underlying
CdkScrollable
instance through the MatSidenavContainer
.
class YourComponent {
@ViewChild(MatSidenavContainer) sidenavContainer: MatSidenavContainer;
constructor() {
this.sidenavContainer.scrollable.elementScrolled().subscribe(() => /* react to scrolling */);
}
}
The <mat-sidenav>
an <mat-sidenav-content>
should each be given an appropriate role
attribute
depending on the context in which they are used.
For example, a <mat-sidenav>
that contains links
to other pages might be marked role="navigation"
, whereas one that contains a table of
contents about might be marked as role="directory"
. If there is no more specific role that
describes your sidenav, role="region"
is recommended.
Similarly, the <mat-sidenav-content>
should be given a role based on what it contains. If it
represents the primary content of the page, it may make sense to mark it role="main"
. If no more
specific role makes sense, role="region"
is again a good fallback.
This error is thrown if you have more than one sidenav or drawer in a given container with the same
position
. The position
property defaults to start
, so the issue may just be that you forgot to
mark the end
sidenav with position="end"
.
<mat-divider>
is a component that allows for Material styling of a line separator with various orientation options.
A <mat-divider>
element can be used on its own to create a horizontal or vertical line styled with a Material theme
<mat-divider></mat-divider>
Add the inset
attribute in order to set whether or not the divider is an inset divider.
<mat-divider [inset]="true"></mat-divider>
Add the vertical
attribute in order to set whether or not the divider is vertically-oriented.
<mat-divider [vertical]="true"></mat-divider>
Dividers can be added to lists as a means of separating content into distinct sections.
Inset dividers can also be added to provide the appearance of distinct elements in a list without cluttering content
like avatar images or icons. Make sure to avoid adding an inset divider to the last element
in a list, because it will overlap with the section divider.
<mat-list>
<h3 mat-subheader>Folders</h3>
<mat-list-item *ngFor="let folder of folders; last as last">
<mat-icon mat-list-icon>folder</mat-icon>
<h4 mat-line>{{folder.name}}</h4>
<p mat-line class="demo-2"> {{folder.updated}} </p>
<mat-divider [inset]="true" *ngIf="!last"></mat-divider>
</mat-list-item>
<mat-divider></mat-divider>
<h3 mat-subheader>Notes</h3>
<mat-list-item *ngFor="let note of notes">
<mat-icon mat-list-icon>note</mat-icon>
<h4 mat-line>{{note.name}}</h4>
<p mat-line class="demo-2"> {{note.updated}} </p>
</mat-list-item>
</mat-list>
iwe7-box-x
指定宽度
iwe7-box-y
指定高度
配置 | 说明 | 默认 |
---|---|---|
ratio | 比率 | 0.618 |
params | 附加 | 1 |
reversal | 反转 | false |
color | 背景色 |
<div>
<iwe7-box-y style="height: 30px;" color="red">
</iwe7-box-y>
<iwe7-box-y style="height: 30px;" color="green">
</iwe7-box-y>
<iwe7-box-y style="height: 30px;" color="black">
</iwe7-box-y>
</div>
<div>
<iwe7-box-y reversal style="height: 30px;" color="red">
</iwe7-box-y>
<iwe7-box-y reversal style="height: 30px;" color="green">
</iwe7-box-y>
<iwe7-box-y reversal style="height: 30px;" color="black">
</iwe7-box-y>
</div>
<div>
<iwe7-box-x style="width: 33.33%;" color="red">
</iwe7-box-x>
<iwe7-box-x style="width: 33.33%;" color="green">
</iwe7-box-x>
<iwe7-box-x style="width: 33.33%;" color="black">
</iwe7-box-x>
</div>
<div>
<iwe7-box-x reversal style="width: 33.33%;" color="black">
</iwe7-box-x>
<iwe7-box-x reversal style="width: 33.33%;" color="red">
</iwe7-box-x>
<iwe7-box-x reversal style="width: 33.33%;" color="green">
</iwe7-box-x>
</div>
组件 | 说明 | 类型 | 使用 |
---|---|---|---|
swiper-outlet | 容器 | Component | element |
[swiperItem] | slide模板 | Directive | ng-template |
[swiperDot] | dot模板 | Directive | ng-template |
输入 | 默认 | 类型 |
---|---|---|
hasDot | true | boolean |
loop | true | boolean |
click | true | boolean |
autoPlay | true | boolean |
scrollX | true | boolean |
scrollY | false | boolean |
interval | 4000 | number |
threshold | 0.3 | number |
speed | 400 | number |
list | [] | array |
<swiper-outlet [list]="list"></swiper-outlet>
<button mat-flat-button (click)="showDialogX()">showDialogX</button>
<button mat-flat-button (click)="showDialogY()">showDialogY</button>
<ng-template #tplX>
<swiper-outlet [list]="list"></swiper-outlet>
</ng-template>
<ng-template #tplY>
<swiper-outlet scrollY [list]="list"></swiper-outlet>
</ng-template>
list: any[] = [{
image: 'http://y.gtimg.cn/music/photo_new/T003R720x288M000004ckGfg3zaho0.jpg'
}, {
image: 'http://y.gtimg.cn/music/photo_new/T003R720x288M000004ckGfg3zaho0.jpg'
}];
showDialogX() {
this.getCyc('ngAfterViewInit').subscribe(res => {
const dialogRef = this.dialog.open(this.tplX);
});
}
showDialogY() {
this.getCyc('ngAfterViewInit').subscribe(res => {
const dialogRef = this.dialog.open(this.tplY);
});
}
MatSnackBar
is a service for displaying snack-bar notifications.
A snack-bar can contain either a string message or a given component.
// Simple message.
let snackBarRef = snackBar.open('Message archived');
// Simple message with an action.
let snackBarRef = snackBar.open('Message archived', 'Undo');
// Load the given component into the snack-bar.
let snackBarRef = snackbar.openFromComponent(MessageArchivedComponent);
In either case, a MatSnackBarRef
is returned. This can be used to dismiss the snack-bar or to
receive notification of when the snack-bar is dismissed. For simple messages with an action, the
MatSnackBarRef
exposes an observable for when the action is triggered.
If you want to close a custom snack-bar that was opened via openFromComponent
, from within the
component itself, you can inject the MatSnackBarRef
.
snackBarRef.afterDismissed().subscribe(() => {
console.log('The snack-bar was dismissed');
});
snackBarRef.onAction().subscribe(() => {
console.log('The snack-bar action was triggered!');
});
snackBarRef.dismiss();
A snack-bar can be dismissed manually by calling the dismiss
method on the MatSnackBarRef
returned from the call to open
.
Only one snack-bar can ever be opened at one time. If a new snackbar is opened while a previous
message is still showing, the older message will be automatically dismissed.
A snack-bar can also be given a duration via the optional configuration object:
snackbar.open('Message archived', 'Undo', {
duration: 3000
});
You can share data with the custom snack-bar, that you opened via the openFromComponent
method,
by passing it through the data
property.
snackbar.openFromComponent(MessageArchivedComponent, {
data: 'some data'
});
To access the data in your component, you have to use the MAT_SNACK_BAR_DATA
injection token:
import {Component, Inject} from '@angular/core';
import {MAT_SNACK_BAR_DATA} from '@angular/material';
@Component({
selector: 'your-snack-bar',
template: 'passed in {{ data }}',
})
export class MessageArchivedComponent {
constructor(@Inject(MAT_SNACK_BAR_DATA) public data: any) { }
}
If you want to override the default snack bar options, you can do so using the
MAT_SNACK_BAR_DEFAULT_OPTIONS
injection token.
@NgModule({
providers: [
{provide: MAT_SNACK_BAR_DEFAULT_OPTIONS, useValue: {duration: 2500}}
]
})
Snack-bar messages are announced via an aria-live
region. By default, the polite
setting is
used. While polite
is recommended, this can be customized by setting the politeness
property of
the MatSnackBarConfig
.
Focus is not, and should not be, moved to the snack-bar element. Moving the focus would be
disruptive to a user in the middle of a workflow. It is recommended that, for any action offered
in the snack-bar, the application offer the user an alternative way to perform the action.
Alternative interactions are typically keyboard shortcuts or menu options. When the action is
performed in this way, the snack-bar should be dismissed.
Snack-bars that have an action available should not be given a duration
, as to accomodate
screen-reader users that want to navigate to the snack-bar element to activate the action. If the
user has manually moved their focus within the snackbar, focus should be placed somewhere sensible
based on the application context when the snack-bar is dismissed.
Don't use "Dismiss" as a snack-bar-action, instead preferring to use a duration
when there is
no additional action associated with the notification.
The Angular Material tooltip provides a text label that is displayed when the user hovers
over or longpresses an element.
The tooltip will be displayed below the element but this can be configured using the
matTooltipPosition
input.
The tooltip can be displayed above, below, left, or right of the element. By default the position
will be below. If the tooltip should switch left/right positions in an RTL layout direction, then
the positions before
and after
should be used instead of left
and right
, respectively.
Position | Description |
---|---|
above |
Always display above the element |
below |
Always display beneath the element |
left |
Always display to the left of the element |
right |
Always display to the right of the element |
before |
Display to the left in left-to-right layout and to the right in right-to-left layout |
after |
Display to the right in left-to-right layout and to the left in right-to-left layout |
By default, the tooltip will be immediately shown when the user's mouse hovers over the tooltip's
trigger element and immediately hides when the user's mouse leaves.
On mobile, the tooltip is displayed when the user longpresses the element and hides after a
delay of 1500ms. The longpress behavior requires HammerJS to be loaded on the page. To learn more
about adding HammerJS to your app, check out the Gesture Support section of the Getting Started
guide.
To add a delay before showing or hiding the tooltip, you can use the inputs matTooltipShowDelay
and matTooltipHideDelay
to provide a delay time in milliseconds.
The following example has a tooltip that waits one second to display after the user
hovers over the button, and waits two seconds to hide after the user moves the mouse away.
You can configure your app's tooltip default show/hide delays by configuring and providing
your options using the MAT_TOOLTIP_DEFAULT_OPTIONS
injection token.
To manually cause the tooltip to show or hide, you can call the show
and hide
directive methods,
which both accept a number in milliseconds to delay before applying the display change.
To completely disable a tooltip, set matTooltipDisabled
. While disabled, a tooltip will never be
shown.
Elements with the matTooltip
will add an aria-describedby
label that provides a reference
to a visually hidden element containing the tooltip's message. This provides screenreaders the
information needed to read out the tooltip's contents when the end-user focuses on the element
triggering the tooltip. The element referenced via aria-describedby
is not the tooltip itself,
but instead an invisible copy of the tooltip content that is always present in the DOM.
If a tooltip will only be shown manually via click, keypress, etc., then extra care should be taken
such that the action behaves similarly for screen-reader users. One possible approach would be
to use the LiveAnnouncer
from the cdk/a11y
package to announce the tooltip content on such
an interaction.
<mat-form-field>
is a component used to wrap several Angular Material components and apply common
Text field styles such as the
underline, floating label, and hint messages.
In this document, "form field" refers to the wrapper component <mat-form-field>
and
"form field control" refers to the component that the <mat-form-field>
is wrapping
(e.g. the input, textarea, select, etc.)
The following Angular Material components are designed to work inside a <mat-form-field>
:
The mat-form-field
supports 4 different appearance variants which can be set via the appearance
input. The legacy
appearance is the default style that the mat-form-field
has traditionally had.
It shows the input box with an underline underneath it. The standard
appearance is a slightly
updated version of the legacy
appearance that has spacing that is more consistent with the fill
and outline
appearances. The fill
appearance displays the form field with a filled background
box in addition to the underline. Finally the outline
appearance shows the form field with a
border all the way around, not just an underline.
There are a couple differences to be aware of between the legacy
appearance and the newer
standard
, fill
, and outline
appearances. The matPrefix
and matSuffix
elements are center
aligned by default for the newer appearances. The Material Design spec shows this as being the
standard way to align prefix and suffix icons in the newer appearance variants. We do not recommend
using text prefix and suffixes in the new variants because the label and input do not have the same
alignment. It is therefore impossible to align the prefix or suffix in a way that looks good when
compared with both the label and input text.
The second important difference is that the standard
, fill
, and outline
appearances do not
promote placeholders to labels. For the legacy
appearance specifying
<input placeholder="placeholder">
will result in a floating label being added to the
mat-form-field
. For the newer variants it will just add a normal placeholder to the input. If you
want a floating label, add a <mat-label>
to the mat-form-field
.
The floating label is a text label displayed on top of the form field control when
the control does not contain any text. By default, when text is present the floating label
floats above the form field control. The label for a form field can be specified by adding a
mat-label
element.
In the legacy version of the <mat-form-field>
(one that has no appearance
attribute or has
appearance="legacy"
) if a label is not specified, the placeholder
attribute on the form control
is promoted to a label. If a label is specified, the placeholder
will be displayed as a normal
placeholder. The placeholder
will never be promoted to a label for standard
, fill
, and
outline
form fields. If you want to create a legacy form field with a placeholder but no label,
you will need to specify an empty label to prevent the placeholder
from being promoted.
<mat-form-field>
<mat-label></mat-label>
<input placeholder="Just a placeholder">
</mat-form-field>
If the form field control is marked with a required
attribute, an asterisk will be appended to the
label to indicate the fact that it is a required field. If unwanted, this can be disabled by
setting the hideRequiredMarker
property on <mat-form-field>
The floatLabel
property of <mat-form-field>
can be used to change this default floating
behavior. It can set to never
to hide the label instead of float it when text is present in
the form field control. It can be set to always
to float the label even when no text is
present in the form field control. It can also be set to auto
to restore the default behavior.
Global default label options can be specified by providing a value for
MAT_LABEL_GLOBAL_OPTIONS
in your application's root module. Like the property, the global
setting can be either always
, never
, or auto
.
@NgModule({
providers: [
{provide: MAT_LABEL_GLOBAL_OPTIONS, useValue: {float: 'always'}}
]
})
Hint labels are additional descriptive text that appears below the form field's underline. A
<mat-form-field>
can have up to two hint labels; one start-aligned (left in an LTR language, right
in RTL), and one end-aligned.
Hint labels are specified in one of two ways: either by using the hintLabel
property of
<mat-form-field>
, or by adding a <mat-hint>
element inside the form field. When adding a hint
via the hintLabel
property, it will be treated as the start hint. Hints added via the
<mat-hint>
hint element can be added to either side by setting the align
property on
<mat-hint>
to either start
or end
. Attempting to add multiple hints to the same side will
raise an error.
Error messages can be shown under the form field underline by adding mat-error
elements inside the
form field. Errors are hidden initially and will be displayed on invalid form fields after the user
has interacted with the element or the parent form has been submitted. Since the errors occupy the
same space as the hints, the hints are hidden when the errors are shown.
If a form field can have more than one error state, it is up to the consumer to toggle which
messages should be displayed. This can be done with CSS, ngIf
or ngSwitch
. Multiple error
messages can be shown at the same time if desired, but the <mat-form-field>
only reserves enough
space to display one error message at a time. Ensuring that enough space is available to display
multiple errors is up to the user.
Custom content can be included before and after the input tag, as a prefix or suffix. It will be
included within the visual container that wraps the form control as per the Material specification.
Adding the matPrefix
directive to an element inside the <mat-form-field>
will designate it as
the prefix. Similarly, adding matSuffix
will designate it as the suffix.
In addition to the form field controls that Angular Material provides, it is possible to create
custom form field controls that work with <mat-form-field>
in the same way. For additional
information on this see the guide on
Creating Custom mat-form-field Controls.
<mat-form-field>
has a color
property which can be set to primary
, accent
, or warn
. This
will set the color of the form field underline and floating label based on the theme colors
of your app.
<mat-form-field>
inherits its font-size
from its parent element. This can be overridden to an
explicit size using CSS. We recommend a specificity of at least 1 element + 1 class.
mat-form-field.mat-form-field {
font-size: 16px;
}
If a floating label is specified, it will be automatically used as the label for the form
field control. If no floating label is specified, the user should label the form field control
themselves using aria-label
, aria-labelledby
or <label for=...>
.
Any errors and hints added to the form field are automatically added to the form field control's
aria-describedby
set.
This error occurs when you have specified two conflicting placeholders. Make sure that you haven't
included both a placeholder
property on your form field control and a <mat-placeholder>
element. The <mat-placeholder>
element is deprecated, you should use placeholder
for
placeholders and <mat-label>
for labels.
This error occurs if you have added multiple hints for the same side. Keep in mind that the
hintLabel
property adds a hint to the start side.
This error occurs when you have not added a form field control to your form field. If your form
field contains a native <input>
or <textarea>
element, make sure you've added the matInput
directive to it and have imported MatInputModule
. Other components that can act as a form field
control include <mat-select>
, <mat-chip-list>
, and any custom form field controls you've
created.
<mat-select>
is a form control for selecting a value from a set of options, similar to the native
<select>
element. You can read more about selects in the
Material Design spec. It is designed to work
inside of a <mat-form-field>
element.
To add options to the select, add <mat-option>
elements to the <mat-select>
. Each <mat-option>
has a value
property that can be used to set the value that will be selected if the user chooses
this option. The content of the <mat-option>
is what will be shown to the user.
The <mat-select>
supports 2-way binding to the value
property without the need for Angular
forms.
The <mat-select>
also supports all of the form directives from the core FormsModule
(NgModel
) and
ReactiveFormsModule
(FormControl
, FormGroup
, etc.) As with native <select>
, <mat-select>
also supports a compareWith
function. (Additional information about using a custom compareWith
function can be found in the
Angular forms documentation).
There are a number of <mat-form-field>
features that can be used with any <mat-select>
. These
include error messages, hint text, prefix & suffix, and theming. For additional information about
these features, see the
form field documentation.
The placeholder is text shown when the <mat-form-field>
label is floating but the <mat-select>
is empty. It is used to give the user an additional hint about the value they should select. The
placeholder can be specified by setting the placeholder
attribute on the <mat-select>
element.
In some cases that <mat-form-field>
may use the placeholder as the label (see the
form field label documentation).
It is possible to disable the entire select or individual options in the select by using the
disabled property on the <mat-select>
and the <mat-option>
components respectively.
If you want one of your options to reset the select's value, you can omit specifying its value.
The <mat-optgroup>
element can be used to group common options under a subheading. The name of the
group can be set using the label
property of <mat-optgroup>
. Like individual <mat-option>
elements, an entire <mat-optgroup>
can be disabled or enabled by setting the disabled
property
on the group.
<mat-select>
defaults to single-selection mode, but can be configured to allow multiple selection
by setting the multiple
property. This will allow the user to select multiple values at once. When
using the <mat-select>
in multiple selection mode, its value will be a sorted list of all selected
values rather than a single value.
If you want to display a custom trigger label inside a select, you can use the
<mat-select-trigger>
element.
By default, when a user clicks on a <mat-option>
, a ripple animation is shown. This can be disabled
by setting the disableRipple
property on <mat-select>
.
In order to facilitate easily styling the dropdown panel, <mat-select>
has a panelClass
property
which can be used to apply additional CSS classes to the dropdown panel.
The <mat-form-field>
allows you to
associate error messages
with your <mat-select>
. By default, these error messages are shown when the control is invalid and
either the user has interacted with (touched) the element or the parent form has been submitted. If
you wish to override this behavior (e.g. to show the error as soon as the invalid control is dirty
or when a parent form group is invalid), you can use the errorStateMatcher
property of the
<mat-select>
. The property takes an instance of an ErrorStateMatcher
object. An
ErrorStateMatcher
must implement a single method isErrorState
which takes the FormControl
for
this <mat-select>
as well as the parent form and returns a boolean indicating whether errors
should be shown. (true
indicating that they should be shown, and false
indicating that they
should not.)
A global error state matcher can be specified by setting the ErrorStateMatcher
provider. This
applies to all inputs. For convenience, ShowOnDirtyErrorStateMatcher
is available in order to
globally cause input errors to show when the input is dirty and invalid.
@NgModule({
providers: [
{provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher}
]
})
The select component without text or label should be given a meaningful label via
aria-label
or aria-labelledby
.
The select component has role="listbox"
and options inside select have role="option"
.
multiple
mode of select after initializationThis error is thrown if you attempt to bind the multiple
property on <mat-select>
to a dynamic
value. (e.g. [multiple]="isMultiple"
where the value of isMultiple
changes over the course of
the component's lifetime). If you need to change this dynamically, use ngIf
or ngSwitch
instead:
<mat-select *ngIf="isMultiple" multiple>
...
</mat-select>
<mat-select *ngIf="!isMultiple">
...
</mat-select>
This error is thrown if you attempt to assign a value other than null
, undefined
, or an array to
a <mat-select multiple>
. For example, something like mySelect.value = 'option1'
. What you likely
meant to do was mySelect.value = ['option1']
.
compareWith
must be a functionThis error occurs if you attempt to assign something other than a function to the compareWith
property. For more information on proper usage of compareWith
see the
Angular forms documentation).
mat-icon
makes it easier to use vector-based icons in your app. This directive supports both
icon fonts and SVG icons, but not bitmap-based formats (png, jpg, etc.).
MatIconRegistry
is an injectable service that allows you to associate icon names with SVG URLs,
HTML strings and to define aliases for CSS font classes. Its methods are discussed below and listed
in the API summary.
Some fonts are designed to show icons by using
ligatures, for example by rendering the text
"home" as a home image. To use a ligature icon, put its text in the content of the mat-icon
component.
By default, <mat-icon>
expects the
Material icons font.
(You will still need to include the HTML to load the font and its CSS, as described in the link).
You can specify a different font by setting the fontSet
input to either the CSS class to apply to
use the desired font, or to an alias previously registered with
MatIconRegistry.registerFontClassAlias
.
Fonts can also display icons by defining a CSS class for each icon glyph, which typically uses a
:before
selector to cause the icon to appear.
FontAwesome uses this approach to display
its icons. To use such a font, set the fontSet
input to the font's CSS class (either the class
itself or an alias registered with MatIconRegistry.registerFontClassAlias
), and set the fontIcon
input to the class for the specific icon to show.
For both types of font icons, you can specify the default font class to use when fontSet
is not
explicitly set by calling MatIconRegistry.setDefaultFontSetClass
.
When an mat-icon
component displays an SVG icon, it does so by directly inlining the SVG content
into the page as a child of the component. (Rather than using an tag or a div background
image). This makes it easier to apply CSS styles to SVG icons. For example, the default color of the
SVG content is the CSS
currentColor
value. This makes SVG icons by default have the same color as surrounding text, and allows you to
change the color by setting the "color" style on the mat-icon
element.
In order to prevent XSS vulnerabilities, any SVG URLs and HTML strings passed to the
MatIconRegistry
must be marked as trusted by using Angular's DomSanitizer
service.
Also note that all SVG icons, registered by URL, are fetched via XmlHttpRequest, and due to the
same-origin policy, their URLs must be on the same domain as the containing page, or their servers
must be configured to allow cross-domain access.
To associate a name with an icon URL, use the addSvgIcon
, addSvgIconInNamespace
,
addSvgIconLiteral
or addSvgIconLiteralInNamespace
methods of MatIconRegistry
. After
registering an icon, it can be displayed by setting the svgIcon
input. For an icon in the
default namespace, use the name directly. For a non-default namespace, use the format
[namespace]:[name]
.
Icon sets allow grouping multiple icons into a single SVG file. This is done by creating a single
root <svg>
tag that contains multiple nested <svg>
tags in its <defs>
section. Each of these
nested tags is identified with an id
attribute. This id
is used as the name of the icon.
Icon sets are registered using the addSvgIconSet
, addSvgIconSetInNamespace
,
addSvgIconSetLiteral
or addSvgIconSetLiteralInNamespace
methods of MatIconRegistry
.
After an icon set is registered, each of its embedded icons can be accessed by their id
attributes. To display an icon from an icon set, use the svgIcon
input in the same way
as for individually registered icons.
Multiple icon sets can be registered in the same namespace. Requesting an icon whose id appears in
more than one icon set, the icon from the most recently registered set will be used.
By default, icons will use the current font color (currentColor
). this color can be changed to
match the current theme's colors using the color
attribute. This can be changed to
'primary'
, 'accent'
, or 'warn'
.
Similar to an <img>
element, an icon alone does not convey any useful information for a
screen-reader user. The user of <mat-icon>
must provide additional information pertaining to how
the icon is used. Based on the use-cases described below, mat-icon
is marked as
aria-hidden="true"
by default, but this can be overriden by adding aria-hidden="false"
to the
element.
In thinking about accessibility, it is useful to place icon use into one of three categories:
By default icons in an RTL layout will look exactly the same as in LTR, however certain icons have
to be mirrored for RTL users. If
you want to mirror an icon only in an RTL layout, you can use the mat-icon-rtl-mirror
CSS class.
<mat-icon class="mat-icon-rtl-mirror" svgIcon="thumb-up"></mat-icon>
When the icon is purely cosmetic and conveys no real semantic meaning, the <mat-icon>
element
is marked with aria-hidden="true"
.
Icons alone are not interactive elements for screen-reader users; when the user would interact with
some icon on the page, a more appropriate element should "own" the interaction:
<mat-icon>
element should be a child of a <button>
or <a>
element.<button>
or <a>
should either have a meaningful label provided either througharia-label
, or aria-labelledby
.When the presence of an icon communicates some information to the user whether as an indicator or
by being inlined into a block of text, that information must also be made available to
screen-readers. The most straightforward way to do this is to
<span>
as an adjacent sibling to the <mat-icon>
element with text that conveys the samecdk-visually-hidden
class to the <span>
. This will make the message invisibleReactiveFormsModule
The observers
package provides convenience directives built on top of native web platform
observers, such as MutationObserver.
A directive for observing when the content of the host element changes. An event is emitted when a
mutation to the content is observed.
<div class="projected-content-wrapper" (cdkObserveContent)="projectContentChanged()">
<ng-content></ng-content>
</div>
observe(element: Element): Observable<MutationRecord[]>;
create(callback: MutationCallback): MutationObserver | null;
The datepicker allows users to enter a date either through text input, or by choosing a date from
the calendar. It is made up of several components and directives that work together.
A datepicker is composed of a text input and a calendar pop-up, connected via the matDatepicker
property on the text input.
<input [matDatepicker]="myDatepicker">
<mat-datepicker #myDatepicker></mat-datepicker>
An optional datepicker toggle button is available. A toggle can be added to the example above:
<input [matDatepicker]="myDatepicker">
<mat-datepicker-toggle [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
This works exactly the same with an input that is part of an <mat-form-field>
and the toggle
can easily be used as a prefix or suffix on the material input:
<mat-form-field>
<input matInput [matDatepicker]="myDatepicker">
<mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
<mat-datepicker #myDatepicker></mat-datepicker>
</mat-form-field>
If you want to customize the icon that is rendered inside the mat-datepicker-toggle
, you can do so
by using the matDatepickerToggleIcon
directive:
The startView
property of <mat-datepicker>
can be used to set the view that will show up when
the calendar first opens. It can be set to month
, year
, or multi-year
; by default it will open
to month view.
The month, year, or range of years that the calendar opens to is determined by first checking if any
date is currently selected, if so it will open to the month or year containing that date. Otherwise
it will open to the month or year containing today's date. This behavior can be overridden by using
the startAt
property of <mat-datepicker>
. In this case the calendar will open to the month or
year containing the startAt
date.
When a year or a month is selected in multi-year
and year
views respectively, the yearSelected
and monthSelected
outputs emit a normalized date representing the chosen year or month. By
"normalized" we mean that the dates representing years will have their month set to January and
their day set to the 1st. Dates representing months will have their day set to the 1st of the
month. For example, if <mat-datepicker>
is configured to work with javascript native Date
objects, the yearSelected
will emit new Date(2017, 0, 1)
if the user selects 2017 in
multi-year
view. Similarly, monthSelected
will emit new Date(2017, 1, 1)
if the user
selects February in year
view and the current date value of the connected <input>
was
set to something like new Date(2017, MM, dd)
when the calendar was opened (the month and day are
irrelevant in this case).
Notice that the emitted value does not affect the current value in the connected <input>
, which
is only bound to the selection made in the month
view. So if the end user closes the calendar
after choosing a year in multi-view
mode (by pressing the ESC
key, for example), the selected
year, emitted by yearSelected
output, will not cause any change in the value of the date in the
associated <input>
.
The following example uses yearSelected
and monthSelected
outputs to emulate a month and year
picker (if you're not familiar with the usage of MomentDateAdapter
and MAT_DATE_FORMATS
you can read more about them below in
this document to fully understand the example).
The type of values that the datepicker expects depends on the type of DateAdapter
provided in your
application. The NativeDateAdapter
, for example, works directly with plain JavaScript Date
objects. When using the MomentDateAdapter
, however, the values will all be Moment.js instances.
This use of the adapter pattern allows the datepicker component to work with any arbitrary date
representation with a custom DateAdapter
.
See Choosing a date implementation
for more information.
Depending on the DateAdapter
being used, the datepicker may automatically deserialize certain date
formats for you as well. For example, both the NativeDateAdapter
and MomentDateAdapter
allow
ISO 8601 strings to be passed to the datepicker and
automatically converted to the proper object type. This can be convenient when binding data directly
from your backend to the datepicker. However, the datepicker will not accept date strings formatted
in user format such as "1/2/2017"
as this is ambiguous and will mean different things depending on
the locale of the browser running the code.
As with other types of <input>
, the datepicker works with @angular/forms
directives such as
formGroup
, formControl
, ngModel
, etc.
The datepicker popup will automatically inherit the color palette (primary
, accent
, or warn
)
from the mat-form-field
it is attached to. If you would like to specify a different palette for
the popup you can do so by setting the color
property on mat-datepicker
.
There are three properties that add date validation to the datepicker input. The first two are the
min
and max
properties. In addition to enforcing validation on the input, these properties will
disable all dates on the calendar popup before or after the respective values and prevent the user
from advancing the calendar past the month
or year
(depending on current view) containing the
min
or max
date.
The second way to add date validation is using the matDatepickerFilter
property of the datepicker
input. This property accepts a function of <D> => boolean
(where <D>
is the date type used by
the datepicker, see
Choosing a date implementation).
A result of true
indicates that the date is valid and a result of false
indicates that it is
not. Again this will also disable the dates on the calendar that are invalid. However, one important
difference between using matDatepickerFilter
vs using min
or max
is that filtering out all
dates before or after a certain point, will not prevent the user from advancing the calendar past
that point.
In this example the user can back past 2005, but all of the dates before then will be unselectable.
They will not be able to go further back in the calendar than 2000. If they manually type in a date
that is before the min, after the max, or filtered out, the input will have validation errors.
Each validation property has a different error that can be checked:
min
property will have a matDatepickerMin
error.max
property will have a matDatepickerMax
error.matDatepickerFilter
property will have a matDatepickerFilter
error.The input's native (input)
and (change)
events will only trigger due to user interaction with
the input element; they will not fire when the user selects a date from the calendar popup.
Therefore, the datepicker input also has support for (dateInput)
and (dateChange)
events. These
trigger when the user interacts with either the input or the popup.
The (dateInput)
event will fire whenever the value changes due to the user typing or selecting a
date from the calendar. The (dateChange)
event will fire whenever the user finishes typing input
(on <input>
blur), or when the user chooses a date from the calendar.
As with any standard <input>
, it is possible to disable the datepicker input by adding the
disabled
property. By default, the <mat-datepicker>
and <mat-datepicker-toggle>
will inherit
their disabled state from the <input>
, but this can be overridden by setting the disabled
property on the datepicker or toggle elements. This can be useful if you want to disable text input
but allow selection via the calendar or vice-versa.
The datepicker normally opens as a popup under the input. However this is not ideal for touch
devices that don't have as much screen real estate and need bigger click targets. For this reason
<mat-datepicker>
has a touchUi
property that can be set to true
in order to enable a more
touch friendly UI where the calendar opens in a large dialog.
The calendar popup can be programmatically controlled using the open
and close
methods on the
<mat-datepicker>
. It also has an opened
property that reflects the status of the popup.
Internationalization of the datepicker is configured via four aspects:
By default, the MAT_DATE_LOCALE
injection token will use the existing LOCALE_ID
locale code
from @angular/core
. If you want to override it, you can provide a new value for the
MAT_DATE_LOCALE
token:
@NgModule({
providers: [
{provide: MAT_DATE_LOCALE, useValue: 'en-GB'},
],
})
export class MyApp {}
It's also possible to set the locale at runtime using the setLocale
method of the DateAdapter
.
The datepicker was built to be date implementation agnostic. This means that it can be made to work
with a variety of different date implementations. However it also means that developers need to make
sure to provide the appropriate pieces for the datepicker to work with their chosen implementation.
The easiest way to ensure this is just to import one of the pre-made modules:
Module | Date type | Supported locales | Dependencies | Import from |
---|---|---|---|---|
MatNativeDateModule |
Date |
en-US | None | @angular/material |
MatMomentDateModule |
Moment |
See project | Moment.js | @angular/material-moment-adapter |
Please note: MatNativeDateModule
is based off of the functionality available in JavaScript's
native Date
object, and is thus not suitable for many locales. One of the biggest shortcomings of
the native Date
object is the inability to set the parse format. We highly recommend using the
MomentDateAdapter
or a custom DateAdapter
that works with the formatting/parsing library of your
choice.
These modules include providers for DateAdapter
and MAT_DATE_FORMATS
@NgModule({
imports: [MatDatepickerModule, MatNativeDateModule],
})
export class MyApp {}
Because DateAdapter
is a generic class, MatDatepicker
and MatDatepickerInput
also need to be
made generic. When working with these classes (for example as a ViewChild
) you should include the
appropriate generic type that corresponds to the DateAdapter
implementation you are using. For
example:
@Component({...})
export class MyComponent {
@ViewChild(MatDatepicker) datepicker: MatDatepicker<Date>;
}
It is also possible to create your own DateAdapter
that works with any date format your app
requires. This is accomplished by subclassing DateAdapter
and providing your subclass as the
DateAdapter
implementation. You will also want to make sure that the MAT_DATE_FORMATS
provided
in your app are formats that can be understood by your date implementation. See
Customizing the parse and display formatsfor more
information about MAT_DATE_FORMATS
.
@NgModule({
imports: [MatDatepickerModule],
providers: [
{provide: DateAdapter, useClass: MyDateAdapter},
{provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS},
],
})
export class MyApp {}
The MAT_DATE_FORMATS
object is just a collection of formats that the datepicker uses when parsing
and displaying dates. These formats are passed through to the DateAdapter
so you will want to make
sure that the format objects you're using are compatible with the DateAdapter
used in your app.
If you want use one of the DateAdapters
that ships with Angular Material, but use your own
MAT_DATE_FORMATS
, you can import the NativeDateModule
or MomentDateModule
. These modules are
identical to the "Mat"-prefixed versions (MatNativeDateModule
and MatMomentDateModule
) except
they do not include the default formats. For example:
@NgModule({
imports: [MatDatepickerModule, NativeDateModule],
providers: [
{provide: MAT_DATE_FORMATS, useValue: MY_NATIVE_DATE_FORMATS},
],
})
export class MyApp {}
The header section of the calendar (the part containing the view switcher and previous and next
buttons) can be replaced with a custom component if desired. This is accomplished using the
calendarHeaderComponent
property of <mat-datepicker>
. It takes a component class and constructs
an instance of the component to use as the header.
In order to interact with the calendar in your custom header component, you can inject the parent
MatCalendar
in the constructor. To make sure your header stays in sync with the calendar,
subscribe to the stateChanges
observable of the calendar and mark your header component for change
detection.
The various text strings used by the datepicker are provided through MatDatepickerIntl
.
Localization of these messages can be done by providing a subclass with translated values in your
application root module.
@NgModule({
imports: [MatDatepickerModule, MatNativeDateModule],
providers: [
{provide: MatDatepickerIntl, useClass: MyIntl},
],
})
export class MyApp {}
The MatDatepickerInput
directive adds aria-haspopup
attribute to the native input element, and it
triggers a calendar dialog with role="dialog"
.
MatDatepickerIntl
includes strings that are used for aria-label
s. The datepicker input
should have a placeholder or be given a meaningful label via aria-label
, aria-labelledby
or
MatDatepickerIntl
.
The datepicker supports the following keyboard shortcuts:
Shortcut | Action |
---|---|
ALT + DOWN_ARROW |
Open the calendar pop-up |
ESCAPE |
Close the calendar pop-up |
In month view:
Shortcut | Action |
---|---|
LEFT_ARROW |
Go to previous day |
RIGHT_ARROW |
Go to next day |
UP_ARROW |
Go to same day in the previous week |
DOWN_ARROW |
Go to same day in the next week |
HOME |
Go to the first day of the month |
END |
Go to the last day of the month |
PAGE_UP |
Go to the same day in the previous month |
ALT + PAGE_UP |
Go to the same day in the previous year |
PAGE_DOWN |
Go to the same day in the next month |
ALT + PAGE_DOWN |
Go to the same day in the next year |
ENTER |
Select current date |
In year view:
Shortcut | Action |
---|---|
LEFT_ARROW |
Go to previous month |
RIGHT_ARROW |
Go to next month |
UP_ARROW |
Go up a row (back 4 months) |
DOWN_ARROW |
Go down a row (forward 4 months) |
HOME |
Go to the first month of the year |
END |
Go to the last month of the year |
PAGE_UP |
Go to the same month in the previous year |
ALT + PAGE_UP |
Go to the same month 10 years back |
PAGE_DOWN |
Go to the same month in the next year |
ALT + PAGE_DOWN |
Go to the same month 10 years forward |
ENTER |
Select current month |
In multi-year view:
Shortcut | Action |
---|---|
LEFT_ARROW |
Go to previous year |
RIGHT_ARROW |
Go to next year |
UP_ARROW |
Go up a row (back 4 years) |
DOWN_ARROW |
Go down a row (forward 4 years) |
HOME |
Go to the first year in the current range |
END |
Go to the last year in the current range |
PAGE_UP |
Go back 24 years |
ALT + PAGE_UP |
Go back 240 years |
PAGE_DOWN |
Go forward 24 years |
ALT + PAGE_DOWN |
Go forward 240 years |
ENTER |
Select current year |
This error is thrown if you have not provided all of the injectables the datepicker needs to work.
The easiest way to resolve this is to import the MatNativeDateModule
or MatMomentDateModule
in
your application's root module. See
Choosing a date implementation) for
more information.
This error is thrown if more than one <input>
tries to claim ownership over the same
<mat-datepicker>
(via the matDatepicker
attribute on the input). A datepicker can only be
associated with a single input.
This error occurs if your <mat-datepicker>
is not associated with any <input>
. To associate an
input with your datepicker, create a template reference for the datepicker and assign it to the
matDatepicker
attribute on the input:
<input [matDatepicker]="picker">
<mat-datepicker #picker></mat-datepicker>
<mat-card>
is a content container for text, photos, and actions in the context of a single subject.
The most basic card needs only an <mat-card>
element with some content. However, Angular Material
provides a number of preset sections that you can use inside of an <mat-card>
:
Element | Description |
---|---|
<mat-card-title> |
Card title |
<mat-card-subtitle> |
Card subtitle |
<mat-card-content> |
Primary card content. Intended for blocks of text |
<img mat-card-image> |
Card image. Stretches the image to the container width |
<mat-card-actions> |
Container for buttons at the bottom of the card |
<mat-card-footer> |
Section anchored to the bottom of the card |
These elements primary serve as pre-styled content containers without any additional APIs.
However, the align
property on <mat-card-actions>
can be used to position the actions at the
'start'
or 'end'
of the container.
In addition to the aforementioned sections, <mat-card-header>
gives the ability to add a rich
header to a card. This header can contain:
Element | Description |
---|---|
<mat-card-title> |
A title within the header |
<mat-card-subtitle> |
A subtitle within the header |
<img mat-card-avatar> |
An image used as an avatar within the header |
<mat-card-title-group>
can be used to combine a title, subtitle, and image into a single section.
This element can contain:
<mat-card-title>
<mat-card-subtitle>
<img mat-card-sm-image>
<img mat-card-md-image>
<img mat-card-lg-image>
Cards can be used in a wide variety of scenarios and can contain many different types of content.
Due to this dynamic nature, the appropriate accessibility treatment depends on how <mat-card>
is
used.
There are several ARIA roles that communicate that a portion of the UI represents some semantically
meaningful whole. Depending on what the content of the card means to your application,
role="group"
, role="region"
, or [one of the landmark roles][3] should typically be
applied to the <mat-card>
element.
A role is not necessary when the card is used as a purely decorative container that does not
convey a meaningful grouping of related content for a single subject. In these cases, the content
of the card should follow standard practices for document content.
Depending on how cards are used, it may be appropriate to apply a tabindex
to the <mat-card>
element. If cards are a primary mechanism through which user interact with the application,
tabindex="0"
is appropriate. If attention can be sent to the card, but it's not part of the
document flow, tabindex="-1"
is appropriate.
If the card acts as a purely decorative container, it does not need to be tabbable. In this case,
the card content should follow normal best practices for tab order.
matInput
is a directive that allows native <input>
and <textarea>
elements to work with
<mat-form-field>
.
<input>
and <textarea>
attributesAll of the attributes that can be used with normal <input>
and <textarea>
elements can be used
on elements inside <mat-form-field>
as well. This includes Angular directives such as ngModel
and formControl
.
The only limitation is that the type
attribute can only be one of the values supported by
matInput
.
<input>
typesThe following input types can
be used with matInput
:
There are a number of <mat-form-field>
features that can be used with any <input matInput>
or
<textarea matInput>
. These include error messages, hint text, prefix & suffix, and theming. For
additional information about these features, see the
form field documentation.
The placeholder is text shown when the <mat-form-field>
label is floating but the input is empty.
It is used to give the user an additional hint about what they should type in the input. The
placeholder can be specified by setting the placeholder
attribute on the <input>
or <textarea>
element. In some cases that <mat-form-field>
may use the placeholder as the label (see the
form field label documentation).
The <mat-form-field>
allows you to
associate error messages
with your matInput
. By default, these error messages are shown when the control is invalid and
either the user has interacted with (touched) the element or the parent form has been submitted. If
you wish to override this behavior (e.g. to show the error as soon as the invalid control is dirty
or when a parent form group is invalid), you can use the errorStateMatcher
property of the
matInput
. The property takes an instance of an ErrorStateMatcher
object. An ErrorStateMatcher
must implement a single method isErrorState
which takes the FormControl
for this matInput
as
well as the parent form and returns a boolean indicating whether errors should be shown. (true
indicating that they should be shown, and false
indicating that they should not.)
A global error state matcher can be specified by setting the ErrorStateMatcher
provider. This
applies to all inputs. For convenience, ShowOnDirtyErrorStateMatcher
is available in order to
globally cause input errors to show when the input is dirty and invalid.
@NgModule({
providers: [
{provide: ErrorStateMatcher, useClass: ShowOnDirtyErrorStateMatcher}
]
})
<textarea>
elements<textarea>
elements can be made to automatically resize by using the
cdkAutosizeTextarea
directive
available in the CDK.
<input>
The CDK provides
utilities
for detecting when an input becomes autofilled and changing the appearance of the autofilled state.
The matInput
directive works with native <input>
to provide an accessible experience.
If the containing <mat-form-field>
has a label it will automatically be used as the aria-label
for the <input>
. However, if there's no label specified in the form field, aria-label
,
aria-labelledby
or <label for=...>
should be added.
Any mat-error
and mat-hint
are automatically added to the input's aria-describedby
list, and
aria-invalid
is automatically updated based on the input's validity state.
This error is thrown when you attempt to set an input's type
property to a value that isn't
supported by the matInput
directive. If you need to use an unsupported input type with
<mat-form-field>
consider writing a
custom form field control
for it.
CDK stepper provides a foundation upon which more concrete stepper varities can be built. A
stepper is a wizard-like workflow that divides content into logical steps
The base CDK version of the stepper primarily manages which step is active. This includes handling
keyboard interactions and exposing an API for advancing or rewinding through the workflow.
A stepper marked as linear
requires the user to complete previous steps before proceeding.
For each step, the stepControl
attribute can be set to the top level AbstractControl
that
is used to check the validity of the step.
There are two possible approaches. One is using a single form for stepper, and the other is
using a different form for each step.
Alternatively, if you don't want to use the Angular forms, you can pass in the completed
property
to each of the steps which won't allow the user to continue until it becomes true
. Note that if
both completed
and stepControl
are set, the stepControl
will take precedence.
When using a single form for the stepper, any intermediate next/previous buttons within the steps
must be set to type="button"
in order to prevent submission of the form before all steps are
complete.
When using a form for each step, the workflow is advanced whenever one of the forms is submitted.
If completion of a step in linear stepper is not required, then the optional
attribute can be set
on CdkStep
in a linear
stepper.
By default, steps are editable, which means users can return to previously completed steps and
edit their responses. editable="true"
can be set on CdkStep
to change the default.
By default, the completed
attribute of a step returns true
if the step is valid (in case of
linear stepper) and the user has interacted with the step. The user, however, can also override
this default completed
behavior by setting the completed
attribute as needed.
There are two button directives to support navigation between different steps:
CdkStepperNext
and CdkStepperPrevious
. When placed inside of a step, these will automatically
add click handlers to advance or rewind the workflow, respectively.
If you want to reset a stepper to its initial state, you can use the reset
method. Note that
resetting it will call reset
on the underlying form control which clears the value.
The CDK stepper is treated as a tabbed view for accessibility purposes, so it is given
role="tablist"
by default. The header of step that can be clicked to select the step
is given role="tab"
, and the content that can be expanded upon selection is given
role="tabpanel"
. aria-selected
attribute of step header and aria-expanded
attribute of
step content is automatically set based on step selection change.
The stepper and each step should be given a meaningful label via aria-label
or aria-labelledby
.
The bidi
package provides a common system for components to get and respond to change in the
application's LTR/RTL layout direction.
When including the CDK's BidiModule
, components can inject Directionality
to get the current
text direction (RTL or LTR);
@Component({ ... })
export class MyWidget implements OnDestroy {
/** Whether the widget is in RTL mode or not. */
private isRtl: boolean;
/** Subscription to the Directionality change EventEmitter. */
private _dirChangeSubscription = Subscription.EMPTY;
constructor(dir: Directionality) {
this.isRtl = dir.value === 'rtl';
_dirChangeSubscription = dir.change.subscribe(() => {
this.flipDirection();
});
}
ngOnDestroy() {
this._dirChangeSubscription.unsubscribe();
}
}
Dir
directiveThe BidiModule
also includes a directive that matches any elements with a dir
attribute. This
directive has the same API as Directionality and provides itself as Directionality
. By doing
this, any component that injects Directionality
will get the closest ancestor layout direction
context.
<iwe7-square width="30" color="red"></iwe7-square>
The MatDialog
service can be used to open modal dialogs with Material Design styling and
animations.
A dialog is opened by calling the open
method with a component to be loaded and an optional
config object. The open
method will return an instance of MatDialogRef
:
let dialogRef = dialog.open(UserProfileComponent, {
height: '400px',
width: '600px',
});
The MatDialogRef
provides a handle on the opened dialog. It can be used to close the dialog and to
receive notification when the dialog has been closed.
dialogRef.afterClosed().subscribe(result => {
console.log(`Dialog result: ${result}`); // Pizza!
});
dialogRef.close('Pizza!');
Components created via MatDialog
can inject MatDialogRef
and use it to close the dialog
in which they are contained. When closing, an optional result value can be provided. This result
value is forwarded as the result of the afterClosed
promise.
@Component({/* ... */})
export class YourDialog {
constructor(public dialogRef: MatDialogRef<YourDialog>) { }
closeDialog() {
this.dialogRef.close('Pizza!');
}
}
Default dialog options can be specified by providing an instance of MatDialogConfig
for
MAT_DIALOG_DEFAULT_OPTIONS in your application's root module.
@NgModule({
providers: [
{provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: {hasBackdrop: false}}
]
})
If you want to share data with your dialog, you can use the data
option to pass information to the dialog component.
let dialogRef = dialog.open(YourDialog, {
data: { name: 'austin' },
});
To access the data in your dialog component, you have to use the MAT_DIALOG_DATA injection token:
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA} from '@angular/material';
@Component({
selector: 'your-dialog',
template: 'passed in {{ data.name }}',
})
export class YourDialog {
constructor(@Inject(MAT_DIALOG_DATA) public data: any) { }
}
Several directives are available to make it easier to structure your dialog content:
Name | Description |
---|---|
mat-dialog-title |
[Attr] Dialog title, applied to a heading element (e.g., <h1> , <h2> ) |
<mat-dialog-content> |
Primary scrollable content of the dialog |
<mat-dialog-actions> |
Container for action buttons at the bottom of the dialog |
mat-dialog-close |
[Attr] Added to a <button> , makes the button close the dialog with an optional result from the bound value. |
For example:
<h2 mat-dialog-title>Delete all</h2>
<mat-dialog-content>Are you sure?</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close>No</button>
<!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. -->
<button mat-button [mat-dialog-close]="true">Yes</button>
</mat-dialog-actions>
Once a dialog opens, the dialog will automatically focus the first tabbable element.
You can control which elements are tab stops with the tabindex
attribute
<button mat-button tabindex="-1">Not Tabbable</button>
entryComponents
Because MatDialog
instantiates components at run-time, the Angular compiler needs extra
information to create the necessary ComponentFactory
for your dialog content component.
For any component loaded into a dialog, you must include your component class in the list of
entryComponents
in your NgModule definition so that the Angular compiler knows to create
the ComponentFactory
for it.
@NgModule({
imports: [
// ...
MatDialogModule
],
declarations: [
AppComponent,
ExampleDialogComponent
],
entryComponents: [
ExampleDialogComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
By default, each dialog has role="dialog"
on the root element. The role can be changed to
alertdialog
via the MatDialogConfig
when opening.
The aria-label
, aria-labelledby
, and aria-describedby
attributes can all be set to the
dialog element via the MatDialogConfig
as well. Each dialog should typically have a label
set via aria-label
or aria-labelledby
.
When a dialog is opened, it will move focus to the first focusable element that it can find. In
order to prevent users from tabbing into elements in the background, the Material dialog uses
a focus trap to contain focus
within itself. Once a dialog is closed, it will return focus to the element that was focused
before the dialog was opened.
By default, the first tabbable element within the dialog will receive focus upon open. This can
be configured by setting the cdkFocusInitial
attribute on another focusable element.
Tabbing through the elements of the dialog will keep focus inside of the dialog element,
wrapping back to the first tabbable element when reaching the end of the tab sequence.
By default pressing the escape key will close the dialog. While this behavior can
be turned off via the disableClose
option, users should generally avoid doing so
as it breaks the expected interaction pattern for screen-reader users.
The autocomplete is a normal text input enhanced by a panel of suggested options.
Start by adding a regular matInput
to your template. Let's assume you're using the formControl
directive from ReactiveFormsModule
to track the value of the input.
Note: It is possible to use template-driven forms instead, if you prefer. We use reactive forms
in this example because it makes subscribing to changes in the input's value easy. For this
example, be sure to importReactiveFormsModule
from@angular/forms
into yourNgModule
.
If you are unfamiliar with using reactive forms, you can read more about the subject in the
Angular documentation.
my-comp.html
<mat-form-field>
<input type="text" matInput [formControl]="myControl">
</mat-form-field>
Next, create the autocomplete panel and the options displayed inside it. Each option should be
defined by an mat-option
tag. Set each option's value property to whatever you'd like the value
of the text input to be upon that option's selection.
my-comp.html
<mat-autocomplete>
<mat-option *ngFor="let option of options" [value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
Now we'll need to link the text input to its panel. We can do this by exporting the autocomplete
panel instance into a local template variable (here we called it "auto"), and binding that variable
to the input's matAutocomplete
property.
my-comp.html
<mat-form-field>
<input type="text" matInput [formControl]="myControl" [matAutocomplete]="auto">
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of options" [value]="option">{{option}}</mat-option>
</mat-autocomplete>
At this point, the autocomplete panel should be toggleable on focus and options should be
selectable. But if we want our options to filter when we type, we need to add a custom filter.
You can filter the options in any way you like based on the text input*. Here we will perform a
simple string test on the option value to see if it matches the input value, starting from the
option's first letter. We already have access to the built-in valueChanges
Observable on the
FormControl
, so we can simply map the text input's values to the suggested options by passing
them through this filter. The resulting Observable, filteredOptions
, can be added to the
template in place of the options
property using the async
pipe.
Below we are also priming our value change stream with an empty string so that the options are
filtered by that value on init (before there are any value changes).
*For optimal accessibility, you may want to consider adding text guidance on the page to explain
filter criteria. This is especially helpful for screenreader users if you're using a non-standard
filter that doesn't limit matches to the beginning of the string.
If you want the option's control value (what is saved in the form) to be different than the option's
display value (what is displayed in the text field), you'll need to set the displayWith
property on your autocomplete element. A common use case for this might be if you want to save your
data as an object, but display just one of the option's string properties.
To make this work, create a function on your component class that maps the control value to the
desired display value. Then bind it to the autocomplete's displayWith
property.
If your use case requires for the first autocomplete option to be highlighted when the user opens
the panel, you can do so by setting the autoActiveFirstOption
input on the mat-autocomplete
component. This behavior can be configured globally using the MAT_AUTOCOMPLETE_DEFAULT_OPTIONS
injection token.
By default the autocomplete panel will be attached to your input element, however in some cases you
may want it to attach to a different container element. You can change the element that the
autocomplete is attached to using the matAutocompleteOrigin
directive together with the
matAutocompleteConnectedTo
input:
<div class="custom-wrapper-example" matAutocompleteOrigin #origin="matAutocompleteOrigin">
<input
matInput
[formControl]="myControl"
[matAutocomplete]="auto"
[matAutocompleteConnectedTo]="origin">
</div>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of options" [value]="option">{{option}}</mat-option>
</mat-autocomplete>
mat-option
can be collected into groups using the mat-optgroup
element:
<mat-autocomplete #auto="matAutocomplete">
<mat-optgroup *ngFor="let group of filteredGroups | async" [label]="group.name">
<mat-option *ngFor="let option of group.options" [value]="option">
{{option.name}}
</mat-option>
</mat-optgroup>
</mat-autocomplete>
The input for an autocomplete without text or labels should be given a meaningful label via
aria-label
or aria-labelledby
.
The autocomplete trigger is given role="combobox"
. The trigger sets aria-owns
to the
autocomplete's id, and sets aria-activedescendant
to the active option's id.
<mat-chip-list>
displays a list of values as individual, keyboard accessible, chips.
<mat-chip-list>
<mat-chip>Papadum</mat-chip>
<mat-chip>Naan</mat-chip>
<mat-chip>Dal</mat-chip>
</mat-chip-list>
By default, <mat-chip>
has Material Design styles applied. For a chip with no styles applied,
use <mat-basic-chip>
. You can then customize the chip appearance by adding your own CSS.
Hint: <mat-basic-chip>
receives the mat-basic-chip
CSS class in addition to the mat-chip
class.
Chips can be selected via the selected
property. Selection can be disabled by setting
selectable
to false
on the <mat-chip-list>
.
Whenever the selection state changes, a ChipSelectionChange
event will be emitted via
(selectionChange)
.
Individual chips may be disabled by applying the disabled
attribute to the chip. When disabled,
chips are neither selectable nor focusable. Currently, disabled chips receive no special styling.
The MatChipInput
directive can be used together with a chip-list to streamline the interaction
between the two components. This directive adds chip-specific behaviors to the input element
within <mat-form-field>
for adding and removing chips. The <input>
with MatChipInput
can
be placed inside or outside the chip-list element.
An example of chip input placed inside the chip-list element.
An example of chip input placed outside the chip-list element.
<mat-form-field>
<mat-chip-list #chipList>
<mat-chip>Chip 1</mat-chip>
<mat-chip>Chip 2</mat-chip>
</mat-chip-list>
<input [matChipInputFor]="chipList">
</mat-form-field>
An example of chip input with an autocomplete placed inside the chip-list element.
Users can move through the chips using the arrow keys and select/deselect them with the space. Chips
also gain focus when clicked, ensuring keyboard navigation starts at the appropriate chip.
If you want the chips in the list to be stacked vertically, instead of horizontally, you can apply
the mat-chip-list-stacked
class, as well as the aria-orientation="vertical"
attribute:
<mat-chip-list class="mat-chip-list-stacked" aria-orientation="vertical">
<mat-chip>Papadum</mat-chip>
<mat-chip>Naan</mat-chip>
<mat-chip>Dal</mat-chip>
</mat-chip-list>
Default options for the chips module can be specified using the MAT_CHIPS_DEFAULT_OPTIONS
injection token.
@NgModule({
providers: [
{
provide: MAT_CHIPS_DEFAULT_OPTIONS,
useValue: {
separatorKeyCodes: [ENTER, COMMA]
}
}
]
})
The selected color of an <mat-chip>
can be changed by using the color
property. By default, chips
use a neutral background color based on the current theme (light or dark). This can be changed to
'primary'
, 'accent'
, or 'warn'
.
A chip-list behaves as a role="listbox"
, with each chip being a role="option"
. The chip input
should have a placeholder or be given a meaningful label via aria-label
or aria-labelledby
.
FormsModule
<mat-button-toggle>
are on/off toggles with the appearance of a button. These toggles can be
configured to behave as either radio-buttons or checkboxes. While they can be standalone, they are
typically part of a mat-button-toggle-group
.
By default, mat-button-toggle-group
acts like a radio-button group- only one item can be selected.
In this mode, the value
of the mat-button-toggle-group
will reflect the value of the selected
button and ngModel
is supported.
Adding the multiple
attribute allows multiple items to be selected (checkbox behavior). In this
mode the values of the the toggles are not used, the mat-button-toggle-group
does not have a value,
and ngModel
is not supported.
The button-toggles will present themselves as either checkboxes or radio-buttons based on the
presence of the multiple
attribute.
For button toggles containing only icons, each button toggle should be given a meaningful label via
aria-label
or aria-labelledby
.
For button toggle groups, each group should be given a meaningful label via aria-label
or
aria-labelledby
.
The button-toggles can be rendered in a vertical orientation by adding the vertical
attribute.
<mat-checkbox>
provides the same functionality as a native <input type="checkbox">
enhanced with Material Design styling and animations.
The checkbox label is provided as the content to the <mat-checkbox>
element. The label can be
positioned before or after the checkbox by setting the labelPosition
property to 'before'
or
'after'
.
If you don't want the label to appear next to the checkbox, you can use
aria-label
or
aria-labelledby
to
specify an appropriate label.
@angular/forms
<mat-checkbox>
is compatible with @angular/forms
and supports both FormsModule
and ReactiveFormsModule
.
<mat-checkbox>
supports an indeterminate
state, similar to the native <input type="checkbox">
.
While the indeterminate
property of the checkbox is true, it will render as indeterminate
regardless of the checked
value. Any interaction with the checkbox by a user (i.e., clicking) will
remove the indeterminate state.
When user clicks on the mat-checkbox
, the default behavior is toggle checked
value and set
indeterminate
to false
. This behavior can be customized by
providing a new value
of MAT_CHECKBOX_CLICK_ACTION
to the checkbox.
providers: [
{provide: MAT_CHECKBOX_CLICK_ACTION, useValue: 'check'}
]
The possible values are:
noop
Do not change the checked
value or indeterminate
value. Developers have the power to
implement customized click actions.
check
Toggle checked
value of the checkbox, ignore indeterminate
value. If the
checkbox is in indeterminate
state, the checkbox will display as an indeterminate
checkbox
regardless the checked
value.
check-indeterminate
Default behavior of mat-checkbox
. Always set indeterminate
to false
when user click on the mat-checkbox
.
This matches the behavior of native <input type="checkbox">
.
The color of a <mat-checkbox>
can be changed by using the color
property. By default, checkboxes
use the theme's accent color. This can be changed to 'primary'
or 'warn'
.
The <mat-checkbox>
uses an internal <input type="checkbox">
to provide an accessible experience.
This internal checkbox receives focus and is automatically labelled by the text content of the
<mat-checkbox>
element.
Checkboxes without text or labels should be given a meaningful label via aria-label
or
aria-labelledby
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.