Skip to content

Commit

Permalink
feat(#100): SwitchCase 컴포넌트 추가 (#101)
Browse files Browse the repository at this point in the history
* feat(#100): SwitchCase 컴포넌트 추가

* feat(#100): try catch 문 제거

* feat(#100): change props name defaultCase into defaultCaseComponent

* test(#100): update test case

* feat(#100): add fallback props to When component
  • Loading branch information
soonki-98 authored May 5, 2024
1 parent b3318a6 commit 61d6df3
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 2 deletions.
56 changes: 56 additions & 0 deletions packages/react/src/components/SwitchCase/SwitchCase.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { screen } from '@testing-library/react';

import { renderSetup } from '../../utils/test/renderSetup';

import { SwitchCase } from '.';

describe('SwitchCase', () => {
it('should SwitchCase component receive condition.', () => {
renderSetup(
<SwitchCase
condition={0 as number}
cases={{ 0: <button>case no.1</button> }}
/>
);
const CaseOneComponent = screen.queryByRole('button', {
name: 'case no.1',
});

expect(CaseOneComponent).toBeInTheDocument();
});

it('should render defaultCaseComponent when there is no matched condition.', () => {
renderSetup(
<SwitchCase
condition={0 as number}
cases={{ 1: <button>case no.1</button> }}
defaultCaseComponent={<button>default component</button>}
/>
);

const CaseOneComponent = screen.queryByRole('button', {
name: 'case no.1',
});
const DefaultCaseComponent = screen.queryByRole('button', {
name: 'default component',
});

expect(CaseOneComponent).not.toBeInTheDocument();
expect(DefaultCaseComponent).toBeInTheDocument();
});

it('should render defaultCaseComponent when condition is nullable.', () => {
renderSetup(
<SwitchCase
condition={null}
cases={{}}
defaultCaseComponent={<button>default component</button>}
/>
);

const DefaultCaseComponent = screen.queryByRole('button', {
name: 'default component',
});
expect(DefaultCaseComponent).toBeInTheDocument();
});
});
21 changes: 21 additions & 0 deletions packages/react/src/components/SwitchCase/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Nullable } from '@modern-kit/types';

type Component = Nullable<React.ReactNode>;

interface SwitchCaseProps<Condition extends string | number> {
condition: Condition | null | undefined;
cases: Partial<Record<Condition, Component>>;
defaultCaseComponent?: Component;
}

export const SwitchCase = <Condition extends string | number>({
condition,
cases,
defaultCaseComponent = null,
}: SwitchCaseProps<Condition>) => {
if (condition == null) {
return defaultCaseComponent;
}

return cases[condition] ?? defaultCaseComponent;
};
15 changes: 15 additions & 0 deletions packages/react/src/components/When/When.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,19 @@ describe('When Component', () => {

expect(header).not.toBeInTheDocument();
});

it('should render fallback when condition is false and has fallback props', () => {
render(
<When condition={false} fallback={<p role="paragraph">false</p>}>
<button>true</button>
</When>
);

const button = screen.queryByRole('button');

const fallbackParagraph = screen.queryByRole('paragraph');

expect(button).not.toBeInTheDocument();
expect(fallbackParagraph).toBeInTheDocument();
});
});
9 changes: 7 additions & 2 deletions packages/react/src/components/When/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ type Condition = boolean | ((...args: any[]) => boolean);

interface WhenProps {
condition: Condition;
fallback?: React.ReactNode;
}

const getConditionResult = (condition: Condition) => {
return typeof condition === 'function' ? condition() : condition;
};

export const When = ({ children, condition }: PropsWithChildren<WhenProps>) => {
export const When = ({
children,
condition,
fallback,
}: PropsWithChildren<WhenProps>) => {
const conditionResult = getConditionResult(condition);

if (!conditionResult) return null;
if (!conditionResult) return <React.Fragment>{fallback}</React.Fragment>;
return <React.Fragment>{children}</React.Fragment>;
};
1 change: 1 addition & 0 deletions packages/react/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './InView';
export * from './LazyImage';
export * from './Portal';
export * from './When';
export * from './SwitchCase';

0 comments on commit 61d6df3

Please sign in to comment.