Skip to content

Commit

Permalink
feat(cdk): add TuiRepeatTimes pipe
Browse files Browse the repository at this point in the history
  • Loading branch information
splincode committed Sep 29, 2024
1 parent 8cce7ee commit 30647d2
Show file tree
Hide file tree
Showing 15 changed files with 163 additions and 0 deletions.
1 change: 1 addition & 0 deletions projects/cdk/pipes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from '@taiga-ui/cdk/pipes/filter';
export * from '@taiga-ui/cdk/pipes/is-present';
export * from '@taiga-ui/cdk/pipes/keys';
export * from '@taiga-ui/cdk/pipes/mapper';
export * from '@taiga-ui/cdk/pipes/repeat-times';
export * from '@taiga-ui/cdk/pipes/replace';
export * from '@taiga-ui/cdk/pipes/to-array';
14 changes: 14 additions & 0 deletions projects/cdk/pipes/repeat-times/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {Pipe, type PipeTransform} from '@angular/core';
import type {TuiIterationRange} from '@taiga-ui/cdk/types';

type Range<From extends number, To extends number> = TuiIterationRange<From, To, 1>;

@Pipe({
standalone: true,
name: 'tuiRepeatTimes',
})
export class TuiRepeatTimesPipe implements PipeTransform {
public transform<N extends number>(length: N): Range<1, N> {
return Array.from({length}, (_, i) => ++i) as unknown as Range<1, N>;
}
}
5 changes: 5 additions & 0 deletions projects/cdk/pipes/repeat-times/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"lib": {
"entryFile": "index.ts"
}
}
21 changes: 21 additions & 0 deletions projects/cdk/pipes/repeat-times/test/repeat-times.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {TuiRepeatTimesPipe} from '@taiga-ui/cdk';

describe('TuiRepeatTimes pipe', () => {
const pipe = new TuiRepeatTimesPipe();

it('repeat works', () => {
const arr = pipe.transform(5);

expect(arr).toEqual([1, 2, 3, 4, 5]);

expect(pipe.transform(0)).toEqual([]);
expect(pipe.transform(1)).toEqual([1]);
expect(pipe.transform(2)).toEqual([1, 2]);
expect(pipe.transform(3)).toEqual([1, 2, 3]);
});

it('repeat pipe should not compile and cannot be less than minimum value', () => {
// @ts-expect-error
expect(pipe.transform(-1)).toEqual([]);
});
});
1 change: 1 addition & 0 deletions projects/cdk/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './handler';
export * from './loose-union';
export * from './mapper';
export * from './matcher';
export * from './range';
export * from './rounding';
export * from './safe-html';
export * from './values-of';
44 changes: 44 additions & 0 deletions projects/cdk/types/range.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
type ComputeRange<
N extends number,
Result extends unknown[] = [],
> = Result['length'] extends N ? Result : ComputeRange<N, [...Result, Result['length']]>;

type Add<A extends number, B extends number> = [
...ComputeRange<A>,
...ComputeRange<B>,
]['length'];

type IsGreater<A extends number, B extends number> =
IsLiteralNumber<[...ComputeRange<B>][Last<[...ComputeRange<A>]>]> extends true
? false
: true;

type Last<T extends any[]> = T extends [
// eslint-disable-next-line @typescript-eslint/no-unused-vars
...infer _never,
infer Last,
]
? Last extends number
? Last
: never
: never;

type RemoveLast<T extends any[]> = T extends [
...infer Rest,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
infer _never,
]
? Rest
: never;

type IsLiteralNumber<N> = N extends number ? (number extends N ? false : true) : false;

export type TuiIterationRange<
Min extends number,
Max extends number,
ScaleBy extends number,
Result extends unknown[] = [Min],
> =
IsGreater<Last<Result>, Max> extends true
? RemoveLast<Result>
: TuiIterationRange<Min, Max, ScaleBy, [...Result, Add<Last<Result>, ScaleBy>]>;
5 changes: 5 additions & 0 deletions projects/demo/src/modules/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,11 @@ export const ROUTES: Routes = [
loadComponent: async () => import('../pipes/mapper'),
title: 'Mapper',
}),
route({
path: DemoRoute.RepeatTimes,
loadComponent: async () => import('../pipes/repeat-times'),
title: 'RepeatTimes',
}),
route({
path: DemoRoute.Stringify,
loadComponent: async () => import('../pipes/stringify'),
Expand Down
1 change: 1 addition & 0 deletions projects/demo/src/modules/app/demo-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export const DemoRoute = {
FormatNumber: '/pipes/format-number',
IsPresent: '/pipes/is-present',
Mapper: '/pipes/mapper',
RepeatTimes: '/pipes/repeat-times',
Stringify: '/pipes/stringify',
StringifyContent: '/pipes/stringify-content',
Alert: '/components/alert',
Expand Down
6 changes: 6 additions & 0 deletions projects/demo/src/modules/app/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,12 @@ export const pages: TuiDocRoutePages = [
keywords: 'mapper, мап, преобразование, пайп, pipe',
route: DemoRoute.Mapper,
},
{
section: 'Tools',
title: 'RepeatTimes',
keywords: 'повторение, repeat, пайп, pipe',
route: DemoRoute.RepeatTimes,
},
{
section: 'Tools',
title: 'FieldError',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ng-container *ngFor="let item of 5 | tuiRepeatTimes">
{{ item }}
</ng-container>
14 changes: 14 additions & 0 deletions projects/demo/src/modules/pipes/repeat-times/examples/1/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {NgForOf} from '@angular/common';
import {Component} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';
import {TuiRepeatTimesPipe} from '@taiga-ui/cdk';

@Component({
standalone: true,
imports: [NgForOf, TuiRepeatTimesPipe],
templateUrl: './index.html',
encapsulation,
changeDetection,
})
export default class Example {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```ts
import {TuiRepeatTimesPipe} from '@taiga-ui/cdk';

//...

@Component({
standalone: true,
imports: [
// ...
TuiRepeatTimesPipe,
],
// ...
})
export class Example {}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
```html
@for (item of 3 | tuiRepeatTimes; track item) {
<div class="t-cell"></div>
}
```
17 changes: 17 additions & 0 deletions projects/demo/src/modules/pipes/repeat-times/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<tui-doc-page
header="RepeatTimes"
package="CDK"
type="pipes"
>
<ng-template pageTab>
<tui-doc-example
id="base"
description="Pipe for making an array of elements by length"
heading="Base"
[component]="1 | tuiComponent"
[content]="1 | tuiExample"
/>
</ng-template>

<tui-setup *pageTab="'Setup'" />
</tui-doc-page>
11 changes: 11 additions & 0 deletions projects/demo/src/modules/pipes/repeat-times/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {Component} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {TuiDemo} from '@demo/utils';

@Component({
standalone: true,
imports: [TuiDemo],
templateUrl: './index.html',
changeDetection,
})
export default class Page {}

0 comments on commit 30647d2

Please sign in to comment.