Skip to content

Commit

Permalink
add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba committed Oct 27, 2017
1 parent 88c703d commit bbdef2f
Show file tree
Hide file tree
Showing 30 changed files with 453 additions and 295 deletions.
171 changes: 1 addition & 170 deletions src/lib/sidenav/README.md
Original file line number Diff line number Diff line change
@@ -1,170 +1 @@
**NOTE: The <code>mat-sidenav-layout</code> element is deprecated. <code>mat-sidenav-container</code>
should be used instead.**


# MatSidenav

MatSidenav is the side navigation component for Angular Material. It is composed of two components: `<mat-sidenav-container>` and `<mat-sidenav>`.

## Screenshots

<img src="https://material.angularjs.org/material2_assets/sidenav-example.png">


## `<mat-sidenav-container>`

The parent component. Contains the code necessary to coordinate one or two sidenav and the backdrop.

## `<mat-sidenav>`

The sidenav panel.

### Bound Properties

| Name | Type | Description |
| --- | --- | --- |
| `position` | `"start"\|"end"` | The position of this sidenav. In LTR direction, `"start"` will be shown on the left, `"end"` on the right. In RTL, it is reversed. `"start"` is used by default. If there is more than 1 sidenav on either side the container will be considered invalid and none of the sidenavs will be visible or toggleable until the container is valid again. |
| `mode` | `"over"\|"push"\|"side"` | The mode or styling of the sidenav, default being `"over"`. With `"over"` the sidenav will appear above the content, and a backdrop will be shown. With `"push"` the sidenav will push the content of the `<mat-sidenav-container>` to the side, and show a backdrop over it. `"side"` will resize the content and keep the sidenav opened. Clicking the backdrop will close sidenavs that do not have `mode="side"`. |
| `opened` | `boolean` | Whether or not the sidenav is opened. Use this binding to open/close the sidenav. |

### Events

| Name | Description |
| --- | --- |
| `open-start` | Emitted when the sidenav is starting opening. This should only be used to coordinate animations. |
| `close-start` | Emitted when the sidenav is starting closing. This should only be used to coordinate animations. |
| `open` | Emitted when the sidenav is done opening. Use this for, e.g., setting focus on controls or updating state. |
| `close` | Emitted when the sidenav is done closing. |

### Methods

| Signature | Description |
| --- | --- |
| `open(): Promise<void>` | Open the sidenav. Equivalent to `opened = true`. Returns a promise that will resolve when the animation completes, or be rejected if the animation was cancelled. |
| `close(): Promise<void>` | Close the sidenav. Equivalent to `opened = false`. Returns a promise that will resolve when the animation completes, or be rejected if the animation was cancelled. |
| `toggle(): Promise<void>` | Toggle the sidenav. This is equivalent to `opened = !opened`. Returns a promise that will resolve when the animation completes, or be rejected if the animation was cancelled. |





### Notes

The `<mat-sidenav>` will resize based on its content. You can also set its width in CSS, like so:

```css
mat-sidenav {
width: 200px;
}
```

Try to avoid percent based width as `resize` events are not (yet) supported.

## Examples

Here's a simple example of using the sidenav:

```html
<app>
<mat-sidenav-container>
<mat-sidenav #start (open)="closeStartButton.focus()">
Start Sidenav.
<br>
<button mat-button #closeStartButton (click)="start.close()">Close</button>
</mat-sidenav>
<mat-sidenav #end position="end">
End Sidenav.
<button mat-button (click)="end.close()">Close</button>
</mat-sidenav>

My regular content. This will be moved into the proper DOM at runtime.
<button mat-button (click)="start.open()">Open start sidenav</button>
<button mat-button (click)="end.open()">Open end sidenav</button>

</mat-sidenav-container>
</app>
```

For a fullscreen sidenav, the recommended approach is set up the DOM such that the
`mat-sidenav-container` can naturally take up the full space:

```html
<app>
<mat-sidenav-container>
<mat-sidenav mode="side" opened="true">Drawer content</mat-sidenav>
<div class="my-content">Main content</div>
</mat-sidenav-container>
</app>
```
```css
html, body, material-app, mat-sidenav-container, .my-content {
margin: 0;
width: 100%;
height: 100%;
}
```

For a sidenav with a FAB (or other floating element), the recommended approach is to place the FAB
outside of the scrollable region and absolutely position it.

```html
<app>
<mat-sidenav-container class="my-container">
<mat-sidenav mode="side" opened="true">
<button mat-mini-fab class="my-fab">
<mat-icon>add</mat-icon>
</button>
<div class="my-scrolling-content">
Lorem ipsum dolor sit amet, pede a libero aenean phasellus, lectus metus sint ut risus,
fusce vel in pellentesque. Nisl rutrum etiam morbi consectetuer tempor magna, aenean nullam
nunc id, neque vivamus interdum sociis nulla scelerisque sem, dolor id wisi turpis magna
aliquam magna. Risus accumsan hac eget etiam donec sed, senectus erat mattis quam, tempor
vel urna occaecat cras, metus urna augue nec at. Et morbi amet dui praesent, nec eu at,
ligula ipsum dui sollicitudin, quis nisl massa viverra ligula, mauris fermentum orci arcu
enim fringilla. Arcu erat nulla in aenean lacinia ullamcorper, urna ante nam et sagittis,
tristique vehicula nibh ipsum vivamus, proin proin. Porta commodo nibh quis libero amet.
Taciti dui, sapien consectetuer.
</div>
</mat-sidenav>
<button mat-mini-fab class="my-fab">
<mat-icon>add</mat-icon>
</button>
<div class="my-scrolling-content">
Lorem ipsum dolor sit amet, pede a libero aenean phasellus, lectus metus sint ut risus, fusce
vel in pellentesque. Nisl rutrum etiam morbi consectetuer tempor magna, aenean nullam nunc id,
neque vivamus interdum sociis nulla scelerisque sem, dolor id wisi turpis magna aliquam magna.
Risus accumsan hac eget etiam donec sed, senectus erat mattis quam, tempor vel urna occaecat
cras, metus urna augue nec at. Et morbi amet dui praesent, nec eu at, ligula ipsum dui
sollicitudin, quis nisl massa viverra ligula, mauris fermentum orci arcu enim fringilla. Arcu
erat nulla in aenean lacinia ullamcorper, urna ante nam et sagittis, tristique vehicula nibh
ipsum vivamus, proin proin. Porta commodo nibh quis libero amet. Taciti dui, sapien
consectetuer.
</div>
</mat-sidenav-container>
</app>
```
```css
.my-container {
width: 500px;
height: 300px;
}

.my-container .mat-sidenav {
max-width: 200px;
}

.my-container .mat-sidenav-content,
.my-container mat-sidenav {
display: flex;
}

.my-scrolling-content {
overflow: auto;
}

button.my-fab {
position: absolute;
right: 20px;
bottom: 10px;
}
```
Please see the official documentation at https://material.angular.io/components/component/sidenav
54 changes: 35 additions & 19 deletions src/lib/sidenav/sidenav.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ use three components: `<mat-sidenav-container>` which acts as a structural conta
and sidenav, `<mat-sidenav-content>` which represents the main content, and `<mat-sidenav>` which
represents the added side content.

<!-- TODO(mmalerba): sidenav example -->
<!-- example(sidenav-overview) -->

There are also drawer components, `<mat-drawer-container>`, `<mat-drawer-content>`, and
`<mat-drawer>`, 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.

<!-- TODO(mmalerba): drawer example -->
<!-- example(sidenav-drawer-overview) -->

### Specifying the main and side content

Expand All @@ -32,7 +32,9 @@ 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.
of it.

<!-- example(sidenav-position) -->

The following are examples of valid sidenav layouts:

Expand All @@ -55,7 +57,7 @@ The following are examples of valid sidenav layouts:
<mat-sidenav-container></mat-sidenav-container>
```

Anf these are examples of invalid sidenav layouts:
And these are examples of invalid sidenav layouts:

```html
<mat-sidenav-container>
Expand Down Expand Up @@ -90,7 +92,7 @@ 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.

<!-- TODO(mmalerba): open/close example -->
<!-- example(sidenav-open-close) -->

All of these properties and methods work on `<mat-drawer>` as well.

Expand All @@ -100,13 +102,13 @@ The `<mat-sidenav>` can render in one of three different ways based on the `mode

| 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. |
| `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.

<!-- TODO(mmalerba): modes example -->
<!-- example(sidenav-mode) -->

`<mat-drawer>` also supports all of these same modes.

Expand All @@ -120,7 +122,7 @@ Custom handling for <kbd>Esc</kbd> can be done by adding a keydown listener to t
Custom handling for backdrop clicks can be done via the `(backdropClick)` output property on
`<mat-sidenav-container>`.

<!-- TODO(mmalerba): autoclose example -->
<!-- example(sidenav-disable-close) -->

### Setting the sidenav's size

Expand All @@ -142,21 +144,35 @@ setting the `fixedInViewport` property. Additionally, top and bottom space can b
`fixedTopGap` and `fixedBottomGap`. These properties accept a pixel value amount of space to add at
the top or bottom.

<!-- TODO(mmalerba): fixed example -->
<!-- example(sidenav-fixed) -->

### Common layout patterns
### Creating a responsive layout for mobile & desktop

<!-- TODO(mmalerba): fill out -->
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.

#### Full-height sidenav
#### Sidenav under toolbar
#### Mobile sidenav
#### Responsive sidenav
<!-- example(sidenav-responsive) -->

### Accessibility

<!-- TODO(mmalerba): fill out -->
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-contnet>` 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.

### Troubleshooting

<!-- TODO(mmalerba): fill out -->
#### Error: A drawer was already declared for 'position="..."'

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"`.
60 changes: 54 additions & 6 deletions src/material-examples/example-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,14 @@ import {SelectOverviewExample} from './select-overview/select-overview-example';
import {SelectPanelClassExample} from './select-panel-class/select-panel-class-example';
import {SelectResetExample} from './select-reset/select-reset-example';
import {SelectValueBindingExample} from './select-value-binding/select-value-binding-example';
import {SidenavFabExample} from './sidenav-fab/sidenav-fab-example';
import {SidenavDisableCloseExample} from './sidenav-disable-close/sidenav-disable-close-example';
import {SidenavDrawerOverviewExample} from './sidenav-drawer-overview/sidenav-drawer-overview-example';
import {SidenavFixedExample} from './sidenav-fixed/sidenav-fixed-example';
import {SidenavModeExample} from './sidenav-mode/sidenav-mode-example';
import {SidenavOpenCloseExample} from './sidenav-open-close/sidenav-open-close-example';
import {SidenavOverviewExample} from './sidenav-overview/sidenav-overview-example';
import {SidenavPositionExample} from './sidenav-position/sidenav-position-example';
import {SidenavResponsiveExample} from './sidenav-responsive/sidenav-responsive-example';
import {SlideToggleConfigurableExample} from './slide-toggle-configurable/slide-toggle-configurable-example';
import {SlideToggleFormsExample} from './slide-toggle-forms/slide-toggle-forms-example';
import {SlideToggleOverviewExample} from './slide-toggle-overview/slide-toggle-overview-example';
Expand Down Expand Up @@ -612,18 +618,54 @@ export const EXAMPLE_COMPONENTS = {
additionalFiles: null,
selectorName: null
},
'sidenav-fab': {
title: 'Sidenav with a FAB',
component: SidenavFabExample,
'sidenav-disable-close': {
title: 'Sidenav with custom escape and backdrop click behavior ',
component: SidenavDisableCloseExample,
additionalFiles: null,
selectorName: null
},
'sidenav-drawer-overview': {
title: 'Basic drawer ',
component: SidenavDrawerOverviewExample,
additionalFiles: null,
selectorName: null
},
'sidenav-fixed': {
title: 'Fixed sidenav ',
component: SidenavFixedExample,
additionalFiles: null,
selectorName: null
},
'sidenav-mode': {
title: 'Sidenav with configurable mode ',
component: SidenavModeExample,
additionalFiles: null,
selectorName: null
},
'sidenav-open-close': {
title: 'Sidenav open & close behavior ',
component: SidenavOpenCloseExample,
additionalFiles: null,
selectorName: null
},
'sidenav-overview': {
title: 'Basic sidenav',
title: 'Basic sidenav ',
component: SidenavOverviewExample,
additionalFiles: null,
selectorName: null
},
'sidenav-position': {
title: 'Implicit main content with two sidenavs ',
component: SidenavPositionExample,
additionalFiles: null,
selectorName: null
},
'sidenav-responsive': {
title: 'Responsive sidenav ',
component: SidenavResponsiveExample,
additionalFiles: null,
selectorName: null
},
'slide-toggle-configurable': {
title: 'Configurable slide-toggle',
component: SlideToggleConfigurableExample,
Expand Down Expand Up @@ -835,8 +877,14 @@ export const EXAMPLE_LIST = [
SelectPanelClassExample,
SelectResetExample,
SelectValueBindingExample,
SidenavFabExample,
SidenavDisableCloseExample,
SidenavDrawerOverviewExample,
SidenavFixedExample,
SidenavModeExample,
SidenavOpenCloseExample,
SidenavOverviewExample,
SidenavPositionExample,
SidenavResponsiveExample,
SlideToggleConfigurableExample,
SlideToggleFormsExample,
SlideToggleOverviewExample,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.example-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
Loading

0 comments on commit bbdef2f

Please sign in to comment.