Last active
November 6, 2019 05:46
-
-
Save YuriGor/c413b6d5b6e82554b8a37400a8f6580e to your computer and use it in GitHub Desktop.
vanilla-picker as absolutely auto-positioned dialog added to document.body - WIP: https://github.com/Sphinxxxx/vanilla-picker/issues/24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import colorDialog from './vanillaColorDialog'; | |
document.getElementById('some-other-button').addEventListener('click',function(e){ | |
// auto position is by default | |
colorDialog(e, '#000000'/* ,{ popup: 'auto', popup: ['right', 'left', 'bottom', 'top'], otherVanillaOption: 'whatever' }*/).then(console.log); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/Sphinxxxx/vanilla-picker/issues/24 | |
// https://jsfiddle.net/9g4nsdz3/2/ | |
import merge from 'lodash-es/merge'; | |
import each from 'lodash-es/each'; | |
import isArray from 'lodash-es/isArray'; | |
import Picker from 'vanilla-picker'; | |
const settings = { | |
layout: 'default', | |
alpha: true, | |
editor: true, | |
editorFormat: 'hex', | |
cancelButton: false, | |
popup: 'auto', | |
}; | |
const picker = new Picker({ | |
parent: document.body, | |
}); | |
const placementStyle = document.body.appendChild( | |
document.createElement('style') | |
); | |
picker.originalOpenHandler = picker.openHandler; | |
picker.openHandler = function() {}; | |
export default function showColorDialog(e, currentColor, options) { | |
return new Promise((resolve) => { | |
const clickedElement = e.target; | |
options = merge({}, settings, options); | |
if (options.color || options.colour) { | |
throw new Error('Dont set color in options, use second arg instead.'); | |
} | |
var popups = options.popup; | |
if (isArray(popups)) { | |
options.popup = options.popup[0]; | |
} else { | |
popups = [popups]; | |
} | |
if (options.popup == 'auto') { | |
options.popup = 'right'; | |
popups = ['right', 'left', 'bottom', 'top']; | |
} | |
setPosition(popups[0], clickedElement); | |
picker.setOptions(options); | |
console.log('setOptions', options); | |
picker.setColor(currentColor); | |
picker.onClose = (color) => { | |
color.hexOrRgba = () => { | |
var hexOrRgba = color.hex.toLowerCase(); | |
if (_.endsWith(hexOrRgba, 'ff')) { | |
hexOrRgba = hexOrRgba.substr(0, 7); | |
} else { | |
hexOrRgba = color.rgbaString; | |
} | |
return hexOrRgba; | |
}; | |
resolve(color); | |
}; | |
picker.originalOpenHandler(e); | |
if (!options.alpha) { | |
picker.domElement.classList.add('no_alpha'); | |
} else { | |
picker.domElement.classList.remove('no_alpha'); | |
} | |
if (!options.editor) { | |
picker.domElement.classList.add('no_editor'); | |
} else { | |
picker.domElement.classList.remove('no_editor'); | |
} | |
if (!options.cancelButton) { | |
picker.domElement.classList.add('no_cancel'); | |
} else { | |
picker.domElement.classList.remove('no_cancel'); | |
} | |
autoPosition(popups, options, clickedElement); | |
}); | |
} | |
function setPosition(popup, clickedElement) { | |
const bounds = clickedElement.getBoundingClientRect(); | |
let top, left, translate; | |
switch (popup) { | |
case 'right': | |
left = bounds.right + 15 + window.pageXOffset + 'px'; | |
top = bounds.bottom - 15 + window.pageYOffset + 'px'; | |
translate = '0, 0'; | |
break; | |
case 'left': | |
left = bounds.left - 45 + window.pageXOffset + 'px'; | |
top = bounds.bottom - 15 + window.pageYOffset + 'px'; | |
translate = '-100%, 0'; | |
break; | |
case 'top': | |
left = bounds.left - 15 + window.pageXOffset + 'px'; | |
top = bounds.top - 45 + window.pageYOffset + 'px'; | |
translate = '0, -100%'; | |
break; | |
case 'bottom': | |
left = bounds.left - 15 + window.pageXOffset + 'px'; | |
top = bounds.bottom + 15 + window.pageYOffset + 'px'; | |
translate = '0, 0'; | |
break; | |
} | |
placementStyle.textContent = ` | |
.picker_wrapper.popup.popup_${popup} { | |
top: ${top}; | |
left: ${left}; | |
transform: translate(${translate}); | |
bottom: auto; | |
right: auto; | |
}`; | |
console.log('style updated', placementStyle); | |
} | |
function autoPosition(popups, options, clickedElement) { | |
let pickerBounds = picker.domElement.getBoundingClientRect(); | |
if (doesPickerFit(pickerBounds)) return; | |
each(popups, (popup) => { | |
console.log('autoPosition', popup); | |
if (popup != options.popup) { | |
console.log('switch to new ' + popup + ' position'); | |
options.popup = popup; | |
setPosition(popup, clickedElement); | |
picker.setOptions(options); | |
console.log('setOptions', options); | |
picker.show(); | |
pickerBounds = picker.domElement.getBoundingClientRect(); | |
} | |
if (doesPickerFit(pickerBounds)) { | |
console.log('picker fits ', pickerBounds); | |
return false; | |
} else { | |
console.log("picker doesn't fit ", pickerBounds); | |
} | |
}); | |
} | |
function doesPickerFit(bounds) { | |
return ( | |
bounds.top >= 0 && | |
bounds.right <= window.innerWidth && | |
bounds.bottom <= window.innerHeight && | |
bounds.left >= 0 | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment