diff --git a/dist/common/bundler/css-processor/processor.js b/dist/common/bundler/css-processor/processor.jsindex 7dd369fa3197dbd622832c89ac3854c401e55c3e..ab3ea1a9520907321f9c21c2a3a859262fe5075b 100644--- a/dist/common/bundler/css-processor/processor.js+++ b/dist/common/bundler/css-processor/processor.js@@ -105,6 +105,64 @@ class ProcessorBuilder { style.importantProperties.push(declaration.property); } }+ readSelectorVariants(tokens) {+ const variants = {+ rtl: null,+ theme: null,+ active: null,+ focus: null,+ disabled: null,+ dataAttributes: null+ };+ tokens.forEach((token) => {+ if (token.type === "pseudo-class" && token.kind === "where") {+ token.selectors.forEach((compound) => {+ compound.forEach((inner) => {+ if (inner.type === "class" && this.bundlerConfig.themes.includes(inner.name)) {+ variants.theme = inner.name;+ }+ if (inner.type === "pseudo-class" && inner.kind === "dir") {+ variants.rtl = inner.direction === "rtl";+ }+ });+ });+ }+ if (token.type === "pseudo-class" && token.kind === "active") {+ variants.active = true;+ }+ if (token.type === "pseudo-class" && token.kind === "focus") {+ variants.focus = true;+ }+ if (token.type === "pseudo-class" && token.kind === "disabled") {+ variants.disabled = true;+ }+ if (token.type === "attribute" && token.operation === null && token.name.startsWith("data-")) {+ variants.dataAttributes ??= {};+ variants.dataAttributes[token.name] = `"true"`;+ }+ if (token.type === "attribute" && token.operation?.operator === "equal" && token.name.startsWith("data-")) {+ variants.dataAttributes ??= {};+ variants.dataAttributes[token.name] = `"${token.operation.value}"`;+ }+ });+ const hasVariants = Object.values(variants).some(_utils.isDefined);+ return { variants, hasVariants };+ }+ withSelectorVariants(variants, run) {+ this.declarationConfig.rtl ??= variants.rtl;+ this.declarationConfig.theme ??= variants.theme;+ this.declarationConfig.active ??= variants.active;+ this.declarationConfig.focus ??= variants.focus;+ this.declarationConfig.disabled ??= variants.disabled;+ this.declarationConfig.dataAttributes ??= variants.dataAttributes;+ run();+ this.declarationConfig.rtl = null;+ this.declarationConfig.theme = null;+ this.declarationConfig.active = null;+ this.declarationConfig.focus = null;+ this.declarationConfig.disabled = null;+ this.declarationConfig.dataAttributes = null;+ } parseRuleRec(rule) { if (this.declarationConfig.className !== null) { const lastStyle = this.stylesheets[this.declarationConfig.className]?.at(-1);@@ -120,64 +178,30 @@ class ProcessorBuilder { this.declarationConfig.className = newClassName; this.stylesheets[newClassName] ??= []; this.stylesheets[newClassName].push({});- rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration));- rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true));- rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2));- return;- }- let rtl = null;- let theme = null;- let active = null;- let focus = null;- let disabled = null;- let dataAttributes = null;- selector.forEach(selector2 => {- if (selector2.type === "pseudo-class" && selector2.kind === "where") {- selector2.selectors.forEach(selector3 => {- selector3.forEach(selector4 => {- if (selector4.type === "class" && this.bundlerConfig.themes.includes(selector4.name)) {- theme = selector4.name;- }- if (selector4.type === "pseudo-class" && selector4.kind === "dir") {- rtl = selector4.direction === "rtl";- }- });- });- }- if (selector2.type === "pseudo-class" && selector2.kind === "active") {- active = true;+ const trailing = selector.slice(1);+ const { variants, hasVariants } = this.readSelectorVariants(trailing);+ if (trailing.length > 0 && !hasVariants) {+ return; }- if (selector2.type === "pseudo-class" && selector2.kind === "focus") {- focus = true;- }- if (selector2.type === "pseudo-class" && selector2.kind === "disabled") {- disabled = true;- }- if (selector2.type === "attribute" && selector2.operation === null && selector2.name.startsWith("data-")) {- dataAttributes ??= {};- dataAttributes[selector2.name] = `"true"`;- }- if (selector2.type === "attribute" && selector2.operation?.operator === "equal" && selector2.name.startsWith("data-")) {- dataAttributes ??= {};- dataAttributes[selector2.name] = `"${selector2.operation.value}"`;+ const parseClassRule = () => {+ rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration));+ rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true));+ rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2));+ };+ if (hasVariants) {+ this.withSelectorVariants(variants, parseClassRule);+ } else {+ parseClassRule(); }- });- if ([rtl, theme, active, focus, disabled, dataAttributes].some(_utils.isDefined)) {- this.declarationConfig.rtl ??= rtl;- this.declarationConfig.theme ??= theme;- this.declarationConfig.active ??= active;- this.declarationConfig.focus ??= focus;- this.declarationConfig.disabled ??= disabled;- this.declarationConfig.dataAttributes ??= dataAttributes;- rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration));- rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true));- rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2));- this.declarationConfig.rtl = null;- this.declarationConfig.theme = null;- this.declarationConfig.active = null;- this.declarationConfig.focus = null;- this.declarationConfig.disabled = null;- this.declarationConfig.dataAttributes = null;+ return;+ }+ const { variants, hasVariants } = this.readSelectorVariants(selector);+ if (hasVariants) {+ this.withSelectorVariants(variants, () => {+ rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration));+ rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true));+ rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2));+ }); return; } selector.forEach(selectorToken => {diff --git a/dist/metro/transformer.cjs b/dist/metro/transformer.cjsindex d57ca8161f411f0dc7df827132586e428cafdf1b..3650a353b0db269ad4fc51b70a7158885c992e36 100644--- a/dist/metro/transformer.cjs+++ b/dist/metro/transformer.cjs@@ -7,6 +7,7 @@ const culori = require('culori'); const node = require('@tailwindcss/node'); const oxide = require('@tailwindcss/oxide'); const fs = require('fs');+const node_crypto = require('node:crypto'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } @@ -1537,6 +1538,64 @@ class ProcessorBuilder { style.importantProperties.push(declaration.property); } }+ readSelectorVariants(tokens) {+ const variants = {+ rtl: null,+ theme: null,+ active: null,+ focus: null,+ disabled: null,+ dataAttributes: null+ };+ tokens.forEach((token) => {+ if (token.type === "pseudo-class" && token.kind === "where") {+ token.selectors.forEach((compound) => {+ compound.forEach((inner) => {+ if (inner.type === "class" && this.bundlerConfig.themes.includes(inner.name)) {+ variants.theme = inner.name;+ }+ if (inner.type === "pseudo-class" && inner.kind === "dir") {+ variants.rtl = inner.direction === "rtl";+ }+ });+ });+ }+ if (token.type === "pseudo-class" && token.kind === "active") {+ variants.active = true;+ }+ if (token.type === "pseudo-class" && token.kind === "focus") {+ variants.focus = true;+ }+ if (token.type === "pseudo-class" && token.kind === "disabled") {+ variants.disabled = true;+ }+ if (token.type === "attribute" && token.operation === null && token.name.startsWith("data-")) {+ variants.dataAttributes ??= {};+ variants.dataAttributes[token.name] = `"true"`;+ }+ if (token.type === "attribute" && token.operation?.operator === "equal" && token.name.startsWith("data-")) {+ variants.dataAttributes ??= {};+ variants.dataAttributes[token.name] = `"${token.operation.value}"`;+ }+ });+ const hasVariants = Object.values(variants).some(config.isDefined);+ return { variants, hasVariants };+ }+ withSelectorVariants(variants, run) {+ this.declarationConfig.rtl ??= variants.rtl;+ this.declarationConfig.theme ??= variants.theme;+ this.declarationConfig.active ??= variants.active;+ this.declarationConfig.focus ??= variants.focus;+ this.declarationConfig.disabled ??= variants.disabled;+ this.declarationConfig.dataAttributes ??= variants.dataAttributes;+ run();+ this.declarationConfig.rtl = null;+ this.declarationConfig.theme = null;+ this.declarationConfig.active = null;+ this.declarationConfig.focus = null;+ this.declarationConfig.disabled = null;+ this.declarationConfig.dataAttributes = null;+ } parseRuleRec(rule) { if (this.declarationConfig.className !== null) { const lastStyle = this.stylesheets[this.declarationConfig.className]?.at(-1);@@ -1552,64 +1611,30 @@ class ProcessorBuilder { this.declarationConfig.className = newClassName; this.stylesheets[newClassName] ??= []; this.stylesheets[newClassName].push({});- rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));- rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));- rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));- return;- }- let rtl = null;- let theme = null;- let active = null;- let focus = null;- let disabled = null;- let dataAttributes = null;- selector.forEach((selector2) => {- if (selector2.type === "pseudo-class" && selector2.kind === "where") {- selector2.selectors.forEach((selector3) => {- selector3.forEach((selector4) => {- if (selector4.type === "class" && this.bundlerConfig.themes.includes(selector4.name)) {- theme = selector4.name;- }- if (selector4.type === "pseudo-class" && selector4.kind === "dir") {- rtl = selector4.direction === "rtl";- }- });- });- }- if (selector2.type === "pseudo-class" && selector2.kind === "active") {- active = true;- }- if (selector2.type === "pseudo-class" && selector2.kind === "focus") {- focus = true;+ const trailing = selector.slice(1);+ const { variants, hasVariants } = this.readSelectorVariants(trailing);+ if (trailing.length > 0 && !hasVariants) {+ return; }- if (selector2.type === "pseudo-class" && selector2.kind === "disabled") {- disabled = true;- }- if (selector2.type === "attribute" && selector2.operation === null && selector2.name.startsWith("data-")) {- dataAttributes ??= {};- dataAttributes[selector2.name] = `"true"`;- }- if (selector2.type === "attribute" && selector2.operation?.operator === "equal" && selector2.name.startsWith("data-")) {- dataAttributes ??= {};- dataAttributes[selector2.name] = `"${selector2.operation.value}"`;+ const parseClassRule = () => {+ rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));+ rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));+ rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));+ };+ if (hasVariants) {+ this.withSelectorVariants(variants, parseClassRule);+ } else {+ parseClassRule(); }- });- if ([rtl, theme, active, focus, disabled, dataAttributes].some(config.isDefined)) {- this.declarationConfig.rtl ??= rtl;- this.declarationConfig.theme ??= theme;- this.declarationConfig.active ??= active;- this.declarationConfig.focus ??= focus;- this.declarationConfig.disabled ??= disabled;- this.declarationConfig.dataAttributes ??= dataAttributes;- rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));- rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));- rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));- this.declarationConfig.rtl = null;- this.declarationConfig.theme = null;- this.declarationConfig.active = null;- this.declarationConfig.focus = null;- this.declarationConfig.disabled = null;- this.declarationConfig.dataAttributes = null;+ return;+ }+ const { variants, hasVariants } = this.readSelectorVariants(selector);+ if (hasVariants) {+ this.withSelectorVariants(variants, () => {+ rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));+ rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));+ rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));+ }); return; } selector.forEach((selectorToken) => {@@ -1753,10 +1778,11 @@ const transform = async (config$1, projectRoot, filePath, data, options) => { await bundlerConfig.generateArtifacts(cssArtifactPath); const virtualCode = await compileCSS(bundlerConfig); const isWeb = bundlerConfig.platform === config.Platform.Web;+ const nativeStylesFingerprint = isWeb ? void 0 : node_crypto.createHash("sha256").update(virtualCode).update("\0").update(bundlerConfig.stringifiedThemes).digest("hex"); data = Buffer.from( isWeb ? virtualCode : [ `const { Uniwind } = require('uniwind');`,- `Uniwind.__reinit(rt => ${virtualCode}, ${bundlerConfig.stringifiedThemes});`+ `Uniwind.__reinit(rt => ${virtualCode}, ${bundlerConfig.stringifiedThemes}, '${nativeStylesFingerprint}');` ].join(""), "utf-8" );diff --git a/dist/metro/transformer.mjs b/dist/metro/transformer.mjsindex d3e7475f8f0aaba510b318657dc8374e6c6097cb..6ff8cffc4bb703521b6d86f0ac14be054ba5b9ce 100644--- a/dist/metro/transformer.mjs+++ b/dist/metro/transformer.mjs@@ -5,6 +5,7 @@ import { converter, parse, formatHex, formatHex8 } from 'culori'; import { compile } from '@tailwindcss/node'; import { Scanner } from '@tailwindcss/oxide'; import fs from 'fs';+import { createHash } from 'node:crypto'; const toCamelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()); const pipe = (data) => ((...fns) => fns.reduce((acc, fn) => fn(acc), data));@@ -1530,6 +1531,64 @@ class ProcessorBuilder { style.importantProperties.push(declaration.property); } }+ readSelectorVariants(tokens) {+ const variants = {+ rtl: null,+ theme: null,+ active: null,+ focus: null,+ disabled: null,+ dataAttributes: null+ };+ tokens.forEach((token) => {+ if (token.type === "pseudo-class" && token.kind === "where") {+ token.selectors.forEach((compound) => {+ compound.forEach((inner) => {+ if (inner.type === "class" && this.bundlerConfig.themes.includes(inner.name)) {+ variants.theme = inner.name;+ }+ if (inner.type === "pseudo-class" && inner.kind === "dir") {+ variants.rtl = inner.direction === "rtl";+ }+ });+ });+ }+ if (token.type === "pseudo-class" && token.kind === "active") {+ variants.active = true;+ }+ if (token.type === "pseudo-class" && token.kind === "focus") {+ variants.focus = true;+ }+ if (token.type === "pseudo-class" && token.kind === "disabled") {+ variants.disabled = true;+ }+ if (token.type === "attribute" && token.operation === null && token.name.startsWith("data-")) {+ variants.dataAttributes ??= {};+ variants.dataAttributes[token.name] = `"true"`;+ }+ if (token.type === "attribute" && token.operation?.operator === "equal" && token.name.startsWith("data-")) {+ variants.dataAttributes ??= {};+ variants.dataAttributes[token.name] = `"${token.operation.value}"`;+ }+ });+ const hasVariants = Object.values(variants).some(isDefined);+ return { variants, hasVariants };+ }+ withSelectorVariants(variants, run) {+ this.declarationConfig.rtl ??= variants.rtl;+ this.declarationConfig.theme ??= variants.theme;+ this.declarationConfig.active ??= variants.active;+ this.declarationConfig.focus ??= variants.focus;+ this.declarationConfig.disabled ??= variants.disabled;+ this.declarationConfig.dataAttributes ??= variants.dataAttributes;+ run();+ this.declarationConfig.rtl = null;+ this.declarationConfig.theme = null;+ this.declarationConfig.active = null;+ this.declarationConfig.focus = null;+ this.declarationConfig.disabled = null;+ this.declarationConfig.dataAttributes = null;+ } parseRuleRec(rule) { if (this.declarationConfig.className !== null) { const lastStyle = this.stylesheets[this.declarationConfig.className]?.at(-1);@@ -1545,64 +1604,30 @@ class ProcessorBuilder { this.declarationConfig.className = newClassName; this.stylesheets[newClassName] ??= []; this.stylesheets[newClassName].push({});- rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));- rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));- rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));- return;- }- let rtl = null;- let theme = null;- let active = null;- let focus = null;- let disabled = null;- let dataAttributes = null;- selector.forEach((selector2) => {- if (selector2.type === "pseudo-class" && selector2.kind === "where") {- selector2.selectors.forEach((selector3) => {- selector3.forEach((selector4) => {- if (selector4.type === "class" && this.bundlerConfig.themes.includes(selector4.name)) {- theme = selector4.name;- }- if (selector4.type === "pseudo-class" && selector4.kind === "dir") {- rtl = selector4.direction === "rtl";- }- });- });- }- if (selector2.type === "pseudo-class" && selector2.kind === "active") {- active = true;- }- if (selector2.type === "pseudo-class" && selector2.kind === "focus") {- focus = true;+ const trailing = selector.slice(1);+ const { variants, hasVariants } = this.readSelectorVariants(trailing);+ if (trailing.length > 0 && !hasVariants) {+ return; }- if (selector2.type === "pseudo-class" && selector2.kind === "disabled") {- disabled = true;- }- if (selector2.type === "attribute" && selector2.operation === null && selector2.name.startsWith("data-")) {- dataAttributes ??= {};- dataAttributes[selector2.name] = `"true"`;- }- if (selector2.type === "attribute" && selector2.operation?.operator === "equal" && selector2.name.startsWith("data-")) {- dataAttributes ??= {};- dataAttributes[selector2.name] = `"${selector2.operation.value}"`;+ const parseClassRule = () => {+ rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));+ rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));+ rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));+ };+ if (hasVariants) {+ this.withSelectorVariants(variants, parseClassRule);+ } else {+ parseClassRule(); }- });- if ([rtl, theme, active, focus, disabled, dataAttributes].some(isDefined)) {- this.declarationConfig.rtl ??= rtl;- this.declarationConfig.theme ??= theme;- this.declarationConfig.active ??= active;- this.declarationConfig.focus ??= focus;- this.declarationConfig.disabled ??= disabled;- this.declarationConfig.dataAttributes ??= dataAttributes;- rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));- rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));- rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));- this.declarationConfig.rtl = null;- this.declarationConfig.theme = null;- this.declarationConfig.active = null;- this.declarationConfig.focus = null;- this.declarationConfig.disabled = null;- this.declarationConfig.dataAttributes = null;+ return;+ }+ const { variants, hasVariants } = this.readSelectorVariants(selector);+ if (hasVariants) {+ this.withSelectorVariants(variants, () => {+ rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration));+ rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true));+ rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2));+ }); return; } selector.forEach((selectorToken) => {@@ -1746,10 +1771,11 @@ const transform = async (config, projectRoot, filePath, data, options) => { await bundlerConfig.generateArtifacts(cssArtifactPath); const virtualCode = await compileCSS(bundlerConfig);Lines 1–500 of 920. Load more
diff --git a/dist/common/bundler/css-processor/processor.js b/dist/common/bundler/css-processor/processor.js index 7dd369fa3197dbd622832c89ac3854c401e55c3e..ab3ea1a9520907321f9c21c2a3a859262fe5075b 100644 --- a/dist/common/bundler/css-processor/processor.js +++ b/dist/common/bundler/css-processor/processor.js @@ -105,6 +105,64 @@ class ProcessorBuilder { style.importantProperties.push(declaration.property); } } + readSelectorVariants(tokens) { + const variants = { + rtl: null, + theme: null, + active: null, + focus: null, + disabled: null, + dataAttributes: null + }; + tokens.forEach((token) => { + if (token.type === "pseudo-class" && token.kind === "where") { + token.selectors.forEach((compound) => { + compound.forEach((inner) => { + if (inner.type === "class" && this.bundlerConfig.themes.includes(inner.name)) { + variants.theme = inner.name; + } + if (inner.type === "pseudo-class" && inner.kind === "dir") { + variants.rtl = inner.direction === "rtl"; + } + }); + }); + } + if (token.type === "pseudo-class" && token.kind === "active") { + variants.active = true; + } + if (token.type === "pseudo-class" && token.kind === "focus") { + variants.focus = true; + } + if (token.type === "pseudo-class" && token.kind === "disabled") { + variants.disabled = true; + } + if (token.type === "attribute" && token.operation === null && token.name.startsWith("data-")) { + variants.dataAttributes ??= {}; + variants.dataAttributes[token.name] = `"true"`; + } + if (token.type === "attribute" && token.operation?.operator === "equal" && token.name.startsWith("data-")) { + variants.dataAttributes ??= {}; + variants.dataAttributes[token.name] = `"${token.operation.value}"`; + } + }); + const hasVariants = Object.values(variants).some(_utils.isDefined); + return { variants, hasVariants }; + } + withSelectorVariants(variants, run) { + this.declarationConfig.rtl ??= variants.rtl; + this.declarationConfig.theme ??= variants.theme; + this.declarationConfig.active ??= variants.active; + this.declarationConfig.focus ??= variants.focus; + this.declarationConfig.disabled ??= variants.disabled; + this.declarationConfig.dataAttributes ??= variants.dataAttributes; + run(); + this.declarationConfig.rtl = null; + this.declarationConfig.theme = null; + this.declarationConfig.active = null; + this.declarationConfig.focus = null; + this.declarationConfig.disabled = null; + this.declarationConfig.dataAttributes = null; + } parseRuleRec(rule) { if (this.declarationConfig.className !== null) { const lastStyle = this.stylesheets[this.declarationConfig.className]?.at(-1); @@ -120,64 +178,30 @@ class ProcessorBuilder { this.declarationConfig.className = newClassName; this.stylesheets[newClassName] ??= []; this.stylesheets[newClassName].push({}); - rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration)); - rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true)); - rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2)); - return; - } - let rtl = null; - let theme = null; - let active = null; - let focus = null; - let disabled = null; - let dataAttributes = null; - selector.forEach(selector2 => { - if (selector2.type === "pseudo-class" && selector2.kind === "where") { - selector2.selectors.forEach(selector3 => { - selector3.forEach(selector4 => { - if (selector4.type === "class" && this.bundlerConfig.themes.includes(selector4.name)) { - theme = selector4.name; - } - if (selector4.type === "pseudo-class" && selector4.kind === "dir") { - rtl = selector4.direction === "rtl"; - } - }); - }); - } - if (selector2.type === "pseudo-class" && selector2.kind === "active") { - active = true; + const trailing = selector.slice(1); + const { variants, hasVariants } = this.readSelectorVariants(trailing); + if (trailing.length > 0 && !hasVariants) { + return; } - if (selector2.type === "pseudo-class" && selector2.kind === "focus") { - focus = true; - } - if (selector2.type === "pseudo-class" && selector2.kind === "disabled") { - disabled = true; - } - if (selector2.type === "attribute" && selector2.operation === null && selector2.name.startsWith("data-")) { - dataAttributes ??= {}; - dataAttributes[selector2.name] = `"true"`; - } - if (selector2.type === "attribute" && selector2.operation?.operator === "equal" && selector2.name.startsWith("data-")) { - dataAttributes ??= {}; - dataAttributes[selector2.name] = `"${selector2.operation.value}"`; + const parseClassRule = () => { + rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration)); + rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true)); + rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2)); + }; + if (hasVariants) { + this.withSelectorVariants(variants, parseClassRule); + } else { + parseClassRule(); } - }); - if ([rtl, theme, active, focus, disabled, dataAttributes].some(_utils.isDefined)) { - this.declarationConfig.rtl ??= rtl; - this.declarationConfig.theme ??= theme; - this.declarationConfig.active ??= active; - this.declarationConfig.focus ??= focus; - this.declarationConfig.disabled ??= disabled; - this.declarationConfig.dataAttributes ??= dataAttributes; - rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration)); - rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true)); - rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2)); - this.declarationConfig.rtl = null; - this.declarationConfig.theme = null; - this.declarationConfig.active = null; - this.declarationConfig.focus = null; - this.declarationConfig.disabled = null; - this.declarationConfig.dataAttributes = null; + return; + } + const { variants, hasVariants } = this.readSelectorVariants(selector); + if (hasVariants) { + this.withSelectorVariants(variants, () => { + rule.value.declarations?.declarations?.forEach(declaration => this.addDeclaration(declaration)); + rule.value.declarations?.importantDeclarations?.forEach(declaration => this.addDeclaration(declaration, true)); + rule.value.rules?.forEach(rule2 => this.parseRuleRec(rule2)); + }); return; } selector.forEach(selectorToken => { diff --git a/dist/metro/transformer.cjs b/dist/metro/transformer.cjs index d57ca8161f411f0dc7df827132586e428cafdf1b..3650a353b0db269ad4fc51b70a7158885c992e36 100644 --- a/dist/metro/transformer.cjs +++ b/dist/metro/transformer.cjs @@ -7,6 +7,7 @@ const culori = require('culori'); const node = require('@tailwindcss/node'); const oxide = require('@tailwindcss/oxide'); const fs = require('fs'); +const node_crypto = require('node:crypto'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } @@ -1537,6 +1538,64 @@ class ProcessorBuilder { style.importantProperties.push(declaration.property); } } + readSelectorVariants(tokens) { + const variants = { + rtl: null, + theme: null, + active: null, + focus: null, + disabled: null, + dataAttributes: null + }; + tokens.forEach((token) => { + if (token.type === "pseudo-class" && token.kind === "where") { + token.selectors.forEach((compound) => { + compound.forEach((inner) => { + if (inner.type === "class" && this.bundlerConfig.themes.includes(inner.name)) { + variants.theme = inner.name; + } + if (inner.type === "pseudo-class" && inner.kind === "dir") { + variants.rtl = inner.direction === "rtl"; + } + }); + }); + } + if (token.type === "pseudo-class" && token.kind === "active") { + variants.active = true; + } + if (token.type === "pseudo-class" && token.kind === "focus") { + variants.focus = true; + } + if (token.type === "pseudo-class" && token.kind === "disabled") { + variants.disabled = true; + } + if (token.type === "attribute" && token.operation === null && token.name.startsWith("data-")) { + variants.dataAttributes ??= {}; + variants.dataAttributes[token.name] = `"true"`; + } + if (token.type === "attribute" && token.operation?.operator === "equal" && token.name.startsWith("data-")) { + variants.dataAttributes ??= {}; + variants.dataAttributes[token.name] = `"${token.operation.value}"`; + } + }); + const hasVariants = Object.values(variants).some(config.isDefined); + return { variants, hasVariants }; + } + withSelectorVariants(variants, run) { + this.declarationConfig.rtl ??= variants.rtl; + this.declarationConfig.theme ??= variants.theme; + this.declarationConfig.active ??= variants.active; + this.declarationConfig.focus ??= variants.focus; + this.declarationConfig.disabled ??= variants.disabled; + this.declarationConfig.dataAttributes ??= variants.dataAttributes; + run(); + this.declarationConfig.rtl = null; + this.declarationConfig.theme = null; + this.declarationConfig.active = null; + this.declarationConfig.focus = null; + this.declarationConfig.disabled = null; + this.declarationConfig.dataAttributes = null; + } parseRuleRec(rule) { if (this.declarationConfig.className !== null) { const lastStyle = this.stylesheets[this.declarationConfig.className]?.at(-1); @@ -1552,64 +1611,30 @@ class ProcessorBuilder { this.declarationConfig.className = newClassName; this.stylesheets[newClassName] ??= []; this.stylesheets[newClassName].push({}); - rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); - rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); - rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); - return; - } - let rtl = null; - let theme = null; - let active = null; - let focus = null; - let disabled = null; - let dataAttributes = null; - selector.forEach((selector2) => { - if (selector2.type === "pseudo-class" && selector2.kind === "where") { - selector2.selectors.forEach((selector3) => { - selector3.forEach((selector4) => { - if (selector4.type === "class" && this.bundlerConfig.themes.includes(selector4.name)) { - theme = selector4.name; - } - if (selector4.type === "pseudo-class" && selector4.kind === "dir") { - rtl = selector4.direction === "rtl"; - } - }); - }); - } - if (selector2.type === "pseudo-class" && selector2.kind === "active") { - active = true; - } - if (selector2.type === "pseudo-class" && selector2.kind === "focus") { - focus = true; + const trailing = selector.slice(1); + const { variants, hasVariants } = this.readSelectorVariants(trailing); + if (trailing.length > 0 && !hasVariants) { + return; } - if (selector2.type === "pseudo-class" && selector2.kind === "disabled") { - disabled = true; - } - if (selector2.type === "attribute" && selector2.operation === null && selector2.name.startsWith("data-")) { - dataAttributes ??= {}; - dataAttributes[selector2.name] = `"true"`; - } - if (selector2.type === "attribute" && selector2.operation?.operator === "equal" && selector2.name.startsWith("data-")) { - dataAttributes ??= {}; - dataAttributes[selector2.name] = `"${selector2.operation.value}"`; + const parseClassRule = () => { + rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); + rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); + rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); + }; + if (hasVariants) { + this.withSelectorVariants(variants, parseClassRule); + } else { + parseClassRule(); } - }); - if ([rtl, theme, active, focus, disabled, dataAttributes].some(config.isDefined)) { - this.declarationConfig.rtl ??= rtl; - this.declarationConfig.theme ??= theme; - this.declarationConfig.active ??= active; - this.declarationConfig.focus ??= focus; - this.declarationConfig.disabled ??= disabled; - this.declarationConfig.dataAttributes ??= dataAttributes; - rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); - rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); - rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); - this.declarationConfig.rtl = null; - this.declarationConfig.theme = null; - this.declarationConfig.active = null; - this.declarationConfig.focus = null; - this.declarationConfig.disabled = null; - this.declarationConfig.dataAttributes = null; + return; + } + const { variants, hasVariants } = this.readSelectorVariants(selector); + if (hasVariants) { + this.withSelectorVariants(variants, () => { + rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); + rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); + rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); + }); return; } selector.forEach((selectorToken) => { @@ -1753,10 +1778,11 @@ const transform = async (config$1, projectRoot, filePath, data, options) => { await bundlerConfig.generateArtifacts(cssArtifactPath); const virtualCode = await compileCSS(bundlerConfig); const isWeb = bundlerConfig.platform === config.Platform.Web; + const nativeStylesFingerprint = isWeb ? void 0 : node_crypto.createHash("sha256").update(virtualCode).update("\0").update(bundlerConfig.stringifiedThemes).digest("hex"); data = Buffer.from( isWeb ? virtualCode : [ `const { Uniwind } = require('uniwind');`, - `Uniwind.__reinit(rt => ${virtualCode}, ${bundlerConfig.stringifiedThemes});` + `Uniwind.__reinit(rt => ${virtualCode}, ${bundlerConfig.stringifiedThemes}, '${nativeStylesFingerprint}');` ].join(""), "utf-8" ); diff --git a/dist/metro/transformer.mjs b/dist/metro/transformer.mjs index d3e7475f8f0aaba510b318657dc8374e6c6097cb..6ff8cffc4bb703521b6d86f0ac14be054ba5b9ce 100644 --- a/dist/metro/transformer.mjs +++ b/dist/metro/transformer.mjs @@ -5,6 +5,7 @@ import { converter, parse, formatHex, formatHex8 } from 'culori'; import { compile } from '@tailwindcss/node'; import { Scanner } from '@tailwindcss/oxide'; import fs from 'fs'; +import { createHash } from 'node:crypto'; const toCamelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()); const pipe = (data) => ((...fns) => fns.reduce((acc, fn) => fn(acc), data)); @@ -1530,6 +1531,64 @@ class ProcessorBuilder { style.importantProperties.push(declaration.property); } } + readSelectorVariants(tokens) { + const variants = { + rtl: null, + theme: null, + active: null, + focus: null, + disabled: null, + dataAttributes: null + }; + tokens.forEach((token) => { + if (token.type === "pseudo-class" && token.kind === "where") { + token.selectors.forEach((compound) => { + compound.forEach((inner) => { + if (inner.type === "class" && this.bundlerConfig.themes.includes(inner.name)) { + variants.theme = inner.name; + } + if (inner.type === "pseudo-class" && inner.kind === "dir") { + variants.rtl = inner.direction === "rtl"; + } + }); + }); + } + if (token.type === "pseudo-class" && token.kind === "active") { + variants.active = true; + } + if (token.type === "pseudo-class" && token.kind === "focus") { + variants.focus = true; + } + if (token.type === "pseudo-class" && token.kind === "disabled") { + variants.disabled = true; + } + if (token.type === "attribute" && token.operation === null && token.name.startsWith("data-")) { + variants.dataAttributes ??= {}; + variants.dataAttributes[token.name] = `"true"`; + } + if (token.type === "attribute" && token.operation?.operator === "equal" && token.name.startsWith("data-")) { + variants.dataAttributes ??= {}; + variants.dataAttributes[token.name] = `"${token.operation.value}"`; + } + }); + const hasVariants = Object.values(variants).some(isDefined); + return { variants, hasVariants }; + } + withSelectorVariants(variants, run) { + this.declarationConfig.rtl ??= variants.rtl; + this.declarationConfig.theme ??= variants.theme; + this.declarationConfig.active ??= variants.active; + this.declarationConfig.focus ??= variants.focus; + this.declarationConfig.disabled ??= variants.disabled; + this.declarationConfig.dataAttributes ??= variants.dataAttributes; + run(); + this.declarationConfig.rtl = null; + this.declarationConfig.theme = null; + this.declarationConfig.active = null; + this.declarationConfig.focus = null; + this.declarationConfig.disabled = null; + this.declarationConfig.dataAttributes = null; + } parseRuleRec(rule) { if (this.declarationConfig.className !== null) { const lastStyle = this.stylesheets[this.declarationConfig.className]?.at(-1); @@ -1545,64 +1604,30 @@ class ProcessorBuilder { this.declarationConfig.className = newClassName; this.stylesheets[newClassName] ??= []; this.stylesheets[newClassName].push({}); - rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); - rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); - rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); - return; - } - let rtl = null; - let theme = null; - let active = null; - let focus = null; - let disabled = null; - let dataAttributes = null; - selector.forEach((selector2) => { - if (selector2.type === "pseudo-class" && selector2.kind === "where") { - selector2.selectors.forEach((selector3) => { - selector3.forEach((selector4) => { - if (selector4.type === "class" && this.bundlerConfig.themes.includes(selector4.name)) { - theme = selector4.name; - } - if (selector4.type === "pseudo-class" && selector4.kind === "dir") { - rtl = selector4.direction === "rtl"; - } - }); - }); - } - if (selector2.type === "pseudo-class" && selector2.kind === "active") { - active = true; - } - if (selector2.type === "pseudo-class" && selector2.kind === "focus") { - focus = true; + const trailing = selector.slice(1); + const { variants, hasVariants } = this.readSelectorVariants(trailing); + if (trailing.length > 0 && !hasVariants) { + return; } - if (selector2.type === "pseudo-class" && selector2.kind === "disabled") { - disabled = true; - } - if (selector2.type === "attribute" && selector2.operation === null && selector2.name.startsWith("data-")) { - dataAttributes ??= {}; - dataAttributes[selector2.name] = `"true"`; - } - if (selector2.type === "attribute" && selector2.operation?.operator === "equal" && selector2.name.startsWith("data-")) { - dataAttributes ??= {}; - dataAttributes[selector2.name] = `"${selector2.operation.value}"`; + const parseClassRule = () => { + rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); + rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); + rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); + }; + if (hasVariants) { + this.withSelectorVariants(variants, parseClassRule); + } else { + parseClassRule(); } - }); - if ([rtl, theme, active, focus, disabled, dataAttributes].some(isDefined)) { - this.declarationConfig.rtl ??= rtl; - this.declarationConfig.theme ??= theme; - this.declarationConfig.active ??= active; - this.declarationConfig.focus ??= focus; - this.declarationConfig.disabled ??= disabled; - this.declarationConfig.dataAttributes ??= dataAttributes; - rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); - rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); - rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); - this.declarationConfig.rtl = null; - this.declarationConfig.theme = null; - this.declarationConfig.active = null; - this.declarationConfig.focus = null; - this.declarationConfig.disabled = null; - this.declarationConfig.dataAttributes = null; + return; + } + const { variants, hasVariants } = this.readSelectorVariants(selector); + if (hasVariants) { + this.withSelectorVariants(variants, () => { + rule.value.declarations?.declarations?.forEach((declaration) => this.addDeclaration(declaration)); + rule.value.declarations?.importantDeclarations?.forEach((declaration) => this.addDeclaration(declaration, true)); + rule.value.rules?.forEach((rule2) => this.parseRuleRec(rule2)); + }); return; } selector.forEach((selectorToken) => { @@ -1746,10 +1771,11 @@ const transform = async (config, projectRoot, filePath, data, options) => { await bundlerConfig.generateArtifacts(cssArtifactPath); const virtualCode = await compileCSS(bundlerConfig);