Molbap's picture
Molbap HF Staff
push a bunch of updates
e903a32
raw
history blame
4.08 kB
---
interface Props {
/** The word or term to define */
term: string;
/** The definition of the term */
definition: string;
/** Optional CSS class to apply to the term */
class?: string;
/** Optional style to apply to the term */
style?: string;
/** Tooltip position (top, bottom, left, right) */
position?: 'top' | 'bottom' | 'left' | 'right';
/** Delay before showing tooltip in ms */
delay?: number;
/** Disable tooltip on mobile */
disableOnMobile?: boolean;
}
const {
term,
definition,
class: className = '',
style: inlineStyle = '',
position = 'top',
delay = 300,
disableOnMobile = false,
} = Astro.props as Props;
// Generate a unique ID for this component
const tooltipId = `glossary-${Math.random().toString(36).slice(2)}`;
---
<div class="glossary-container" data-glossary-container-id={tooltipId}>
<span
class={`glossary-term ${className}`}
style={inlineStyle}
data-glossary-term={term}
data-glossary-definition={definition}
data-glossary-position={position}
data-glossary-delay={delay}
data-glossary-disable-mobile={disableOnMobile}
data-glossary-id={tooltipId}
tabindex="0"
role="button"
aria-describedby={`${tooltipId}-tooltip`}
>
{term}
</span>
<div
id={`${tooltipId}-tooltip`}
class="glossary-tooltip"
data-glossary-tooltip-id={tooltipId}
data-position={position}
role="tooltip"
aria-hidden="true"
>
<div class="glossary-tooltip__content">
<div class="glossary-tooltip__term">{term}</div>
<div class="glossary-tooltip__definition">{definition}</div>
</div>
<div class="glossary-tooltip__arrow"></div>
</div>
</div>
<script is:inline>
// Global script for all Glossary tooltips
if (!window.glossaryInitialized) {
window.glossaryInitialized = true;
function initAllGlossaryTooltips() {
const glossaryTerms = document.querySelectorAll('.glossary-term');
glossaryTerms.forEach((termElement) => {
const tooltipElement = termElement.parentElement.querySelector('.glossary-tooltip');
if (!tooltipElement) return;
const term = termElement.getAttribute('data-glossary-term');
const definition = termElement.getAttribute('data-glossary-definition');
if (!term || !definition) return;
// Fonction pour afficher le tooltip au niveau de la souris
const showTooltip = (event) => {
tooltipElement.style.display = 'block';
tooltipElement.style.opacity = '1';
tooltipElement.style.position = 'fixed';
tooltipElement.style.top = (event.clientY + 10) + 'px';
tooltipElement.style.left = (event.clientX + 10) + 'px';
tooltipElement.style.zIndex = '9999';
tooltipElement.style.pointerEvents = 'none';
};
const hideTooltip = () => {
tooltipElement.style.display = 'none';
tooltipElement.style.opacity = '0';
};
// Add events
termElement.addEventListener('mouseenter', showTooltip);
termElement.addEventListener('mouseleave', hideTooltip);
termElement.addEventListener('mousemove', showTooltip);
});
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initAllGlossaryTooltips);
} else {
initAllGlossaryTooltips();
}
// Observe DOM changes for new elements
if (window.MutationObserver) {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1 && node.querySelector && node.querySelector('.glossary-term')) {
initAllGlossaryTooltips();
}
});
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
}
</script>