refactor(forms): Add a lightweight DI token for Control (#64188)

This will allow optionally injecting the Control directive without
importing the full directive.

PR Close #64188
This commit is contained in:
Miles Malerba
2025-10-01 14:50:23 -07:00
parent 732635b382
commit 823384207b
2 changed files with 16 additions and 0 deletions
@@ -10,6 +10,7 @@ import { ElementRef } from '@angular/core';
import { HttpResourceOptions } from '@angular/common/http';
import { HttpResourceRequest } from '@angular/common/http';
import * as i0 from '@angular/core';
import { InjectionToken } from '@angular/core';
import { Injector } from '@angular/core';
import { InputSignal } from '@angular/core';
import { ModelSignal } from '@angular/core';
@@ -64,6 +65,9 @@ export interface ChildFieldContext<TValue> extends RootFieldContext<TValue> {
readonly key: Signal<string>;
}
// @public
export const CONTROL: InjectionToken<Control<unknown>>;
// @public
export class Control<T> {
get cva(): ControlValueAccessor | undefined;
@@ -15,6 +15,7 @@ import {
ElementRef,
EventEmitter,
inject,
InjectionToken,
Injector,
Input,
InputSignal,
@@ -41,6 +42,13 @@ import {FormCheckboxControl, FormUiControl, FormValueControl} from './control';
import {AggregateProperty, MAX, MAX_LENGTH, MIN, MIN_LENGTH, PATTERN, REQUIRED} from './property';
import type {Field} from './types';
/**
* Lightweight DI token provided by the {@link Control} directive.
*/
export const CONTROL = new InjectionToken<Control<unknown>>(
typeof ngDevMode !== undefined && ngDevMode ? 'CONTROL' : '',
);
/**
* Binds a form `Field` to a UI control that edits it. A UI control can be one of several things:
* 1. A native HTML input or textarea
@@ -66,6 +74,10 @@ import type {Field} from './types';
provide: NgControl,
useFactory: () => inject(Control).ngControl,
},
{
provide: CONTROL,
useExisting: Control,
},
],
})
export class Control<T> {