Skip to content

Commit 2b677a4

Browse files
authored
Merge pull request #359 from Pedrozxcv/undefined-react-native-version
Fix Platform.constants.reactNativeVersion issue related with react-native-web
2 parents 5a91810 + e98f67a commit 2b677a4

File tree

6 files changed

+77
-33
lines changed

6 files changed

+77
-33
lines changed

src/UtilityParser.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { TwConfig } from './tw-config';
2-
import type { StyleIR, DeviceContext, ParseContext, Platform, Version } from './types';
2+
import type { StyleIR, DeviceContext, ParseContext, Version } from './types';
33
import type Cache from './cache';
44
import fontSize from './resolve/font-size';
55
import lineHeight from './resolve/line-height';
@@ -40,7 +40,6 @@ export default class UtilityParser {
4040
private config: TwConfig = {},
4141
private cache: Cache,
4242
device: DeviceContext,
43-
platform: Platform,
4443
reactNativeVersion: Version,
4544
) {
4645
this.context.device = device;
@@ -54,7 +53,7 @@ export default class UtilityParser {
5453
prefixes = parts;
5554
}
5655
this.char = this.string[0];
57-
this.parsePrefixes(prefixes, device, platform);
56+
this.parsePrefixes(prefixes, device);
5857
}
5958

6059
public parse(): StyleIR {
@@ -404,11 +403,7 @@ export default class UtilityParser {
404403
return false;
405404
}
406405

407-
private parsePrefixes(
408-
prefixes: string[],
409-
device: DeviceContext,
410-
platform: Platform,
411-
): void {
406+
private parsePrefixes(prefixes: string[], device: DeviceContext): void {
412407
const widthBreakpoints = screens(this.config.theme?.screens);
413408

414409
// loop through the prefixes ONE time, extracting useful info
@@ -429,7 +424,7 @@ export default class UtilityParser {
429424
this.isNull = true;
430425
}
431426
} else if (isPlatform(prefix)) {
432-
this.isNull = prefix !== platform;
427+
this.isNull = prefix !== device.platform;
433428
} else if (isOrientation(prefix)) {
434429
if (!device.windowDimensions) {
435430
this.isNull = true;

src/__tests__/transform.spec.ts

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import rn from 'react-native';
1+
import { Platform } from 'react-native';
22
import { create } from '../';
33

44
describe(`transform utilities`, () => {
@@ -243,11 +243,9 @@ describe(`transform utilities`, () => {
243243
});
244244

245245
test(`translate w/percentage values`, () => {
246-
rn.Platform.constants.reactNativeVersion = {
247-
major: 0,
248-
minor: 75,
249-
patch: 0,
250-
};
246+
Platform.OS = `web`;
247+
jest.spyOn(Platform, `constants`, `get`).mockReturnValue(undefined as any);
248+
tw = create();
251249

252250
expect(tw.style(`translate-x-full`)).toMatchObject({
253251
transform: [{ translateX: `100%` }],
@@ -274,11 +272,51 @@ describe(`transform utilities`, () => {
274272
transform: [{ translateY: `20%` }],
275273
});
276274

277-
rn.Platform.constants.reactNativeVersion = {
278-
major: 0,
279-
minor: 74,
280-
patch: 0,
281-
};
275+
Platform.OS = `ios`;
276+
jest.spyOn(Platform, `constants`, `get`).mockReturnValue({
277+
...Platform.constants,
278+
reactNativeVersion: {
279+
major: 0,
280+
minor: 75,
281+
patch: 0,
282+
},
283+
});
284+
tw = create();
285+
286+
expect(tw.style(`translate-x-full`)).toMatchObject({
287+
transform: [{ translateX: `100%` }],
288+
});
289+
expect(tw.style(`translate-y-full`)).toMatchObject({
290+
transform: [{ translateY: `100%` }],
291+
});
292+
expect(tw.style(`translate-x-1/2`)).toMatchObject({
293+
transform: [{ translateX: `50%` }],
294+
});
295+
expect(tw.style(`translate-y-1/2`)).toMatchObject({
296+
transform: [{ translateY: `50%` }],
297+
});
298+
expect(tw.style(`translate-x-[10%]`)).toMatchObject({
299+
transform: [{ translateX: `10%` }],
300+
});
301+
expect(tw.style(`translate-y-[10%]`)).toMatchObject({
302+
transform: [{ translateY: `10%` }],
303+
});
304+
expect(tw.style(`translate-x-1/5`)).toMatchObject({
305+
transform: [{ translateX: `20%` }],
306+
});
307+
expect(tw.style(`translate-y-1/5`)).toMatchObject({
308+
transform: [{ translateY: `20%` }],
309+
});
310+
311+
jest.spyOn(Platform, `constants`, `get`).mockReturnValue({
312+
...Platform.constants,
313+
reactNativeVersion: {
314+
major: 0,
315+
minor: 74,
316+
patch: 0,
317+
},
318+
});
319+
tw = create();
282320

283321
expect(tw.style(`translate-x-full`)).toMatchObject({});
284322
expect(tw.style(`translate-y-full`)).toMatchObject({});

src/create.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ export function create(
2525
reactNativeVersion: Version,
2626
): TailwindFn {
2727
const config = resolveConfig(withContent(customConfig) as any) as TwConfig;
28-
const device: DeviceContext = {};
28+
const device: DeviceContext = {
29+
platform,
30+
};
2931

3032
const pluginUtils = getAddedUtilities(config.plugins);
3133
const customStringUtils: Record<string, string> = {};
@@ -110,7 +112,6 @@ export function create(
110112
config,
111113
cache,
112114
device,
113-
platform,
114115
reactNativeVersion,
115116
);
116117
styleIr = parser.parse();
@@ -201,7 +202,6 @@ export function create(
201202
config,
202203
cache,
203204
device,
204-
platform,
205205
reactNativeVersion,
206206
);
207207
const ir = parser.parse();

src/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@ import plugin from './plugin';
55
import rawCreate from './create';
66

77
// Apply default config and inject RN Platform and RN version
8-
const create = (twConfig: TwConfig = {}): TailwindFn =>
9-
rawCreate(twConfig, Platform.OS, Platform.constants.reactNativeVersion);
8+
const create = (twConfig: TwConfig = {}): TailwindFn => {
9+
return rawCreate(
10+
twConfig,
11+
Platform.OS,
12+
// react-native-web does not expose a constants object
13+
// @see https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/Platform/index.js
14+
Platform.constants?.reactNativeVersion,
15+
);
16+
};
1017

1118
export type { TailwindFn, TwConfig, RnColorScheme, ClassInput, Style };
1219
export { useDeviceContext, useAppColorScheme } from './hooks';

src/resolve/transform.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ export function translate(
133133
if (
134134
styleVal === null ||
135135
(isString(styleVal) &&
136-
context.reactNativeVersion &&
137-
context.reactNativeVersion.major === 0 &&
138-
context.reactNativeVersion.minor < 75)
136+
context.device?.platform !== `web` &&
137+
(!context.reactNativeVersion ||
138+
(context.reactNativeVersion.major === 0 &&
139+
context.reactNativeVersion.minor < 75)))
139140
) {
140141
return null;
141142
}

src/types.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export interface DeviceContext {
7575
colorScheme?: 'light' | 'dark' | null;
7676
fontScale?: number;
7777
pixelDensity?: 1 | 2;
78+
platform?: Platform;
7879
}
7980

8081
export interface ParseContext {
@@ -232,8 +233,10 @@ export function isObject(value: unknown): value is Record<string, unknown> {
232233
return typeof value === `object`;
233234
}
234235

235-
export type Version = {
236-
major: number;
237-
minor: number;
238-
patch: number;
239-
};
236+
export type Version =
237+
| {
238+
major: number;
239+
minor: number;
240+
patch: number;
241+
}
242+
| undefined;

0 commit comments

Comments
 (0)