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.
- checksums.yaml +7 -0
- data/src/font/icomoon.eot +0 -0
- data/src/font/icomoon.svg +125 -0
- data/src/font/icomoon.ttf +0 -0
- data/src/font/icomoon.woff +0 -0
- data/src/img/black-cat.svg +15 -0
- data/src/img/cart.svg +16 -0
- data/src/img/china-flag.svg +16 -0
- data/src/img/ecpay.svg +12 -0
- data/src/img/family-mart.svg +13 -0
- data/src/img/fb-messenger.svg +12 -0
- data/src/img/fb.svg +10 -0
- data/src/img/hct.svg +16 -0
- data/src/img/hi-life.svg +23 -0
- data/src/img/line.svg +14 -0
- data/src/img/ok-mart.svg +9 -0
- data/src/img/pelican.svg +33 -0
- data/src/img/seven-eleven.svg +13 -0
- data/src/img/smilepay.svg +13 -0
- data/src/img/taiwan-flag.svg +17 -0
- data/src/js/components/Alert.js +23 -0
- data/src/js/components/Autocomplete.js +110 -0
- data/src/js/components/AutocompleteMenu.js +88 -0
- data/src/js/components/Btn.js +41 -0
- data/src/js/components/Checkbox.js +24 -0
- data/src/js/components/DateInput.js +74 -0
- data/src/js/components/DateMenu.js +370 -0
- data/src/js/components/DateTimeRanger.js +436 -0
- data/src/js/components/Datepicker.js +250 -0
- data/src/js/components/DatepickerBtnArrow.js +18 -0
- data/src/js/components/Dropdown.js +137 -0
- data/src/js/components/Menu.js +43 -0
- data/src/js/components/Modal.js +76 -0
- data/src/js/components/Navbar.js +47 -0
- data/src/js/components/Radio.js +24 -0
- data/src/js/components/SearchDropdown.js +339 -0
- data/src/js/components/Sidebar.js +56 -0
- data/src/js/components/Tabbox.js +229 -0
- data/src/js/components/TimeInput.js +71 -0
- data/src/js/components/TimeMenu.js +117 -0
- data/src/js/components/Toast.js +47 -0
- data/src/js/components/ToastItem.js +62 -0
- data/src/js/components/Tooltip.js +94 -0
- data/src/js/consts/createdComponents.js +1 -0
- data/src/js/consts/index.js +5 -0
- data/src/js/helpers/bind.js +53 -0
- data/src/js/helpers/dateEq.js +5 -0
- data/src/js/helpers/dateGt.js +5 -0
- data/src/js/helpers/dateLt.js +5 -0
- data/src/js/helpers/docReady.js +10 -0
- data/src/js/helpers/getFloatedTargetPos.js +250 -0
- data/src/js/helpers/getKey.js +14 -0
- data/src/js/helpers/isTouchDevice.js +3 -0
- data/src/js/helpers/msToS.js +3 -0
- data/src/js/helpers/promisify.js +9 -0
- data/src/js/helpers/range.js +7 -0
- data/src/js/helpers/supportDom.js +46 -0
- data/src/js/helpers/toPixel.js +3 -0
- data/src/js/helpers/unbindAll.js +6 -0
- data/src/js/index.js +47 -0
- data/src/js/jquery/bindAlertFn.js +13 -0
- data/src/js/jquery/bindAutocompleteFn.js +13 -0
- data/src/js/jquery/bindBtnFn.js +17 -0
- data/src/js/jquery/bindCheckboxFn.js +13 -0
- data/src/js/jquery/bindDateTimeRangerFn.js +14 -0
- data/src/js/jquery/bindDatepickerFn.js +14 -0
- data/src/js/jquery/bindDropdownFn.js +14 -0
- data/src/js/jquery/bindMenuFn.js +13 -0
- data/src/js/jquery/bindModalFn.js +14 -0
- data/src/js/jquery/bindNavbarFn.js +13 -0
- data/src/js/jquery/bindRadioFn.js +13 -0
- data/src/js/jquery/bindSearchDropdownFn.js +14 -0
- data/src/js/jquery/bindSidebarFn.js +13 -0
- data/src/js/jquery/bindTabboxFn.js +13 -0
- data/src/js/jquery/bindToastFn.js +6 -0
- data/src/js/jquery/bindTooltipFn.js +13 -0
- data/src/js/jquery/index.js +52 -0
- data/src/js/polyfills/classList.js +263 -0
- data/src/js/polyfills/elementDataset.js +3 -0
- data/src/js/polyfills/nodeContains.js +17 -0
- data/src/js/polyfills/nodeHasAttribute.js +5 -0
- data/src/js/polyfills/nodeRemove.js +19 -0
- data/src/sass/_beyond-sprockets.scss +1 -0
- data/src/sass/_beyond.scss +50 -0
- data/src/sass/_main.scss +141 -0
- data/src/sass/abstracts/_mixins.scss +129 -0
- data/src/sass/abstracts/_placeholders.scss +43 -0
- data/src/sass/abstracts/_variables.scss +355 -0
- data/src/sass/base/_background.scss +10 -0
- data/src/sass/base/_typography.scss +183 -0
- data/src/sass/components/_alert.scss +50 -0
- data/src/sass/components/_autocomplete.scss +29 -0
- data/src/sass/components/_avatar.scss +28 -0
- data/src/sass/components/_badge.scss +29 -0
- data/src/sass/components/_breadcrumb.scss +17 -0
- data/src/sass/components/_btn-group.scss +19 -0
- data/src/sass/components/_btn.scss +172 -0
- data/src/sass/components/_card.scss +183 -0
- data/src/sass/components/_checkbox.scss +99 -0
- data/src/sass/components/_date-input.scss +28 -0
- data/src/sass/components/_date-menu.scss +85 -0
- data/src/sass/components/_date-time-ranger.scss +21 -0
- data/src/sass/components/_datepicker.scss +3 -0
- data/src/sass/components/_dropdown.scss +144 -0
- data/src/sass/components/_form.scss +383 -0
- data/src/sass/components/_icon.scss +371 -0
- data/src/sass/components/_input.scss +48 -0
- data/src/sass/components/_list.scss +23 -0
- data/src/sass/components/_modal.scss +72 -0
- data/src/sass/components/_nav.scss +75 -0
- data/src/sass/components/_navbar.scss +211 -0
- data/src/sass/components/_pagination.scss +64 -0
- data/src/sass/components/_radio.scss +71 -0
- data/src/sass/components/_search-dropdown.scss +28 -0
- data/src/sass/components/_select.scss +54 -0
- data/src/sass/components/_sidebar.scss +35 -0
- data/src/sass/components/_spinner.scss +79 -0
- data/src/sass/components/_tabbox.scss +83 -0
- data/src/sass/components/_table.scss +65 -0
- data/src/sass/components/_tag.scss +43 -0
- data/src/sass/components/_time-input.scss +28 -0
- data/src/sass/components/_time-menu.scss +24 -0
- data/src/sass/components/_toast.scss +51 -0
- data/src/sass/components/_tooltip.scss +10 -0
- data/src/sass/img/arrow-dropdown.svg +4 -0
- data/src/sass/img/arrow-select-ex.svg +18 -0
- data/src/sass/img/arrow-select.svg +18 -0
- data/src/sass/layout/_border-util.scss +36 -0
- data/src/sass/layout/_col.scss +90 -0
- data/src/sass/layout/_container.scss +44 -0
- data/src/sass/layout/_flex-util.scss +18 -0
- data/src/sass/layout/_offset-util.scss +20 -0
- data/src/sass/layout/_sizing-util.scss +14 -0
- data/src/sass/layout/_spacing-util.scss +9 -0
- data/src/sass/layout/_visibility-util.scss +25 -0
- data/src/sass/vendor/_normalize.scss +578 -0
- data/src/sass/vendor/_turbolink.scss +5 -0
- 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,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,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
|
+
}
|