https://github.com/mkeller1992/ng-error-tooltips
An Angular library for reactive forms that displays tooltips on form inputs with errors, providing a user-friendly way to visualize validation messages.
https://github.com/mkeller1992/ng-error-tooltips
Last synced: 4 days ago
JSON representation
An Angular library for reactive forms that displays tooltips on form inputs with errors, providing a user-friendly way to visualize validation messages.
- Host: GitHub
- URL: https://github.com/mkeller1992/ng-error-tooltips
- Owner: mkeller1992
- License: mit
- Created: 2025-03-20T10:29:55.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2026-01-13T17:16:36.000Z (5 days ago)
- Last Synced: 2026-01-13T18:22:04.635Z (5 days ago)
- Language: TypeScript
- Size: 2.64 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- fucking-awesome-angular - ng-error-tooltips - Angular reactive forms library that shows error tooltips for user-friendly validation messages. (Third Party Components / Form Validation)
- awesome-angular - ng-error-tooltips - Angular reactive forms library that shows error tooltips for user-friendly validation messages. (Third Party Components / Form Validation)
README
# ng-error-tooltips
[](https://badge.fury.io/js/ng-error-tooltips)

[](https://codecov.io/gh/mkeller1992/ng-error-tooltips)
An Angular library for reactive forms that displays tooltips on form inputs with errors, providing a user-friendly way to visualize validation messages.
The latest library version is compatible with **Angular 21**.
Starting with version **20.1.0**, `ng-error-tooltips` is fully **zoneless-compatible**.
---
## Demo
https://mkeller1992.github.io/ng-error-tooltips/
---
## Install
To install the library, enter the following command in your console:
```bash
npm i ng-error-tooltips
```
---
## Setup
### For apps based on standalone components
Import `ErrorTooltipDirective` directly in your component:
```ts
import { ErrorTooltipDirective } from '@ng-error-tooltips';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
imports: [ErrorTooltipDirective]
})
export class AppComponent {}
```
---
## Usage
Define a reactive form with validators in your TypeScript component.
You can use validators from the `CustomValidators` class, which is part of this library.
For applications with language switching support, use the `CustomValidatorsI18n` variants instead.
```ts
import { Component, inject } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ErrorTooltipDirective, CustomValidators } from '@ng-error-tooltips';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
imports: [FormsModule, ReactiveFormsModule, ErrorTooltipDirective],
})
export class AppComponent {
private readonly formBuilder = inject(FormBuilder);
formGroup: FormGroup = this.formBuilder.group({
nameInput: new FormControl('', {
validators: [
CustomValidators.required(),
CustomValidators.minLength(3),
],
}),
});
}
```
Create the corresponding form in your HTML file and add `ngErrorTooltip` to the form fields where error tooltips should be displayed.
```html
Sample Form
Submit
```
---
### Two ways to pass additional properties
You can pass separate properties, such as `placement`, as shown in the example below:
```html
```
Alternatively, you can pass one or more properties via an `ErrorTooltipOptions` object:
```ts
import { ErrorTooltipOptions } from '@ng-error-tooltips';
tooltipOptions: ErrorTooltipOptions = {
placement: 'right',
};
```
```html
```
---
## Internationalisation (i18n)
Starting with version **21.1.0**, `ng-error-tooltips` supports **reactive multi-language error messages**.
The library itself is intentionally lightweight regarding translations:
- No dependency on `ngx-translate` or similar libraries
- No internal language management
- Fully signal-based and zoneless-friendly
Your application remains the single source of truth for the active language.
### Default behaviour (no configuration)
If you do nothing, the tooltip falls back to **German (`de`)** error messages.
This guarantees **backwards compatibility** for existing applications.
### Providing the active language
To enable language switching, provide the current language as a
`Signal<'de' | 'fr' | 'en'>` using `provideErrorTooltips`.
Example (standalone bootstrap):
```ts
import { bootstrapApplication, inject } from '@angular/core';
import { provideErrorTooltips } from '@ng-error-tooltips';
import { LanguageService } from './language.service';
export const currentLanguageCode = signal(defaultLanguage);
bootstrapApplication(AppComponent, {
providers: [
provideErrorTooltips({ lang: currentLanguageCode })
]
});
```
Whenever the language signal changes, all visible error tooltips update automatically.
### Using i18n-aware validators
For applications with language switching, use the `CustomValidatorsI18n` variants.
```ts
import { CustomValidatorsI18n } from '@ng-error-tooltips';
formGroup = this.fb.group({
name: ['', [
CustomValidatorsI18n.requiredI18n(),
CustomValidatorsI18n.minLengthI18n(3)
]]
});
```
Internally, these validators return tri-language payloads:
```ts
{
de: 'Eingabe erforderlich',
fr: 'Saisie requise',
en: 'Input required'
}
```
The tooltip resolves the correct language automatically.
### App-specific messages (regexPattern)
For domain-specific validation rules, all translations must be provided explicitly:
```ts
CustomValidatorsI18n.regexPatternI18n(
/^[A-Z]{3}\d{4}$/,
{
de: 'Ungültiges Format',
fr: 'Format invalide',
en: 'Invalid format'
}
);
```
This is intentional, as such messages are application-specific and cannot be provided by the library.
### Mixing legacy and i18n validators
You can freely mix:
- legacy validators (`CustomValidators.required()`)
- i18n validators (`CustomValidatorsI18n.requiredI18n()`)
The tooltip handles both transparently.
---
## Properties
| name | type | default | description |
|-----|------|---------|-------------|
| id | string \| number | 0 | A custom id that can be assigned to the tooltip |
| showFirstErrorOnly | boolean | false | Whether the tooltip should only display the first error if multiple errors exist |
| placement | Placement | 'bottom-left' | The position of the tooltip |
| zIndex | number | 1101 | The z-index of the tooltip |
| tooltipClass | string | '' | Additional CSS classes applied to the tooltip (`::ng-deep`) |
| shadow | boolean | true | Whether the tooltip has a shadow |
| offset | number | 8 | Offset of the tooltip relative to the element |
| width | string | '' | Fixed width of the tooltip |
| maxWidth | string | '350px' | Maximum width of the tooltip |
| pointerEvents | "auto" \| "none" | 'auto' | Whether the tooltip reacts to pointer events |
---
## Angular Jest unit tests
### Mocking `ErrorTooltipDirective`
In unit tests, you may want to replace the real directive with the mock directive provided by the library.
```ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ErrorTooltipDirective, MockErrorTooltipDirective } from '@ng-error-tooltips';
import { FormBuilder } from '@angular/forms';
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
providers: [FormBuilder]
})
.overrideComponent(AppComponent, {
remove: {
imports: [ErrorTooltipDirective]
},
add: {
imports: [MockErrorTooltipDirective]
}
})
.compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
});
```