Skip to content

Commit 29340a0

Browse files
crisbetoAndrewKushnir
authored andcommitted
fix(core): expose input transform function on ComponentFactory and ComponentMirror (#50713)
Exposes the function used to transform an input on `ComponentFactory.inputs` and `ComponentMirror.inputs`. We'll need this to support input transforms in `elements`. PR Close #50713
1 parent 30154ae commit 29340a0

File tree

6 files changed

+54
-7
lines changed

6 files changed

+54
-7
lines changed

goldens/public-api/core/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ export abstract class ComponentFactory<C> {
225225
abstract get inputs(): {
226226
propName: string;
227227
templateName: string;
228+
transform?: (value: any) => any;
228229
}[];
229230
abstract get ngContentSelectors(): string[];
230231
abstract get outputs(): {
@@ -246,6 +247,7 @@ export interface ComponentMirror<C> {
246247
get inputs(): ReadonlyArray<{
247248
readonly propName: string;
248249
readonly templateName: string;
250+
readonly transform?: (value: any) => any;
249251
}>;
250252
get isStandalone(): boolean;
251253
get ngContentSelectors(): ReadonlyArray<string>;

packages/core/src/linker/component_factory.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ export abstract class ComponentFactory<C> {
106106
/**
107107
* The inputs of the component.
108108
*/
109-
abstract get inputs(): {propName: string, templateName: string}[];
109+
abstract get inputs(): {
110+
propName: string,
111+
templateName: string,
112+
transform?: (value: any) => any,
113+
}[];
110114
/**
111115
* The outputs of the component.
112116
*/

packages/core/src/render3/component.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ export interface ComponentMirror<C> {
106106
/**
107107
* The inputs of the component.
108108
*/
109-
get inputs(): ReadonlyArray<{readonly propName: string, readonly templateName: string}>;
109+
get inputs(): ReadonlyArray<{
110+
readonly propName: string,
111+
readonly templateName: string,
112+
readonly transform?: (value: any) => any,
113+
}>;
110114
/**
111115
* The outputs of the component.
112116
*/
@@ -178,7 +182,11 @@ export function reflectComponentType<C>(component: Type<C>): ComponentMirror<C>|
178182
get type(): Type<C> {
179183
return factory.componentType;
180184
},
181-
get inputs(): ReadonlyArray<{propName: string, templateName: string}> {
185+
get inputs(): ReadonlyArray<{
186+
propName: string,
187+
templateName: string,
188+
transform?: (value: any) => any,
189+
}> {
182190
return factory.inputs;
183191
},
184192
get outputs(): ReadonlyArray<{propName: string, templateName: string}> {

packages/core/src/render3/component_ref.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,28 @@ export class ComponentFactory<T> extends AbstractComponentFactory<T> {
118118
override ngContentSelectors: string[];
119119
isBoundToModule: boolean;
120120

121-
override get inputs(): {propName: string; templateName: string;}[] {
122-
return toRefArray(this.componentDef.inputs);
121+
override get inputs(): {
122+
propName: string,
123+
templateName: string,
124+
transform?: (value: any) => any,
125+
}[] {
126+
const componentDef = this.componentDef;
127+
const inputTransforms = componentDef.inputTransforms;
128+
const refArray = toRefArray(componentDef.inputs) as {
129+
propName: string,
130+
templateName: string,
131+
transform?: (value: any) => any,
132+
}[];
133+
134+
if (inputTransforms !== null) {
135+
for (const input of refArray) {
136+
if (inputTransforms.hasOwnProperty(input.propName)) {
137+
input.transform = inputTransforms[input.propName];
138+
}
139+
}
140+
}
141+
142+
return refArray;
123143
}
124144

125145
override get outputs(): {propName: string; templateName: string;}[] {

packages/core/test/acceptance/component_spec.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,8 @@ describe('component', () => {
924924

925925
describe('reflectComponentType', () => {
926926
it('should create an ComponentMirror for a standalone component', () => {
927+
function transformFn() {}
928+
927929
@Component({
928930
selector: 'standalone-component',
929931
standalone: true,
@@ -937,6 +939,7 @@ describe('component', () => {
937939
outputs: ['output-a', 'output-b:output-alias-b'],
938940
})
939941
class StandaloneComponent {
942+
@Input({alias: 'input-alias-c', transform: transformFn}) inputC: unknown;
940943
}
941944

942945
const mirror = reflectComponentType(StandaloneComponent)!;
@@ -946,7 +949,8 @@ describe('component', () => {
946949
expect(mirror.isStandalone).toEqual(true);
947950
expect(mirror.inputs).toEqual([
948951
{propName: 'input-a', templateName: 'input-a'},
949-
{propName: 'input-b', templateName: 'input-alias-b'}
952+
{propName: 'input-b', templateName: 'input-alias-b'},
953+
{propName: 'inputC', templateName: 'input-alias-c', transform: transformFn},
950954
]);
951955
expect(mirror.outputs).toEqual([
952956
{propName: 'output-a', templateName: 'output-a'},
@@ -958,6 +962,8 @@ describe('component', () => {
958962
});
959963

960964
it('should create an ComponentMirror for a non-standalone component', () => {
965+
function transformFn() {}
966+
961967
@Component({
962968
selector: 'non-standalone-component',
963969
template: `
@@ -970,6 +976,7 @@ describe('component', () => {
970976
outputs: ['output-a', 'output-b:output-alias-b'],
971977
})
972978
class NonStandaloneComponent {
979+
@Input({alias: 'input-alias-c', transform: transformFn}) inputC: unknown;
973980
}
974981

975982
const mirror = reflectComponentType(NonStandaloneComponent)!;
@@ -979,7 +986,8 @@ describe('component', () => {
979986
expect(mirror.isStandalone).toEqual(false);
980987
expect(mirror.inputs).toEqual([
981988
{propName: 'input-a', templateName: 'input-a'},
982-
{propName: 'input-b', templateName: 'input-alias-b'}
989+
{propName: 'input-b', templateName: 'input-alias-b'},
990+
{propName: 'inputC', templateName: 'input-alias-c', transform: transformFn},
983991
]);
984992
expect(mirror.outputs).toEqual([
985993
{propName: 'output-a', templateName: 'output-a'},

packages/core/test/render3/component_ref_spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ describe('ComponentFactory', () => {
5151
});
5252

5353
it('should correctly populate defined properties', () => {
54+
function transformFn() {}
55+
5456
@Component({
5557
selector: 'test[foo], bar',
5658
standalone: true,
@@ -65,6 +67,8 @@ describe('ComponentFactory', () => {
6567

6668
@Input('input-attr-2') in2: unknown;
6769

70+
@Input({alias: 'input-attr-3', transform: transformFn}) in3: unknown;
71+
6872
@Output() out1: unknown;
6973

7074
@Output('output-attr-2') out2: unknown;
@@ -79,6 +83,7 @@ describe('ComponentFactory', () => {
7983
expect(cf.inputs).toEqual([
8084
{propName: 'in1', templateName: 'in1'},
8185
{propName: 'in2', templateName: 'input-attr-2'},
86+
{propName: 'in3', templateName: 'input-attr-3', transform: transformFn},
8287
]);
8388
expect(cf.outputs).toEqual([
8489
{propName: 'out1', templateName: 'out1'},

0 commit comments

Comments
 (0)