uniform-ui 2.3.7 → 3.0.0.beta4
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 +4 -4
- data/lib/assets/javascripts/uniform.es5.js +1 -1
- data/lib/assets/javascripts/uniform.js +19 -19
- data/lib/assets/javascripts/uniform/checkbox.js +59 -16
- data/lib/assets/javascripts/uniform/component.js +20 -4
- data/lib/assets/javascripts/uniform/dropdown.js +78 -209
- data/lib/assets/javascripts/uniform/floating-label-input.js +63 -0
- data/lib/assets/javascripts/uniform/icons.js +12 -3
- data/lib/assets/javascripts/uniform/modal.js +15 -18
- data/lib/assets/javascripts/uniform/popover.js +45 -29
- data/lib/assets/javascripts/uniform/resizer.js +26 -30
- data/lib/assets/javascripts/uniform/select.js +188 -218
- data/lib/assets/javascripts/uniform/tooltip.js +11 -11
- data/lib/assets/stylesheets/uniform.scss +3 -7
- data/lib/assets/stylesheets/uniform/base.scss +20 -1
- data/lib/assets/stylesheets/uniform/components/buttons.scss +171 -184
- data/lib/assets/stylesheets/uniform/components/checkbox.scss +104 -0
- data/lib/assets/stylesheets/uniform/components/container.scss +3 -2
- data/lib/assets/stylesheets/uniform/components/dropdown.scss +8 -5
- data/lib/assets/stylesheets/uniform/components/floating-label-input.scss +29 -0
- data/lib/assets/stylesheets/uniform/components/input-group.scss +30 -0
- data/lib/assets/stylesheets/uniform/components/label.scss +21 -16
- data/lib/assets/stylesheets/uniform/components/loaders.scss +28 -51
- data/lib/assets/stylesheets/uniform/components/nav.scss +50 -87
- data/lib/assets/stylesheets/uniform/components/pointer.scss +83 -0
- data/lib/assets/stylesheets/uniform/components/select.scss +97 -107
- data/lib/assets/stylesheets/uniform/components/table.scss +31 -138
- data/lib/assets/stylesheets/uniform/components/thumb.scss +40 -25
- data/lib/assets/stylesheets/uniform/components/z-input.scss +20 -0
- data/lib/assets/stylesheets/uniform/defaults.scss +31 -10
- data/lib/assets/stylesheets/uniform/functions.scss +32 -7
- data/lib/assets/stylesheets/uniform/mixins.scss +110 -57
- data/lib/assets/stylesheets/uniform/utilities.scss +55 -0
- data/lib/assets/stylesheets/uniform/utilities/background.scss +9 -0
- data/lib/assets/stylesheets/uniform/utilities/borders.scss +84 -0
- data/lib/assets/stylesheets/uniform/utilities/effects.scss +172 -0
- data/lib/assets/stylesheets/uniform/utilities/layout.scss +174 -0
- data/lib/assets/stylesheets/uniform/utilities/position.scss +42 -0
- data/lib/assets/stylesheets/uniform/utilities/sizing.scss +54 -0
- data/lib/assets/stylesheets/uniform/utilities/spacing.scss +62 -0
- data/lib/assets/stylesheets/uniform/utilities/svg.scss +5 -0
- data/lib/assets/stylesheets/uniform/utilities/text.scss +158 -0
- data/lib/assets/stylesheets/uniform/variables.scss +111 -42
- data/lib/uniform/version.rb +1 -1
- metadata +25 -48
- data/lib/assets/javascripts/uniform.jquery.js +0 -152
- data/lib/assets/javascripts/uniform/dom-helpers.js +0 -158
- data/lib/assets/javascripts/uniform/floating-label.js +0 -54
- data/lib/assets/stylesheets/uniform-print.scss +0 -1
- data/lib/assets/stylesheets/uniform/components.scss +0 -11
- data/lib/assets/stylesheets/uniform/components/alert.scss +0 -72
- data/lib/assets/stylesheets/uniform/components/card.scss +0 -93
- data/lib/assets/stylesheets/uniform/components/form.scss +0 -149
- data/lib/assets/stylesheets/uniform/components/form/checkbox-collection.scss +0 -103
- data/lib/assets/stylesheets/uniform/components/form/checkbox.scss +0 -58
- data/lib/assets/stylesheets/uniform/components/form/floating-label.scss +0 -65
- data/lib/assets/stylesheets/uniform/components/form/input-group.scss +0 -56
- data/lib/assets/stylesheets/uniform/components/form/tristate.scss +0 -88
- data/lib/assets/stylesheets/uniform/components/grid.scss +0 -179
- data/lib/assets/stylesheets/uniform/components/row.scss +0 -67
- data/lib/assets/stylesheets/uniform/components/tooltip.scss +0 -41
- data/lib/assets/stylesheets/uniform/helpers.scss +0 -133
- data/lib/assets/stylesheets/uniform/helpers/border.scss +0 -28
- data/lib/assets/stylesheets/uniform/helpers/colors.scss +0 -24
- data/lib/assets/stylesheets/uniform/helpers/margin.scss +0 -27
- data/lib/assets/stylesheets/uniform/helpers/padding.scss +0 -9
- data/lib/assets/stylesheets/uniform/helpers/position.scss +0 -20
- data/lib/assets/stylesheets/uniform/helpers/sizes.scss +0 -38
- data/lib/assets/stylesheets/uniform/helpers/text.scss +0 -152
- data/lib/assets/stylesheets/uniform/print/grid.scss +0 -50
@@ -0,0 +1,63 @@
|
|
1
|
+
import Component from './component';
|
2
|
+
import { isVisible, isFocus, css, createElement } from 'dolla';
|
3
|
+
|
4
|
+
export default class FloatingLabel extends Component {
|
5
|
+
|
6
|
+
initialize(options){
|
7
|
+
if(options.input instanceof Element) {
|
8
|
+
this.input = options.input
|
9
|
+
} else {
|
10
|
+
this.input = createElement('input', Object.assign({}, {
|
11
|
+
type: this.constructor.type
|
12
|
+
}, options.input)) // TODO filter options to dolla.HTML_ATTRIBUTES
|
13
|
+
}
|
14
|
+
this.label = createElement('label', {
|
15
|
+
for: this.input.id,
|
16
|
+
children: [options.label]
|
17
|
+
});
|
18
|
+
this.input.setAttribute('aria-label', options.label);
|
19
|
+
|
20
|
+
this.el.classList.add('uniformFloatingLabelInput');
|
21
|
+
|
22
|
+
this.listenTo(this.input, 'focus', this.focus);
|
23
|
+
this.listenTo(this.input, 'blur', this.blur);
|
24
|
+
this.listenTo(this.input, 'revealed', this.render);
|
25
|
+
}
|
26
|
+
|
27
|
+
render () {
|
28
|
+
if(!isVisible(this.input)) return;
|
29
|
+
|
30
|
+
let internalHeight = parseInt(css(this.input, 'height')) - parseInt(css(this.input, 'borderTopWidth')) - parseInt(css(this.input, 'borderBottomWidth'));
|
31
|
+
this.input.style.lineHeight = 1;
|
32
|
+
let lineHeight = parseInt(css(this.input, 'lineHeight'));
|
33
|
+
let fontSize = parseInt(css(this.input, 'fontSize'));
|
34
|
+
let padding = internalHeight - lineHeight;
|
35
|
+
|
36
|
+
this.label.style.setProperty('--font-size', css(this.input, 'fontSize'))
|
37
|
+
this.label.style.paddingLeft = css(this.input, 'paddingLeft');
|
38
|
+
this.label.style.lineHeight = lineHeight + "px";
|
39
|
+
this.label.style.paddingTop = (internalHeight/2 - lineHeight) + "px";
|
40
|
+
this.label.style.paddingBottom = (internalHeight/2 - lineHeight) + "px";
|
41
|
+
|
42
|
+
this.input.style.paddingTop = internalHeight/2 - (lineHeight - fontSize) + "px";
|
43
|
+
this.input.style.paddingBottom = (internalHeight/2 - lineHeight) + (lineHeight - fontSize) + "px";
|
44
|
+
|
45
|
+
this.input.parentNode.insertBefore(this.el, this.input.nextSibling);
|
46
|
+
this.el.append(this.input);
|
47
|
+
this.el.append(this.label);
|
48
|
+
|
49
|
+
if(this.input.value != ""){
|
50
|
+
this.focus()
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
focus (e) {
|
55
|
+
this.el.classList.add('present');
|
56
|
+
}
|
57
|
+
|
58
|
+
blur (e) {
|
59
|
+
if(this.input.value == ""){
|
60
|
+
this.el.classList.remove('present');
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
@@ -1,16 +1,25 @@
|
|
1
1
|
let check = `
|
2
|
-
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
2
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32">
|
3
3
|
<path d="M28.998 8.531l-2.134-2.134c-0.394-0.393-1.030-0.393-1.423 0l-12.795 12.795-6.086-6.13c-0.393-0.393-1.029-0.393-1.423 0l-2.134 2.134c-0.393 0.394-0.393 1.030 0 1.423l8.924 8.984c0.393 0.393 1.030 0.393 1.423 0l15.648-15.649c0.393-0.392 0.393-1.030 0-1.423z"></path>
|
4
4
|
</svg>
|
5
5
|
`.trim()
|
6
6
|
|
7
7
|
let arrow_down = `
|
8
|
-
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
8
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
|
9
9
|
<path d="M13.418 7.601c0.271-0.268 0.709-0.268 0.979 0s0.271 0.701 0 0.969l-3.907 3.83c-0.271 0.268-0.709 0.268-0.979 0l-3.908-3.83c-0.27-0.268-0.27-0.701 0-0.969s0.708-0.268 0.979 0l3.418 3.14 3.418-3.14z"></path>
|
10
10
|
</svg>
|
11
11
|
`.trim()
|
12
12
|
|
13
|
+
let x = `
|
14
|
+
<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64" xml:space="preserve">
|
15
|
+
<g><rect x="-2.352" y="29.385" transform="matrix(0.7071 0.7071 -0.7071 0.7071 32.3545 -14.3899)" width="71.799" height="4.95"/></g>
|
16
|
+
<g><rect x="-2.374" y="29.376" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -12.7023 33.0352)" width="71.799" height="4.95"/></g>
|
17
|
+
</svg>
|
18
|
+
|
19
|
+
`.trim()
|
20
|
+
|
13
21
|
export {
|
14
22
|
check,
|
15
|
-
arrow_down
|
23
|
+
arrow_down,
|
24
|
+
x
|
16
25
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import Component from './component';
|
2
|
-
import
|
2
|
+
import {css, trigger, append} from 'dolla';
|
3
3
|
|
4
4
|
/* UniformModal.initialize
|
5
5
|
Options
|
@@ -14,8 +14,9 @@ export default class Modal extends Component {
|
|
14
14
|
this.options = {};
|
15
15
|
this.options.klass = options.klass || false;
|
16
16
|
this.content = options.content;
|
17
|
+
this.el.removeAttribute('content');
|
17
18
|
|
18
|
-
|
19
|
+
this.el.classList.add('uniformModal');
|
19
20
|
this.listenTo(document, 'keyup', this.keyup);
|
20
21
|
this.listenTo(this.el, 'click', this.checkCloseButton);
|
21
22
|
}
|
@@ -27,21 +28,20 @@ export default class Modal extends Component {
|
|
27
28
|
|
28
29
|
render () {
|
29
30
|
var that = this;
|
30
|
-
var content = typeof this.content == 'function' ? this.content() : this.content;
|
31
31
|
|
32
32
|
this.highest_z_index = 0;
|
33
33
|
this.overlay = document.createElement('div');
|
34
|
-
|
34
|
+
this.overlay.classList.add('uniformModal-overlay');
|
35
35
|
|
36
36
|
this.blur = document.createElement('div');
|
37
|
-
|
37
|
+
this.blur.classList.add('uniformModal-blur');
|
38
38
|
|
39
39
|
this.original_scroll = window.scrollY;
|
40
40
|
this.blur.style.top = 0 - this.original_scroll + "px";
|
41
41
|
|
42
42
|
if (document.body.querySelectorAll('.uniformModal').length > 0) {
|
43
43
|
this.highest_z_index = Math.max(Array.prototype.map.call(document.body.querySelectorAll('.uniformModal'), function(el){
|
44
|
-
return parseInt(
|
44
|
+
return parseInt(css(el, 'zIndex'));
|
45
45
|
}));
|
46
46
|
this.el.style.zIndex = this.highest_z_index + 2;
|
47
47
|
}
|
@@ -57,40 +57,37 @@ export default class Modal extends Component {
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
|
60
|
-
|
60
|
+
document.body.classList.add('uniformModal-active');
|
61
61
|
document.body.appendChild(this.blur);
|
62
62
|
document.body.appendChild(this.el);
|
63
63
|
|
64
64
|
var container = document.createElement('div');
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
} else {
|
69
|
-
container.innerHTML = content;
|
70
|
-
}
|
65
|
+
container.classList.add('uniformModal-container');
|
66
|
+
|
67
|
+
append(container, this.content);
|
71
68
|
|
72
69
|
var closeButton = document.createElement('div');
|
73
|
-
|
70
|
+
closeButton.classList.add('uniformModal-close');
|
74
71
|
this.el.appendChild(closeButton);
|
75
72
|
|
76
73
|
this.el.style.top = window.scrollY;
|
77
74
|
this.listenTo(this.overlay, 'click', this.close);
|
78
75
|
this.el.appendChild(container);
|
79
76
|
|
80
|
-
if (this.options.klass)
|
81
|
-
if (content.innerHTML)
|
77
|
+
if (this.options.klass) container.classList.add(this.options.klass);
|
78
|
+
if (this.content.innerHTML) trigger(this.content, 'rendered');
|
82
79
|
this.trigger('rendered');
|
83
80
|
|
84
81
|
return this;
|
85
82
|
}
|
86
83
|
|
87
84
|
checkCloseButton (e) {
|
88
|
-
if(
|
85
|
+
if(e.target.classList.contains('uniformModal-close'))
|
89
86
|
this.close();
|
90
87
|
}
|
91
88
|
|
92
89
|
close () {
|
93
|
-
|
90
|
+
document.querySelectorAll('uniformModal-active').forEach(el => el.classList.remove('uniformModal-active'));
|
94
91
|
var elements = this.blur.children;
|
95
92
|
var elementCount = elements.length
|
96
93
|
for(var i=0; i < elementCount; i++){
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import Component from './component';
|
2
|
-
import
|
2
|
+
import { offset, outerWidth, outerHeight, append } from 'dolla';
|
3
3
|
|
4
4
|
/*
|
5
5
|
Requirements
|
@@ -12,6 +12,7 @@ import * as Helpers from './dom-helpers';
|
|
12
12
|
align: [left|right|center|#px] [top|center|bottom|#px] | default: 'center bottom'
|
13
13
|
zIndex: # | default: unset
|
14
14
|
offset: {left: 0, top: 0}
|
15
|
+
container: element to append popover to. default: document
|
15
16
|
*/
|
16
17
|
export default class Popover extends Component {
|
17
18
|
initialize (options) {
|
@@ -26,7 +27,9 @@ export default class Popover extends Component {
|
|
26
27
|
offset: {left: 0, top: 0}
|
27
28
|
};
|
28
29
|
Object.assign(this.options, this.pick(options, Object.keys(this.options)));
|
30
|
+
this.el.removeAttribute('content');
|
29
31
|
|
32
|
+
this.options.anchor.popover = this
|
30
33
|
this.listenTo(document, 'click', this.checkFocus);
|
31
34
|
this.listenTo(document, 'focusin', this.checkFocus);
|
32
35
|
this.listenTo(document, 'keyup', this.checkEscape);
|
@@ -35,9 +38,10 @@ export default class Popover extends Component {
|
|
35
38
|
});
|
36
39
|
|
37
40
|
if(typeof this.options.container == "string"){
|
38
|
-
this.options.container =
|
39
|
-
this.options.container = this.options.container || document.body
|
41
|
+
this.options.container = this.options.anchor.closest(this.options.container)
|
40
42
|
}
|
43
|
+
this.options.container = this.options.container || document.body
|
44
|
+
|
41
45
|
}
|
42
46
|
|
43
47
|
render () {
|
@@ -45,10 +49,7 @@ export default class Popover extends Component {
|
|
45
49
|
this.el.style.position = 'absolute';
|
46
50
|
this.el.style.zIndex = this.options.zIndex;
|
47
51
|
|
48
|
-
|
49
|
-
this.el.appendChild(this.options.content);
|
50
|
-
else
|
51
|
-
this.el.innerHTML = this.options.content;
|
52
|
+
append(this.el, this.options.content)
|
52
53
|
|
53
54
|
this.options.container.appendChild(this.el);
|
54
55
|
this.resize();
|
@@ -59,7 +60,7 @@ export default class Popover extends Component {
|
|
59
60
|
|
60
61
|
resize () {
|
61
62
|
this.setPosition();
|
62
|
-
|
63
|
+
let bounds = this.el.getBoundingClientRect();
|
63
64
|
const body_bounds = document.body.getBoundingClientRect();
|
64
65
|
const window_bounds = {
|
65
66
|
top: 0,
|
@@ -69,10 +70,14 @@ export default class Popover extends Component {
|
|
69
70
|
};
|
70
71
|
|
71
72
|
var reposition = false;
|
72
|
-
if (bounds.bottom > body_bounds.bottom
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
if (bounds.bottom > Math.max(body_bounds.bottom, window_bounds.bottom)) {
|
74
|
+
var [leftAlign, topAlign] = this.options.align.split(" ");
|
75
|
+
this.setPosition(`${leftAlign} top`);
|
76
|
+
bounds = this.el.getBoundingClientRect()
|
77
|
+
if(bounds.top < 0) {
|
78
|
+
this.setPosition(`${leftAlign} bottom`);
|
79
|
+
}
|
80
|
+
bounds = this.el.getBoundingClientRect()
|
76
81
|
}
|
77
82
|
if (bounds.top < body_bounds.top) {
|
78
83
|
const difference = body_bounds.top - bounds.top
|
@@ -83,6 +88,7 @@ export default class Popover extends Component {
|
|
83
88
|
const difference = body_bounds.left - bounds.left
|
84
89
|
if(this.el.style.left != null) this.el.style.left = parseInt(this.el.style.left) + difference + "px"
|
85
90
|
if(this.el.style.right != null) this.el.style.right = parseInt(this.el.style.right) - difference + "px"
|
91
|
+
bounds = this.el.getBoundingClientRect()
|
86
92
|
}
|
87
93
|
if (bounds.right > body_bounds.right) {
|
88
94
|
const difference = body_bounds.right - bounds.right
|
@@ -96,43 +102,43 @@ export default class Popover extends Component {
|
|
96
102
|
var [leftAlign, topAlign] = align.split(" ");
|
97
103
|
leftAlign = leftAlign || "bottom";
|
98
104
|
|
99
|
-
var
|
105
|
+
var anchorOffset = offset(this.options.anchor);
|
100
106
|
var container = this.options.container;
|
101
107
|
if(getComputedStyle(container)['position'] == "static") container = container.offsetParent;
|
102
108
|
if(!container) container = document.body;
|
103
109
|
|
104
|
-
var containerOffset =
|
105
|
-
|
106
|
-
top:
|
107
|
-
left:
|
110
|
+
var containerOffset = offset(container);
|
111
|
+
anchorOffset = {
|
112
|
+
top: anchorOffset.top - containerOffset.top,
|
113
|
+
left: anchorOffset.left - containerOffset.left
|
108
114
|
}
|
109
115
|
|
110
116
|
var position = {};
|
111
117
|
if(leftAlign == 'left'){
|
112
|
-
position.right =
|
118
|
+
position.right = outerWidth(container) - anchorOffset.left;
|
113
119
|
} else if(leftAlign == 'center'){
|
114
|
-
position.left =
|
120
|
+
position.left = anchorOffset.left + outerWidth(this.options.anchor) / 2 - outerWidth(this.el) / 2;
|
115
121
|
} else if (leftAlign == 'right'){
|
116
|
-
position.left =
|
122
|
+
position.left = anchorOffset.left + outerWidth(this.options.anchor);
|
117
123
|
} else if (leftAlign.includes("px")){
|
118
|
-
position.left =
|
124
|
+
position.left = anchorOffset.left + parseInt(leftAlign);
|
119
125
|
}
|
120
126
|
|
121
127
|
if(topAlign == 'top'){
|
122
|
-
let height =
|
128
|
+
let height = outerHeight(container);
|
123
129
|
if(container == document.body && getComputedStyle(container)['position'] == "static"){
|
124
130
|
height = window.innerHeight;
|
125
131
|
} else if (container == document.body) {
|
126
132
|
height = Math.max(height, document.body.clientHeight);
|
127
133
|
}
|
128
|
-
position.bottom = height -
|
134
|
+
position.bottom = height - anchorOffset.top;
|
129
135
|
} else if(topAlign == 'center'){
|
130
|
-
position.top =
|
136
|
+
position.top = anchorOffset.top + outerHeight(this.options.anchor) / 2;
|
131
137
|
position.transform = "translateY(-50%)";
|
132
138
|
} else if (topAlign == 'bottom'){
|
133
|
-
position.top =
|
139
|
+
position.top = anchorOffset.top + outerHeight(this.options.anchor);
|
134
140
|
} else if (topAlign.includes("px")){
|
135
|
-
position.top =
|
141
|
+
position.top = anchorOffset.top + parseInt(topAlign);
|
136
142
|
}
|
137
143
|
|
138
144
|
if(this.options.offset.left) position.left += parseInt(this.options.offset.left);
|
@@ -145,9 +151,9 @@ export default class Popover extends Component {
|
|
145
151
|
this.el.style.top = null;
|
146
152
|
this.el.style.bottom = null;
|
147
153
|
this.el.style.transform = null;
|
148
|
-
|
149
|
-
|
150
|
-
|
154
|
+
this.el.classList.remove('popover-left', 'popover-right', 'popover-center', 'popover-top', 'popover-bottom');
|
155
|
+
this.el.classList.add('popover-' + topAlign);
|
156
|
+
this.el.classList.add('popover-' + leftAlign);
|
151
157
|
Object.keys(position).forEach(function(key){
|
152
158
|
this.el.style[key] = position[key] + (key != "transform" ? "px" : "");
|
153
159
|
}, this);
|
@@ -160,11 +166,13 @@ export default class Popover extends Component {
|
|
160
166
|
if (e.target == this.options.anchor) return;
|
161
167
|
if (this.el.contains(e.target)) return;
|
162
168
|
if (this.options.anchor.contains(e.target)) return;
|
169
|
+
if (this.persisting) return;
|
163
170
|
this.hide();
|
164
171
|
}
|
165
172
|
|
166
173
|
checkEscape (e) {
|
167
174
|
if(e.which != 27) return;
|
175
|
+
if (this.persisting) return;
|
168
176
|
this.hide();
|
169
177
|
}
|
170
178
|
|
@@ -193,4 +201,12 @@ export default class Popover extends Component {
|
|
193
201
|
flag = flag || this.showing;
|
194
202
|
if(flag) this.hide(); else this.show();
|
195
203
|
}
|
204
|
+
|
205
|
+
persist() {
|
206
|
+
this.persisting = true;
|
207
|
+
}
|
208
|
+
|
209
|
+
unpersist() {
|
210
|
+
this.persisting = false;
|
211
|
+
}
|
196
212
|
}
|
@@ -1,43 +1,39 @@
|
|
1
1
|
import Component from './component';
|
2
|
-
import
|
2
|
+
import { trigger } from 'dolla';
|
3
3
|
|
4
4
|
export default class Resizer extends Component {
|
5
5
|
|
6
6
|
initialize () {
|
7
|
+
const breakpoints = getComputedStyle(window.document.body).getPropertyValue('--breakpoints')
|
8
|
+
this.breakpoints = {}
|
9
|
+
breakpoints.split(",").forEach(breakpoint => {
|
10
|
+
const [key, value] = breakpoint.split("/")
|
11
|
+
this.breakpoints[key.trim()] = value;
|
12
|
+
})
|
13
|
+
|
7
14
|
this.listenTo(window, 'resize', this.resize);
|
8
|
-
|
15
|
+
this.resize();
|
9
16
|
}
|
10
17
|
|
11
18
|
resize () {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
if(width > 1080 && !Helpers.hasClass(this.el, 'lg-size')) {
|
23
|
-
Helpers.addClass(this.el, 'lg-size');
|
24
|
-
Helpers.trigger(window, 'resized-lg');
|
25
|
-
} else if (width < 1080 && Helpers.hasClass(this.el, 'lg-size')) {
|
26
|
-
Helpers.removeClass(this.el, 'lg-size');
|
19
|
+
const width = this.el.offsetWidth;
|
20
|
+
Object.keys(this.breakpoints).forEach(size => {
|
21
|
+
const query = this.breakpoints[size]
|
22
|
+
const css_class = size + '-container'
|
23
|
+
let [attribute, value] = query.split(":")
|
24
|
+
if(value.match("px")){
|
25
|
+
value = parseInt(value)
|
26
|
+
} else {
|
27
|
+
throw "unsupported media units"
|
27
28
|
}
|
28
|
-
|
29
|
-
if(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if(width < 720 && !Helpers.hasClass(this.el, 'sm-size')) {
|
37
|
-
Helpers.addClass(this.el, 'sm-size');
|
38
|
-
Helpers.trigger(window, 'resized-sm');
|
39
|
-
} else if (width > 720 && Helpers.hasClass(this.el, 'sm-size')) {
|
40
|
-
Helpers.removeClass(this.el, 'sm-size');
|
29
|
+
|
30
|
+
if(attribute == "min-width") {
|
31
|
+
this.el.classList.toggle(css_class, width > value)
|
32
|
+
} else if (attribute == "max-width") {
|
33
|
+
this.el.classList.toggle(css_class, width < value)
|
34
|
+
} else {
|
35
|
+
throw "unsupported media feature"
|
41
36
|
}
|
37
|
+
});
|
42
38
|
}
|
43
39
|
}
|
@@ -1,248 +1,218 @@
|
|
1
1
|
import Component from './component';
|
2
2
|
import Popover from './popover';
|
3
3
|
import Modal from './modal';
|
4
|
-
import { check as checkIcon, arrow_down as arrowIcon } from './icons';
|
5
|
-
import
|
4
|
+
import { check as checkIcon, arrow_down as arrowIcon, x as xIcon } from './icons';
|
5
|
+
import { createElement, HTML_ATTRIBUTES, filter, css, isEmpty, trigger } from 'dolla';
|
6
6
|
|
7
7
|
/*
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
options: array of html options, each item can be string | array | object
|
9
|
+
ex. ["Employee", "Manager", "General Manager"]
|
10
|
+
ex. [
|
11
|
+
["Employee", "employee", false],
|
12
|
+
["Manager", "manager", false],
|
13
|
+
["General Manager", "general_manager", true],
|
14
|
+
]
|
15
|
+
ex. [
|
16
|
+
{value: "employee", text: 'Employee', selected: false},
|
17
|
+
{value: "manager", text: 'Manager', selected: false},
|
18
|
+
{value: "general_manager", text: 'General Manager', selected: true}
|
19
|
+
]
|
20
|
+
limit: int | false - number of options to limit to, or false to not limit
|
21
|
+
container: selector for where to render dropdown
|
22
|
+
multiple: false
|
14
23
|
*/
|
15
24
|
export default class Select extends Component {
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
var button = button_options.querySelector('.uniformSelect-show-all');
|
24
|
-
button.parentNode.removeChild(button);
|
25
|
-
|
26
|
-
return false;
|
27
|
-
},
|
28
|
-
limit: 8,
|
29
|
-
container: false
|
26
|
+
initialize (options = {}) {
|
27
|
+
this.htmlOptions = options.options.map(option => {
|
28
|
+
if(typeof option == "string") {
|
29
|
+
return {
|
30
|
+
value: option,
|
31
|
+
text: option
|
30
32
|
}
|
33
|
+
} else if (Array.isArray(option)){
|
34
|
+
return {
|
35
|
+
value: option[1],
|
36
|
+
text: option[0],
|
37
|
+
selected: option[2]
|
38
|
+
}
|
39
|
+
} else if (typeof option == "object") {
|
40
|
+
return option
|
41
|
+
} else {
|
42
|
+
throw "option of unexpected type"
|
43
|
+
}
|
44
|
+
});
|
45
|
+
this.options = {
|
46
|
+
multiple: false,
|
47
|
+
limit: 8,
|
48
|
+
container: false
|
49
|
+
}
|
50
|
+
Object.assign(this.options, this.pick(options, Object.keys(this.options)));
|
31
51
|
|
32
|
-
|
52
|
+
this.el_options = Object.assign({}, this.pick(options, HTML_ATTRIBUTES));
|
53
|
+
this.el = createElement('button', this.el_options);
|
54
|
+
this.el.classList.add('uniformSelect');
|
33
55
|
|
34
|
-
|
35
|
-
|
36
|
-
|
56
|
+
this.listenTo(this.el, 'click', this.toggleOptions);
|
57
|
+
this.listenTo(this.el, 'click', '.uniformSelect-remove', this.removeSelection);
|
58
|
+
this.listenTo(this.el, 'change', 'select', this.renderValue);
|
59
|
+
this.listenTo(this.el, 'close', 'select', this.removeOptions);
|
60
|
+
}
|
61
|
+
|
62
|
+
render () {
|
63
|
+
this.valueEl = createElement('span');
|
64
|
+
this.valueEl.classList.add('uniformSelect-value')
|
65
|
+
this.el.append(this.valueEl);
|
37
66
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
}
|
67
|
+
this.indicatorEl = createElement('span', {children: arrowIcon})
|
68
|
+
this.indicatorEl.classList.add('uniformSelect-indicator')
|
69
|
+
this.el.append(this.indicatorEl);
|
42
70
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
71
|
+
this.select = createElement('select', this.el_options);
|
72
|
+
this.htmlOptions.forEach(option => {
|
73
|
+
this.select.append(createElement('option', Object.assign({}, {children: option.text}, option)))
|
74
|
+
});
|
75
|
+
this.el.append(this.select);
|
47
76
|
|
48
|
-
this.activeIcon.parentNode.removeChild(this.activeIcon);
|
49
|
-
delete this.activeIcon;
|
50
77
|
|
51
|
-
|
52
|
-
|
78
|
+
// Append placeholder of longest option, to set width
|
79
|
+
const longestText = this.htmlOptions.map(x => x.text).sort((a, b) => a.length < b.length)[0]
|
80
|
+
const placeholder = createElement('span', {class: 'uniformSelect-placeholder', children: longestText})
|
81
|
+
this.el.append(placeholder);
|
53
82
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
}
|
58
|
-
}
|
83
|
+
this.renderValue();
|
84
|
+
return this;
|
85
|
+
}
|
59
86
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
if (this.el.name) {
|
69
|
-
Helpers.addClass(this.edit_button, this.el.name.toLowerCase().replace(/[^a-z0-9\-_]+/g, '-'));
|
70
|
-
}
|
71
|
-
this.el.style.display = "none";
|
72
|
-
this.el.insertAdjacentElement('beforebegin', this.edit_button);
|
73
|
-
if(!this.options.container) {
|
74
|
-
this.options.container = this.edit_button.parentElement
|
75
|
-
}
|
76
|
-
|
77
|
-
// Set Min-Width for when empty
|
78
|
-
const option = this.el.querySelectorAll("option")[0];
|
79
|
-
this.edit_button.querySelector('.text-js').style.opacity = 0;
|
80
|
-
this.edit_button.querySelector('.text-js').innerHTML = option.textContent;
|
81
|
-
const min_width = this.edit_button.querySelector('.text-js').offsetWidth;
|
82
|
-
this.edit_button.style.minWidth = min_width + "px";
|
83
|
-
this.edit_button.querySelector('.text-js').innerHTML = "";
|
84
|
-
this.edit_button.querySelector('.text-js').style.opacity = null;
|
87
|
+
renderValue () {
|
88
|
+
const selectedOptions = filter(this.select.querySelectorAll("option"), el => el.selected);
|
89
|
+
const html = selectedOptions.map(el => this.options.multiple ? `
|
90
|
+
<span class="uniformSelect-selection">
|
91
|
+
<span>${el.textContent}</span><span class="uniformSelect-remove">${xIcon}</span>
|
92
|
+
</span>
|
93
|
+
` : el.textContent).join(" ");
|
85
94
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
95
|
+
this.valueEl.innerHTML = html;
|
96
|
+
}
|
97
|
+
|
98
|
+
selectOption (e) {
|
99
|
+
const makeActive = !e.target.option.selected;
|
100
|
+
if (!this.options.multiple && makeActive) {
|
101
|
+
e.target.offsetParent.querySelectorAll('.active').forEach(el => el.classList.remove('active'));
|
92
102
|
}
|
93
|
-
|
94
|
-
|
95
|
-
this.button_options = Helpers.createElement("<div class='uniformSelect-options'>");
|
96
|
-
if (this.el.name) {
|
97
|
-
Helpers.addClass(this.button_options, this.el.name.toLowerCase().replace(/[^a-z0-9\-_]+/g, '-'));
|
98
|
-
}
|
99
|
-
this.button_options.style.fontSize = Helpers.css(this.el, 'font-size');
|
103
|
+
e.target.classList.toggle('active', makeActive);
|
104
|
+
e.target.option.selected = makeActive;
|
100
105
|
|
101
|
-
|
102
|
-
|
103
|
-
button.option = el;
|
104
|
-
button.textContent = el.textContent;
|
105
|
-
button.value = el.value;
|
106
|
-
if (button.textContent == "") button.innerHTML = "<span class='text-italic text-muted'>None</span>";
|
107
|
-
if(el.selected){
|
108
|
-
Helpers.addClass(button, 'active');
|
109
|
-
button.append(this.activeIcon.cloneNode(true));
|
110
|
-
} else if (this.options.limit && index > this.options.limit) {
|
111
|
-
Helpers.addClass(button, 'hide');
|
112
|
-
}
|
113
|
-
this.button_options.append(button);
|
114
|
-
}.bind(this));
|
115
|
-
|
116
|
-
this.listenTo(this.button_options, 'click', '.uniformSelect-option', this.selectOption);
|
117
|
-
|
118
|
-
const actions_el = Helpers.createElement('<div class="uniformSelect-options-actions"></div>');
|
119
|
-
if (this.options.limit && this.el.querySelectorAll('option').length > this.options.limit) {
|
120
|
-
const show_all_button = Helpers.createElement("<button type='button' class='uniformSelect-show-all outline blue' style='display: block; border: none'>Show All</button>");
|
121
|
-
this.listenTo(show_all_button, 'click', function(e){
|
122
|
-
Helpers.trigger(this.el, 'show_all');
|
123
|
-
if (this.options.showAll) this.options.showAll(this.button_options);
|
124
|
-
e.preventDefault();
|
125
|
-
e.stopPropagation();
|
126
|
-
})
|
127
|
-
actions_el.appendChild(show_all_button);
|
128
|
-
}
|
129
|
-
if (this.el.multiple) {
|
130
|
-
var done_button = Helpers.createElement("<button type='button' class='uniformSelect-done block outline blue'>Done</button>");
|
131
|
-
this.listenTo(done_button, 'click', this.hideOptions);
|
132
|
-
actions_el.appendChild(done_button);
|
133
|
-
}
|
134
|
-
if (!Helpers.is_empty(actions_el)) {
|
135
|
-
this.button_options.appendChild(actions_el);
|
136
|
-
}
|
106
|
+
if (!this.options.multiple) {
|
107
|
+
this.removeOptions();
|
137
108
|
}
|
138
|
-
|
139
|
-
renderSelected () {
|
140
|
-
const selected_options = Helpers.filter(this.el.querySelectorAll("option"), function(el){
|
141
|
-
return el.selected;
|
142
|
-
});
|
143
|
-
const html = Helpers.map(selected_options, function(el){
|
144
|
-
return this.el.multiple ? `<span class="uniformSelect-selection">${el.textContent}<span class="uniformSelect-remove"></span></span>` : el.textContent;
|
145
|
-
}.bind(this)).join(" ");
|
146
109
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
110
|
+
trigger(this.select, 'change');
|
111
|
+
}
|
112
|
+
|
113
|
+
removeSelection (e) {
|
114
|
+
e.preventDefault();
|
115
|
+
e.stopPropagation();
|
116
|
+
var option = filter(this.select.querySelectorAll("option"), function(el){
|
117
|
+
return el.innerText.trim() == e.target.closest('.uniformSelect-selection').innerText.trim();
|
118
|
+
})[0];
|
119
|
+
if(!option) return;
|
120
|
+
option.selected = false;
|
121
|
+
option.button.classList.remove('active');
|
152
122
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
Helpers.removeClass(el, 'active');
|
160
|
-
Helpers.each(el.querySelectorAll('.uniformSelect-option-icon'), Helpers.remove);
|
161
|
-
}
|
162
|
-
}.bind(this))
|
163
|
-
}
|
123
|
+
trigger(this.select, 'change');
|
124
|
+
}
|
125
|
+
|
126
|
+
toggleOptions (e) {
|
127
|
+
if(e && (e.target.matches('.uniformSelect-remove') || e.target.closest('.uniformSelect-remove'))){
|
128
|
+
return;
|
164
129
|
}
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
this.button_options_popover.remove();
|
171
|
-
delete this.button_options_popover;
|
172
|
-
}
|
173
|
-
Helpers.removeClass(this.edit_button, 'active');
|
130
|
+
this.el.classList.toggle('active')
|
131
|
+
if(this.el.contains('active')){
|
132
|
+
this.renderOptions()
|
133
|
+
} else {
|
134
|
+
this.removeOptions()
|
174
135
|
}
|
136
|
+
}
|
175
137
|
|
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
|
-
} else {
|
204
|
-
this.button_options.style.minWidth = this.edit_button.offsetWidth + "px";
|
205
|
-
this.button_options_popover = new Popover({
|
206
|
-
offset: {top: 1},
|
207
|
-
anchor: this.edit_button,
|
208
|
-
align: '0px bottom',
|
209
|
-
content: this.button_options,
|
210
|
-
container: this.options.container
|
211
|
-
}).render()
|
212
|
-
this.button_options_popover.on('hidden', () => {
|
213
|
-
Helpers.removeClass(this.edit_button, 'active');
|
214
|
-
this.button_options_popover.remove();
|
215
|
-
delete this.button_options_popover;
|
216
|
-
})
|
217
|
-
}
|
218
|
-
}
|
138
|
+
renderOptions () {
|
139
|
+
const options = createElement("div", {
|
140
|
+
class: 'uniformSelect-options'
|
141
|
+
});
|
142
|
+
|
143
|
+
options.style.fontSize = css(this.el, 'font-size')
|
144
|
+
|
145
|
+
this.select.querySelectorAll('option').forEach(function(option, index){
|
146
|
+
var button = createElement("button", {
|
147
|
+
type: 'button',
|
148
|
+
class: 'uniformSelect-option'
|
149
|
+
});
|
150
|
+
button.option = option;
|
151
|
+
option.button = button;
|
152
|
+
button.textContent = option.textContent;
|
153
|
+
button.value = option.value;
|
154
|
+
if (button.textContent == "") button.innerHTML = "<span class='text-italic text-muted'>None</span>";
|
155
|
+
button.classList.toggle('active', option.selected);
|
156
|
+
|
157
|
+
console.log(this.options.limit, index);
|
158
|
+
if (this.options.limit && (index + 1) > this.options.limit) {
|
159
|
+
button.classList.add('hide')
|
160
|
+
}
|
161
|
+
options.append(button);
|
162
|
+
}, this);
|
163
|
+
|
164
|
+
this.listenTo(options, 'click', '.uniformSelect-option', this.selectOption);
|
219
165
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
Helpers.removeClass(this.button_options.querySelectorAll('.uniformSelect-option.active'), 'active');
|
225
|
-
}
|
226
|
-
Helpers.toggleClass(e.target, 'active');
|
227
|
-
e.target.option.selected = Helpers.hasClass(e.target, 'active');
|
228
|
-
if (Helpers.hasClass(e.target, 'active')) {
|
229
|
-
e.target.append(this.activeIcon.cloneNode(true));
|
230
|
-
} else {
|
231
|
-
Helpers.each(e.target.querySelectorAll('.uniformSelect-option-icon'), Helpers.remove);
|
232
|
-
}
|
233
|
-
if (!this.el.multiple) {
|
234
|
-
this.hideOptions();
|
235
|
-
}
|
236
|
-
Helpers.trigger(this.el, 'change');
|
237
|
-
}
|
166
|
+
|
167
|
+
const actions = createElement('div', {
|
168
|
+
class: 'uniformSelect-actions'
|
169
|
+
});
|
238
170
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
171
|
+
if (this.options.limit && this.htmlOptions.length > this.options.limit) {
|
172
|
+
const button = createElement('button', {
|
173
|
+
type: 'button',
|
174
|
+
class: 'uniformSelect-show-all',
|
175
|
+
children: 'Show All'
|
176
|
+
});
|
177
|
+
this.listenTo(button, 'click', this.showAllOptions.bind(this))
|
178
|
+
actions.append(button);
|
179
|
+
}
|
180
|
+
if (this.options.multiple) {
|
181
|
+
const button = createElement('button', {
|
182
|
+
type: 'button',
|
183
|
+
class: 'uniformSelect-done',
|
184
|
+
children: ['Done']
|
185
|
+
});
|
186
|
+
this.listenTo(button, 'click', this.removeOptions.bind(this));
|
187
|
+
actions.append(button);
|
247
188
|
}
|
189
|
+
if (!isEmpty(actions)) {
|
190
|
+
options.append(actions);
|
191
|
+
}
|
192
|
+
|
193
|
+
this.popover = new Popover({
|
194
|
+
offset: {top: 1},
|
195
|
+
align: '0px bottom',
|
196
|
+
anchor: this.el,
|
197
|
+
content: options,
|
198
|
+
container: this.options.container
|
199
|
+
}).render()
|
200
|
+
|
201
|
+
this.listenTo(this.popover, 'hidden', this.removeOptions);
|
202
|
+
}
|
203
|
+
|
204
|
+
removeOptions () {
|
205
|
+
this.el.classList.remove('active')
|
206
|
+
if(!this.popover) return;
|
207
|
+
this.popover.remove()
|
208
|
+
}
|
209
|
+
|
210
|
+
showAllOptions (e) {
|
211
|
+
e.preventDefault();
|
212
|
+
e.stopPropagation();
|
213
|
+
if(!this.popover) return;
|
214
|
+
this.popover.el.querySelectorAll('button.hide').forEach(el => el.classList.remove('hide'));
|
215
|
+
var button = this.popover.el.querySelector('.uniformSelect-show-all');
|
216
|
+
button.parentNode.removeChild(button);
|
217
|
+
}
|
248
218
|
}
|