@litejs/ui 26.2.0 → 26.3.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.
package/css/base.css CHANGED
@@ -91,4 +91,8 @@ button,
91
91
  user-select: none;
92
92
  }
93
93
 
94
+ .no-scroll {
95
+ overflow: hidden;
96
+ }
97
+
94
98
 
package/el/dialog.ui CHANGED
@@ -1,15 +1,15 @@
1
1
 
2
2
  %css
3
3
  .Modal {
4
+ overflow: auto;
5
+ overscroll-behavior: contain;
4
6
  z-index: 9;
5
7
  }
6
8
  .Modal-bg {
7
- position: absolute;
8
- position: static;
9
9
  background-color: rgba(0, 0, 0, .6);
10
+ pointer-events: none;
10
11
  }
11
12
  .Modal-content {
12
- position: absolute;
13
13
  left: 0;
14
14
  right: 0;
15
15
  margin: 0 auto;
@@ -59,111 +59,100 @@
59
59
  // { "action": "no", "title": "No", "icon": "images/no.png" }
60
60
  // ]
61
61
  %js
62
- $ui.on("modal", function(title, opts, next) {
63
- El.blur()
64
- if (!next && typeof opts === "function") {
65
- next = opts
66
- opts = null
62
+ $ui.on("modal", function(title, opts) {
63
+ var oldFocus = document.activeElement
64
+ , modal = El("Modal")
65
+ , el = El("Dialog.Modal-content.Modal--blur.abs")
66
+ , scope = El.scope(el, el, typeof opts === "string" ? { body: opts } : opts)
67
+ , kbMap = {
68
+ bubble: 1, input: 1,
69
+ tab: function(e) {
70
+ var items = $$("a[href],:is(button,input,select,textarea):not(:disabled),[tabindex]:not([tabindex='-1'])", modal)
71
+ , last = items.length - 1
72
+ if (document.activeElement === items[e.shiftKey ? 0 : last]) {
73
+ items[e.shiftKey ? last : 0].focus()
74
+ El.stop(e)
75
+ }
76
+ }
67
77
  }
68
- var sound, vibrate
69
- , code = ""
70
- , el = El("Dialog")
71
- , scope = Object.assign(El.scope(el, el), opts)
72
- , kbMap = {}
73
78
  , body = document.body
74
- , blurEl = $(scope.blur) || $ui.root.lastChild
75
- scope.title = title || "Confirm?"
79
+ , scrollEl = document.scrollingElement || document.documentElement
80
+ , vibrate = scope.vibrate && navigator.vibrate
81
+ , sound = scope.sound && window.Audio && new Audio(scope.sound)
82
+ scope.title = title
76
83
  if (!scope.actions) scope.actions = [
77
- { action: "close", title: "Close", key: "esc" }
84
+ { title: "Close", key: "esc" }
78
85
  ]
79
- for (var a, i = 0; a = scope.actions[i++]; ) {
80
- if (typeof a == "string") a = scope.actions[i-1] = {title:a,action:a}
81
- if (a.key) kbMap[a.key] = resolve.bind(el, el, a.action)
82
- }
83
- El.cls(blurEl, "Modal--blur")
84
- var mm = El("Modal")
85
- El.append(mm, el)
86
- El.append(body, mm)
87
- El.render(mm)
88
- if (scope.code) {
89
- $$(".js-numpad", el).on("click", numpad)
90
- kbMap.backspace = kbMap.del = kbMap.num = numpad
91
- }
92
- El.addKb(kbMap, el)
93
- $$(".js-btn", el).on("click", resolve)
94
- $ui.one("show", resolve)
95
- if (scope.bgClose) El.on(el, "click", resolve)
96
- El.on(el, "wheel", El.stop)
97
- El.on(el.lastChild, "click", El.stop)
98
- if (scope.vibrate && navigator.vibrate) {
99
- vibrate = navigator.vibrate(scope.vibrate)
86
+ for (var a, i = 0; (a = scope.actions[i++]); ) {
87
+ if (typeof a === "string") a = scope.actions[i - 1] = { title: a, action: a }
88
+ if (a.key) kbMap[a.key] = resolve.bind(el, a.action)
100
89
  }
101
- if (scope.sound && window.Audio) {
102
- sound = new Audio(scope.sound)
103
- sound.play()
90
+ El.append(modal, el)
91
+ if (scope.el) El.append(el, El(scope.el))
92
+ El.append(body, modal)
93
+ El.render(modal)
94
+ El.addKb(kbMap, modal)
95
+ if (El.closest(document.activeElement, 'form') !== el) {
96
+ el.focus()
104
97
  }
105
- function numpad(e, _num) {
106
- // Enter pressed on focused element
107
- if (_num == void 0 && e.clientX == 0) return
108
- var num = _num == void 0 ? e.target[El.T] : _num
109
- code += num
110
- if (num == "CLEAR" || num == "del" || num == "backspace") code = ""
111
- El.md($(".js-body", el), code.replace(/./g, "•") || opts.body)
112
- if (typeof scope.code == "number" && code.length == scope.code && id && !sent) next(sent = code, id, resolve, reject)
113
- }
114
- function resolve(e, key) {
115
- if (el) {
116
- var action = key || El.get(this, "data-action")
117
- , result = {
118
- code: code,
119
- input: El.val($(".js-input", el)),
120
- inputMd: El.val($(".js-inputMd", el)),
121
- select: El.val($(".js-select", el))
122
- }
123
- El.kill(mm, "transparent")
124
- El.cls(blurEl, "Modal--blur", el = false)
125
- if (action && next) {
126
- if (typeof next === "function") next(action, result)
127
- else if (typeof next[action] === "function") next[action](result)
128
- else if (next[action]) $ui.emit(next[action], result)
129
- }
130
- if (vibrate) navigator.vibrate(0)
98
+ El.on(el, "click", function(e) {
99
+ console.log("click1 resolve")
100
+ resolve(El.get(e.target, "data-action"), e)
101
+ }, "[data-action]")
102
+ El.cls(el, "Modal--blur",!1,1)
103
+ $ui.emit("modalOpen", scope)
104
+ $ui.one("show", function() { resolve() })
105
+ El.on(modal.firstChild, "click", function() {
106
+ console.log("click resolve")
107
+ resolve()
108
+ })
109
+ if (vibrate) vibrate(scope.vibrate)
110
+ if (sound) sound.play()
111
+ El.cls(scrollEl, "no-scroll")
112
+ function resolve(action, e) {
113
+ if (modal) {
114
+ El.stop(e)
115
+ El.cls(scrollEl, "no-scroll", 0)
116
+ El.kill(modal, "transparent", 1)
117
+ if (vibrate) vibrate(0)
131
118
  if (sound) sound.pause()
119
+ modal = null
120
+ if (action) {
121
+ $ui.emit(scope.event || "modal:" + action, El.val(el), scope)
122
+ }
123
+ $ui.emit("modalClose", scope)
124
+ if (oldFocus) oldFocus.focus()
132
125
  }
133
126
  }
134
- scope.resolve = resolve
135
- $ui.emit("modal:open", scope)
136
127
  })
137
128
 
138
- %el Dialog-numpad
139
- .row.js-numpad
140
- @click ".btn", function(){}
141
- ;each! "num",[1,2,3,4,5,6,7,8,9,"CLEAR",0]
142
- .col.w4>.btn {num}
143
-
144
- %js
145
- $ui.on("showDialog", function(e, el, dialog) {
146
- console.log("showDialog", El.scope(el), arguments)
147
- El.kill(dialog)
148
- })
129
+ %el Modal
130
+ .Modal.fix.max.anim>.Modal-bg.abs.max
149
131
 
150
132
  %el Dialog
151
- .Dialog.grid.p2.anim
152
- .col.ts3 ;txt! _(title, map)
153
- .col.js-body ;md! _(body, map)
154
- .col
155
- .group ;each! action in actions
156
- .btn.js-btn
157
- ;txt! _(action.title)
158
- ;class! "w" + (12/actions.length)
159
- ;nop! this.focus()
160
- ;set! "data-action", action.action
161
- ;class! "is-" + action.action, action.action
133
+ form.Dialog.grid.p2.anim[action="javascript:"][method=POST][tabindex='-1']
134
+ .col>h1 ;txt title
135
+ .col ;if body; d body
136
+ %slot
137
+ .col.group
138
+ button.btn.js-action
139
+ ;each! 'action',actions
140
+ ;set! "data-action", action.action||"-"
141
+ ;txt _(action.title)
142
+ ;cls! "w" + (12/actions.length)
143
+ ;cls! action.action && "is-" + action.action, action.action
162
144
 
163
- %el Modal
164
- .Modal.max.fix.anim
165
- .Modal-bg.max.abs
166
- .Modal-content.Modal--blur.grid.p2.anim
167
- ;cls! "Modal--blur",!1,1
168
- %slot
145
+ %el Dialog-input
146
+ .col
147
+ input.field[name=value][type=text][placeholder="Enter value"] ;focus
148
+
149
+ %el Dialog-numpad
150
+ .grid.p1.js-numpad
151
+ @click function(e,b,n,v){$s.in.value=(v=$s.in.value,n=b[El.T])>-1?v+n:n=='DEL'?v.slice(0,-1):'',$s.in.focus()},'.btn'
152
+ ;kb!{num:function(e,b,n){$s.in.value=(n)>-1?$s.in.value+n:''},del:function(e,b,n){$s.in.value=$s.in.value.slice(-1)}}
153
+ .col>input[name=code] ;ref!'in';focus
154
+ .col.w4
155
+ ;each! "num",[1,2,3,4,5,6,7,8,9,"CLEAR",0,"DEL"]
156
+ button.btn.w12[type=button]
157
+ ;txt!num
169
158
 
package/el/material.ui ADDED
@@ -0,0 +1,154 @@
1
+
2
+ %css
3
+ .shadow-1 {
4
+ box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
5
+ }
6
+ /**
7
+ * 1. Fix Webkit border-radius cropping for children.
8
+ */
9
+ .Button,
10
+ .Checkbox,
11
+ .Fab,
12
+ .material {
13
+ font-size: 14px;
14
+ font-weight: 500;
15
+ position: relative;
16
+ text-transform: uppercase;
17
+ transition: all .2s cubic-bezier(.4,0,.2,1);
18
+ perspective: 1px; /* 1 */
19
+ }
20
+ .Button:focus,
21
+ .Fab:focus {
22
+ outline: none;
23
+ }
24
+ .Button,
25
+ .Button:disabled:hover {
26
+ background: transparent;
27
+ border: none;
28
+ min-width: 64px;
29
+ height: 36px;
30
+ line-height: 36px;
31
+ border-radius: 2px;
32
+ padding: 0 16px;
33
+ letter-spacing: 0;
34
+ text-align: center;
35
+ }
36
+ .Button.raised,
37
+ .Button:hover {
38
+ background-color: rgba(158,158,158, 0.20);
39
+ }
40
+ .Button:focus {
41
+ background-color: #ddd;
42
+ }
43
+ .raised:focus:not(:active) {
44
+ box-shadow: 0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);
45
+ }
46
+ .Button:disabled {
47
+ color: #aaa;
48
+ background: transparent;
49
+ }
50
+ .Fab {
51
+ border: none;
52
+ border-radius: 50%;
53
+ font-size: 24px;
54
+ height: 56px;
55
+ line-height: 56px;
56
+ width: 56px;
57
+ padding: 0;
58
+ background: rgba(158,158,158,.2);
59
+ }
60
+ .Button.is-warning,
61
+ .Fab--red {
62
+ color: #fff;
63
+ background-color: #f40;
64
+ }
65
+ .Button.is-warning>.waves-ripple,
66
+ .Fab--red>.waves-ripple {
67
+ background-color: #fff;
68
+ }
69
+ .Fab--red>.waves-ripple--play {
70
+ opacity: .6;
71
+ }
72
+ .raised {
73
+ box-shadow: 0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);
74
+ }
75
+ .Checkbox {
76
+ display: block;
77
+ height: 56px;
78
+ line-height: 56px;
79
+ width: 56px;
80
+ }
81
+ .Checkbox-icon {
82
+ overflow: visible;
83
+ display: block;
84
+ height: 50%;
85
+ width: 50%;
86
+ top: 25%;
87
+ left: 25%;
88
+ }
89
+
90
+ %el Checkbox
91
+ label.Checkbox
92
+ input[type=checkbox].hide
93
+ i.Checkbox-icon.waves
94
+
95
+ %el Button
96
+ button[type=button].Button.waves Button
97
+
98
+ %el Fab
99
+ button[type=button].Fab.waves.raised
100
+
101
+ %el Radio
102
+ button[type=button].Radio.waves
103
+
104
+ %css
105
+ .MenuBtn {
106
+ position: relative;
107
+ width: 30px;
108
+ height: 30px;
109
+ background: transparent;
110
+ color: #fff;
111
+ }
112
+ .MenuBtn-x,
113
+ .MenuBtn-x:before,
114
+ .MenuBtn-x:after {
115
+ display: block;
116
+ content: "";
117
+ background-color: currentColor;
118
+ position: absolute;
119
+ width: 100%;
120
+ height: .3em;
121
+ border-radius: .3em;
122
+ pointer-events: none;
123
+ transition-property: transform;
124
+ }
125
+ .MenuBtn-x:before {
126
+ transform: translate(0, -.6em);
127
+ }
128
+ .MenuBtn-x:after {
129
+ transform: translate(0, .6em);
130
+ }
131
+ .MenuBtn--back > .MenuBtn-x,
132
+ .MenuBtn--close > .MenuBtn-x {
133
+ color: #666;
134
+ transform: rotateZ(-180deg);
135
+ }
136
+ .MenuBtn--back > .MenuBtn-x:before {
137
+ transform: rotateZ(45deg) scaleX(.75) translate(0, -230%);
138
+ }
139
+ .MenuBtn--back > .MenuBtn-x:after {
140
+ transform: rotateZ(-45deg) scaleX(.75) translate(0, 230%)
141
+ }
142
+ .MenuBtn--close > .MenuBtn-x {
143
+ background-color: transparent;
144
+ }
145
+ .MenuBtn--close > .MenuBtn-x:before {
146
+ transform: rotateZ(45deg) translate(0, 0);
147
+ }
148
+ .MenuBtn--close > .MenuBtn-x:after {
149
+ transform: rotateZ(-45deg) translate(0, 0);
150
+ }
151
+
152
+ %el MenuBtn
153
+ button[type=button].MenuBtn.reset.noselect
154
+ .MenuBtn-x.anim
package/el/menu.ui ADDED
@@ -0,0 +1,213 @@
1
+
2
+ %css
3
+ .Menu,
4
+ .Tooltip {
5
+ border-radius: 2px;
6
+ position: absolute;
7
+ margin: 0;
8
+ opacity: 0;
9
+ transform: scale(0);
10
+ transition: opacity .4s cubic-bezier(0, 0, .2, 1) 0s, transform .2s cubic-bezier(0, 0, .2, 1) 0s;
11
+ }
12
+ .Tooltip {
13
+ padding: 8px;
14
+ color: #fff;
15
+ background: #666;
16
+ font-weight: 500;
17
+ max-width: 90%;
18
+ text-align: center;
19
+ z-index: 8;
20
+ }
21
+ .Tooltip[data-pos]:before {
22
+ content: "";
23
+ position: absolute;
24
+ display: block;
25
+ width: .4em;
26
+ height: .4em;
27
+ border: .4em solid transparent;
28
+ border-left-color: #666;
29
+ border-top-color: #666;
30
+ }
31
+ .Tooltip[data-pos=top]:before {
32
+ bottom: -.3em;
33
+ left: -.3em;
34
+ margin-left: 50%;
35
+ transform: rotate(225deg);
36
+ }
37
+ .Tooltip[data-pos=bottom]:before {
38
+ top: -.3em;
39
+ left: -.3em;
40
+ margin-left: 50%;
41
+ transform: rotate(45deg);
42
+ }
43
+ .Tooltip[data-pos=right]:before {
44
+ top: 50%;
45
+ left: -.3em;
46
+ margin-top: -.4em;
47
+ transform: rotate(315deg);
48
+ }
49
+ .Tooltip[data-pos=left]:before {
50
+ top: -.3em;
51
+ right: -.3em;
52
+ margin-top: 50%;
53
+ transform: rotate(135deg);
54
+ }
55
+ .Menu {
56
+ padding: 8px 0;
57
+ color: #000;
58
+ background: #fff;
59
+ min-width: 124px;
60
+ max-width: 100%;
61
+ z-index: 7;
62
+ }
63
+ .Menu-item {
64
+ display: block;
65
+ padding: 12px 16px;
66
+ text-decoration: none;
67
+ line-height: 24px;
68
+ cursor: pointer;
69
+ overflow: hidden;
70
+ text-overflow: ellipsis;
71
+ white-space: nowrap;
72
+ }
73
+ .Menu-item:hover {
74
+ background-color: #eee;
75
+ }
76
+ .Menu-item[disabled] {
77
+ color: #bdbdbd;
78
+ background-color: transparent;
79
+ cursor: auto;
80
+ }
81
+ .Menu-item.is-divider {
82
+ border-bottom: 1px solid #ddd;
83
+ }
84
+ .Menu.is-visible,
85
+ .Tooltip.is-visible {
86
+ transform: scale(1);
87
+ opacity: 1;
88
+ }
89
+
90
+ %js
91
+ !function($ui) {
92
+ var menuTarget, menuEl, tipTarget, tipEl
93
+ , html = document.documentElement
94
+ El.near = near
95
+ function near(source, target, x, y, margin) {
96
+ var rect = target.getBoundingClientRect()
97
+ , top = rect.top + El.scrollTop()
98
+ , left = rect.left + El.scrollLeft()
99
+ // svg elements dont have offsetWidth, IE8 does not have rect.width
100
+ , width = rect.width || target.offsetWidth || 0
101
+ , height = rect.height || target.offsetHeight || 0
102
+ if (x == "left") {
103
+ left -= source.offsetWidth + margin
104
+ x = "150%"
105
+ } else if (x == "left-start") {
106
+ left -= margin
107
+ x = "0%"
108
+ } else if (x == "right") {
109
+ left += width + margin
110
+ x = "-50%"
111
+ } else if (x == "right-end") {
112
+ left += width + margin - source.offsetWidth
113
+ x = "100%"
114
+ } else {
115
+ left += (width / 2) - (source.offsetWidth/2)
116
+ x = "50%"
117
+ }
118
+ if (y == "top") {
119
+ top -= margin + source.offsetHeight
120
+ y = " 150%"
121
+ } else if (y == "bottom") {
122
+ top += height + margin
123
+ y = " -50%"
124
+ setTimeout(function() {
125
+ var overflow = top + source.offsetHeight - El.scrollTop() - html.offsetHeight
126
+ if (overflow > 0) scrollBy({ top: overflow, left: 0, behavior: "smooth" })
127
+ }, 400)
128
+ } else {
129
+ top += (height / 2) - (source.offsetHeight/2)
130
+ y = " 50%"
131
+ }
132
+ El.css(source, {
133
+ "transform-origin": x + y,
134
+ top: (top < 0 ? 0 : top) + "px",
135
+ left: (left < 0 ? 0 : left) + "px"
136
+ })
137
+ }
138
+ El.on(html, "mouseover focusin", function(e) {
139
+ var x, y, pos
140
+ , target = e.target
141
+ , text = El.get(target, "data-tooltip")
142
+ if (!e.relatedTarget && e.type !== "focusin" || target === tipTarget) return
143
+ if (!text && tipTarget) {
144
+ if (tipEl && tipEl.contains(target)) return
145
+ for (; target = target.parentNode; ) {
146
+ if (target === tipTarget) return
147
+ }
148
+ }
149
+ closeTooltip()
150
+ if (!text) return
151
+ tipEl = openVisible("pre.Tooltip", tipTarget = target)
152
+ pos = El.get(target, "data-tooltip-pos") || "top"
153
+ El.txt(tipEl, text)
154
+ if (pos === "left" || pos === "right") {
155
+ x = pos
156
+ } else {
157
+ y = pos
158
+ }
159
+ El.set(tipEl, "data-pos", pos)
160
+ near(tipEl, target, x, y, 6)
161
+ })
162
+ $ui.on("show", closeTooltip)
163
+ function openVisible(tag, target) {
164
+ var el = typeof tag == "string" ? El(tag) : tag
165
+ , scope = El.scope(el, target)
166
+ scope.openTarget = target
167
+ El.render(el)
168
+ El.append(document.body, el)
169
+ El.cls(el, "is-visible", 1, 5)
170
+ return el
171
+ }
172
+ function closeVisible(el, delay) {
173
+ if (el) {
174
+ El.kill(el, null, 999)
175
+ El.cls(el, "is-visible", 0, delay)
176
+ }
177
+ }
178
+ function closeTooltip() {
179
+ if (tipEl) {
180
+ closeVisible(tipEl)
181
+ tipTarget = tipEl = null
182
+ }
183
+ }
184
+ function menuClose(e) {
185
+ if (e && e.target == menuTarget) return
186
+ if (menuEl) {
187
+ closeVisible(menuEl, 200)
188
+ El.cls(menuTarget, "is-active", menuEl = menuTarget = null)
189
+ }
190
+ }
191
+ $ui.on("ping,menuClose", menuClose)
192
+ $ui.on("menu", function(e, target, menu, x, y, margin) {
193
+ El.stop(e)
194
+ var close = menuEl && menuTarget == target
195
+ menuClose()
196
+ if (close) return
197
+ menuEl = openVisible(menu, target)
198
+ if (x == "mouse") {
199
+ El.css(menuEl, {
200
+ top: e.pageY + "px",
201
+ left: e.pageX + "px"
202
+ })
203
+ } else {
204
+ El.cls(menuTarget = target, "is-active")
205
+ near(menuEl, target, x, y, margin)
206
+ }
207
+ El.cls(menuEl, "no-events")
208
+ El.on(menuEl, "transitionend", function(e) {
209
+ if (e.propertyName === "transform") El.cls(menuEl, "no-events", 0)
210
+ })
211
+ })
212
+ El.on(html, "click", menuClose)
213
+ }($ui)
package/el/ripple.ui ADDED
@@ -0,0 +1,56 @@
1
+
2
+ %css
3
+ .waves {
4
+ position: relative;
5
+ overflow: hidden;
6
+ }
7
+ .waves-ripple {
8
+ position: absolute;
9
+ border-radius: 50%;
10
+ background-color: #000;
11
+ opacity: 0;
12
+ transform: scale(0);
13
+ transition: opacity .6s cubic-bezier(0, 0, .2, 1) 0s, transform 0s cubic-bezier(0, 0, .2, 1) .6s;
14
+ pointer-events: none;
15
+ }
16
+ .waves-ripple--play {
17
+ opacity: .4;
18
+ transform: scale(1);
19
+ transition: opacity 1s cubic-bezier(0, 0, .2, 1) 0ms, transform .4s cubic-bezier(0, 0, .2, 1) 0ms;
20
+ }
21
+
22
+ %js
23
+ !function() {
24
+ var tick, wait
25
+ , ripple = El(".waves-ripple")
26
+ , html = document.documentElement
27
+ El.on(html, "pointerdown", function(e) {
28
+ var target = e.target
29
+ if (!El.hasClass(target, "waves") || target.disabled) return
30
+ var rect = target.getBoundingClientRect()
31
+ , top = e.clientY - rect.top
32
+ , left = e.clientX - rect.left
33
+ , maxH = Math.max(top, target.offsetHeight - top)
34
+ , maxW = Math.max(left, target.offsetWidth - left)
35
+ , max = 2 * Math.sqrt(maxH * maxH + maxW * maxW)
36
+ El.css(ripple, {
37
+ top: (top - max / 2) + "px",
38
+ left: (left - max / 2) + "px",
39
+ width: max + "px",
40
+ height: max + "px"
41
+ })
42
+ El.append(target, ripple)
43
+ clearTimeout(tick)
44
+ end()
45
+ wait = 1
46
+ tick = setTimeout(end, 600)
47
+ El.one(html, "pointerup", end)
48
+ ripple.offsetTop // force repaint
49
+ El.cls(ripple, "waves-ripple--play")
50
+ })
51
+ function end() {
52
+ if (!(wait--)) {
53
+ El.cls(ripple, "waves-ripple--play", 0)
54
+ }
55
+ }
56
+ }()