Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated ReactHTML and ReactSVG #362

Open
eps1lon opened this issue Mar 17, 2024 · 2 comments
Open

Remove deprecated ReactHTML and ReactSVG #362

eps1lon opened this issue Mar 17, 2024 · 2 comments
Labels
enhancement New feature or request React 19

Comments

@eps1lon
Copy link
Owner

eps1lon commented Mar 17, 2024

ReactHMTL and ReactSVG were related to createFactories but we found usage using it as a list of possible built-in browser element types.

We now have HTMLElementType and SVGElementType which can be used instead of keyof ReactHTML and keyof ReactSVG respectively.

Needs real world codebase with usage to test on.

@eps1lon eps1lon added the enhancement New feature or request label Mar 17, 2024
@eps1lon eps1lon moved this to Ready in React 19 types Mar 17, 2024
@eps1lon eps1lon assigned eps1lon and unassigned eps1lon Mar 17, 2024
@mattgperry
Copy link

Previously to type <motion.div /> components and props we had:

type UnwrapFactoryAttributes<F> = F extends DetailedHTMLFactory<infer P, any>
    ? P
    : never
type UnwrapFactoryElement<F> = F extends DetailedHTMLFactory<any, infer P>
    ? P
    : never

type HTMLAttributesWithoutMotionProps<
    Attributes extends HTMLAttributes<Element>,
    Element extends HTMLElement
> = { [K in Exclude<keyof Attributes, keyof MotionProps>]?: Attributes[K] }

export type HTMLMotionProps<TagName extends keyof ReactHTML> =
    HTMLAttributesWithoutMotionProps<
        UnwrapFactoryAttributes<ReactHTML[TagName]>,
        UnwrapFactoryElement<ReactHTML[TagName]>
    > &
        MotionProps

export type HTMLMotionComponents = {
    [K in HTMLElements]: ForwardRefComponent<
        UnwrapFactoryElement<ReactHTML[K]>,
        HTMLMotionProps<K>
    >
}

Which I've attempted to replace with

interface HTMLElements {
    a: HTMLAnchorElement
    abbr: HTMLElement
    address: HTMLElement
    /** etc **/
}

type AttributesWithoutMotionProps<Attributes> = {
    [K in Exclude<keyof Attributes, keyof MotionProps>]?: Attributes[K]
}

export type HTMLMotionProps<Tag extends keyof HTMLElements> = MotionProps &
    AttributesWithoutMotionProps<DOMAttributes<HTMLElements[Tag]>> &
    AttributesWithoutMotionProps<HTMLAttributes<HTMLElements[Tag]>>

export type HTMLMotionComponents = {
    [Tag in keyof HTMLElements]: ForwardRefComponent<
        HTMLElements[Tag],
        HTMLMotionProps<Tag>
    >
}

But this hasn't proven to be a direct replacement - <motion.button disabled /> will flag for errors.

This is quite a complex change and keyof ReactHTML -> HTMLElementType isn't enough, do you have an idea how this would be properly migrated?

@mattgperry
Copy link

mattgperry commented Jun 5, 2024

Ah - I got it. The replacement for the props is

AttributesWithoutMotionProps<JSX.IntrinsicElements[Tag]>

And the whole thing can be replaced with

AttributesWithoutMotionProps<Attributes> = {
    [K in Exclude<keyof Attributes, keyof MotionProps>]?: Attributes[K]
}

export type HTMLMotionProps<Tag extends HTMLElementType> =
    AttributesWithoutMotionProps<JSX.IntrinsicElements[Tag]> & MotionProps

export type HTMLMotionComponents = {
    [Tag in HTMLElementType]: ForwardRefComponent<Tag, HTMLMotionProps<Tag>>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request React 19
Projects
Status: Ready
Development

No branches or pull requests

2 participants