Skip to content

Commit

Permalink
feat(eslint-plugin-clarity-adoption): add datalist fixer
Browse files Browse the repository at this point in the history
Signed-off-by: Bogdan Bogdanov <bbogdanov@vmware.com>
  • Loading branch information
bbogdanov committed Nov 2, 2021
1 parent 629537a commit efeaf75
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
Expand Up @@ -97,7 +97,13 @@ export function getAttributeNameFixes(
return [fixer.replaceTextRange([start, end], newName)];
}

export function getTagFixes(fixer: RuleFixer, node: HTMLElement, oldTag: string, newTag: string): Array<RuleFix> {
export function getTagFixes(
fixer: RuleFixer,
node: HTMLElement,
oldTag: string,
newTag: string,
newAttributes: Array<string> = []
): Array<RuleFix> {
const openingTag = `<${oldTag}`;
const closingTag = `</${oldTag}>`;

Expand All @@ -109,7 +115,10 @@ export function getTagFixes(fixer: RuleFixer, node: HTMLElement, oldTag: string,
const closingTagEnd = closingTagStart + closingTag.length - 1;

return [
fixer.replaceTextRange([openingTagStart, openingTagEnd], `<${newTag}`),
fixer.replaceTextRange(
[openingTagStart, openingTagEnd],
newAttributes.length ? `<${newTag}` + ' ' + newAttributes?.join(' ') : `<${newTag}`
),
fixer.replaceTextRange([closingTagStart, closingTagEnd], `</${newTag}`),
];
}
Expand Down
@@ -1,6 +1,7 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils';
import { HTMLElement } from '../../types/index';
import { lintDecoratorTemplate } from '../decorator-template-helper';
import { getDeprecatedClassFixes, getTagFixes } from '../html-fixer-helpers';

export const createESLintRule = ESLintUtils.RuleCreator(() => ``);
export type MessageIds = 'clrDatalistFailure';
Expand All @@ -26,9 +27,19 @@ export default createESLintRule({
create(context) {
return {
[`HTMLElement[tagName="${disallowedTag}"]`](node: HTMLElement): void {
const classNode = node.attributes?.find(attribute => attribute.attributeName.value === 'class');

context.report({
node: node as any,
messageId: 'clrDatalistFailure',
fix: fixer => {
const tagFixes = getTagFixes(fixer, node, 'clr-datalist-container', 'cds-datalist', [
`control-width="shrink"`,
]);
const attributeFixes = getDeprecatedClassFixes(fixer, classNode, [] as any);

return [...tagFixes, ...attributeFixes];
},
});
},
'ClassDeclaration > Decorator'(node: TSESTree.Decorator): void {
Expand Down
Expand Up @@ -15,6 +15,27 @@ htmlRuleTester.run('no-clr-datalist', rule, {
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</clr-datalist-container>`,
output: `<cds-datalist control-width="shrink">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</cds-datalist>`,
locations: [{ line: 1, column: 1 }],
}),
getInvalidDatalistTest({
code: `<clr-datalist-container id="custom-id">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</clr-datalist-container>`,
output: `<cds-datalist control-width="shrink" id="custom-id">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</cds-datalist>`,
locations: [{ line: 1, column: 1 }],
}),
getInvalidDatalistTest({
Expand All @@ -27,6 +48,15 @@ htmlRuleTester.run('no-clr-datalist', rule, {
</datalist>
</clr-datalist-container>
`,
output: `
<div></div>
<cds-datalist control-width="shrink">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</cds-datalist>
`,
locations: [{ line: 3, column: 9 }],
}),
getInvalidDatalistTest({
Expand All @@ -40,8 +70,33 @@ htmlRuleTester.run('no-clr-datalist', rule, {
</clr-datalist-container>
</div>
`,
output: `
<div>
<cds-datalist control-width="shrink">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</cds-datalist>
</div>
`,
locations: [{ line: 3, column: 11 }],
}),
getInvalidDatalistTest({
code: `<clr-datalist-container id="custom-id" class="custom-class">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</clr-datalist-container>`,
output: `<cds-datalist control-width="shrink" id="custom-id" class="custom-class">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</cds-datalist>`,
locations: [{ line: 1, column: 1 }],
}),
getInvalidDatalistTest({
code: `
<div>
Expand All @@ -54,6 +109,17 @@ htmlRuleTester.run('no-clr-datalist', rule, {
</div>
<clr-datalist-container></clr-datalist-container>
`,
output: `
<div>
<cds-datalist control-width="shrink">
<input clrDatalistInput [(ngModel)]="vertical" placeholder="No label" name="Option" />
<datalist>
<option *ngFor="let item of items" [value]="item"></option>
</datalist>
</cds-datalist>
</div>
<cds-datalist control-width="shrink"></cds-datalist>
`,
locations: [
{ line: 3, column: 11 },
{ line: 10, column: 9 },
Expand Down

0 comments on commit efeaf75

Please sign in to comment.