beyond-rails 0.0.139

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.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/src/font/icomoon.eot +0 -0
  3. data/src/font/icomoon.svg +125 -0
  4. data/src/font/icomoon.ttf +0 -0
  5. data/src/font/icomoon.woff +0 -0
  6. data/src/img/black-cat.svg +15 -0
  7. data/src/img/cart.svg +16 -0
  8. data/src/img/china-flag.svg +16 -0
  9. data/src/img/ecpay.svg +12 -0
  10. data/src/img/family-mart.svg +13 -0
  11. data/src/img/fb-messenger.svg +12 -0
  12. data/src/img/fb.svg +10 -0
  13. data/src/img/hct.svg +16 -0
  14. data/src/img/hi-life.svg +23 -0
  15. data/src/img/line.svg +14 -0
  16. data/src/img/ok-mart.svg +9 -0
  17. data/src/img/pelican.svg +33 -0
  18. data/src/img/seven-eleven.svg +13 -0
  19. data/src/img/smilepay.svg +13 -0
  20. data/src/img/taiwan-flag.svg +17 -0
  21. data/src/js/components/Alert.js +23 -0
  22. data/src/js/components/Autocomplete.js +110 -0
  23. data/src/js/components/AutocompleteMenu.js +88 -0
  24. data/src/js/components/Btn.js +41 -0
  25. data/src/js/components/Checkbox.js +24 -0
  26. data/src/js/components/DateInput.js +74 -0
  27. data/src/js/components/DateMenu.js +370 -0
  28. data/src/js/components/DateTimeRanger.js +436 -0
  29. data/src/js/components/Datepicker.js +250 -0
  30. data/src/js/components/DatepickerBtnArrow.js +18 -0
  31. data/src/js/components/Dropdown.js +137 -0
  32. data/src/js/components/Menu.js +43 -0
  33. data/src/js/components/Modal.js +76 -0
  34. data/src/js/components/Navbar.js +47 -0
  35. data/src/js/components/Radio.js +24 -0
  36. data/src/js/components/SearchDropdown.js +339 -0
  37. data/src/js/components/Sidebar.js +56 -0
  38. data/src/js/components/Tabbox.js +229 -0
  39. data/src/js/components/TimeInput.js +71 -0
  40. data/src/js/components/TimeMenu.js +117 -0
  41. data/src/js/components/Toast.js +47 -0
  42. data/src/js/components/ToastItem.js +62 -0
  43. data/src/js/components/Tooltip.js +94 -0
  44. data/src/js/consts/createdComponents.js +1 -0
  45. data/src/js/consts/index.js +5 -0
  46. data/src/js/helpers/bind.js +53 -0
  47. data/src/js/helpers/dateEq.js +5 -0
  48. data/src/js/helpers/dateGt.js +5 -0
  49. data/src/js/helpers/dateLt.js +5 -0
  50. data/src/js/helpers/docReady.js +10 -0
  51. data/src/js/helpers/getFloatedTargetPos.js +250 -0
  52. data/src/js/helpers/getKey.js +14 -0
  53. data/src/js/helpers/isTouchDevice.js +3 -0
  54. data/src/js/helpers/msToS.js +3 -0
  55. data/src/js/helpers/promisify.js +9 -0
  56. data/src/js/helpers/range.js +7 -0
  57. data/src/js/helpers/supportDom.js +46 -0
  58. data/src/js/helpers/toPixel.js +3 -0
  59. data/src/js/helpers/unbindAll.js +6 -0
  60. data/src/js/index.js +47 -0
  61. data/src/js/jquery/bindAlertFn.js +13 -0
  62. data/src/js/jquery/bindAutocompleteFn.js +13 -0
  63. data/src/js/jquery/bindBtnFn.js +17 -0
  64. data/src/js/jquery/bindCheckboxFn.js +13 -0
  65. data/src/js/jquery/bindDateTimeRangerFn.js +14 -0
  66. data/src/js/jquery/bindDatepickerFn.js +14 -0
  67. data/src/js/jquery/bindDropdownFn.js +14 -0
  68. data/src/js/jquery/bindMenuFn.js +13 -0
  69. data/src/js/jquery/bindModalFn.js +14 -0
  70. data/src/js/jquery/bindNavbarFn.js +13 -0
  71. data/src/js/jquery/bindRadioFn.js +13 -0
  72. data/src/js/jquery/bindSearchDropdownFn.js +14 -0
  73. data/src/js/jquery/bindSidebarFn.js +13 -0
  74. data/src/js/jquery/bindTabboxFn.js +13 -0
  75. data/src/js/jquery/bindToastFn.js +6 -0
  76. data/src/js/jquery/bindTooltipFn.js +13 -0
  77. data/src/js/jquery/index.js +52 -0
  78. data/src/js/polyfills/classList.js +263 -0
  79. data/src/js/polyfills/elementDataset.js +3 -0
  80. data/src/js/polyfills/nodeContains.js +17 -0
  81. data/src/js/polyfills/nodeHasAttribute.js +5 -0
  82. data/src/js/polyfills/nodeRemove.js +19 -0
  83. data/src/sass/_beyond-sprockets.scss +1 -0
  84. data/src/sass/_beyond.scss +50 -0
  85. data/src/sass/_main.scss +141 -0
  86. data/src/sass/abstracts/_mixins.scss +129 -0
  87. data/src/sass/abstracts/_placeholders.scss +43 -0
  88. data/src/sass/abstracts/_variables.scss +355 -0
  89. data/src/sass/base/_background.scss +10 -0
  90. data/src/sass/base/_typography.scss +183 -0
  91. data/src/sass/components/_alert.scss +50 -0
  92. data/src/sass/components/_autocomplete.scss +29 -0
  93. data/src/sass/components/_avatar.scss +28 -0
  94. data/src/sass/components/_badge.scss +29 -0
  95. data/src/sass/components/_breadcrumb.scss +17 -0
  96. data/src/sass/components/_btn-group.scss +19 -0
  97. data/src/sass/components/_btn.scss +172 -0
  98. data/src/sass/components/_card.scss +183 -0
  99. data/src/sass/components/_checkbox.scss +99 -0
  100. data/src/sass/components/_date-input.scss +28 -0
  101. data/src/sass/components/_date-menu.scss +85 -0
  102. data/src/sass/components/_date-time-ranger.scss +21 -0
  103. data/src/sass/components/_datepicker.scss +3 -0
  104. data/src/sass/components/_dropdown.scss +144 -0
  105. data/src/sass/components/_form.scss +383 -0
  106. data/src/sass/components/_icon.scss +371 -0
  107. data/src/sass/components/_input.scss +48 -0
  108. data/src/sass/components/_list.scss +23 -0
  109. data/src/sass/components/_modal.scss +72 -0
  110. data/src/sass/components/_nav.scss +75 -0
  111. data/src/sass/components/_navbar.scss +211 -0
  112. data/src/sass/components/_pagination.scss +64 -0
  113. data/src/sass/components/_radio.scss +71 -0
  114. data/src/sass/components/_search-dropdown.scss +28 -0
  115. data/src/sass/components/_select.scss +54 -0
  116. data/src/sass/components/_sidebar.scss +35 -0
  117. data/src/sass/components/_spinner.scss +79 -0
  118. data/src/sass/components/_tabbox.scss +83 -0
  119. data/src/sass/components/_table.scss +65 -0
  120. data/src/sass/components/_tag.scss +43 -0
  121. data/src/sass/components/_time-input.scss +28 -0
  122. data/src/sass/components/_time-menu.scss +24 -0
  123. data/src/sass/components/_toast.scss +51 -0
  124. data/src/sass/components/_tooltip.scss +10 -0
  125. data/src/sass/img/arrow-dropdown.svg +4 -0
  126. data/src/sass/img/arrow-select-ex.svg +18 -0
  127. data/src/sass/img/arrow-select.svg +18 -0
  128. data/src/sass/layout/_border-util.scss +36 -0
  129. data/src/sass/layout/_col.scss +90 -0
  130. data/src/sass/layout/_container.scss +44 -0
  131. data/src/sass/layout/_flex-util.scss +18 -0
  132. data/src/sass/layout/_offset-util.scss +20 -0
  133. data/src/sass/layout/_sizing-util.scss +14 -0
  134. data/src/sass/layout/_spacing-util.scss +9 -0
  135. data/src/sass/layout/_visibility-util.scss +25 -0
  136. data/src/sass/vendor/_normalize.scss +578 -0
  137. data/src/sass/vendor/_turbolink.scss +5 -0
  138. metadata +235 -0
@@ -0,0 +1,88 @@
1
+ import getFloatedTargetPos from '../helpers/getFloatedTargetPos'
2
+ import toPixel from '../helpers/toPixel'
3
+ import supportDom from '../helpers/supportDom'
4
+
5
+ @supportDom
6
+ export default class AutocompleteMenu {
7
+
8
+ constructor(options = {}) {
9
+ this.options = options
10
+ this.isVisible = false
11
+ this.lastSrc = null
12
+ this.init()
13
+ }
14
+
15
+ init() {
16
+ this.addMenu()
17
+ this.addEvents()
18
+ }
19
+
20
+ pos(src) {
21
+ const offsetLeft = this.options.offsetLeft || 0
22
+ const offsetTop = this.options.offsetTop || 0
23
+ const { pos } = getFloatedTargetPos({
24
+ src,
25
+ target: this.dom,
26
+ place: 'bottom',
27
+ align: 'left',
28
+ offset: 3,
29
+ offsetLeft,
30
+ offsetTop
31
+ })
32
+ this.dom.style.left = toPixel(pos.left)
33
+ this.dom.style.top = toPixel(pos.top)
34
+ this.lastSrc = src
35
+ }
36
+
37
+ show(src) {
38
+ this.dom.style.opacity = 0
39
+ this.dom.style.display = 'block'
40
+ this.pos(src)
41
+ this.dom.style.opacity = 1
42
+ this.isVisible = true
43
+ }
44
+
45
+ hide() {
46
+ this.dom.style.display = 'none'
47
+ this.isVisible = false
48
+ }
49
+
50
+ addMenu() {
51
+ const dom = document.createElement('div')
52
+ dom.className = 'autocomplete-menu'
53
+ dom.style.display = 'none'
54
+ document.body.appendChild(dom)
55
+ this.dom = dom
56
+ }
57
+
58
+ renderMenuItem(rows, renderFunc) {
59
+ const nodes = rows.map(row => renderFunc(row))
60
+ const html = nodes.map(node => {
61
+ if ((typeof node === 'object') && ('outerHTML' in node)) {
62
+ return node.outerHTML
63
+ }
64
+ return node
65
+ }).join('')
66
+ this.dom.innerHTML = html
67
+ }
68
+
69
+ addEvents() {
70
+ this.addEvent(this.dom, 'click', event => {
71
+ let node = event.target
72
+ while (node.parentNode !== this.dom) {
73
+ node = node.parentNode
74
+ }
75
+ const index = Array.from(this.dom.children).indexOf(node)
76
+ this.fire('click', index)
77
+ })
78
+ this.addEvent(window, 'resize', () => {
79
+ if (this.isVisible && this.lastSrc) {
80
+ this.pos(this.lastSrc)
81
+ }
82
+ })
83
+ }
84
+
85
+ destroy() {
86
+ this.dom.remove()
87
+ }
88
+ }
@@ -0,0 +1,41 @@
1
+ import supportDom from '../helpers/supportDom'
2
+ import toPixel from '../helpers/toPixel'
3
+
4
+ @supportDom
5
+ export default class Btn {
6
+
7
+ constructor(dom) {
8
+ this.dom = dom
9
+ this.loading = false
10
+ this.init()
11
+ }
12
+
13
+ showLoader() {
14
+ const { dom } = this
15
+ this._innerHtml = dom.innerHTML
16
+ dom.style.height = toPixel(dom.offsetHeight)
17
+ dom.style.width = toPixel(dom.offsetWidth)
18
+ dom.innerHTML = `
19
+ <div class="btn-loader">
20
+ <div class="ring-loader">
21
+ <div></div>
22
+ <div></div>
23
+ <div></div>
24
+ <div></div>
25
+ </div>
26
+ </div>
27
+ `
28
+ }
29
+
30
+ hideLoader() {
31
+ const { dom } = this
32
+ dom.style.removeProperty('width')
33
+ dom.style.removeProperty('height')
34
+ dom.innerHTML = this._innerHtml
35
+ }
36
+
37
+ setLoading(loading) {
38
+ this.loading = loading
39
+ loading ? this.showLoader() : this.hideLoader()
40
+ }
41
+ }
@@ -0,0 +1,24 @@
1
+ import supportDom from '../helpers/supportDom'
2
+
3
+ @supportDom
4
+ export default class Checkbox {
5
+
6
+ constructor(dom) {
7
+ this.dom = dom
8
+ this.init()
9
+ }
10
+
11
+ init() {
12
+ const { dom } = this
13
+ this.addEvent(dom, 'focus', this.handleFocus)
14
+ this.addEvent(dom, 'blur', this.handleBlur)
15
+ }
16
+
17
+ handleFocus() {
18
+ this.parentNode.classList.add('focus')
19
+ }
20
+
21
+ handleBlur() {
22
+ this.parentNode.classList.remove('focus')
23
+ }
24
+ }
@@ -0,0 +1,74 @@
1
+ import { format } from 'date-fns-tz'
2
+ import { DEFAULT_TIMEZONE } from '../consts'
3
+ import supportDom from '../helpers/supportDom'
4
+ import isTouchDevice from '../helpers/isTouchDevice'
5
+
6
+ @supportDom
7
+ export default class DateInput {
8
+
9
+ constructor(dom, date, options = {}) {
10
+ this.active = false
11
+ this.danger = false
12
+ this.dom = dom
13
+ this.date = date
14
+ this.options = options
15
+ this.tz = options.tz || DEFAULT_TIMEZONE
16
+ this.datePattern = options.datePattern || 'yyyy/MM/dd'
17
+ this.init()
18
+ }
19
+
20
+ focus() {
21
+ this.dom.focus()
22
+ }
23
+
24
+ init() {
25
+ this.initInput()
26
+ this.addEvents()
27
+ }
28
+
29
+ initInput() {
30
+ const { dom } = this
31
+ if (this.date) {
32
+ dom.value = this.format(this.date)
33
+ }
34
+ if (! dom.hasAttribute('placeholder')) {
35
+ dom.setAttribute('placeholder', this.datePattern.toUpperCase())
36
+ }
37
+ if (isTouchDevice()) {
38
+ dom.setAttribute('readonly', 'readonly')
39
+ }
40
+ }
41
+
42
+ format(date) {
43
+ return format(date, this.datePattern, { timezone: this.tz })
44
+ }
45
+
46
+ setDate(date) {
47
+ this.date = date
48
+ this.dom.value = date ? this.format(date) : ''
49
+ }
50
+
51
+ setActive(active) {
52
+ this.active = active
53
+ const func = active ? 'add' : 'remove'
54
+ this.dom.classList[func]('active')
55
+ }
56
+
57
+ setDanger(danger) {
58
+ this.danger = danger
59
+ const func = danger ? 'add' : 'remove'
60
+ this.dom.classList[func]('danger')
61
+ }
62
+
63
+ clearStatus() {
64
+ this.setActive(false)
65
+ this.setDanger(false)
66
+ }
67
+
68
+ addEvents() {
69
+ const { dom } = this
70
+ this.addEvent(dom, 'focus', event => this.fire('focus', event))
71
+ this.addEvent(dom, 'keyup', event => this.fire('keyup', event))
72
+ this.addEvent(dom, 'blur', event => this.fire('blur', event))
73
+ }
74
+ }
@@ -0,0 +1,370 @@
1
+ import { format } from 'date-fns-tz'
2
+ import addDays from 'date-fns/addDays'
3
+ import set from 'date-fns/set'
4
+ import addMonths from 'date-fns/addMonths'
5
+ import compareAsc from 'date-fns/compareAsc'
6
+ import endOfMonth from 'date-fns/endOfMonth'
7
+ import getDay from 'date-fns/getDay'
8
+ import getDaysInMonth from 'date-fns/getDaysInMonth'
9
+ import getMonth from 'date-fns/getMonth'
10
+ import getYear from 'date-fns/getYear'
11
+ import startOfDay from 'date-fns/startOfDay'
12
+ import startOfMonth from 'date-fns/startOfMonth'
13
+ import subMonths from 'date-fns/subMonths'
14
+ import getFloatedTargetPos from '../helpers/getFloatedTargetPos'
15
+ import range from '../helpers/range'
16
+ import toPixel from '../helpers/toPixel'
17
+ import isTouchDevice from '../helpers/isTouchDevice'
18
+ import dateLt from '../helpers/dateLt'
19
+ import dateEq from '../helpers/dateEq'
20
+ import { DEFAULT_TIMEZONE, DEFAULT_LOCALE } from '../consts'
21
+ import supportDom from '../helpers/supportDom'
22
+ import throttle from 'lodash.throttle'
23
+
24
+ const DEFAULT_WEEK_HEADER_ITEMS = [
25
+ { id: 'monday', text: '一' },
26
+ { id: 'tuesday', text: '二' },
27
+ { id: 'wednesday', text: '三' },
28
+ { id: 'thursday', text: '四' },
29
+ { id: 'friday', text: '五' },
30
+ { id: 'saturday', text: '六' },
31
+ { id: 'sunday', text: '日' }
32
+ ]
33
+
34
+ const CELL_TYPE_EMPTY = Symbol('CELL_TYPE_EMPTY')
35
+ const CELL_TYPE_DAY = Symbol('CELL_TYPE_DAY')
36
+
37
+ @supportDom
38
+ export default class DateMenu {
39
+
40
+ constructor({ date, startDate, endDate, options = {} }) {
41
+ this.date = date
42
+ this.date2 = addMonths(date, 1)
43
+ this.startDate = startDate
44
+ this.endDate = endDate
45
+ this.hoveredCellData = null
46
+ this.options = options
47
+ this.tz = options.tz || DEFAULT_TIMEZONE
48
+ this.locale = options.locale || DEFAULT_LOCALE
49
+ this.captionPattern = options.captionPattern || 'yyyy MMMM'
50
+ this.weekHeaderItems = options.weekHeaderItems || DEFAULT_WEEK_HEADER_ITEMS
51
+ this.isVisible = false
52
+ this.init()
53
+ }
54
+
55
+ init() {
56
+ this.addMenu()
57
+ this.addEvents()
58
+ }
59
+
60
+ useSingleMenu() {
61
+ return isTouchDevice() || this.options.useSingleMenu
62
+ }
63
+
64
+ setHoveredCell(data) {
65
+ const dataChanged = JSON.stringify(data) !== JSON.stringify(this.hoveredCellData)
66
+ if (dataChanged && (! this.endDate)) {
67
+ this.hoveredCellData = data
68
+ this.drawTables()
69
+ }
70
+ }
71
+
72
+ getTableRows(date) {
73
+
74
+ const { startDate, endDate } = this
75
+
76
+ const daysInMonth = getDaysInMonth(date)
77
+ const firstDateOfMonth = startOfMonth(date)
78
+ const toEmptyCell = () => ({ type: CELL_TYPE_EMPTY })
79
+
80
+ const firstWeekday = getDay(startOfMonth(date))
81
+ const beforeWeekday = ((firstWeekday - 1) === -1) ? 6 : (firstWeekday - 1)
82
+ const emptyHeadRows = range(1, beforeWeekday).map(toEmptyCell)
83
+
84
+ const initialStartDate = startOfDay(startDate)
85
+ const initialEndDate = startOfDay(endDate)
86
+
87
+ // 00:00:00
88
+ // eslint-disable-next-line prefer-const
89
+ let startOfStartDate = initialStartDate
90
+
91
+ // eslint-disable-next-line prefer-const
92
+ let startOfEndDate = initialEndDate
93
+
94
+ if (startDate && (! endDate) && this.hoveredCellData) {
95
+ const { year: y, month: m, date: d } = this.hoveredCellData
96
+ startOfEndDate = set(startOfStartDate, { year: y, month: m, date: d })
97
+ if (dateLt(startOfEndDate, startOfStartDate)) {
98
+ [startOfStartDate, startOfEndDate] = [startOfEndDate, startOfStartDate]
99
+ }
100
+ }
101
+
102
+ const formatDate = date => {
103
+ return format(date, 'yyyy-MM-dd', { timezone: this.tz, locale: this.locale })
104
+ }
105
+ const today = formatDate(new Date())
106
+
107
+ const rows = range(1, daysInMonth).map(day => {
108
+
109
+ const d = addDays(firstDateOfMonth, day - 1)
110
+ const resCompareStart = compareAsc(startOfStartDate, d)
111
+ const resCompareEnd = compareAsc(startOfEndDate, d)
112
+
113
+ return {
114
+ type: CELL_TYPE_DAY,
115
+ isStartDate: dateEq(initialStartDate, d),
116
+ isEndDate: dateEq(initialEndDate, d),
117
+ isSelected: (resCompareStart <= 0) && (resCompareEnd >= 0),
118
+ isToday: (today === formatDate(d)),
119
+ day
120
+ }
121
+ })
122
+
123
+ const lastWeekday = getDay(endOfMonth(date))
124
+ const emptyDays = ((7 - lastWeekday) % 7)
125
+ const emptyTailRows = range(1, emptyDays).map(toEmptyCell)
126
+
127
+ return emptyHeadRows.concat(rows).concat(emptyTailRows)
128
+ }
129
+
130
+ setCaption() {
131
+ const { date, date2 } = this
132
+ const options = { timezone: this.tz, locale: this.locale }
133
+ if (this.useSingleMenu()) {
134
+ this.caption.textContent = format(date, this.captionPattern, options)
135
+ }
136
+ else {
137
+ this.caption1.textContent = format(date, this.captionPattern, options)
138
+ this.caption2.textContent = format(date2, this.captionPattern, options)
139
+ }
140
+ }
141
+
142
+ drawTables() {
143
+ if (this.useSingleMenu()) {
144
+ const rows = this.getTableRows(this.date)
145
+ this.table.innerHTML = this.getTableHtml(rows)
146
+ }
147
+ else {
148
+ this.table1.innerHTML = this.getTableHtml(this.getTableRows(this.date))
149
+ this.table2.innerHTML = this.getTableHtml(this.getTableRows(this.date2))
150
+ }
151
+ }
152
+
153
+ setDate({ date, startDate, endDate }) {
154
+ if (date) {
155
+ this.date = date
156
+ this.date2 = addMonths(date, 1)
157
+ this.setCaption()
158
+ }
159
+ if (typeof startDate !== 'undefined') {
160
+ this.startDate = startDate
161
+ }
162
+ if (typeof endDate !== 'undefined') {
163
+ this.endDate = endDate
164
+ }
165
+ this.drawTables()
166
+ }
167
+
168
+ getWeekHeaderItems() {
169
+ return this.weekHeaderItems.map(item => `<li>${item.text}</li>`)
170
+ .join('')
171
+ }
172
+
173
+ getTableHtml(rows) {
174
+ return rows.map((row, i) => {
175
+ const rowHtml = this.getTdHtml(row)
176
+ const r = i % 7
177
+ if (r === 0) {
178
+ return `<tr>${rowHtml}`
179
+ }
180
+ if (r === 6) {
181
+ return `${rowHtml}</tr>`
182
+ }
183
+ return rowHtml
184
+ }).join('')
185
+ }
186
+
187
+ getTdHtml(row) {
188
+ if (row.type === CELL_TYPE_EMPTY) {
189
+ return '<td></td>'
190
+ }
191
+ if (row.isStartDate || row.isEndDate) {
192
+ return `<td class="cell selected-ex" data-date-table-cell>${row.day}</td>`
193
+ }
194
+ if (row.isSelected) {
195
+ return `<td class="cell selected" data-date-table-cell>${row.day}</td>`
196
+ }
197
+ if (this.options.highlightToday && row.isToday) {
198
+ return `<td class="cell today" data-date-table-cell>${row.day}</td>`
199
+ }
200
+ return `<td class="cell" data-date-table-cell>${row.day}</td>`
201
+ }
202
+
203
+ addMenu() {
204
+ const dom = document.createElement('div')
205
+ dom.className = 'date-menu'
206
+
207
+ if (this.useSingleMenu()) {
208
+ dom.innerHTML = `
209
+ <div class="date-menu-content">
210
+ <div class="date-menu-caption" data-menu-caption></div>
211
+ <ul class="date-menu-week-header">
212
+ ${this.getWeekHeaderItems()}
213
+ </ul>
214
+ <table class="date-menu-date-table" data-date-table></table>
215
+ <button class="date-menu-btn-prev" data-btn-prev>
216
+ <i class="icon icon-chevron-left"></i>
217
+ </button>
218
+ <button class="date-menu-btn-next" data-btn-next>
219
+ <i class="icon icon-chevron-right"></i>
220
+ </button>
221
+ </div>
222
+ `
223
+ this.caption = dom.querySelector('[data-menu-caption]')
224
+ this.table = dom.querySelector('[data-date-table]')
225
+ this.btnPrev = dom.querySelector('[data-btn-prev]')
226
+ this.btnNext = dom.querySelector('[data-btn-next]')
227
+ }
228
+ else {
229
+ dom.innerHTML = `
230
+ <div class="date-menu-content">
231
+ <div class="date-menu-caption" data-menu-caption1></div>
232
+ <ul class="date-menu-week-header">
233
+ ${this.getWeekHeaderItems()}
234
+ </ul>
235
+ <table class="date-menu-date-table" data-date-table1></table>
236
+ <button class="date-menu-btn-prev" data-btn-prev>
237
+ <i class="icon icon-chevron-left"></i>
238
+ </button>
239
+ </div>
240
+ <div class="date-menu-content second-content">
241
+ <div class="date-menu-caption" data-menu-caption2></div>
242
+ <ul class="date-menu-week-header">
243
+ ${this.getWeekHeaderItems()}
244
+ </ul>
245
+ <table class="date-menu-date-table" data-date-table2></table>
246
+ <button class="date-menu-btn-next" data-btn-next>
247
+ <i class="icon icon-chevron-right"></i>
248
+ </button>
249
+ </div>
250
+ `
251
+ this.caption1 = dom.querySelector('[data-menu-caption1]')
252
+ this.caption2 = dom.querySelector('[data-menu-caption2]')
253
+ this.table1 = dom.querySelector('[data-date-table1]')
254
+ this.table2 = dom.querySelector('[data-date-table2]')
255
+ this.btnPrev = dom.querySelector('[data-btn-prev]')
256
+ this.btnNext = dom.querySelector('[data-btn-next]')
257
+ }
258
+ document.body.appendChild(dom)
259
+ this.dom = dom
260
+ }
261
+
262
+ findTable(target) {
263
+ let node = target
264
+ while (node.parentNode) {
265
+ node = node.parentNode
266
+ if (node.tagName === 'TABLE') {
267
+ return node
268
+ }
269
+ }
270
+ return null
271
+ }
272
+
273
+ addEvents() {
274
+ this.addEvent(this.btnPrev, 'click', event => {
275
+ this.setDate({ date: subMonths(this.date, 1) })
276
+ })
277
+
278
+ this.addEvent(this.btnNext, 'click', () => {
279
+ this.setDate({ date: addMonths(this.date, 1) })
280
+ })
281
+
282
+ if (this.useSingleMenu()) {
283
+ this.addEvent(this.table, 'click', event => {
284
+ if ('dateTableCell' in event.target.dataset) {
285
+ const res = {
286
+ year: getYear(this.date),
287
+ month: getMonth(this.date),
288
+ date: parseInt(event.target.textContent.trim(), 10)
289
+ }
290
+ this.fire('td-click', event, res)
291
+ }
292
+ })
293
+ }
294
+ else {
295
+ this.addEvent(this.table1, 'click', event => {
296
+ if ('dateTableCell' in event.target.dataset) {
297
+ const res = {
298
+ year: getYear(this.date),
299
+ month: getMonth(this.date),
300
+ date: parseInt(event.target.textContent.trim(), 10)
301
+ }
302
+ this.fire('td-click', event, res)
303
+ }
304
+ })
305
+ this.addEvent(this.table2, 'click', event => {
306
+ if ('dateTableCell' in event.target.dataset) {
307
+ const res = {
308
+ year: getYear(this.date2),
309
+ month: getMonth(this.date2),
310
+ date: parseInt(event.target.textContent.trim(), 10)
311
+ }
312
+ this.fire('td-click', event, res)
313
+ }
314
+ })
315
+
316
+ if (this.options.useMouseOver) {
317
+ this.addEvent(this.dom, 'mouseover', throttle(event => {
318
+ if ('dateTableCell' in event.target.dataset) {
319
+ const table = this.findTable(event.target)
320
+ const date = ('dateTable1' in table.dataset) ? this.date : this.date2
321
+ const res = {
322
+ year: getYear(date),
323
+ month: getMonth(date),
324
+ date: parseInt(event.target.textContent.trim(), 10)
325
+ }
326
+ return this.fire('td-mouseover', event, res)
327
+ }
328
+ this.fire('td-mouseover', event, null)
329
+ }, 300))
330
+ }
331
+
332
+ }
333
+ }
334
+
335
+ pos(src) {
336
+ const { dom } = this
337
+ const { pos } = getFloatedTargetPos({
338
+ src,
339
+ target: dom,
340
+ place: 'bottom',
341
+ align: 'left',
342
+ offset: 4
343
+ })
344
+ dom.style.left = toPixel(pos.left)
345
+ dom.style.top = toPixel(pos.top)
346
+ }
347
+
348
+ show(src) {
349
+ const { dom } = this
350
+ dom.style.opacity = 0
351
+ dom.style.display = 'block'
352
+ this.pos(src)
353
+ dom.style.opacity = 1
354
+ this.isVisible = true
355
+ }
356
+
357
+ hide() {
358
+ this.dom.style.display = 'none'
359
+ this.isVisible = false
360
+ }
361
+
362
+ destroy() {
363
+ this.caption = null
364
+ this.btnPrev = null
365
+ this.btnNext = null
366
+ this.table = null
367
+ this.dom.remove()
368
+ this.menu = null
369
+ }
370
+ }