0.0.8 • Published 10 months ago

@controllable-ui/ngx-tooltip v0.0.8

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

Controllable UI - Angular Library ⚡️

✨ Check out the demo here.

license npm version npm downloads

Tooltip

Customizable tooltip component with advanced placement strategies for positioning. It ensures the tooltip is positioned optimally within available screen space, automatically adjusting based on user-defined preferences and space constraints.

Features

  • Uses new browser Popover API: Learn more here (check browser compatibility).
  • HTML content support: Supports HTML content, allowing for richer and more flexible tooltip messages.
  • Customizable style & animations: Supports customizable styles and animations by exposing CSS classes for different parts of the tooltip.
  • Dynamic Placement: Automatically adjusts the tooltip placement based on available space.
  • Customizable Fallback Placements: Define the order of fallback placements to try if the preferred placement lacks space.
  • Multiple Trigger Actions: Open tooltips using hover, focus, or click events.
  • Arrow pointer: Offers an optional arrow that automatically adjusts its position to point to the target element.
  • Timeout Configuration: Configure open and close timeouts for tooltip behavior.
  • Flexible Positioning Strategies: Choose between two strategies:
    • immediately reposition the tooltip when space is limited
    • keep the current placement as long as it fits within the min/max tooltip sizes.

Angular Version Compatibility

Library VersionAngular Version
0.0.717.x.x
0.0.718.x.x

Installation

npm install @controllable-ui/ngx-tooltip

Include the NgxTooltipComponent component in your project by adding it in the imports array.

import { NgxTooltipComponent } from "@controllable-ui/ngx-tooltip";

@Component({
  // ...
  imports: [
    NgxTooltipComponent
  ],
  // ...
})
// ...

Ensure you have the necessary dependencies and the environment set up for compiling and running the component.

Usage

Create the Basic Tooltip Component with desired behavior

<ngx-tooltip [arrow]="arrow()" [triggerActions]="triggerActions()" [tooltipRootClass]="tooltipRootClass()" [scrollableContainer]="scrollableContainer()" [open]="dialogIsOpen()" [enterDelay]="enterDelay()" [leaveDelay]="leaveDelay()" [preferredPlacement]="preferredPlacement()" [placementStrategy]="placementStrategy()" [dialogMinMaxSizes]="dialogMinMaxSizes()" [dialogOffset]="dialogOffset()" (onOpen$)="handleOpen$()" (onClose$)="handleClose$()">
  <span class="relative-element">
    <ng-content select=".relative-element" />
  </span>
  <span class="message">
    <ng-content select=".message" />
  </span>
</ngx-tooltip>
import { CommonModule } from "@angular/common";
import { ChangeDetectionStrategy, Component, ElementRef, input, signal, ViewEncapsulation } from "@angular/core";

import { NgxTooltipComponent } from "@controllable-ui/ngx-tooltip";
import { Placement } from "../../components/tooltip/types";

@Component({
  selector: "app-basic-tooltip",
  standalone: true,
  imports: [CommonModule, NgxTooltipComponent],
  templateUrl: "./basic-tooltip.component.html",
  styleUrl: "./basic-tooltip.component.scss",
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class BasicTooltipComponent {
  arrow = input<boolean>(false);
  triggerActions = input<("hover" | "focus" | "click")[]>(["hover", "focus"]);
  tooltipRootClass = input<string>();
  preferredPlacement = input<Placement>("bottom");
  placementStrategy = input<"default" | "considerKeepingCurrentPlacement">("default");
  dialogOffset = input<number>(10);

  dialogMinMaxSizes = input<{
    dialogMaxHeight?: number;
    dialogMinHeight?: number;
    dialogMaxWidth?: number;
    dialogMinWidth?: number;
  }>();

  scrollableContainer = input<ElementRef<any>>();
  enterDelay = input<number>(100);
  leaveDelay = input<number>(150);

  dialogIsOpen = signal<boolean>(false);

  handleOpen$ = () => {
    this.dialogIsOpen.set(true);
  };

  handleClose$ = () => {
    this.dialogIsOpen.set(false);
  };
}

How to use the created BasicTooltipComponent 🎉

<app-basic-tooltip [scrollableContainer]="scrollableContainerElement()" [tooltipRootClass]="'my-amazing-tooltip'">
  <button class="relative-element">Default - interactive</button>
  <span class="message"> Hover this tooltip and select its content </span>
</app-basic-tooltip>
@Component({
  selector: "app-root",
  standalone: true,
  imports: [RouterOutlet, CommonModule, BasicTooltipComponent],
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  scrollableContainerElement = viewChild<ElementRef>("scrollableContainer");
}

Props

BaseProps

PropTypeDescription
openInputSignal<boolean \| undefined>Input signal that controls whether the tooltip is open or closed.
onOpen$QRL<() => void>Optional callback when the tooltip opens.
onClose$QRL<() => void>Optional callback when the tooltip closes.
preferredPlacementPlacementThe preferred placement of the tooltip (bottom-end, bottom-start, bottom, left-end, left-start, left, right-end, right-start, right, top-end, top-start, top).
orderOfPlacementsToBeTried[Placement, ...Placement[]]The list of placements to try if the preferred one lacks space.
triggerActions("hover", "focus", "click")[]Defines how the tooltip should be triggered (hover, focus, or click).
dialogOffsetnumberDistance between the tooltip and the triggering element.
enterDelaynumberThe number of milliseconds to wait before showing the tooltip.
leaveDelaynumberThe number of milliseconds to wait before hiding the tooltip.
arrowbooleanIf true, renders an arrow on the tooltip.
scrollableContainerHTMLElementScrollable container is the one used to track scroll event and position dialog while scrolling inside it.
tooltipClassstringAdditional class for tooltip dialog.
tooltipRootClassstringAdditional class for tooltip root element (element containing the dialog plus the space between it and relative element).

DefaultStrategyProps

In this strategy, the tooltip is repositioned immediately if the current placement no longer has enough space.

placementStrategy: "default";

KeepCurrentPlacementStrategyProps

Keep current placement of dialog as time as it remains in min & max sizes boundaries.

/* Strategy to keep the current placement as long as space allows. */
placementStrategy: "considerKeepingCurrentPlacement";
/* Dialog size constraints. */
dialogMinMaxSizes?: {
  dialogMaxHeight?: number;
  dialogMinHeight?: number;
  dialogMaxWidth?: number;
  dialogMinWidth?: number;
};

dialogMinMaxSizes:

In case we need to keep current position, we will use maximum & minimum sizes of dialog to check if it fits in current placement, without going over its minimum sizes. In case we don't have minimum size available for current placement, than will be tried next place from orderOfPlacementsToBeTried.

Maximum size is used to make sure to not have a bigger maximum size on dialog popover.

📝Note: we make sure to override the maximum size in case the available space is smaller than the dialog size).

Placement Strategies

You can choose between two different strategies for tooltip placement:

  1. Default Strategy (placementStrategy: "default")

    • The dialog placement will be recalculated immediately if there is insufficient space in the current position.
  2. Consider Keeping Current Placement Strategy (placementStrategy: "considerKeepingCurrentPlacement")

    • Attempts to keep the tooltip in its current position as long as it fits within the provided minimum and maximum size constraints. If space becomes too tight, it switches to the next placement in the list.

Order of Placements

The defaultOrderOfPlacementsToBeTried object provides fallback placement orders for various initial placements. For example:

export const defaultOrderOfPlacementsToBeTried = {
  "top-start": ["top-start", "bottom-start", "left", "right"],
  top: ["top", "bottom", "left", "right"],
  // Additional placement configurations
};

This means if the preferred placement is top-start, the system will try bottom-start, left, and right if there isn’t enough space.

CSS Classes

These class names are useful for styling with CSS. They are applied to the component's slots when specific states are triggered.

Class Names

Class NameDescription
.ngxTooltip-root-containerStyles applied to the root container of the tooltip (it holds the relative element and the tooltip dialog).
.ngxTooltip-arrowStyles applied to the arrow element of the tooltip.
.ngxTooltip-dialog-with-bridgeStyles applied to the tooltip dialog container.
.ngxTooltip-inner-dialog-with-bridgeStyles applied to the inner container of the tooltip dialog.
.ngxTooltip-animated-inner-dialog-with-bridgeStyles applied to the animated container of the tooltip dialog.
.ngxTooltip-tooltipStyles applied to the tooltip's content box.
.ngxTooltip-placement-top-startStyles applied to the tooltip's content box when the placement is "top-start".
.ngxTooltip-placement-topStyles applied to the tooltip's content box when the placement is "top".
.ngxTooltip-placement-top-endStyles applied to the tooltip's content box when the placement is "top-end".
.ngxTooltip-placement-bottom-startStyles applied to the tooltip's content box when the placement is "bottom-start".
.ngxTooltip-placement-bottomStyles applied to the tooltip's content box when the placement is "bottom".
.ngxTooltip-placement-bottom-endStyles applied to the tooltip's content box when the placement is "bottom-end".
.ngxTooltip-placement-left-startStyles applied to the tooltip's content box when the placement is "left-start".
.ngxTooltip-placement-leftStyles applied to the tooltip's content box when the placement is "left".
.ngxTooltip-placement-left-endStyles applied to the tooltip's content box when the placement is "left-end".
.ngxTooltip-placement-right-startStyles applied to the tooltip's content box when the placement is "right-start".
.ngxTooltip-placement-rightStyles applied to the tooltip's content box when the placement is "right".
.ngxTooltip-placement-right-endStyles applied to the tooltip's content box when the placement is "right-end".
.ngxTooltip-showStyles applied to the tooltip when it is visible, triggering the ngxTooltip-show animation.
.ngxTooltip-hideStyles applied to the tooltip when it is hidden, triggering the ngxTooltip-hide animation.
.ngxTooltip-relative-elementStyles applied to the relative element that the tooltip is anchored to.

Animation Classes

  • .ngxTooltip-show

    • Animation: Applies the ngxTooltip-show keyframes.
    • Description: Fades in and scales up the tooltip.
  • .ngxTooltip-hide

    • Animation: Applies the ngxTooltip-hide keyframes.
    • Description: Fades out and scales down the tooltip.

Keyframes

  • @keyframes ngxTooltip-show

    • 0%: Opacity 0, transform scale(0.8)
    • 100%: Opacity 1, transform scale(1)
  • @keyframes ngxTooltip-hide

    • 0%: Opacity 1, transform scale(1)
    • 100%: Opacity 0, transform scale(0.8)

Customization

You can override the style of the component using one of these customization options:

  • With a global class name: Apply custom styles globally to override the default styles.

    .my-amazing-tooltip {
      .ngxTooltip-tooltip {
        background-color: #333;
        color: #fff;
        font-size: 14px;
      }
    
      .ngxTooltip-arrow {
        color: #333;
      }
    }

License

This project is licensed under the MIT License.

0.0.8

10 months ago

0.0.7

10 months ago

0.0.6

10 months ago

0.0.5

10 months ago

0.0.4

10 months ago

0.0.3

10 months ago

0.0.2

10 months ago

0.0.1

10 months ago