polymer-paper-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +69 -0
  3. data/Rakefile +1 -0
  4. data/app/assets/components/core/animation/web-animations.html.erb +1 -0
  5. data/app/assets/components/core/animation/web-animations.js +5666 -0
  6. data/app/assets/components/core/icon/core-icon.css +25 -0
  7. data/app/assets/components/core/icon/core-icon.html.erb +126 -0
  8. data/app/assets/components/core/iconset/core-iconset.html.erb +236 -0
  9. data/app/assets/components/core/input/core-input.css +35 -0
  10. data/app/assets/components/core/input/core-input.html.erb +385 -0
  11. data/app/assets/components/core/list/core-list.css +20 -0
  12. data/app/assets/components/core/list/core-list.html.erb +403 -0
  13. data/app/assets/components/core/media-query/core-media-query.html +86 -0
  14. data/app/assets/components/core/menu/core-menu.css +18 -0
  15. data/app/assets/components/core/menu/core-menu.html.erb +62 -0
  16. data/app/assets/components/core/menu/core-submenu.css +29 -0
  17. data/app/assets/components/core/menu/core-submenu.html.erb +106 -0
  18. data/app/assets/components/core/meta/core-meta.html +143 -0
  19. data/app/assets/components/core/overlay/core-key-helper.html +17 -0
  20. data/app/assets/components/core/overlay/core-overlay-layer.html +112 -0
  21. data/app/assets/components/core/overlay/core-overlay.html.erb +661 -0
  22. data/app/assets/components/core/range/core-range.html +106 -0
  23. data/app/assets/components/core/selection/core-selection.html +148 -0
  24. data/app/assets/components/core/selector/core-selector.html.erb +423 -0
  25. data/app/assets/components/core/style/core-style.html +386 -0
  26. data/app/assets/components/core/transition/core-transition-css.html.erb +76 -0
  27. data/app/assets/components/core/transition/core-transition-overlay.css +46 -0
  28. data/app/assets/components/core/transition/core-transition.html.erb +44 -0
  29. data/app/assets/components/paper-button/paper-button.css +115 -0
  30. data/app/assets/components/paper-button/paper-button.html.erb +210 -0
  31. data/app/assets/components/paper-checkbox/paper-checkbox.css +262 -0
  32. data/app/assets/components/paper-checkbox/paper-checkbox.html.erb +104 -0
  33. data/app/assets/components/paper-dialog/paper-dialog-transition.css +59 -0
  34. data/app/assets/components/paper-dialog/paper-dialog-transition.html.erb +27 -0
  35. data/app/assets/components/paper-dialog/paper-dialog.css +0 -0
  36. data/app/assets/components/paper-dialog/paper-dialog.html.erb +176 -0
  37. data/app/assets/components/paper-fab/paper-fab.css +27 -0
  38. data/app/assets/components/paper-fab/paper-fab.html.erb +55 -0
  39. data/app/assets/components/paper-focusable/paper-focusable.html +144 -0
  40. data/app/assets/components/paper-icon-button/paper-icon-button.css +17 -0
  41. data/app/assets/components/paper-icon-button/paper-icon-button.html.erb +87 -0
  42. data/app/assets/components/paper-input/error-100.png +0 -0
  43. data/app/assets/components/paper-input/error-200.png +0 -0
  44. data/app/assets/components/paper-input/paper-input.html.erb +398 -0
  45. data/app/assets/components/paper-input/paper-input.scss +203 -0
  46. data/app/assets/components/paper-item/paper-item.css +30 -0
  47. data/app/assets/components/paper-item/paper-item.html.erb +103 -0
  48. data/app/assets/components/paper-menu-button/paper-menu-button-overlay.html.erb +86 -0
  49. data/app/assets/components/paper-menu-button/paper-menu-button-transition.css +19 -0
  50. data/app/assets/components/paper-menu-button/paper-menu-button-transition.html.erb +118 -0
  51. data/app/assets/components/paper-menu-button/paper-menu-button.css +86 -0
  52. data/app/assets/components/paper-menu-button/paper-menu-button.html.erb +128 -0
  53. data/app/assets/components/paper-progress/paper-progress.css +35 -0
  54. data/app/assets/components/paper-progress/paper-progress.html.erb +98 -0
  55. data/app/assets/components/paper-radio-button/paper-radio-button.css +98 -0
  56. data/app/assets/components/paper-radio-button/paper-radio-button.html.erb +148 -0
  57. data/app/assets/components/paper-radio-group/paper-radio-group.html.erb +68 -0
  58. data/app/assets/components/paper-ripple/paper-ripple.html +426 -0
  59. data/app/assets/components/paper-shadow/paper-shadow.css +81 -0
  60. data/app/assets/components/paper-shadow/paper-shadow.html.erb +212 -0
  61. data/app/assets/components/paper-slider/paper-slider.css +193 -0
  62. data/app/assets/components/paper-slider/paper-slider.html.erb +310 -0
  63. data/app/assets/components/paper-tabs/paper-tab.css +49 -0
  64. data/app/assets/components/paper-tabs/paper-tab.html.erb +66 -0
  65. data/app/assets/components/paper-tabs/paper-tabs.css +57 -0
  66. data/app/assets/components/paper-tabs/paper-tabs.html.erb +127 -0
  67. data/app/assets/components/paper-toast/paper-toast.css +0 -0
  68. data/app/assets/components/paper-toast/paper-toast.html.erb +258 -0
  69. data/app/assets/components/paper-toggle-button/paper-toggle-button.css +61 -0
  70. data/app/assets/components/paper-toggle-button/paper-toggle-button.html.erb +125 -0
  71. data/lib/polymer-paper-rails/engine.rb +4 -0
  72. data/lib/polymer-paper-rails/version.rb +3 -0
  73. data/lib/polymer-paper-rails.rb +2 -0
  74. metadata +158 -0
@@ -0,0 +1,20 @@
1
+ :host {
2
+ display: block;
3
+ overflow: auto;
4
+ /*-webkit-overflow-scrolling: touch;
5
+ -webkit-transform: translateZ(0);
6
+ transform: translateZ(0);*/
7
+ }
8
+
9
+ .core-list-viewport > * {
10
+ overflow: hidden;
11
+ }
12
+
13
+ .core-list-viewport.horizontal {
14
+ height: 100%;
15
+ white-space: nowrap;
16
+ }
17
+
18
+ .core-list-viewport.horizontal > * {
19
+ display: inline-block;
20
+ }
@@ -0,0 +1,403 @@
1
+ <!--
2
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6
+ Code distributed by Google as part of the polymer project is also
7
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8
+ -->
9
+
10
+ <!--
11
+ `core-list` displays a virtual, 'infinite' list. The template inside the
12
+ `core-list` element represents the dom to create for each list item. The
13
+ `data` property specifies an array of list item data. The `height` property
14
+ represents the height of a list item.
15
+
16
+ By default, the list supports selection via tapping. Styling the selection
17
+ should be done via binding. The `selectedProperty` property is set on the
18
+ list view data for each selected item.
19
+
20
+ `core-list` manages a viewport of data based on the current scroll position.
21
+ For performance reasons, not every item in the list is rendered at once.
22
+
23
+ <core-list data="{{data}}" height="80">
24
+ <template>
25
+ <div class="{{ {selected: selected} | tokenList }}">List row: {{index}}</div>
26
+ </template>
27
+ </core-list>
28
+
29
+ @group Polymer Core Elements
30
+ @element core-list
31
+ -->
32
+
33
+ <%= html_import_tag "core/selection/core-selection" %>
34
+
35
+ <polymer-element name="core-list" on-tap="{{tapHandler}}">
36
+ <template>
37
+ <core-selection id="selection" multi="{{multi}}" on-core-select="{{selectedHandler}}"></core-selection>
38
+ <%= stylesheet_link_tag "core-list/core-list"%>
39
+ <div id="viewport" class="core-list-viewport"><content></content></div>
40
+ </template>
41
+ <script>
42
+ (function() {
43
+
44
+ Polymer('core-list', {
45
+
46
+ publish: {
47
+ /**
48
+ * Fired when an item element is tapped.
49
+ *
50
+ * @event core-activate
51
+ * @param {Object} detail
52
+ * @param {Object} detail.item the item element
53
+ */
54
+
55
+ /**
56
+ *
57
+ * An array of source data for the list to display.
58
+ *
59
+ * @attribute data
60
+ * @type array
61
+ * @default null
62
+ */
63
+ data: null,
64
+
65
+ /**
66
+ *
67
+ * An optional element on which to listen for scroll events.
68
+ *
69
+ * @attribute scrollTarget
70
+ * @type Element
71
+ * @default core-list
72
+ */
73
+ scrollTarget: null,
74
+
75
+ /**
76
+ *
77
+ * The height of a list item. `core-list` currently supports only fixed-height
78
+ * list items. This height must be specified via the height property.
79
+ *
80
+ * @attribute height
81
+ * @type number
82
+ * @default 80
83
+ */
84
+ height: 80,
85
+
86
+ /**
87
+ *
88
+ * The number of extra items rendered above the minimum set required to
89
+ * fill the list's height.
90
+ *
91
+ * @attribute extraItems
92
+ * @type number
93
+ * @default 30
94
+ */
95
+ extraItems: 30,
96
+
97
+ /**
98
+ *
99
+ * The property set on the list view data to represent selection state.
100
+ * This should set so that it does not conflict with other data properties.
101
+ * Note, selection data is not stored on the data in given in the data property.
102
+ *
103
+ * @attribute selectedProperty
104
+ * @type string
105
+ * @default 'selected'
106
+ */
107
+ selectedProperty: 'selected',
108
+
109
+ // TODO(sorvell): experimental
110
+ /**
111
+ *
112
+ * If true, data is sync'd from the list back to the list's data.
113
+ *
114
+ * @attribute sync
115
+ * @type boolean
116
+ * @default false
117
+ */
118
+ sync: false,
119
+
120
+ /**
121
+ *
122
+ * Set to true to support multiple selection.
123
+ *
124
+ * @attribute multi
125
+ * @type boolean
126
+ * @default false
127
+ */
128
+ multi: false
129
+
130
+ },
131
+
132
+ observe: {
133
+ 'data template scrollTarget': 'initialize'
134
+ },
135
+
136
+ ready: function() {
137
+ this.clearSelection();
138
+ this._boundScrollHandler = this.scrollHandler.bind(this);
139
+ },
140
+
141
+ attached: function() {
142
+ this.template = this.querySelector('template');
143
+ },
144
+
145
+ // TODO(sorvell): it'd be nice to dispense with 'data' and just use
146
+ // template repeat's model. However, we need tighter integration
147
+ // with TemplateBinding for this.
148
+ initialize: function() {
149
+ if (!this.data || !this.template) {
150
+ return;
151
+ }
152
+ var target = this.scrollTarget || this;
153
+ if (this._target !== target) {
154
+ if (this._target) {
155
+ this._target.removeEventListener('scroll', this._boundScrollHandler, false);
156
+ }
157
+ this._target = target;
158
+ this._target.addEventListener('scroll', this._boundScrollHandler, false);
159
+ }
160
+
161
+ this.initializeViewport();
162
+ this.initalizeData();
163
+ this.onMutation(this, this.initializeItems);
164
+ },
165
+
166
+ // TODO(sorvell): need to handle resizing
167
+ initializeViewport: function() {
168
+ this.$.viewport.style.height = this.height * this.data.length + 'px';
169
+ this._visibleCount = Math.ceil(this._target.offsetHeight / this.height);
170
+ this._physicalCount = Math.min(this._visibleCount + this.extraItems,
171
+ this.data.length);
172
+ this._physicalHeight = this.height * this._physicalCount;
173
+ },
174
+
175
+ // TODO(sorvell): selection currently cannot be maintained when
176
+ // items are added or deleted.
177
+ initalizeData: function() {
178
+ var exampleDatum = this.data[0] || {};
179
+ this._propertyNames = Object.getOwnPropertyNames(exampleDatum);
180
+ this._physicalData = new Array(this._physicalCount);
181
+ for (var i = 0; i < this._physicalCount; ++i) {
182
+ this._physicalData[i] = {};
183
+ this.updateItem(i, i);
184
+ }
185
+ this.template.model = this._physicalData;
186
+ this.template.setAttribute('repeat', '');
187
+ },
188
+
189
+ initializeItems: function() {
190
+ this._physicalItems = new Array(this._physicalCount);
191
+ for (var i = 0, item = this.template.nextElementSibling;
192
+ item && i < this._physicalCount;
193
+ ++i, item = item.nextElementSibling) {
194
+ this._physicalItems[i] = item;
195
+ item._transformValue = 0;
196
+ }
197
+ this.refresh(false);
198
+ },
199
+
200
+ updateItem: function(virtualIndex, physicalIndex) {
201
+ var virtualDatum = this.data[virtualIndex];
202
+ var physicalDatum = this._physicalData[physicalIndex];
203
+ this.pushItemData(virtualDatum, physicalDatum);
204
+ physicalDatum._physicalIndex = physicalIndex;
205
+ physicalDatum._virtualIndex = virtualIndex;
206
+ if (this.selectedProperty) {
207
+ physicalDatum[this.selectedProperty] = this._selectedData.get(virtualDatum);
208
+ }
209
+ },
210
+
211
+ pushItemData: function(source, dest) {
212
+ for (var i = 0; i < this._propertyNames.length; ++i) {
213
+ var propertyName = this._propertyNames[i];
214
+ dest[propertyName] = source[propertyName];
215
+ }
216
+ },
217
+
218
+ // experimental: push physical data back to this.data.
219
+ // this is optional when scrolling and needs to be called at other times.
220
+ syncData: function() {
221
+ if (this.firstPhysicalIndex === undefined ||
222
+ this.baseVirtualIndex === undefined) {
223
+ return;
224
+ }
225
+ var p, v;
226
+ for (var i = 0; i < this.firstPhysicalIndex; ++i) {
227
+ p = this._physicalData[i];
228
+ v = this.data[this.baseVirtualIndex + this._physicalCount + i];
229
+ this.pushItemData(p, v);
230
+ }
231
+ for (var i = this.firstPhysicalIndex; i < this._physicalCount; ++i) {
232
+ p = this._physicalData[i];
233
+ v = this.data[this.baseVirtualIndex + i];
234
+ this.pushItemData(p, v);
235
+ }
236
+ },
237
+
238
+ scrollHandler: function(e, detail) {
239
+ this._scrollTop = e.detail ? e.detail.target.scrollTop : e.target.scrollTop;
240
+ this.refresh(false);
241
+ },
242
+
243
+ /**
244
+ * Refresh the list at the current scroll position.
245
+ *
246
+ * @method refresh
247
+ */
248
+ refresh: function(force) {
249
+ var firstVisibleIndex = Math.floor(this._scrollTop / this.height);
250
+ var visibleMidpoint = firstVisibleIndex + this._visibleCount / 2;
251
+
252
+ var firstReifiedIndex = Math.max(0, Math.floor(visibleMidpoint -
253
+ this._physicalCount / 2));
254
+ firstReifiedIndex = Math.min(firstReifiedIndex, this.data.length -
255
+ this._physicalCount);
256
+
257
+ var firstPhysicalIndex = firstReifiedIndex % this._physicalCount;
258
+ var baseVirtualIndex = firstReifiedIndex - firstPhysicalIndex;
259
+
260
+ var baseTransformValue = Math.floor(this.height * baseVirtualIndex);
261
+ var nextTransformValue = Math.floor(baseTransformValue +
262
+ this._physicalHeight);
263
+
264
+ var baseTransformString = 'translate3d(0,' + baseTransformValue + 'px,0)';
265
+ var nextTransformString = 'translate3d(0,' + nextTransformValue + 'px,0)';
266
+ // TODO(sorvell): experiemental for sync'ing back to virtual data.
267
+ if (this.sync) {
268
+ this.syncData();
269
+ }
270
+ this.firstPhysicalIndex = firstPhysicalIndex;
271
+ this.baseVirtualIndex = baseVirtualIndex;
272
+
273
+ for (var i = 0; i < firstPhysicalIndex; ++i) {
274
+ var item = this._physicalItems[i];
275
+ if (force || item._transformValue != nextTransformValue) {
276
+ this.updateItem(baseVirtualIndex + this._physicalCount + i, i);
277
+ setTransform(item, nextTransformString, nextTransformValue);
278
+ }
279
+ }
280
+ for (var i = firstPhysicalIndex; i < this._physicalCount; ++i) {
281
+ var item = this._physicalItems[i];
282
+ if (force || item._transformValue != baseTransformValue) {
283
+ this.updateItem(baseVirtualIndex + i, i);
284
+ setTransform(item, baseTransformString, baseTransformValue);
285
+ }
286
+ }
287
+ },
288
+
289
+ // list selection
290
+ tapHandler: function(e) {
291
+ if (e.target === this) {
292
+ return;
293
+ }
294
+ if (this.sync) {
295
+ this.syncData();
296
+ }
297
+ var n = e.target;
298
+ var model = n.templateInstance && n.templateInstance.model;
299
+ if (model) {
300
+ var vi = model._virtualIndex, pi = model._physicalIndex;
301
+ var data = this.data[vi], item = this._physicalItems[pi];
302
+ this.$.selection.select(data);
303
+ this.asyncFire('core-activate', {data: data, item: item});
304
+ }
305
+ },
306
+
307
+ selectedHandler: function(e, detail) {
308
+ if (this.selectedProperty) {
309
+ var i$ = this.indexesForData(detail.item);
310
+ // TODO(sorvell): we should be relying on selection to store the
311
+ // selected data but we want to optimize for lookup.
312
+ this._selectedData.set(detail.item, detail.isSelected);
313
+ if (i$.physical >= 0) {
314
+ this.updateItem(i$.virtual, i$.physical);
315
+ }
316
+ }
317
+ },
318
+
319
+ /**
320
+ * Select the list item at the given index.
321
+ *
322
+ * @method selectItem
323
+ * @param {number} index
324
+ */
325
+ selectItem: function(index) {
326
+ var data = this.data[index];
327
+ if (data) {
328
+ this.$.selection.select(data);
329
+ }
330
+ },
331
+
332
+ /**
333
+ * Set the selected state of the list item at the given index.
334
+ *
335
+ * @method setItemSelected
336
+ * @param {number} index
337
+ * @param {boolean} isSelected
338
+ */
339
+ setItemSelected: function(index, isSelected) {
340
+ var data = this.data[index];
341
+ if (data) {
342
+ this.$.selection.setItemSelected(data, isSelected);
343
+ }
344
+ },
345
+
346
+ indexesForData: function(data) {
347
+ var virtual = this.data.indexOf(data);
348
+ var physical = this.virtualToPhysicalIndex(virtual);
349
+ return { virtual: virtual, physical: physical };
350
+ },
351
+
352
+ virtualToPhysicalIndex: function(index) {
353
+ for (var i=0, l=this._physicalData.length; i<l; i++) {
354
+ if (this._physicalData[i]._virtualIndex === index) {
355
+ return i;
356
+ }
357
+ }
358
+ return -1;
359
+ },
360
+
361
+ get selection() {
362
+ return this.$.selection.getSelection();
363
+ },
364
+
365
+ selectedChanged: function() {
366
+ this.$.selection.select(this.selected);
367
+ },
368
+
369
+ clearSelection: function() {
370
+ this._selectedData = new WeakMap();
371
+ if (this.multi) {
372
+ var s$ = this.selection;
373
+ for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) {
374
+ this.$.selection.setItemSelected(s, false);
375
+ }
376
+ } else {
377
+ this.$.selection.setItemSelected(this.selection, false);
378
+ }
379
+ this.$.selection.clear();
380
+ },
381
+
382
+ scrollToItem: function(index) {
383
+ this.scrollTop = index * this.height;
384
+ }
385
+
386
+ });
387
+
388
+ // determine proper transform mechanizm
389
+ if (document.documentElement.style.transform !== undefined) {
390
+ function setTransform(element, string, value) {
391
+ element.style.transform = string;
392
+ element._transformValue = value;
393
+ }
394
+ } else {
395
+ function setTransform(element, string, value) {
396
+ element.style.webkitTransform = string;
397
+ element._transformValue = value;
398
+ }
399
+ }
400
+
401
+ })();
402
+ </script>
403
+ </polymer-element>
@@ -0,0 +1,86 @@
1
+ <!--
2
+ Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3
+ This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4
+ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5
+ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6
+ Code distributed by Google as part of the polymer project is also
7
+ subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8
+ -->
9
+ <!--
10
+ /**
11
+ * @group Polymer Core Elements
12
+ * @element core-media-query
13
+ * @status beta
14
+ * @homepage github.io
15
+ *
16
+ * core-media-query can be used to data bind to a CSS media query.
17
+ * The "query" property is a bare CSS media query.
18
+ * The "queryMatches" property will be a boolean representing if the page matches that media query.
19
+ *
20
+ * core-media-query uses media query listeners to dynamically update the "queryMatches" property.
21
+ * A "core-media-change" event also fires when queryMatches changes.
22
+ *
23
+ * Example:
24
+ *
25
+ * <core-media-query query="max-width: 640px" queryMatches="{{phoneScreen}}"></core-media-query>
26
+ *
27
+ */
28
+
29
+ /**
30
+ * Fired when the media query state changes
31
+ *
32
+ * @event core-media-change
33
+ */
34
+ -->
35
+
36
+ <polymer-element name="core-media-query" attributes="query queryMatches">
37
+ <template>
38
+ <style>
39
+ :host {
40
+ display: none;
41
+ }
42
+ </style>
43
+ </template>
44
+ <script>
45
+ Polymer('core-media-query', {
46
+
47
+ /**
48
+ * The Boolean return value of the media query
49
+ *
50
+ * @attribute queryMatches
51
+ * @type Boolean
52
+ * @default false
53
+ */
54
+ queryMatches: false,
55
+
56
+ /**
57
+ * The CSS media query to evaulate
58
+ *
59
+ * @attribute query
60
+ * @type string
61
+ * @default ''
62
+ */
63
+ query: '',
64
+ ready: function() {
65
+ this._mqHandler = this.queryHandler.bind(this);
66
+ this._mq = null;
67
+ },
68
+ queryChanged: function() {
69
+ if (this._mq) {
70
+ this._mq.removeListener(this._mqHandler);
71
+ }
72
+ var query = this.query;
73
+ if (query[0] !== '(') {
74
+ query = '(' + this.query + ')';
75
+ }
76
+ this._mq = window.matchMedia(query);
77
+ this._mq.addListener(this._mqHandler);
78
+ this.queryHandler(this._mq);
79
+ },
80
+ queryHandler: function(mq) {
81
+ this.queryMatches = mq.matches;
82
+ this.asyncFire('core-media-change', mq);
83
+ }
84
+ });
85
+ </script>
86
+ </polymer-element>