Skip to content

Instantly share code, notes, and snippets.

@premanshup
Created December 27, 2023 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save premanshup/bf8d36a8868ff55c36818dfc2f3e5661 to your computer and use it in GitHub Desktop.
Save premanshup/bf8d36a8868ff55c36818dfc2f3e5661 to your computer and use it in GitHub Desktop.
Floating UI: autoPlacement demo
<!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