Created
December 27, 2023 08:08
-
-
Save premanshup/bf8d36a8868ff55c36818dfc2f3e5661 to your computer and use it in GitHub Desktop.
Floating UI: autoPlacement demo
This file contains 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
<!doctype html> | |
<html> | |
<head> | |
<title>Floating UI Tutorial</title> | |
<style> | |
body { | |
display: flex; | |
height: 100vh; | |
} | |
button { | |
height: 20px; | |
} | |
#tooltip, #click-tooltip { | |
display: none; | |
width: max-content; | |
position: absolute; | |
top: 0; | |
left: 0; | |
background: #222; | |
color: white; | |
font-weight: bold; | |
padding: 5px; | |
border-radius: 4px; | |
font-size: 90%; | |
} | |
#arrow, #click-arrow { | |
position: absolute; | |
background: #222; | |
width: 8px; | |
height: 8px; | |
transform: rotate(45deg); | |
} | |
/* | |
* TOGGLE COMMENTS TO SET DIFFERENT POSITIONS | |
*/ | |
/* TOP LEFT */ | |
/* body { | |
justify-content: flex-start; | |
} */ | |
/* TOP CENTER */ | |
/* body { | |
justify-content: center; | |
} */ | |
/* TOP RIGHT */ | |
/* body { | |
justify-content: flex-end; | |
} */ | |
/* CENTER LEFT */ | |
/* body { | |
align-items: center; | |
justify-content: flex-start; | |
} */ | |
/* CENTER CENTER */ | |
/* body { | |
align-items: center; | |
justify-content: center; | |
} */ | |
/* CENTER RIGHT */ | |
/* body { | |
align-items: center; | |
justify-content: flex-end; | |
} */ | |
/* BOTTOM LEFT */ | |
/* body { | |
align-items: flex-end; | |
justify-content: flex-start; | |
} */ | |
/* BOTTOM CENTER */ | |
/* body { | |
align-items: flex-end; | |
justify-content: center; | |
} */ | |
/* BOTTOM RIGHT */ | |
/* body { | |
align-items: flex-end; | |
justify-content: flex-end; | |
} */ | |
</style> | |
</head> | |
<body> | |
<button id="button" aria-describedby="tooltip"> | |
My button | |
</button> | |
<div id="tooltip" role="tooltip"> | |
My tooltip | |
<div id="arrow"></div> | |
</div> | |
<script type="module"> | |
import { | |
computePosition, | |
flip, | |
shift, | |
offset, | |
arrow, | |
autoPlacement, | |
} from 'https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.5.3/+esm'; | |
const button = document.querySelector('#button'); | |
const tooltip = document.querySelector('#tooltip'); | |
const arrowElement = document.querySelector('#arrow'); | |
function update() { | |
computePosition(button, tooltip, { | |
placement: 'top', | |
middleware: [ | |
autoPlacement({ | |
alignment: 'start', | |
// Won't also choose 'end' alignments if those fit better | |
autoAlignment: false, | |
}), | |
offset(6), | |
// flip(), | |
shift({padding: 5}), | |
arrow({element: arrowElement}), | |
], | |
}).then(({x, y, placement, middlewareData}) => { | |
Object.assign(tooltip.style, { | |
left: `${x}px`, | |
top: `${y}px`, | |
}); | |
// Accessing the data | |
const {x: arrowX, y: arrowY} = middlewareData.arrow; | |
const staticSide = { | |
top: 'bottom', | |
right: 'left', | |
bottom: 'top', | |
left: 'right', | |
}[placement.split('-')[0]]; | |
Object.assign(arrowElement.style, { | |
left: arrowX != null ? `${arrowX}px` : '', | |
top: arrowY != null ? `${arrowY}px` : '', | |
right: '', | |
bottom: '', | |
[staticSide]: '-4px', | |
}); | |
}); | |
} | |
function showTooltip() { | |
tooltip.style.display = 'block'; | |
update(); | |
} | |
function hideTooltip() { | |
tooltip.style.display = ''; | |
} | |
[ | |
['mouseenter', showTooltip], | |
['mouseleave', hideTooltip], | |
['focus', showTooltip], | |
['blur', hideTooltip], | |
].forEach(([event, listener]) => { | |
button.addEventListener(event, listener); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment