React is adding props intended for Emotion HOC

Viewed 18

I am trying to make a HOC that uses the Emotion library to return a React component that accepts any CSS property as a prop and styles it with Emotion as well as accepting a prop called css, also injecting that into Emotion's own css prop.

Here is what that looks like:

/** @jsx jsx */
/** @jsxRuntime classic */
import React from "react"
import { jsx, type CSSObject } from '@emotion/react'

// Returns the type of CSS style properties, like 'marginTop' or 'backgroundColor'
type HOCProps = Partial<React.CSSProperties> & {
    css?: CSSObject | string
}

// Converts a string of css into an object for Emotion
const cssStringToObject = (css: string): CSSObject => {
    const r = /(?<=^|;)\s*([^:]+)\s*:\s*([^;]+)\s*/g, o = {}
    css.replace(r, (_, p, v) => o[p.replace(/-(.)/g, (m,p) => p.toUpperCase())] = v)
    return o
}

export default function withStyles<T>(Component: React.ComponentType<T>) {
    return (props: T & HOCProps) =>
        <Component
            {...props}
            css={{
                ...props,
                ...(props.css && (
                    typeof props.css === 'string'
                    ? cssStringToObject(props.css)
                    : props.css
                ))
            }}
        />
}

This is then used like this:

// AnotherFile.jsx
import React from 'react';
import withStyles from './withStyles'

const ButtonComponent = (props: React.HTMLAttributes<HTMLButtonElement>) => {
  return (
    <button {...props}>
      {props.children}
    </button>
  )
}

const Button = withStyles(ButtonComponent)

function App() {
  return (
    <div className="App">
      <Button
        padding="5em"
        marginLeft="10em"
        marginTop="10em"
        backgroundColor="lightblue"
        css={{
          borderRadius: '5em'
        }}
        onClick={() => alert("Hello")}
      >
        Click Me
      </Button>
    </div>
  );
}

This works fine as far as styling the component, but in the DOM it produces an element that looks like this:

<button class="css-1nsumwm" padding="5em" marginleft="10em" margintop="10em" backgroundcolor="lightblue">Click Me</button>

which is throwing React errors:

Warning: React does not recognize the `backgroundColor` prop on a DOM element.

How can I prevent these props from being attached in this way?

0 Answers
Related