beyond-rails 0.0.139

Sign up to get free protection for your applications and to get access to all the features.
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
+ }