beyond-rails 0.0.228 → 0.0.233
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/src/js/components/SearchDropdown.js +27 -15
- data/src/js/components/TagInput.js +144 -0
- data/src/js/decorators/chartCommon.js +6 -8
- data/src/js/index.js +2 -0
- data/src/js/utils/getKey.js +1 -0
- data/src/js/utils/isStr.js +3 -0
- data/src/js/utils/raf.js +8 -0
- data/src/sass/_animations.scss +13 -0
- data/src/sass/_beyond.scss +2 -0
- data/src/sass/_main.scss +4 -0
- data/src/sass/components/_form.scss +3 -0
- data/src/sass/components/_search-dropdown.scss +1 -3
- data/src/sass/components/_tag-input.scss +26 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89c9f25010a6deb7c07fd392f5ba12feeaefb1a46fe0d8b72ba48c4bc5b431d4
|
4
|
+
data.tar.gz: eb9ca399dce141a787cbc0848eabdce20062b0cda24877935b3fc91527177c21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f016a0df26bf377aa5cbeea5b6ac9696b3a20b2e5817faff4c4193263bcdb4e0c167a93197fa16a08db64e54779bf63de780c729fb4c94a88d681331c3aa660d
|
7
|
+
data.tar.gz: 4bb6585874c2bd701aec8ba3851b85c61b1deba91eaabb3ccc90e1657be7ce51f09dd7093d288d4da26be39c1226bf4a34769cbb47d7184ef6a352bd80c93ac5
|
@@ -20,8 +20,11 @@ export default class SearchDropdown {
|
|
20
20
|
this.options.itemClick = options.itemClick || itemClick
|
21
21
|
this.options.change = options.change || noop
|
22
22
|
this.options.wait = options.wait || 50
|
23
|
-
this.place = 'bottom'
|
24
|
-
this.align = 'left'
|
23
|
+
this.place = options.place || 'bottom'
|
24
|
+
this.align = options.align || 'left'
|
25
|
+
this.offset = options.offset || 14
|
26
|
+
this.offsetTop = options.offsetTop || 0
|
27
|
+
this.offsetLeft = options.offsetLeft || 0
|
25
28
|
this.isMenuVisible = false
|
26
29
|
this.lastKeyword = null
|
27
30
|
this.selectedIndex = 0
|
@@ -53,7 +56,16 @@ export default class SearchDropdown {
|
|
53
56
|
}
|
54
57
|
|
55
58
|
appendMenu() {
|
59
|
+
|
56
60
|
const menu = document.createElement('div')
|
61
|
+
const { dataset } = menu
|
62
|
+
|
63
|
+
dataset.place = this.place
|
64
|
+
dataset.align = this.align
|
65
|
+
dataset.offset = this.offset
|
66
|
+
dataset.offsetTop = this.offsetTop
|
67
|
+
dataset.offsetLeft = this.offsetLeft
|
68
|
+
|
57
69
|
menu.className = 'search-dropdown dropdown-menu'
|
58
70
|
|
59
71
|
const inputWrap = document.createElement('div')
|
@@ -100,15 +112,19 @@ export default class SearchDropdown {
|
|
100
112
|
showMenu() {
|
101
113
|
const { input, menu } = this
|
102
114
|
this.getData(input.value)
|
115
|
+
|
103
116
|
menu.style.display = 'block'
|
104
117
|
menu.style.opacity = 0
|
105
118
|
menu.style.transform = 'scale(.8)'
|
106
119
|
document.body.appendChild(menu)
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
120
|
+
|
121
|
+
setTimeout(() => {
|
122
|
+
this.adjustMenuPos()
|
123
|
+
menu.style.transform = 'scale(1)'
|
124
|
+
menu.style.opacity = 1
|
125
|
+
this.isMenuVisible = true
|
126
|
+
this.input.focus()
|
127
|
+
}, 0)
|
112
128
|
}
|
113
129
|
|
114
130
|
toggleMenu() {
|
@@ -116,22 +132,18 @@ export default class SearchDropdown {
|
|
116
132
|
}
|
117
133
|
|
118
134
|
adjustMenuPos() {
|
119
|
-
const { menu, dom } = this
|
120
|
-
const { dataset } = menu
|
121
|
-
const offsetLeft = ('offsetLeft' in dataset) ? parseInt(dataset.offsetLeft, 10) : 0
|
122
|
-
const offsetTop = ('offsetTop' in dataset) ? parseInt(dataset.offsetTop, 10) : 0
|
123
|
-
|
135
|
+
const { menu, dom, offset, offsetLeft, offsetTop } = this
|
124
136
|
const { pos, place, align } = getFloatedTargetPos({
|
125
137
|
src: dom,
|
126
138
|
target: menu,
|
127
139
|
place: this.place,
|
128
140
|
align: this.align,
|
129
|
-
offset
|
141
|
+
offset,
|
130
142
|
offsetLeft,
|
131
143
|
offsetTop
|
132
144
|
})
|
133
|
-
dataset.place = place
|
134
|
-
dataset.align = align
|
145
|
+
menu.dataset.place = place
|
146
|
+
menu.dataset.align = align
|
135
147
|
menu.style.left = toPixel(pos.left)
|
136
148
|
menu.style.top = toPixel(pos.top)
|
137
149
|
}
|
@@ -0,0 +1,144 @@
|
|
1
|
+
import raf from '../utils/raf'
|
2
|
+
import supportDom from '../decorators/supportDom'
|
3
|
+
import getKey from '../utils/getKey'
|
4
|
+
|
5
|
+
@supportDom
|
6
|
+
export default class TagInput {
|
7
|
+
|
8
|
+
constructor(dom, options = {}) {
|
9
|
+
this.dom = dom
|
10
|
+
this.defaultInputWidth = 128
|
11
|
+
this.validate = options.validate || (() => ({ isTag: true }))
|
12
|
+
this.change = options.change || (() => {})
|
13
|
+
this.isComposing = false
|
14
|
+
this.raf = raf
|
15
|
+
this.tags = []
|
16
|
+
this.init()
|
17
|
+
}
|
18
|
+
|
19
|
+
init() {
|
20
|
+
this.setup()
|
21
|
+
this.addEvents()
|
22
|
+
}
|
23
|
+
|
24
|
+
setup() {
|
25
|
+
const input = document.createElement('input')
|
26
|
+
input.type = 'text'
|
27
|
+
input.style.width = this.defaultInputWidth + 'px'
|
28
|
+
this.input = input
|
29
|
+
this.canvas = document.createElement('canvas')
|
30
|
+
this.dom.append(input)
|
31
|
+
}
|
32
|
+
|
33
|
+
getTextWidth(text, font) {
|
34
|
+
const context = this.canvas.getContext('2d')
|
35
|
+
context.font = font
|
36
|
+
const metrics = context.measureText(text)
|
37
|
+
return metrics.width
|
38
|
+
}
|
39
|
+
|
40
|
+
getNextInputWidth(textWidth) {
|
41
|
+
const { defaultInputWidth } = this
|
42
|
+
// spaces before text and after text
|
43
|
+
const delta = 5
|
44
|
+
const nextWidth = textWidth + delta
|
45
|
+
if (nextWidth < defaultInputWidth) {
|
46
|
+
return defaultInputWidth
|
47
|
+
}
|
48
|
+
return nextWidth
|
49
|
+
}
|
50
|
+
|
51
|
+
shake() {
|
52
|
+
this.dom.classList.add('shake')
|
53
|
+
setTimeout(() => {
|
54
|
+
this.dom.classList.remove('shake')
|
55
|
+
}, 500)
|
56
|
+
}
|
57
|
+
|
58
|
+
async addTagIfNeeded(value) {
|
59
|
+
const { input } = this
|
60
|
+
const inputValue = input.value
|
61
|
+
const res = await this.validate(inputValue)
|
62
|
+
if (! res.isTag) {
|
63
|
+
return this.shake()
|
64
|
+
}
|
65
|
+
const classname = res.classname ? ` ${res.classname}` : ''
|
66
|
+
const tag = document.createElement('div')
|
67
|
+
|
68
|
+
tag.className = 'tag' + classname
|
69
|
+
tag.textContent = inputValue
|
70
|
+
|
71
|
+
const btn = document.createElement('button')
|
72
|
+
btn.type = 'button'
|
73
|
+
|
74
|
+
// https://wesbos.com/times-html-entity-close-button
|
75
|
+
btn.textContent = '×'
|
76
|
+
const handleBtnClick = () => {
|
77
|
+
this.tags = this.tags.filter(row => row.elem !== tag)
|
78
|
+
btn.removeEventListener('click', handleBtnClick)
|
79
|
+
tag.remove()
|
80
|
+
this.change(this.tags.slice())
|
81
|
+
}
|
82
|
+
btn.addEventListener('click', handleBtnClick)
|
83
|
+
tag.appendChild(btn)
|
84
|
+
|
85
|
+
this.tags.push({ elem: tag, remove: handleBtnClick, res })
|
86
|
+
this.dom.insertBefore(tag, input)
|
87
|
+
input.value = ''
|
88
|
+
|
89
|
+
this.change(this.tags.slice())
|
90
|
+
}
|
91
|
+
|
92
|
+
removeTagIfNeeded() {
|
93
|
+
const lastTag = this.tags[this.tags.length - 1]
|
94
|
+
if ((this.input.value === '') && lastTag) {
|
95
|
+
lastTag.remove()
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
addEvents() {
|
100
|
+
const { input } = this
|
101
|
+
const font = window.getComputedStyle(input)
|
102
|
+
.getPropertyValue('font')
|
103
|
+
|
104
|
+
this.addEvent(this.dom, 'click', event => {
|
105
|
+
if (event.target === this.dom) {
|
106
|
+
this.input.focus()
|
107
|
+
}
|
108
|
+
})
|
109
|
+
|
110
|
+
this.addEvent(input, 'compositionstart', event => {
|
111
|
+
this.isComposing = true
|
112
|
+
})
|
113
|
+
|
114
|
+
this.addEvent(input, 'compositionend', event => {
|
115
|
+
this.isComposing = false
|
116
|
+
})
|
117
|
+
|
118
|
+
let lastValue = ''
|
119
|
+
|
120
|
+
this.addEvent(input, 'keydown', async event => {
|
121
|
+
const key = getKey(event)
|
122
|
+
if ((key === 'enter') && (! this.isComposing)) {
|
123
|
+
await this.addTagIfNeeded(input.value)
|
124
|
+
}
|
125
|
+
else if ((key === 'backspace') && (lastValue === '')) {
|
126
|
+
this.removeTagIfNeeded()
|
127
|
+
}
|
128
|
+
lastValue = input.value
|
129
|
+
})
|
130
|
+
|
131
|
+
this.addEvent(input, 'input', event => {
|
132
|
+
this.raf(() => {
|
133
|
+
const textWidth = this.getTextWidth(input.value, font)
|
134
|
+
const nextWidth = this.getNextInputWidth(textWidth)
|
135
|
+
input.style.width = nextWidth + 'px'
|
136
|
+
})
|
137
|
+
})
|
138
|
+
}
|
139
|
+
|
140
|
+
destroy() {
|
141
|
+
this.tags.forEach(tag => tag.remove())
|
142
|
+
this.input.remove()
|
143
|
+
}
|
144
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import raf from '../utils/raf'
|
2
2
|
import isUndef from '../utils/isUndef'
|
3
3
|
import { getDomPos, range, toPixel, isFunction } from '../utils'
|
4
4
|
|
@@ -6,6 +6,11 @@ export default function chartCommon(target) {
|
|
6
6
|
|
7
7
|
return class extends target {
|
8
8
|
|
9
|
+
constructor(...args) {
|
10
|
+
super(...args)
|
11
|
+
this.raf = raf
|
12
|
+
}
|
13
|
+
|
9
14
|
init() {
|
10
15
|
this.layers = []
|
11
16
|
if (isFunction(super.init)) {
|
@@ -159,13 +164,6 @@ export default function chartCommon(target) {
|
|
159
164
|
return this.ctx.measureText(value).width
|
160
165
|
}
|
161
166
|
|
162
|
-
raf(fn) {
|
163
|
-
if (isDef(window.requestAnimationFrame)) {
|
164
|
-
return window.requestAnimationFrame(fn)
|
165
|
-
}
|
166
|
-
return fn()
|
167
|
-
}
|
168
|
-
|
169
167
|
removeAllLayers() {
|
170
168
|
const { dom } = this
|
171
169
|
this.layers.forEach(layer => {
|
data/src/js/index.js
CHANGED
@@ -20,6 +20,7 @@ import Navbar from './components/Navbar'
|
|
20
20
|
import Radio from './components/Radio'
|
21
21
|
import SearchDropdown from './components/SearchDropdown'
|
22
22
|
import Sidebar from './components/Sidebar'
|
23
|
+
import TagInput from './components/TagInput'
|
23
24
|
import Tabbox from './components/Tabbox'
|
24
25
|
import Timepicker from './components/Timepicker'
|
25
26
|
import Toast from './components/Toast'
|
@@ -55,6 +56,7 @@ export {
|
|
55
56
|
Radio,
|
56
57
|
SearchDropdown,
|
57
58
|
Sidebar,
|
59
|
+
TagInput,
|
58
60
|
Tabbox,
|
59
61
|
Timepicker,
|
60
62
|
Toast,
|
data/src/js/utils/getKey.js
CHANGED
data/src/js/utils/raf.js
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
@keyframes shake {
|
2
|
+
0% { transform: translate(1px, 1px) rotate(0deg); }
|
3
|
+
10% { transform: translate(-1px, -2px) rotate(-1deg); }
|
4
|
+
20% { transform: translate(-3px, 0px) rotate(1deg); }
|
5
|
+
30% { transform: translate(3px, 2px) rotate(0deg); }
|
6
|
+
40% { transform: translate(1px, -1px) rotate(1deg); }
|
7
|
+
50% { transform: translate(-1px, 2px) rotate(-1deg); }
|
8
|
+
60% { transform: translate(-3px, 1px) rotate(0deg); }
|
9
|
+
70% { transform: translate(3px, 1px) rotate(-1deg); }
|
10
|
+
80% { transform: translate(-1px, -1px) rotate(1deg); }
|
11
|
+
90% { transform: translate(1px, 2px) rotate(0deg); }
|
12
|
+
100% { transform: translate(1px, -2px) rotate(-1deg); }
|
13
|
+
}
|
data/src/sass/_beyond.scss
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
@import './vendor/_turbolink';
|
6
6
|
@import './base/_background';
|
7
7
|
@import './base/_typography';
|
8
|
+
@import './_animations';
|
8
9
|
@import './_main';
|
9
10
|
@import './layout/_border-util';
|
10
11
|
@import './layout/_col';
|
@@ -44,6 +45,7 @@
|
|
44
45
|
@import './components/_tabbox';
|
45
46
|
@import './components/_table';
|
46
47
|
@import './components/_tag';
|
48
|
+
@import './components/_tag-input';
|
47
49
|
@import './components/_time-input';
|
48
50
|
@import './components/_time-menu';
|
49
51
|
@import './components/_toast';
|
data/src/sass/_main.scss
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
.tag-input {
|
2
|
+
cursor: text;
|
3
|
+
background-color: #fff;
|
4
|
+
padding: .4em .4em 0 .4em;
|
5
|
+
min-height: 40px;
|
6
|
+
> input {
|
7
|
+
border: 0;
|
8
|
+
&:focus {
|
9
|
+
outline: none;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
.tag {
|
13
|
+
padding-right: 0;
|
14
|
+
display: inline-flex;
|
15
|
+
align-items: center;
|
16
|
+
margin-right: .7em;
|
17
|
+
margin-bottom: .7em;
|
18
|
+
> button {
|
19
|
+
border: 0;
|
20
|
+
background-color: transparent;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
&.shake {
|
24
|
+
animation: shake .5s;
|
25
|
+
}
|
26
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beyond-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.233
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kmsheng
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-10-
|
12
|
+
date: 2020-10-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sassc
|
@@ -79,6 +79,20 @@ dependencies:
|
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '5.0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: will_paginate
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 3.3.0
|
89
|
+
type: :runtime
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 3.3.0
|
82
96
|
description:
|
83
97
|
email: kmsh3ng@gmail.com
|
84
98
|
executables: []
|
@@ -130,6 +144,7 @@ files:
|
|
130
144
|
- src/js/components/SearchDropdown.js
|
131
145
|
- src/js/components/Sidebar.js
|
132
146
|
- src/js/components/Tabbox.js
|
147
|
+
- src/js/components/TagInput.js
|
133
148
|
- src/js/components/TimeInput.js
|
134
149
|
- src/js/components/TimeMenu.js
|
135
150
|
- src/js/components/Timepicker.js
|
@@ -180,11 +195,14 @@ files:
|
|
180
195
|
- src/js/utils/index.js
|
181
196
|
- src/js/utils/isDef.js
|
182
197
|
- src/js/utils/isInt.js
|
198
|
+
- src/js/utils/isStr.js
|
183
199
|
- src/js/utils/isTouchDevice.js
|
184
200
|
- src/js/utils/isUndef.js
|
185
201
|
- src/js/utils/msToS.js
|
186
202
|
- src/js/utils/promisify.js
|
203
|
+
- src/js/utils/raf.js
|
187
204
|
- src/js/utils/unbindAll.js
|
205
|
+
- src/sass/_animations.scss
|
188
206
|
- src/sass/_beyond-sprockets.scss
|
189
207
|
- src/sass/_beyond.scss
|
190
208
|
- src/sass/_main.scss
|
@@ -225,6 +243,7 @@ files:
|
|
225
243
|
- src/sass/components/_switch.scss
|
226
244
|
- src/sass/components/_tabbox.scss
|
227
245
|
- src/sass/components/_table.scss
|
246
|
+
- src/sass/components/_tag-input.scss
|
228
247
|
- src/sass/components/_tag.scss
|
229
248
|
- src/sass/components/_time-input.scss
|
230
249
|
- src/sass/components/_time-menu.scss
|