Skip to content

Feature Request: Resolve font family + font weight + font style to different font families #578

@tobimori

Description

@tobimori

font-sans font-medium italic works on web, but falls back to the system font on native when using custom font files (tested with Expo Font, it might vary per system).

On native, Uniwind currently resolves this roughly as:

{
	fontFamily: "Inter_400Regular",
	fontWeight: "500",
	fontStyle: "italic",
}

For React Native custom fonts, this often fails because each font file is registered as a separate family. Native does not reliably resolve Inter_400Regular + 500 + italic into Inter_500Medium_Italic.

The native output needs to become:

{
	fontFamily: "Inter_500Medium_Italic",
}

Suggested theme convention:

@theme {
	--font-sans: "Inter Variable", sans-serif; /* this would only apply on web, where we don't resolve the below variables */

	--font-sans--400: "Inter_400Regular";
	--font-sans--400--italic: "Inter_400Regular_Italic";

	--font-sans--500: "Inter_500Medium";
	--font-sans--500--italic: "Inter_500Medium_Italic";

	--font-sans--600: "Inter_600SemiBold";
	--font-sans--600--italic: "Inter_600SemiBold_Italic";
}

Expected native resolution:

<Text className="font-sans" />
// -> --font-sans--400

<Text className="font-sans italic" />
// -> --font-sans--400--italic

<Text className="font-sans font-medium" />
// -> --font-sans--500

<Text className="font-sans font-medium italic" />
// -> --font-sans--500--italic

<Text className="font-sans font-semibold italic" />
// -> --font-sans--600--italic

If the exact variant variable exists, Uniwind should use that as fontFamily on native and avoid emitting fontWeight/fontStyle for that resolved custom font variant. If no matching variant variable exists, current behavior can remain unchanged.

This keeps web behavior natural while making React Native custom fonts work without needing explicit classes like font-sans--500--italic everywhere.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions