Tailwind CSS: adding `className` to components

Hi there !

I’m trying to use tailwind CSS with React Native. What is the best way to wrap components.

Unfortunately, I cannot find a simple way to extend types with “className”… Maybe this could be done on the jsx setup ? And then, no wrapping at all is needed anymore.

// This does not compile: type spreading only works for objects, .
type styled<'a> = {...'a, className?: string}

@module("nativewind")
external styled: React.component<'a> => React.component<styled<'a>> = "styled"

module Image = {
  let make = styled(ReactNative.Image.make)
}

Indeed in this case the best solution is likely to spread the jsx type and add a styled field to it, you can read more about customizing JSX here.

Unfortunately, this doesn’t work because the types for a component can be defined as named function arguments instead of an object:


type styledProps<'a> = {
  ...'a, // <=== The type 'a is not an object type
  className?: string,
}

type component<'props> = Jsx.component<styledProps<'props>>

PS: props type for Elements is not a problem because JsxDOM.domProps already has “className”.

So, I explored changing the types in rescript-react-native to a record (named _props to not conflict with the props type created by @react.component). Now this seems to work.

Are there any downsides to using records instead of function arguments in rescript-react-native?

And why does @react.component create a generic props< 'children, ...>?

module View = {
  type p = {
    ...ReactNative.View._props,
    ...styledProps,
  }
  let make: React.component<p> = styled(ReactNative.View.make)
}

well actually @react.component is just a shortcut that generates the props type and change the function from accepting labeled arguments to a props object, so doing it manually is not an issue at all!

I have no idea why @react.component creates a generic props though, likely because the jsx transform doesn’t have access to types at this point. If it didn’t do that, you would not have to redefine a _props type, you could actually still use the generated props type if you don’t mind defining all the type parameters yourself.