mirror of
https://github.com/zhigang1992/nativewind.git
synced 2026-06-15 10:17:54 +08:00
fix: forwarding refs of styled components
This commit is contained in:
@@ -6,10 +6,20 @@ export type StyledComponentProps<P> = StyledProps<P> & {
|
||||
component: React.ComponentType<P>;
|
||||
};
|
||||
|
||||
export function StyledComponent<P>({
|
||||
component,
|
||||
...options
|
||||
}: StyledComponentProps<P>) {
|
||||
const Component = styled<P>(component);
|
||||
return <Component {...(options as P)} />;
|
||||
declare module "react" {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function forwardRef<T, P = {}>(
|
||||
render: (props: P, ref: React.Ref<T>) => React.ReactElement | null
|
||||
): (props: P & React.RefAttributes<T>) => React.ReactElement | null;
|
||||
}
|
||||
|
||||
function StyledComponentFunction<P>(
|
||||
{ component, ...options }: StyledComponentProps<P>,
|
||||
ref: React.ForwardedRef<unknown>
|
||||
) {
|
||||
const Component = styled(component);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return <Component {...(options as any)} ref={ref} />;
|
||||
}
|
||||
|
||||
export const StyledComponent = React.forwardRef(StyledComponentFunction);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import {
|
||||
ComponentProps,
|
||||
createElement,
|
||||
FC,
|
||||
ReactNode,
|
||||
ComponentType,
|
||||
forwardRef,
|
||||
RefAttributes,
|
||||
ForwardedRef,
|
||||
ClassAttributes,
|
||||
ForwardRefExoticComponent,
|
||||
PropsWithoutRef,
|
||||
} from "react";
|
||||
import { StyledProps, StyledPropsWithKeys } from "./utils/styled";
|
||||
import { ComponentContext } from "./context/component";
|
||||
@@ -22,20 +27,30 @@ export interface StyledOptions<P> {
|
||||
supportsClassName?: boolean;
|
||||
}
|
||||
|
||||
type ForwardRef<T, P> = ForwardRefExoticComponent<
|
||||
PropsWithoutRef<P> & RefAttributes<T>
|
||||
>;
|
||||
|
||||
type InferRef<T> = T extends RefAttributes<infer R> | ClassAttributes<infer R>
|
||||
? R
|
||||
: unknown;
|
||||
|
||||
/**
|
||||
* Normal usage
|
||||
*/
|
||||
export function styled<T>(
|
||||
Component: ComponentType<T>,
|
||||
options?: { props?: undefined; spreadProps?: undefined }
|
||||
): FC<StyledProps<T>>;
|
||||
): ForwardRef<InferRef<T>, StyledProps<T>>;
|
||||
|
||||
/**
|
||||
* With either props or valueProps
|
||||
*/
|
||||
export function styled<T, K extends keyof T & string>(
|
||||
Component: ComponentType<T>,
|
||||
options: { props?: Array<K>; spreadProps?: Array<K>; classProps?: Array<K> }
|
||||
): FC<StyledPropsWithKeys<T, K>>;
|
||||
): ForwardRef<InferRef<T>, StyledPropsWithKeys<T, K>>;
|
||||
|
||||
/**
|
||||
* Actual implementation
|
||||
*/
|
||||
@@ -50,13 +65,16 @@ export function styled<
|
||||
supportsClassName = false,
|
||||
}: StyledOptions<T> = {}
|
||||
) {
|
||||
function Styled({
|
||||
className,
|
||||
tw: twClassName,
|
||||
style: styleProp,
|
||||
children: componentChildren,
|
||||
...componentProps
|
||||
}: StyledProps<T>) {
|
||||
function Styled(
|
||||
{
|
||||
className,
|
||||
tw: twClassName,
|
||||
style: styleProp,
|
||||
children: componentChildren,
|
||||
...componentProps
|
||||
}: StyledProps<T>,
|
||||
ref: ForwardedRef<unknown>
|
||||
) {
|
||||
const { platform, preview } = usePlatform();
|
||||
|
||||
const { classes, allClasses, isComponent } = withClassNames({
|
||||
@@ -105,6 +123,7 @@ export function styled<
|
||||
...handlers,
|
||||
...styledProps,
|
||||
children,
|
||||
ref,
|
||||
} as unknown as T);
|
||||
|
||||
return !isComponent
|
||||
@@ -124,5 +143,5 @@ export function styled<
|
||||
}`;
|
||||
}
|
||||
|
||||
return Styled;
|
||||
return forwardRef(Styled);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user