Files
ionic-framework/packages/angular/src/ionic-module.ts
Sean Perkins 77707b8c1e fix(angular): min/max validator for ion-input type number (#27993)
Issue number: Resolves #23480

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

Angular's min/max validators do not work with `ion-input[type=number]`.
Using the built-in validators with `ion-input` will not update the
control status to invalid, reflect the `ng-invalid` class or report the
correct errors.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- The `IonicModule` now includes two additional directive declarations
that extend Angular's built-in min/max validators and target the
`ion-input` component when using `type="number"`.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-08-18 18:34:02 +00:00

100 lines
3.0 KiB
TypeScript

import { CommonModule, DOCUMENT } from '@angular/common';
import { ModuleWithProviders, APP_INITIALIZER, NgModule, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { IonicConfig } from '@ionic/core';
import { appInitialize } from './app-initialize';
import {
BooleanValueAccessorDirective,
NumericValueAccessorDirective,
RadioValueAccessorDirective,
SelectValueAccessorDirective,
TextValueAccessorDirective,
} from './directives/control-value-accessors';
import { IonBackButtonDelegateDirective } from './directives/navigation/ion-back-button';
import { INPUT_BINDER, IonRouterOutlet, RoutedComponentInputBinder } from './directives/navigation/ion-router-outlet';
import { IonTabs } from './directives/navigation/ion-tabs';
import { NavDelegate } from './directives/navigation/nav-delegate';
import {
RouterLinkDelegateDirective,
RouterLinkWithHrefDelegateDirective,
} from './directives/navigation/router-link-delegate';
import { IonModal } from './directives/overlays/modal';
import { IonPopover } from './directives/overlays/popover';
import { DIRECTIVES } from './directives/proxies-list';
import { IonMaxValidator, IonMinValidator } from './directives/validators';
import { AngularDelegate } from './providers/angular-delegate';
import { ConfigToken } from './providers/config';
import { ModalController } from './providers/modal-controller';
import { PopoverController } from './providers/popover-controller';
const DECLARATIONS = [
// generated proxies
...DIRECTIVES,
// manual proxies
IonModal,
IonPopover,
// ngModel accessors
BooleanValueAccessorDirective,
NumericValueAccessorDirective,
RadioValueAccessorDirective,
SelectValueAccessorDirective,
TextValueAccessorDirective,
// navigation
IonTabs,
IonRouterOutlet,
IonBackButtonDelegateDirective,
NavDelegate,
RouterLinkDelegateDirective,
RouterLinkWithHrefDelegateDirective,
// validators
IonMinValidator,
IonMaxValidator,
];
@NgModule({
declarations: DECLARATIONS,
exports: DECLARATIONS,
providers: [AngularDelegate, ModalController, PopoverController],
imports: [CommonModule],
})
export class IonicModule {
static forRoot(config?: IonicConfig): ModuleWithProviders<IonicModule> {
return {
ngModule: IonicModule,
providers: [
{
provide: ConfigToken,
useValue: config,
},
{
provide: APP_INITIALIZER,
useFactory: appInitialize,
multi: true,
deps: [ConfigToken, DOCUMENT, NgZone],
},
{
provide: INPUT_BINDER,
useFactory: componentInputBindingFactory,
deps: [Router],
},
],
};
}
}
function componentInputBindingFactory(router?: Router) {
/**
* We cast the router to any here, since the componentInputBindingEnabled
* property is not available until Angular v16.
*/
if ((router as any)?.componentInputBindingEnabled) {
return new RoutedComponentInputBinder();
}
return null;
}