mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
docs(sidenav): update docs and add examples (#7775)
This commit is contained in:
+1
-166
@@ -1,166 +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
|
||||
|
||||
+159
-58
@@ -1,44 +1,140 @@
|
||||
`<mat-sidenav>` is a panel that can be placed next to or above some primary content. A sidenav is
|
||||
typically used for navigation, but can contain any content.
|
||||
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.
|
||||
|
||||
<!-- example(sidenav-overview) -->
|
||||
|
||||
The sidenav and its associated content live inside of an `<mat-sidenav-container>`:
|
||||
```html
|
||||
<mat-sidenav-container>
|
||||
<mat-sidenav>
|
||||
<!-- sidenav content -->
|
||||
</mat-sidenav>
|
||||
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.
|
||||
|
||||
<!-- primary content -->
|
||||
<!-- example(sidenav-drawer-overview) -->
|
||||
|
||||
### Specifying the main and side content
|
||||
|
||||
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.
|
||||
|
||||
<!-- example(sidenav-position) -->
|
||||
|
||||
The following are examples of valid sidenav layouts:
|
||||
|
||||
```html
|
||||
<!-- 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>
|
||||
```
|
||||
|
||||
A sidenav container may contain one or two `<mat-sidenav>` elements. When there are two
|
||||
`<mat-sidenav>` elements, each must be placed on a different side of the container.
|
||||
See the section on positioning below.
|
||||
```html
|
||||
<!-- 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>
|
||||
```
|
||||
|
||||
### Sidenav mode
|
||||
The sidenav can render in one of three different ways based on the `mode` property.
|
||||
```html
|
||||
<!-- Creates an empty sidenav container with no sidenavs and implicit empty content. -->
|
||||
<mat-sidenav-container></mat-sidenav-container>
|
||||
```
|
||||
|
||||
| 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 primary content |
|
||||
And these are examples of invalid sidenav layouts:
|
||||
|
||||
Using the `side` mode on mobile devices can affect the performance and is also not recommended by the
|
||||
[Material Design specification](https://material.io/guidelines/patterns/navigation-drawer.html#navigation-drawer-behavior).
|
||||
```html
|
||||
<!-- 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>
|
||||
```
|
||||
|
||||
### Positioning the sidenav
|
||||
The `position` property determines whether the sidenav appears at the `"start"` or `"end"` of the
|
||||
container. This is affected by the current text direction ("ltr" or "rtl"). By default, the sidenav
|
||||
appears at the start of the container.
|
||||
```html
|
||||
<!-- 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>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- Invalid because the `<mat-sidenav>` is outside of the `<mat-sidenav-container>`. -->
|
||||
<mat-sidenav-container></mat-sidenav-container>
|
||||
<mat-sidenav></mat-sidenav>
|
||||
```
|
||||
|
||||
### Sizing the sidenav
|
||||
The `<mat-sidenav>` will, by default, fit the size of its content. The width can be explicitly set
|
||||
via CSS:
|
||||
These same rules all apply to the drawer components as well.
|
||||
|
||||
### Opening and closing a sidenav
|
||||
|
||||
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.
|
||||
|
||||
<!-- example(sidenav-open-close) -->
|
||||
|
||||
All of these properties and methods work on `<mat-drawer>` as well.
|
||||
|
||||
### Changing the sidenav's behavior
|
||||
|
||||
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.
|
||||
|
||||
<!-- example(sidenav-mode) -->
|
||||
|
||||
`<mat-drawer>` also supports all of these same modes.
|
||||
|
||||
### Disabling automatic close
|
||||
|
||||
Clicking on the backdrop or pressing the <kbd>Esc</kbd> 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 <kbd>Esc</kbd> 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>`.
|
||||
|
||||
<!-- example(sidenav-disable-close) -->
|
||||
|
||||
### Setting the sidenav's size
|
||||
|
||||
The `<mat-sidenav>` and `<mat-drawer>` will, by default, fit the size of its content. The width can
|
||||
be explicitly set via CSS:
|
||||
|
||||
```css
|
||||
mat-sidenav {
|
||||
@@ -48,37 +144,42 @@ mat-sidenav {
|
||||
|
||||
Try to avoid percent based width as `resize` events are not (yet) supported.
|
||||
|
||||
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:
|
||||
### Fixed position sidenavs
|
||||
|
||||
```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 `<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.
|
||||
|
||||
### FABs inside sidenav
|
||||
For a sidenav with a FAB (Floating Action Button) or other floating element, the recommended approach is to place the FAB
|
||||
outside of the scrollable region and absolutely position it.
|
||||
<!-- example(sidenav-fixed) -->
|
||||
|
||||
### Creating a responsive layout for mobile & desktop
|
||||
|
||||
### Disabling closing of sidenav
|
||||
By default, sidenav can be closed either by clicking on the backdrop or by pressing <kbd>ESCAPE</kbd>.
|
||||
The `disableClose` attribute can be set on `mat-sidenav` to disable automatic closing when the backdrop
|
||||
is clicked or <kbd>ESCAPE</kbd> is pressed. To add custom logic on backdrop click, add a `(backdropClick)` listener to
|
||||
`mat-sidenav-container`. For custom <kbd>ESCAPE</kbd> logic, a standard `(keydown)` listener will suffice.
|
||||
```html
|
||||
<mat-sidenav-container (backdropClick)="customBackdropClickHandler()">
|
||||
<mat-sidenav disableClose (keydown)="customKeydownHandler($event)"></mat-sidenav>
|
||||
</mat-sidenav-container>
|
||||
```
|
||||
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.
|
||||
|
||||
<!-- example(sidenav-responsive) -->
|
||||
|
||||
### Accessibility
|
||||
|
||||
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.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### 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"`.
|
||||
|
||||
@@ -96,8 +96,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';
|
||||
@@ -620,18 +626,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,
|
||||
@@ -850,8 +892,14 @@ export const EXAMPLE_LIST = [
|
||||
SelectPanelClassExample,
|
||||
SelectResetExample,
|
||||
SelectValueBindingExample,
|
||||
SidenavFabExample,
|
||||
SidenavDisableCloseExample,
|
||||
SidenavDrawerOverviewExample,
|
||||
SidenavFixedExample,
|
||||
SidenavModeExample,
|
||||
SidenavOpenCloseExample,
|
||||
SidenavOverviewExample,
|
||||
SidenavPositionExample,
|
||||
SidenavResponsiveExample,
|
||||
SlideToggleConfigurableExample,
|
||||
SlideToggleFormsExample,
|
||||
SlideToggleOverviewExample,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.example-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<mat-sidenav-container
|
||||
class="example-container" (backdropClick)="close('backdrop')" *ngIf="shouldRun">
|
||||
<mat-sidenav #sidenav (keydown.escape)="close('escape')" disableClose>
|
||||
<p><button mat-button (click)="close('toggle button')">Toggle</button></p>
|
||||
</mat-sidenav>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<p><button mat-button (click)="sidenav.open()">Open</button></p>
|
||||
<p>Closed due to: {{reason}}</p>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
import {Component, ViewChild} from '@angular/core';
|
||||
import {MatSidenav} from '@angular/material/sidenav';
|
||||
|
||||
/** @title Sidenav with custom escape and backdrop click behavior */
|
||||
@Component({
|
||||
selector: 'sidenav-disable-close-example',
|
||||
templateUrl: 'sidenav-disable-close-example.html',
|
||||
styleUrls: ['sidenav-disable-close-example.css'],
|
||||
})
|
||||
export class SidenavDisableCloseExample {
|
||||
@ViewChild('sidenav') sidenav: MatSidenav;
|
||||
|
||||
reason = '';
|
||||
|
||||
close(reason: string) {
|
||||
this.reason = reason;
|
||||
this.sidenav.close();
|
||||
}
|
||||
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
.example-container {
|
||||
width: 400px;
|
||||
height: 200px;
|
||||
margin: 10px;
|
||||
border: 1px solid #555;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<mat-drawer-container class="example-container">
|
||||
<mat-drawer mode="side" opened="true">Drawer content</mat-drawer>
|
||||
<mat-drawer-content>Main content</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
@@ -0,0 +1,9 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
/** @title Basic drawer */
|
||||
@Component({
|
||||
selector: 'sidenav-drawer-overview-example',
|
||||
templateUrl: 'sidenav-drawer-overview-example.html',
|
||||
styleUrls: ['sidenav-drawer-overview-example.css'],
|
||||
})
|
||||
export class SidenavDrawerOverviewExample {}
|
||||
@@ -1,26 +0,0 @@
|
||||
.example-sidenav-fab-container {
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.example-sidenav-fab-container mat-sidenav {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.example-sidenav-fab-container .mat-sidenav-content,
|
||||
.example-sidenav-fab-container mat-sidenav {
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.example-scrolling-content {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.example-fab.mat-mini-fab {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 10px;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<mat-sidenav-container class="example-sidenav-fab-container">
|
||||
<mat-sidenav #sidenav mode="side" opened="true">
|
||||
<button mat-mini-fab class="example-fab" (click)="sidenav.toggle()">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
<div class="example-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="example-fab" (click)="sidenav.toggle()">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
<div class="example-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>
|
||||
@@ -1,13 +0,0 @@
|
||||
import {Component, ViewEncapsulation} from '@angular/core';
|
||||
|
||||
/**
|
||||
* @title Sidenav with a FAB
|
||||
*/
|
||||
@Component({
|
||||
selector: 'sidenav-fab-example',
|
||||
templateUrl: 'sidenav-fab-example.html',
|
||||
styleUrls: ['sidenav-fab-example.css'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
preserveWhitespaces: false,
|
||||
})
|
||||
export class SidenavFabExample {}
|
||||
@@ -0,0 +1,29 @@
|
||||
.example-container {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
bottom: 60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.example-sidenav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 200px;
|
||||
background: rgba(255, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.example-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.example-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<ng-container *ngIf="shouldRun">
|
||||
<mat-toolbar class="example-header">Header</mat-toolbar>
|
||||
|
||||
<mat-sidenav-container class="example-container">
|
||||
<mat-sidenav #sidenav mode="side" opened="true" class="example-sidenav"
|
||||
[fixedInViewport]="options.value.fixed" [fixedTopGap]="options.value.top"
|
||||
[fixedBottomGap]="options.value.bottom">
|
||||
{{options.value.fixed ? 'Fixed' : 'Non-fixed'}} Sidenav
|
||||
</mat-sidenav>
|
||||
|
||||
<mat-sidenav-content [formGroup]="options">
|
||||
<p><mat-checkbox formControlName="fixed">Fixed</mat-checkbox></p>
|
||||
<p><mat-form-field>
|
||||
<input matInput type="number" formControlName="top" placeholder="Top gap">
|
||||
</mat-form-field></p>
|
||||
<p><mat-form-field>
|
||||
<input matInput type="number" formControlName="bottom" placeholder="Bottom gap">
|
||||
</mat-form-field></p>
|
||||
<p><button mat-button (click)="sidenav.toggle()">Toggle</button></p>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
||||
<mat-toolbar class="example-footer">Footer</mat-toolbar>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {FormBuilder, FormGroup} from '@angular/forms';
|
||||
|
||||
/** @title Fixed sidenav */
|
||||
@Component({
|
||||
selector: 'sidenav-fixed-example',
|
||||
templateUrl: 'sidenav-fixed-example.html',
|
||||
styleUrls: ['sidenav-fixed-example.css'],
|
||||
})
|
||||
export class SidenavFixedExample {
|
||||
options: FormGroup;
|
||||
|
||||
constructor(fb: FormBuilder) {
|
||||
this.options = fb.group({
|
||||
'fixed': false,
|
||||
'top': 0,
|
||||
'bottom': 0,
|
||||
});
|
||||
}
|
||||
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
.example-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.example-radio-group {
|
||||
display: block;
|
||||
border: 1px solid #555;
|
||||
margin: 20px;
|
||||
padding: 10px;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<mat-sidenav-container class="example-container" *ngIf="shouldRun">
|
||||
<mat-sidenav #sidenav [mode]="mode.value">
|
||||
<p><button mat-button (click)="sidenav.toggle()">Toggle</button></p>
|
||||
<p>
|
||||
<mat-radio-group class="example-radio-group" [formControl]="mode">
|
||||
<label>Mode:</label>
|
||||
<mat-radio-button value="over">Over</mat-radio-button>
|
||||
<mat-radio-button value="side">Side</mat-radio-button>
|
||||
<mat-radio-button value="push">Push</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</p>
|
||||
</mat-sidenav>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<p><button mat-button (click)="sidenav.toggle()">Toggle</button></p>
|
||||
<p>
|
||||
<mat-radio-group class="example-radio-group" [formControl]="mode">
|
||||
<label>Mode:</label>
|
||||
<mat-radio-button value="over">Over</mat-radio-button>
|
||||
<mat-radio-button value="side">Side</mat-radio-button>
|
||||
<mat-radio-button value="push">Push</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</p>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
@@ -0,0 +1,14 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {FormControl} from '@angular/forms';
|
||||
|
||||
/** @title Sidenav with configurable mode */
|
||||
@Component({
|
||||
selector: 'sidenav-mode-example',
|
||||
templateUrl: 'sidenav-mode-example.html',
|
||||
styleUrls: ['sidenav-mode-example.css'],
|
||||
})
|
||||
export class SidenavModeExample {
|
||||
mode = new FormControl('over');
|
||||
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
.example-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.example-events {
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
border: 1px solid #555;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<mat-sidenav-container class="example-container" *ngIf="shouldRun">
|
||||
<mat-sidenav #sidenav mode="side" [(opened)]="opened" (opened)="events.push('open!')"
|
||||
(closed)="events.push('close!')">
|
||||
Sidenav content
|
||||
</mat-sidenav>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<p><mat-checkbox [(ngModel)]="opened">sidenav.opened</mat-checkbox></p>
|
||||
<p><button mat-button (click)="sidenav.toggle()">sidenav.toggle()</button></p>
|
||||
<p>Events:</p>
|
||||
<div class="example-events">
|
||||
<div *ngFor="let e of events">{{e}}</div>
|
||||
</div>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
@@ -0,0 +1,13 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
/** @title Sidenav open & close behavior */
|
||||
@Component({
|
||||
selector: 'sidenav-open-close-example',
|
||||
templateUrl: 'sidenav-open-close-example.html',
|
||||
styleUrls: ['sidenav-open-close-example.css'],
|
||||
})
|
||||
export class SidenavOpenCloseExample {
|
||||
events = [];
|
||||
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
@@ -1,16 +1,7 @@
|
||||
.example-container {
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.example-sidenav-content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.example-sidenav {
|
||||
padding: 20px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<mat-sidenav-container class="example-container">
|
||||
<mat-sidenav #sidenav class="example-sidenav">
|
||||
Jolly good!
|
||||
</mat-sidenav>
|
||||
|
||||
<div class="example-sidenav-content">
|
||||
<button type="button" mat-button (click)="sidenav.open()">
|
||||
Open sidenav
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-sidenav-container class="example-container" *ngIf="shouldRun">
|
||||
<mat-sidenav mode="side" opened="true">Sidenav content</mat-sidenav>
|
||||
<mat-sidenav-content>Main content</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
/**
|
||||
* @title Basic sidenav
|
||||
*/
|
||||
/** @title Basic sidenav */
|
||||
@Component({
|
||||
selector: 'sidenav-overview-example',
|
||||
templateUrl: 'sidenav-overview-example.html',
|
||||
styleUrls: ['sidenav-overview-example.css'],
|
||||
})
|
||||
export class SidenavOverviewExample {}
|
||||
export class SidenavOverviewExample {
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.example-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<mat-sidenav-container class="example-container" *ngIf="shouldRun">
|
||||
<mat-sidenav opened mode="side">Start content</mat-sidenav>
|
||||
<mat-sidenav opened mode="side" position="end">End content</mat-sidenav>
|
||||
Implicit main content
|
||||
</mat-sidenav-container>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
/** @title Implicit main content with two sidenavs */
|
||||
@Component({
|
||||
selector: 'sidenav-position-example',
|
||||
templateUrl: 'sidenav-position-example.html',
|
||||
styleUrls: ['sidenav-position-example.css'],
|
||||
})
|
||||
export class SidenavPositionExample {
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
.example-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.example-is-mobile .example-toolbar {
|
||||
position: fixed;
|
||||
/* Make sure the toolbar will stay on top of the content as it scrolls past. */
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
h1.example-app-name {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.example-sidenav-container {
|
||||
/* When the sidenav is not fixed, stretch the sidenav container to fill the available space. This
|
||||
causes `<mat-sidenav-content>` to act as our scrolling element for desktop layouts. */
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.example-is-mobile .example-sidenav-container {
|
||||
/* When the sidenav is fixed, don't constrain the height of the sidenav container. This allows the
|
||||
`<body>` to be our scrolling element for mobile layouts. */
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<div class="example-container" [class.example-is-mobile]="mobileQuery.matches" *ngIf="shouldRun">
|
||||
<mat-toolbar color="primary" class="example-toolbar">
|
||||
<button mat-icon-button (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
|
||||
<h1 class="example-app-name">Responsive App</h1>
|
||||
</mat-toolbar>
|
||||
|
||||
<mat-sidenav-container class="example-sidenav-container"
|
||||
[style.marginTop.px]="mobileQuery.matches ? 56 : 0">
|
||||
<mat-sidenav #snav [mode]="mobileQuery.matches ? 'over' : 'side'"
|
||||
[fixedInViewport]="mobileQuery.matches" fixedTopGap="56">
|
||||
<mat-nav-list>
|
||||
<a mat-list-item routerLink="." *ngFor="let nav of fillerNav">{{nav}}</a>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<p *ngFor="let content of fillerContent">{{content}}</p>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!shouldRun">Please open in Plunker to see result</div>
|
||||
@@ -0,0 +1,35 @@
|
||||
import {MediaMatcher} from '@angular/cdk/layout';
|
||||
import {ChangeDetectorRef, Component} from '@angular/core';
|
||||
|
||||
/** @title Responsive sidenav */
|
||||
@Component({
|
||||
selector: 'sidenav-responsive-example',
|
||||
templateUrl: 'sidenav-responsive-example.html',
|
||||
styleUrls: ['sidenav-responsive-example.css'],
|
||||
})
|
||||
export class SidenavResponsiveExample {
|
||||
mobileQuery: MediaQueryList;
|
||||
|
||||
fillerNav = Array(50).fill(0).map((_, i) => `Nav Item ${i + 1}`);
|
||||
|
||||
fillerContent = Array(50).fill(0).map(() =>
|
||||
`Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
|
||||
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
|
||||
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
|
||||
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
|
||||
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`);
|
||||
|
||||
private _mobileQueryListener: () => void;
|
||||
|
||||
constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher) {
|
||||
this.mobileQuery = media.matchMedia('(max-width: 600px)');
|
||||
this._mobileQueryListener = () => changeDetectorRef.detectChanges();
|
||||
this.mobileQuery.addListener(this._mobileQueryListener);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.mobileQuery.removeListener(this._mobileQueryListener);
|
||||
}
|
||||
|
||||
shouldRun = [/(^|\.)plnkr\.co$/, /(^|\.)stackblitz\.io$/].some(h => h.test(window.location.host));
|
||||
}
|
||||
Reference in New Issue
Block a user