diff --git a/src/classname-to-inline-style.ts b/src/classname-to-inline-style.ts index 3ba0802..35ece3b 100644 --- a/src/classname-to-inline-style.ts +++ b/src/classname-to-inline-style.ts @@ -1,3 +1,5 @@ +import { UseTailwindOptions } from "./use-tailwind"; + const cacheKey = Symbol("tailwind-cache-key"); let stylesheet: CSSStyleSheet & { @@ -12,13 +14,16 @@ let stylesheet: CSSStyleSheet & { * This hasn't been benched-marked, but is assumed to be slow and unreliable. * This is why we recommend people avoid using useTailwind()/spreadProps for runtime values. */ -export function classNameToInlineStyle(className: string) { +export function classNameToInlineStyle( + className: string, + options: UseTailwindOptions = {} +) { if (!stylesheet) findStyleSheet(className); const styles = {}; for (const name of className.split(/\s+/)) { if (!name) continue; - Object.assign(styles, getStyles(name)); + Object.assign(styles, getStyles(CSS.escape(name), options)); } return styles; @@ -28,8 +33,9 @@ export function classNameToInlineStyle(className: string) { * Finds a stylesheet that includes this css selector */ function findStyleSheet(className: string) { - const firstClassName = className.split(/\s+/).find(Boolean); if (stylesheet) return stylesheet; + + const firstClassName = className.split(/\s+/).find(Boolean) as string; const maybeStyleSheet = [ ...(document.styleSheets as unknown as CSSStyleSheet[]), ].find((stylesheet) => { @@ -37,7 +43,7 @@ function findStyleSheet(className: string) { (cssRule) => { return ( isCSSStyleRule(cssRule) && - cssRule.selectorText.includes(`.${firstClassName}`) + cssRule.selectorText.includes(`.${CSS.escape(firstClassName)}`) ); } ); @@ -48,27 +54,45 @@ function findStyleSheet(className: string) { } } -function getStyles(className: string) { - if (stylesheet[cacheKey][className]) { - return stylesheet[cacheKey][className]; +function getStyles( + className: string, + { active, focus, hover }: UseTailwindOptions +) { + const classNameCacheKey = `${className}:${active}:${focus}:${hover}`; + + if (stylesheet[cacheKey][classNameCacheKey]) { + return stylesheet[cacheKey][classNameCacheKey]; } const rule = [ ...(stylesheet.cssRules as unknown as CSSRule[]), ].find((cssRule): cssRule is CSSStyleRule => { - return ( - isCSSStyleRule(cssRule) && cssRule.selectorText.includes(`.${className}`) - ); + if ( + isCSSStyleRule(cssRule) && + cssRule.selectorText.includes(`.${className}`) + ) { + const states = []; + + // We cannot just test for `:active` as it will match hover\\:active-foobar:hover + // Due to how classNames are escaped, we can just check for :active and ensure + // it doesn't have an escape character before it. + if (/(? = {} ) => { return flatten - ? classNameToInlineStyle(className) + ? classNameToInlineStyle(className, useTailwindOptions) : { $$css: true, tailwindClassName: className }; }) as UseTailwindCallback

; }