beyond-rails 0.0.225 → 0.0.230

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e4265a216a874f0d0601c2ffb2166a1fd7faa9cb5453aa9e23ca0f09a3a4f7f
4
- data.tar.gz: 8cc3c1212f19a02734fca2dc4b542d67dab8514483952a0ea2725d124c8d5e3d
3
+ metadata.gz: cf80575d0a2ac63e76f75b053115cd6c5518382878d406745c4f959d602d2767
4
+ data.tar.gz: b4c4372056bc1e9d5deddafbf62cadb8ab5ac8f53e3761a36f876b8b4db3897d
5
5
  SHA512:
6
- metadata.gz: dc7afcff18a3f923bb9eb0a30bf48df340add79ed3ac4a20d312061286fb6ba716cdc0a7e813c86143c1c7d0e00780a0589aafad58e6c8861c3f60f61cf77633
7
- data.tar.gz: 84f4d67e13db8aa0e05662e4d70728126aac064be37f78536b21621de25a1625552942fc1b6ef4695dfc8b40b7b48c5d9ff6dbe0d9455879f05f8aca5d0dc735
6
+ metadata.gz: e6c4b45f205f287d815e16e2b1b9065463a730f66c6e4eb62189165e37b29eede35006033568840aba125af4f0ef79740cab5458095aae0ac7a49935b24d07e8
7
+ data.tar.gz: ff1f358c7be11d00acfe9756e163be5391188f8d2b7f6581f95aeb1bcc2dc1552be875e63862960be5e3bd97dc225ee4e0535033b908cdef3aab7588defce173
@@ -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';
@@ -153,6 +153,15 @@ $color-active: #5469d4;
153
153
  border: 0;
154
154
  }
155
155
 
156
+ hr {
157
+ margin-top: 20px;
158
+ margin-bottom: 20px;
159
+ border-top: 1px solid #e3e8ee;
160
+ border-left: 0;
161
+ border-right: 0;
162
+ border-bottom: 0;
163
+ }
164
+
156
165
  input[type=file], /* FF, IE7+, chrome (except button) */
157
166
  input[type=file]::-webkit-file-upload-button { /* chromes and blink button */
158
167
  cursor: pointer;
@@ -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;
@@ -186,3 +191,18 @@ button.close {
186
191
  color: #fff;
187
192
  }
188
193
  }
194
+
195
+ .btn-file {
196
+ position: relative;
197
+ input[type="file"] {
198
+ position: absolute;
199
+ top: 0;
200
+ right: 0;
201
+ left: 0;
202
+ bottom: 0;
203
+ width: 100%;
204
+ padding: 0;
205
+ margin: 0;
206
+ opacity: 0;
207
+ }
208
+ }
@@ -4,6 +4,14 @@
4
4
  overflow-x: auto;
5
5
  -webkit-overflow-scrolling: touch;
6
6
  }
7
+
8
+ %disabled-td {
9
+ cursor: not-allowed;
10
+ background-color: #ddd;
11
+ color: #333;
12
+ box-shadow: inset 0 -1px #c7c7c7;
13
+ }
14
+
7
15
  .table {
8
16
  width: 100%;
9
17
  margin-bottom: 1rem;
@@ -51,6 +59,11 @@
51
59
  padding: 7px;
52
60
  box-shadow: inset 0 -1px #e3e8ee;
53
61
  }
62
+ tr.disabled {
63
+ > td {
64
+ @extend %disabled-td;
65
+ }
66
+ }
54
67
  tr {
55
68
  transition: .3s all;
56
69
  }
@@ -61,5 +74,8 @@
61
74
  tr:nth-child(even) td {
62
75
  background-color: #f7fafc;
63
76
  }
77
+ tr.disabled:nth-child(even) td {
78
+ @extend %disabled-td;
79
+ }
64
80
  }
65
81
  }
@@ -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
+ }
@@ -49,13 +49,12 @@
49
49
  }
50
50
 
51
51
  @for $i from 1 through length($breakpoints) {
52
- $breakpoint: nth($breakpoints, $i);
53
52
  $size: nth($screen-sizes, $i);
54
53
  .col-#{$size} {
55
54
  @extend %col-basic;
56
55
  }
57
56
  @for $j from 1 through $col-total {
58
- .col-#{$i},
57
+ .col-#{$j},
59
58
  .col-#{$size}-#{$j} {
60
59
  @extend %col-basic;
61
60
  }
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.225
4
+ version: 0.0.230
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-08 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