diff --git a/src/use-tailwind.native.ts b/src/use-tailwind.native.ts index 509ebd6..a5a9774 100644 --- a/src/use-tailwind.native.ts +++ b/src/use-tailwind.native.ts @@ -26,8 +26,6 @@ import { UseTailwindOptions, } from "./use-tailwind"; -const computedStyles = new WeakMap(); - export function useTailwind
( options?: UseTailwindOptions ): UseTailwindCallback
; @@ -90,20 +88,16 @@ export function useTailwind
({ siblingClassName = "" } = {}) { } } + let computedStyles: P; + const proxy = new Proxy(tailwindStyleIds, { - get(target, property: string | number | symbol) { + get(_, 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]; + computedStyles ??= StyleSheet.flatten(tailwindStyleIds) as P; + return computedStyles[property as keyof P]; }, }); diff --git a/src/use-tailwind.web.ts b/src/use-tailwind.web.ts index c74cded..ed822b8 100644 --- a/src/use-tailwind.web.ts +++ b/src/use-tailwind.web.ts @@ -1,5 +1,5 @@ import { useContext } from "react"; -import { ImageStyle, StyleProp, TextStyle, ViewStyle } from "react-native"; +import { ImageStyle, TextStyle, ViewStyle } from "react-native"; import { TailwindPlatformContext, TailwindPreviewContext } from "./context"; import { RWNCssStyle, @@ -9,6 +9,8 @@ import { import { useTailwind as useNativeTailwind } from "./use-tailwind.native"; +let element: HTMLElement; + export function useTailwind
( options?: UseTailwindOptions ): UseTailwindCallback
; @@ -33,12 +35,51 @@ export function useTailwind
(options?: UseTailwindOptions) { if (platform === "web" && preview) { return (className = "") => { - return { + const style: RWNCssStyle = { $$css: true, tailwindClassName: className, - } as unknown as StyleProp
; + }; + + let computedStyles: CSSStyleDeclaration; + + return new Proxy(style, { + get(_, property: string | number | symbol) { + if (property in style) { + return style[property as keyof RWNCssStyle]; + } + + computedStyles ??= getComputedStyle(className); + + return computedStyles[property as keyof CSSStyleDeclaration]; + }, + }); }; } return useNativeTailwind
(options); } + +function getComputedStyle(className = ""): CSSStyleDeclaration { + if (typeof window !== "undefined") { + if (!element) { + element = document.createElement("tailwindcss-react-native"); // Use custom element to avoid styles + element.setAttribute("aria-hidden", "true"); + element.style.position = "absolute"; + element.style.width = "1px"; + element.style.height = "1px"; + element.style.padding = "0"; + element.style.margin = "-1px"; + element.style.overflow = "hidden"; + element.style.whiteSpace = "nowrap"; + element.style.borderWidth = "0"; + document.body.append(element); + } + + const newElement = document.createElement("tailwindcss-react-native"); // Use custom element to avoid styles + newElement.setAttribute("class", className); + element.append(newElement); + return { ...window.getComputedStyle(newElement) }; + } else { + return {} as CSSStyleDeclaration; + } +}