mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 15:49:39 +02:00
Add stimulus tooltip controller (#1065)
* Add Tooltip Stimulus controller * Add test for tooltip * Remove comma * Normalize translations * Use floating-ui instead popper * Use component classes * Increase cross axis value * Cleanup * Update app/views/accounts/show.html.erb Use correct tailwind class Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com> Signed-off-by: Tony Vincent <tonyvince7@gmail.com> * Use default values for options * Remove tooltip global variable * Add arrow target * Remove unused method --------- Signed-off-by: Tony Vincent <tonyvince7@gmail.com> Co-authored-by: Zach Gollwitzer <zach.gollwitzer@gmail.com>
This commit is contained in:
parent
6e74414cb2
commit
f315370512
11 changed files with 164 additions and 4 deletions
74
app/javascript/controllers/tooltip_controller.js
Normal file
74
app/javascript/controllers/tooltip_controller.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { Controller } from '@hotwired/stimulus'
|
||||
import {
|
||||
computePosition,
|
||||
flip,
|
||||
shift,
|
||||
offset,
|
||||
arrow
|
||||
} from '@floating-ui/dom';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["arrow", "tooltip"];
|
||||
static values = {
|
||||
placement: { type: String, default: "top" },
|
||||
offset: { type: Number, default: 10 },
|
||||
crossAxis: { type: Number, default: 0 },
|
||||
alignmentAxis: { type: Number, default: null },
|
||||
};
|
||||
|
||||
connect() {
|
||||
this.element.addEventListener("mouseenter", this.showTooltip);
|
||||
this.element.addEventListener("mouseleave", this.hideTooltip);
|
||||
this.element.addEventListener("focus", this.showTooltip);
|
||||
this.element.addEventListener("blur", this.hideTooltip);
|
||||
};
|
||||
|
||||
showTooltip = () => {
|
||||
this.tooltipTarget.style.display = 'block';
|
||||
this.#update();
|
||||
};
|
||||
|
||||
hideTooltip = () => {
|
||||
this.tooltipTarget.style.display = '';
|
||||
};
|
||||
|
||||
disconnect() {
|
||||
this.element.removeEventListener("mouseenter", this.showTooltip);
|
||||
this.element.removeEventListener("mouseleave", this.hideTooltip);
|
||||
this.element.removeEventListener("focus", this.showTooltip);
|
||||
this.element.removeEventListener("blur", this.hideTooltip);
|
||||
};
|
||||
|
||||
#update() {
|
||||
computePosition(this.element, this.tooltipTarget, {
|
||||
placement: this.placementValue,
|
||||
middleware: [
|
||||
offset({ mainAxis: this.offsetValue, crossAxis: this.crossAxisValue, alignmentAxis: this.alignmentAxisValue }),
|
||||
flip(),
|
||||
shift({ padding: 5 }),
|
||||
arrow({ element: this.arrowTarget }),
|
||||
],
|
||||
}).then(({ x, y, placement, middlewareData }) => {
|
||||
Object.assign(this.tooltipTarget.style, {
|
||||
left: `${x}px`,
|
||||
top: `${y}px`,
|
||||
});
|
||||
|
||||
const { x: arrowX, y: arrowY } = middlewareData.arrow;
|
||||
const staticSide = {
|
||||
top: 'bottom',
|
||||
right: 'left',
|
||||
bottom: 'top',
|
||||
left: 'right',
|
||||
}[placement.split('-')[0]];
|
||||
|
||||
Object.assign(this.arrowTarget.style, {
|
||||
left: arrowX != null ? `${arrowX}px` : '',
|
||||
top: arrowY != null ? `${arrowY}px` : '',
|
||||
right: '',
|
||||
bottom: '',
|
||||
[staticSide]: '-4px',
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue