diff --git a/src/cdk/a11y/a11y.md b/src/cdk/a11y/a11y.md
index 548326f0bcc7..7b08ce5d9928 100644
--- a/src/cdk/a11y/a11y.md
+++ b/src/cdk/a11y/a11y.md
@@ -1,10 +1,10 @@
The `a11y` package provides a number of tools to improve accessibility, described below.
-### ListKeyManager
+## ListKeyManager
`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.
-#### Basic usage
+### Basic usage
Any component that uses a `ListKeyManager` will generally do three things:
* Create a `@ViewChildren` query for the options being managed.
* Initialize the `ListKeyManager`, passing in the options.
@@ -18,16 +18,16 @@ interface ListKeyManagerOption {
}
```
-#### Wrapping
+### Wrapping
Navigation through options can be made to wrap via the `withWrap` method
```ts
this.keyManager = new FocusKeyManager(...).withWrap();
```
-#### Types of key managers
+### Types of key managers
There are two varieties of `ListKeyManager`, `FocusKeyManager` and `ActiveDescendantKeyManager`.
-##### FocusKeyManager
+#### FocusKeyManager
Used when options will directly receive browser focus. Each item managed must implement the
`FocusableOption` interface:
```ts
@@ -36,7 +36,7 @@ interface FocusableOption extends ListKeyManagerOption {
}
```
-##### ActiveDescendantKeyManager
+#### ActiveDescendantKeyManager
Used when options will be marked as active via `aria-activedescendant`.
Each item managed must implement the
`Highlightable` interface:
@@ -50,7 +50,7 @@ interface Highlightable extends ListKeyManagerOption {
Each item must also have an ID bound to the listbox's or menu's `aria-activedescendant`.
-### FocusTrap
+## FocusTrap
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](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal), where focus must be
@@ -58,7 +58,7 @@ constrained.
This directive is declared in `A11yModule`.
-#### Example
+### Example
```html
@@ -68,7 +68,7 @@ This directive is declared in `A11yModule`.
This directive will not prevent focus from moving out of the trapped region due to mouse
interaction.
-#### Regions
+### Regions
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.
@@ -85,18 +85,18 @@ For example:
```
-### InteractivityChecker
+## InteractivityChecker
`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
+## LiveAnnouncer
`LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region.
See [the W3C's WAI-ARIA](https://www.w3.org/TR/wai-aria/states_and_properties#aria-live)
for more information on aria-live regions.
-#### Example
+### Example
```ts
@Component({...})
export class MyComponent {
@@ -106,3 +106,55 @@ export class MyComponent {
}
}
```
+
+## FocusMonitor
+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 programmatically
+* `null` indicates the element was blurred
+
+In 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.
+
+```ts
+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.
+
+
+
+### cdkMonitorElementFocus and cdkMonitorSubtreeFocus
+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.
+
+
diff --git a/src/material-examples/focus-monitor-directives/focus-monitor-directives-example.css b/src/material-examples/focus-monitor-directives/focus-monitor-directives-example.css
new file mode 100644
index 000000000000..f64065c60cea
--- /dev/null
+++ b/src/material-examples/focus-monitor-directives/focus-monitor-directives-example.css
@@ -0,0 +1,19 @@
+.example-focus-monitor {
+ padding: 20px;
+}
+
+.example-focus-monitor .cdk-mouse-focused {
+ background: rgba(255, 0, 0, 0.5);
+}
+
+.example-focus-monitor .cdk-keyboard-focused {
+ background: rgba(0, 255, 0, 0.5);
+}
+
+.example-focus-monitor .cdk-touch-focused {
+ background: rgba(0, 0, 255, 0.5);
+}
+
+.example-focus-monitor .cdk-program-focused {
+ background: rgba(255, 0, 255, 0.5);
+}
diff --git a/src/material-examples/focus-monitor-directives/focus-monitor-directives-example.html b/src/material-examples/focus-monitor-directives/focus-monitor-directives-example.html
new file mode 100644
index 000000000000..e9b22e4b536b
--- /dev/null
+++ b/src/material-examples/focus-monitor-directives/focus-monitor-directives-example.html
@@ -0,0 +1,15 @@
+