Tooltip "smartPosition"

I am having trouble debuggin why the position of my Tooltip is extending beyond the window width when the tooltip opening is position to far right (As seen on the first 2 images).
image
image

I have narrowed it down to the method:

openPopup: function (parent, id, syncWidth, position, x, y, instance, callback, closeOnDocumentClick = true, autoFocusFirstElement = false, disableSmartPosition = false)
if (smartPosition && left + rect.width > window.innerWidth + scrollbarSize && window.innerWidth + scrollbarSize > rect.width) {
      left = window.innerWidth - rect.width;

      if (position) {
        var tooltipContent = popup.children[0];
        var tooltipContentClassName = 'rz-' + position + '-tooltip-content';
        if (tooltipContent.classList.contains(tooltipContentClassName)) {
          tooltipContent.classList.remove(tooltipContentClassName);
          tooltipContent.classList.add('rz-left-tooltip-content');
          left = parentRect.left - rect.width - 5;
          top = parentRect.top - parentRect.height;
        }
      }
    }

Why does the scrollbarSize have to be taken into account when checking for placement of the tooltip on the x-axis? In my case the scrollbarSize has been calculated based on the verical scroll which had a value of 524. I have double checked this that the scrollbarSize is set here (through clientHeight if statement):

    while (el && el != document.documentElement) {
        if (el.scrollWidth > el.clientWidth) {
            scrollbarSize = el.scrollWidth - el.clientWidth;
            break;
        }

        if (el.scrollHeight > el.clientHeight) {
            scrollbarSize = el.scrollHeight - el.clientHeight;
            break;
        }
        el = el.parentElement;
    }

So take this as an example:
TooltipWidth = 300px
WindowWidth = 2000px
ParentLeft = 1800px
ScrollbarSize = 500px

then the left position will never be re-positioned since WindowWidth + ScrollbarSize is allways greater than TooltipWidth + ParentLeft.

Am i doing anything wrong here? I have tried to do some modifications to the code but then another problem occurs where the hero of the tooltip (the tiny traingle pointing at the parent) is positioned badly. Then it should have a css class indicating that the hero should be right aligned instead of left aligned.

I know this description might be a bit messy so please tell me if i need to elaborate or modify some of it to make it a bit more readable.

As allways thanks for component.

Can you provide an example using our demos demonstrating the problem?

@enchev

@inject TooltipService tooltipService

<div class="rz-p-12 rz-text-align-end">
    <RadzenButton Text="Show tooltip" MouseEnter="@(args => ShowTooltip(args) )" />
</div>

@code {
    void ShowTooltip(ElementReference elementReference, TooltipOptions options = null) => tooltipService.Open(elementReference, "Hello, this is a long text to indicate that the tooltip will then extend the right side of the screen.!", new TooltipOptions() { Duration = 0 });
}


My solution was a bit quick and hacky but what i hoped is something like this:

And then the triangle pointy thing is right aligned instead of left, but that i do not know how to.

We will do our best to improve this for our next update later the week.

1 Like

@enchev

Hi enchev
Some more feedback to the new fix.

try run this code on you demo page and first open popup for uppermost button and afterwards the other:

@inject TooltipService tooltipService

<div class="rz-p-12 rz-text-align-end">
    <RadzenButton Text="Show tooltip" MouseEnter="@(args => ShowTooltip(args) )" />
</div>
<div class="rz-p-12 rz-text-align-center">
    <RadzenButton Text="Show tooltip" MouseEnter="@(args => ShowTooltip(args) )" />
</div>

@code {
    void ShowTooltip(ElementReference elementReference, TooltipOptions options = null) => tooltipService.Open(elementReference, "Hello, this is a long text to indicate that the tooltip will then extend the right side of the screen.!", new TooltipOptions() { Duration = 0 });
}

It only seems to occur when the Popup is not properly closed before opening a new one. I also noticed that in this case the openPopup JavaScript method is actually triggered twice allways.
If you switch back and forth between the 2 popups there also seems to be some calculations which offsets its left position even more.
The top position of the tooltip is not to aligned with the parent top position either.

It seems that the tooltip css can sometimes enter a state where it does not get "reset" when closing.

Also noticed that your default example for all 4 positions (Blazor Tooltip Component | Free UI Components by Radzen) have more offset on "left" and "top" positions than "bottom" and "right".

Regards
Ole

I'll try to address the rest of the issues however this one might need more time.

1 Like

Hi @enchev

Some suggestions and feedback. In my opinion, if i tell the tooltip to have a position of "bottom" it should be placed at bottom no matter what (just like "left", "right" and "top" will do) and not be automatically smartPosition'end.

I know there is an edge case where screen is too small for positioning the entire tooltip in from left or right of parent and will still overflow.

I have made a solution which only solves my bottom positioning, i tried to implement similar logic to positioning the "top" but it did not seem to work properly with the css class of placing the triangle pointer.

I have replaced the code which checks for smartPoisition on x-axis with this:

    // Reset custom classes
    var tooltipContent = popup.children[0];
    tooltipContent.classList.remove('rz-bottom-left-tooltip-content');
    tooltipContent.classList.remove('rz-bottom-right-tooltip-content');
    if (smartPosition && left + rect.width > window.innerWidth && window.innerWidth > rect.width) {
        left = parentRect.right - rect.width;

        var tooltipContentClassName = 'rz-' + position + '-right-tooltip-content';
        tooltipContent.classList.add(tooltipContentClassName);
        tooltipContent.classList.remove('rz-bottom-tooltip-content');
    }
    else if (smartPosition && !tooltipContent.classList.contains('rz-bottom-tooltip-content')) {
        tooltipContent.classList.add('rz-bottom-tooltip-content')
    }

and the CSS classes:

.rz-tooltip .rz-bottom-left-tooltip-content, .rz-bottom-right-tooltip-content {
    margin-top: -8px;
}

    .rz-tooltip .rz-bottom-left-tooltip-content:after {
        content: ' ';
        position: absolute;
        width: 8px;
        height: 8px;
        inset-block-start: 0;
        inset-inline-start: 12px;
        background-color: inherit;
        transform-origin: center;
        transform: translate(-50%, -12px) rotate(45deg);
        border-bottom: inherit;
        border-right: inherit;
    }

.rz-tooltip .rz-bottom-right-tooltip-content:after {
    content: ' ';
    position: absolute;
    width: 8px;
    height: 8px;
    direction: rtl;
    inset-block-start: 0;
    inset-inline-start: 12px;
    background-color: inherit;
    transform-origin: center;
    transform: translate(-50%, -12px) rotate(45deg);
    border-bottom: inherit;
    border-right: inherit;
}

Sorry for the trouble and hope this can help in any kind of way. :slight_smile:

Feel free to submit pull request! If everything works as expected we will merge it.

Okay i will try to look into that.

I've just pushed fix that will be released with our next update:

You can test your cases using our master branch.

1 Like