beyond-rails 0.0.284 → 0.0.289

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: 63ba182611ef8ef26ad8589924f920756257dffa44cec1b672f49aae74f00a72
4
- data.tar.gz: bff2df6564e4937dc29c5a52227a8bf4f8c961e9c3733fcaa1d1fbb3c6a504b1
3
+ metadata.gz: cb9e9304222537428cb1d6283b208229d204a489a21df5669c3ea32a05c0ef98
4
+ data.tar.gz: d6a261de41c3f7c9b45b1a4baefe600aa14adcd4d7c413c549459716a01612c4
5
5
  SHA512:
6
- metadata.gz: 880db176153aaf81da3896873b71b8ed4c05e3b2e29f2b6f41f322b95677ff637c344e62c9114c07d34de76466f3f75da646930d8541cdc55502383486f16a2c
7
- data.tar.gz: 48178537bbff03a5daad5e3a2225234066df79fb0f459c229a9f70ec8693ceca9d99bae1375ce7fa08986ff3401869b22013e9c08340d240799563643bddba6f
6
+ metadata.gz: a0b4edc27d4b0d0e1087d96669cee5d9569f74b7b81503e6d9ca9e4fb33258d33c36d72aebcda0f9ad798e9eeae8283ef0e911595569005f2cb2d3cde2f804a6
7
+ data.tar.gz: 627f5715183a66d2b2401aada77f5521075498092ecb23e36b805d88a055a706b7fab0d977a3095adb62f561ae493e74f24517e8d46518a0cce3bc2ab9450384
@@ -0,0 +1,282 @@
1
+ import supportDom from '../decorators/supportDom'
2
+ import { range, noop, toInt } from '../utils'
3
+ import { $, $$ } from '../utils/dom'
4
+
5
+ const ACTIVE_CLASSNAME = 'js-active'
6
+ const DOTS = '⸱⸱⸱'
7
+
8
+ @supportDom
9
+ export default class Pagination {
10
+
11
+ constructor(config) {
12
+
13
+ this.dom = config.dom
14
+ this.page = config.page || 1
15
+ this.total = config.total || 0
16
+ this.maxVisiblePage = config.maxVisiblePage || 7
17
+ this.currentPageNode = null
18
+ this.change = config.change || noop
19
+
20
+ this.init()
21
+ this.addEvents()
22
+ }
23
+
24
+ init() {
25
+ const { dom } = this
26
+ this.ul = $('[data-pagination]', dom)
27
+ this.prevBtn = $('[data-prev]', dom)
28
+ this.nextBtn = $('[data-next]', dom)
29
+ this.input = $('[data-page-input]', dom)
30
+ this.drawPages()
31
+ }
32
+
33
+ clearPages() {
34
+ const { ul } = this
35
+ $$('[data-page-item]', ul)
36
+ .concat($$('[data-page-dots]', ul))
37
+ .map(item => item.parentNode)
38
+ .forEach(item => item.remove())
39
+ }
40
+
41
+ getLiNode(pageOrDots) {
42
+
43
+ const li = document.createElement('li')
44
+ li.className = 'page-item'
45
+ const anchor = document.createElement('a')
46
+ anchor.className = 'page-link'
47
+
48
+ if (pageOrDots === DOTS) {
49
+ anchor.setAttribute('data-page-dots', '')
50
+ anchor.textContent = DOTS
51
+ }
52
+ else {
53
+ const page = pageOrDots
54
+ anchor.setAttribute('data-page-item', page)
55
+ anchor.textContent = page
56
+ }
57
+
58
+ li.appendChild(anchor)
59
+ return li
60
+ }
61
+
62
+ setActive(page) {
63
+
64
+ const { currentPageNode } = this
65
+
66
+ if (currentPageNode) {
67
+ currentPageNode.classList.remove(ACTIVE_CLASSNAME)
68
+ }
69
+
70
+ const anchor = $(`[data-page-item="${page}"]`)
71
+
72
+ if (! anchor) {
73
+ return
74
+ }
75
+ anchor.classList.add(ACTIVE_CLASSNAME)
76
+ this.currentPageNode = anchor
77
+ this.page = page
78
+ }
79
+
80
+ insertPageLi(li) {
81
+ this.ul.insertBefore(li, this.nextBtn.parentNode)
82
+ }
83
+
84
+ hideInput() {
85
+ this.input.parentNode.style.display = 'none'
86
+ }
87
+
88
+ showInput() {
89
+ this.input.parentNode.style.display = 'flex'
90
+ }
91
+
92
+ drawRegularPages(currentPage = this.page) {
93
+
94
+ this.hideInput()
95
+
96
+ range(1, this.total + 1)
97
+ .forEach(page => {
98
+ const li = this.getLiNode(page)
99
+ this.insertPageLi(li)
100
+ })
101
+ this.setActive(currentPage)
102
+ }
103
+
104
+ drawPagesWithInput(page = this.page) {
105
+
106
+ this.clearPages()
107
+
108
+ this.showInput()
109
+
110
+ const { total } = this
111
+ const beforeLast = total - 1
112
+
113
+ const isFirst = (page === 1)
114
+ const isSecond = (page === 2)
115
+ const isBeforeLast = (page === beforeLast)
116
+ const isLast = (page === total)
117
+
118
+ // Consider the five cases below:
119
+ // [1] 2 ... 9 10
120
+ // 1 [2] 3 ... 10
121
+ // 1 ... [5] ... 10
122
+ // 1 ... 8 [9] 10
123
+ // 1 2 ... 9 [10]
124
+ const firstLi = this.getLiNode(1)
125
+ this.insertPageLi(firstLi)
126
+
127
+ const secondText = ((page <= 3) || isLast) ? 2 : DOTS
128
+ const secondLi = this.getLiNode(secondText)
129
+ this.insertPageLi(secondLi)
130
+
131
+ const thirdText = (function(p) {
132
+ if (isFirst || isLast) {
133
+ return DOTS
134
+ }
135
+ if (isSecond) {
136
+ return 3
137
+ }
138
+ if (isBeforeLast) {
139
+ return beforeLast - 1
140
+ }
141
+ return p
142
+ })(page)
143
+
144
+ const thirdLi = this.getLiNode(thirdText)
145
+ this.insertPageLi(thirdLi)
146
+
147
+ const fourthText = (function(p) {
148
+ if (isFirst || isBeforeLast || isLast) {
149
+ return beforeLast
150
+ }
151
+ if (p === (beforeLast - 1)) {
152
+ return beforeLast
153
+ }
154
+ return DOTS
155
+ })(page)
156
+
157
+ const fourthLi = this.getLiNode(fourthText)
158
+ this.insertPageLi(fourthLi)
159
+
160
+ const lastLi = this.getLiNode(total)
161
+ this.insertPageLi(lastLi)
162
+
163
+ this.setActive(page)
164
+ }
165
+
166
+ isInputView() {
167
+ const { total } = this
168
+ return ((total > this.maxVisiblePage) && (total > 5))
169
+ }
170
+
171
+ drawPages() {
172
+
173
+ this.clearPages()
174
+
175
+ if (this.isInputView()) {
176
+ this.drawPagesWithInput()
177
+ }
178
+ else {
179
+ this.drawRegularPages()
180
+ }
181
+ }
182
+
183
+ isPrevBtn(target) {
184
+ return ('prev' in target.dataset)
185
+ }
186
+
187
+ isNextBtn(target) {
188
+ return ('next' in target.dataset)
189
+ }
190
+
191
+ isPageBtn(target) {
192
+ return ('pageItem' in target.dataset)
193
+ }
194
+
195
+ isDotBtn(target) {
196
+ return ('pageDots' in target.dataset)
197
+ }
198
+
199
+ handlePageClick(target) {
200
+ const page = toInt(target.dataset.pageItem)
201
+ if (page === this.page) {
202
+ return
203
+ }
204
+ this.setActive(page)
205
+ this.change(page)
206
+ }
207
+
208
+ handleDotBtnClick() {
209
+ this.input.focus()
210
+ }
211
+
212
+ setActiveAndChangeInputViewIfNeeded(page) {
213
+ if (this.isInputView()) {
214
+ return this.drawPagesWithInput(page)
215
+ }
216
+ this.setActive(page)
217
+ }
218
+
219
+ isValidPage(page) {
220
+ return (! isNaN(page)) && (page >= 1) && (page <= this.total)
221
+ }
222
+
223
+ setInputDanger() {
224
+ this.input.classList.add('is-invalid')
225
+ }
226
+
227
+ setInputNormal() {
228
+ this.input.classList.remove('is-invalid')
229
+ }
230
+
231
+ addEvents() {
232
+ this.addEvent(this.ul, 'click', event => {
233
+
234
+ let { target } = event
235
+ if (target.tagName === 'I') {
236
+ target = target.parentNode
237
+ }
238
+
239
+ const { page } = this
240
+
241
+ if (this.isNextBtn(target) && (page < this.total)) {
242
+ const nextPage = page + 1
243
+ this.setActiveAndChangeInputViewIfNeeded(nextPage)
244
+ this.change(nextPage)
245
+ }
246
+ else if (this.isPageBtn(target)) {
247
+ this.handlePageClick(target)
248
+ }
249
+ else if (this.isPrevBtn(target) && (page > 1)) {
250
+ const prevPage = page - 1
251
+ this.setActiveAndChangeInputViewIfNeeded(prevPage)
252
+ this.change(prevPage)
253
+ }
254
+ else if (this.isDotBtn(target)) {
255
+ this.handleDotBtnClick()
256
+ }
257
+ })
258
+
259
+ this.addEvent(this.input, 'change', event => {
260
+ const page = toInt(event.target.value)
261
+
262
+ if (! this.isValidPage(page)) {
263
+ return this.setInputDanger()
264
+ }
265
+ if (page === this.page) {
266
+ return
267
+ }
268
+ this.setInputNormal()
269
+ this.setActiveAndChangeInputViewIfNeeded(page)
270
+ this.change(page)
271
+ })
272
+ }
273
+
274
+ setTotal(total) {
275
+ this.total = total
276
+ this.drawPages()
277
+ }
278
+
279
+ destroy() {
280
+ this.clearPages()
281
+ }
282
+ }
@@ -185,7 +185,7 @@ export default class SearchDropdown {
185
185
  const { renderItem } = this.options
186
186
 
187
187
  const menuItems = items.map((item, i) => {
188
- return renderItem(item, i, (selectedIndex === i))
188
+ return renderItem(item, i, (selectedIndex === i), items)
189
189
  })
190
190
 
191
191
  if (this.noDataMsgVisible) {
data/src/js/index.js CHANGED
@@ -19,6 +19,7 @@ import MonthMenu from './components/MonthMenu'
19
19
  import Menu from './components/Menu'
20
20
  import Modal from './components/Modal'
21
21
  import Navbar from './components/Navbar'
22
+ import Pagination from './components/Pagination'
22
23
  import PieChart from './components/PieChart'
23
24
  import Radio from './components/Radio'
24
25
  import SearchDropdown from './components/SearchDropdown'
@@ -58,6 +59,7 @@ export {
58
59
  Menu,
59
60
  Modal,
60
61
  Navbar,
62
+ Pagination,
61
63
  PieChart,
62
64
  Radio,
63
65
  SearchDropdown,
@@ -1,9 +1,11 @@
1
1
  // @superlanding
2
2
  import dateToTimestamp from '@superlanding/datetotimestamp'
3
+ import extend from '@superlanding/extend'
3
4
  import getDomPos from '@superlanding/getdompos'
4
5
  import getScrollLeft from '@superlanding/getscrollleft'
5
6
  import getScrollTop from '@superlanding/getscrolltop'
6
7
  import timestampToDate from '@superlanding/timestamptodate'
8
+ import toInt from '@superlanding/toint'
7
9
  import toPixel from '@superlanding/topixel'
8
10
 
9
11
  // date-fns
@@ -47,10 +49,12 @@ import mem from 'mem'
47
49
  export {
48
50
  // @superlanding
49
51
  dateToTimestamp,
52
+ extend,
50
53
  getDomPos,
51
54
  getScrollLeft,
52
55
  getScrollTop,
53
56
  timestampToDate,
57
+ toInt,
54
58
  toPixel,
55
59
 
56
60
  // date-fns
@@ -1,8 +1,4 @@
1
- .pagination {
2
- display: flex;
3
- list-style: none;
4
- flex-wrap: wrap;
5
- }
1
+ $page-active-color: #3c4258;
6
2
 
7
3
  %page-link {
8
4
  border-radius: 3px;
@@ -15,9 +11,61 @@
15
11
  &:disabled {
16
12
  cursor: not-allowed;
17
13
  }
14
+ &.js-active,
18
15
  &:hover {
19
- background-color: #3c4258;
16
+ background-color: $page-active-color;
17
+ color: #fff;
18
+ }
19
+ }
20
+
21
+ .pagination-wrap {
22
+ display: flex;
23
+ .pagination-input {
24
+ display: none;
25
+ }
26
+ > .input-group {
27
+ width: initial;
28
+ }
29
+ > .input,
30
+ > .input-group > .input {
31
+ width: 7em;
32
+ &.is-invalid:focus {
33
+ box-shadow: 0 0 0 1px #cd3d64;
34
+ color: #cd3d64;
35
+ }
36
+ }
37
+ .input-group-append > .input-group-text {
38
+ background-color: $page-active-color;
20
39
  color: #fff;
40
+ height: 100%;
41
+ }
42
+ @media (max-width: $screen-sm) {
43
+ display: block;
44
+ > .input-group {
45
+ margin-top: 1em;
46
+ }
47
+ > .pagination {
48
+ justify-content: space-between;
49
+ }
50
+ }
51
+ }
52
+
53
+ .pagination {
54
+ display: flex;
55
+ list-style: none;
56
+ flex-wrap: wrap;
57
+ @media (max-width: $screen-sm) {
58
+ .page-link {
59
+ margin-left: 3px;
60
+ margin-right: 3px;
61
+ }
62
+ .page-link,
63
+ .page-link-btn {
64
+ padding: .2em .5em;
65
+ i {
66
+ font-size: 12px;
67
+ }
68
+ }
21
69
  }
22
70
  }
23
71
 
@@ -38,6 +38,14 @@ label.radio {
38
38
  }
39
39
  }
40
40
  .icon-radio {
41
+
42
+ // prevent overriden by icomoon
43
+ font-family: inherit !important;
44
+ line-height: initial !important;
45
+ &:before {
46
+ content: ''
47
+ }
48
+
41
49
  transform: translateY(-1px);
42
50
  background-color: #fff;
43
51
  border: 0;
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.284
4
+ version: 0.0.289
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: 2021-03-09 00:00:00.000000000 Z
12
+ date: 2021-06-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sassc
@@ -143,6 +143,7 @@ files:
143
143
  - src/js/components/MonthMenu.js
144
144
  - src/js/components/Monthpicker.js
145
145
  - src/js/components/Navbar.js
146
+ - src/js/components/Pagination.js
146
147
  - src/js/components/PieChart.js
147
148
  - src/js/components/Radio.js
148
149
  - src/js/components/SearchDropdown.js