-
Notifications
You must be signed in to change notification settings - Fork 59
Open
Labels
Description
Is there an existing issue or pull request for this?
- I have searched the existing issues and pull requests
Feature description
Adding a as prop is a very interesting feature. As an advanced abstraction layer, it can determine the type of element to render based on the passed-in as. This is particularly useful in scenarios that require dynamic rendering. For example, we may need to render different elements based on various conditions and add animation effects.
Desired solution
import { AnimatePresence, motion } from 'motion/react';
import { If } from 'react-if';
function List({ loading, list }) {
const [tag, setTag] = useState('h1');
return (
<If condition={!loading} as={AnimatePresence} initial={false}>
<Then
as={motion.div}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
{/* ... */}
</Then>
<Else
as={motion.div}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
{/* ... */}
</Else>
</If>
);
}Corresponding implementation:
import type { JSX } from 'react'
import { createElement } from 'react'
export type WrapperAs = keyof JSX.IntrinsicElements | Function
export type WrapperProps<As extends keyof JSX.IntrinsicElements | React.FC | unknown> =
{ as?: As } &
(As extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[As] : unknown) &
(As extends React.FC<infer P> ? P : unknown)
export function wrapper(as: any, props: unknown, children?: React.ReactNode) {
return as ? createElement(as, props, children) : children
}
// if.tsx
export type IfProps<As> = WrapperProps<As> & {
condition?: BooleanLike
children?: ReactNode
}
export function If<As extends WrapperAs>(props: IfProps<As>) {
const { condition, children, as, ...attrs } = props
// ...
return wrapper(as, attrs, content)
}Alternatives considered
none
Additional context
No response
Reactions are currently unavailable