Skip to content

Commit

Permalink
fix: fixed the code to work with React 18
Browse files Browse the repository at this point in the history
  • Loading branch information
favna committed Apr 15, 2022
1 parent 357124c commit 4d504e1
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/Default.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { FC } from 'react';
import { render } from './render';
import type { FCWithImplicitChildren } from './types';

/**
* If no `<Case />` have its condition evaluates to true inside the parent `<Switch />`,
* the first `<Default />` will be the only one rendered.
* @param props The props to pass down to the `<Default />` component
*/
export const Default: FC = (props) => render(props);
export const Default: FCWithImplicitChildren = (props) => render(props);

Default.defaultProps = {
children: null
Expand Down
4 changes: 2 additions & 2 deletions src/Else.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { FC } from 'react';
import { render } from './render';
import type { FCWithImplicitChildren } from './types';

/**
* Must only contain a single child, which it renders as-is.
* Should not be used outside of an `<If />` block.
* @param props The props to pass down to the `<Else />` component
*/
export const Else: FC = (props) => render(props);
export const Else: FCWithImplicitChildren = (props) => render(props);
4 changes: 2 additions & 2 deletions src/Fallback.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { FC } from 'react';
import { render } from './render';
import type { FCWithImplicitChildren } from './types';

/**
* Must contain only a single child, which it renders as-is.
* Should not be used outside of an `<If />` block whose condition prop is a promise.
* @param props The props to pass down to the `<Fallback />` component
*/
export const Fallback: FC = (props) => render(props);
export const Fallback: FCWithImplicitChildren = (props) => render(props);
5 changes: 3 additions & 2 deletions src/Switch.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React, { FC, ReactElement } from 'react';
import React, { ReactElement } from 'react';
import { Case } from './Case';
import { Default } from './Default';
import { getConditionResult } from './getConditionResults';
import type { FCWithImplicitChildren } from './types';

/**
* It will render the first matching `<Case />`, or the first encountered `<Default />` (or `null`).
*
* This component can contain any number of `<Case />` and one `<Default />` blocks
* @param __namedParameters Children to pass into the `<Switch />` component
*/
export const Switch: FC = ({ children }) => {
export const Switch: FCWithImplicitChildren = ({ children }) => {
// -- Inspired by react-router --

// We use React.Children.forEach instead of React.Children.toArray().find()
Expand Down
4 changes: 2 additions & 2 deletions src/Then.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { FC } from 'react';
import { render } from './render';
import type { FCWithImplicitChildren } from './types';

/**
* Must contain only a single child, which it renders as-is.
* Should not be used outside of an `<If />` block.
* @param props The props to pass down to the `<Then />` component
*/
export const Then: FC = (props) => render(props);
export const Then: FCWithImplicitChildren = (props) => render(props);
9 changes: 6 additions & 3 deletions src/render.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React, { FC, Fragment } from 'react';
import React, { Fragment } from 'react';
import type { FCWithImplicitChildren } from './types';

/**
* Renders a React component while also checking whether the children are a function or not
* @param props Props of the component to render
*/
export const render: FC = (props) => {
export const render: FCWithImplicitChildren = (props) => {
if (typeof props.children === 'function') {
return <Fragment>{props.children()}</Fragment>;
return <Fragment>{(props.children as CustomFunction)()}</Fragment>;
}

return <Fragment>{props.children || null}</Fragment>;
};

type CustomFunction = (...args: unknown[]) => JSX.Element;
15 changes: 14 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PropsWithChildren } from 'react';
import type { PropsWithChildren, ReactElement, ValidationMap, WeakValidationMap } from 'react';

/**
* Type for a value that can properly be parsed by `Boolean(...)`
Expand Down Expand Up @@ -43,3 +43,16 @@ export interface AsyncSupportProps {
* to also support async
*/
export interface ComponentWithConditionPropsAsyncSupport extends ComponentWithConditionProps, AsyncSupportProps {}

export type FCWithImplicitChildren<P = NonNullObject> = FunctionComponentWithImplicitChildren<P>;

interface FunctionComponentWithImplicitChildren<P = NonNullObject> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P> | undefined;
contextTypes?: ValidationMap<any> | undefined;
defaultProps?: Partial<P> | undefined;
displayName?: string | undefined;
}

// eslint-disable-next-line @typescript-eslint/ban-types
type NonNullObject = {} & object;
1 change: 1 addition & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const createCancellablePromise = <T>(promise: ExtendablePromise<T>): Canc
}

const isCancelled = { value: false };

const wrappedPromise: ExtendablePromise<T> = new Promise(async (res, rej) => {
try {
const d = await promise;
Expand Down

0 comments on commit 4d504e1

Please sign in to comment.