Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(@toss/react): enhance Separated component #508

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions packages/react/react/src/components/Separated/Separated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ import { Children, Fragment, isValidElement, PropsWithChildren, ReactNode } from

interface Props extends PropsWithChildren {
with: ReactNode;
first?: boolean;
last?: boolean;
}

export function Separated({ children, with: separator }: Props) {
const childrenArray = Children.toArray(children).filter(isValidElement);
export function Separated({ children, with: separator, first = false, last = false }: Props) {
const childrenArray = Children.toArray(children);
const childrenLength = childrenArray.length;

return (
<>
{childrenArray.map((child, i) => (
<Fragment key={i}>
{first && separator}
{childrenArray.map((child, index) => (
<Fragment key={isValidElement(child) ? child.key : index}>
{child}
{i + 1 !== childrenLength ? separator : null}
{index + 1 !== childrenLength && separator}
</Fragment>
))}
{last && separator}
</>
);
}
16 changes: 15 additions & 1 deletion packages/react/react/src/components/Separated/Seperated.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,21 @@ title: Separated

# Separated

Used when
A convenient component used to insert a repeating component between each element.

```tsx
<Separated
with={separator}
// Adds a separator before the first element
first={true}
// Adds a separator after the last element
last={true}
>
{children}
</Separated>
```

## Example

```tsx
<Separated with={<Border type="padding24" />}>
Expand Down
14 changes: 14 additions & 0 deletions packages/react/react/src/components/Separated/Seperated.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ title: Separated

각 요소 사이에 반복되는 컴포넌트를 삽입하고자 할 때 사용할 수 있는 편리한 컴포넌트입니다.

```tsx
<Separated
with={separator}
// 첫 번째 요소 앞에 separator를 추가합니다.
first={true}
// 마지막 요소 뒤에 separator를 추가합니다.
last={true}
>
{children}
</Separated>
```

## Example

```tsx
<Separated with={<Border type="padding24" />}>
{LIST.map(item => (
Expand Down
54 changes: 54 additions & 0 deletions packages/react/react/src/components/Separated/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,58 @@ describe('Separated', () => {

expect(screen.queryByTestId(/separator/)).not.toBeInTheDocument();
});

it('should render separator at the beginning when first prop is true', () => {
const CHILDREN_COUNT = 10;
const separator = <span data-testid="separator" />;
const children = Array.from({ length: CHILDREN_COUNT }, (_, i) => (
<div key={i} data-testid={i}>
container_{i}
</div>
));

const { container } = render(
<Separated with={separator} first>
{children}
</Separated>
);

expect(container.firstChild).toHaveAttribute('data-testid', 'separator');
expect(screen.getAllByText(/container/)).toHaveLength(CHILDREN_COUNT);
expect(screen.getAllByTestId(/separator/)).toHaveLength(CHILDREN_COUNT);
});

it('should render separator at the end when last prop is true', () => {
const CHILDREN_COUNT = 10;
const separator = <span data-testid="separator" />;
const children = Array.from({ length: CHILDREN_COUNT }, (_, i) => (
<div key={i} data-testid={i}>
container_{i}
</div>
));

const { container } = render(
<Separated with={separator} last>
{children}
</Separated>
);

expect(container.lastChild).toHaveAttribute('data-testid', 'separator');
expect(screen.getAllByText(/container/)).toHaveLength(CHILDREN_COUNT);
expect(screen.getAllByTestId(/separator/)).toHaveLength(CHILDREN_COUNT);
});

it('should render all ReactNode types', () => {
const separator = <span data-testid="separator" />;

render(
<Separated with={separator}>
string
{0}
string
</Separated>
);

expect(screen.getAllByTestId(/separator/)).toHaveLength(2);
});
});