Skip to content

Commit 2921182

Browse files
authored
feat: handle CSS infinity keyword (#60)
1 parent 42cfef6 commit 2921182

File tree

2 files changed

+146
-123
lines changed

2 files changed

+146
-123
lines changed

src/compiler/declarations.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,8 +1157,15 @@ export function parseLength(
11571157

11581158
if ("unit" in length) {
11591159
switch (length.unit) {
1160-
case "px":
1161-
return length.value;
1160+
case "px": {
1161+
if (length.value === Infinity) {
1162+
return 9999;
1163+
} else if (length.value === -Infinity) {
1164+
return -9999;
1165+
} else {
1166+
return length.value;
1167+
}
1168+
}
11621169
case "rem":
11631170
if (typeof inlineRem === "number") {
11641171
return length.value * inlineRem;
@@ -2222,7 +2229,11 @@ export function parseDimension(
22222229
): StyleDescriptor {
22232230
switch (unit) {
22242231
case "px":
2225-
return value;
2232+
if (value === Infinity) {
2233+
return 9999;
2234+
} else {
2235+
return value;
2236+
}
22262237
case "%":
22272238
return `${value}%`;
22282239
case "rnh":

src/runtime/native/__tests__/calc.test.tsx

Lines changed: 132 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -2,167 +2,165 @@ import { render, screen } from "@testing-library/react-native";
22
import { View } from "react-native-css/components/View";
33
import { registerCSS, testID } from "react-native-css/jest";
44

5-
describe("css", () => {
6-
test("calc(10px + 100px)", () => {
7-
registerCSS(
8-
`.my-class {
5+
test("calc(10px + 100px)", () => {
6+
registerCSS(
7+
`.my-class {
98
width: calc(10px + 100px);
109
}`,
11-
);
12-
13-
render(<View testID={testID} className="my-class" />);
14-
const component = screen.getByTestId(testID);
15-
16-
expect(component.type).toBe("View");
17-
expect(component.props).toStrictEqual({
18-
children: undefined,
19-
style: {
20-
width: 110,
21-
},
22-
testID,
23-
});
10+
);
11+
12+
render(<View testID={testID} className="my-class" />);
13+
const component = screen.getByTestId(testID);
14+
15+
expect(component.type).toBe("View");
16+
expect(component.props).toStrictEqual({
17+
children: undefined,
18+
style: {
19+
width: 110,
20+
},
21+
testID,
2422
});
23+
});
2524

26-
test("calc(100% - 30px)", () => {
27-
registerCSS(
28-
`.my-class {
25+
test("calc(100% - 30px)", () => {
26+
registerCSS(
27+
`.my-class {
2928
width: calc(100% - 30px);
3029
}`,
31-
);
30+
);
3231

33-
render(<View testID={testID} className="my-class" />);
34-
const component = screen.getByTestId(testID);
32+
render(<View testID={testID} className="my-class" />);
33+
const component = screen.getByTestId(testID);
3534

36-
// React Native does not support calc() with a percentage value, so there should be no style
37-
expect(component.type).toBe("View");
38-
expect(component.props).toStrictEqual({
39-
children: undefined,
40-
testID,
41-
});
35+
// React Native does not support calc() with a percentage value, so there should be no style
36+
expect(component.type).toBe("View");
37+
expect(component.props).toStrictEqual({
38+
children: undefined,
39+
testID,
4240
});
41+
});
4342

44-
test("calc(2em * 3)", () => {
45-
registerCSS(
46-
`.my-class {
43+
test("calc(2em * 3)", () => {
44+
registerCSS(
45+
`.my-class {
4746
width: calc(2em * 2);
4847
font-size: 5px
4948
}`,
50-
);
51-
52-
render(<View testID={testID} className="my-class" />);
53-
const component = screen.getByTestId(testID);
54-
55-
expect(component.type).toBe("View");
56-
expect(component.props).toStrictEqual({
57-
children: undefined,
58-
style: {
59-
width: 20,
60-
fontSize: 5,
61-
},
62-
testID,
63-
});
49+
);
50+
51+
render(<View testID={testID} className="my-class" />);
52+
const component = screen.getByTestId(testID);
53+
54+
expect(component.type).toBe("View");
55+
expect(component.props).toStrictEqual({
56+
children: undefined,
57+
style: {
58+
width: 20,
59+
fontSize: 5,
60+
},
61+
testID,
6462
});
63+
});
6564

66-
test("calc(2rem * 5)", () => {
67-
registerCSS(
68-
`.my-class {
65+
test("calc(2rem * 5)", () => {
66+
registerCSS(
67+
`.my-class {
6968
width: calc(2rem * 5)
7069
}`,
71-
);
72-
73-
render(<View testID={testID} className="my-class" />);
74-
const component = screen.getByTestId(testID);
75-
76-
expect(component.type).toBe("View");
77-
expect(component.props).toStrictEqual({
78-
children: undefined,
79-
style: {
80-
width: 140,
81-
},
82-
testID,
83-
});
70+
);
71+
72+
render(<View testID={testID} className="my-class" />);
73+
const component = screen.getByTestId(testID);
74+
75+
expect(component.type).toBe("View");
76+
expect(component.props).toStrictEqual({
77+
children: undefined,
78+
style: {
79+
width: 140,
80+
},
81+
testID,
8482
});
83+
});
8584

86-
test("calc(var(--variable) + 20px)", () => {
87-
registerCSS(
88-
`.my-class {
85+
test("calc(var(--variable) + 20px)", () => {
86+
registerCSS(
87+
`.my-class {
8988
--my-var: 100px;
9089
width: calc(var(--my-var) + 20px)
9190
}`,
92-
);
93-
94-
render(<View testID={testID} className="my-class" />);
95-
const component = screen.getByTestId(testID);
96-
97-
expect(component.type).toBe("View");
98-
expect(component.props).toStrictEqual({
99-
children: undefined,
100-
style: {
101-
width: 120,
102-
},
103-
testID,
104-
});
91+
);
92+
93+
render(<View testID={testID} className="my-class" />);
94+
const component = screen.getByTestId(testID);
95+
96+
expect(component.type).toBe("View");
97+
expect(component.props).toStrictEqual({
98+
children: undefined,
99+
style: {
100+
width: 120,
101+
},
102+
testID,
105103
});
104+
});
106105

107-
test("calc(var(--percent) + 20%)", () => {
108-
registerCSS(
109-
`.my-class {
106+
test("calc(var(--percent) + 20%)", () => {
107+
registerCSS(
108+
`.my-class {
110109
--percent: 10%;
111110
width: calc(var(--percent) + 20%)
112111
}`,
113-
);
114-
115-
render(<View testID={testID} className="my-class" />);
116-
const component = screen.getByTestId(testID);
117-
118-
expect(component.type).toBe("View");
119-
expect(component.props).toStrictEqual({
120-
children: undefined,
121-
style: {
122-
width: "30%",
123-
},
124-
testID,
125-
});
112+
);
113+
114+
render(<View testID={testID} className="my-class" />);
115+
const component = screen.getByTestId(testID);
116+
117+
expect(component.type).toBe("View");
118+
expect(component.props).toStrictEqual({
119+
children: undefined,
120+
style: {
121+
width: "30%",
122+
},
123+
testID,
126124
});
125+
});
127126

128-
test("calc(var(--variable) + 20%)", () => {
129-
// React Native does not support calc() with a percentage value and a non-percentage unit, so this should be `undefined`
130-
registerCSS(
131-
`.my-class {
127+
test("calc(var(--variable) + 20%)", () => {
128+
// React Native does not support calc() with a percentage value and a non-percentage unit, so this should be `undefined`
129+
registerCSS(
130+
`.my-class {
132131
--variable: 100px;
133132
width: calc(var(--variable) + 20%)
134133
}`,
135-
);
134+
);
136135

137-
render(<View testID={testID} className="my-class" />);
138-
const component = screen.getByTestId(testID);
136+
render(<View testID={testID} className="my-class" />);
137+
const component = screen.getByTestId(testID);
139138

140-
expect(component.type).toBe("View");
141-
expect(component.props).toStrictEqual({
142-
children: undefined,
143-
style: {},
144-
testID,
145-
});
139+
expect(component.type).toBe("View");
140+
expect(component.props).toStrictEqual({
141+
children: undefined,
142+
style: {},
143+
testID,
146144
});
145+
});
147146

148-
test("calc(var(--percent) + 20px)", () => {
149-
// React Native does not support calc() with a percentage value and a non-percentage unit, so this should be `undefined`
150-
registerCSS(
151-
`.my-class {
147+
test("calc(var(--percent) + 20px)", () => {
148+
// React Native does not support calc() with a percentage value and a non-percentage unit, so this should be `undefined`
149+
registerCSS(
150+
`.my-class {
152151
--percent: 10%;
153152
width: calc(var(--percent) + 20px)
154153
}`,
155-
);
154+
);
156155

157-
render(<View testID={testID} className="my-class" />);
158-
const component = screen.getByTestId(testID);
156+
render(<View testID={testID} className="my-class" />);
157+
const component = screen.getByTestId(testID);
159158

160-
expect(component.type).toBe("View");
161-
expect(component.props).toStrictEqual({
162-
children: undefined,
163-
style: {},
164-
testID,
165-
});
159+
expect(component.type).toBe("View");
160+
expect(component.props).toStrictEqual({
161+
children: undefined,
162+
style: {},
163+
testID,
166164
});
167165
});
168166

@@ -192,3 +190,17 @@ test("calc & colors", () => {
192190
testID,
193191
});
194192
});
193+
194+
test("infinity", () => {
195+
registerCSS(`.my-class {
196+
border-radius: calc(infinity * 1px);
197+
}`);
198+
199+
render(<View testID={testID} className="my-class" />);
200+
const component = screen.getByTestId(testID);
201+
202+
expect(component.type).toBe("View");
203+
expect(component.props.style).toStrictEqual({
204+
borderRadius: 9999,
205+
});
206+
});

0 commit comments

Comments
 (0)