Skip to content

fontWeight and fontFamily not applied on breakpoints in Gluestack UI #2718

Open
@MrLapa

Description

@MrLapa

Description

fontWeight & fontFamily styles not being applied when using breakpoints in custom components

CodeSandbox/Snack link

--

Steps to reproduce

When implementing custom components with breakpoint-specific styles in Gluestack UI, the fontWeight and fontFamily styles are not properly applied under breakpoint conditions. This inconsistency affects styling across various viewport sizes. Notably, other styles like fontSize and lineHeight work as expected and are correctly applied at different breakpoints.

Heading component code:

Heading.tsx

import { H1, H2, H3, H4, H5, H6 } from "@expo/html-elements"
import React from "react"

import { GluestackHeading } from "./Heading.styles"

import { type IHeadingProps } from "@/modules/eve"

const sizeToElement = {
  h1: H1,
  h2: H2,
  h3: H3,
  h4: H4,
  h5: H5,
  h6: H6,
}

export const Heading: React.FunctionComponent<IHeadingProps> = ({
  children,
  ...props
}) => {
  return (
    <GluestackHeading as={sizeToElement[props.size]} {...props}>
      {children}
    </GluestackHeading>
  )
}

export default Heading

Theme Configuration:

theme.ts

import { AnimationResolver } from "@gluestack-style/animation-resolver"
import { MotionAnimationDriver } from "@gluestack-style/legend-motion-animation-driver"
import {
  createComponents,
  createConfig,
  FontResolver,
} from "@gluestack-style/react"

import * as componentsTheme from "./components"

export const config = createConfig({
  aliases: {
    bg: "backgroundColor",
    bgColor: "backgroundColor",
    h: "height",
    w: "width",
    p: "padding",
    px: "paddingHorizontal",
    py: "paddingVertical",
    pt: "paddingTop",
    pb: "paddingBottom",
    pr: "paddingRight",
    pl: "paddingLeft",
    m: "margin",
    mx: "marginHorizontal",
    my: "marginVertical",
    mt: "marginTop",
    mb: "marginBottom",
    mr: "marginRight",
    ml: "marginLeft",
    rounded: "borderRadius",
  } as const,
  tokens: {
    colors: {
      primary5: "#fffae5",
      primary10: "#fff5cc",
      primary20: "#ffea9b",
      primary30: "#ffe275",
      primary40: "#ffdb47",
      primary50: "#ffcb05",
      primary60: "#d2ab13",
      primary70: "#aebf13",
      primary80: "#7d6712",
      primary90: "#4c3f0b",

      secondary5: "#ebefff",
      secondary10: "#d5dff6",
      secondary20: "#afc3ee",
      secondary30: "#8199d9",
      secondary40: "#3956a7",
      secondary45: "#162d88",
      secondary50: "#162d6d",
      secondary60: "#19274c",
      secondary70: "#182139",
      secondary80: "#141a29",
      secondary90: "#0d111b",

      blue5: "#ebefff",
      blue10: "#d5dff6",
      blue20: "#afc3ee",
      blue30: "#8199d9",
      blue40: "#3956a7",
      blue45: "#162d88",
      blue50: "#162d6d",
      blue60: "#19274c",
      blue70: "#182139",
      blue80: "#141a29",
      blue90: "#0d111b",
      gray5: "#f7f7f7",
      gray10: "#ebebeb",
      gray20: "#e2e2e2",
      gray30: "#cbcbcb",
      gray40: "#adadad",
      gray50: "#737373",
      gray60: "#5e5e5e",
      gray70: "#474747",
      gray80: "#2e2e2e",
      gray90: "#1a1a1a",
      green5: "#eff5f2",
      green10: "#d7eae1",
      green20: "#acdcc6",
      green30: "#86caaa",
      green40: "#35a76e",
      green50: "#017a47",
      green60: "#04623a",
      green70: "#044d2e",
      green80: "#103823",
      green90: "#0c2c1b",
      orange5: "#fff3e5",
      orange10: "#ffe7cc",
      orange20: "#fed19a",
      orange30: "#febf71",
      orange40: "#faa438",
      orange50: "#f69904",
      orange60: "#ce7c09",
      orange70: "#935d10",
      orange80: "#643f0c",
      orange90: "#402808",
      purple5: "#fbebff",
      purple10: "#efd7f4",
      purple20: "#dcb2e6",
      purple30: "#c890d5",
      purple40: "#b66bc7",
      purple50: "#9e47b2",
      purple60: "#8b2da0",
      purple70: "#791e8e",
      purple80: "#5e0f70",
      purple90: "#3f064b",
      red5: "#ffebeb",
      red10: "#f5d9d6",
      red20: "#ebb4ad",
      red30: "#e08c81",
      red40: "#d7695b",
      red50: "#be322e",
      red60: "#9b1b17",
      red70: "#760d0a",
      red80: "#620704",
      red90: "#4f0401",
      seaGreen5: "#ebfffd",
      seaGreen10: "#d5f6f4",
      seaGreen20: "#acece6",
      seaGreen30: "#83e2d9",
      seaGreen40: "#23c7b9",
      seaGreen50: "#09b5a6",
      seaGreen60: "#009f92",
      seaGreen70: "#008579",
      seaGreen80: "#00665d",
      seaGreen90: "#004c46",
      turquoise5: "#ebfaff",
      turquoise10: "#d5edf6",
      turquoise20: "#afdae9",
      turquoise30: "#8ac6db",
      turquoise40: "#63b2cf",
      turquoise50: "#429dbd",
      turquoise60: "#207fa1",
      turquoise70: "#146f8f",
      turquoise80: "#095b78",
      turquoise90: "#02374a",
      yellow5: "#fffae5",
      yellow10: "#fff5cc",
      yellow20: "#ffea9b",
      yellow30: "#ffe275",
      yellow40: "#ffdb47",
      yellow50: "#ffcb05",
      yellow60: "#d2ab13",
      yellow70: "#aebf13",
      yellow80: "#7d6712",
      yellow90: "#4c3f0b",

      coolGray: "#f9fafb",
      white: "#ffffff",
      black: "#000000",

      error: "#be322e",
    },
    space: {
      "px": "1px",
      "0": 0,
      "0.25": 2,
      "0.5": 4,
      "0.75": 6,
      "1": 8,
      "1.25": 10,
      "1.5": 12,
      "2": 16,
      "2.5": 20,
      "3": 24,
      "4": 32,
      "5": 40,
      "6": 48,
      "8": 64,
      "10": 80,
      "1/12": "8.333%",
      "2/12": "16.666%",
      "3/12": "25%",
      "4/12": "33.333%",
      "5/12": "41.666%",
      "6/12": "50%",
      "7/12": "58.333%",
      "8/12": "66.666%",
      "9/12": "75%",
      "10/12": "83.333%",
      "11/12": "91.666%",
      "12/12": "100%",
      "full": "100%",
    },
    borderWidths: {
      "0": 0,
      "1": 1,
      "2": 2,
      "4": 4,
      "8": 8,
    },
    radii: {
      "none": 0,
      "xs": 2,
      "sm": 4,
      "md": 6,
      "lg": 8,
      "xl": 12,
      "2xl": 16,
      "3xl": 24,
      "full": 9999,
    },
    breakpoints: {
      base: 0,
      sm: 480,
      md: 768,
      lg: 992,
      xl: 1280,
    },
    mediaQueries: {
      base: "@media screen and (min-width: 0)",
      xs: "@media screen and (min-width: 400px)",
      sm: "@media screen and (min-width: 480px)",
      md: "@media screen and (min-width: 768px)",
      lg: "@media screen and (min-width: 992px)",
      xl: "@media screen and (min-width: 1280px)",
    },
    letterSpacings: {
      "xs": -0.4,
      "sm": -0.2,
      "md": 0,
      "lg": 0.2,
      "xl": 0.4,
      "2xl": 1.6,
    },
    lineHeights: {
      "xs": 20,
      "sm": 22,
      "md": 24,
      "lg": 28,
      "xl": 32,
      "2xl": 40,
      "3xl": 48,
      "4xl": 56,
      "5xl": 72,
      "6xl": 104,
    },
    fontWeights: {
      hairline: "100",
      thin: "200",
      light: "300",
      normal: "400",
      medium: "500",
      semibold: "600",
      bold: "700",
      extrabold: "800",
      black: "900",
    },
    fonts: {
      heading: "SourceSerifPro",
      body: "PublicSans",
      mono: "PublicSans",
    },
    fontSizes: {
      "xs": 12,
      "sm": 14,
      "md": 16,
      "lg": 20,
      "xl": 26,
      "2xl": 32,
      "3xl": 40,
      "4xl": 48,
      "5xl": 64,
      "6xl": 96,
    },
    opacity: {
      0: 0,
      5: 0.05,
      10: 0.1,
      20: 0.2,
      25: 0.25,
      30: 0.3,
      40: 0.4,
      50: 0.5,
      60: 0.6,
      70: 0.7,
      75: 0.75,
      80: 0.8,
      90: 0.9,
      95: 0.95,
      100: 1,
    },
  } as const,
  globalStyle: {
    variants: {
      hardShadow: {
        "1": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: -2,
            height: 2,
          },
          shadowRadius: 8,
          shadowOpacity: 0.5,
          elevation: 10,
        },
        "2": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: 0,
            height: 3,
          },
          shadowRadius: 8,
          shadowOpacity: 0.5,
          elevation: 10,
        },
        "3": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: 2,
            height: 2,
          },
          shadowRadius: 8,
          shadowOpacity: 0.5,
          elevation: 10,
        },
        /** card shadow */
        "4": {
          shadowColor: "$black",
          shadowOffset: {
            width: 0,
            height: 1,
          },
          shadowRadius: 4,
          shadowOpacity: 0.12,
          elevation: 5,
        },
        // this 5th version is only for toast shadow
        // temporary
        "5": {
          shadowColor: "$blue50",
          shadowOffset: {
            width: 0,
            height: 3,
          },
          shadowRadius: 8,
          shadowOpacity: 0.5,
          elevation: 5,
        },
      },
      softShadow: {
        "1": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: 0,
            height: 0,
          },
          shadowRadius: 10,
          shadowOpacity: 0.1,
          _android: {
            shadowColor: "$backgroundLight500",
            elevation: 5,
            shadowOpacity: 0.05,
          },
        },
        "2": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: 0,
            height: 0,
          },
          shadowRadius: 20,
          elevation: 3,
          shadowOpacity: 0.1,
          _android: {
            shadowColor: "$backgroundLight500",
            elevation: 10,
            shadowOpacity: 0.1,
          },
        },
        "3": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: 0,
            height: 0,
          },
          shadowRadius: 30,
          shadowOpacity: 0.1,
          elevation: 4,
          _android: {
            shadowColor: "$backgroundLight500",
            elevation: 15,
            shadowOpacity: 0.15,
          },
        },
        "4": {
          shadowColor: "$gray50",
          shadowOffset: {
            width: 0,
            height: 0,
          },
          shadowRadius: 40,
          shadowOpacity: 0.1,
          elevation: 10,
          _android: {
            shadowColor: "$backgroundLight500",
            elevation: 20,
            shadowOpacity: 0.2,
          },
        },
      },
    },
  },
  plugins: [new AnimationResolver(MotionAnimationDriver), new FontResolver()],
})

const components = createComponents(componentsTheme)

export const theme = {
  config,
  components,
}


Steps to Reproduce:

  1. Use the following configuration for the Heading component:
import { createStyle } from "@gluestack-style/react";

export const Heading = createStyle({
  variants: {
    size: {
      h1: {
        "fontFamily": "$body",
        "fontSize": "$xl",
        "lineHeight": "$xl",
        "fontWeight": "$semibold",
        "@md": {
          fontFamily: "$heading",
          fontSize: "$2xl",
          lineHeight: "$2xl",
          fontWeight: "$bold",
        },
      },
      h2: {
        "fontFamily": "$body",
        "fontSize": "$xl",
        "lineHeight": "$xl",
        "fontWeight": "$semibold",
        "@md": {
          fontFamily: "$heading",
          fontWeight: "$bold",
        },
      },
      // Other heading levels...
    },
  },
});

  1. Apply the Heading component to a React component:

<Heading size="h1">Responsive Heading</Heading>

  1. Resize the browser window to test responsiveness.

Expected Behavior

The styles under the @md breakpoint should be applied when the browser width meets the defined breakpoint.

Actual Behavior

The styles defined under the @md breakpoint are not applied. Instead, only the base styles are reflected, regardless of the viewport size.

Environment Details
Library Version:

"@gluestack-style/react": "1.0.57",
"@gluestack-ui/config": "^1.1.18",
"@gluestack-ui/themed": "1.1.30",

React Version: "react-dom": "18.2.0",
Browser: Version 132.0.6834.84 (Official Build) (arm64)

gluestack-ui Version

1.1.18

Platform

  • Expo
  • React Native CLI
  • Next
  • Web
  • Android
  • iOS

Other Platform

No response

Additional Information

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions