beyond-rails 0.0.226 → 0.0.231
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/Dropdown.js +27 -5
- data/src/js/components/TagInput.js +145 -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/components/_btn.scss +5 -0
- data/src/sass/components/_form.scss +3 -0
- 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: 776e10e5717c1ba85ad7924f5dd0e177a8e3814d849798574d2feff163b34dfe
|
4
|
+
data.tar.gz: 12f8e4062b55a088d827946dfaa7fc379065faa8290586a778d3073ef7288638
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddbb71238f923642fd41e4bdd195051b26c55c4f7f20a4ea6c3af1d27904f1704405b7e540c85b5f24c24d0ecf5ab96ad810b8e7f44c3af06c204dcfaca734cb
|
7
|
+
data.tar.gz: c990592736a42d15e7f07bb5f0e745963de9b1bf134f4a32ab9cbf1951d01e7bd4334d76f6ac5eae698416ae434a03c358d1a4946fd5392181a92891996c154d
|
@@ -51,15 +51,28 @@ export default class Dropdown {
|
|
51
51
|
this.addEvents()
|
52
52
|
}
|
53
53
|
|
54
|
-
|
54
|
+
restoreMenuAttrs() {
|
55
|
+
const { menu, place, align } = this
|
56
|
+
if (place) {
|
57
|
+
menu.dataset.place = place
|
58
|
+
}
|
59
|
+
if (align) {
|
60
|
+
menu.dataset.align = align
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
hideMenu(immediate = false) {
|
55
65
|
const { menu } = this
|
56
66
|
menu.style.transform = 'scale(.8)'
|
57
67
|
menu.style.opacity = 0
|
58
|
-
setTimeout(() => menu.remove(), 300)
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
|
69
|
+
if (immediate) {
|
70
|
+
menu.remove()
|
71
|
+
}
|
72
|
+
else {
|
73
|
+
setTimeout(() => menu.remove(), 300)
|
74
|
+
}
|
75
|
+
this.restoreMenuAttrs()
|
63
76
|
this.isMenuVisible = false
|
64
77
|
}
|
65
78
|
|
@@ -145,4 +158,13 @@ export default class Dropdown {
|
|
145
158
|
this.adjustMenuPos()
|
146
159
|
}, 300))
|
147
160
|
}
|
161
|
+
|
162
|
+
destroy() {
|
163
|
+
// prevent next re-bind error
|
164
|
+
const { menu } = this
|
165
|
+
if (menu) {
|
166
|
+
this.hideMenu(true)
|
167
|
+
document.body.appendChild(menu)
|
168
|
+
}
|
169
|
+
}
|
148
170
|
}
|
@@ -0,0 +1,145 @@
|
|
1
|
+
import raf from '../utils/raf'
|
2
|
+
import isStr from '../utils/isStr'
|
3
|
+
import supportDom from '../decorators/supportDom'
|
4
|
+
import getKey from '../utils/getKey'
|
5
|
+
|
6
|
+
@supportDom
|
7
|
+
export default class TagInput {
|
8
|
+
|
9
|
+
constructor(dom, options = {}) {
|
10
|
+
this.dom = dom
|
11
|
+
this.defaultInputWidth = 128
|
12
|
+
this.validate = options.validate || (() => ({ isTag: true }))
|
13
|
+
this.change = options.change || (() => {})
|
14
|
+
this.isComposing = false
|
15
|
+
this.raf = raf
|
16
|
+
this.tags = []
|
17
|
+
this.init()
|
18
|
+
}
|
19
|
+
|
20
|
+
init() {
|
21
|
+
this.setup()
|
22
|
+
this.addEvents()
|
23
|
+
}
|
24
|
+
|
25
|
+
setup() {
|
26
|
+
const input = document.createElement('input')
|
27
|
+
input.type = 'text'
|
28
|
+
input.style.width = this.defaultInputWidth + 'px'
|
29
|
+
this.input = input
|
30
|
+
this.canvas = document.createElement('canvas')
|
31
|
+
this.dom.append(input)
|
32
|
+
}
|
33
|
+
|
34
|
+
getTextWidth(text, font) {
|
35
|
+
const context = this.canvas.getContext('2d')
|
36
|
+
context.font = font
|
37
|
+
const metrics = context.measureText(text)
|
38
|
+
return metrics.width
|
39
|
+
}
|
40
|
+
|
41
|
+
getNextInputWidth(textWidth) {
|
42
|
+
const { defaultInputWidth } = this
|
43
|
+
// spaces before text and after text
|
44
|
+
const delta = 5
|
45
|
+
const nextWidth = textWidth + delta
|
46
|
+
if (nextWidth < defaultInputWidth) {
|
47
|
+
return defaultInputWidth
|
48
|
+
}
|
49
|
+
return nextWidth
|
50
|
+
}
|
51
|
+
|
52
|
+
shake() {
|
53
|
+
this.dom.classList.add('shake')
|
54
|
+
setTimeout(() => {
|
55
|
+
this.dom.classList.remove('shake')
|
56
|
+
}, 500)
|
57
|
+
}
|
58
|
+
|
59
|
+
async addTagIfNeeded(value) {
|
60
|
+
const { input } = this
|
61
|
+
const inputValue = input.value
|
62
|
+
const res = await this.validate(inputValue)
|
63
|
+
if (! res.isTag) {
|
64
|
+
return this.shake()
|
65
|
+
}
|
66
|
+
const classname = res.classname ? ` ${res.classname}` : ''
|
67
|
+
const tag = document.createElement('div')
|
68
|
+
|
69
|
+
tag.className = 'tag' + classname
|
70
|
+
tag.textContent = inputValue
|
71
|
+
|
72
|
+
const btn = document.createElement('button')
|
73
|
+
btn.type = 'button'
|
74
|
+
|
75
|
+
// https://wesbos.com/times-html-entity-close-button
|
76
|
+
btn.textContent = '×'
|
77
|
+
const handleBtnClick = () => {
|
78
|
+
this.tags = this.tags.filter(row => row.elem !== tag)
|
79
|
+
btn.removeEventListener('click', handleBtnClick)
|
80
|
+
tag.remove()
|
81
|
+
this.change(this.tags.slice())
|
82
|
+
}
|
83
|
+
btn.addEventListener('click', handleBtnClick)
|
84
|
+
tag.appendChild(btn)
|
85
|
+
|
86
|
+
this.tags.push({ elem: tag, remove: handleBtnClick, res })
|
87
|
+
this.dom.insertBefore(tag, input)
|
88
|
+
input.value = ''
|
89
|
+
|
90
|
+
this.change(this.tags.slice())
|
91
|
+
}
|
92
|
+
|
93
|
+
removeTagIfNeeded() {
|
94
|
+
const lastTag = this.tags[this.tags.length - 1]
|
95
|
+
if ((this.input.value === '') && lastTag) {
|
96
|
+
lastTag.remove()
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
addEvents() {
|
101
|
+
const { input } = this
|
102
|
+
const font = window.getComputedStyle(input)
|
103
|
+
.getPropertyValue('font')
|
104
|
+
|
105
|
+
this.addEvent(this.dom, 'click', event => {
|
106
|
+
if (event.target === this.dom) {
|
107
|
+
this.input.focus()
|
108
|
+
}
|
109
|
+
})
|
110
|
+
|
111
|
+
this.addEvent(input, 'compositionstart', event => {
|
112
|
+
this.isComposing = true
|
113
|
+
})
|
114
|
+
|
115
|
+
this.addEvent(input, 'compositionend', event => {
|
116
|
+
this.isComposing = false
|
117
|
+
})
|
118
|
+
|
119
|
+
let lastValue = ''
|
120
|
+
|
121
|
+
this.addEvent(input, 'keydown', async event => {
|
122
|
+
const key = getKey(event)
|
123
|
+
if ((key === 'enter') && (! this.isComposing)) {
|
124
|
+
await this.addTagIfNeeded(input.value)
|
125
|
+
}
|
126
|
+
else if ((key === 'backspace') && (lastValue === '')) {
|
127
|
+
this.removeTagIfNeeded()
|
128
|
+
}
|
129
|
+
lastValue = input.value
|
130
|
+
})
|
131
|
+
|
132
|
+
this.addEvent(input, 'input', event => {
|
133
|
+
this.raf(() => {
|
134
|
+
const textWidth = this.getTextWidth(input.value, font)
|
135
|
+
const nextWidth = this.getNextInputWidth(textWidth)
|
136
|
+
input.style.width = nextWidth + 'px'
|
137
|
+
})
|
138
|
+
})
|
139
|
+
}
|
140
|
+
|
141
|
+
destroy() {
|
142
|
+
this.tags.forEach(tag => tag.remove())
|
143
|
+
this.input.remove()
|
144
|
+
}
|
145
|
+
}
|
@@ -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';
|
@@ -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.231
|
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-13 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
|