Skip to content

Commit e750f70

Browse files
committed
refactor: refactor Switch components. #50
1 parent 976b4c1 commit e750f70

File tree

6 files changed

+45
-95
lines changed

6 files changed

+45
-95
lines changed

core/src/If.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ReactElement } from 'react';
2-
import { FC, PropsWithChildren } from 'react';
1+
import type { ReactElement } from 'react';
2+
import type { FC, PropsWithChildren } from 'react';
33

44
export interface IfProps {
55
readonly condition?: boolean;

core/src/case.tsx

Lines changed: 0 additions & 30 deletions
This file was deleted.

core/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { PropsWithChildren } from 'react';
1+
import React, { type PropsWithChildren } from 'react';
22
import { If } from './If';
33

44
export * from './If';

core/src/switch.store.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

core/src/switch.tsx

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
1-
import { type FC, type PropsWithChildren } from 'react';
2-
import { DispatchSwitch, Context, useSwitch, useSwitchStore } from './switch.store';
3-
4-
export * from './case';
1+
import type { FC, PropsWithChildren } from 'react';
52

3+
type Child = typeof Case | typeof Default;
64
export const Switch: FC<PropsWithChildren<{}>> = ({ children }) => {
7-
const [state, dispatch] = useSwitch();
8-
return (
9-
<Context.Provider value={state}>
10-
<DispatchSwitch.Provider value={dispatch}>{children}</DispatchSwitch.Provider>
11-
<Render />
12-
</Context.Provider>
13-
);
14-
};
5+
let matchChild: Child | null = null;
6+
let defaultCase: typeof Default | null = null;
157

16-
const Render = () => {
17-
const state = useSwitchStore();
18-
let activeKey;
19-
for (var key in state.active) {
20-
if (state.active[key] === true) {
21-
activeKey = key;
22-
break;
8+
const childs = Array.isArray(children) ? children : [children];
9+
childs.some((child) => {
10+
if (!defaultCase && child && child.type === Default) {
11+
defaultCase = child;
2312
}
24-
}
25-
return state[activeKey ?? 'default'] ?? null;
13+
if (child && child.type === Case) {
14+
const { condition } = child.props;
15+
const conditionIsTrue = Boolean(condition);
16+
if (conditionIsTrue) {
17+
matchChild = child;
18+
return true;
19+
}
20+
}
21+
return false;
22+
});
23+
return <>{matchChild ?? defaultCase ?? null}</>;
24+
};
25+
26+
type TagType = React.ElementType | keyof JSX.IntrinsicElements;
27+
interface CaseElementProps<T extends TagType> {
28+
as?: T;
29+
readonly condition?: boolean;
30+
}
31+
32+
export type CaseProps<T extends TagType> = CaseElementProps<T> & React.ComponentPropsWithoutRef<T>;
33+
34+
export const Case = <T extends TagType>(props: CaseProps<T>) => {
35+
const { children, condition, as: Comp, ...reset } = props;
36+
const Elm = Comp as TagType;
37+
return Elm ? <Elm {...reset}>{children}</Elm> : children;
2638
};
39+
40+
export const Default = <T extends TagType>(props: CaseProps<T>) => <Case {...props} />;

core/switch.d.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
declare module '@uiw/react-only-when/switch' {
22
import { FC, PropsWithChildren } from 'react';
3-
export const Switch: FC<PropsWithChildren<{}>>;
4-
export interface CaseProps {
3+
export declare const Switch: <T extends TagType>({ children }: PropsWithChildren) => null;
4+
type TagType = React.ElementType | keyof JSX.IntrinsicElements;
5+
interface CaseElementProps<T extends TagType> {
6+
as?: T;
57
readonly condition?: boolean;
68
}
7-
export const Case: FC<PropsWithChildren<CaseProps>>;
8-
export const Default: FC<PropsWithChildren>;
9+
export type CaseProps<T extends TagType> = CaseElementProps<T> & React.ComponentPropsWithoutRef<T>;
10+
export declare const Case: <T extends TagType>(props: CaseProps<T>) => any;
11+
export declare const Default: <T extends TagType>(props: CaseProps<T>) => any;
912
}

0 commit comments

Comments
 (0)