# easy-invoice/2.3.4/assets/js/tooltip-manager.js

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.3.4. 339 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.3.4/code/assets/js/tooltip-manager.js
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.3.4/raw/assets/js/tooltip-manager.js
- Modified: 2025-08-14T09:51:16+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.3.4/code/assets/js/tooltip-manager.js#L10-L20`.

```javascript
/**
 * Easy Invoice Tooltip Manager
 * Reusable tooltip system for the Easy Invoice plugin
 */
(function($) {
    'use strict';
    
    // Tooltip Manager object
    window.EasyInvoiceTooltip = {
        
        // Initialize tooltip system
        init: function() {
            this.setupTooltipContainer();
            this.bindEvents();
        },
        
        // Create tooltip container if it doesn't exist
        setupTooltipContainer: function() {
            if ($('#easy-invoice-tooltip').length === 0) {
                var tooltipHTML = `
                    <div id="easy-invoice-tooltip" class="fixed z-[9999] px-3 py-2 text-sm text-white bg-gray-900 rounded-lg shadow-xl opacity-0 transition-all duration-200 transform scale-95" style="display: none; pointer-events: none; user-select: none;">
                        <div class="tooltip-content font-medium"></div>
                        <div class="tooltip-arrow" style="position: absolute; width: 0; height: 0; border: 6px solid transparent;"></div>
                    </div>
                `;
                $('body').append(tooltipHTML);
            }
        },
        
        // Bind tooltip events
        bindEvents: function() {
            var self = this;
            
            // Mouse enter event
            $(document).off('mouseenter', '[data-tooltip]').on('mouseenter', '[data-tooltip]', function(e) {
                var tooltipText = $(this).data('tooltip');
                var position = $(this).data('tooltip-position') || 'top'; // top, bottom, left, right
                var delay = $(this).data('tooltip-delay') || 200;
                
                self.showTooltip($(this), tooltipText, position, delay);
            });
            
            // Mouse leave event
            $(document).off('mouseleave', '[data-tooltip]').on('mouseleave', '[data-tooltip]', function() {
                self.hideTooltip();
            });
            
            // Hide tooltip on scroll
            $(window).off('scroll.tooltip').on('scroll.tooltip', function() {
                self.hideTooltip();
            });
            

        },
        
        // Show tooltip
        showTooltip: function($element, text, position, delay) {
            var self = this;
            var $tooltip = $('#easy-invoice-tooltip');
            
            // Set tooltip content
            $tooltip.find('.tooltip-content').text(text);
            
            // Clear any existing timeout
            if (self.showTimeout) {
                clearTimeout(self.showTimeout);
            }
            
            // Show tooltip after delay
            self.showTimeout = setTimeout(function() {
                // Disable transitions temporarily to prevent sliding
                $tooltip.css('transition', 'none');
                
                // First make tooltip visible but transparent to get dimensions
                $tooltip.show().css('opacity', '0').removeClass('opacity-0 scale-95');
                
                // Position tooltip
                self.positionTooltip($element, $tooltip, position);
                
                // Re-enable transitions and make it visible with animation
                setTimeout(function() {
                    $tooltip.css('transition', 'all 0.2s ease');
                    $tooltip.addClass('opacity-100 scale-100').css('opacity', '1');
                }, 10);
            }, delay);
        },
        
        // Hide tooltip
        hideTooltip: function() {
            var $tooltip = $('#easy-invoice-tooltip');
            
            // Clear any existing timeout
            if (this.showTimeout) {
                clearTimeout(this.showTimeout);
            }
            
            $tooltip.removeClass('opacity-100 scale-100').addClass('opacity-0 scale-95');
            setTimeout(function() {
                $tooltip.hide();
            }, 200);
        },
        
        // Position tooltip
        positionTooltip: function($element, $tooltip, position) {
            var elementRect = $element[0].getBoundingClientRect();
            var $arrow = $tooltip.find('.tooltip-arrow');
            
            // Get tooltip dimensions after it's visible
            var tooltipWidth = $tooltip.outerWidth();
            var tooltipHeight = $tooltip.outerHeight();
            
            var left, top;
            var arrowStyles = {};
            var offset = 12; // Space between tooltip and element
            
            // Calculate position based on preference
            switch (position) {
                case 'top':
                    left = elementRect.left + (elementRect.width / 2) - (tooltipWidth / 2);
                    top = elementRect.top - tooltipHeight - offset;
                    arrowStyles = {
                        'position': 'absolute',
                        'top': '100%',
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-left': '6px solid transparent',
                        'border-right': '6px solid transparent',
                        'border-top': '6px solid #111827',
                        'border-bottom': 'none'
                    };
                    break;
                    
                case 'bottom':
                    left = elementRect.left + (elementRect.width / 2) - (tooltipWidth / 2);
                    top = elementRect.bottom + offset;
                    arrowStyles = {
                        'position': 'absolute',
                        'bottom': '100%',
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-left': '6px solid transparent',
                        'border-right': '6px solid transparent',
                        'border-bottom': '6px solid #111827',
                        'border-top': 'none'
                    };
                    break;
                    
                case 'left':
                    left = elementRect.left - tooltipWidth - offset;
                    top = elementRect.top + (elementRect.height / 2) - (tooltipHeight / 2);
                    arrowStyles = {
                        'position': 'absolute',
                        'left': '100%',
                        'top': '50%',
                        'transform': 'translateY(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-top': '6px solid transparent',
                        'border-bottom': '6px solid transparent',
                        'border-left': '6px solid #111827',
                        'border-right': 'none'
                    };
                    break;
                    
                case 'right':
                    left = elementRect.right + offset;
                    top = elementRect.top + (elementRect.height / 2) - (tooltipHeight / 2);
                    arrowStyles = {
                        'position': 'absolute',
                        'right': '100%',
                        'top': '50%',
                        'transform': 'translateY(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-top': '6px solid transparent',
                        'border-bottom': '6px solid transparent',
                        'border-right': '6px solid #111827',
                        'border-left': 'none'
                    };
                    break;
                    
                default:
                    left = elementRect.left + (elementRect.width / 2) - (tooltipWidth / 2);
                    top = elementRect.top - tooltipHeight - offset;
                    arrowStyles = {
                        'position': 'absolute',
                        'top': '100%',
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-left': '6px solid transparent',
                        'border-right': '6px solid transparent',
                        'border-top': '6px solid #111827',
                        'border-bottom': 'none'
                    };
            }
            
            // Ensure tooltip doesn't go off screen
            var adjustedPosition = this.adjustPosition(left, top, { width: tooltipWidth, height: tooltipHeight }, position);
            left = adjustedPosition.left;
            top = adjustedPosition.top;
            
            // Update arrow styles if position changed
            if (adjustedPosition.position !== position) {
                arrowStyles = this.getArrowStyles(adjustedPosition.position);
            }
            
            // Apply positioning
            $tooltip.css({
                left: left + 'px',
                top: top + 'px'
            });
            
            // Update arrow with complete styles
            $arrow.css(arrowStyles);
        },
        
        // Adjust position to keep tooltip on screen
        adjustPosition: function(left, top, tooltipRect, position) {
            var windowWidth = window.innerWidth;
            var windowHeight = window.innerHeight;
            var margin = 10;
            
            // Check horizontal bounds
            if (left < margin) {
                left = margin;
            } else if (left + tooltipRect.width > windowWidth - margin) {
                left = windowWidth - tooltipRect.width - margin;
            }
            
            // Check vertical bounds and adjust position if needed
            if (top < margin) {
                if (position === 'top') {
                    top = margin;
                    position = 'bottom';
                }
            } else if (top + tooltipRect.height > windowHeight - margin) {
                if (position === 'bottom') {
                    top = windowHeight - tooltipRect.height - margin;
                    position = 'top';
                }
            }
            
            return { left: left, top: top, position: position };
        },
        
        // Get arrow styles for position
        getArrowStyles: function(position) {
            switch (position) {
                case 'top':
                    return {
                        'position': 'absolute',
                        'top': '100%',
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-left': '6px solid transparent',
                        'border-right': '6px solid transparent',
                        'border-top': '6px solid #111827',
                        'border-bottom': 'none'
                    };
                case 'bottom':
                    return {
                        'position': 'absolute',
                        'bottom': '100%',
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-left': '6px solid transparent',
                        'border-right': '6px solid transparent',
                        'border-bottom': '6px solid #111827',
                        'border-top': 'none'
                    };
                case 'left':
                    return {
                        'position': 'absolute',
                        'left': '100%',
                        'top': '50%',
                        'transform': 'translateY(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-top': '6px solid transparent',
                        'border-bottom': '6px solid transparent',
                        'border-left': '6px solid #111827',
                        'border-right': 'none'
                    };
                case 'right':
                    return {
                        'position': 'absolute',
                        'right': '100%',
                        'top': '50%',
                        'transform': 'translateY(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-top': '6px solid transparent',
                        'border-bottom': '6px solid transparent',
                        'border-right': '6px solid #111827',
                        'border-left': 'none'
                    };
                default:
                    return {
                        'position': 'absolute',
                        'top': '100%',
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '0',
                        'height': '0',
                        'border-left': '6px solid transparent',
                        'border-right': '6px solid transparent',
                        'border-top': '6px solid #111827',
                        'border-bottom': 'none'
                    };
            }
        },
        
        // Public method to show tooltip programmatically
        show: function($element, text, position, delay) {
            this.showTooltip($element, text, position || 'top', delay || 0);
        },
        
        // Public method to hide tooltip programmatically
        hide: function() {
            this.hideTooltip();
        }
    };
    
    // Initialize tooltip system when document is ready
    $(document).ready(function() {
        EasyInvoiceTooltip.init();
    });
    
})(jQuery); 
```
