Files
rio/frontend/code/components/tooltip.ts
2024-07-27 20:02:37 +02:00

90 lines
2.6 KiB
TypeScript

import { ComponentId } from '../dataModels';
import { ComponentBase, ComponentState } from './componentBase';
import { getPositionerByName, PopupManager } from '../popupManager';
export type TooltipState = ComponentState & {
_type_: 'Tooltip-builtin';
anchor?: ComponentId;
_tip_component?: ComponentId | null;
position?: 'auto' | 'left' | 'top' | 'right' | 'bottom';
gap?: number;
};
export class TooltipComponent extends ComponentBase {
state: Required<TooltipState>;
private popupElement: HTMLElement;
private popupManager: PopupManager;
createElement(): HTMLElement {
// Set up the HTML
let element = document.createElement('div');
element.classList.add('rio-tooltip');
this.popupElement = document.createElement('div');
this.popupElement.classList.add(
'rio-tooltip-popup',
'rio-popup-animation-scale',
'rio-switcheroo-hud'
);
// Listen for events
element.addEventListener('mouseover', () => {
this.popupManager.isOpen = true;
});
element.addEventListener('mouseout', () => {
this.popupManager.isOpen = false;
});
// Initialize the popup manager. Many of these values will be
// overwritten by the updateElement method.
this.popupManager = new PopupManager(
element,
this.popupElement,
getPositionerByName('center', 0.5, 0.0)
);
return element;
}
updateElement(
deltaState: TooltipState,
latentComponents: Set<ComponentBase>
): void {
super.updateElement(deltaState, latentComponents);
// Update the anchor
if (deltaState.anchor !== undefined) {
this.replaceOnlyChild(
latentComponents,
deltaState.anchor,
this.element
);
}
// Update tip
if (deltaState._tip_component !== undefined) {
this.replaceOnlyChild(
latentComponents,
deltaState._tip_component,
this.popupElement
);
}
// Update the popup manager
if (deltaState.position !== undefined || deltaState.gap !== undefined) {
this.popupManager.positioner = getPositionerByName(
deltaState.position ?? this.state.position,
0.5,
deltaState.gap ?? this.state.gap
);
}
}
onDestruction(): void {
super.onDestruction();
this.popupManager.destroy();
}
}