Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions goldens/public-api/core/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1029,8 +1029,8 @@ export interface InputFunction {
<T>(initialValue: undefined, opts: InputOptionsWithoutTransform<T>): InputSignal<T | undefined>;
<T, TransformT>(initialValue: T, opts: InputOptionsWithTransform<T, TransformT>): InputSignalWithTransform<T, TransformT>;
<T, TransformT>(initialValue: undefined, opts: InputOptionsWithTransform<T | undefined, TransformT>): InputSignalWithTransform<T | undefined, TransformT>;
<T>(initialValue: T, opts: InputOptionsWithTransform<T, unknown>): InputSignalWithTransform<T, T>;
<T>(initialValue: undefined, opts: InputOptionsWithTransform<T | undefined, unknown>): InputSignalWithTransform<T | undefined, T | undefined>;
<T>(initialValue: T, opts: InputOptionsWithTransform<T, unknown>): InputSignalWithTransform<T, T | string>;
<T>(initialValue: undefined, opts: InputOptionsWithTransform<T | undefined, unknown>): InputSignalWithTransform<T | undefined, T | undefined | string>;
required: {
<T>(opts?: InputOptionsWithoutTransform<T>): InputSignal<T>;
<T, TransformT>(opts: InputOptionsWithTransform<T, TransformT>): InputSignalWithTransform<T, TransformT>;
Expand Down
60 changes: 60 additions & 0 deletions packages/compiler-cli/test/ngtsc/authoring_inputs_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,66 @@ runInEachFileSystem(() => {
);
});

it('should allow text attributes for explicit signal inputs with booleanAttribute transform', () => {
env.write(
'test.ts',
`
import {booleanAttribute, Component, Directive, input} from '@angular/core';

@Directive({
selector: '[directiveName]',
})
export class TestDir {
dismissible = input<boolean>(true, {transform: booleanAttribute});
}

@Component({
template: \`
<div directiveName [dismissible]="true"></div>
<div directiveName dismissible="true"></div>
<div directiveName dismissible></div>
\`,
imports: [TestDir],
})
export class TestComp {
}
`,
);

const diagnostics = env.driveDiagnostics();
expect(diagnostics).toEqual([]);
});

it('should allow text attributes for explicit signal inputs with numberAttribute transform', () => {
env.write(
'test.ts',
`
import {Component, Directive, input, numberAttribute} from '@angular/core';

@Directive({
selector: '[directiveName]',
})
export class TestDir {
count = input<number>(0, {transform: numberAttribute});
}

@Component({
template: \`
<div directiveName [count]="1"></div>
<div directiveName count="1"></div>
<div directiveName count=""></div>
\`,
imports: [TestDir],
})
export class TestComp {
}
`,
);

const diagnostics = env.driveDiagnostics();
expect(diagnostics).toEqual([]);
});

it('should report unset required inputs', () => {
env.write(
'test.ts',
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/authoring/input/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,20 @@ export interface InputFunction {
): InputSignalWithTransform<T | undefined, TransformT>;
/**
* Declares an input of type `T` with an initial value and a transform function
* that accepts values of the same type.
* that accepts values of the same type, or string values from static attributes.
*/
<T>(initialValue: T, opts: InputOptionsWithTransform<T, unknown>): InputSignalWithTransform<T, T>;
<T>(
initialValue: T,
opts: InputOptionsWithTransform<T, unknown>,
): InputSignalWithTransform<T, T | string>;
/**
* Declares an input of type `T|undefined` without an initial value and with a transform
* function that accepts values of the same type.
* function that accepts values of the same type, or string values from static attributes.
*/
<T>(
initialValue: undefined,
opts: InputOptionsWithTransform<T | undefined, unknown>,
): InputSignalWithTransform<T | undefined, T | undefined>;
): InputSignalWithTransform<T | undefined, T | undefined | string>;

/**
* Initializes a required input.
Expand Down
8 changes: 4 additions & 4 deletions packages/core/test/authoring/signal_input_signature_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ export class InputSignatureTest {
transform: (v: string | boolean) => '',
});

/** boolean, boolean */
/** boolean, string | boolean */
explicitReadWithBooleanAttributeTransform = input<boolean>(false, {transform: booleanAttribute});
/** number, number */
/** number, string | number */
explicitReadWithNumberAttributeTransform = input<number>(0, {transform: numberAttribute});
/** boolean | undefined, boolean | undefined */
/** boolean | undefined, string | boolean | undefined */
explicitReadWithUndefinedInitialBooleanAttributeTransform = input<boolean>(undefined, {
transform: booleanAttribute,
});
/** number | undefined, number | undefined */
/** number | undefined, string | number | undefined */
explicitReadWithUndefinedInitialNumberAttributeTransform = input<number>(undefined, {
transform: numberAttribute,
});
Expand Down
Loading