Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 4x 4x 4x 5x 5x 5x 5x 5x 5x 5x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 5x 5x 4x 4x 4x 4x 4x 4x 5x 5x 5x 5x 5x 4x 4x 4x 4x 4x 4x 4x 4x 4x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x | import { dropdownEl } from '../../utils/dynamic-select-dom.js'
import { isMobile } from '../../utils/mobile-detection.js'
import { IterableWeakSet } from '../../utils/iterable-weak-struct.js'
/** @import {DynamicSelect} from '../../utils/dynamic-select-dom.js' */
/**
* @returns {boolean} true if dropdown should be centered on screen instead
* of being anchored to the select box
*/
export function shouldCenterDropdown () {
return isMobile()
}
const positionFixer = (() => {
/** @type {IterableWeakSet<DynamicSelect>} */
const selectBoxes = new IterableWeakSet()
const viewport = window.visualViewport
if (!viewport) {
return {
applyOnSelect () {},
}
}
const startListening = () => {
viewport.addEventListener('scroll', handler)
viewport.addEventListener('resize', handler)
}
const stopListening = () => {
viewport.removeEventListener('scroll', handler)
viewport.removeEventListener('resize', handler)
}
/**
* @param {HTMLDialogElement} element - dialog element
*/
const updateDropdownPosition = (element) => {
const offsetLeft = viewport.offsetLeft
const offsetTop = viewport.offsetTop
const left = offsetLeft + viewport.width / 2
const top = offsetTop + viewport.height / 2
// You could also do this by setting style.left and style.top if you
// use width: 100% instead.
element.style.transform = `translate(calc(${left}px - 50%), calc(${top}px - 50%)) scale(${1 / viewport.scale})`
element.style.transformOrigin = 'center'
}
const handler = () => {
if (selectBoxes.size <= 0) {
stopListening()
return
}
for (const select of selectBoxes) {
if (!select.open) {
selectBoxes.delete(select)
continue
}
updateDropdownPosition(dropdownEl(select))
}
}
/**
* @param {DynamicSelect} dynamicSelect - target dynamic select
*/
const applyOnSelect = (dynamicSelect) => {
selectBoxes.add(dynamicSelect)
if (dynamicSelect.open) {
const dropdown = dropdownEl(dynamicSelect)
updateDropdownPosition(dropdown)
// apply twice because first `getBoundingClientRect` is not applying in updated transformation
updateDropdownPosition(dropdown)
}
startListening()
}
return {
applyOnSelect,
}
})()
/**
* Updated dropdown content based on the content in dynamic select in light DOM
* @param {DynamicSelect} dynamicSelect - web component element reference
*/
export function centerDropdownPosition (dynamicSelect) {
const dropdown = dropdownEl(dynamicSelect)
positionFixer.applyOnSelect(dynamicSelect)
dropdown.classList.remove('top-direction', 'left-direction')
dropdown.style.marginTop = ''
dropdown.style.marginLeft = ''
}
|