diff --git a/packages/eslint-plugin/src/rules/no-input-rename.ts b/packages/eslint-plugin/src/rules/no-input-rename.ts index aa81e9a55..9431af5a5 100644 --- a/packages/eslint-plugin/src/rules/no-input-rename.ts +++ b/packages/eslint-plugin/src/rules/no-input-rename.ts @@ -139,6 +139,28 @@ export default createESLintRule({ [Selectors.INPUTS_METADATA_PROPERTY_LITERAL]( node: TSESTree.Literal | TSESTree.TemplateElement, ) { + const ancestorMaybeHostDirectiveAPI = + node.parent?.parent?.parent?.parent?.parent; + if ( + ancestorMaybeHostDirectiveAPI && + ASTUtils.isProperty(ancestorMaybeHostDirectiveAPI) + ) { + /** + * Angular v15 introduced the directive composition API: https://angular.io/guide/directive-composition-api + * Renaming host directive inputs using this API is not a bad practice and should not be reported + */ + const hostDirectiveAPIPropertyName = 'hostDirectives'; + if ( + (ASTUtils.isLiteral(ancestorMaybeHostDirectiveAPI.key) && + ancestorMaybeHostDirectiveAPI.key.value === + hostDirectiveAPIPropertyName) || + (TSESLintASTUtils.isIdentifier(ancestorMaybeHostDirectiveAPI.key) && + ancestorMaybeHostDirectiveAPI.key.name === + hostDirectiveAPIPropertyName) + ) { + return; + } + } const [propertyName, aliasName] = withoutBracketsAndWhitespaces( ASTUtils.getRawText(node), ).split(':'); diff --git a/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts b/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts index 9cfbd6e53..05ac84021 100644 --- a/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts +++ b/packages/eslint-plugin/tests/rules/no-input-rename/cases.ts @@ -50,6 +50,41 @@ export const valid = [ }) class Test {} `, + /** + * Renaming inputs when using the directive composition API is not a bad practice + * https://angular.io/guide/directive-composition-api + * https://www.youtube.com/watch?v=EJJwyyjsRGs + */ + ` + @Component({ + selector: 'qx-menuitem', + hostDirectives: [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] + }) + class Test {} + `, + ` + @Component({ + selector: 'qx-menuitem', + 'hostDirectives': [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] + }) + class Test {} + `, + ` + @Component({ + selector: 'qx-menuitem', + ['hostDirectives']: [{ + directive: CdkMenuItem, + inputs: ['cdkMenuItemDisabled: disabled'], + }] + }) + class Test {} + `, ` @Component({}) class Test {