-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapp-bottom-nav.html
208 lines (173 loc) · 6.68 KB
/
app-bottom-nav.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../iron-selector/iron-selector.html">
<link rel="import" href="../iron-media-query/iron-media-query.html">
<link rel="import" href="app-bottom-nav-item.html">
<!--
`app-bottom-nav` is a <a href="https://material.io/guidelines/components/bottom-navigation.html">Material Design</a> compliant bottom navigation element.
### Usage Instructions
By default, the element will only be visible when the viewport is less than
640px. This corresponds to the default `app-drawer-layout` responsive width and
means the `app-bottom-nav` will show when the app-drawer retracts.
- Each navigation option is added as an `app-bottom-nav-item` element and assigned
an icon and a text label.
- `app-bottom-nav` should only contain between 3 and 5 `app-bottom-nav-item` elements.
- The `selected` attribute will contain the label of the currently selected navigation item.
### Examples
The following snippet adds a bottom navigation element with three child navigation options.
```html
<app-bottom-nav selected="{{selected}}">
<app-bottom-nav-item icon="abn-demo:history" label="Recent"></app-bottom-nav-item>
<app-bottom-nav-item icon="abn-demo:favorite" label="Favorites"></app-bottom-nav-item>
<app-bottom-nav-item icon="abn-demo:near-me" label="Nearby"></app-bottom-nav-item>
</app-bottom-nav>
```
By default, the `app-bottom-nav` element is only shown on narrow screens. To
override this behavior, add the `force-narrow` attribute as shown below.
```html
<app-bottom-nav force-narrow="true">
<app-bottom-nav-item icon="abn-demo:history" label="Recent"></app-bottom-nav-item>
<app-bottom-nav-item icon="abn-demo:favorite" label="Favorites"></app-bottom-nav-item>
<app-bottom-nav-item icon="abn-demo:near-me" label="Nearby"></app-bottom-nav-item>
</app-bottom-nav>
```
The demos here use icons from the file `app-bottom-nav/demo/demo-icons.html`.
### Styling
Custom property | Description | Default
---------------------------------|----------------------------------------|--------------------
`--app-bottom-nav-background` | Background color of the element | `--primary-background-color`
`--app-bottom-nav-active` | Color of active navigation items | `--primary-color`
`--app-bottom-nav-inactive` | Color of inactive navigation items | `--secondary-text-color`
<strong>Remarks:</strong>
- If the background of the parent `app-bottom-nav` is colored, the active and inactive colors should be white or black.
@demo demo/index-compact.html
@demo demo/index-triple.html
-->
<dom-module id="app-bottom-nav">
<template>
<style>
:host {
--abn-impl-bg: var(--app-bottom-nav-background, var(--primary-background-color, #FFFFFF));
@apply(--layout-fixed-bottom);
margin: 0px;
padding: 0px;
height: 56px;
background-color: var(--abn-impl-bg);
opacity: 1;
visibility: hidden;
z-index: 1;
transition-property: visibility;
}
:host(.narrow) {
visibility: visible;
}
container {
margin: 0 auto;
display: block;
}
iron-selector {
@apply(--layout-horizontal);
@apply(--layout-center-justified);
}
</style>
<iron-media-query
query="[[_computeMediaQuery(forceNarrow, responsiveWidth)]]"
on-query-matches-changed="_onQueryMatchesChanged"></iron-media-query>
<iron-selector id="nav-selector" attr-for-selected="label" selected="{{selected}}" selected-attribute="active">
<content></content>
</iron-selector>
</template>
<script>
Polymer({
is: 'app-bottom-nav',
properties: {
/**
* If true, ignore `responsiveWidth` setting and force the narrow layout. (nav is visble)
*/
forceNarrow: {
type: Boolean,
value: false,
reflectToAttribute: true
},
/**
* If true, ignore number of children check and force the compact layout.
*/
forceCompact: {
type: Boolean,
value: false,
observer: '_forceCompactChanged'
},
/**
* The label of the currently selected `app-bottom-nav-item`.
*/
selected: {
type: String,
notify: true,
reflectToAttribute: true
},
/**
* If the viewport's width is smaller than this value, the bottom-nav will be visible.
* Otherwise, it will be hidden as it is expected an `app-drawer` or `app-side-nav` element will be present.
*/
responsiveWidth: {
type: String,
value: '640px'
},
},
listeners: {
'nav-item-tap': '_tapHandler'
},
attached: function() {
this._computeCompactAttribute(this.forceCompact);
},
_computeCompactAttribute: function (forceCompact) {
elist = this.queryAllEffectiveChildren("app-bottom-nav-item");
var c = elist.length > 3 || forceCompact;
elist.forEach(function(e){e.toggleAttribute('compact', c, e);});
},
/**
* Observes `force-compact` property and updates children appropriately
*/
_forceCompactChanged: function(val) {
if (this.isAttached) { this._computeCompactAttribute(val); }
},
/**
* Forces the `app-bottom-nav` to appear at all times, ignoring `responsiveWidth`
*/
showAlways: function() {
this.forceNarrow = true;
},
/**
* Resets the element to it's default responsive behavior of "only show when narrow"
*/
showDefault: function() {
this.forceNarrow = false;
},
/**
* Toggles this element's responsive behavior between "always show" and "only show when narrow"
*/
toggleForceNarrow: function() {
this.forceNarrow = !this.forceNarrow;
},
_tapHandler: function(e) {
if (e.detail.name == 'nav-item-tap' && e.detail.active == true) {
this.fire('scroll-top', {'from': 'app-bottom-nav'})
}
},
_narrowChanged: function(narrow) {
this.toggleClass('narrow', narrow, this);
},
_onQueryMatchesChanged: function(event) {
this._narrowChanged(event.detail.value);
},
_computeMediaQuery: function(forceNarrow, responsiveWidth) {
return forceNarrow ? '(min-width: 0px)' : '(max-width: ' + responsiveWidth + ')';
}
/*
* Requests that the parent scroll to the top of the page.
* Fired when the currently selected nav item is tapped.
* @event scroll-top
*/
});
</script>
</dom-module>