Creating Custom Tooltips
Overview
This guide will teach you how to create a custom tooltip component for the @celerofinancas/ui-directives library using the TOOLTIP_COMPONENT_TOKEN. You'll learn to build a tooltip component from scratch that integrates seamlessly with the tooltip directive system.
What You'll Build
By the end of this guide, you'll have:
- A custom tooltip component that implements the required interface
- Proper styling with arrow indicators for different placements
- A component that can be injected via dependency injection tokens
- Full integration with the existing tooltip directive system
Prerequisites
- Basic Angular knowledge
- Understanding of Angular components and dependency injection
- Familiarity with TypeScript interfaces
Step 1: Understanding the TooltipBase Interface
First, you need to understand what interface your component must implement:
export interface TooltipBase {
text: string;
tooltipRef?: TemplateRef<any>;
maxWidth?: string | number;
placement?: TooltipPlacement;
}
export type TooltipPlacement = 'top' | 'bottom' | 'start' | 'end';
Step 2: Create the Component Structure
Create your tooltip component file:
import { ChangeDetectionStrategy, Component, Input, TemplateRef } from '@angular/core';
import { TooltipBase, TooltipPlacement } from '@celerofinancas/ui-directives';
@Component({
selector: 'app-tooltip',
standalone: true,
templateUrl: './tooltip.component.html',
styleUrl: './tooltip.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TooltipComponent implements TooltipBase {
// We'll implement the required properties next
}
Step 3: Implement Required Properties
Add the required properties from the TooltipBase interface:
export class TooltipComponent implements TooltipBase {
/**
* The text content to display in the tooltip
*/
@Input()
public text = '';
/**
* Optional template reference for custom tooltip content
*/
@Input()
public tooltipRef?: TemplateRef<any>;
/**
* Maximum width constraint for the tooltip
*/
@Input()
public maxWidth?: string | number;
/**
* Position of the tooltip relative to the trigger element
*/
@Input()
public placement?: TooltipPlacement = 'top';
}
Step 4: Create the Template
Create the HTML template for your tooltip:
<div
[class]="'tooltip-container ' + (placement || 'top')"
[style.max-width.px]="maxWidth"
>
<!-- Handle custom template content -->
<ng-container *ngIf="tooltipRef; else defaultContent">
<ng-container *ngTemplateOutlet="tooltipRef"></ng-container>
</ng-container>
<!-- Default text content -->
<ng-template #defaultContent>
<span class="tooltip-text">{{ text }}</span>
</ng-template>
</div>
Step 5: Add Styling
Create the CSS/SCSS styles for your tooltip:
.tooltip-container {
background: #333;
color: white;
padding: 8px 12px;
border-radius: 4px;
font-size: 14px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
.tooltip-text {
white-space: nowrap;
font-weight: 500;
}
// Arrow styles for different placements
&.top::before {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: #333;
}
&.bottom::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-bottom-color: #333;
}
&.start::before {
content: '';
position: absolute;
top: 50%;
left: 100%;
transform: translateY(-50%);
border: 6px solid transparent;
border-left-color: #333;
}
&.end::before {
content: '';
position: absolute;
top: 50%;
right: 100%;
transform: translateY(-50%);
border: 6px solid transparent;
border-right-color: #333;
}
}
Step 6: Register Your Component with the Token
Configure your custom tooltip component to be used by the directive system:
import { TOOLTIP_COMPONENT_TOKEN } from '@celerofinancas/ui-directives';
import { TooltipComponent } from '@shared/components/tooltip/tooltip.component';
export const APPLICATION_TOKENS = [
// Register your custom tooltip component
{ provide: TOOLTIP_COMPONENT_TOKEN, useValue: TooltipComponent },
// ... other tokens
];
Step 7: Provide the Token in Your Application
Add the token to your application's providers:
import { ApplicationConfig } from '@angular/core';
import { APPLICATION_TOKENS } from './configs/tokens';
export const appConfig: ApplicationConfig = {
providers: [
// ... other providers
...APPLICATION_TOKENS,
],
};
Step 8: Test Your Component
Now you can use your custom tooltip component with the directive:
<!-- Basic usage -->
<button
[cdsTooltip]="'This is a custom tooltip'"
placement="top"
>
Hover me
</button>
<!-- With different placements -->
<div [cdsTooltip]="'Bottom tooltip'" placement="bottom">Bottom</div>
<div [cdsTooltip]="'Start tooltip'" placement="start">Start</div>
<div [cdsTooltip]="'End tooltip'" placement="end">End</div>
<!-- With max width -->
<span
[cdsTooltip]="'This is a very long tooltip text that will be constrained by max width'"
[maxWidth]="200"
>
Long tooltip
</span>
Advanced Customization
Adding Animation
Enhance your tooltip with animations:
.tooltip-container {
// ... existing styles
animation: fadeIn 0.2s ease-in-out;
@keyframes fadeIn {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
}
Theme Support
Add CSS custom properties for theming:
.tooltip-container {
background: var(--tooltip-background, #333);
color: var(--tooltip-text-color, white);
border: var(--tooltip-border, none);
// Update arrow colors to use custom properties
&.top::before {
border-top-color: var(--tooltip-background, #333);
}
// ... repeat for other placements
}
Adding Custom Logic
Extend your component with additional functionality:
export class TooltipComponent implements TooltipBase {
@Input() text = '';
@Input() tooltipRef?: TemplateRef<any>;
@Input() maxWidth?: string | number;
@Input() placement?: TooltipPlacement = 'top';
// Additional custom properties
@Input() showDelay = 0;
@Input() hideDelay = 0;
@Input() theme: 'light' | 'dark' = 'dark';
get containerClasses(): string {
return `tooltip-container ${this.placement} ${this.theme}`;
}
}
Best Practices
1. Accessibility
- Add ARIA attributes for screen readers
- Ensure proper keyboard navigation support
- Use semantic HTML elements
2. Performance
- Use
OnPushchange detection strategy - Keep animations lightweight
- Avoid complex calculations in templates
3. Maintainability
- Follow consistent naming conventions
- Document your custom properties
- Write unit tests for your component
4. Design System Integration
- Use design tokens/CSS custom properties
- Follow your organization's design guidelines
- Ensure consistency across different themes
Troubleshooting
Common Issues
- Component not appearing: Ensure the token is properly registered and provided
- Styling not applied: Check CSS specificity and ensure styles are included
- Arrow positioning issues: Verify placement classes and CSS calculations
- Animation glitches: Test with different placement positions and screen sizes
Congratulations! You now have a fully functional custom tooltip component that integrates with the @celerofinancas/ui-directives system.