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.
- checksums.yaml +7 -0
- data/README.md +69 -0
- data/Rakefile +1 -0
- data/app/assets/components/core/animation/web-animations.html.erb +1 -0
- data/app/assets/components/core/animation/web-animations.js +5666 -0
- data/app/assets/components/core/icon/core-icon.css +25 -0
- data/app/assets/components/core/icon/core-icon.html.erb +126 -0
- data/app/assets/components/core/iconset/core-iconset.html.erb +236 -0
- data/app/assets/components/core/input/core-input.css +35 -0
- data/app/assets/components/core/input/core-input.html.erb +385 -0
- data/app/assets/components/core/list/core-list.css +20 -0
- data/app/assets/components/core/list/core-list.html.erb +403 -0
- data/app/assets/components/core/media-query/core-media-query.html +86 -0
- data/app/assets/components/core/menu/core-menu.css +18 -0
- data/app/assets/components/core/menu/core-menu.html.erb +62 -0
- data/app/assets/components/core/menu/core-submenu.css +29 -0
- data/app/assets/components/core/menu/core-submenu.html.erb +106 -0
- data/app/assets/components/core/meta/core-meta.html +143 -0
- data/app/assets/components/core/overlay/core-key-helper.html +17 -0
- data/app/assets/components/core/overlay/core-overlay-layer.html +112 -0
- data/app/assets/components/core/overlay/core-overlay.html.erb +661 -0
- data/app/assets/components/core/range/core-range.html +106 -0
- data/app/assets/components/core/selection/core-selection.html +148 -0
- data/app/assets/components/core/selector/core-selector.html.erb +423 -0
- data/app/assets/components/core/style/core-style.html +386 -0
- data/app/assets/components/core/transition/core-transition-css.html.erb +76 -0
- data/app/assets/components/core/transition/core-transition-overlay.css +46 -0
- data/app/assets/components/core/transition/core-transition.html.erb +44 -0
- data/app/assets/components/paper-button/paper-button.css +115 -0
- data/app/assets/components/paper-button/paper-button.html.erb +210 -0
- data/app/assets/components/paper-checkbox/paper-checkbox.css +262 -0
- data/app/assets/components/paper-checkbox/paper-checkbox.html.erb +104 -0
- data/app/assets/components/paper-dialog/paper-dialog-transition.css +59 -0
- data/app/assets/components/paper-dialog/paper-dialog-transition.html.erb +27 -0
- data/app/assets/components/paper-dialog/paper-dialog.css +0 -0
- data/app/assets/components/paper-dialog/paper-dialog.html.erb +176 -0
- data/app/assets/components/paper-fab/paper-fab.css +27 -0
- data/app/assets/components/paper-fab/paper-fab.html.erb +55 -0
- data/app/assets/components/paper-focusable/paper-focusable.html +144 -0
- data/app/assets/components/paper-icon-button/paper-icon-button.css +17 -0
- data/app/assets/components/paper-icon-button/paper-icon-button.html.erb +87 -0
- data/app/assets/components/paper-input/error-100.png +0 -0
- data/app/assets/components/paper-input/error-200.png +0 -0
- data/app/assets/components/paper-input/paper-input.html.erb +398 -0
- data/app/assets/components/paper-input/paper-input.scss +203 -0
- data/app/assets/components/paper-item/paper-item.css +30 -0
- data/app/assets/components/paper-item/paper-item.html.erb +103 -0
- data/app/assets/components/paper-menu-button/paper-menu-button-overlay.html.erb +86 -0
- data/app/assets/components/paper-menu-button/paper-menu-button-transition.css +19 -0
- data/app/assets/components/paper-menu-button/paper-menu-button-transition.html.erb +118 -0
- data/app/assets/components/paper-menu-button/paper-menu-button.css +86 -0
- data/app/assets/components/paper-menu-button/paper-menu-button.html.erb +128 -0
- data/app/assets/components/paper-progress/paper-progress.css +35 -0
- data/app/assets/components/paper-progress/paper-progress.html.erb +98 -0
- data/app/assets/components/paper-radio-button/paper-radio-button.css +98 -0
- data/app/assets/components/paper-radio-button/paper-radio-button.html.erb +148 -0
- data/app/assets/components/paper-radio-group/paper-radio-group.html.erb +68 -0
- data/app/assets/components/paper-ripple/paper-ripple.html +426 -0
- data/app/assets/components/paper-shadow/paper-shadow.css +81 -0
- data/app/assets/components/paper-shadow/paper-shadow.html.erb +212 -0
- data/app/assets/components/paper-slider/paper-slider.css +193 -0
- data/app/assets/components/paper-slider/paper-slider.html.erb +310 -0
- data/app/assets/components/paper-tabs/paper-tab.css +49 -0
- data/app/assets/components/paper-tabs/paper-tab.html.erb +66 -0
- data/app/assets/components/paper-tabs/paper-tabs.css +57 -0
- data/app/assets/components/paper-tabs/paper-tabs.html.erb +127 -0
- data/app/assets/components/paper-toast/paper-toast.css +0 -0
- data/app/assets/components/paper-toast/paper-toast.html.erb +258 -0
- data/app/assets/components/paper-toggle-button/paper-toggle-button.css +61 -0
- data/app/assets/components/paper-toggle-button/paper-toggle-button.html.erb +125 -0
- data/lib/polymer-paper-rails/engine.rb +4 -0
- data/lib/polymer-paper-rails/version.rb +3 -0
- data/lib/polymer-paper-rails.rb +2 -0
- metadata +158 -0
|
@@ -0,0 +1,106 @@
|
|
|
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
|
+
The `core-range` element is used for managing a numeric value within a given
|
|
12
|
+
range. It has no visual appearance and is typically used in conjunction with
|
|
13
|
+
another element.
|
|
14
|
+
|
|
15
|
+
One can build a progress bar using `core-range` like this:
|
|
16
|
+
|
|
17
|
+
<core-range min="0" max="200" value="100" ratio="{{ratio}}"></core-range>
|
|
18
|
+
<div class="progress-bar" style="width: {{ratio}}%;"></div>
|
|
19
|
+
|
|
20
|
+
@group Polymer Core Elements
|
|
21
|
+
@element core-range
|
|
22
|
+
@homepage github.io
|
|
23
|
+
|
|
24
|
+
-->
|
|
25
|
+
|
|
26
|
+
<polymer-element name="core-range" attributes="value min max step ratio">
|
|
27
|
+
<script>
|
|
28
|
+
|
|
29
|
+
Polymer('core-range', {
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The number that represents the current value.
|
|
33
|
+
*
|
|
34
|
+
* @attribute value
|
|
35
|
+
* @type number
|
|
36
|
+
* @default 0
|
|
37
|
+
*/
|
|
38
|
+
value: 0,
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The number that indicates the minimum value of the range.
|
|
42
|
+
*
|
|
43
|
+
* @attribute min
|
|
44
|
+
* @type number
|
|
45
|
+
* @default 0
|
|
46
|
+
*/
|
|
47
|
+
min: 0,
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The number that indicates the maximum value of the range.
|
|
51
|
+
*
|
|
52
|
+
* @attribute max
|
|
53
|
+
* @type number
|
|
54
|
+
* @default 100
|
|
55
|
+
*/
|
|
56
|
+
max: 100,
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Specifies the value granularity of the range's value.
|
|
60
|
+
*
|
|
61
|
+
* @attribute step
|
|
62
|
+
* @type number
|
|
63
|
+
* @default 1
|
|
64
|
+
*/
|
|
65
|
+
step: 1,
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Returns the ratio of the value.
|
|
69
|
+
*
|
|
70
|
+
* @attribute ratio
|
|
71
|
+
* @type number
|
|
72
|
+
* @default 0
|
|
73
|
+
*/
|
|
74
|
+
ratio: 0,
|
|
75
|
+
|
|
76
|
+
observe: {
|
|
77
|
+
'value min max step': 'update'
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
calcRatio: function(value) {
|
|
81
|
+
return (this.clampValue(value) - this.min) / (this.max - this.min);
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
clampValue: function(value) {
|
|
85
|
+
return Math.min(this.max, Math.max(this.min, this.calcStep(value)));
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
calcStep: function(value) {
|
|
89
|
+
return this.step ? (Math.round(value / this.step) / (1 / this.step)) : value;
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
validateValue: function() {
|
|
93
|
+
var v = this.clampValue(this.value);
|
|
94
|
+
this.value = this.oldValue = isNaN(v) ? this.oldValue : v;
|
|
95
|
+
return this.value !== v;
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
update: function() {
|
|
99
|
+
this.validateValue();
|
|
100
|
+
this.ratio = this.calcRatio(this.value) * 100;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
</script>
|
|
106
|
+
</polymer-element>
|
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
@group Polymer Core Elements
|
|
11
|
+
|
|
12
|
+
The `<core-selection>` element is used to manage selection state. It has no
|
|
13
|
+
visual appearance and is typically used in conjunction with another element.
|
|
14
|
+
For example, [core-selector](#core-selector)
|
|
15
|
+
use a `<core-selection>` to manage selection.
|
|
16
|
+
|
|
17
|
+
To mark an item as selected, call the `select(item)` method on
|
|
18
|
+
`<core-selection>`. The item itself is an argument to this method.
|
|
19
|
+
|
|
20
|
+
The `<core-selection>`element manages selection state for any given set of
|
|
21
|
+
items. When an item is selected, the `core-select` event is fired.
|
|
22
|
+
|
|
23
|
+
The attribute `multi` indicates if multiple items can be selected at once.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
|
|
27
|
+
<polymer-element name="selection-example">
|
|
28
|
+
<template>
|
|
29
|
+
<style>
|
|
30
|
+
polyfill-next-selector { content: ':host > .selected'; }
|
|
31
|
+
::content > .selected {
|
|
32
|
+
font-weight: bold;
|
|
33
|
+
font-style: italic;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
36
|
+
<ul on-tap="{{itemTapAction}}">
|
|
37
|
+
<content></content>
|
|
38
|
+
</ul>
|
|
39
|
+
<core-selection id="selection" multi
|
|
40
|
+
on-core-select="{{selectAction}}"></core-selection>
|
|
41
|
+
</template>
|
|
42
|
+
<script>
|
|
43
|
+
Polymer('selection-example', {
|
|
44
|
+
itemTapAction: function(e, detail, sender) {
|
|
45
|
+
this.$.selection.select(e.target);
|
|
46
|
+
},
|
|
47
|
+
selectAction: function(e, detail, sender) {
|
|
48
|
+
detail.item.classList.toggle('selected', detail.isSelected);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
</script>
|
|
52
|
+
</polymer-element>
|
|
53
|
+
|
|
54
|
+
<selection-example>
|
|
55
|
+
<li>Red</li>
|
|
56
|
+
<li>Green</li>
|
|
57
|
+
<li>Blue</li>
|
|
58
|
+
</selection-example>
|
|
59
|
+
|
|
60
|
+
@element core-selection
|
|
61
|
+
-->
|
|
62
|
+
|
|
63
|
+
<!--
|
|
64
|
+
Fired when an item's selection state is changed. This event is fired both
|
|
65
|
+
when an item is selected or deselected. The `isSelected` detail property
|
|
66
|
+
contains the selection state.
|
|
67
|
+
|
|
68
|
+
@event core-select
|
|
69
|
+
@param {Object} detail
|
|
70
|
+
@param {boolean} detail.isSelected true for selection and false for de-selection
|
|
71
|
+
@param {Object} detail.item the item element
|
|
72
|
+
-->
|
|
73
|
+
|
|
74
|
+
<polymer-element name="core-selection" attributes="multi" hidden>
|
|
75
|
+
<script>
|
|
76
|
+
Polymer('core-selection', {
|
|
77
|
+
/**
|
|
78
|
+
* If true, multiple selections are allowed.
|
|
79
|
+
*
|
|
80
|
+
* @attribute multi
|
|
81
|
+
* @type boolean
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
multi: false,
|
|
85
|
+
ready: function() {
|
|
86
|
+
this.clear();
|
|
87
|
+
},
|
|
88
|
+
clear: function() {
|
|
89
|
+
this.selection = [];
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* Retrieves the selected item(s).
|
|
93
|
+
* @method getSelection
|
|
94
|
+
* @returns Returns the selected item(s). If the multi property is true,
|
|
95
|
+
* getSelection will return an array, otherwise it will return
|
|
96
|
+
* the selected item or undefined if there is no selection.
|
|
97
|
+
*/
|
|
98
|
+
getSelection: function() {
|
|
99
|
+
return this.multi ? this.selection : this.selection[0];
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* Indicates if a given item is selected.
|
|
103
|
+
* @method isSelected
|
|
104
|
+
* @param {any} item The item whose selection state should be checked.
|
|
105
|
+
* @returns Returns true if `item` is selected.
|
|
106
|
+
*/
|
|
107
|
+
isSelected: function(item) {
|
|
108
|
+
return this.selection.indexOf(item) >= 0;
|
|
109
|
+
},
|
|
110
|
+
setItemSelected: function(item, isSelected) {
|
|
111
|
+
if (item !== undefined && item !== null) {
|
|
112
|
+
if (isSelected) {
|
|
113
|
+
this.selection.push(item);
|
|
114
|
+
} else {
|
|
115
|
+
var i = this.selection.indexOf(item);
|
|
116
|
+
if (i >= 0) {
|
|
117
|
+
this.selection.splice(i, 1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
this.fire("core-select", {isSelected: isSelected, item: item});
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Set the selection state for a given `item`. If the multi property
|
|
125
|
+
* is true, then the selected state of `item` will be toggled; otherwise
|
|
126
|
+
* the `item` will be selected.
|
|
127
|
+
* @method select
|
|
128
|
+
* @param {any} item: The item to select.
|
|
129
|
+
*/
|
|
130
|
+
select: function(item) {
|
|
131
|
+
if (this.multi) {
|
|
132
|
+
this.toggle(item);
|
|
133
|
+
} else if (this.getSelection() !== item) {
|
|
134
|
+
this.setItemSelected(this.getSelection(), false);
|
|
135
|
+
this.setItemSelected(item, true);
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* Toggles the selection state for `item`.
|
|
140
|
+
* @method toggle
|
|
141
|
+
* @param {any} item: The item to toggle.
|
|
142
|
+
*/
|
|
143
|
+
toggle: function(item) {
|
|
144
|
+
this.setItemSelected(item, !this.isSelected(item));
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
</script>
|
|
148
|
+
</polymer-element>
|
|
@@ -0,0 +1,423 @@
|
|
|
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
|
+
|
|
13
|
+
`<core-selector>` is used to manage a list of elements that can be selected.
|
|
14
|
+
|
|
15
|
+
The attribute `selected` indicates which item element is being selected.
|
|
16
|
+
The attribute `multi` indicates if multiple items can be selected at once.
|
|
17
|
+
Tapping on the item element would fire `core-activate` event. Use
|
|
18
|
+
`core-select` event to listen for selection changes.
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
|
|
22
|
+
<core-selector selected="0">
|
|
23
|
+
<div>Item 1</div>
|
|
24
|
+
<div>Item 2</div>
|
|
25
|
+
<div>Item 3</div>
|
|
26
|
+
</core-selector>
|
|
27
|
+
|
|
28
|
+
`<core-selector>` is not styled. Use the `core-selected` CSS class to style the selected element.
|
|
29
|
+
|
|
30
|
+
<style>
|
|
31
|
+
.item.core-selected {
|
|
32
|
+
background: #eee;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
...
|
|
36
|
+
<core-selector>
|
|
37
|
+
<div class="item">Item 1</div>
|
|
38
|
+
<div class="item">Item 2</div>
|
|
39
|
+
<div class="item">Item 3</div>
|
|
40
|
+
</core-selector>
|
|
41
|
+
|
|
42
|
+
@element core-selector
|
|
43
|
+
@status stable
|
|
44
|
+
@homepage github.io
|
|
45
|
+
-->
|
|
46
|
+
|
|
47
|
+
<!--
|
|
48
|
+
Fired when an item's selection state is changed. This event is fired both
|
|
49
|
+
when an item is selected or deselected. The `isSelected` detail property
|
|
50
|
+
contains the selection state.
|
|
51
|
+
|
|
52
|
+
@event core-select
|
|
53
|
+
@param {Object} detail
|
|
54
|
+
@param {boolean} detail.isSelected true for selection and false for deselection
|
|
55
|
+
@param {Object} detail.item the item element
|
|
56
|
+
-->
|
|
57
|
+
<!--
|
|
58
|
+
Fired when an item element is tapped.
|
|
59
|
+
|
|
60
|
+
@event core-activate
|
|
61
|
+
@param {Object} detail
|
|
62
|
+
@param {Object} detail.item the item element
|
|
63
|
+
-->
|
|
64
|
+
|
|
65
|
+
<%= html_import_tag 'core/selection/core-selection'%>
|
|
66
|
+
|
|
67
|
+
<polymer-element name="core-selector"
|
|
68
|
+
attributes="selected multi valueattr selectedClass selectedProperty selectedAttribute selectedItem selectedModel selectedIndex notap target itemsSelector activateEvent">
|
|
69
|
+
|
|
70
|
+
<template>
|
|
71
|
+
<core-selection id="selection" multi="{{multi}}" on-core-select="{{selectionSelect}}"></core-selection>
|
|
72
|
+
<content id="items" select="*"></content>
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<script>
|
|
76
|
+
|
|
77
|
+
Polymer('core-selector', {
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Gets or sets the selected element. Default to use the index
|
|
81
|
+
* of the item element.
|
|
82
|
+
*
|
|
83
|
+
* If you want a specific attribute value of the element to be
|
|
84
|
+
* used instead of index, set "valueattr" to that attribute name.
|
|
85
|
+
*
|
|
86
|
+
* Example:
|
|
87
|
+
*
|
|
88
|
+
* <core-selector valueattr="label" selected="foo">
|
|
89
|
+
* <div label="foo"></div>
|
|
90
|
+
* <div label="bar"></div>
|
|
91
|
+
* <div label="zot"></div>
|
|
92
|
+
* </core-selector>
|
|
93
|
+
*
|
|
94
|
+
* In multi-selection this should be an array of values.
|
|
95
|
+
*
|
|
96
|
+
* Example:
|
|
97
|
+
*
|
|
98
|
+
* <core-selector id="selector" valueattr="label" multi>
|
|
99
|
+
* <div label="foo"></div>
|
|
100
|
+
* <div label="bar"></div>
|
|
101
|
+
* <div label="zot"></div>
|
|
102
|
+
* </core-selector>
|
|
103
|
+
*
|
|
104
|
+
* this.$.selector.selected = ['foo', 'zot'];
|
|
105
|
+
*
|
|
106
|
+
* @attribute selected
|
|
107
|
+
* @type Object
|
|
108
|
+
* @default null
|
|
109
|
+
*/
|
|
110
|
+
selected: null,
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* If true, multiple selections are allowed.
|
|
114
|
+
*
|
|
115
|
+
* @attribute multi
|
|
116
|
+
* @type boolean
|
|
117
|
+
* @default false
|
|
118
|
+
*/
|
|
119
|
+
multi: false,
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Specifies the attribute to be used for "selected" attribute.
|
|
123
|
+
*
|
|
124
|
+
* @attribute valueattr
|
|
125
|
+
* @type string
|
|
126
|
+
* @default 'name'
|
|
127
|
+
*/
|
|
128
|
+
valueattr: 'name',
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Specifies the CSS class to be used to add to the selected element.
|
|
132
|
+
*
|
|
133
|
+
* @attribute selectedClass
|
|
134
|
+
* @type string
|
|
135
|
+
* @default 'core-selected'
|
|
136
|
+
*/
|
|
137
|
+
selectedClass: 'core-selected',
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Specifies the property to be used to set on the selected element
|
|
141
|
+
* to indicate its active state.
|
|
142
|
+
*
|
|
143
|
+
* @attribute selectedProperty
|
|
144
|
+
* @type string
|
|
145
|
+
* @default ''
|
|
146
|
+
*/
|
|
147
|
+
selectedProperty: '',
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Specifies the attribute to set on the selected element to indicate
|
|
151
|
+
* its active state.
|
|
152
|
+
*
|
|
153
|
+
* @attribute selectedAttribute
|
|
154
|
+
* @type string
|
|
155
|
+
* @default 'active'
|
|
156
|
+
*/
|
|
157
|
+
selectedAttribute: 'active',
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns the currently selected element. In multi-selection this returns
|
|
161
|
+
* an array of selected elements.
|
|
162
|
+
*
|
|
163
|
+
* @attribute selectedItem
|
|
164
|
+
* @type Object
|
|
165
|
+
* @default null
|
|
166
|
+
*/
|
|
167
|
+
selectedItem: null,
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* In single selection, this returns the model associated with the
|
|
171
|
+
* selected element.
|
|
172
|
+
*
|
|
173
|
+
* @attribute selectedModel
|
|
174
|
+
* @type Object
|
|
175
|
+
* @default null
|
|
176
|
+
*/
|
|
177
|
+
selectedModel: null,
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* In single selection, this returns the selected index.
|
|
181
|
+
*
|
|
182
|
+
* @attribute selectedIndex
|
|
183
|
+
* @type number
|
|
184
|
+
* @default -1
|
|
185
|
+
*/
|
|
186
|
+
selectedIndex: -1,
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The target element that contains items. If this is not set
|
|
190
|
+
* core-selector is the container.
|
|
191
|
+
*
|
|
192
|
+
* @attribute target
|
|
193
|
+
* @type Object
|
|
194
|
+
* @default null
|
|
195
|
+
*/
|
|
196
|
+
target: null,
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* This can be used to query nodes from the target node to be used for
|
|
200
|
+
* selection items. Note this only works if the 'target' property is set.
|
|
201
|
+
*
|
|
202
|
+
* Example:
|
|
203
|
+
*
|
|
204
|
+
* <core-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></core-selector>
|
|
205
|
+
* <form id="myForm">
|
|
206
|
+
* <label><input type="radio" name="color" value="red"> Red</label> <br>
|
|
207
|
+
* <label><input type="radio" name="color" value="green"> Green</label> <br>
|
|
208
|
+
* <label><input type="radio" name="color" value="blue"> Blue</label> <br>
|
|
209
|
+
* <p>color = {{color}}</p>
|
|
210
|
+
* </form>
|
|
211
|
+
*
|
|
212
|
+
* @attribute itemSelector
|
|
213
|
+
* @type string
|
|
214
|
+
* @default ''
|
|
215
|
+
*/
|
|
216
|
+
itemsSelector: '',
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* The event that would be fired from the item element to indicate
|
|
220
|
+
* it is being selected.
|
|
221
|
+
*
|
|
222
|
+
* @attribute activateEvent
|
|
223
|
+
* @type string
|
|
224
|
+
* @default 'tap'
|
|
225
|
+
*/
|
|
226
|
+
activateEvent: 'tap',
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Set this to true to disallow changing the selection via the
|
|
230
|
+
* `activateEvent`.
|
|
231
|
+
*
|
|
232
|
+
* @attribute notap
|
|
233
|
+
* @type boolean
|
|
234
|
+
* @default false
|
|
235
|
+
*/
|
|
236
|
+
notap: false,
|
|
237
|
+
|
|
238
|
+
ready: function() {
|
|
239
|
+
this.activateListener = this.activateHandler.bind(this);
|
|
240
|
+
this.observer = new MutationObserver(this.updateSelected.bind(this));
|
|
241
|
+
if (!this.target) {
|
|
242
|
+
this.target = this;
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
get items() {
|
|
247
|
+
if (!this.target) {
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
var nodes = this.target !== this ? (this.itemsSelector ?
|
|
251
|
+
this.target.querySelectorAll(this.itemsSelector) :
|
|
252
|
+
this.target.children) : this.$.items.getDistributedNodes();
|
|
253
|
+
return Array.prototype.filter.call(nodes || [], function(n) {
|
|
254
|
+
return n && n.localName !== 'template';
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
targetChanged: function(old) {
|
|
259
|
+
if (old) {
|
|
260
|
+
this.removeListener(old);
|
|
261
|
+
this.observer.disconnect();
|
|
262
|
+
this.clearSelection();
|
|
263
|
+
}
|
|
264
|
+
if (this.target) {
|
|
265
|
+
this.addListener(this.target);
|
|
266
|
+
this.observer.observe(this.target, {childList: true});
|
|
267
|
+
this.updateSelected();
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
addListener: function(node) {
|
|
272
|
+
node.addEventListener(this.activateEvent, this.activateListener);
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
removeListener: function(node) {
|
|
276
|
+
node.removeEventListener(this.activateEvent, this.activateListener);
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
get selection() {
|
|
280
|
+
return this.$.selection.getSelection();
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
selectedChanged: function() {
|
|
284
|
+
this.updateSelected();
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
updateSelected: function() {
|
|
288
|
+
this.validateSelected();
|
|
289
|
+
if (this.multi) {
|
|
290
|
+
this.clearSelection();
|
|
291
|
+
this.selected && this.selected.forEach(function(s) {
|
|
292
|
+
this.valueToSelection(s);
|
|
293
|
+
}, this);
|
|
294
|
+
} else {
|
|
295
|
+
this.valueToSelection(this.selected);
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
validateSelected: function() {
|
|
300
|
+
// convert to an array for multi-selection
|
|
301
|
+
if (this.multi && !Array.isArray(this.selected) &&
|
|
302
|
+
this.selected !== null && this.selected !== undefined) {
|
|
303
|
+
this.selected = [this.selected];
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
clearSelection: function() {
|
|
308
|
+
if (this.multi) {
|
|
309
|
+
this.selection.slice().forEach(function(s) {
|
|
310
|
+
this.$.selection.setItemSelected(s, false);
|
|
311
|
+
}, this);
|
|
312
|
+
} else {
|
|
313
|
+
this.$.selection.setItemSelected(this.selection, false);
|
|
314
|
+
}
|
|
315
|
+
this.selectedItem = null;
|
|
316
|
+
this.$.selection.clear();
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
valueToSelection: function(value) {
|
|
320
|
+
var item = (value === null || value === undefined) ?
|
|
321
|
+
null : this.items[this.valueToIndex(value)];
|
|
322
|
+
this.$.selection.select(item);
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
updateSelectedItem: function() {
|
|
326
|
+
this.selectedItem = this.selection;
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
selectedItemChanged: function() {
|
|
330
|
+
if (this.selectedItem) {
|
|
331
|
+
var t = this.selectedItem.templateInstance;
|
|
332
|
+
this.selectedModel = t ? t.model : undefined;
|
|
333
|
+
} else {
|
|
334
|
+
this.selectedModel = null;
|
|
335
|
+
}
|
|
336
|
+
this.selectedIndex = this.selectedItem ?
|
|
337
|
+
parseInt(this.valueToIndex(this.selected)) : -1;
|
|
338
|
+
},
|
|
339
|
+
|
|
340
|
+
valueToIndex: function(value) {
|
|
341
|
+
// find an item with value == value and return it's index
|
|
342
|
+
for (var i=0, items=this.items, c; (c=items[i]); i++) {
|
|
343
|
+
if (this.valueForNode(c) == value) {
|
|
344
|
+
return i;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// if no item found, the value itself is probably the index
|
|
348
|
+
return value;
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
valueForNode: function(node) {
|
|
352
|
+
return node[this.valueattr] || node.getAttribute(this.valueattr);
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
// events fired from <core-selection> object
|
|
356
|
+
selectionSelect: function(e, detail) {
|
|
357
|
+
this.updateSelectedItem();
|
|
358
|
+
if (detail.item) {
|
|
359
|
+
this.applySelection(detail.item, detail.isSelected);
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
|
|
363
|
+
applySelection: function(item, isSelected) {
|
|
364
|
+
if (this.selectedClass) {
|
|
365
|
+
item.classList.toggle(this.selectedClass, isSelected);
|
|
366
|
+
}
|
|
367
|
+
if (this.selectedProperty) {
|
|
368
|
+
item[this.selectedProperty] = isSelected;
|
|
369
|
+
}
|
|
370
|
+
if (this.selectedAttribute && item.setAttribute) {
|
|
371
|
+
if (isSelected) {
|
|
372
|
+
item.setAttribute(this.selectedAttribute, '');
|
|
373
|
+
} else {
|
|
374
|
+
item.removeAttribute(this.selectedAttribute);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
// event fired from host
|
|
380
|
+
activateHandler: function(e) {
|
|
381
|
+
if (!this.notap) {
|
|
382
|
+
var i = this.findDistributedTarget(e.target, this.items);
|
|
383
|
+
if (i >= 0) {
|
|
384
|
+
var item = this.items[i];
|
|
385
|
+
var s = this.valueForNode(item) || i;
|
|
386
|
+
if (this.multi) {
|
|
387
|
+
if (this.selected) {
|
|
388
|
+
this.addRemoveSelected(s);
|
|
389
|
+
} else {
|
|
390
|
+
this.selected = [s];
|
|
391
|
+
}
|
|
392
|
+
} else {
|
|
393
|
+
this.selected = s;
|
|
394
|
+
}
|
|
395
|
+
this.asyncFire('core-activate', {item: item});
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
|
|
400
|
+
addRemoveSelected: function(value) {
|
|
401
|
+
var i = this.selected.indexOf(value);
|
|
402
|
+
if (i >= 0) {
|
|
403
|
+
this.selected.splice(i, 1);
|
|
404
|
+
} else {
|
|
405
|
+
this.selected.push(value);
|
|
406
|
+
}
|
|
407
|
+
this.valueToSelection(value);
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
findDistributedTarget: function(target, nodes) {
|
|
411
|
+
// find first ancestor of target (including itself) that
|
|
412
|
+
// is in nodes, if any
|
|
413
|
+
while (target && target != this) {
|
|
414
|
+
var i = Array.prototype.indexOf.call(nodes, target);
|
|
415
|
+
if (i >= 0) {
|
|
416
|
+
return i;
|
|
417
|
+
}
|
|
418
|
+
target = target.parentNode;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
</script>
|
|
423
|
+
</polymer-element>
|