mirror of
https://github.com/zhigang1992/nativewind.git
synced 2026-06-15 10:17:54 +08:00
fix: tw getComputedStyle
This commit is contained in:
@@ -9,12 +9,14 @@ const useWindowDimensions = RNuseWindowDimensions as jest.Mock<
|
||||
>;
|
||||
|
||||
jest.mock("react-native", () => {
|
||||
const { Appearance, Dimensions } = jest.requireActual("react-native");
|
||||
const { Appearance, Dimensions, StyleSheet } =
|
||||
jest.requireActual("react-native");
|
||||
|
||||
return {
|
||||
__esModule: true,
|
||||
Appearance,
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
useWindowDimensions: jest.fn(() => ({
|
||||
width: 0,
|
||||
height: 0,
|
||||
@@ -73,6 +75,25 @@ describe("native", () => {
|
||||
expect(result.current).toEqual([{ fontWeight: "700" }]);
|
||||
});
|
||||
|
||||
test("can flatten properties", () => {
|
||||
const { result } = renderHook(() => useTailwind()("font-bold"), {
|
||||
wrapper,
|
||||
initialProps: {
|
||||
platform: "native",
|
||||
styles: {
|
||||
"font-bold": {
|
||||
fontWeight: "700",
|
||||
},
|
||||
"font-extrabold": {
|
||||
fontWeight: "800",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.current.fontWeight).toEqual("700");
|
||||
});
|
||||
|
||||
test("media - width", () => {
|
||||
useWindowDimensions.mockReturnValue({
|
||||
width: 1000,
|
||||
|
||||
37
__tests__/use-tailwind.web-preview.tsx
Normal file
37
__tests__/use-tailwind.web-preview.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PropsWithChildren } from "react";
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { useTailwind } from "../src/use-tailwind.web";
|
||||
import { TailwindProvider, TailwindProviderProps } from "../src/provider";
|
||||
import { RWNCssStyle } from "../src/use-tailwind";
|
||||
|
||||
const wrapper = ({
|
||||
children,
|
||||
...props
|
||||
}: PropsWithChildren<TailwindProviderProps>) => (
|
||||
<TailwindProvider {...props}>{children}</TailwindProvider>
|
||||
);
|
||||
|
||||
describe("web", () => {
|
||||
test("can accept no arguments", () => {
|
||||
const { result } = renderHook(() => useTailwind<RWNCssStyle>()(), {
|
||||
wrapper,
|
||||
initialProps: { platform: "web", preview: true },
|
||||
});
|
||||
|
||||
expect(result.current.$$css).toBe(true);
|
||||
expect(result.current.tailwindClassName).toBe("");
|
||||
});
|
||||
|
||||
test("will pass-through any arguments", () => {
|
||||
const { result } = renderHook(
|
||||
() => useTailwind<RWNCssStyle>()("hello-world"),
|
||||
{
|
||||
wrapper,
|
||||
initialProps: { platform: "web", preview: true },
|
||||
}
|
||||
);
|
||||
|
||||
expect(result.current.$$css).toBe(true);
|
||||
expect(result.current.tailwindClassName).toBe("hello-world");
|
||||
});
|
||||
});
|
||||
@@ -1,8 +1,15 @@
|
||||
import {
|
||||
TextStyle,
|
||||
useWindowDimensions as RNuseWindowDimensions,
|
||||
} from "react-native";
|
||||
import { PropsWithChildren } from "react";
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { useTailwind } from "../src/use-tailwind.web";
|
||||
import { TailwindProvider, TailwindProviderProps } from "../src/provider";
|
||||
import { RWNCssStyle } from "../src/use-tailwind";
|
||||
|
||||
const useWindowDimensions = RNuseWindowDimensions as jest.Mock<
|
||||
Partial<ReturnType<typeof RNuseWindowDimensions>>
|
||||
>;
|
||||
|
||||
const wrapper = ({
|
||||
children,
|
||||
@@ -11,27 +18,134 @@ const wrapper = ({
|
||||
<TailwindProvider {...props}>{children}</TailwindProvider>
|
||||
);
|
||||
|
||||
jest.mock("react-native", () => {
|
||||
/**
|
||||
* Run this test with react-native-web instead of react-native
|
||||
*/
|
||||
const { Appearance, Dimensions, StyleSheet, Platform } =
|
||||
jest.requireActual("react-native-web");
|
||||
|
||||
return {
|
||||
__esModule: true,
|
||||
Appearance,
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
useWindowDimensions: jest.fn(() => ({
|
||||
width: 0,
|
||||
height: 0,
|
||||
scale: 1,
|
||||
fontScale: 1,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("web", () => {
|
||||
test("can accept no arguments", () => {
|
||||
const { result } = renderHook(() => useTailwind<RWNCssStyle>()(), {
|
||||
const { result } = renderHook(() => useTailwind()(), {
|
||||
wrapper,
|
||||
initialProps: { platform: "web", preview: true },
|
||||
initialProps: { platform: "native" },
|
||||
});
|
||||
|
||||
expect(result.current.$$css).toBe(true);
|
||||
expect(result.current.tailwindClassName).toBe("");
|
||||
expect(result.current).toEqual([]);
|
||||
});
|
||||
|
||||
test("will pass-through any arguments", () => {
|
||||
const { result } = renderHook(
|
||||
() => useTailwind<RWNCssStyle>()("hello-world"),
|
||||
{
|
||||
wrapper,
|
||||
initialProps: { platform: "web", preview: true },
|
||||
}
|
||||
);
|
||||
test("will return nothing is no styles match", () => {
|
||||
const { result } = renderHook(() => useTailwind()("hello-world"), {
|
||||
wrapper,
|
||||
initialProps: { platform: "native" },
|
||||
});
|
||||
|
||||
expect(result.current.$$css).toBe(true);
|
||||
expect(result.current.tailwindClassName).toBe("hello-world");
|
||||
expect(result.current).toEqual([]);
|
||||
});
|
||||
|
||||
test("will return matched styles", () => {
|
||||
const { result } = renderHook(() => useTailwind()("font-bold"), {
|
||||
wrapper,
|
||||
initialProps: {
|
||||
platform: "native",
|
||||
styles: {
|
||||
"font-bold": {
|
||||
fontWeight: "700",
|
||||
},
|
||||
"font-extrabold": {
|
||||
fontWeight: "800",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.current).toEqual([{ fontWeight: "700" }]);
|
||||
});
|
||||
|
||||
test("can flatten properties", () => {
|
||||
const { result } = renderHook(() => useTailwind<TextStyle>()("font-bold"), {
|
||||
wrapper,
|
||||
initialProps: {
|
||||
platform: "native",
|
||||
styles: {
|
||||
"font-bold": {
|
||||
fontWeight: "700",
|
||||
},
|
||||
"font-extrabold": {
|
||||
fontWeight: "800",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.current.fontWeight).toEqual("700");
|
||||
});
|
||||
|
||||
test("media - width", () => {
|
||||
useWindowDimensions.mockReturnValue({
|
||||
width: 1000,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTailwind()("container"), {
|
||||
wrapper,
|
||||
initialProps: {
|
||||
platform: "native",
|
||||
styles: {
|
||||
container: {
|
||||
width: "100%",
|
||||
},
|
||||
"container.0": {
|
||||
maxWidth: 640,
|
||||
},
|
||||
"container.1": {
|
||||
maxWidth: 768,
|
||||
},
|
||||
"container.2": {
|
||||
maxWidth: 1024,
|
||||
},
|
||||
"container.3": {
|
||||
maxWidth: 1280,
|
||||
},
|
||||
"container.4": {
|
||||
maxWidth: 1536,
|
||||
},
|
||||
},
|
||||
media: {
|
||||
container: [
|
||||
"(min-width: 640px)",
|
||||
"(min-width: 768px)",
|
||||
"(min-width: 1024px)",
|
||||
"(min-width: 1280px)",
|
||||
"(min-width: 1536px)",
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.current).toEqual([
|
||||
{ width: "100%" },
|
||||
{ maxWidth: 640 },
|
||||
{ maxWidth: 768 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
1670
package-lock.json
generated
1670
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -79,11 +79,14 @@
|
||||
"eslint-plugin-unicorn": "42.0.0",
|
||||
"husky": "7.0.4",
|
||||
"jest": "28.1.0",
|
||||
"jest-environment-jsdom": "^28.1.0",
|
||||
"metro-react-native-babel-preset": "0.70.3",
|
||||
"moti": "0.17.1",
|
||||
"prettier": "2.6.2",
|
||||
"react": "18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"react-native": "0.68.1",
|
||||
"react-native-web": "^0.17.7",
|
||||
"react-test-renderer": "18.1.0",
|
||||
"tailwindcss": "3.0.24",
|
||||
"ts-jest": "28.0.2",
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useWindowDimensions, StyleProp } from "react-native";
|
||||
import {
|
||||
useWindowDimensions,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
TextStyle,
|
||||
} from "react-native";
|
||||
import { useContext } from "react";
|
||||
|
||||
import { useDeviceOrientation } from "@react-native-community/hooks";
|
||||
@@ -13,6 +18,8 @@ import {
|
||||
TailwindStyleContext,
|
||||
} from "./context";
|
||||
|
||||
const computedStyles = new WeakMap();
|
||||
|
||||
export function useTailwind<P>({ siblingClassName = "" } = {}) {
|
||||
const platform = useContext(TailwindPlatformContext);
|
||||
const styles = useContext(TailwindStyleContext);
|
||||
@@ -63,6 +70,23 @@ export function useTailwind<P>({ siblingClassName = "" } = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
return tailwindStyleIds;
|
||||
const proxy = new Proxy(tailwindStyleIds, {
|
||||
get(target, property: string | number | symbol) {
|
||||
if (property in tailwindStyleIds) {
|
||||
return tailwindStyleIds[property as keyof typeof tailwindStyleIds];
|
||||
}
|
||||
|
||||
if (!computedStyles.has(tailwindStyleIds)) {
|
||||
computedStyles.set(
|
||||
tailwindStyleIds,
|
||||
StyleSheet.flatten(tailwindStyleIds)
|
||||
);
|
||||
}
|
||||
|
||||
return computedStyles.get(target)[property];
|
||||
},
|
||||
});
|
||||
|
||||
return proxy as StyleProp<P> & TextStyle;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user