Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit b6e2b05

Browse files
author
Yvonne Yip
committed
contacts-v2: refactoring, responsive create screen
1 parent f633695 commit b6e2b05

File tree

5 files changed

+334
-342
lines changed

5 files changed

+334
-342
lines changed

shiny/Contacts-v2/components/contacts-app.html

+328-21
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1+
<link href="../../../../polymer-elements/polymer-animation/polymer-animation.html" rel="import">
2+
<link href="../../../../polymer-elements/polymer-animation/polymer-animation-group.html" rel="import">
3+
<link href="../../../../polymer-elements/polymer-animation/polymer-fadein.html" rel="import">
4+
<link href="../../../../polymer-elements/polymer-animation/polymer-fadeout.html" rel="import">
5+
<link href="../../../../polymer-elements/polymer-animation/polymer-translate.html" rel="import">
16
<link href="../../../../polymer-elements/polymer-flex-layout/polymer-flex-layout.html" rel="import">
27
<link href="../../../../polymer-elements/polymer-grid-layout/polymer-grid-layout.html" rel="import">
38
<link href="../../../../polymer-elements/polymer-media-query/polymer-media-query.html" rel="import">
9+
<link href="../../../../polymer-elements/polymer-scrub/polymer-scrub.html" rel="import">
10+
<link href="../../../../polymer-ui-elements/polymer-ui-icon-button/polymer-ui-icon-button.html" rel="import">
411
<link href="../../../../polymer-ui-elements/polymer-ui-menu/polymer-ui-menu.html" rel="import">
512
<link href="../../../../polymer-ui-elements/polymer-ui-menu-item/polymer-ui-menu-item.html" rel="import">
613
<link href="../../../../polymer-ui-elements/polymer-ui-overlay/polymer-ui-overlay.html" rel="import">
7-
<link href="../../../../polymer-ui-elements/polymer-ui-pages/polymer-ui-pages.html" rel="import">
14+
<link href="../../../../polymer-ui-elements/polymer-ui-toolbar/polymer-ui-toolbar.html" rel="import">
15+
<link href="../../../list/elements/polymer-list/polymer-list.html" rel="import">
816
<link href="contacts-create.html" rel="import">
17+
<link href="contacts-detail.html" rel="import">
918
<link href="contacts-icon.html" rel="import">
10-
<link href="contacts-list.html" rel="import">
11-
<polymer-element name="contacts-app" attribiutes="page">
19+
<link href="mock-data.html" rel="import">
20+
<polymer-element name="contacts-app" attributes="page desktopLayout tabletLayout">
1221
<template>
1322
<style>
1423
polymer-ui-menu {
@@ -39,14 +48,144 @@
3948
margin: 10px;
4049
color: black;
4150
}
42-
polymer-ui-pages {
43-
display: block;
51+
/* @polyfill @host */
52+
:host {
53+
position: absolute;
54+
top: 0;
55+
left: 0;
56+
bottom: 0;
57+
right: 0;
58+
background: #f0f0f0;
59+
}
60+
polymer-ui-toolbar {
61+
padding-left: 8px;
62+
padding-right: 8px;
63+
}
64+
#listContainer {
65+
background: #eeeeee;
66+
overflow: hidden;
67+
position: relative;
68+
}
69+
[desktopLayout]#listContainer {
70+
min-width: 320px;
71+
max-width: 384px;
72+
}
73+
polymer-list {
74+
height: 100%;
75+
}
76+
[tabletLayout] polymer-list {
77+
margin: 24px;
78+
}
79+
.contactItem {
80+
font-size: 14px;
81+
font-family: 'Helvetica Neue', HelveticaNeue, Helvetica, sans-serif;
82+
}
83+
.contactItem.sticky {
84+
position: absolute;
85+
top: 0;
86+
left: 0;
87+
right: 0;
88+
z-index: 10;
89+
opacity: 0.95;
90+
}
91+
[tabletLayout] .contactItem.sticky {
92+
display: none;
93+
}
94+
.contactItem.header {
95+
background: #f0f0f0;
96+
border-style: solid;
97+
border-color: rgba(0, 0, 0, 0.15);
98+
border-width: 0 1px 1px;
99+
box-sizing: border-box;
100+
color: #999;
101+
font-variant: small-caps;
102+
padding: 16px 24px;
103+
}
104+
[tabletLayout] .contactItem.header:nth-child(3) {
105+
border-top-width: 1px;
106+
}
107+
.contactItem .firstName {
108+
font-weight: bold;
109+
}
110+
[desktopLayout] .contactItem.polymer-selected {
111+
background: #f7f7f7;
112+
}
113+
.contactItemControls {
114+
position: absolute;
115+
top: 0;
116+
left: -100%;
117+
box-sizing: border-box;
118+
width: 100%;
119+
height: 100%;
120+
border-style: solid;
121+
border-color: rgba(0, 0, 0, 0.15);
122+
border-width: 0 0 1px;
123+
text-align: right;
124+
padding: 17px 24px;
125+
}
126+
.contactItemControls.active {
127+
background: #f5565a;
128+
opacity: 0;
129+
}
130+
.contactItemBody {
131+
background-color: white;
132+
border-style: solid;
133+
border-color: rgba(0, 0, 0, 0.15);
134+
border-width: 0 1px 1px;
135+
box-sizing: border-box;
136+
padding: 16px;
137+
}
138+
[desktopLayout] #details {
139+
min-width: 50%;
140+
height: 100%;
141+
}
142+
#details.polymer-overlay {
143+
position: fixed;
144+
top: 0;
145+
left: 0;
146+
bottom: 0;
147+
right: 0;
148+
-webkit-transform-origin-y: top;
149+
opacity: 0;
150+
}
151+
#details.polymer-overlay.opened {
152+
opacity: 1;
153+
}
154+
#createOverlay {
155+
position: fixed;
156+
top: 0;
157+
left: 0;
158+
bottom: 0;
159+
right: 0;
160+
}
161+
#createOverlay[desktopLayout] {
162+
right: 16px;
163+
left: 336px;
164+
}
165+
#createOverlay::x-overlay {
44166
height: 100%;
45-
z-index: 0;
46167
}
168+
#createOverlay[desktopLayout]::x-overlay {
169+
border-radius: 3px;
170+
}
171+
.addButton {
172+
position: absolute;
173+
left: auto;
174+
bottom: 16px;
175+
right: 16px;
176+
color: white;
177+
padding: 8px 14px;
178+
background: #bdc146;
179+
font-size: 20px;
180+
border: 1px solid #d9d9d9;
181+
border-radius: 20px;
182+
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
183+
}
47184
</style>
48-
<polymer-media-query query="min-width: 768px" queryMatches="{{wideLayout}}"></polymer-media-query>
49-
<polymer-grid-layout id="grid"></polymer-grid-layout>
185+
<mock-data id="mock"></mock-data>
186+
<polymer-media-query query="min-width: 768px" queryMatches="{{desktopLayout}}"></polymer-media-query>
187+
<polymer-media-query query="(min-width: 480px) and (max-width: 768px)" queryMatches="{{tabletLayout}}"></polymer-media-query>
188+
<polymer-grid-layout id="grid" nodes="{{layoutNodes}}" on-polymer-grid-layout="{{layoutAction}}"></polymer-grid-layout>
50189
<polymer-ui-overlay id="sidebar" class="sidebar" backdrop modal>
51190
<polymer-ui-menu valueattr="label" on-polymer-select="{{sidebarCloseAction}}">
52191
<div class="header">
@@ -63,25 +202,193 @@
63202
<polymer-ui-menu-item label="Help" icon="dialog"></polymer-ui-menu-item>
64203
</polymer-ui-menu>
65204
</polymer-ui-overlay>
66-
<polymer-ui-pages selected="{{page}}" wideLayout?="{{wideLayout}}">
67-
<contacts-list id="listView" on-contacts-list-add="{{addContactAction}}" on-contacts-menu-open="{{sidebarOpenAction}}"></contacts-list>
68-
<contacts-create on-contacts-create-cancel="{{shrinkAction}}"></contacts-create>
69-
</polymer-ui-pages>
205+
<polymer-ui-toolbar id="toolbar">
206+
<polymer-ui-icon-button icon="menu" on-tap="{{menuAction}}"></polymer-ui-icon-button>
207+
<div flex>Everyone</div>
208+
<polymer-ui-icon-button icon="search"></polymer-ui-icon-button>
209+
<template if="{{desktopLayout}}">
210+
<polymer-ui-icon-button icon="shortcut"></polymer-ui-icon-button>
211+
<polymer-ui-icon-button icon="favorite"></polymer-ui-icon-button>
212+
</template>
213+
</polymer-ui-toolbar>
214+
<div id="listContainer" desktopLayout?="{{desktopLayout}}" tabletLayout?="{{tabletLayout}}">
215+
<div id="sticky" class="contactItem header sticky">
216+
{{stickyContent}}
217+
</div>
218+
<polymer-list id="list" data="{{$.mock.withHeaders}}" listData="{{listData}}" on-polymer-list-scroll="{{scrollAction}}">
219+
<template repeat="{{contact in listData}}">
220+
<!-- <contacts-list-item contact="{{contact}}"></contacts-list-item> -->
221+
222+
<template if="{{contact.header}}">
223+
<div class="contactItem header {{contact.page}}">
224+
{{contact.header}}
225+
</div>
226+
</template>
227+
<template if="{{!contact.header}}">
228+
<div class="contactItem {{contact.page}}" on-pointerdown="{{pointerdownAction}}">
229+
<div class="contactItemControls active"></div>
230+
<div class="contactItemControls">
231+
<polymer-ui-icon-button icon="close"></polymer-ui-icon-button>
232+
</div>
233+
<div class="contactItemBody" on-click="{{activateAction}}">
234+
<polymer-flex-layout align="center"></polymer-flex-layout>
235+
<contacts-icon contact="{{contact}}"></contacts-icon>
236+
<div><span class="firstName">{{contact.firstName}}</span> {{contact.surname}}</div>
237+
</div>
238+
</div>
239+
</template>
240+
241+
</template>
242+
</polymer-list>
243+
</div>
244+
<contacts-detail id="details" contact="{{selectedContact.contact}}" desktopLayout?="{{desktopLayout}}" on-contacts-detail-cancel="{{closeDetailsAction}}"></contacts-detail>
245+
<polymer-ui-overlay id="createOverlay" desktopLayout?="{{desktopLayout}}" autocloseDisabled backdrop on-polymer-overlay-open="{{openCreateAction}}">
246+
<contacts-create id="create" on-contacts-create-cancel="{{closeCreateAction}}" on-contacts-create="{{closeCreateAction}}"></contacts-create>
247+
</polymer-ui-overlay>
248+
<div class="addButton" on-tap="{{addAction}}">&#x2b;</div>
249+
<!-- overlay -->
250+
<polymer-overlay id="detailsOverlay" transitions="{{activateTransitions}}" autocloseDisabled></polymer-overlay>
251+
<!-- <polymer-overlay id="createOverlay" target="{{$.create}}" autocloseDisabled></polymer-overlay> -->
252+
<!-- scrubbing -->
253+
<polymer-scrub id="scrub" animation="{{$.slideAnimation.animation}}" snapThreshold="0.2" on-polymer-scrub-animation-end="{{scrubAnimationEndAction}}"></polymer-scrub>
254+
<polymer-animation-group id="slideAnimation" type="par" fillMode="forwards">
255+
<polymer-translate id="translateAnimation" fromX="0" toX="100%" duration="0.6" fillMode="forwards"></polymer-translate>
256+
<polymer-fadein id="fadeAnimation" duration="0.1" fillMode="forwards"></polymer-fadein>
257+
</polymer-animation-group>
258+
<!-- item delete animation -->
259+
<polymer-translate id="deleteAnimation" duration="0.1" fromY="0" toY="-100%" fillMode="forwards" easing="ease-in" on-polymer-animation-end="{{deleteAnimationEndAction}}"></polymer-translate>
260+
<!-- transition -->
261+
<polymer-animation-group id="activateAnimation" type="par" duration="0.1">
262+
<polymer-translate target="{{$.toolbar}}" fromY="0" toY="-100%"></polymer-translate>
263+
<polymer-fadeout target="{{$.toolbar}}"></polymer-fadeout>
264+
<polymer-fadeout target="{{$.sticky}}"></polymer-fadeout>
265+
<polymer-fadeout target="{{$.list}}"></polymer-fadeout>
266+
<polymer-animation target="{{$.details}}" easing="ease-in">
267+
<polymer-animation-keyframe>
268+
<polymer-animation-prop name="transform" value="scaleY(1.5)"></polymer-animation-prop>
269+
<polymer-animation-prop name="opacity" value="0"></polymer-animation-prop>
270+
</polymer-animation-keyframe>
271+
<polymer-animation-keyframe>
272+
<polymer-animation-prop name="transform" value="scaleY(1)"></polymer-animation-prop>
273+
<polymer-animation-prop name="opacity" value="1"></polymer-animation-prop>
274+
</polymer-animation-keyframe>
275+
</polymer-animation>
276+
</polymer-animation-group>
70277
</template>
71278
<script>
72279
Polymer('contacts-app', {
73-
page: 0,
74-
wideLayout: false,
280+
desktopLayout: true,
281+
tabletLayout: false,
282+
stickyContent: 'A',
283+
selectedContact: null,
284+
observe: {
285+
desktopLayout: 'layoutChanged',
286+
tabletLayout: 'layoutChanged'
287+
},
75288
ready: function() {
76-
// this.$.grid.layout = [
77-
// [2, 3, 3]
78-
// ]
289+
this.activateTransitions = [this.$.activateAnimation, null];
290+
this.selectedContact = {contact: this.$.mock.contacts[0]};
291+
this.layoutChanged();
292+
},
293+
enableOverlays: function() {
294+
this.$.details.removeAttribute('style');
295+
this.$.detailsOverlay.target = this.$.details;
296+
},
297+
disableOverlays: function() {
298+
this.$.detailsOverlay.opened && (this.$.detailsOverlay.opened = false);
299+
this.$.detailsOverlay.target = null;
300+
},
301+
layoutChanged: function() {
302+
if (this.desktopLayout) {
303+
this.disableOverlays();
304+
this.$.listContainer.style.width = null;
305+
this.layoutNodes = [this.$.toolbar, this.$.listContainer, this.$.details];
306+
this.$.grid.layout = [
307+
[1, 1],
308+
[2, 3],
309+
[2, 3],
310+
];
311+
} else {
312+
this.enableOverlays();
313+
this.layoutNodes = [this.$.toolbar, this.$.listContainer];
314+
this.$.grid.layout = [
315+
[1, 1],
316+
[2, 2],
317+
[2, 2],
318+
];
319+
}
320+
},
321+
layoutAction: function() {
322+
this.$.list.reset();
323+
},
324+
scrollAction: function() {
325+
var items = this.$.list.querySelectorAll('.contactItem');
326+
var scrollTop = this.$.list.scrollOffset;
327+
var lastHeader;
328+
for (var i = 0, item; item = items[i]; i++) {
329+
var offset = item.offsetTop + (item.offsetParent ? item.offsetParent.offsetTop : 0);
330+
var isHeader = item.classList.contains('header');
331+
if (offset > scrollTop) {
332+
this.stickyContent = lastHeader.textContent;
333+
var transY = offset - scrollTop - lastHeader.offsetHeight;
334+
if (transY < 0 && isHeader) {
335+
this.$.sticky.style['-webkit-transform'] = 'translateY(' + transY + 'px)';
336+
} else {
337+
this.$.sticky.style['-webkit-transform'] = null;
338+
}
339+
break;
340+
}
341+
if (isHeader) {
342+
lastHeader = item;
343+
}
344+
}
345+
},
346+
pointerdownAction: function(e, detail, sender) {
347+
this.$.scrub.target = sender;
348+
this.$.translateAnimation.target = sender;
349+
this.$.fadeAnimation.target = sender.querySelector('.contactItemControls.active');
350+
this.$.slideAnimation.apply();
351+
},
352+
scrubAnimationEndAction: function(e, detail, sender) {
353+
this.deletedContact = sender.target.templateInstance.model.contact.__proto__;
354+
var listRect = this.$.list.getBoundingClientRect();
355+
var itemRect = sender.target.getBoundingClientRect();
356+
var height = listRect.bottom - itemRect.top;
357+
var item = sender.target;
358+
var targets = [];
359+
do {
360+
item = item.nextElementSibling;
361+
if (item.classList.contains('contactItem')) {
362+
targets.push(item);
363+
height -= itemRect.height;
364+
}
365+
} while (height > 0);
366+
this.$.deleteAnimation.target = targets;
367+
this.$.deleteAnimation.play();
368+
},
369+
deleteAnimationEndAction: function(e, detail, sender) {
370+
var index = this.$.mock.withHeaders.indexOf(this.deletedContact);
371+
this.$.mock.withHeaders.splice(index, 1);
372+
},
373+
addAction: function() {
374+
this.$.createOverlay.active = true;
375+
},
376+
menuAction: function() {
377+
this.fire('contacts-menu-open');
378+
},
379+
closeDetailsAction: function() {
380+
this.$.detailsOverlay.opened = false;
79381
},
80-
addContactAction: function() {
81-
this.page = 1;
382+
closeCreateAction: function() {
383+
this.$.createOverlay.active = false;
82384
},
83-
shrinkAction: function() {
84-
this.page = 0;
385+
activateAction: function(e, detail, sender) {
386+
if (!this.$.scrub.scrubbing) {
387+
this.selectedContact = sender.templateInstance.model;
388+
if (!this.desktopLayout) {
389+
this.$.detailsOverlay.opened = true;
390+
}
391+
}
85392
},
86393
sidebarOpenAction: function() {
87394
this.$.sidebar.active = true;

shiny/Contacts-v2/components/contacts-create.html

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
<polymer-element name="contacts-create" attributes="contact">
66
<template>
77
<style>
8+
:host {
9+
background: white;
10+
}
811
polymer-ui-toolbar {
912
background: transparent none !important;
1013
padding: 0;

0 commit comments

Comments
 (0)