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