beyond-rails 0.0.228 → 0.0.233
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/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
|