Skip to content

Commit

Permalink
feat(repeat): add Repeat directive (#19)
Browse files Browse the repository at this point in the history
closes #14

This PR adds `Repeat` directive that extends `NgFor`. This directive allows consumers to iterate over a number of times instead of a list of items

```html
<!-- before -->
<p *ngFor="let i of [0, 1, 2]">{{ i }}</p>

<!-- after -->
<p *ngFor="let i; repeat 3">{{ i }}</p>
```
  • Loading branch information
nartc authored Sep 11, 2023
1 parent e1570a6 commit 1db2f48
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 1 deletion.
1 change: 1 addition & 0 deletions libs/ngxtension/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
],
"rules": {
"@angular-eslint/directive-class-suffix": 0,
"@angular-eslint/component-class-suffix": 0,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/ban-types": [
"error",
Expand Down
4 changes: 3 additions & 1 deletion libs/ngxtension/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
"libs/ngxtension/create-injection-token/**/*.ts",
"libs/ngxtension/create-injection-token/**/*.html",
"libs/ngxtension/assert-injector/**/*.ts",
"libs/ngxtension/assert-injector/**/*.html"
"libs/ngxtension/assert-injector/**/*.html",
"libs/ngxtension/repeat/**/*.ts",
"libs/ngxtension/repeat/**/*.html"
]
}
},
Expand Down
3 changes: 3 additions & 0 deletions libs/ngxtension/repeat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ngxtension/repeat

Secondary entry point of `ngxtension`. It can be used by importing from `ngxtension/repeat`.
5 changes: 5 additions & 0 deletions libs/ngxtension/repeat/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"lib": {
"entryFile": "src/index.ts"
}
}
1 change: 1 addition & 0 deletions libs/ngxtension/repeat/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './repeat';
26 changes: 26 additions & 0 deletions libs/ngxtension/repeat/src/repeat.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Component } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Repeat } from './repeat';

describe(Repeat.name, () => {
@Component({
standalone: true,
template: `
<p *ngFor="let i; repeat: 3">{{ i }}</p>
`,
imports: [Repeat],
})
class Dummy {}

it('given 3, when render, then render 3 items', () => {
const fixture = TestBed.createComponent(Dummy);
fixture.detectChanges();

const items = fixture.debugElement.queryAll(By.css('p'));
expect(items).toHaveLength(3);
items.forEach((item, i) => {
expect(item.nativeElement.textContent).toContain(i.toString());
});
});
});
18 changes: 18 additions & 0 deletions libs/ngxtension/repeat/src/repeat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NgFor } from '@angular/common';
import { Directive, Input } from '@angular/core';

@Directive({
standalone: true,
selector: '[ngFor][ngForRepeat]',
})
export class Repeat extends NgFor<number> {
@Input() set ngForRepeat(count: number) {
if (Number.isNaN(count) || !Number.isInteger(count)) {
throw new Error(
`[Repeat] repeat requires an integer but ${count} is passed in`
);
}
this.ngForOf = Array.from({ length: count }, (_, i) => i);
this.ngForTrackBy = (i) => i;
}
}
1 change: 1 addition & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"ngxtension/create-injection-token": [
"libs/ngxtension/create-injection-token/src/index.ts"
],
"ngxtension/repeat": ["libs/ngxtension/repeat/src/index.ts"],
"ngxtension/resize": ["libs/ngxtension/resize/src/index.ts"]
}
},
Expand Down

0 comments on commit 1db2f48

Please sign in to comment.