Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

A list with a `var()` entry renders without the variable an ancestor sets: `transition-duration: var(--x), 2s` gives `[2000]`

Ouverte
#527 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 3 jours

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
56/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
react-native, typescript
Domaine
frontend

Piste de recherche

Start with src/compiler/stylesheet.ts and postProcessStyleFunction, then trace how updateRules in src/native/react/rules.ts supplies inherited variables to rules. The issue includes a reproducer at src/__tests__/native/list-variable.test.tsx; run it to check the listed declarations. Done means each list retains its var() entry resolved from the ancestor, alongside the remaining entries.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Before submitting a new issue
  • I tested using the latest version of the library, as the bug might be already fixed.
  • I tested using a supported version of react native.
  • I checked for possible duplicate issues, with possible answers.
Bug summary

A declaration whose value compiles to a plain list with a var() in it — transition-duration: var(--x), 2s, margin: var(--x) 2px — renders without the variable when an ancestor sets it: the var() entry is dropped and the rest of the list reaches React Native (transitionDuration: [2000], margin: [2]). The same var(--x) alone resolves. Each case is a .parent { --x: … } around a .child that reads it, compiled with inlineVariables: false.

transition-duration: var(--x), 2s over --x: 3s
dv=undefined d=[[[[{},"var","x",1],2000],"transitionDuration"]]
rendered={"transitionDuration":[2000]}
transition-duration: var(--x) over --x: 3s
dv=1 d=[[[{},"var","x",1],"transitionDuration",1]]
rendered={"transitionDuration":3000}
transition-delay: var(--x), 2s over --x: 3s
dv=undefined d=[[[[{},"var","x",1],2000],"transitionDelay"]]
rendered={"transitionDelay":[2000]}
transition-timing-function: var(--x), ease-in over --x: linear
dv=undefined d=[[[[{},"var","x",1],"ease-in"],"transitionTimingFunction"]]
rendered={"transitionTimingFunction":["ease-in"]}
transition-property: var(--x), height over --x: width
dv=undefined d=[[[[{},"var","x",1],"height"],"transitionProperty"]]
rendered={"transitionProperty":["height"]}
animation-duration: var(--x), 2s over --x: 3s
dv=undefined d=[[[[{},"var","x",1],2000],"animationDuration"]]
rendered={"animationDuration":[2000]}
margin: var(--x) 2px over --x: 4px
dv=undefined d=[[[[{},"var","x",1],2],"margin"]]
rendered={"margin":[2]}
padding: var(--x) 2px over --x: 4px
dv=undefined d=[[[[{},"var","x",1],2],"padding"]]
rendered={"padding":[2]}
border-width: var(--x) 2px over --x: 4px
dv=undefined d=[[[[{},"var","x",1],2],"borderWidth"]]
rendered={"borderWidth":[2]}
font-family: var(--x), sans-serif over --x: Inter
dv=undefined d=[[[[{},"var","x",1],"sans-serif"],"fontFamily"]]
rendered={"fontFamily":["sans-serif"]}
transform: translateX(var(--x)) rotate(5deg) over --x: 10px
dv=1 d=[[[{},"transform",[[{},"translateX",[{},"var","x",1]],[{},"rotate","5deg"]],1],"transform",1]]
rendered={"transform":[{"translateX":10},{"rotate":"5deg"}]}
box-shadow: var(--x) 1px red over --x: 4px
dv=1 d=[[[{},"boxShadow",[[{},"var","x",1],1,"red"],1],"boxShadow",1]]
rendered={"boxShadow":[{"offsetX":4,"offsetY":1,"color":"red"}]}
width: var(--x) over --x: 4px
dv=1 d=[[[{},"var","x",1],"width",1]]
rendered={"width":4}

Expected: transitionDuration: [3000, 2000], and the variable's value in each list. StylesheetBuilder.addDescriptor (src/compiler/stylesheet.ts) runs postProcessStyleFunction, which sets the rule's dv and the declaration's delay flag, only when the value itself is a style function; a list holding one takes the other branch and gets neither, and updateRules (src/native/react/rules.ts) adds the inherited variables to a style's inputs only for a rule with dv.

Library version

main at 2421ea7 (0.0.0-nightly.2421ea7)

Environment info
System:
  OS: Windows 11 10.0.26300
  CPU: "(32) x64 AMD Ryzen 9 9950X3D 16-Core Processor          "
  Memory: 155.26 GB / 255.67 GB
Binaries:
  Node:
    version: 26.12.1
    path: C:\Program Files\nodejs\node.EXE
  Yarn:
    version: 4.9.2
    path: C:\Users\<user>\AppData\Roaming\npm\yarn.CMD
  npm:
    version: 12.2.1
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK:
    API Levels:
      - "33"
      - "35"
      - "35"
      - "35"
      - "36"
      - "37"
    Build Tools:
      - 35.0.0
      - 36.0.0
      - 36.1.0
      - 37.0.0
    System Images:
      - android-26 | Google APIs Intel x86_64 Atom
      - android-28 | Google APIs Intel x86_64 Atom
      - android-29 | Google APIs Intel x86_64 Atom
      - android-30 | Google APIs Intel x86_64 Atom
      - android-31 | Google APIs Intel x86_64 Atom
      - android-32 | Google APIs Intel x86_64 Atom
      - android-33 | Google APIs Intel x86_64 Atom
      - android-34 | Google APIs Intel x86_64 Atom
      - android-35 | Google APIs Intel x86_64 Atom
      - android-36.1 | Google Play Intel x86_64 Atom
      - android-36.1 | Pre-Release 16 KB Page Size Google Play Intel x86_64 Atom
      - android-37.0 | Google APIs Intel x86_64 Atom
    Android NDK: Not Found
  Windows SDK: Not Found
IDEs:
  Android Studio: AI-262.9437.185.2621.16467767
  Visual Studio: Not Found
Languages:
  Java:
    version: 17.0.20.1
    path: C:\Program Files\Microsoft\jdk-17.0.20.101-hotspot\bin\javac.EXE
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 19.2.3
    wanted: 19.2.3
  react-native:
    installed: 0.86.3
    wanted: 0.86.3
  react-native-windows: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found
Steps to reproduce
  1. Clone the reproducer branch, which is main at 2421ea7 with one file added, src/__tests__/native/list-variable.test.tsx, and install:
    git clone --branch repro/527-list-value-loses-an-ancestors-variable https://github.com/YevheniiKotyrlo/react-native-css
    cd react-native-css
    yarn install
    
  2. Run yarn jest src/__tests__/native/list-variable.test.tsx.

src/__tests__/native/list-variable.test.tsx:

// Run from a react-native-css checkout: copy to src/__tests__/native/list-variable.test.tsx, then `yarn jest src/__tests__/native/list-variable.test.tsx`.
import { StyleSheet } from "react-native";

import { render, screen } from "@testing-library/react-native";
import { compile } from "react-native-css/compiler";
import { View } from "react-native-css/components/View";
import { registerCSS } from "react-native-css/jest";

jest.mock("../../native/reanimated", () => ({
  animatedComponentFamily: (component: unknown) => component,
}));

const cases: readonly (readonly [string, string, string])[] = [
  ["transition-duration", "3s", "var(--x), 2s"],
  ["transition-duration", "3s", "var(--x)"],
  ["transition-delay", "3s", "var(--x), 2s"],
  ["transition-timing-function", "linear", "var(--x), ease-in"],
  ["transition-property", "width", "var(--x), height"],
  ["animation-duration", "3s", "var(--x), 2s"],
  ["margin", "4px", "var(--x) 2px"],
  ["padding", "4px", "var(--x) 2px"],
  ["border-width", "4px", "var(--x) 2px"],
  ["font-family", "Inter", "var(--x), sans-serif"],
  ["transform", "10px", "translateX(var(--x)) rotate(5deg)"],
  ["box-shadow", "4px", "var(--x) 1px red"],
  ["width", "4px", "var(--x)"],
];

test.each(cases)("%s: %s through %s from an ancestor", (property, held, value) => {
  const css = `.parent { --x: ${held}; } .child { ${property}: ${value}; }`;
  for (const inlineVariables of [false] as const) {
    registerCSS(css, { inlineVariables });
    const rule = compile(css, { inlineVariables })
      .stylesheet()
      .s?.find(([name]) => name === "child")?.[1][0];
    render(
      <View className="parent">
        <View testID="child" className="child" />
      </View>,
    );
    console.log(
      `${property}: ${value} over --x: ${held}\n  dv=${String(rule?.dv)} d=${JSON.stringify(rule?.d)}\n  rendered=${JSON.stringify(StyleSheet.flatten(screen.getByTestId("child").props.style))}`,
    );
    screen.unmount();
  }
});

Expected: the var() entry takes the value the ancestor sets, so the list keeps every entry.

Actual: the var() entry is dropped and the rest of the list reaches React Native: transitionDuration: [2000], margin: [2].

The run's output on main at 2421ea7, Windows 11, Node 26.12.1
  console.log
    transition-duration: var(--x), 2s over --x: 3s
      dv=undefined d=[[[[{},"var","x",1],2000],"transitionDuration"]]
      rendered={"transitionDuration":[2000]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    transition-duration: var(--x) over --x: 3s
      dv=1 d=[[[{},"var","x",1],"transitionDuration",1]]
      rendered={"transitionDuration":3000}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    transition-delay: var(--x), 2s over --x: 3s
      dv=undefined d=[[[[{},"var","x",1],2000],"transitionDelay"]]
      rendered={"transitionDelay":[2000]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    transition-timing-function: var(--x), ease-in over --x: linear
      dv=undefined d=[[[[{},"var","x",1],"ease-in"],"transitionTimingFunction"]]
      rendered={"transitionTimingFunction":["ease-in"]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    transition-property: var(--x), height over --x: width
      dv=undefined d=[[[[{},"var","x",1],"height"],"transitionProperty"]]
      rendered={"transitionProperty":["height"]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    animation-duration: var(--x), 2s over --x: 3s
      dv=undefined d=[[[[{},"var","x",1],2000],"animationDuration"]]
      rendered={"animationDuration":[2000]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    margin: var(--x) 2px over --x: 4px
      dv=undefined d=[[[[{},"var","x",1],2],"margin"]]
      rendered={"margin":[2]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    padding: var(--x) 2px over --x: 4px
      dv=undefined d=[[[[{},"var","x",1],2],"padding"]]
      rendered={"padding":[2]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    border-width: var(--x) 2px over --x: 4px
      dv=undefined d=[[[[{},"var","x",1],2],"borderWidth"]]
      rendered={"borderWidth":[2]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    font-family: var(--x), sans-serif over --x: Inter
      dv=undefined d=[[[[{},"var","x",1],"sans-serif"],"fontFamily"]]
      rendered={"fontFamily":["sans-serif"]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    transform: translateX(var(--x)) rotate(5deg) over --x: 10px
      dv=1 d=[[[{},"transform",[[{},"translateX",[{},"var","x",1]],[{},"rotate","5deg"]],1],"transform",1]]
      rendered={"transform":[{"translateX":10},{"rotate":"5deg"}]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    box-shadow: var(--x) 1px red over --x: 4px
      dv=1 d=[[[{},"boxShadow",[[{},"var","x",1],1,"red"],1],"boxShadow",1]]
      rendered={"boxShadow":[{"offsetX":4,"offsetY":1,"color":"red"}]}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
  console.log
    width: var(--x) over --x: 4px
      dv=1 d=[[[{},"var","x",1],"width",1]]
      rendered={"width":4}
      at log (src/__tests__/native/list-variable.test.tsx:41:13)
PASS src/__tests__/native/list-variable.test.tsx
  √ transition-duration: 3s through var(--x), 2s from an ancestor (28 ms)
  √ transition-duration: 3s through var(--x) from an ancestor (6 ms)
  √ transition-delay: 3s through var(--x), 2s from an ancestor (2 ms)
  √ transition-timing-function: linear through var(--x), ease-in from an ancestor (1 ms)
  √ transition-property: width through var(--x), height from an ancestor (1 ms)
  √ animation-duration: 3s through var(--x), 2s from an ancestor (2 ms)
  √ margin: 4px through var(--x) 2px from an ancestor (2 ms)
  √ padding: 4px through var(--x) 2px from an ancestor (1 ms)
  √ border-width: 4px through var(--x) 2px from an ancestor (2 ms)
  √ font-family: Inter through var(--x), sans-serif from an ancestor (1 ms)
  √ transform: 10px through translateX(var(--x)) rotate(5deg) from an ancestor (2 ms)
  √ box-shadow: 4px through var(--x) 1px red from an ancestor (1 ms)
  √ width: 4px through var(--x) from an ancestor (3 ms)
Test Suites: 1 passed, 1 total
Tests:       13 passed, 13 total
Snapshots:   0 total
Time:        1.052 s, estimated 3 s
Ran all test suites matching /src\\__tests__\\native\\list-variable.test.tsx/i.
Reproducible example repository

https://github.com/YevheniiKotyrlo/react-native-css/tree/repro/527-list-value-loses-an-ancestors-variable

Langage dominant
TypeScript
Étoiles
166
Forks
45
Merge moyen
13 j 14 h
PR mergées (30 j)
1

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de nativewind/react-native-css

Toutes les issues de nativewind/react-native-css

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.