Skip to content

Commit d727403

Browse files
feat: introduce repeat component
1 parent f017c93 commit d727403

5 files changed

Lines changed: 131 additions & 0 deletions

File tree

.changeset/fuzzy-berries-taste.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'classic-react-components': minor
3+
---
4+
5+
## Features
6+
7+
### Repeat component
8+
```tsx
9+
<Repeat times={3}>
10+
<div>this is content</div>
11+
</Repeat>
12+
```

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ $ yarn add classic-react-components
6262
- [Then](#then)
6363
- [Else](#else)
6464
- [For](#for)
65+
- [Repeat](#repeat)
6566
- [Switch](#switch)
6667

68+
6769
## If
6870

6971
| Prop | Type | Required | Default Value | Description |
@@ -286,6 +288,59 @@ export default function YourComponent() {
286288
```
287289

288290

291+
## Repeat
292+
293+
| Prop | Type | Required | Default Value | Description |
294+
| -------- | :-------: | :------: | :-----------: | ---------------------------------------------- |
295+
| times | number || 0 | Times to repeat the children |
296+
| children | JSX.Element \| (()=> JSX.Element) || undefined | children needed to repeat |
297+
298+
### Working
299+
300+
- Used for rendering template or loaders in repeated manner without writing `new Array(length).map()` code.
301+
- Just pass `times` and `children` props, and children will be renderd `n times` automatically.
302+
303+
304+
305+
### Examples
306+
307+
#### 1. Passing children as default JSX
308+
```tsx
309+
import { Repeat } from 'classic-react-components'
310+
311+
export default function YourComponent() {
312+
313+
return (
314+
<div>
315+
<Repeat times={1}>
316+
<div>this is going to repeated</div>
317+
</Repeat>
318+
</div>
319+
)
320+
}
321+
```
322+
323+
#### 2. Passing children as function which renders jsx (used to dynamically injecting things in jsx).
324+
```tsx
325+
import { Repeat } from 'classic-react-components'
326+
327+
export default function YourComponent() {
328+
const someState = "this is text"
329+
return (
330+
<div>
331+
<Repeat times={3}>
332+
{(idx) => {
333+
return (
334+
<div>this is content-{idx}- {someState}</div>
335+
)
336+
}}
337+
</Repeat>
338+
</div>
339+
)
340+
}
341+
```
342+
343+
289344
## Switch
290345

291346
| Prop | Type | Required | Default Value | Description |

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export { default as Else } from './lib/components/Else/Else'
44
export { default as Then } from './lib/components/Then/Then'
55
export { default as For } from './lib/components/For/For'
66
export { default as Switch } from './lib/components/Switch/Switch'
7+
export { default as Repeat } from './lib/components/Repeat/Repeat'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { render, screen } from '@testing-library/react'
2+
import Repeat from './Repeat'
3+
4+
describe('Repeat.tsx', () => {
5+
it('should render without any errors or crash', () => {
6+
render(
7+
<Repeat times={1}>
8+
<div>this is going to repeated</div>
9+
</Repeat>
10+
)
11+
})
12+
13+
it('should render nothing without any errors if <times> prop is not provided', () => {
14+
render(
15+
<Repeat>
16+
<div data-testid='children'>this is content</div>
17+
</Repeat>
18+
)
19+
expect(screen.queryByTestId('children')).not.toBeInTheDocument()
20+
})
21+
22+
it('should render children repeated n times', () => {
23+
render(
24+
<Repeat times={3}>
25+
<div data-testid='children'>this is content</div>
26+
</Repeat>
27+
)
28+
expect(screen.queryAllByTestId('children').length).toBe(3)
29+
})
30+
31+
it('should render children of function type repeated n times', () => {
32+
render(<Repeat times={3}>{(idx) => <div data-testid={`children-${idx}`}>this is content-{idx}</div>}</Repeat>)
33+
expect(screen.queryAllByTestId(/^children-(.*)$/).length).toBe(3)
34+
expect(screen.queryByTestId('children-0')).toBeInTheDocument()
35+
expect(screen.queryByTestId('children-1')).toBeInTheDocument()
36+
expect(screen.queryByTestId('children-2')).toBeInTheDocument()
37+
})
38+
})
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Fragment } from 'react'
2+
3+
export default function Repeat({
4+
times = 0,
5+
children,
6+
}: {
7+
times?: number
8+
children?: JSX.Element | ((idx: number) => JSX.Element)
9+
}): JSX.Element {
10+
if (times == 0) {
11+
return <></>
12+
}
13+
14+
const childArr = new Array(times)
15+
16+
for (let i = 0; i < times; i++) {
17+
if (typeof children == 'function') {
18+
childArr.push(<Fragment key={i}>{children(i)}</Fragment>)
19+
} else {
20+
childArr.push(children)
21+
}
22+
}
23+
24+
return <>{childArr}</>
25+
}

0 commit comments

Comments
 (0)