Skip to content

withUniwind (native) forwards className to the wrapped component — #615's prop-stripping fix is missing from withUniwind.native.tsx #638

Description

@invivek26

Description

On native, withUniwind spreads the original props — className included — through to the wrapped component after converting them:

// src/hoc/withUniwind.native.tsx (1.11.0)
return (
    <Component
        {...props}          // still contains className / *ClassName props
        {...generatedProps}
    />
)

This is the same class of bug that #614 reported and #615 fixed, but #615 only touched withUniwind.tsx (web) and its web tests — withUniwind.native.tsx still forwards the class props.

Why it matters on native

If the wrapped component is app-source and forwards unknown props onto a core react-native component (whose import Metro has rewritten to the uniwind className-aware version), the leaked className applies the styles a second time on a different node than the style prop produced by the HOC.

We hit this with a first-party Pressable that routes its style prop to an inner glass surface while spreading the rest of its props onto RN's Pressable: every pill/card rendered doubled — an outer capsule (from the leaked className on the rewritten inner Pressable) plus the inner styled surface (from the converted style). Components wrapped from node_modules are unaffected because their internals aren't rewritten, which makes the failure look app-specific and hard to attribute.

Repro sketch

// app-source component that forwards unknown props to core RN
const Card = ({ style, ...rest }: ViewProps) => (
    <Pressable {...rest}>            // Metro-rewritten, className-aware
        <GlassSurface style={style} />  // HOC's converted style lands here
    </Pressable>
)

const StyledCard = withUniwind(Card)

<StyledCard className="rounded-full bg-blue-600 px-5 py-2" />
// → styles applied on BOTH the outer Pressable and the GlassSurface

Expected

withUniwind (auto and manual modes) removes className / *ClassName / *ColorClassName input props after converting them, matching the web behavior after #615.

Workaround

A shim between withUniwind and the component that strips className from the spread:

const withUniwindAppSource = (Component) =>
    withUniwind(({ className: _c, ...rest }) => <Component {...rest} />)

Environment

  • uniwind 1.11.0 (free tier), React Native 0.85.3, Expo SDK 56, New Architecture
  • Coexisting with react-native-unistyles 3.2.4 during an incremental migration (not related to the bug — the forwarding is visible in the HOC source regardless)

Metadata

Metadata

Assignees

No one assigned

    Labels

    invalidThis doesn't seem right

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions