A value read through `var()` that the property can't take still applies: `border: var(--b)` over `--b: 1px, solid` draws a border, and `border-inline-width` over `red` keeps an earlier width

Abierto
#552 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 5 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
Medio día
Aptitud para principiantes
45/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
react-native, typescript
Área
frontend, mobile

Línea de trabajo

Start with the reproducer src/__tests__/native/comma-list-in-a-variable.test.tsx and run it to see the four logged cases. The comma-list case is in shorthandHandler in src/native/styles/shorthands/_handler.ts, which calls args.flat() before matching patterns. The refused-value case is in logicalWidth in src/native/styles/shorthands/logical-border-width.ts, which returns undefined where the keys should be unset. Done when the expected outputs hold on both the folded and inlineVariables: false routes; check the interaction with #547 before changing the list handling.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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

In CSS a var() whose value doesn't fit the property's grammar makes the declaration invalid at computed-value time (css-variables-1 §3): the property is unset, and an earlier rule's value for it no longer applies. The shorthand readers get both halves of that wrong, on the folded route and with inlineVariables: false alike:

  1. A comma list is read as a space list. border and border-inline-width have no comma in their grammar, yet border: var(--b) over --b: 1px, solid draws a 1px solid border, and border-inline-width: var(--w) over --w: 1px, 2px applies 1 and 2, as if the value were written 1px 2px.
  2. A refused value leaves the earlier one. border-inline-width: var(--w) and border-block-width: var(--w) over --w: red are refused, but an earlier rule's 5px stays, where the property should be unset.
folded .a { --b: 1px, solid; border: var(--b); }
   => {"borderWidth":1,"borderStyle":"solid"}
kept   .a { --b: 1px, solid; border: var(--b); }
   => {"borderWidth":1,"borderStyle":"solid"}
folded .earlier { border-inline-width: 5px; } .a { --w: 1px, 2px; border-inline-width: var(--w); }
   => {"borderStartWidth":1,"borderEndWidth":2}
kept   .earlier { border-inline-width: 5px; } .a { --w: 1px, 2px; border-inline-width: var(--w); }
   => {"borderStartWidth":1,"borderEndWidth":2}
folded .earlier { border-inline-width: 5px; } .a { --w: red; border-inline-width: var(--w); }
   => {"borderStartWidth":5,"borderEndWidth":5}
kept   .earlier { border-inline-width: 5px; } .a { --w: red; border-inline-width: var(--w); }
   => {"borderStartWidth":5,"borderEndWidth":5}
folded .earlier { border-block-width: 5px; } .a { --w: red; border-block-width: var(--w); }
   => {"borderTopWidth":5,"borderBottomWidth":5}
kept   .earlier { border-block-width: 5px; } .a { --w: red; border-block-width: var(--w); }
   => {"borderTopWidth":5,"borderBottomWidth":5}
  • shorthandHandler (src/native/styles/shorthands/_handler.ts) runs args = args.flat() on the resolved value before matching it against the shorthand's patterns, so a comma-separated list's items match as one space-separated list.
  • logicalWidth (src/native/styles/shorthands/logical-border-width.ts) returns undefined for a value that isn't one or two finite non-negative numbers, and undefined sets nothing, so the earlier rule's width stays; returning the two keys as null would unset them.

I've filed them together since they're the same rule failing in two readers that share one harness. #547 keeps a list's separator when it's read through a variable, so it makes case 1 a refusal for border-inline-width, which then lands in case 2.

Library version

main at a37903f (0.0.0-nightly.a37903f)

Environment info
Windows 11 10.0.26300, Node 26.12.1, Yarn 4.9.2, react-native 0.86.3 (the repository's dev dependency).
No app or native build is involved: the output comes from the repository's jest setup.
Steps to reproduce
  1. Clone the reproducer branch, which is main at a37903f with one file added, src/__tests__/native/comma-list-in-a-variable.test.tsx, and install:
    git clone --branch repro/552-comma-list-read-as-a-space-list https://github.com/YevheniiKotyrlo/react-native-css
    cd react-native-css
    yarn install
    
  2. Run yarn jest src/__tests__/native/comma-list-in-a-variable.test.tsx and read the logged lines.

src/__tests__/native/comma-list-in-a-variable.test.tsx:

import { StyleSheet } from "react-native";

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

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

test.each([
  ".a { --b: 1px, solid; border: var(--b); }",
  ".earlier { border-inline-width: 5px; } .a { --w: 1px, 2px; border-inline-width: var(--w); }",
  ".earlier { border-inline-width: 5px; } .a { --w: red; border-inline-width: var(--w); }",
  ".earlier { border-block-width: 5px; } .a { --w: red; border-block-width: var(--w); }",
])("%s", (css) => {
  for (const inlineVariables of [true, false]) {
    registerCSS(css, inlineVariables ? {} : { inlineVariables: false });
    render(<View testID={testID} className="earlier a" />);
    console.log(
      `${inlineVariables ? "folded" : "kept  "} ${css}\n   => ${JSON.stringify(StyleSheet.flatten(screen.getByTestId(testID).props.style))}`,
    );
    screen.unmount();
  }
});

Expected: border: var(--b) over 1px, solid draws no border; border-inline-width: var(--w) over 1px, 2px or red sets neither borderStartWidth nor borderEndWidth, so the earlier 5px no longer applies; the same for border-block-width.

Actual: the border is drawn 1px solid, 1px, 2px applies 1 and 2, and red leaves the earlier 5px.

The run's output on main at a37903f, Windows 11, Node 26.12.1
  console.log
    folded .a { --b: 1px, solid; border: var(--b); }
       => {"borderWidth":1,"borderStyle":"solid"}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    kept   .a { --b: 1px, solid; border: var(--b); }
       => {"borderWidth":1,"borderStyle":"solid"}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    folded .earlier { border-inline-width: 5px; } .a { --w: 1px, 2px; border-inline-width: var(--w); }
       => {"borderStartWidth":1,"borderEndWidth":2}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    kept   .earlier { border-inline-width: 5px; } .a { --w: 1px, 2px; border-inline-width: var(--w); }
       => {"borderStartWidth":1,"borderEndWidth":2}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    folded .earlier { border-inline-width: 5px; } .a { --w: red; border-inline-width: var(--w); }
       => {"borderStartWidth":5,"borderEndWidth":5}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    kept   .earlier { border-inline-width: 5px; } .a { --w: red; border-inline-width: var(--w); }
       => {"borderStartWidth":5,"borderEndWidth":5}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    folded .earlier { border-block-width: 5px; } .a { --w: red; border-block-width: var(--w); }
       => {"borderTopWidth":5,"borderBottomWidth":5}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

  console.log
    kept   .earlier { border-block-width: 5px; } .a { --w: red; border-block-width: var(--w); }
       => {"borderTopWidth":5,"borderBottomWidth":5}

      at log (src/__tests__/native/comma-list-in-a-variable.test.tsx:20:13)

PASS src/__tests__/native/comma-list-in-a-variable.test.tsx
  √ .a { --b: 1px, solid; border: var(--b); } (31 ms)
  √ .earlier { border-inline-width: 5px; } .a { --w: 1px, 2px; border-inline-width: var(--w); } (5 ms)
  √ .earlier { border-inline-width: 5px; } .a { --w: red; border-inline-width: var(--w); } (3 ms)
  √ .earlier { border-block-width: 5px; } .a { --w: red; border-block-width: var(--w); } (2 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.684 s, estimated 2 s
Ran all test suites matching /src\\__tests__\\native\\comma-list-in-a-variable.test.tsx/i.
Reproducible example repository

https://github.com/YevheniiKotyrlo/react-native-css/tree/repro/552-comma-list-read-as-a-space-list

Lenguaje dominante
TypeScript
Estrellas
166
Forks
45
Merge medio
10 d 1 h
PR fusionados (30 d)
4

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de nativewind/react-native-css

Todos los issues de nativewind/react-native-css

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.