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,47 @@
1
+ import supportDom from '../helpers/supportDom'
2
+ import ToastItem from './ToastItem'
3
+
4
+ @supportDom
5
+ export default class Toast {
6
+
7
+ constructor() {
8
+ this.init()
9
+ }
10
+
11
+ init() {
12
+ const toast = document.createElement('div')
13
+ toast.classList.add('toast')
14
+ document.body.appendChild(toast)
15
+ this.toast = toast
16
+ this.items = []
17
+ }
18
+
19
+ send(arg) {
20
+
21
+ let options = arg
22
+
23
+ if (typeof arg === 'string') {
24
+ options = { message: arg }
25
+ }
26
+
27
+ const toastItem = new ToastItem(options)
28
+ this.toast.appendChild(toastItem.dom)
29
+ this.items.push(toastItem)
30
+
31
+ toastItem._showTimer = setTimeout(() => toastItem.show(), 50)
32
+ toastItem._timer = setTimeout(() => {
33
+ this.items = this.items.filter(item => item !== toastItem)
34
+ toastItem.destroy()
35
+ }, options.duration || 3000)
36
+
37
+ return () => {
38
+ this.items = this.items.filter(item => item !== toastItem)
39
+ toastItem.destroy()
40
+ }
41
+ }
42
+
43
+ destroy() {
44
+ this.items.forEach(item => item.destroy())
45
+ this.toast.remove()
46
+ }
47
+ }
@@ -0,0 +1,62 @@
1
+ import supportDom from '../helpers/supportDom'
2
+
3
+ @supportDom
4
+ export default class ToastItem {
5
+
6
+ constructor(options = {}) {
7
+ this.options = options
8
+ this.init()
9
+ }
10
+
11
+ init() {
12
+
13
+ const { message, btnText, btnCb } = this.options
14
+
15
+ const dom = document.createElement('div')
16
+ dom.innerHTML = `
17
+ <div class="toast-item">
18
+ <div class="toast-message">${message}</div>
19
+ </div>
20
+ `
21
+ dom.className = 'toast-item-box'
22
+
23
+ this.dom = dom
24
+
25
+ if (btnText) {
26
+ this.dom.classList.add('has-btn')
27
+ this.createBtn(btnText)
28
+ }
29
+ if (btnText && btnCb) {
30
+ this.createBtnCb()
31
+ }
32
+ }
33
+
34
+ show() {
35
+ this.dom.classList.add('visible')
36
+ }
37
+
38
+ createBtn() {
39
+ const btn = document.createElement('button')
40
+ btn.className = 'toast-btn'
41
+ btn.innerText = this.options.btnText
42
+ this.dom.querySelector('.toast-item').appendChild(btn)
43
+ this.btn = btn
44
+ }
45
+
46
+ createBtnCb() {
47
+ this.addEvent(this.btn, 'click', () => {
48
+ this.options.btnCb({
49
+ clear: () => {
50
+ this.destroy()
51
+ }
52
+ })
53
+ })
54
+ }
55
+
56
+ destroy() {
57
+ const { dom } = this
58
+ clearTimeout(dom._showTimer)
59
+ clearTimeout(dom._timer)
60
+ dom.remove()
61
+ }
62
+ }
@@ -0,0 +1,94 @@
1
+ import getFloatedTargetPos from '../helpers/getFloatedTargetPos'
2
+ import toPixel from '../helpers/toPixel'
3
+ import supportDom from '../helpers/supportDom'
4
+
5
+ const TOOLTIP_PLACEMENTS = ['top', 'bottom', 'left', 'right']
6
+
7
+ @supportDom
8
+ export default class Tooltip {
9
+
10
+ constructor(dom) {
11
+ this.dom = dom
12
+ this.tooltip = document.querySelector('[data-global-tooltip]')
13
+ this.init()
14
+ }
15
+
16
+ init() {
17
+ this.appendTooltip()
18
+ this.addEvents()
19
+ }
20
+
21
+ appendTooltip() {
22
+ if (this.tooltip) {
23
+ return
24
+ }
25
+ const tooltip = document.createElement('div')
26
+ tooltip.setAttribute('data-global-tooltip', '')
27
+ tooltip.classList.add('tooltip')
28
+ document.body.appendChild(tooltip)
29
+ this.tooltip = tooltip
30
+ }
31
+
32
+ static remove() {
33
+ const div = document.querySelector('[data-global-tooltip]')
34
+ if (div) {
35
+ div.remove()
36
+ }
37
+ }
38
+
39
+ getPlace() {
40
+ const str = this.dom.dataset.place
41
+ return TOOLTIP_PLACEMENTS.includes(str) ? str : 'bottom'
42
+ }
43
+
44
+ getOffset() {
45
+ const num = parseInt(this.dom.dataset.offset, 10)
46
+ return Number.isInteger(num) ? num : 10
47
+ }
48
+
49
+ setTooltipMsg() {
50
+ const { msg } = this.dom.dataset
51
+ if (this.tooltip.innerHTML !== msg) {
52
+ this.tooltip.innerHTML = msg
53
+ }
54
+ }
55
+
56
+ hide() {
57
+ const { tooltip } = this
58
+ if (tooltip) {
59
+ tooltip.style.opacity = 0
60
+ tooltip.style.display = 'none'
61
+ }
62
+ }
63
+
64
+ addEvents() {
65
+ const { dom, tooltip } = this
66
+ if ('onmouseover' in dom) {
67
+ this.addEvent(dom, 'mouseover', () => {
68
+ this.setTooltipMsg()
69
+
70
+ tooltip.style.opacity = 0
71
+ tooltip.style.display = 'block'
72
+
73
+ const { pos } = getFloatedTargetPos({
74
+ src: dom,
75
+ target: tooltip,
76
+ place: this.getPlace(),
77
+ offset: this.getOffset()
78
+ })
79
+ tooltip.style.left = toPixel(pos.left)
80
+ tooltip.style.top = toPixel(pos.top)
81
+ tooltip.style.opacity = 1
82
+ })
83
+ }
84
+ if ('onmouseleave' in dom) {
85
+ const handleMouseLeave = () => this.hide()
86
+ this.addEvent(dom, 'click', handleMouseLeave)
87
+ this.addEvent(dom, 'mouseleave', handleMouseLeave)
88
+ }
89
+ }
90
+
91
+ destroy() {
92
+ this.hide()
93
+ }
94
+ }
@@ -0,0 +1 @@
1
+ export default []
@@ -0,0 +1,5 @@
1
+ import locale from 'date-fns/locale/zh-TW'
2
+
3
+ export const DEFAULT_TIMEZONE = 'Asia/Taipei'
4
+
5
+ export const DEFAULT_LOCALE = locale
@@ -0,0 +1,53 @@
1
+ import Alert from '../components/Alert'
2
+ import Checkbox from '../components/Checkbox'
3
+ import Dropdown from '../components/Dropdown'
4
+ import Menu from '../components/Menu'
5
+ import Navbar from '../components/Navbar'
6
+ import Radio from '../components/Radio'
7
+ import Sidebar from '../components/Sidebar'
8
+ import Tabbox from '../components/Tabbox'
9
+ import Tooltip from '../components/Tooltip'
10
+
11
+ const $ = selector => Array.from(document.querySelectorAll(selector))
12
+
13
+ const defaultOptions = {
14
+ selectors: {
15
+ alert: '[data-alert]',
16
+ checkbox: 'input[type="checkbox"]',
17
+ dropdown: '[data-dropdown]',
18
+ menu: '[data-menu-toggle]',
19
+ navbar: '[data-navbar]',
20
+ radio: 'input[type="radio"]',
21
+ sidebar: '[data-sidebar-opener]',
22
+ tabbox: '[data-tabbox]',
23
+ tooltip: '[data-tooltip]'
24
+ }
25
+ }
26
+
27
+ export default function bind(opts = {}) {
28
+
29
+ const options = Object.assign({}, defaultOptions, opts)
30
+ const { selectors } = options
31
+
32
+ const alerts = $(selectors.alert).map(dom => new Alert(dom))
33
+ const checkboxes = $(selectors.checkbox).map(dom => new Checkbox(dom))
34
+ const dropdowns = $(selectors.dropdown).map(dom => new Dropdown(dom))
35
+ const menus = $(selectors.menu).map(dom => new Menu(dom))
36
+ const navbars = $(selectors.navbar).map(dom => new Navbar(dom))
37
+ const radios = $(selectors.radio).map(dom => new Radio(dom))
38
+ const sidebars = $(selectors.sidebar).map(dom => new Sidebar(dom))
39
+ const tabboxes = $(selectors.tabbox).map(dom => new Tabbox(dom))
40
+ const tooltips = $(selectors.tooltip).map(dom => new Tooltip(dom))
41
+
42
+ return function unbind() {
43
+ alerts.forEach(alert => alert.destroy())
44
+ checkboxes.forEach(checkbox => checkbox.destroy())
45
+ dropdowns.forEach(dropdown => dropdown.destroy())
46
+ menus.forEach(menu => menu.destroy())
47
+ navbars.forEach(navbar => navbar.destroy())
48
+ radios.forEach(radio => radio.destroy())
49
+ sidebars.forEach(sidebar => sidebar.destroy())
50
+ tabboxes.forEach(tabbox => tabbox.destroy())
51
+ tooltips.forEach(tooltip => tooltip.destroy())
52
+ }
53
+ }
@@ -0,0 +1,5 @@
1
+ import compareAsc from 'date-fns/compareAsc'
2
+
3
+ export default function dateEq(date1, date2) {
4
+ return compareAsc(date1, date2) === 0
5
+ }
@@ -0,0 +1,5 @@
1
+ import compareAsc from 'date-fns/compareAsc'
2
+
3
+ export default function dateLt(date1, date2) {
4
+ return compareAsc(date1, date2) === 1
5
+ }
@@ -0,0 +1,5 @@
1
+ import compareAsc from 'date-fns/compareAsc'
2
+
3
+ export default function dateLt(date1, date2) {
4
+ return compareAsc(date1, date2) === -1
5
+ }
@@ -0,0 +1,10 @@
1
+ export default function docReady() {
2
+ return new Promise(resolve => {
3
+ const { readyState } = document
4
+ if (['complete', 'interactive'].includes(readyState)) {
5
+ setTimeout(resolve, 1)
6
+ return
7
+ }
8
+ document.addEventListener('DOMContentLoaded', resolve)
9
+ })
10
+ }
@@ -0,0 +1,250 @@
1
+ import getDomPos from '@superlanding/getdompos'
2
+ import getScrollTop from '@superlanding/getscrolltop'
3
+ import getScrollLeft from '@superlanding/getscrollleft'
4
+
5
+ // Calculate floated target position for tooltip and dropdown
6
+ export default function getFloatedTargetPos(options) {
7
+
8
+ const { src, target, place, align, offset = 0, offsetLeft, offsetTop } = options
9
+
10
+ const { x: x1, y: y1 } = getDomPos(src)
11
+
12
+ const w1 = src.offsetWidth
13
+ const h1 = src.offsetHeight
14
+
15
+ const w2 = target.offsetWidth
16
+ const h2 = target.offsetHeight
17
+
18
+ let pos = getPos({ x1, y1, w1, h1, w2, h2, place, align, offset })
19
+ let posWithOffsets = addExtraOffsets({ pos, offsetLeft, offsetTop })
20
+
21
+ // auto detect the best placement and alignment
22
+ const detectedPlace = detectPlace({ pos: posWithOffsets, place, w2, h2 })
23
+ const detectedAlign = detectAlign({ pos: posWithOffsets, place, align, w2, h2 })
24
+
25
+ const placeDifferent = (place !== detectedPlace)
26
+ const alignDifferent = (align !== detectedAlign)
27
+
28
+ if (placeDifferent || alignDifferent) {
29
+ pos = getPos({
30
+ x1, y1, w1, h1, w2, h2,
31
+ place: detectedPlace, align: detectedAlign, offset
32
+ })
33
+
34
+ let adjustedOffsetLeft = offsetLeft
35
+ let adjustedOffsetTop = offsetTop
36
+
37
+ if (placeDifferent && ['left', 'right'].includes(detectedPlace)) {
38
+ adjustedOffsetLeft = -adjustedOffsetLeft
39
+ }
40
+ if (placeDifferent && ['top', 'bottom'].includes(detectedPlace)) {
41
+ adjustedOffsetTop = -adjustedOffsetTop
42
+ }
43
+
44
+ posWithOffsets = addExtraOffsets({
45
+ pos,
46
+ offsetLeft: adjustedOffsetLeft,
47
+ offsetTop: adjustedOffsetTop
48
+ })
49
+ }
50
+
51
+ const posWithSafeBoundary = adjustToBoundary({
52
+ pos: posWithOffsets,
53
+ w1, h1, w2, h2,
54
+ place, align
55
+ })
56
+ return {
57
+ pos: posWithSafeBoundary,
58
+ place: detectedPlace,
59
+ align: detectedAlign
60
+ }
61
+ }
62
+
63
+ function getTouchedData({ pos, w2, h2 }) {
64
+ const { left, top } = pos
65
+ const scrollTop = getScrollTop()
66
+ const scrollBottom = scrollTop + window.innerHeight
67
+ const scrollLeft = getScrollLeft()
68
+ const scrollRight = scrollLeft + window.innerWidth
69
+ const touchedTop = (top < scrollTop)
70
+ const touchedBottom = ((top + h2) > scrollBottom)
71
+ const touchedLeft = (left < scrollLeft)
72
+ const touchedRight = ((left + w2) > scrollRight)
73
+ return { touchedTop, touchedBottom, touchedLeft, touchedRight }
74
+ }
75
+
76
+ function detectPlace({ pos, place, w2, h2 }) {
77
+
78
+ const { touchedTop, touchedBottom,
79
+ touchedLeft, touchedRight } = getTouchedData({ pos, w2, h2 })
80
+
81
+ if ((place === 'top') && touchedTop) {
82
+ return 'bottom'
83
+ }
84
+ if ((place === 'bottom') && touchedBottom) {
85
+ return 'top'
86
+ }
87
+ if ((place === 'left') && touchedLeft) {
88
+ return 'right'
89
+ }
90
+ if ((place === 'right') && touchedRight) {
91
+ return 'left'
92
+ }
93
+ return place
94
+ }
95
+
96
+ function detectAlign({ pos, place, align, w2, h2 }) {
97
+ const isVertical = ['top', 'bottom'].includes(place)
98
+ const isHorizontal = ['left', 'right'].includes(place)
99
+ const { touchedTop, touchedBottom,
100
+ touchedLeft, touchedRight } = getTouchedData({ pos, w2, h2 })
101
+
102
+ if (isVertical && touchedLeft) {
103
+ return 'left'
104
+ }
105
+ if (isVertical && touchedRight) {
106
+ return 'right'
107
+ }
108
+ if (isHorizontal && touchedTop) {
109
+ return 'top'
110
+ }
111
+ if (isHorizontal && touchedBottom) {
112
+ return 'bottom'
113
+ }
114
+ return align
115
+ }
116
+
117
+ function getPos(options) {
118
+
119
+ const { place, align = 'center' } = options
120
+
121
+ switch (`${place}_${align}`) {
122
+ case 'top_left':
123
+ return getTopLeftPos(options)
124
+ case 'top_right':
125
+ return getTopRightPos(options)
126
+ case 'top_center':
127
+ return getTopCenterPos(options)
128
+ case 'bottom_left':
129
+ return getBottomLeftPos(options)
130
+ case 'bottom_right':
131
+ return getBottomRightPos(options)
132
+ case 'bottom_center':
133
+ return getBottomCenterPos(options)
134
+ case 'left_top':
135
+ return getLeftTopPos(options)
136
+ case 'left_bottom':
137
+ return getLeftBottomPos(options)
138
+ case 'left_center':
139
+ return getLeftCenterPos(options)
140
+ case 'right_top':
141
+ return getRightTopPos(options)
142
+ case 'right_bottom':
143
+ return getRightBottomPos(options)
144
+ case 'right_center':
145
+ return getRightCenterPos(options)
146
+ default:
147
+ throw new Error(`Unsupported placement and alignment: ${place} ${align}`)
148
+ }
149
+ }
150
+
151
+ function getTopLeftPos({ x1, y1, h2, offset }) {
152
+ const top = y1 - offset - h2
153
+ const left = x1
154
+ return { left, top }
155
+ }
156
+
157
+ function getTopRightPos({ x1, y1, w1, w2, h2, offset }) {
158
+ const top = y1 - offset - h2
159
+ const left = x1 - (w2 - w1)
160
+ return { left, top }
161
+ }
162
+
163
+ function getTopCenterPos({ x1, y1, w1, w2, h2, offset }) {
164
+ const top = y1 - offset - h2
165
+ const left = x1 + (w1 / 2) - (w2 / 2)
166
+ return { left, top }
167
+ }
168
+
169
+ function getBottomLeftPos({ x1, y1, h1, offset }) {
170
+ const top = y1 + h1 + offset
171
+ const left = x1
172
+ return { left, top }
173
+ }
174
+
175
+ function getBottomRightPos({ x1, y1, w1, h1, w2, offset }) {
176
+ const top = y1 + h1 + offset
177
+ const left = x1 - (w2 - w1)
178
+ return { left, top }
179
+ }
180
+
181
+ function getBottomCenterPos({ x1, y1, w1, h1, w2, offset }) {
182
+ const top = y1 + h1 + offset
183
+ const left = x1 + (w1 / 2) - (w2 / 2)
184
+ return { left, top }
185
+ }
186
+
187
+ function getLeftTopPos({ x1, y1, w2, offset }) {
188
+ const left = x1 - offset - w2
189
+ const top = y1
190
+ return { left, top }
191
+ }
192
+
193
+ function getLeftBottomPos({ x1, y1, h1, w2, h2, offset }) {
194
+ const left = x1 - offset - w2
195
+ const top = y1 - (h2 - h1)
196
+ return { left, top }
197
+ }
198
+
199
+ function getLeftCenterPos({ x1, y1, h1, w2, h2, offset }) {
200
+ const left = x1 - offset - w2
201
+ const top = y1 + (h1 / 2) - (h2 / 2)
202
+ return { left, top }
203
+ }
204
+
205
+ function getRightTopPos({ x1, y1, w1, offset }) {
206
+ const left = x1 + w1 + offset
207
+ const top = y1
208
+ return { left, top }
209
+ }
210
+
211
+ function getRightBottomPos({ x1, y1, w1, h1, h2, offset }) {
212
+ const left = x1 + w1 + offset
213
+ const top = y1 - (h2 - h1)
214
+ return { left, top }
215
+ }
216
+
217
+ function getRightCenterPos({ x1, y1, w1, h1, h2, offset }) {
218
+ const left = x1 + w1 + offset
219
+ const top = y1 + (h1 / 2) - (h2 / 2)
220
+ return { left, top }
221
+ }
222
+
223
+ function adjustToBoundary({ pos, w1, w2, h1, h2 }) {
224
+
225
+ const { touchedTop, touchedBottom,
226
+ touchedLeft, touchedRight } = getTouchedData({ pos, w2, h2 })
227
+
228
+ let left = pos.left
229
+ let top = pos.top
230
+ if (touchedLeft) {
231
+ left = 0
232
+ }
233
+ if (touchedRight) {
234
+ left = window.innerWidth - w2 + w1;
235
+ }
236
+ if (touchedTop) {
237
+ top = 0
238
+ }
239
+ if (touchedBottom) {
240
+ top = window.innerHeight - h2 + h1
241
+ }
242
+ return { top, left }
243
+ }
244
+
245
+ function addExtraOffsets({ pos, offsetLeft = 0, offsetTop = 0 }) {
246
+ return {
247
+ left: pos.left + offsetLeft,
248
+ top: pos.top + offsetTop
249
+ }
250
+ }