Skip to content

Commit

Permalink
refactor: refactor Switch components. #50
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Mar 22, 2024
1 parent 976b4c1 commit e750f70
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 95 deletions.
4 changes: 2 additions & 2 deletions core/src/If.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ReactElement } from 'react';
import { FC, PropsWithChildren } from 'react';
import type { ReactElement } from 'react';
import type { FC, PropsWithChildren } from 'react';

export interface IfProps {
readonly condition?: boolean;
Expand Down
30 changes: 0 additions & 30 deletions core/src/case.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { PropsWithChildren } from 'react';
import React, { type PropsWithChildren } from 'react';
import { If } from './If';

export * from './If';
Expand Down
37 changes: 0 additions & 37 deletions core/src/switch.store.tsx

This file was deleted.

56 changes: 35 additions & 21 deletions core/src/switch.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
import { type FC, type PropsWithChildren } from 'react';
import { DispatchSwitch, Context, useSwitch, useSwitchStore } from './switch.store';

export * from './case';
import type { FC, PropsWithChildren } from 'react';

type Child = typeof Case | typeof Default;
export const Switch: FC<PropsWithChildren<{}>> = ({ children }) => {
const [state, dispatch] = useSwitch();
return (
<Context.Provider value={state}>
<DispatchSwitch.Provider value={dispatch}>{children}</DispatchSwitch.Provider>
<Render />
</Context.Provider>
);
};
let matchChild: Child | null = null;
let defaultCase: typeof Default | null = null;

const Render = () => {
const state = useSwitchStore();
let activeKey;
for (var key in state.active) {
if (state.active[key] === true) {
activeKey = key;
break;
const childs = Array.isArray(children) ? children : [children];
childs.some((child) => {
if (!defaultCase && child && child.type === Default) {
defaultCase = child;
}
}
return state[activeKey ?? 'default'] ?? null;
if (child && child.type === Case) {
const { condition } = child.props;
const conditionIsTrue = Boolean(condition);
if (conditionIsTrue) {
matchChild = child;
return true;
}
}
return false;
});
return <>{matchChild ?? defaultCase ?? null}</>;
};

type TagType = React.ElementType | keyof JSX.IntrinsicElements;
interface CaseElementProps<T extends TagType> {
as?: T;
readonly condition?: boolean;
}

export type CaseProps<T extends TagType> = CaseElementProps<T> & React.ComponentPropsWithoutRef<T>;

export const Case = <T extends TagType>(props: CaseProps<T>) => {
const { children, condition, as: Comp, ...reset } = props;
const Elm = Comp as TagType;
return Elm ? <Elm {...reset}>{children}</Elm> : children;
};

export const Default = <T extends TagType>(props: CaseProps<T>) => <Case {...props} />;
11 changes: 7 additions & 4 deletions core/switch.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
declare module '@uiw/react-only-when/switch' {
import { FC, PropsWithChildren } from 'react';
export const Switch: FC<PropsWithChildren<{}>>;
export interface CaseProps {
export declare const Switch: <T extends TagType>({ children }: PropsWithChildren) => null;
type TagType = React.ElementType | keyof JSX.IntrinsicElements;
interface CaseElementProps<T extends TagType> {
as?: T;
readonly condition?: boolean;
}
export const Case: FC<PropsWithChildren<CaseProps>>;
export const Default: FC<PropsWithChildren>;
export type CaseProps<T extends TagType> = CaseElementProps<T> & React.ComponentPropsWithoutRef<T>;
export declare const Case: <T extends TagType>(props: CaseProps<T>) => any;
export declare const Default: <T extends TagType>(props: CaseProps<T>) => any;
}

0 comments on commit e750f70

Please sign in to comment.