All files / app/common/hoc createInjectHoc.tsx

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51  153x 153x                 153x             586x       1398x 1398x 1398x   1398x 5819x     1398x 8212x 23810x   8212x 320x     7892x   7892x     1398x 1395x     1398x      
 
import { isEmpty, pickBy } from 'lodash';
import React, { memo, useContext, ComponentType, Context, FunctionComponent } from 'react';
 
import InjectHoc from './InjectHoc';
 
export interface InjectHocOptions<TInjectedProps> {
    displayNamePrefix?: string;
    pickProps?(value: TInjectedProps[keyof TInjectedProps], key: keyof TInjectedProps): boolean;
}
 
export default function createInjectHoc<
    TInjectedProps extends object | undefined,
    TPickedProps extends Partial<TInjectedProps> = TInjectedProps
>(
    ContextComponent: Context<TInjectedProps>,
    options?: InjectHocOptions<TInjectedProps>
): InjectHoc<NonNullable<TPickedProps>> {
    return <TProps extends TPickedProps>(
        OriginalComponent: ComponentType<TProps>
    ) => {
        const {
            displayNamePrefix = '',
            pickProps = () => true,
        } = options || {};
 
        const InnerDecoratedComponent: FunctionComponent<TProps> = memo(props =>
            <OriginalComponent { ...props } />
        );
 
        const DecoratedComponent = (props: Omit<TProps, keyof NonNullable<TPickedProps>>) => {
            const context = useContext(ContextComponent);
            const injectedProps = pickBy(context, (value, key) => pickProps(value, key as keyof TInjectedProps));
 
            if (isEmpty(injectedProps)) {
                return null;
            }
 
            const mergedProps = { ...injectedProps, ...props } as unknown as TProps;
 
            return <InnerDecoratedComponent { ...mergedProps } />;
        };
 
        if (displayNamePrefix) {
            DecoratedComponent.displayName = `${displayNamePrefix}(${OriginalComponent.displayName || OriginalComponent.name})`;
        }
 
        return DecoratedComponent;
    };
}