Box component that can take a ref #121
-
I'm using the Box component from the Codesandbox. import type { ElementType, ComponentPropsWithoutRef } from "react";
import type { Sprinkles } from "~/styles/sprinkles.css";
import { sprinkles } from "~/styles/sprinkles.css";
import clsx from "clsx";
export type BoxProps<C extends ElementType> = Sprinkles &
ComponentPropsWithoutRef<C> & {
as?: C;
};
export const Box = <C extends ElementType = "div">({
as,
children,
className: classes,
...props
}: BoxProps<C>) => {
const { className, style, otherProps } = sprinkles(props);
const Component = as || "div";
return (
<Component
className={clsx(classes, className)}
style={style}
{...otherProps}
>
{children}
</Component>
);
}; Has anyone got a Box component working that takes a |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
TypeScript + forwardRef + polymorphism = not a fun time :( This is true even without rainbow sprinkles. That said, I've got it working before. I recommend using this utility, it's the best typing I've seen for forward ref and polymorphism. |
Beta Was this translation helpful? Give feedback.
-
@roginfarrer @brandonpittman I'm struggling a bit with this same problem. Do either of you haven any code samples I could take a look at? Thanks! |
Beta Was this translation helpful? Give feedback.
-
Another approach is to just not use working theory so far: import type { PropsWithChildren } from 'react';
import { Children, isValidElement, cloneElement } from 'react';
import classnames from 'classnames'
import type { BoxSprinkleProps } from './Box.css';
import { BoxSprinkles, withDividers } from './Box.css';
type AsChildProps<DefaultElementProps> = PropsWithChildren<
{ asChild?: boolean } & DefaultElementProps
>
export type BoxProps = AsChildProps<{
dividers?: boolean;
asChild?: boolean;
className?: string;
style?: string;
} & React.HTMLAttributes<HTMLElement> & BoxSprinkleProps>
function Slot({
children,
style,
className,
...props
}: React.HTMLAttributes<HTMLElement> & {
children?: React.ReactNode
}) {
if (isValidElement(children)) {
return cloneElement(children, {
...props,
...children.props,
style: {
...style,
...children.props.style,
},
className: classnames(
className,
children.props.className
)
})
}
if (Children.count(children) > 1) {
Children.only(null)
}
return null
}
export const Box = ({ asChild, className, dividers, children, style, ...props }: BoxProps) => {
const Component = asChild ? Slot : 'div'
return (
<Component
style={style}
className={classnames(
'box',
className,
dividers && withDividers,
BoxSprinkles({ display: 'flex', ...props })
)}
>{children}</Component>
)
} usage: <Box direction="column" justify="center" align="center" asChild>
<img src={theImage} ... />
</Box> |
Beta Was this translation helpful? Give feedback.
TypeScript + forwardRef + polymorphism = not a fun time :(
This is true even without rainbow sprinkles. That said, I've got it working before. I recommend using this utility, it's the best typing I've seen for forward ref and polymorphism.