-
Notifications
You must be signed in to change notification settings - Fork 6.8k
chore: expand and polish cdk docs #7675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
The `a11y` package provides a number of tools to improve accessibility, described below. | ||
|
||
### 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 | ||
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. | ||
* Forward keyboard events from the managed component to the `ListKeyManager`. | ||
|
||
Each option should implement the `ListKeyManagerOption` interface: | ||
```ts | ||
interface ListKeyManagerOption { | ||
disabled?: boolean; | ||
getLabel?(): string; | ||
} | ||
``` | ||
|
||
#### Wrapping | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a short paragraph like this for typeahead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can add in a follow-up PR. |
||
Navigation through options can be made to wrap via the `withWrap` method | ||
```ts | ||
this.keyManager = new FocusKeyManager(...).withWrap(); | ||
``` | ||
|
||
#### Types of key managers | ||
There are two varieties of `ListKeyManager`, `FocusKeyManager` and `ActiveDescendantKeyManager`. | ||
|
||
##### FocusKeyManager | ||
Used when options will directly receive browser focus. Each item managed must implement the | ||
`FocusableOption` interface: | ||
```ts | ||
interface FocusableOption extends ListKeyManagerOption { | ||
focus(): void; | ||
} | ||
``` | ||
|
||
##### ActiveDescendantKeyManager | ||
Used when options will be marked as active via `aria-activedescendant`. | ||
Each item managed must implement the | ||
`Highlightable` interface: | ||
```ts | ||
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`. | ||
|
||
|
||
### FocusTrap | ||
The `cdkTrapFocus` directive traps <kbd>Tab</kbd> 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 | ||
constrained. | ||
|
||
This directive is declared in `A11yModule`. | ||
|
||
#### Example | ||
```html | ||
<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. | ||
|
||
|
||
### 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` 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 | ||
```ts | ||
@Component({...}) | ||
export class MyComponent { | ||
|
||
constructor(liveAnnouncer: LiveAnnouncer) { | ||
liveAnnouncer.announce("Hey Google"); | ||
} | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,11 +9,10 @@ | |
import {Injectable} from '@angular/core'; | ||
import {Platform} from '@angular/cdk/platform'; | ||
|
||
/** | ||
* The InteractivityChecker leans heavily on the ally.js accessibility utilities. | ||
* Methods like `isTabbable` are only covering specific edge-cases for the browsers which are | ||
* supported. | ||
*/ | ||
|
||
// The InteractivityChecker leans heavily on the ally.js accessibility utilities. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With |
||
// Methods like `isTabbable` are only covering specific edge-cases for the browsers which are | ||
// supported. | ||
|
||
/** | ||
* Utility for checking the interactivity of an element, such as whether is is focusable or | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
The `layout` package provides utilities to build responsive UIs that react to screen-size changes. | ||
|
||
### BreakpointObserver | ||
|
||
`BreakpointObserver` is a utility for evaluating media queries and reacting to their changing. | ||
|
||
#### Evaluate against the current viewport | ||
The `isMatched` method is used to evaluate one or more media queries against the current viewport | ||
size. | ||
```ts | ||
const isSmallScreen = breakpointObserver.isMatched('(max-width: 599px)'); | ||
``` | ||
|
||
#### React to changes to the viewport | ||
The `observe` method is used to get an observable stream that will emit whenever one of the given | ||
media queries would have a different result. | ||
```ts | ||
const layoutChanges = breakpointObserver.observe([ | ||
'(orientation: portrait)', | ||
'(orientation: landscape)', | ||
]); | ||
|
||
layoutChanges.subscribe(result => { | ||
updateMyLayoutForOrientationChange(); | ||
}); | ||
``` | ||
|
||
#### Default breakpoints | ||
A set of default media queries are available corresponding to breakpoints for different device | ||
types. | ||
|
||
```ts | ||
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout'; | ||
|
||
@Component({...}) | ||
class MyComponent { | ||
constructor(breakpointObserver: BreakpointObserver) { | ||
breakpointObserver.observe([ | ||
Breakpoints.HandsetLandscape, | ||
Breakpoints.HandsetPortrait | ||
]).subscribe(result => { | ||
if (result.matches) { | ||
this.activateHandsetLayout(); | ||
} | ||
}); | ||
} | ||
} | ||
``` | ||
|
||
The built-in breakpoints based on [Google's Material Design | ||
specification](https://material.io/guidelines/layout/responsive-ui.html#responsive-ui-breakpoints). | ||
The available values are: | ||
* Handset | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should these be styled as code? i.e. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's fine without the code style |
||
* Tablet | ||
* Web | ||
* HandsetPortrait | ||
* TabletPortrait | ||
* WebPortrait | ||
* HandsetLandscape | ||
* TabletLandscape | ||
* WebLandscape | ||
|
||
|
||
### MediaMatcher | ||
`MediaMatcher` is a lower-level utility that wraps the native `matchMedia`. This service normalizes | ||
browser differences and serves as a convenient API that can be replaces with a fake in unit tests. | ||
The `matchMedia` method can be used to get a native | ||
[`MediaQueryList`](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList). | ||
|
||
```ts | ||
@Component({...}) | ||
class MyComponent { | ||
constructor(mediaMatcher: MediaMatcher) { | ||
const mediaQueryList = mediaMatcher.matchMedia('(min-width: 1px)'); | ||
} | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FocusMonitor
as wellThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add that in a follow-up PR