beyond-rails 0.0.281 → 0.0.286

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: 4fdbef0c60df577d5177297214104a62d44879abf628e92ba2ac9b263e344d22
4
- data.tar.gz: 91e93ce0cc411b0721d5172b1813d347ce40268ae0815c404a34cf9c50960026
3
+ metadata.gz: 9ec3e181da10e04daca80c0dfa0429d270b01c321688f86fc7a2b4d329d56c51
4
+ data.tar.gz: 8e3e668db1593b11e606335a70bbfbfa328b4e91539ac796355936c5f480bfe5
5
5
  SHA512:
6
- metadata.gz: aadf392da4fb29588d3871759b48aecaacd6e5250c9e6fcff7ec08f6d19232cb5260461565741a53c55a2397f8c6ae07a0ed7384325c9ddf2dc4066c3e19faea
7
- data.tar.gz: e93b2ed5099895a980dcb14466a70a7e985b10cf020b83658130420050845c6c8e99043fc185f030ea060b34fcee4e61ca734b0479e67f47b0da1778d3e329f1
6
+ metadata.gz: 2105d76b9738d20809c5771e9ceed7526d7fb1c39e237e3301340a82de4607aa6277728ea3072e4b89d08a85cdb6172351c52ed3c6eafab579e03329b437fcc1
7
+ data.tar.gz: 9268795c6484a78e794a072a19ba382358204da091a43e549743794cfa128f72a9414d938cdb48969d31c71212f173cb69eab4baf757bd327245b50a8b0a0df5
@@ -0,0 +1,273 @@
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
+ this.setInputNormal()
266
+ this.setActiveAndChangeInputViewIfNeeded(page)
267
+ })
268
+ }
269
+
270
+ destroy() {
271
+ this.clearPages()
272
+ }
273
+ }
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
@@ -78,6 +78,7 @@
78
78
  font-size: 14px;
79
79
  font-weight: 400;
80
80
  }
81
+ .btn.btn-danger,
81
82
  .btn.btn-primary {
82
83
  margin-left: 10px;
83
84
  }
@@ -1,7 +1,4 @@
1
- .pagination {
2
- display: flex;
3
- list-style: none;
4
- }
1
+ $page-active-color: #3c4258;
5
2
 
6
3
  %page-link {
7
4
  border-radius: 3px;
@@ -14,9 +11,61 @@
14
11
  &:disabled {
15
12
  cursor: not-allowed;
16
13
  }
14
+ &.js-active,
17
15
  &:hover {
18
- 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;
19
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
+ }
20
69
  }
21
70
  }
22
71
 
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.281
4
+ version: 0.0.286
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-01-27 00:00:00.000000000 Z
12
+ date: 2021-03-11 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