@spaced-out/ui-design-system
Version:
Sense UI components library
71 lines (63 loc) • 1.74 kB
Flow
// @flow strict
import * as React from 'react';
import classify from '../classify';
export function nameHoc<C, T: React.ComponentType<C>, C2>(
WrapperComponent: T,
WrappedComponent: React.ComponentType<C2>,
hocName: string,
): T {
const wrappedComponentName =
WrappedComponent.displayName || WrappedComponent.name || 'Component';
WrapperComponent.displayName = `${hocName}(${wrappedComponentName})`;
return WrapperComponent;
}
export type ClassNameComponent<
T = 'div',
I = React.ElementRef<T>,
> = React.AbstractComponent<React.ElementConfig<T>, I>;
export function makeClassNameComponent<C: string>(
baseClassName: string,
// $FlowFixMe not sure how to type this correctly
ComponentType: C = 'div',
name?: string,
): React.AbstractComponent<React.ElementConfig<C>, React.ElementRef<C>> {
return React.forwardRef(
// $FlowFixMe[escaped-generic]
nameComponent(
({className, ...props}, ref) => (
// $FlowFixMe[escaped-generic]
<ComponentType
{...props}
ref={ref}
className={classify(baseClassName, className)}
/>
),
`CNC(${name || ComponentType})`,
),
);
}
export function makeClassNameComponentCustom<
C: $ReadOnly<{className?: string}>,
B,
>(
baseClassName: string,
ComponentType: React.AbstractComponent<C, B>,
): React.AbstractComponent<C, B> {
return React.forwardRef(
nameHoc(
({className, ...props}, ref) => (
<ComponentType
{...props}
ref={ref}
className={classify(baseClassName, className)}
/>
),
ComponentType,
'CNC',
),
);
}
function nameComponent(component, name) {
component.displayName = name;
return component;
}