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

Đang mở
#552 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 5 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
Nửa ngày
Mức phù hợp với người mới
45/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
react-native, typescript
Lĩnh vực
frontend, mobile

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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

Ngôn ngữ chính
TypeScript
Star
166
Fork
45
Merge trung bình
10 ngày 1 giờ
Pull request đã merge (30 ngày)
4

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của nativewind/react-native-css

Tất cả issue của nativewind/react-native-css

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.