Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#527 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 3 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
56/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
react-native, typescript
Ambito
frontend

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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

Lingua principale
TypeScript
Stelle
166
Fork
45
Merge medio
13g 14h
PR unite (30g)
1

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di nativewind/react-native-css

Tutte le issue di nativewind/react-native-css

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.