Skip to content

Commit 0f2c272

Browse files
jelbournmmalerba
authored andcommitted
chore: expand and polish cdk docs (#7675)
* Add JsDocs where missing * Adds and polishes overviews for main cdk subpackages * Tweaks dgeni to disambiguate between material and cdk output (e.g. with "table"). * Tweaks markdown process to disambiguate between material and cdk output * Fix an issue where method return types were missing from _all_ api docs * Correct some `any` property types in cdk/stepper * Correct table trackBy JsDoc being omitted because it was on the setter
1 parent dcef604 commit 0f2c272

38 files changed

+418
-103
lines changed

src/cdk/a11y/a11y.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
The `a11y` package provides a number of tools to improve accessibility, described below.
2+
3+
### ListKeyManager
4+
`ListKeyManager` manages the active option in a list of items based on keyboard interaction.
5+
Intended to be used with components that correspond to a `role="menu"` or `role="listbox"` pattern.
6+
7+
#### Basic usage
8+
Any component that uses a `ListKeyManager` will generally do three things:
9+
* Create a `@ViewChildren` query for the options being managed.
10+
* Initialize the `ListKeyManager`, passing in the options.
11+
* Forward keyboard events from the managed component to the `ListKeyManager`.
12+
13+
Each option should implement the `ListKeyManagerOption` interface:
14+
```ts
15+
interface ListKeyManagerOption {
16+
disabled?: boolean;
17+
getLabel?(): string;
18+
}
19+
```
20+
21+
#### Wrapping
22+
Navigation through options can be made to wrap via the `withWrap` method
23+
```ts
24+
this.keyManager = new FocusKeyManager(...).withWrap();
25+
```
26+
27+
#### Types of key managers
28+
There are two varieties of `ListKeyManager`, `FocusKeyManager` and `ActiveDescendantKeyManager`.
29+
30+
##### FocusKeyManager
31+
Used when options will directly receive browser focus. Each item managed must implement the
32+
`FocusableOption` interface:
33+
```ts
34+
interface FocusableOption extends ListKeyManagerOption {
35+
focus(): void;
36+
}
37+
```
38+
39+
##### ActiveDescendantKeyManager
40+
Used when options will be marked as active via `aria-activedescendant`.
41+
Each item managed must implement the
42+
`Highlightable` interface:
43+
```ts
44+
interface Highlightable extends ListKeyManagerOption {
45+
setActiveStyles(): void;
46+
setInactiveStyles(): void;
47+
}
48+
```
49+
50+
Each item must also have an ID bound to the listbox's or menu's `aria-activedescendant`.
51+
52+
53+
### FocusTrap
54+
The `cdkTrapFocus` directive traps <kbd>Tab</kbd> key focus within an element. This is intended to
55+
be used to create accessible experience for components like
56+
[modal dialogs](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal), where focus must be
57+
constrained.
58+
59+
This directive is declared in `A11yModule`.
60+
61+
#### Example
62+
```html
63+
<div class="my-inner-dialog-content" cdkTrapFocus>
64+
<!-- Tab and Shift + Tab will not leave this element. -->
65+
</div>
66+
```
67+
68+
This directive will not prevent focus from moving out of the trapped region due to mouse
69+
interaction.
70+
71+
72+
### InteractivityChecker
73+
`InteractivityChecker` is used to check the interactivity of an element, capturing disabled,
74+
visible, tabbable, and focusable states for accessibility purposes. See the API docs for more
75+
details.
76+
77+
78+
### LiveAnnouncer
79+
`LiveAnnouncer` is used to announce messages for screen-reader users using an `aria-live` region.
80+
See [the W3C's WAI-ARIA](https://www.w3.org/TR/wai-aria/states_and_properties#aria-live)
81+
for more information on aria-live regions.
82+
83+
#### Example
84+
```ts
85+
@Component({...})
86+
export class MyComponent {
87+
88+
constructor(liveAnnouncer: LiveAnnouncer) {
89+
liveAnnouncer.announce("Hey Google");
90+
}
91+
}
92+
```

src/cdk/a11y/focus-trap.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ import {InteractivityChecker} from './interactivity-checker';
2424
/**
2525
* Class that allows for trapping focus within a DOM element.
2626
*
27-
* NOTE: This class currently uses a very simple (naive) approach to focus trapping.
27+
* This class currently uses a relatively simple approach to focus trapping.
2828
* It assumes that the tab order is the same as DOM order, which is not necessarily true.
2929
* Things like tabIndex > 0, flex `order`, and shadow roots can cause to two to misalign.
30-
* This will be replaced with a more intelligent solution before the library is considered stable.
3130
*/
3231
export class FocusTrap {
3332
private _startAnchor: HTMLElement | null;
@@ -169,7 +168,7 @@ export class FocusTrap {
169168

170169
/**
171170
* Focuses the element that should be focused when the focus trap is initialized.
172-
* @returns Returns whether focus was moved successfuly.
171+
* @returns Whether focus was moved successfuly.
173172
*/
174173
focusInitialElement(): boolean {
175174
if (!this._platform.isBrowser) {
@@ -188,7 +187,7 @@ export class FocusTrap {
188187

189188
/**
190189
* Focuses the first tabbable element within the focus trap region.
191-
* @returns Returns whether focus was moved successfuly.
190+
* @returns Whether focus was moved successfuly.
192191
*/
193192
focusFirstTabbableElement(): boolean {
194193
const redirectToElement = this._getRegionBoundary('start');
@@ -202,7 +201,7 @@ export class FocusTrap {
202201

203202
/**
204203
* Focuses the last tabbable element within the focus trap region.
205-
* @returns Returns whether focus was moved successfuly.
204+
* @returns Whether focus was moved successfuly.
206205
*/
207206
focusLastTabbableElement(): boolean {
208207
const redirectToElement = this._getRegionBoundary('end');
@@ -287,14 +286,23 @@ export class FocusTrapFactory {
287286
private _platform: Platform,
288287
private _ngZone: NgZone) { }
289288

290-
create(element: HTMLElement, deferAnchors: boolean = false): FocusTrap {
291-
return new FocusTrap(element, this._platform, this._checker, this._ngZone, deferAnchors);
289+
/**
290+
* Creates a focus-trapped region around the given element.
291+
* @param element The element around which focus will be trapped.
292+
* @param deferCaptureElements Defers the creation of focus-capturing elements to be done
293+
* manually by the user.
294+
* @returns The created focus trap instance.
295+
*/
296+
create(element: HTMLElement, deferCaptureElements: boolean = false): FocusTrap {
297+
return new FocusTrap(
298+
element, this._platform, this._checker, this._ngZone, deferCaptureElements);
292299
}
293300
}
294301

295302

296303
/**
297304
* Directive for trapping focus within a region.
305+
* @docs-private
298306
* @deprecated
299307
*/
300308
@Directive({
@@ -330,6 +338,7 @@ export class FocusTrapDeprecatedDirective implements OnDestroy, AfterContentInit
330338
exportAs: 'cdkTrapFocus',
331339
})
332340
export class FocusTrapDirective implements OnDestroy, AfterContentInit {
341+
/** Underlying FocusTrap instance. */
333342
focusTrap: FocusTrap;
334343

335344
/** Whether the focus trap is active. */

src/cdk/a11y/interactivity-checker.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
import {Injectable} from '@angular/core';
1010
import {Platform} from '@angular/cdk/platform';
1111

12-
/**
13-
* The InteractivityChecker leans heavily on the ally.js accessibility utilities.
14-
* Methods like `isTabbable` are only covering specific edge-cases for the browsers which are
15-
* supported.
16-
*/
12+
13+
// The InteractivityChecker leans heavily on the ally.js accessibility utilities.
14+
// Methods like `isTabbable` are only covering specific edge-cases for the browsers which are
15+
// supported.
1716

1817
/**
1918
* Utility for checking the interactivity of an element, such as whether is is focusable or

src/cdk/a11y/list-key-manager.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import {Subscription} from 'rxjs/Subscription';
1212
import {UP_ARROW, DOWN_ARROW, TAB, A, Z, ZERO, NINE} from '@angular/cdk/keycodes';
1313
import {RxChain, debounceTime, filter, map, doOperator} from '@angular/cdk/rxjs';
1414

15-
/**
16-
* This interface is for items that can be passed to a ListKeyManager.
17-
*/
15+
/** This interface is for items that can be passed to a ListKeyManager. */
1816
export interface ListKeyManagerOption {
1917
disabled?: boolean;
2018
getLabel?(): string;

src/cdk/bidi/bidi.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
### BidiModule
1+
The `bidi` package provides a common system for components to get and respond to change in the
2+
application's LTR/RTL layout direction.
3+
4+
### Directionality
25

36
When including the CDK's `BidiModule`, components can inject `Directionality` to get the current
47
text direction (RTL or LTR);
@@ -28,3 +31,8 @@ export class MyWidget implements OnDestroy {
2831
}
2932
```
3033

34+
### The `Dir` directive
35+
The `BidiModule` also includes a directive that matches any elements with a `dir` attribute. This
36+
directive has the same API as Directionality and provides itself _as_ `Directionality`. By doing
37+
this, any component that injects `Directionality` will get the closest ancestor layout direction
38+
context.

src/cdk/bidi/dir.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {Direction, Directionality} from './directionality';
1818
/**
1919
* Directive to listen for changes of direction of part of the DOM.
2020
*
21-
* Would provide itself in case a component looks for the Directionality service
21+
* Provides itself as Directionality such that descendant directives only need to ever inject
22+
* Directionality to get the closest direction.
2223
*/
2324
@Directive({
2425
selector: '[dir]',
@@ -27,7 +28,6 @@ import {Direction, Directionality} from './directionality';
2728
exportAs: 'dir',
2829
})
2930
export class Dir implements Directionality {
30-
/** Layout direction of the element. */
3131
_dir: Direction = 'ltr';
3232

3333
/** Whether the `value` has been set to its initial value. */
@@ -38,10 +38,7 @@ export class Dir implements Directionality {
3838

3939
/** @docs-private */
4040
@Input('dir')
41-
get dir(): Direction {
42-
return this._dir;
43-
}
44-
41+
get dir(): Direction { return this._dir; }
4542
set dir(v: Direction) {
4643
let old = this._dir;
4744
this._dir = v;

src/cdk/bidi/directionality.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ export const DIR_DOCUMENT = new InjectionToken<Document>('mat-dir-doc');
3737
*/
3838
@Injectable()
3939
export class Directionality {
40+
/** The current 'ltr' or 'rtl' value. */
4041
readonly value: Direction = 'ltr';
42+
43+
/** Stream that emits whenever the 'ltr' / 'rtl' state changes. */
4144
readonly change = new EventEmitter<void>();
4245

4346
constructor(@Optional() @Inject(DIR_DOCUMENT) _document?: any) {

src/cdk/layout/breakpoints-observer.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ interface Query {
2424
mql: MediaQueryList;
2525
}
2626

27-
/**
28-
* Utility for checking the matching state of @media queries.
29-
*/
27+
/** Utility for checking the matching state of @media queries. */
3028
@Injectable()
3129
export class BreakpointObserver implements OnDestroy {
3230
/** A map of all media queries currently being listened for. */
@@ -42,7 +40,11 @@ export class BreakpointObserver implements OnDestroy {
4240
this._destroySubject.complete();
4341
}
4442

45-
/** Whether the query currently is matched. */
43+
/**
44+
* Whether one or more media queries match the current viewport size.
45+
* @param value One or more media queries to check.
46+
* @returns Whether any of the media queries match.
47+
*/
4648
isMatched(value: string | string[]): boolean {
4749
let queries = coerceArray(value);
4850
return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);
@@ -51,6 +53,7 @@ export class BreakpointObserver implements OnDestroy {
5153
/**
5254
* Gets an observable of results for the given queries that will emit new results for any changes
5355
* in matching of the given queries.
56+
* @returns A stream of matches for the given queries.
5457
*/
5558
observe(value: string | string[]): Observable<BreakpointState> {
5659
let queries = coerceArray(value);

src/cdk/layout/layout.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
The `layout` package provides utilities to build responsive UIs that react to screen-size changes.
2+
3+
### BreakpointObserver
4+
5+
`BreakpointObserver` is a utility for evaluating media queries and reacting to their changing.
6+
7+
#### Evaluate against the current viewport
8+
The `isMatched` method is used to evaluate one or more media queries against the current viewport
9+
size.
10+
```ts
11+
const isSmallScreen = breakpointObserver.isMatched('(max-width: 599px)');
12+
```
13+
14+
#### React to changes to the viewport
15+
The `observe` method is used to get an observable stream that will emit whenever one of the given
16+
media queries would have a different result.
17+
```ts
18+
const layoutChanges = breakpointObserver.observe([
19+
'(orientation: portrait)',
20+
'(orientation: landscape)',
21+
]);
22+
23+
layoutChanges.subscribe(result => {
24+
updateMyLayoutForOrientationChange();
25+
});
26+
```
27+
28+
#### Default breakpoints
29+
A set of default media queries are available corresponding to breakpoints for different device
30+
types.
31+
32+
```ts
33+
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
34+
35+
@Component({...})
36+
class MyComponent {
37+
constructor(breakpointObserver: BreakpointObserver) {
38+
breakpointObserver.observe([
39+
Breakpoints.HandsetLandscape,
40+
Breakpoints.HandsetPortrait
41+
]).subscribe(result => {
42+
if (result.matches) {
43+
this.activateHandsetLayout();
44+
}
45+
});
46+
}
47+
}
48+
```
49+
50+
The built-in breakpoints based on [Google's Material Design
51+
specification](https://material.io/guidelines/layout/responsive-ui.html#responsive-ui-breakpoints).
52+
The available values are:
53+
* Handset
54+
* Tablet
55+
* Web
56+
* HandsetPortrait
57+
* TabletPortrait
58+
* WebPortrait
59+
* HandsetLandscape
60+
* TabletLandscape
61+
* WebLandscape
62+
63+
64+
### MediaMatcher
65+
`MediaMatcher` is a lower-level utility that wraps the native `matchMedia`. This service normalizes
66+
browser differences and serves as a convenient API that can be replaces with a fake in unit tests.
67+
The `matchMedia` method can be used to get a native
68+
[`MediaQueryList`](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList).
69+
70+
```ts
71+
@Component({...})
72+
class MyComponent {
73+
constructor(mediaMatcher: MediaMatcher) {
74+
const mediaQueryList = mediaMatcher.matchMedia('(min-width: 1px)');
75+
}
76+
}
77+
```

src/cdk/layout/media-matcher.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ import {Platform} from '@angular/cdk/platform';
1313
*/
1414
const styleElementForWebkitCompatibility: Map<string, HTMLStyleElement> = new Map();
1515

16-
/**
17-
* A utility for calling matchMedia queries.
18-
*/
16+
/** A utility for calling matchMedia queries. */
1917
@Injectable()
2018
export class MediaMatcher {
2119
/** The internal matchMedia method to return back a MediaQueryList like object. */
@@ -30,6 +28,8 @@ export class MediaMatcher {
3028
}
3129

3230
/**
31+
* Evaluates the given media query and returns the native MediaQueryList from which results
32+
* can be retrieved.
3333
* Confirms the layout engine will trigger for the selector query provided and returns the
3434
* MediaQueryList for the query provided.
3535
*/

src/cdk/observers/observers.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
### Observers
1+
The `observers` package provides convenience directives built on top of native web platform
2+
observers, such as MutationObserver.
3+
4+
5+
### cdkObserveContent
26

37
A directive for observing when the content of the host element changes. An event is emitted when a
48
mutation to the content is observed.
59

6-
#### Example
7-
810
```html
911
<div class="projected-content-wrapper" (cdkObserveContent)="projectContentChanged()">
1012
<ng-content></ng-content>

0 commit comments

Comments
 (0)