using Microsoft.AspNetCore.Components; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Radzen.Blazor; namespace Radzen { /// /// A service for displaying tooltips programmatically on UI elements or at specific positions. /// TooltipService provides methods to show tooltips with text or custom HTML content, with configurable positioning, delays, and durations. /// To use this service, add it as a scoped service in your application's service collection and place a RadzenTooltip component in your main layout. /// Manages tooltip lifecycle, automatically closing tooltips on navigation and providing various positioning options (top, bottom, left, right). /// Tooltips can be shown on mouse enter/leave events or on demand, with configurable delays before showing and auto-close durations. /// /// /// Show a simple text tooltip: /// /// @inject TooltipService TooltipService /// <RadzenButton Text="Hover me" MouseEnter="@(args => TooltipService.Open(args, "This is a tooltip"))" /> /// /// Show a tooltip with HTML content and custom options: /// /// @inject TooltipService TooltipService /// <RadzenButton Text="Show tooltip" MouseEnter="@(args => ShowTooltipWithHtml(args))" /> /// @code { /// void ShowTooltipWithHtml(ElementReference element) => TooltipService.Open(element, ts => /// @<div> /// <b>Bold</b> and <i>italic</i> content /// </div>, /// new TooltipOptions { Position = TooltipPosition.Top, Duration = 5000 }); /// } /// /// public class TooltipService : IDisposable { /// /// Gets or sets the navigation manager. /// /// The navigation manager. NavigationManager? navigationManager { get; set; } /// /// Initializes a new instance of the class. /// /// The URI helper. public TooltipService(NavigationManager uriHelper) { navigationManager = uriHelper; if (navigationManager != null) { navigationManager.LocationChanged += UriHelper_OnLocationChanged; } } /// /// Handles the OnLocationChanged event of the UriHelper control. /// /// The source of the event. /// The instance containing the event data. private void UriHelper_OnLocationChanged(object? sender, Microsoft.AspNetCore.Components.Routing.LocationChangedEventArgs e) { if (this.OnNavigate != null) { this.OnNavigate(); } } /// /// Occurs when [on navigate]. /// public event Action? OnNavigate; /// /// Raises the Close event. /// public event Action? OnClose; /// /// Occurs when [on open]. /// public event Action? OnOpen; /// /// Occurs when [on open chart tooltip]. /// internal event Action? OnOpenChartTooltip; /// /// Opens a tooltip with custom HTML content near the specified element. /// The tooltip will be positioned according to the options and can contain any Blazor markup. /// /// The HTML element reference near which the tooltip will be displayed. /// A render fragment that defines the custom HTML content of the tooltip. Receives the TooltipService as context. /// Optional tooltip configuration including position, duration, delay, and styling. If null, default options are used. public void Open(ElementReference element, RenderFragment childContent, TooltipOptions? options = null) { var tooltipOptions = options ?? new TooltipOptions(); tooltipOptions.ChildContent = childContent; OpenTooltip(element, tooltipOptions); } /// /// Opens a tooltip with simple text content near the specified element. /// This is the most common way to show basic informational tooltips. /// /// The HTML element reference near which the tooltip will be displayed. /// The text content to display in the tooltip. /// Optional tooltip configuration including position, duration, delay, and styling. If null, default options are used. public void Open(ElementReference element, string text, TooltipOptions? options = null) { var tooltipOptions = options ?? new TooltipOptions(); tooltipOptions.Text = text; OpenTooltip(element, tooltipOptions); } /// /// Opens a tooltip with text content positioned above the specified element. /// This is a convenience method equivalent to calling Open() with TooltipPosition.Top. /// /// The HTML element reference above which the tooltip will be displayed. /// The text content to display in the tooltip. /// Optional additional tooltip configuration. The Position will be set to Top regardless of the value in options. public void OpenOnTheTop(ElementReference element, string text, TooltipOptions? options = null) { var tooltipOptions = options ?? new TooltipOptions(); tooltipOptions.Text = text; tooltipOptions.Position = TooltipPosition.Top; OpenTooltip(element, tooltipOptions); } /// /// Opens the specified element on the bottom position. /// /// The element. /// The text. /// The o. public void OpenOnTheBottom(ElementReference element, string text, TooltipOptions? o = null) { var options = o ?? new TooltipOptions(); options.Text = text; options.Position = TooltipPosition.Bottom; OpenTooltip(element, options); } /// /// Opens the specified element on the left position. /// /// The element. /// The text. /// The o. public void OpenOnTheLeft(ElementReference element, string text, TooltipOptions? o = null) { var options = o ?? new TooltipOptions(); options.Text = text; options.Position = TooltipPosition.Left; OpenTooltip(element, options); } /// /// Opens the specified element on the right position. /// /// The element. /// The text. /// The o. public void OpenOnTheRight(ElementReference element, string text, TooltipOptions? o = null) { var options = o ?? new TooltipOptions(); options.Text = text; options.Position = TooltipPosition.Right; OpenTooltip(element, options); } /// /// Opens the specified chart tooltip. /// /// The chart element. /// /// /// Content of the chart tooltip. /// The options of the chart tooltip. internal void OpenChartTooltip(ElementReference element, double x, double y, RenderFragment childContent, ChartTooltipOptions? o = null) { var options = o ?? new ChartTooltipOptions(); options.ChildContent = childContent; OnOpenChartTooltip?.Invoke(element, x, y, options); } /// /// Opens the tooltip. /// /// /// The element. /// The options. private void OpenTooltip(ElementReference element, TooltipOptions options) { OnOpen?.Invoke(element, typeof(T), options); } /// /// Closes this instance. /// public void Close() { OnClose?.Invoke(); } /// /// Disposes this instance. /// public void Dispose() { navigationManager?.LocationChanged -= UriHelper_OnLocationChanged; GC.SuppressFinalize(this); } } /// /// Enum TooltipPosition /// public enum TooltipPosition { /// /// The left /// Left, /// /// The top /// Top, /// /// The right /// Right, /// /// The bottom /// Bottom } /// /// Class TooltipOptions. /// public class TooltipOptions { /// /// Gets or sets the position. /// /// The position. public TooltipPosition Position { get; set; } = TooltipPosition.Bottom; /// /// Gets or sets the duration. /// /// The duration. public int? Duration { get; set; } = 2000; /// /// Gets or sets the delay. /// /// The delay. public int? Delay { get; set; } /// /// Gets or sets a value indicating whether the tooltip should be closed by clicking the document. /// /// true if closeable; otherwise, false. public bool CloseTooltipOnDocumentClick { get; set; } = true; /// /// Gets or sets the style. /// /// The style. public string? Style { get; set; } /// /// Gets or sets the CSS class. /// /// The CSS class. public string? CssClass { get; set; } /// /// Gets or sets the text. /// /// The text. public string? Text { get; set; } /// /// Gets or sets the child content. /// /// The child content. public RenderFragment? ChildContent { get; set; } } /// /// Class Tooltip. /// public class Tooltip { /// /// Gets or sets the type. /// /// The type. public Type? Type { get; set; } /// /// Gets or sets the options. /// /// The options. public TooltipOptions Options { get; set; } = new TooltipOptions(); /// /// Gets or sets the element. /// /// The element. public ElementReference Element { get; set; } } internal class ChartTooltipOptions { /// /// Gets or sets the color scheme used to render the tooltip. /// /// The color scheme. public ColorScheme ColorScheme { get; set; } /// /// Gets or sets the child content. /// /// The child content. public RenderFragment? ChildContent { get; set; } } }