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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fe2004947bfbece8fa387026c40c31985d67b4de2fc8898dceb8d3691c7fbf9
4
- data.tar.gz: '0182a586b22fd35847e4339c944dea67ee0a2f9057f4cc7e6384034d1c65cd44'
3
+ metadata.gz: 776e10e5717c1ba85ad7924f5dd0e177a8e3814d849798574d2feff163b34dfe
4
+ data.tar.gz: 12f8e4062b55a088d827946dfaa7fc379065faa8290586a778d3073ef7288638
5
5
  SHA512:
6
- metadata.gz: 4800cdd8e025687e8d85c9a0445ef1fbd2e494bd99163defdbada82c6ec9b55822bea288fb15056250e5cb384a0254c1ff0ceb047b535ba3084d2700c8914987
7
- data.tar.gz: f7ae8ead35cbcd39956223080bd08892d757ccb95f8f904dedcc523d60d53ca537b0be857e7e9dabe97be4ba2a90cc21a01f021a1aadf76e9e2f45eeee16750d
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
- hideMenu() {
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
- // recover
61
- menu.dataset.place = this.place
62
- menu.dataset.align = this.align
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 isDef from '../utils/isDef'
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 => {
@@ -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,
@@ -1,4 +1,5 @@
1
1
  const keyMap = {
2
+ 8: 'backspace',
2
3
  13: 'enter',
3
4
  17: 'ctrl',
4
5
  27: 'esc',
@@ -0,0 +1,3 @@
1
+ export default function isStr(value) {
2
+ return (typeof value === 'string')
3
+ }
@@ -0,0 +1,8 @@
1
+ import isDef from './isDef'
2
+
3
+ export default function raf(fn) {
4
+ if (isDef(window.requestAnimationFrame)) {
5
+ return window.requestAnimationFrame(fn)
6
+ }
7
+ return fn()
8
+ }
@@ -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
+ }
@@ -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';
@@ -97,6 +97,11 @@
97
97
  @include ripple(48px, 0, 0);
98
98
  }
99
99
 
100
+ .btn.btn-outline,
101
+ a.btn.btn-outline {
102
+ color: $text-color;
103
+ }
104
+
100
105
  .btn.btn-outline {
101
106
  background-color: #fff;
102
107
  font-size: 13px;
@@ -345,6 +345,9 @@ input[type="file"] {
345
345
  > .form-control {
346
346
  flex: 1 1 0%;
347
347
  }
348
+ .invalid-feedback {
349
+ flex-basis: 100%;
350
+ }
348
351
  }
349
352
 
350
353
  .input-group-text {
@@ -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.226
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 00:00:00.000000000 Z
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