rnwind 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/core/parser/color.cjs +33 -1
- package/lib/cjs/core/parser/color.cjs.map +1 -1
- package/lib/cjs/core/parser/color.d.ts +10 -0
- package/lib/cjs/core/parser/declaration.cjs +121 -9
- package/lib/cjs/core/parser/declaration.cjs.map +1 -1
- package/lib/cjs/core/parser/gradient.cjs +46 -12
- package/lib/cjs/core/parser/gradient.cjs.map +1 -1
- package/lib/cjs/core/parser/gradient.d.ts +2 -1
- package/lib/cjs/core/parser/keyframes.cjs +27 -12
- package/lib/cjs/core/parser/keyframes.cjs.map +1 -1
- package/lib/cjs/core/parser/keyframes.d.ts +11 -0
- package/lib/cjs/core/parser/layout-dispatcher.cjs +33 -10
- package/lib/cjs/core/parser/layout-dispatcher.cjs.map +1 -1
- package/lib/cjs/core/parser/length.cjs +17 -1
- package/lib/cjs/core/parser/length.cjs.map +1 -1
- package/lib/cjs/core/parser/safe-area.cjs +24 -3
- package/lib/cjs/core/parser/safe-area.cjs.map +1 -1
- package/lib/cjs/core/parser/theme-vars.cjs +58 -8
- package/lib/cjs/core/parser/theme-vars.cjs.map +1 -1
- package/lib/cjs/core/parser/tokens.cjs +77 -9
- package/lib/cjs/core/parser/tokens.cjs.map +1 -1
- package/lib/cjs/core/parser/tokens.d.ts +9 -0
- package/lib/cjs/core/parser/transform.cjs +18 -9
- package/lib/cjs/core/parser/transform.cjs.map +1 -1
- package/lib/cjs/core/parser/tw-parser.cjs +93 -33
- package/lib/cjs/core/parser/tw-parser.cjs.map +1 -1
- package/lib/cjs/core/parser/typography-dispatcher.cjs +19 -1
- package/lib/cjs/core/parser/typography-dispatcher.cjs.map +1 -1
- package/lib/cjs/core/parser/typography.cjs +15 -18
- package/lib/cjs/core/parser/typography.cjs.map +1 -1
- package/lib/cjs/core/parser/typography.d.ts +5 -5
- package/lib/cjs/core/style-builder/union-builder.cjs +0 -10
- package/lib/cjs/core/style-builder/union-builder.cjs.map +1 -1
- package/lib/cjs/core/style-builder/union-builder.d.ts +0 -8
- package/lib/cjs/metro/dts.cjs +6 -1
- package/lib/cjs/metro/dts.cjs.map +1 -1
- package/lib/cjs/metro/transformer.cjs +42 -77
- package/lib/cjs/metro/transformer.cjs.map +1 -1
- package/lib/cjs/metro/with-config.cjs +9 -29
- package/lib/cjs/metro/with-config.cjs.map +1 -1
- package/lib/cjs/runtime/hooks/use-scheme.cjs +9 -6
- package/lib/cjs/runtime/hooks/use-scheme.cjs.map +1 -1
- package/lib/cjs/runtime/hooks/use-scheme.d.ts +7 -4
- package/lib/cjs/runtime/index.cjs +1 -1
- package/lib/cjs/runtime/index.cjs.map +1 -1
- package/lib/cjs/runtime/index.d.ts +1 -1
- package/lib/cjs/runtime/lookup-css.cjs +14 -0
- package/lib/cjs/runtime/lookup-css.cjs.map +1 -1
- package/lib/cjs/runtime/lookup-css.d.ts +11 -0
- package/lib/cjs/runtime/resolve.cjs +8 -6
- package/lib/cjs/runtime/resolve.cjs.map +1 -1
- package/lib/cjs/runtime/wrap.cjs +50 -57
- package/lib/cjs/runtime/wrap.cjs.map +1 -1
- package/lib/cjs/runtime/wrap.d.ts +10 -4
- package/lib/esm/core/parser/color.d.ts +10 -0
- package/lib/esm/core/parser/color.mjs +33 -2
- package/lib/esm/core/parser/color.mjs.map +1 -1
- package/lib/esm/core/parser/declaration.mjs +122 -10
- package/lib/esm/core/parser/declaration.mjs.map +1 -1
- package/lib/esm/core/parser/gradient.d.ts +2 -1
- package/lib/esm/core/parser/gradient.mjs +45 -11
- package/lib/esm/core/parser/gradient.mjs.map +1 -1
- package/lib/esm/core/parser/keyframes.d.ts +11 -0
- package/lib/esm/core/parser/keyframes.mjs +27 -12
- package/lib/esm/core/parser/keyframes.mjs.map +1 -1
- package/lib/esm/core/parser/layout-dispatcher.mjs +33 -10
- package/lib/esm/core/parser/layout-dispatcher.mjs.map +1 -1
- package/lib/esm/core/parser/length.mjs +17 -1
- package/lib/esm/core/parser/length.mjs.map +1 -1
- package/lib/esm/core/parser/safe-area.mjs +24 -3
- package/lib/esm/core/parser/safe-area.mjs.map +1 -1
- package/lib/esm/core/parser/theme-vars.mjs +58 -8
- package/lib/esm/core/parser/theme-vars.mjs.map +1 -1
- package/lib/esm/core/parser/tokens.d.ts +9 -0
- package/lib/esm/core/parser/tokens.mjs +77 -10
- package/lib/esm/core/parser/tokens.mjs.map +1 -1
- package/lib/esm/core/parser/transform.mjs +18 -9
- package/lib/esm/core/parser/transform.mjs.map +1 -1
- package/lib/esm/core/parser/tw-parser.mjs +95 -35
- package/lib/esm/core/parser/tw-parser.mjs.map +1 -1
- package/lib/esm/core/parser/typography-dispatcher.mjs +19 -1
- package/lib/esm/core/parser/typography-dispatcher.mjs.map +1 -1
- package/lib/esm/core/parser/typography.d.ts +5 -5
- package/lib/esm/core/parser/typography.mjs +15 -18
- package/lib/esm/core/parser/typography.mjs.map +1 -1
- package/lib/esm/core/style-builder/union-builder.d.ts +0 -8
- package/lib/esm/core/style-builder/union-builder.mjs +0 -10
- package/lib/esm/core/style-builder/union-builder.mjs.map +1 -1
- package/lib/esm/metro/dts.mjs +6 -1
- package/lib/esm/metro/dts.mjs.map +1 -1
- package/lib/esm/metro/transformer.mjs +42 -77
- package/lib/esm/metro/transformer.mjs.map +1 -1
- package/lib/esm/metro/with-config.mjs +10 -30
- package/lib/esm/metro/with-config.mjs.map +1 -1
- package/lib/esm/runtime/hooks/use-scheme.d.ts +7 -4
- package/lib/esm/runtime/hooks/use-scheme.mjs +9 -6
- package/lib/esm/runtime/hooks/use-scheme.mjs.map +1 -1
- package/lib/esm/runtime/index.d.ts +1 -1
- package/lib/esm/runtime/index.mjs +1 -1
- package/lib/esm/runtime/index.mjs.map +1 -1
- package/lib/esm/runtime/lookup-css.d.ts +11 -0
- package/lib/esm/runtime/lookup-css.mjs +14 -1
- package/lib/esm/runtime/lookup-css.mjs.map +1 -1
- package/lib/esm/runtime/resolve.mjs +9 -7
- package/lib/esm/runtime/resolve.mjs.map +1 -1
- package/lib/esm/runtime/wrap.d.ts +10 -4
- package/lib/esm/runtime/wrap.mjs +50 -57
- package/lib/esm/runtime/wrap.mjs.map +1 -1
- package/package.json +1 -1
- package/src/core/parser/color.ts +32 -1
- package/src/core/parser/declaration.ts +119 -10
- package/src/core/parser/gradient.ts +48 -11
- package/src/core/parser/keyframes.ts +31 -3
- package/src/core/parser/layout-dispatcher.ts +32 -9
- package/src/core/parser/length.ts +18 -1
- package/src/core/parser/safe-area.ts +23 -2
- package/src/core/parser/theme-vars.ts +75 -8
- package/src/core/parser/tokens.ts +76 -9
- package/src/core/parser/transform.ts +19 -8
- package/src/core/parser/tw-parser.ts +95 -30
- package/src/core/parser/typography-dispatcher.ts +20 -1
- package/src/core/parser/typography.ts +15 -15
- package/src/core/style-builder/union-builder.ts +0 -11
- package/src/metro/dts.ts +6 -1
- package/src/metro/transformer.ts +42 -78
- package/src/metro/with-config.ts +10 -29
- package/src/runtime/hooks/use-scheme.ts +9 -6
- package/src/runtime/index.ts +1 -1
- package/src/runtime/lookup-css.ts +14 -0
- package/src/runtime/resolve.ts +9 -7
- package/src/runtime/wrap.tsx +57 -61
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-vars.cjs","sources":["../../../../../src/core/parser/theme-vars.ts"],"sourcesContent":["/**\n * Lightweight extractor for user-declared `@theme` and `@variant` blocks\n * inside `:root` / `@layer theme`. Used by the parser to resolve\n * `var(--x)` references that Tailwind's `theme(inline)` leaves\n * unresolved (it only inlines its own known tokens, not user-added ones).\n *\n * Kept regex-free — a linear paren-balanced scan handles nesting without\n * the backtracking risks of `{[^}]*}` patterns. CSS comment blocks are\n * stripped before scanning so slash-star-sequences inside declaration\n * values don't confuse the parser.\n */\n\n/**\n * `@custom-variant <name> ...content-up-to-semicolon...;`\n * The `[^;]+` class is constant-width relative to its input (one char\n * per step, no alternation backtracking), so sonarjs/slow-regex doesn't\n * apply — the flagged pattern is a false positive.\n */\n// eslint-disable-next-line sonarjs/slow-regex\nconst CUSTOM_VARIANT_WITH_SELECTOR = /@custom-variant\\s+([A-Za-z][A-Za-z0-9_-]*)\\s+([^;]+);/g\n/** Bare `.classname` occurrences (one capture group per class). */\nconst CLASS_IN_SELECTOR = /\\.([A-Za-z_][\\w-]*)/g\n\n/**\n * One iteration step of the block walker — decides whether the next\n * interesting token is a declaration, a nested block, or the end of\n * scope. Kept small to keep {@link walkBlocks} below the cognitive\n * complexity threshold.\n */\ninterface WalkStep {\n /** Next scan index, or `-1` to terminate the outer loop. */\n next: number\n}\n\n/**\n * Recursively descend into `{ ... }` blocks, collecting `--x: y;`\n * declarations under the active scheme. When we hit `@variant <name> {`,\n * the child scope's scheme becomes `<name>` until that block closes.\n * @param source Pre-stripped CSS source.\n * @param start Start index of the block body (0 for top-level).\n * @param scheme Active scheme name for declarations inside this scope.\n * @param table Destination table, mutated in place.\n */\nfunction walkBlocks(source: string, start: number, scheme: string, table: ThemeSchemeTable): void {\n let index = start\n while (index < source.length) {\n const step = nextWalkStep(source, index, scheme, table)\n if (step.next === -1) return\n index = step.next\n }\n}\n\n/**\n * Decide the next action at `index`: declaration, nested block, or EOF.\n * @param source Pre-stripped CSS.\n * @param index Current scan index.\n * @param scheme Active scheme name.\n * @param table Destination table.\n * @returns Step descriptor with the next scan index (or -1 for EOF).\n */\nfunction nextWalkStep(source: string, index: number, scheme: string, table: ThemeSchemeTable): WalkStep {\n // Find the next TOP-LEVEL `--` (outside any `( ... )`). That's the only\n // place a custom-property declaration can start. `--foo` that appears\n // inside `var(--foo)` or `calc(... --value(integer) ...)` is part of a\n // value, not a new declaration — accidentally treating it as one would\n // splice into the `@theme` block's declaration list and produce broken\n // CSS that Tailwind rejects downstream.\n const atIndex = findTopLevelDoubleDash(source, index)\n const openIndex = source.indexOf('{', index)\n const closeIndex = source.indexOf('}', index)\n const blockClose = closeIndex === -1 ? Number.POSITIVE_INFINITY : closeIndex\n if (isDeclarationNext(atIndex, openIndex, blockClose)) {\n return { next: consumeDeclaration(source, atIndex, scheme, table) }\n }\n if (openIndex !== -1 && openIndex < blockClose) {\n return { next: enterBlock(source, index, openIndex, scheme, table) }\n }\n return { next: -1 }\n}\n\n/**\n * Find the next `--` in `source` that's not inside a `( ... )` group.\n * Stops early if we hit an unmatched `}` (end of the containing block)\n * — a `--` inside a nested block isn't our concern either.\n * @param source Pre-stripped CSS source.\n * @param from Start index to scan from.\n * @returns Index of the next top-level `--`, or `-1` when none.\n */\nfunction findTopLevelDoubleDash(source: string, from: number): number {\n let parenDepth = 0\n for (let index = from; index < source.length - 1; index += 1) {\n const ch = source.codePointAt(index)\n if (ch === 40 /* ( */) {\n parenDepth += 1\n continue\n }\n if (ch === 41 /* ) */) {\n if (parenDepth > 0) parenDepth -= 1\n continue\n }\n if (ch === 125 /* } */ && parenDepth === 0) return -1\n if (ch === 45 /* - */ && parenDepth === 0 && source.codePointAt(index + 1) === 45) {\n return index\n }\n }\n return -1\n}\n\n/**\n * Whether the next action at the current scan position is a declaration.\n * @param atIndex Index of the next `--`.\n * @param openIndex Index of the next `{`.\n * @param blockClose Index of the next `}` (or `+Infinity` when absent).\n * @returns True when a declaration should be consumed next.\n */\nfunction isDeclarationNext(atIndex: number, openIndex: number, blockClose: number): boolean {\n if (atIndex === -1 || atIndex >= blockClose) return false\n return openIndex === -1 || atIndex < openIndex\n}\n\n/**\n * Handle a nested `{ ... }` block: recurse with the right scheme, then\n * skip past the matching closing brace.\n * @param source Pre-stripped CSS.\n * @param index Scan position at the start of the header.\n * @param openIndex Index of the opening brace.\n * @param scheme Scheme active in the parent scope.\n * @param table Destination table.\n * @returns Index past the matching closing brace.\n */\nfunction enterBlock(source: string, index: number, openIndex: number, scheme: string, table: ThemeSchemeTable): number {\n const header = source.slice(index, openIndex).trim()\n // Skip blocks that define utilities / at-rules that carry declarations\n // meant for a downstream compiler, not custom-property values for the\n // active theme scheme. `@utility name-*` bodies contain Tailwind v4's\n // `--value(...)` meta-syntax which would otherwise confuse the\n // top-level declaration walker and spill into the extracted theme.\n if (isNonThemeAtRule(header)) return skipMatchingBrace(source, openIndex + 1)\n const childScheme = variantNameOf(header) ?? scheme\n walkBlocks(source, openIndex + 1, childScheme, table)\n return skipMatchingBrace(source, openIndex + 1)\n}\n\n/**\n * Whether a block header belongs to an at-rule whose body should be\n * ignored by the theme-var extractor. `@utility` / `@media` / `@keyframes`\n * / `@supports` / `@container` bodies contain property declarations that\n * are NOT custom-property definitions for the active theme.\n * @param header Text between the outer statement and the opening brace.\n * @returns `true` when the block body should be skipped.\n */\nfunction isNonThemeAtRule(header: string): boolean {\n const trimmed = header.trimStart()\n if (!trimmed.startsWith('@')) return false\n const match = /^@([A-Za-z-]+)/.exec(trimmed)\n if (!match) return false\n const name = match[1]!\n return name === 'utility' || name === 'keyframes' || name === 'media' || name === 'supports' || name === 'container'\n}\n\n/**\n * Consume one `--name: value;` declaration starting at `start`. Commits\n * the name/value pair into the active scheme's map and returns the index\n * just past the terminating `;`.\n * @param source CSS source.\n * @param start Index of the `--`.\n * @param scheme Active scheme.\n * @param table Destination table.\n * @returns Next scan index.\n */\nfunction consumeDeclaration(source: string, start: number, scheme: string, table: ThemeSchemeTable): number {\n const colon = source.indexOf(':', start)\n if (colon === -1) return source.length\n const name = source.slice(start, colon).trim()\n const end = source.indexOf(';', colon)\n const stop = end === -1 ? source.indexOf('}', colon) : end\n if (stop === -1) return source.length\n const value = source.slice(colon + 1, stop).trim()\n if (name.startsWith('--')) {\n const bucket = table.get(scheme) ?? new Map()\n bucket.set(name, value)\n table.set(scheme, bucket)\n }\n return stop + 1\n}\n\n/**\n * Walk forward through the source tracking brace depth; return the index\n * just past the matching `}` for the opener at `start - 1`.\n * @param source CSS source.\n * @param start Index just past the opening brace.\n * @returns Index past the matching closer (or source.length on imbalance).\n */\nfunction skipMatchingBrace(source: string, start: number): number {\n let depth = 1\n for (let index = start; index < source.length; index += 1) {\n const ch = source[index]\n if (ch === '{') depth += 1\n else if (ch === '}') {\n depth -= 1\n if (depth === 0) return index + 1\n }\n }\n return source.length\n}\n\n/**\n * If `header` text (right before an opening brace) names a variant\n * (`@variant <name>`), return that name. Otherwise null.\n * @param header Text between the previous statement and the next `{`.\n * @returns Variant name, or null when this block isn't a `@variant`.\n */\nfunction variantNameOf(header: string): string | null {\n const match = /^@variant\\s+([A-Za-z][A-Za-z0-9_-]*)/.exec(header)\n if (!match) return null\n return match[1] ?? null\n}\n\n/**\n * Emit `@custom-variant` declarations for every scheme the user declared\n * but hasn't manually registered. Makes Tailwind accept `light:*` /\n * `dark:*` / etc. as valid class-name prefixes.\n * @param css Stripped CSS source used to detect already-declared variants.\n * @param schemes Non-base scheme names from the extracted table.\n * @returns Zero or more `@custom-variant ... ;` lines.\n */\nfunction buildCustomVariantDeclarations(css: string, schemes: readonly string[]): string[] {\n if (schemes.length === 0) return []\n const existing = new Set<string>()\n for (const match of css.matchAll(CUSTOM_VARIANT_REGEX)) existing.add(match[1]!)\n const out: string[] = []\n for (const name of schemes) {\n if (!existing.has(name)) out.push(`@custom-variant ${name} (&:where(.${name}, .${name} *));`)\n }\n return out\n}\n\n/**\n * Re-publish variant-scoped tokens into a flat theme block so Tailwind\n * sees every custom-property name it needs. Values come from the base\n * scheme first, with the FIRST declared non-base scheme layering on top\n * — Tailwind only cares about token shape (color vs length), not the\n * exact value, since rnwind does per-scheme substitution at walk time.\n * @param table Extracted scheme → var-name → value table.\n * @param schemes Non-base scheme names (sorted by declaration order).\n * @returns A single `@theme { ... }` block or `null` when there are no tokens.\n */\nfunction buildUnifiedThemeBlock(table: ThemeSchemeTable, schemes: readonly string[]): string | null {\n const unifiedVars = new Map<string, string>()\n const baseTokens = table.get(BASE_SCHEME)\n if (baseTokens) for (const [k, v] of baseTokens) unifiedVars.set(k, v)\n if (schemes.length > 0) {\n const firstTokens = table.get(schemes[0]!)\n if (firstTokens) for (const [k, v] of firstTokens) unifiedVars.set(k, v)\n }\n if (unifiedVars.size === 0) return null\n const decls = [...unifiedVars].map(([name, value]) => ` ${name}: ${value};`).join('\\n')\n return `@theme {\\n${decls}\\n}`\n}\n\nconst CUSTOM_VARIANT_REGEX = /@custom-variant\\s+([A-Za-z][A-Za-z0-9_-]*)\\b/g\nconst VARIANT_OPEN_REGEX = /@variant\\s+[A-Za-z0-9_-]+\\s*\\{/g\n\n/**\n * Strip every `@variant <name> { ... }` block (including nested braces)\n * from a CSS source.\n * @param css Raw CSS.\n * @returns CSS without variant blocks.\n */\nfunction stripVariantBlocks(css: string): string {\n let out = ''\n let cursor = 0\n VARIANT_OPEN_REGEX.lastIndex = 0\n let match: RegExpExecArray | null\n while ((match = VARIANT_OPEN_REGEX.exec(css)) !== null) {\n const openEnd = match.index + match[0].length\n const closeIndex = findMatchingBrace(css, openEnd)\n if (closeIndex === -1) break\n out += css.slice(cursor, match.index)\n cursor = closeIndex + 1\n VARIANT_OPEN_REGEX.lastIndex = cursor\n }\n out += css.slice(cursor)\n return out\n}\n\n/**\n * Walk forward from `start` tracking brace depth; return the index of the\n * matching `}` for the opener just before `start`.\n * @param source Source string.\n * @param start Index just past the opening `{`.\n * @returns Index of matching `}`, or `-1` on imbalance.\n */\nfunction findMatchingBrace(source: string, start: number): number {\n let depth = 1\n for (let index = start; index < source.length; index += 1) {\n const ch = source[index]\n if (ch === '{') depth += 1\n else if (ch === '}') {\n depth -= 1\n if (depth === 0) return index\n }\n }\n return -1\n}\n\n/**\n * Drop CSS comment blocks from a source. Keeps the token-declaration\n * scanner simple — comments can contain braces / `--` sequences that\n * would otherwise fool it.\n * @param css Raw CSS source.\n * @returns Source with every comment block removed.\n */\nfunction stripComments(css: string): string {\n let out = ''\n let index = 0\n while (index < css.length) {\n const open = css.indexOf('/*', index)\n if (open === -1) {\n out += css.slice(index)\n break\n }\n out += css.slice(index, open)\n const close = css.indexOf('*/', open + 2)\n if (close === -1) break\n index = close + 2\n }\n return out\n}\n\n/** Scheme name → (var name → value). The base scheme key is `'base'`. */\nexport type ThemeSchemeTable = Map<string, Map<string, string>>\n\n/** Synthetic scheme name used for tokens declared outside any `@variant`. */\nexport const BASE_SCHEME = 'base'\n\n/**\n * Extract user-declared theme tokens from a CSS source. Scans for:\n * - classic v4 `@theme` blocks (`@theme { --x: y; ... }`)\n * - `@variant <name> { --x: y; ... }` inside any surrounding block\n *\n * Both flavors contribute to the returned table: vars outside any\n * `@variant` go under `'base'`; vars inside `@variant <name>` go under\n * `<name>`.\n *\n * Not a full CSS parser — just enough to recognise the token-declaration\n * shape Tailwind v4 users actually write.\n * @param css Theme CSS source.\n * @returns Scheme → var-name → value map.\n */\nexport function extractThemeVars(css: string): ThemeSchemeTable {\n const table: ThemeSchemeTable = new Map()\n const stripped = stripComments(css)\n walkBlocks(stripped, 0, BASE_SCHEME, table)\n return table\n}\n\n/**\n * Build a `<class-in-selector> → <scheme-name>` alias map from any\n * `@custom-variant <name> (<selector>);` declarations in the theme CSS.\n *\n * Tailwind compiles `dark:opacity-100` to a nested rule whose selector is\n * the user's declared variant selector. When the user writes\n * `@custom-variant dark (&:where(.scheme-dark, .scheme-dark *));`, the\n * generated rule references `.scheme-dark` instead of the literal `.dark`\n * class rnwind's selector matcher defaults to. This alias map lets the\n * parser map those custom selector classes back to their scheme name.\n * @param css Theme CSS source.\n * @returns Class-name → scheme-name map. Empty when no `@custom-variant`\n * declarations are present (rnwind's auto-generated defaults already\n * use the literal scheme name and don't need an alias).\n */\nexport function extractSchemeAliases(css: string): Map<string, string> {\n const aliases = new Map<string, string>()\n const stripped = stripComments(css)\n for (const match of stripped.matchAll(CUSTOM_VARIANT_WITH_SELECTOR)) {\n const schemeName = match[1]!\n const selectorBody = match[2]!\n for (const cls of selectorBody.matchAll(CLASS_IN_SELECTOR)) {\n const className = cls[1]!\n if (className === schemeName) continue\n aliases.set(className, schemeName)\n }\n }\n return aliases\n}\n\n/** Single class token (`.scheme-dark`) — non-global so `.test` is stateless. */\nconst CLASS_TOKEN = /\\.[A-Za-z_][\\w-]*/\n\n/**\n * Whether a `@custom-variant` selector body targets an ancestor *class*\n * container (`&:where(.scheme-dark, .scheme-dark *)`, `.dark`). That's\n * the only shape rnwind resolves as a runtime scheme — the parser's\n * nested-rule matcher keys schemes off `.class` selectors. Pseudo-class\n * / `@media` / `@supports` custom-variants (`&:hover`, `@supports\n * (display: grid)`) carry no class and are ordinary Tailwind variants,\n * not schemes.\n * @param selector Selector body captured after the variant name.\n * @returns True when the selector contains at least one class token.\n */\nfunction isSchemeSelector(selector: string): boolean {\n return CLASS_TOKEN.test(selector)\n}\n\n/**\n * Collect every scheme name declared via `@custom-variant <name>\n * (<class-selector>);` in first-appearance order.\n *\n * A scheme can be declared this way WITHOUT a matching `@variant <name>\n * { … }` override block — its values then come entirely from the base\n * `@theme`. That's Tailwind v4's standard shape: light defaults sit in\n * `@theme` and only `@variant dark { … }` overrides them. Such a scheme\n * still has to register so the runtime can switch to it, but\n * {@link extractThemeVars} (which only sees `@variant` blocks) never\n * surfaces it. The parser unions these names into its declared-scheme\n * list so the base-only scheme isn't dropped.\n *\n * Only class-container selectors count — `@custom-variant` is Tailwind's\n * general variant mechanism, so hover / focus / media / supports\n * variants must NOT inflate the scheme list (or the generated `Scheme`\n * union). See {@link isSchemeSelector}.\n * @param css Theme CSS source.\n * @returns Ordered, de-duplicated `@custom-variant` scheme names.\n */\nexport function extractCustomVariantSchemes(css: string): string[] {\n const stripped = stripComments(css)\n const seen = new Set<string>()\n const out: string[] = []\n for (const match of stripped.matchAll(CUSTOM_VARIANT_WITH_SELECTOR)) {\n const name = match[1]!\n const selector = match[2]!\n if (name === BASE_SCHEME || seen.has(name)) continue\n if (!isSchemeSelector(selector)) continue\n seen.add(name)\n out.push(name)\n }\n return out\n}\n\n/**\n * Rewrite the theme CSS so Tailwind's compiler accepts it:\n * 1. Strip every `@variant <name> { ... }` block — Tailwind rejects\n * them inline because `@variant` is a rnwind concept, not a Tailwind\n * at-rule. The scheme-scoped vars are preserved in the extracted\n * {@link ThemeSchemeTable} and substituted at walk time.\n * 2. Prepend `@custom-variant <name> (&:where(.<name>, .<name> *));`\n * for every scheme name we saw, so Tailwind accepts `light:bg-*`,\n * `dark:bg-*`, etc. as valid class-name prefixes without the user\n * having to duplicate the variant declaration.\n * @param css Theme CSS source.\n * @param table Scheme → var-name → value table from {@link extractThemeVars}.\n * @returns CSS ready to feed `@tailwindcss/node`'s compiler.\n */\nexport function compileReadyTheme(css: string, table: ThemeSchemeTable): string {\n const schemes = [...table.keys()].filter((name) => name !== BASE_SCHEME)\n const stripped = stripVariantBlocks(css)\n const prelude: string[] = []\n const customVariants = buildCustomVariantDeclarations(stripped, schemes)\n if (customVariants.length > 0) prelude.push(...customVariants)\n const themeBlock = buildUnifiedThemeBlock(table, schemes)\n if (themeBlock) prelude.push(themeBlock)\n if (prelude.length === 0) return stripped\n return `${prelude.join('\\n')}\\n${stripped}`\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"theme-vars.cjs","sources":["../../../../../src/core/parser/theme-vars.ts"],"sourcesContent":["/**\n * Lightweight extractor for user-declared `@theme` and `@variant` blocks\n * inside `:root` / `@layer theme`. Used by the parser to resolve\n * `var(--x)` references that Tailwind's `theme(inline)` leaves\n * unresolved (it only inlines its own known tokens, not user-added ones).\n *\n * Kept regex-free — a linear paren-balanced scan handles nesting without\n * the backtracking risks of `{[^}]*}` patterns. CSS comment blocks are\n * stripped before scanning so slash-star-sequences inside declaration\n * values don't confuse the parser.\n */\n\n/**\n * `@custom-variant <name> ...content-up-to-semicolon...;`\n * The `[^;]+` class is constant-width relative to its input (one char\n * per step, no alternation backtracking), so sonarjs/slow-regex doesn't\n * apply — the flagged pattern is a false positive.\n */\n// eslint-disable-next-line sonarjs/slow-regex\nconst CUSTOM_VARIANT_WITH_SELECTOR = /@custom-variant\\s+([A-Za-z][A-Za-z0-9_-]*)\\s+([^;]+);/g\n/** Bare `.classname` occurrences (one capture group per class). */\nconst CLASS_IN_SELECTOR = /\\.([A-Za-z_][\\w-]*)/g\n\n/**\n * One iteration step of the block walker — decides whether the next\n * interesting token is a declaration, a nested block, or the end of\n * scope. Kept small to keep {@link walkBlocks} below the cognitive\n * complexity threshold.\n */\ninterface WalkStep {\n /** Next scan index, or `-1` to terminate the outer loop. */\n next: number\n}\n\n/**\n * Recursively descend into `{ ... }` blocks, collecting `--x: y;`\n * declarations under the active scheme. When we hit `@variant <name> {`,\n * the child scope's scheme becomes `<name>` until that block closes.\n * @param source Pre-stripped CSS source.\n * @param start Start index of the block body (0 for top-level).\n * @param scheme Active scheme name for declarations inside this scope.\n * @param table Destination table, mutated in place.\n * @param schemeClasses Selector-class → scheme-name map (from `@custom-variant` selectors).\n */\nfunction walkBlocks(\n source: string,\n start: number,\n scheme: string,\n table: ThemeSchemeTable,\n schemeClasses: ReadonlyMap<string, string>,\n): void {\n let index = start\n while (index < source.length) {\n const step = nextWalkStep(source, index, scheme, table, schemeClasses)\n if (step.next === -1) return\n index = step.next\n }\n}\n\n/**\n * Decide the next action at `index`: declaration, nested block, or EOF.\n * @param source Pre-stripped CSS.\n * @param index Current scan index.\n * @param scheme Active scheme name.\n * @param table Destination table.\n * @param schemeClasses Selector-class → scheme-name map (from `@custom-variant` selectors).\n * @returns Step descriptor with the next scan index (or -1 for EOF).\n */\nfunction nextWalkStep(\n source: string,\n index: number,\n scheme: string,\n table: ThemeSchemeTable,\n schemeClasses: ReadonlyMap<string, string>,\n): WalkStep {\n // Find the next TOP-LEVEL `--` (outside any `( ... )`). That's the only\n // place a custom-property declaration can start. `--foo` that appears\n // inside `var(--foo)` or `calc(... --value(integer) ...)` is part of a\n // value, not a new declaration — accidentally treating it as one would\n // splice into the `@theme` block's declaration list and produce broken\n // CSS that Tailwind rejects downstream.\n const atIndex = findTopLevelDoubleDash(source, index)\n const openIndex = source.indexOf('{', index)\n const closeIndex = source.indexOf('}', index)\n const blockClose = closeIndex === -1 ? Number.POSITIVE_INFINITY : closeIndex\n if (isDeclarationNext(atIndex, openIndex, blockClose)) {\n return { next: consumeDeclaration(source, atIndex, scheme, table) }\n }\n if (openIndex !== -1 && openIndex < blockClose) {\n return { next: enterBlock(source, index, openIndex, scheme, table, schemeClasses) }\n }\n return { next: -1 }\n}\n\n/**\n * Find the next `--` in `source` that's not inside a `( ... )` group.\n * Stops early if we hit an unmatched `}` (end of the containing block)\n * — a `--` inside a nested block isn't our concern either.\n * @param source Pre-stripped CSS source.\n * @param from Start index to scan from.\n * @returns Index of the next top-level `--`, or `-1` when none.\n */\nfunction findTopLevelDoubleDash(source: string, from: number): number {\n let parenDepth = 0\n for (let index = from; index < source.length - 1; index += 1) {\n const ch = source.codePointAt(index)\n if (ch === 40 /* ( */) {\n parenDepth += 1\n continue\n }\n if (ch === 41 /* ) */) {\n if (parenDepth > 0) parenDepth -= 1\n continue\n }\n if (ch === 125 /* } */ && parenDepth === 0) return -1\n if (ch === 45 /* - */ && parenDepth === 0 && source.codePointAt(index + 1) === 45) {\n return index\n }\n }\n return -1\n}\n\n/**\n * Whether the next action at the current scan position is a declaration.\n * @param atIndex Index of the next `--`.\n * @param openIndex Index of the next `{`.\n * @param blockClose Index of the next `}` (or `+Infinity` when absent).\n * @returns True when a declaration should be consumed next.\n */\nfunction isDeclarationNext(atIndex: number, openIndex: number, blockClose: number): boolean {\n if (atIndex === -1 || atIndex >= blockClose) return false\n return openIndex === -1 || atIndex < openIndex\n}\n\n/**\n * Handle a nested `{ ... }` block: recurse with the right scheme, then\n * skip past the matching closing brace.\n * @param source Pre-stripped CSS.\n * @param index Scan position at the start of the header.\n * @param openIndex Index of the opening brace.\n * @param scheme Scheme active in the parent scope.\n * @param table Destination table.\n * @param schemeClasses Selector-class → scheme-name map (from `@custom-variant` selectors).\n * @returns Index past the matching closing brace.\n */\nfunction enterBlock(\n source: string,\n index: number,\n openIndex: number,\n scheme: string,\n table: ThemeSchemeTable,\n schemeClasses: ReadonlyMap<string, string>,\n): number {\n const header = source.slice(index, openIndex).trim()\n // Skip blocks that define utilities / at-rules that carry declarations\n // meant for a downstream compiler, not custom-property values for the\n // active theme scheme. `@utility name-*` bodies contain Tailwind v4's\n // `--value(...)` meta-syntax which would otherwise confuse the\n // top-level declaration walker and spill into the extracted theme.\n if (isNonThemeAtRule(header)) return skipMatchingBrace(source, openIndex + 1)\n // Scheme scope switches on EITHER an `@variant <name> {` block OR a plain\n // selector block targeting a scheme class (`.dark { … }` — Tailwind v4's\n // standard dark-mode shape, often wrapped in `@layer base`). Without the\n // selector case, `.dark`'s overrides poured into `base` and overwrote the\n // light defaults, so every scheme rendered the dark values.\n const childScheme = variantNameOf(header) ?? schemeFromSelector(header, schemeClasses) ?? scheme\n walkBlocks(source, openIndex + 1, childScheme, table, schemeClasses)\n return skipMatchingBrace(source, openIndex + 1)\n}\n\n/**\n * Map a plain selector block header to the scheme it overrides, using the\n * class → scheme map derived from `@custom-variant` declarations. Returns the\n * first scheme class found in the selector (`.dark { … }` → `dark`,\n * `.scheme-dark, .scheme-dark * { … }` → `dark`), or null for at-rules and\n * non-scheme selectors (which keep the parent scheme).\n * @param header Block header text (the selector before the `{`).\n * @param schemeClasses Class-name → scheme-name map.\n * @returns Scheme name, or null.\n */\nfunction schemeFromSelector(header: string, schemeClasses: ReadonlyMap<string, string>): string | null {\n if (header.startsWith('@') || schemeClasses.size === 0) return null\n for (const match of header.matchAll(CLASS_IN_SELECTOR)) {\n const mapped = schemeClasses.get(match[1]!)\n if (mapped) return mapped\n }\n return null\n}\n\n/**\n * Build a `<selector-class> → <scheme-name>` map from every\n * `@custom-variant <name> (<class-selector>);` declaration. Unlike\n * {@link extractSchemeAliases} this KEEPS the `class === scheme` case\n * (`.dark → dark`) — that's exactly the mapping needed to attribute a\n * `.dark { … }` override block to the dark scheme.\n * @param css Pre-stripped CSS source.\n * @returns Class-name → scheme-name map.\n */\nfunction buildSchemeClassMap(css: string): Map<string, string> {\n const map = new Map<string, string>()\n for (const match of css.matchAll(CUSTOM_VARIANT_WITH_SELECTOR)) {\n const scheme = match[1]!\n const selector = match[2]!\n if (!isSchemeSelector(selector)) continue\n for (const cls of selector.matchAll(CLASS_IN_SELECTOR)) map.set(cls[1]!, scheme)\n }\n return map\n}\n\n/**\n * Whether a block header belongs to an at-rule whose body should be\n * ignored by the theme-var extractor. `@utility` / `@media` / `@keyframes`\n * / `@supports` / `@container` bodies contain property declarations that\n * are NOT custom-property definitions for the active theme.\n * @param header Text between the outer statement and the opening brace.\n * @returns `true` when the block body should be skipped.\n */\nfunction isNonThemeAtRule(header: string): boolean {\n const trimmed = header.trimStart()\n if (!trimmed.startsWith('@')) return false\n const match = /^@([A-Za-z-]+)/.exec(trimmed)\n if (!match) return false\n const name = match[1]!\n return name === 'utility' || name === 'keyframes' || name === 'media' || name === 'supports' || name === 'container'\n}\n\n/**\n * Consume one `--name: value;` declaration starting at `start`. Commits\n * the name/value pair into the active scheme's map and returns the index\n * just past the terminating `;`.\n * @param source CSS source.\n * @param start Index of the `--`.\n * @param scheme Active scheme.\n * @param table Destination table.\n * @returns Next scan index.\n */\nfunction consumeDeclaration(source: string, start: number, scheme: string, table: ThemeSchemeTable): number {\n const colon = source.indexOf(':', start)\n if (colon === -1) return source.length\n const name = source.slice(start, colon).trim()\n const end = source.indexOf(';', colon)\n const stop = end === -1 ? source.indexOf('}', colon) : end\n if (stop === -1) return source.length\n const value = source.slice(colon + 1, stop).trim()\n if (name.startsWith('--')) {\n const bucket = table.get(scheme) ?? new Map()\n bucket.set(name, value)\n table.set(scheme, bucket)\n }\n return stop + 1\n}\n\n/**\n * Walk forward through the source tracking brace depth; return the index\n * just past the matching `}` for the opener at `start - 1`.\n * @param source CSS source.\n * @param start Index just past the opening brace.\n * @returns Index past the matching closer (or source.length on imbalance).\n */\nfunction skipMatchingBrace(source: string, start: number): number {\n let depth = 1\n for (let index = start; index < source.length; index += 1) {\n const ch = source[index]\n if (ch === '{') depth += 1\n else if (ch === '}') {\n depth -= 1\n if (depth === 0) return index + 1\n }\n }\n return source.length\n}\n\n/**\n * If `header` text (right before an opening brace) names a variant\n * (`@variant <name>`), return that name. Otherwise null.\n * @param header Text between the previous statement and the next `{`.\n * @returns Variant name, or null when this block isn't a `@variant`.\n */\nfunction variantNameOf(header: string): string | null {\n const match = /^@variant\\s+([A-Za-z][A-Za-z0-9_-]*)/.exec(header)\n if (!match) return null\n return match[1] ?? null\n}\n\n/**\n * Emit `@custom-variant` declarations for every scheme the user declared\n * but hasn't manually registered. Makes Tailwind accept `light:*` /\n * `dark:*` / etc. as valid class-name prefixes.\n * @param css Stripped CSS source used to detect already-declared variants.\n * @param schemes Non-base scheme names from the extracted table.\n * @returns Zero or more `@custom-variant ... ;` lines.\n */\nfunction buildCustomVariantDeclarations(css: string, schemes: readonly string[]): string[] {\n if (schemes.length === 0) return []\n const existing = new Set<string>()\n for (const match of css.matchAll(CUSTOM_VARIANT_REGEX)) existing.add(match[1]!)\n const out: string[] = []\n for (const name of schemes) {\n if (!existing.has(name)) out.push(`@custom-variant ${name} (&:where(.${name}, .${name} *));`)\n }\n return out\n}\n\n/**\n * Re-publish variant-scoped tokens into a flat theme block so Tailwind\n * sees every custom-property name it needs. Values come from the base\n * scheme first, with the FIRST declared non-base scheme layering on top\n * — Tailwind only cares about token shape (color vs length), not the\n * exact value, since rnwind does per-scheme substitution at walk time.\n * @param table Extracted scheme → var-name → value table.\n * @param schemes Non-base scheme names (sorted by declaration order).\n * @returns A single `@theme { ... }` block or `null` when there are no tokens.\n */\nfunction buildUnifiedThemeBlock(table: ThemeSchemeTable, schemes: readonly string[]): string | null {\n const unifiedVars = new Map<string, string>()\n const baseTokens = table.get(BASE_SCHEME)\n if (baseTokens) for (const [k, v] of baseTokens) unifiedVars.set(k, v)\n if (schemes.length > 0) {\n const firstTokens = table.get(schemes[0]!)\n if (firstTokens) for (const [k, v] of firstTokens) unifiedVars.set(k, v)\n }\n if (unifiedVars.size === 0) return null\n const decls = [...unifiedVars].map(([name, value]) => ` ${name}: ${value};`).join('\\n')\n return `@theme {\\n${decls}\\n}`\n}\n\nconst CUSTOM_VARIANT_REGEX = /@custom-variant\\s+([A-Za-z][A-Za-z0-9_-]*)\\b/g\nconst VARIANT_OPEN_REGEX = /@variant\\s+[A-Za-z0-9_-]+\\s*\\{/g\n\n/**\n * Strip every `@variant <name> { ... }` block (including nested braces)\n * from a CSS source.\n * @param css Raw CSS.\n * @returns CSS without variant blocks.\n */\nfunction stripVariantBlocks(css: string): string {\n let out = ''\n let cursor = 0\n VARIANT_OPEN_REGEX.lastIndex = 0\n let match: RegExpExecArray | null\n while ((match = VARIANT_OPEN_REGEX.exec(css)) !== null) {\n const openEnd = match.index + match[0].length\n const closeIndex = findMatchingBrace(css, openEnd)\n if (closeIndex === -1) break\n out += css.slice(cursor, match.index)\n cursor = closeIndex + 1\n VARIANT_OPEN_REGEX.lastIndex = cursor\n }\n out += css.slice(cursor)\n return out\n}\n\n/**\n * Walk forward from `start` tracking brace depth; return the index of the\n * matching `}` for the opener just before `start`.\n * @param source Source string.\n * @param start Index just past the opening `{`.\n * @returns Index of matching `}`, or `-1` on imbalance.\n */\nfunction findMatchingBrace(source: string, start: number): number {\n let depth = 1\n for (let index = start; index < source.length; index += 1) {\n const ch = source[index]\n if (ch === '{') depth += 1\n else if (ch === '}') {\n depth -= 1\n if (depth === 0) return index\n }\n }\n return -1\n}\n\n/**\n * Drop CSS comment blocks from a source. Keeps the token-declaration\n * scanner simple — comments can contain braces / `--` sequences that\n * would otherwise fool it.\n * @param css Raw CSS source.\n * @returns Source with every comment block removed.\n */\nfunction stripComments(css: string): string {\n let out = ''\n let index = 0\n while (index < css.length) {\n const open = css.indexOf('/*', index)\n if (open === -1) {\n out += css.slice(index)\n break\n }\n out += css.slice(index, open)\n const close = css.indexOf('*/', open + 2)\n if (close === -1) break\n index = close + 2\n }\n return out\n}\n\n/** Scheme name → (var name → value). The base scheme key is `'base'`. */\nexport type ThemeSchemeTable = Map<string, Map<string, string>>\n\n/** Synthetic scheme name used for tokens declared outside any `@variant`. */\nexport const BASE_SCHEME = 'base'\n\n/**\n * Extract user-declared theme tokens from a CSS source. Scans for:\n * - classic v4 `@theme` blocks (`@theme { --x: y; ... }`)\n * - `@variant <name> { --x: y; ... }` inside any surrounding block\n *\n * Both flavors contribute to the returned table: vars outside any\n * `@variant` go under `'base'`; vars inside `@variant <name>` go under\n * `<name>`.\n *\n * Not a full CSS parser — just enough to recognise the token-declaration\n * shape Tailwind v4 users actually write.\n * @param css Theme CSS source.\n * @returns Scheme → var-name → value map.\n */\nexport function extractThemeVars(css: string): ThemeSchemeTable {\n const table: ThemeSchemeTable = new Map()\n const stripped = stripComments(css)\n const schemeClasses = buildSchemeClassMap(stripped)\n walkBlocks(stripped, 0, BASE_SCHEME, table, schemeClasses)\n return table\n}\n\n/**\n * Build a `<class-in-selector> → <scheme-name>` alias map from any\n * `@custom-variant <name> (<selector>);` declarations in the theme CSS.\n *\n * Tailwind compiles `dark:opacity-100` to a nested rule whose selector is\n * the user's declared variant selector. When the user writes\n * `@custom-variant dark (&:where(.scheme-dark, .scheme-dark *));`, the\n * generated rule references `.scheme-dark` instead of the literal `.dark`\n * class rnwind's selector matcher defaults to. This alias map lets the\n * parser map those custom selector classes back to their scheme name.\n * @param css Theme CSS source.\n * @returns Class-name → scheme-name map. Empty when no `@custom-variant`\n * declarations are present (rnwind's auto-generated defaults already\n * use the literal scheme name and don't need an alias).\n */\nexport function extractSchemeAliases(css: string): Map<string, string> {\n const aliases = new Map<string, string>()\n const stripped = stripComments(css)\n for (const match of stripped.matchAll(CUSTOM_VARIANT_WITH_SELECTOR)) {\n const schemeName = match[1]!\n const selectorBody = match[2]!\n for (const cls of selectorBody.matchAll(CLASS_IN_SELECTOR)) {\n const className = cls[1]!\n if (className === schemeName) continue\n aliases.set(className, schemeName)\n }\n }\n return aliases\n}\n\n/** Single class token (`.scheme-dark`) — non-global so `.test` is stateless. */\nconst CLASS_TOKEN = /\\.[A-Za-z_][\\w-]*/\n\n/**\n * Whether a `@custom-variant` selector body targets an ancestor *class*\n * container (`&:where(.scheme-dark, .scheme-dark *)`, `.dark`). That's\n * the only shape rnwind resolves as a runtime scheme — the parser's\n * nested-rule matcher keys schemes off `.class` selectors. Pseudo-class\n * / `@media` / `@supports` custom-variants (`&:hover`, `@supports\n * (display: grid)`) carry no class and are ordinary Tailwind variants,\n * not schemes.\n * @param selector Selector body captured after the variant name.\n * @returns True when the selector contains at least one class token.\n */\nfunction isSchemeSelector(selector: string): boolean {\n return CLASS_TOKEN.test(selector)\n}\n\n/**\n * Collect every scheme name declared via `@custom-variant <name>\n * (<class-selector>);` in first-appearance order.\n *\n * A scheme can be declared this way WITHOUT a matching `@variant <name>\n * { … }` override block — its values then come entirely from the base\n * `@theme`. That's Tailwind v4's standard shape: light defaults sit in\n * `@theme` and only `@variant dark { … }` overrides them. Such a scheme\n * still has to register so the runtime can switch to it, but\n * {@link extractThemeVars} (which only sees `@variant` blocks) never\n * surfaces it. The parser unions these names into its declared-scheme\n * list so the base-only scheme isn't dropped.\n *\n * Only class-container selectors count — `@custom-variant` is Tailwind's\n * general variant mechanism, so hover / focus / media / supports\n * variants must NOT inflate the scheme list (or the generated `Scheme`\n * union). See {@link isSchemeSelector}.\n * @param css Theme CSS source.\n * @returns Ordered, de-duplicated `@custom-variant` scheme names.\n */\nexport function extractCustomVariantSchemes(css: string): string[] {\n const stripped = stripComments(css)\n const seen = new Set<string>()\n const out: string[] = []\n for (const match of stripped.matchAll(CUSTOM_VARIANT_WITH_SELECTOR)) {\n const name = match[1]!\n const selector = match[2]!\n if (name === BASE_SCHEME || seen.has(name)) continue\n if (!isSchemeSelector(selector)) continue\n seen.add(name)\n out.push(name)\n }\n return out\n}\n\n/**\n * Rewrite the theme CSS so Tailwind's compiler accepts it:\n * 1. Strip every `@variant <name> { ... }` block — Tailwind rejects\n * them inline because `@variant` is a rnwind concept, not a Tailwind\n * at-rule. The scheme-scoped vars are preserved in the extracted\n * {@link ThemeSchemeTable} and substituted at walk time.\n * 2. Prepend `@custom-variant <name> (&:where(.<name>, .<name> *));`\n * for every scheme name we saw, so Tailwind accepts `light:bg-*`,\n * `dark:bg-*`, etc. as valid class-name prefixes without the user\n * having to duplicate the variant declaration.\n * @param css Theme CSS source.\n * @param table Scheme → var-name → value table from {@link extractThemeVars}.\n * @returns CSS ready to feed `@tailwindcss/node`'s compiler.\n */\nexport function compileReadyTheme(css: string, table: ThemeSchemeTable): string {\n const schemes = [...table.keys()].filter((name) => name !== BASE_SCHEME)\n const stripped = stripVariantBlocks(css)\n const prelude: string[] = []\n const customVariants = buildCustomVariantDeclarations(stripped, schemes)\n if (customVariants.length > 0) prelude.push(...customVariants)\n const themeBlock = buildUnifiedThemeBlock(table, schemes)\n if (themeBlock) prelude.push(themeBlock)\n if (prelude.length === 0) return stripped\n return `${prelude.join('\\n')}\\n${stripped}`\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -337,12 +337,30 @@ function applyAlphaToCssColor(color, multiplier) {
|
|
|
337
337
|
const trimmed = color.trim();
|
|
338
338
|
if (trimmed === 'transparent')
|
|
339
339
|
return 'rgba(0, 0, 0, 0)';
|
|
340
|
+
// Nested color-mix — Tailwind's `shadow-<token>/<opacity>` emits
|
|
341
|
+
// `color-mix(… color-mix(… <token> N%, transparent) <alpha>, transparent)`.
|
|
342
|
+
// Resolve the inner mix to a concrete color first, then apply this alpha.
|
|
343
|
+
if (trimmed.toLowerCase().startsWith('color-mix(')) {
|
|
344
|
+
const inner = evaluateColorMixWithTransparent(trimmed);
|
|
345
|
+
if (inner !== null)
|
|
346
|
+
return applyAlphaToCssColor(inner, multiplier);
|
|
347
|
+
}
|
|
340
348
|
return alphaFromHex(trimmed, multiplier) ?? alphaFromRgbFunction(trimmed, multiplier) ?? alphaFromCulori(trimmed, multiplier);
|
|
341
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Round a composed alpha to 4 decimals — `0.2 * 1` round-trips through f32 as
|
|
352
|
+
* `0.20000000298…`; the rounded form keeps generated rgba strings compact.
|
|
353
|
+
* @param alpha Raw alpha product.
|
|
354
|
+
* @returns Rounded alpha.
|
|
355
|
+
*/
|
|
356
|
+
function roundAlpha(alpha) {
|
|
357
|
+
return Math.round(alpha * 10_000) / 10_000;
|
|
358
|
+
}
|
|
342
359
|
/**
|
|
343
360
|
* Apply the alpha multiplier to a hex literal, expanding 3/4/6/8-digit forms.
|
|
344
|
-
* @param text
|
|
345
|
-
* @param multiplier
|
|
361
|
+
* @param text Candidate hex color string.
|
|
362
|
+
* @param multiplier Alpha multiplier (0…1).
|
|
363
|
+
* @returns `rgba(…)` string, or null when `text` is not a hex literal.
|
|
346
364
|
*/
|
|
347
365
|
function alphaFromHex(text, multiplier) {
|
|
348
366
|
const hexMatch = /^#([0-9a-fA-F]{3,8})$/.exec(text);
|
|
@@ -351,14 +369,15 @@ function alphaFromHex(text, multiplier) {
|
|
|
351
369
|
const expanded = expandHex(hexMatch[1]);
|
|
352
370
|
if (!expanded)
|
|
353
371
|
return null;
|
|
354
|
-
return `rgba(${expanded.r}, ${expanded.g}, ${expanded.b}, ${expanded.alpha * multiplier})`;
|
|
372
|
+
return `rgba(${expanded.r}, ${expanded.g}, ${expanded.b}, ${roundAlpha(expanded.alpha * multiplier)})`;
|
|
355
373
|
}
|
|
356
374
|
/**
|
|
357
375
|
* Apply alpha to an `rgb(…)` / `rgba(…)` literal. Walks the channels by
|
|
358
376
|
* hand instead of a multi-capture regex (the linter flags the regex
|
|
359
377
|
* form as backtracking-prone).
|
|
360
|
-
* @param text
|
|
361
|
-
* @param multiplier
|
|
378
|
+
* @param text Candidate `rgb(…)` / `rgba(…)` color string.
|
|
379
|
+
* @param multiplier Alpha multiplier (0…1).
|
|
380
|
+
* @returns `rgba(…)` string, or null when `text` is not an rgb function.
|
|
362
381
|
*/
|
|
363
382
|
function alphaFromRgbFunction(text, multiplier) {
|
|
364
383
|
if (!text.startsWith('rgb(') && !text.startsWith('rgba('))
|
|
@@ -373,7 +392,7 @@ function alphaFromRgbFunction(text, multiplier) {
|
|
|
373
392
|
const baseAlpha = channels.length === 4 ? Number(channels[3]) : 1;
|
|
374
393
|
if (![r, g, b, baseAlpha].every((value) => Number.isFinite(value)))
|
|
375
394
|
return null;
|
|
376
|
-
return `rgba(${r}, ${g}, ${b}, ${baseAlpha * multiplier})`;
|
|
395
|
+
return `rgba(${r}, ${g}, ${b}, ${roundAlpha(baseAlpha * multiplier)})`;
|
|
377
396
|
}
|
|
378
397
|
/**
|
|
379
398
|
* Fallback for wide-gamut color forms (`oklch`, `oklab`, `lab`, `lch`,
|
|
@@ -381,8 +400,9 @@ function alphaFromRgbFunction(text, multiplier) {
|
|
|
381
400
|
* `color-mix(in oklab, oklch(...) 50%, transparent)` resolve when
|
|
382
401
|
* Tailwind emits the source color in a wide-gamut space (every
|
|
383
402
|
* built-in `bg-red-500` / `shadow-red-500` does, in v4).
|
|
384
|
-
* @param text
|
|
385
|
-
* @param multiplier
|
|
403
|
+
* @param text Candidate wide-gamut / named CSS color string.
|
|
404
|
+
* @param multiplier Alpha multiplier (0…1).
|
|
405
|
+
* @returns `rgba(…)` string, or null when culori can't parse `text`.
|
|
386
406
|
*/
|
|
387
407
|
function alphaFromCulori(text, multiplier) {
|
|
388
408
|
try {
|
|
@@ -395,7 +415,7 @@ function alphaFromCulori(text, multiplier) {
|
|
|
395
415
|
const g = Math.round(Math.max(0, Math.min(1, parsed.g)) * 255);
|
|
396
416
|
const b = Math.round(Math.max(0, Math.min(1, parsed.b)) * 255);
|
|
397
417
|
const baseAlpha = typeof parsed.alpha === 'number' ? parsed.alpha : 1;
|
|
398
|
-
return `rgba(${r}, ${g}, ${b}, ${baseAlpha * multiplier})`;
|
|
418
|
+
return `rgba(${r}, ${g}, ${b}, ${roundAlpha(baseAlpha * multiplier)})`;
|
|
399
419
|
}
|
|
400
420
|
catch {
|
|
401
421
|
// culori threw on an unrecognised CSS form — fall through.
|
|
@@ -471,6 +491,53 @@ function coerceFontFamily(value) {
|
|
|
471
491
|
const first = value.split(',')[0]?.trim() ?? value;
|
|
472
492
|
return unquoteCssString(first);
|
|
473
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* Generic CSS font-family keywords — NOT real React Native typefaces. A
|
|
496
|
+
* `font-family` stack made only of these (e.g. the default `font-sans`:
|
|
497
|
+
* `ui-sans-serif, system-ui, sans-serif`) should fall back to RN's system
|
|
498
|
+
* font rather than emit a bogus `fontFamily`.
|
|
499
|
+
*/
|
|
500
|
+
const GENERIC_FONT_FAMILIES = new Set([
|
|
501
|
+
'ui-sans-serif',
|
|
502
|
+
'ui-serif',
|
|
503
|
+
'ui-monospace',
|
|
504
|
+
'ui-rounded',
|
|
505
|
+
'system-ui',
|
|
506
|
+
'sans-serif',
|
|
507
|
+
'serif',
|
|
508
|
+
'monospace',
|
|
509
|
+
'cursive',
|
|
510
|
+
'fantasy',
|
|
511
|
+
'math',
|
|
512
|
+
'emoji',
|
|
513
|
+
'fangsong',
|
|
514
|
+
'-apple-system',
|
|
515
|
+
'blinkmacsystemfont',
|
|
516
|
+
// Emoji / symbol fonts that Tailwind appends to the default sans stack —
|
|
517
|
+
// never the intended text typeface.
|
|
518
|
+
'apple color emoji',
|
|
519
|
+
'segoe ui emoji',
|
|
520
|
+
'segoe ui symbol',
|
|
521
|
+
'noto color emoji',
|
|
522
|
+
]);
|
|
523
|
+
/**
|
|
524
|
+
* Pick the first CONCRETE typeface from a typed `font-family` LIST (a CSS
|
|
525
|
+
* fallback stack). RN takes one family, and generic keywords aren't real
|
|
526
|
+
* faces, so skip them. Returns undefined when the whole stack is generic
|
|
527
|
+
* (→ caller emits nothing → system font).
|
|
528
|
+
* @param families Typed `font-family` value — an array of family-name strings.
|
|
529
|
+
* @returns First concrete family name, or undefined.
|
|
530
|
+
*/
|
|
531
|
+
function firstConcreteFontFamily(families) {
|
|
532
|
+
for (const entry of families) {
|
|
533
|
+
if (typeof entry !== 'string')
|
|
534
|
+
continue;
|
|
535
|
+
const bare = coerceFontFamily(entry);
|
|
536
|
+
if (bare.length > 0 && !GENERIC_FONT_FAMILIES.has(bare.toLowerCase()))
|
|
537
|
+
return bare;
|
|
538
|
+
}
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
474
541
|
/**
|
|
475
542
|
* Substitute every `var(--name [, fallback])` reference in `text` with
|
|
476
543
|
* the value from `table` (or the fallback clause when the name misses).
|
|
@@ -494,6 +561,7 @@ function substituteThemeVars(text, table) {
|
|
|
494
561
|
|
|
495
562
|
exports.coerceFontFamily = coerceFontFamily;
|
|
496
563
|
exports.coerceUnparsedValue = coerceUnparsedValue;
|
|
564
|
+
exports.firstConcreteFontFamily = firstConcreteFontFamily;
|
|
497
565
|
exports.serializeRawToken = serializeRawToken;
|
|
498
566
|
exports.serializeToken = serializeToken;
|
|
499
567
|
exports.serializeTokens = serializeTokens;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.cjs","sources":["../../../../../src/core/parser/tokens.ts"],"sourcesContent":["import type { Token, TokenOrValue } from 'lightningcss'\nimport { rgb as culoriRgb } from 'culori'\nimport { BARE_NUMBER_REGEX, CALC_MUL_REGEX, CALC_RATIO_REGEX, LENGTH_PX_REGEX, LENGTH_REM_REGEX, REM_TO_PX } from './constants'\nimport { cssColorToString } from './color'\nimport type { RNStyleValue } from './types'\n\n/**\n * Extract the fallback clause of a `var(--name, fallback)` by walking the\n * string with paren-depth tracking. Linear-time; safe on nested\n * `var(--a, var(--b, var(--c, 1rem)))` without regex backtracking.\n * @param text CSS value already trimmed.\n * @returns Fallback text, or `null` when `text` is not a `var(..., ...)`\n * with a fallback.\n */\nfunction extractVariableFallback(text: string): string | null {\n if (!text.startsWith('var(') || !text.endsWith(')')) return null\n const inner = text.slice(4, -1)\n let depth = 0\n for (let index = 0; index < inner.length; index += 1) {\n const ch = inner[index]\n if (ch === '(') depth += 1\n else if (ch === ')') depth -= 1\n else if (ch === ',' && depth === 0) return inner.slice(index + 1).trim()\n }\n return null\n}\n\n/**\n * Find the matching `)` for the opening `var(` whose body starts at\n * `start`. Returns `-1` when the parens are unbalanced.\n * @param text Source text.\n * @param start Index just past the opening `var(`.\n * @returns Index of the matching `)`, or `-1`.\n */\nfunction findBalancedParenEnd(text: string, start: number): number {\n let depth = 1\n for (let index = start; index < text.length; index += 1) {\n const ch = text[index]\n if (ch === '(') depth += 1\n else if (ch === ')') {\n depth -= 1\n if (depth === 0) return index\n }\n }\n return -1\n}\n\n/**\n * Resolve a `var(…)` body (the bit between parentheses). Reads the\n * variable name, then either returns the table lookup or recurses into\n * the fallback clause. When neither resolves, re-wraps as `var(…)` so\n * downstream coercion still sees a well-formed reference.\n * @param body Text between the outer parentheses of a `var()` call.\n * @param table var → value map.\n * @returns Substituted text fragment.\n */\nfunction resolveVariableBody(body: string, table: ReadonlyMap<string, string>): string {\n let depth = 0\n let commaIndex = -1\n for (const [index, ch] of [...body].entries()) {\n if (ch === '(') depth += 1\n else if (ch === ')') depth -= 1\n else if (ch === ',' && depth === 0) {\n commaIndex = index\n break\n }\n }\n const rawName = (commaIndex === -1 ? body : body.slice(0, commaIndex)).trim()\n const fallback = commaIndex === -1 ? null : body.slice(commaIndex + 1).trim()\n const resolved = table.get(rawName)\n if (resolved !== undefined) return resolved\n if (fallback !== null) return substitutePass(fallback, table)\n return `var(${body})`\n}\n\n/**\n * One pass of left-to-right `var(...)` substitution. Separate from the\n * fixed-point driver so the recursion depth stays bounded.\n * @param text Value text to scan.\n * @param table var → value map.\n * @returns Value text after one pass.\n */\nfunction substitutePass(text: string, table: ReadonlyMap<string, string>): string {\n let out = ''\n let index = 0\n while (index < text.length) {\n const head = text.indexOf('var(', index)\n if (head === -1) {\n out += text.slice(index)\n break\n }\n out += text.slice(index, head)\n const end = findBalancedParenEnd(text, head + 4)\n if (end === -1) {\n out += text.slice(head)\n break\n }\n const body = text.slice(head + 4, end)\n out += resolveVariableBody(body, table)\n index = end + 1\n }\n return out\n}\n\n/**\n * Serialize a list of `TokenOrValue` nodes into a CSS-ish value string.\n * Preserves the CSS form closely enough for downstream numeric coercion.\n * @param tokens Token list from an unparsed declaration or custom-property body.\n * @returns Concatenated CSS-value fragment.\n */\nexport function serializeTokens(tokens: readonly TokenOrValue[]): string {\n let out = ''\n for (const token of tokens) out += serializeToken(token)\n return out.trim()\n}\n\n/**\n * Serialize one `TokenOrValue` node back to CSS text. Handles the shapes\n * Tailwind v4 actually emits in utility-class bodies: raw tokens, `var()`\n * references, and numeric functions (`calc()`).\n * @param token One token node.\n * @returns CSS-value fragment.\n */\nexport function serializeToken(token: TokenOrValue): string {\n switch (token.type) {\n case 'token': {\n return serializeRawToken(token.value)\n }\n case 'var': {\n const head = token.value.name.ident\n const { fallback } = token.value\n if (!fallback || fallback.length === 0) return `var(${head})`\n return `var(${head}, ${serializeTokens(fallback)})`\n }\n case 'function': {\n return `${token.value.name}(${serializeTokens(token.value.arguments)})`\n }\n case 'length': {\n return `${token.value.value}${token.value.unit}`\n }\n case 'dashed-ident': {\n return token.value\n }\n case 'angle': {\n return `${token.value.value}${token.value.type}`\n }\n case 'time': {\n const unit = token.value.type === 'milliseconds' ? 'ms' : 's'\n return `${token.value.value}${unit}`\n }\n case 'resolution': {\n return `${token.value.value}${token.value.type}`\n }\n case 'color': {\n // Pre-resolved CSS color (`oklch(...)`, `rgb(...)`, etc.) — render\n // it back to a hex/rgba string RN can read.\n return cssColorToString(token.value)\n }\n case 'env':\n case 'unresolved-color':\n case 'url':\n case 'animation-name': {\n return ''\n }\n default: {\n return ''\n }\n }\n}\n\n/**\n * Serialize a raw `Token` back to CSS text. `TokenOrValue` with\n * `type === 'token'` wraps one of these; the discriminated union lets\n * TypeScript narrow per branch without casts.\n * @param token Raw token.\n * @returns CSS text fragment.\n */\nexport function serializeRawToken(token: Token): string {\n switch (token.type) {\n case 'ident':\n case 'at-keyword':\n case 'string':\n case 'unquoted-url':\n case 'function': {\n return token.value\n }\n case 'hash':\n case 'id-hash': {\n return `#${token.value}`\n }\n case 'number': {\n return String(token.value)\n }\n case 'percentage': {\n return `${token.value * 100}%`\n }\n case 'dimension': {\n return `${token.value}${token.unit}`\n }\n case 'white-space': {\n return ' '\n }\n case 'delim': {\n return token.value\n }\n case 'comma': {\n return ','\n }\n case 'colon':\n case 'semicolon':\n case 'parenthesis-block':\n case 'square-bracket-block':\n case 'curly-bracket-block':\n case 'cdo':\n case 'cdc':\n case 'include-match':\n case 'dash-match':\n case 'prefix-match':\n case 'suffix-match':\n case 'substring-match':\n case 'comment':\n case 'bad-url':\n case 'bad-string': {\n return ''\n }\n default: {\n return ''\n }\n }\n}\n\n/**\n * Coerce the flat serialization of an unparsed value into an RN scalar.\n * Handles the shapes Tailwind v4 actually emits: bare numbers, pixel /\n * rem lengths, calc ratios, and `var(--x, fallback)` where we recurse into\n * the fallback. Anything else passes through as a string.\n * @param text Serialized CSS value.\n * @returns Coerced primitive, or `null` when unrepresentable.\n */\nexport function coerceUnparsedValue(text: string): RNStyleValue | null {\n const trimmed = text.trim()\n if (trimmed.length === 0) return null\n if (BARE_NUMBER_REGEX.test(trimmed)) return Number(trimmed)\n const px = LENGTH_PX_REGEX.exec(trimmed)\n if (px) return Number(px[1])\n const rem = LENGTH_REM_REGEX.exec(trimmed)\n if (rem) return Number(rem[1]) * REM_TO_PX\n const colorMix = evaluateColorMixWithTransparent(trimmed)\n if (colorMix !== null) return colorMix\n const fallback = extractVariableFallback(trimmed)\n if (fallback !== null) return coerceUnparsedValue(fallback)\n const calcRatio = CALC_RATIO_REGEX.exec(trimmed)\n if (calcRatio) {\n const right = Number(calcRatio[2])\n if (right === 0) return null\n return Number(calcRatio[1]) / right\n }\n const calcMul = CALC_MUL_REGEX.exec(trimmed)\n if (calcMul) {\n // Unit-aware multiply: `calc(0.5rem * 2)` → 16 (rem scaled to px).\n // Regex captures `(number)(unit?) * (number)` — the unit is implicit\n // in the match position; rebuild via the full match text.\n const unitMatch = /^calc\\(\\s*-?\\d+(?:\\.\\d+)?(rem|px)?/.exec(trimmed)\n const unit = unitMatch?.[1]\n const base = Number(calcMul[1]) * Number(calcMul[2])\n return unit === 'rem' ? base * REM_TO_PX : base\n }\n return unquoteCssString(trimmed)\n}\n\n/**\n * Evaluate the specific `color-mix(in <space>, <color> <pct>%, transparent)`\n * shape Tailwind v4 emits for opacity-suffixed themed colors (e.g.\n * `border-text/20`, `bg-on-background/30`). The result is the original\n * color with `alpha = originalAlpha * pct/100` — no actual color-space\n * conversion is needed because mixing a color with `transparent` only\n * changes its alpha, regardless of the named space (oklab / srgb /\n * lab / …) — the chrominance is preserved.\n *\n * Returns null when the expression isn't this shape (handed back to\n * the caller for the next coercion strategy).\n * @param text Trimmed CSS value.\n * @returns RN-compatible `rgba(...)` string, or null when unmatched.\n */\nfunction evaluateColorMixWithTransparent(text: string): string | null {\n const lower = text.toLowerCase()\n if (!lower.startsWith('color-mix(')) return null\n // Match the trailing `, transparent)` (allowing optional whitespace).\n const tail = /,\\s*transparent\\s*\\)\\s*$/.exec(text)\n if (!tail) return null\n // Skip the `in <space>` clause (everything up to the FIRST comma after\n // the opening paren). Walking by hand instead of regex because the\n // color slot may itself contain `(...)` (e.g. `rgb(...)`).\n const inComma = text.indexOf(',', 'color-mix('.length)\n if (inComma === -1 || inComma > tail.index) return null\n const middle = text.slice(inComma + 1, tail.index).trim()\n // `<color> <pct>%` — the `<num>%` token is at the END of `middle`.\n // Anchored, no backtracking — explicit `% ` then end.\n const pctMatch = COLOR_MIX_PCT_TAIL.exec(middle)\n if (!pctMatch) return null\n const pct = Number(pctMatch[1]) / 100\n if (!Number.isFinite(pct)) return null\n const colorText = middle.slice(0, pctMatch.index).trim()\n if (colorText.length === 0) return null\n return applyAlphaToCssColor(colorText, pct)\n}\n\n/** End-anchored `<num>%` matcher used to slice a color-mix percentage off the right of an expression. */\n// eslint-disable-next-line sonarjs/slow-regex -- end-anchored, atomic-style group; bounded backtracking is safe.\nconst COLOR_MIX_PCT_TAIL = /(-?\\d+(?:\\.\\d+)?)%$/\n\n/**\n * Multiply the alpha channel of a serialized CSS color by `multiplier`\n * (0…1). Recognises `#rgb` / `#rrggbb` / `#rrggbbaa` hex, named colors\n * (only `transparent` matters here), and `rgb(…)` / `rgba(…)` forms —\n * which is what theme tokens resolve to after substitution.\n * @param color CSS color text.\n * @param multiplier Alpha multiplier (0…1).\n * @returns `rgba(r, g, b, a)` string with the adjusted alpha.\n */\nfunction applyAlphaToCssColor(color: string, multiplier: number): string | null {\n const trimmed = color.trim()\n if (trimmed === 'transparent') return 'rgba(0, 0, 0, 0)'\n return alphaFromHex(trimmed, multiplier) ?? alphaFromRgbFunction(trimmed, multiplier) ?? alphaFromCulori(trimmed, multiplier)\n}\n\n/**\n * Apply the alpha multiplier to a hex literal, expanding 3/4/6/8-digit forms.\n * @param text\n * @param multiplier\n */\nfunction alphaFromHex(text: string, multiplier: number): string | null {\n const hexMatch = /^#([0-9a-fA-F]{3,8})$/.exec(text)\n if (!hexMatch) return null\n const expanded = expandHex(hexMatch[1]!)\n if (!expanded) return null\n return `rgba(${expanded.r}, ${expanded.g}, ${expanded.b}, ${expanded.alpha * multiplier})`\n}\n\n/**\n * Apply alpha to an `rgb(…)` / `rgba(…)` literal. Walks the channels by\n * hand instead of a multi-capture regex (the linter flags the regex\n * form as backtracking-prone).\n * @param text\n * @param multiplier\n */\nfunction alphaFromRgbFunction(text: string, multiplier: number): string | null {\n if (!text.startsWith('rgb(') && !text.startsWith('rgba(')) return null\n const inner = text.slice(text.indexOf('(') + 1, -1)\n const channels = inner.split(/\\s*[\\s,]\\s*/).filter((part) => part.length > 0)\n if (channels.length !== 3 && channels.length !== 4) return null\n const r = Math.round(Number(channels[0]))\n const g = Math.round(Number(channels[1]))\n const b = Math.round(Number(channels[2]))\n const baseAlpha = channels.length === 4 ? Number(channels[3]) : 1\n if (![r, g, b, baseAlpha].every((value) => Number.isFinite(value))) return null\n return `rgba(${r}, ${g}, ${b}, ${baseAlpha * multiplier})`\n}\n\n/**\n * Fallback for wide-gamut color forms (`oklch`, `oklab`, `lab`, `lch`,\n * `hsl`, …) — culori parses every CSS color shape and yields RGB. Lets\n * `color-mix(in oklab, oklch(...) 50%, transparent)` resolve when\n * Tailwind emits the source color in a wide-gamut space (every\n * built-in `bg-red-500` / `shadow-red-500` does, in v4).\n * @param text\n * @param multiplier\n */\nfunction alphaFromCulori(text: string, multiplier: number): string | null {\n try {\n const parsed = culoriRgb(text) as { r?: number; g?: number; b?: number; alpha?: number } | undefined\n if (!parsed) return null\n if (![parsed.r, parsed.g, parsed.b].every((v) => typeof v === 'number' && Number.isFinite(v))) return null\n const r = Math.round(Math.max(0, Math.min(1, parsed.r!)) * 255)\n const g = Math.round(Math.max(0, Math.min(1, parsed.g!)) * 255)\n const b = Math.round(Math.max(0, Math.min(1, parsed.b!)) * 255)\n const baseAlpha = typeof parsed.alpha === 'number' ? parsed.alpha : 1\n return `rgba(${r}, ${g}, ${b}, ${baseAlpha * multiplier})`\n } catch {\n // culori threw on an unrecognised CSS form — fall through.\n return null\n }\n}\n\n/**\n * Expand `#rgb` / `#rrggbb` / `#rrggbbaa` hex to its `{r, g, b, alpha}`\n * components. Returns null when the digit count doesn't match a CSS hex\n * shape.\n * @param digits Hex digits without the leading `#`.\n * @returns Decoded color or null.\n */\nfunction expandHex(digits: string): { r: number; g: number; b: number; alpha: number } | null {\n const {length} = digits\n if (length === 3 || length === 4) {\n const r = Number.parseInt(digits[0]! + digits[0]!, 16)\n const g = Number.parseInt(digits[1]! + digits[1]!, 16)\n const b = Number.parseInt(digits[2]! + digits[2]!, 16)\n const alpha = length === 4 ? Number.parseInt(digits[3]! + digits[3]!, 16) / 255 : 1\n return Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) ? null : { r, g, b, alpha }\n }\n if (length === 6 || length === 8) {\n const r = Number.parseInt(digits.slice(0, 2), 16)\n const g = Number.parseInt(digits.slice(2, 4), 16)\n const b = Number.parseInt(digits.slice(4, 6), 16)\n const alpha = length === 8 ? Number.parseInt(digits.slice(6, 8), 16) / 255 : 1\n return Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) ? null : { r, g, b, alpha }\n }\n return null\n}\n\n/**\n * Strip the matched outer quote characters from a CSS string literal.\n * `--font-sans: 'Inter-Medium'` flows through `var(--font-sans)`\n * substitution as the raw value text — quotes included. Without this\n * step `fontFamily` lands on the RN style as `\"'Inter-Medium'\"` (with\n * literal quote characters), which RN can't match against the registered\n * native font and silently falls back to the system face.\n *\n * Only strips when both ends agree (`'…'` or `\"…\"`) and there are no\n * other top-level quote chars — keeps multi-segment fallbacks like\n * `'Inter', sans-serif` untouched (those get split downstream).\n * @param text Trimmed CSS value.\n * @returns Same text with outer matching quotes removed, or unchanged.\n */\nfunction unquoteCssString(text: string): string {\n if (text.length < 2) return text\n const first = text.codePointAt(0)\n const last = text.codePointAt(text.length - 1)\n if (first === undefined || first !== last) return text\n if (first !== 34 && first !== 39) return text // \" or '\n const inner = text.slice(1, -1)\n // Don't unquote when the inner string itself contains an unescaped\n // matching quote — that means we'd be merging two adjacent literals.\n if (inner.includes(text[0]!)) return text\n return inner\n}\n\n/**\n * Coerce a CSS `font-family` value into the SINGLE typeface name RN wants.\n * CSS font-family is a fallback LIST (`\"Montserrat\", sans-serif`), but RN's\n * `fontFamily` takes one family — so take the first entry and strip its\n * quotes. This is what lets the standard Tailwind convention\n * (`--font-display: \"Name\", sans-serif`) work out of the box: `font-display`\n * resolves to `{ fontFamily: 'Name' }`, not the raw quoted list.\n * @param value Resolved `font-family` value (possibly a quoted list).\n * @returns Bare first-family name.\n */\nexport function coerceFontFamily(value: string): string {\n const first = value.split(',')[0]?.trim() ?? value\n return unquoteCssString(first)\n}\n\n/**\n * Substitute every `var(--name [, fallback])` reference in `text` with\n * the value from `table` (or the fallback clause when the name misses).\n * Paren-balanced so nested `var(…)` refs don't confuse the scanner.\n * Iterates to a fixed point so multi-hop substitutions land in one call\n * (with a safety cap so a malformed self-referential token can't loop).\n * @param text Raw CSS value.\n * @param table var name → resolved value map.\n * @returns Substituted text.\n */\nexport function substituteThemeVars(text: string, table: ReadonlyMap<string, string>): string {\n let current = text\n for (let pass = 0; pass < 8; pass += 1) {\n const next = substitutePass(current, table)\n if (next === current) return next\n current = next\n }\n return current\n}\n"],"names":["cssColorToString","BARE_NUMBER_REGEX","LENGTH_PX_REGEX","LENGTH_REM_REGEX","REM_TO_PX","CALC_RATIO_REGEX","CALC_MUL_REGEX","culoriRgb"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tokens.cjs","sources":["../../../../../src/core/parser/tokens.ts"],"sourcesContent":["import type { Token, TokenOrValue } from 'lightningcss'\nimport { rgb as culoriRgb } from 'culori'\nimport { BARE_NUMBER_REGEX, CALC_MUL_REGEX, CALC_RATIO_REGEX, LENGTH_PX_REGEX, LENGTH_REM_REGEX, REM_TO_PX } from './constants'\nimport { cssColorToString } from './color'\nimport type { RNStyleValue } from './types'\n\n/**\n * Extract the fallback clause of a `var(--name, fallback)` by walking the\n * string with paren-depth tracking. Linear-time; safe on nested\n * `var(--a, var(--b, var(--c, 1rem)))` without regex backtracking.\n * @param text CSS value already trimmed.\n * @returns Fallback text, or `null` when `text` is not a `var(..., ...)`\n * with a fallback.\n */\nfunction extractVariableFallback(text: string): string | null {\n if (!text.startsWith('var(') || !text.endsWith(')')) return null\n const inner = text.slice(4, -1)\n let depth = 0\n for (let index = 0; index < inner.length; index += 1) {\n const ch = inner[index]\n if (ch === '(') depth += 1\n else if (ch === ')') depth -= 1\n else if (ch === ',' && depth === 0) return inner.slice(index + 1).trim()\n }\n return null\n}\n\n/**\n * Find the matching `)` for the opening `var(` whose body starts at\n * `start`. Returns `-1` when the parens are unbalanced.\n * @param text Source text.\n * @param start Index just past the opening `var(`.\n * @returns Index of the matching `)`, or `-1`.\n */\nfunction findBalancedParenEnd(text: string, start: number): number {\n let depth = 1\n for (let index = start; index < text.length; index += 1) {\n const ch = text[index]\n if (ch === '(') depth += 1\n else if (ch === ')') {\n depth -= 1\n if (depth === 0) return index\n }\n }\n return -1\n}\n\n/**\n * Resolve a `var(…)` body (the bit between parentheses). Reads the\n * variable name, then either returns the table lookup or recurses into\n * the fallback clause. When neither resolves, re-wraps as `var(…)` so\n * downstream coercion still sees a well-formed reference.\n * @param body Text between the outer parentheses of a `var()` call.\n * @param table var → value map.\n * @returns Substituted text fragment.\n */\nfunction resolveVariableBody(body: string, table: ReadonlyMap<string, string>): string {\n let depth = 0\n let commaIndex = -1\n for (const [index, ch] of [...body].entries()) {\n if (ch === '(') depth += 1\n else if (ch === ')') depth -= 1\n else if (ch === ',' && depth === 0) {\n commaIndex = index\n break\n }\n }\n const rawName = (commaIndex === -1 ? body : body.slice(0, commaIndex)).trim()\n const fallback = commaIndex === -1 ? null : body.slice(commaIndex + 1).trim()\n const resolved = table.get(rawName)\n if (resolved !== undefined) return resolved\n if (fallback !== null) return substitutePass(fallback, table)\n return `var(${body})`\n}\n\n/**\n * One pass of left-to-right `var(...)` substitution. Separate from the\n * fixed-point driver so the recursion depth stays bounded.\n * @param text Value text to scan.\n * @param table var → value map.\n * @returns Value text after one pass.\n */\nfunction substitutePass(text: string, table: ReadonlyMap<string, string>): string {\n let out = ''\n let index = 0\n while (index < text.length) {\n const head = text.indexOf('var(', index)\n if (head === -1) {\n out += text.slice(index)\n break\n }\n out += text.slice(index, head)\n const end = findBalancedParenEnd(text, head + 4)\n if (end === -1) {\n out += text.slice(head)\n break\n }\n const body = text.slice(head + 4, end)\n out += resolveVariableBody(body, table)\n index = end + 1\n }\n return out\n}\n\n/**\n * Serialize a list of `TokenOrValue` nodes into a CSS-ish value string.\n * Preserves the CSS form closely enough for downstream numeric coercion.\n * @param tokens Token list from an unparsed declaration or custom-property body.\n * @returns Concatenated CSS-value fragment.\n */\nexport function serializeTokens(tokens: readonly TokenOrValue[]): string {\n let out = ''\n for (const token of tokens) out += serializeToken(token)\n return out.trim()\n}\n\n/**\n * Serialize one `TokenOrValue` node back to CSS text. Handles the shapes\n * Tailwind v4 actually emits in utility-class bodies: raw tokens, `var()`\n * references, and numeric functions (`calc()`).\n * @param token One token node.\n * @returns CSS-value fragment.\n */\nexport function serializeToken(token: TokenOrValue): string {\n switch (token.type) {\n case 'token': {\n return serializeRawToken(token.value)\n }\n case 'var': {\n const head = token.value.name.ident\n const { fallback } = token.value\n if (!fallback || fallback.length === 0) return `var(${head})`\n return `var(${head}, ${serializeTokens(fallback)})`\n }\n case 'function': {\n return `${token.value.name}(${serializeTokens(token.value.arguments)})`\n }\n case 'length': {\n return `${token.value.value}${token.value.unit}`\n }\n case 'dashed-ident': {\n return token.value\n }\n case 'angle': {\n return `${token.value.value}${token.value.type}`\n }\n case 'time': {\n const unit = token.value.type === 'milliseconds' ? 'ms' : 's'\n return `${token.value.value}${unit}`\n }\n case 'resolution': {\n return `${token.value.value}${token.value.type}`\n }\n case 'color': {\n // Pre-resolved CSS color (`oklch(...)`, `rgb(...)`, etc.) — render\n // it back to a hex/rgba string RN can read.\n return cssColorToString(token.value)\n }\n case 'env':\n case 'unresolved-color':\n case 'url':\n case 'animation-name': {\n return ''\n }\n default: {\n return ''\n }\n }\n}\n\n/**\n * Serialize a raw `Token` back to CSS text. `TokenOrValue` with\n * `type === 'token'` wraps one of these; the discriminated union lets\n * TypeScript narrow per branch without casts.\n * @param token Raw token.\n * @returns CSS text fragment.\n */\nexport function serializeRawToken(token: Token): string {\n switch (token.type) {\n case 'ident':\n case 'at-keyword':\n case 'string':\n case 'unquoted-url':\n case 'function': {\n return token.value\n }\n case 'hash':\n case 'id-hash': {\n return `#${token.value}`\n }\n case 'number': {\n return String(token.value)\n }\n case 'percentage': {\n return `${token.value * 100}%`\n }\n case 'dimension': {\n return `${token.value}${token.unit}`\n }\n case 'white-space': {\n return ' '\n }\n case 'delim': {\n return token.value\n }\n case 'comma': {\n return ','\n }\n case 'colon':\n case 'semicolon':\n case 'parenthesis-block':\n case 'square-bracket-block':\n case 'curly-bracket-block':\n case 'cdo':\n case 'cdc':\n case 'include-match':\n case 'dash-match':\n case 'prefix-match':\n case 'suffix-match':\n case 'substring-match':\n case 'comment':\n case 'bad-url':\n case 'bad-string': {\n return ''\n }\n default: {\n return ''\n }\n }\n}\n\n/**\n * Coerce the flat serialization of an unparsed value into an RN scalar.\n * Handles the shapes Tailwind v4 actually emits: bare numbers, pixel /\n * rem lengths, calc ratios, and `var(--x, fallback)` where we recurse into\n * the fallback. Anything else passes through as a string.\n * @param text Serialized CSS value.\n * @returns Coerced primitive, or `null` when unrepresentable.\n */\nexport function coerceUnparsedValue(text: string): RNStyleValue | null {\n const trimmed = text.trim()\n if (trimmed.length === 0) return null\n if (BARE_NUMBER_REGEX.test(trimmed)) return Number(trimmed)\n const px = LENGTH_PX_REGEX.exec(trimmed)\n if (px) return Number(px[1])\n const rem = LENGTH_REM_REGEX.exec(trimmed)\n if (rem) return Number(rem[1]) * REM_TO_PX\n const colorMix = evaluateColorMixWithTransparent(trimmed)\n if (colorMix !== null) return colorMix\n const fallback = extractVariableFallback(trimmed)\n if (fallback !== null) return coerceUnparsedValue(fallback)\n const calcRatio = CALC_RATIO_REGEX.exec(trimmed)\n if (calcRatio) {\n const right = Number(calcRatio[2])\n if (right === 0) return null\n return Number(calcRatio[1]) / right\n }\n const calcMul = CALC_MUL_REGEX.exec(trimmed)\n if (calcMul) {\n // Unit-aware multiply: `calc(0.5rem * 2)` → 16 (rem scaled to px).\n // Regex captures `(number)(unit?) * (number)` — the unit is implicit\n // in the match position; rebuild via the full match text.\n const unitMatch = /^calc\\(\\s*-?\\d+(?:\\.\\d+)?(rem|px)?/.exec(trimmed)\n const unit = unitMatch?.[1]\n const base = Number(calcMul[1]) * Number(calcMul[2])\n return unit === 'rem' ? base * REM_TO_PX : base\n }\n return unquoteCssString(trimmed)\n}\n\n/**\n * Evaluate the specific `color-mix(in <space>, <color> <pct>%, transparent)`\n * shape Tailwind v4 emits for opacity-suffixed themed colors (e.g.\n * `border-text/20`, `bg-on-background/30`). The result is the original\n * color with `alpha = originalAlpha * pct/100` — no actual color-space\n * conversion is needed because mixing a color with `transparent` only\n * changes its alpha, regardless of the named space (oklab / srgb /\n * lab / …) — the chrominance is preserved.\n *\n * Returns null when the expression isn't this shape (handed back to\n * the caller for the next coercion strategy).\n * @param text Trimmed CSS value.\n * @returns RN-compatible `rgba(...)` string, or null when unmatched.\n */\nfunction evaluateColorMixWithTransparent(text: string): string | null {\n const lower = text.toLowerCase()\n if (!lower.startsWith('color-mix(')) return null\n // Match the trailing `, transparent)` (allowing optional whitespace).\n const tail = /,\\s*transparent\\s*\\)\\s*$/.exec(text)\n if (!tail) return null\n // Skip the `in <space>` clause (everything up to the FIRST comma after\n // the opening paren). Walking by hand instead of regex because the\n // color slot may itself contain `(...)` (e.g. `rgb(...)`).\n const inComma = text.indexOf(',', 'color-mix('.length)\n if (inComma === -1 || inComma > tail.index) return null\n const middle = text.slice(inComma + 1, tail.index).trim()\n // `<color> <pct>%` — the `<num>%` token is at the END of `middle`.\n // Anchored, no backtracking — explicit `% ` then end.\n const pctMatch = COLOR_MIX_PCT_TAIL.exec(middle)\n if (!pctMatch) return null\n const pct = Number(pctMatch[1]) / 100\n if (!Number.isFinite(pct)) return null\n const colorText = middle.slice(0, pctMatch.index).trim()\n if (colorText.length === 0) return null\n return applyAlphaToCssColor(colorText, pct)\n}\n\n/** End-anchored `<num>%` matcher used to slice a color-mix percentage off the right of an expression. */\n// eslint-disable-next-line sonarjs/slow-regex -- end-anchored, atomic-style group; bounded backtracking is safe.\nconst COLOR_MIX_PCT_TAIL = /(-?\\d+(?:\\.\\d+)?)%$/\n\n/**\n * Multiply the alpha channel of a serialized CSS color by `multiplier`\n * (0…1). Recognises `#rgb` / `#rrggbb` / `#rrggbbaa` hex, named colors\n * (only `transparent` matters here), and `rgb(…)` / `rgba(…)` forms —\n * which is what theme tokens resolve to after substitution.\n * @param color CSS color text.\n * @param multiplier Alpha multiplier (0…1).\n * @returns `rgba(r, g, b, a)` string with the adjusted alpha.\n */\nfunction applyAlphaToCssColor(color: string, multiplier: number): string | null {\n const trimmed = color.trim()\n if (trimmed === 'transparent') return 'rgba(0, 0, 0, 0)'\n // Nested color-mix — Tailwind's `shadow-<token>/<opacity>` emits\n // `color-mix(… color-mix(… <token> N%, transparent) <alpha>, transparent)`.\n // Resolve the inner mix to a concrete color first, then apply this alpha.\n if (trimmed.toLowerCase().startsWith('color-mix(')) {\n const inner = evaluateColorMixWithTransparent(trimmed)\n if (inner !== null) return applyAlphaToCssColor(inner, multiplier)\n }\n return alphaFromHex(trimmed, multiplier) ?? alphaFromRgbFunction(trimmed, multiplier) ?? alphaFromCulori(trimmed, multiplier)\n}\n\n/**\n * Round a composed alpha to 4 decimals — `0.2 * 1` round-trips through f32 as\n * `0.20000000298…`; the rounded form keeps generated rgba strings compact.\n * @param alpha Raw alpha product.\n * @returns Rounded alpha.\n */\nfunction roundAlpha(alpha: number): number {\n return Math.round(alpha * 10_000) / 10_000\n}\n\n/**\n * Apply the alpha multiplier to a hex literal, expanding 3/4/6/8-digit forms.\n * @param text Candidate hex color string.\n * @param multiplier Alpha multiplier (0…1).\n * @returns `rgba(…)` string, or null when `text` is not a hex literal.\n */\nfunction alphaFromHex(text: string, multiplier: number): string | null {\n const hexMatch = /^#([0-9a-fA-F]{3,8})$/.exec(text)\n if (!hexMatch) return null\n const expanded = expandHex(hexMatch[1]!)\n if (!expanded) return null\n return `rgba(${expanded.r}, ${expanded.g}, ${expanded.b}, ${roundAlpha(expanded.alpha * multiplier)})`\n}\n\n/**\n * Apply alpha to an `rgb(…)` / `rgba(…)` literal. Walks the channels by\n * hand instead of a multi-capture regex (the linter flags the regex\n * form as backtracking-prone).\n * @param text Candidate `rgb(…)` / `rgba(…)` color string.\n * @param multiplier Alpha multiplier (0…1).\n * @returns `rgba(…)` string, or null when `text` is not an rgb function.\n */\nfunction alphaFromRgbFunction(text: string, multiplier: number): string | null {\n if (!text.startsWith('rgb(') && !text.startsWith('rgba(')) return null\n const inner = text.slice(text.indexOf('(') + 1, -1)\n const channels = inner.split(/\\s*[\\s,]\\s*/).filter((part) => part.length > 0)\n if (channels.length !== 3 && channels.length !== 4) return null\n const r = Math.round(Number(channels[0]))\n const g = Math.round(Number(channels[1]))\n const b = Math.round(Number(channels[2]))\n const baseAlpha = channels.length === 4 ? Number(channels[3]) : 1\n if (![r, g, b, baseAlpha].every((value) => Number.isFinite(value))) return null\n return `rgba(${r}, ${g}, ${b}, ${roundAlpha(baseAlpha * multiplier)})`\n}\n\n/**\n * Fallback for wide-gamut color forms (`oklch`, `oklab`, `lab`, `lch`,\n * `hsl`, …) — culori parses every CSS color shape and yields RGB. Lets\n * `color-mix(in oklab, oklch(...) 50%, transparent)` resolve when\n * Tailwind emits the source color in a wide-gamut space (every\n * built-in `bg-red-500` / `shadow-red-500` does, in v4).\n * @param text Candidate wide-gamut / named CSS color string.\n * @param multiplier Alpha multiplier (0…1).\n * @returns `rgba(…)` string, or null when culori can't parse `text`.\n */\nfunction alphaFromCulori(text: string, multiplier: number): string | null {\n try {\n const parsed = culoriRgb(text) as { r?: number; g?: number; b?: number; alpha?: number } | undefined\n if (!parsed) return null\n if (![parsed.r, parsed.g, parsed.b].every((v) => typeof v === 'number' && Number.isFinite(v))) return null\n const r = Math.round(Math.max(0, Math.min(1, parsed.r!)) * 255)\n const g = Math.round(Math.max(0, Math.min(1, parsed.g!)) * 255)\n const b = Math.round(Math.max(0, Math.min(1, parsed.b!)) * 255)\n const baseAlpha = typeof parsed.alpha === 'number' ? parsed.alpha : 1\n return `rgba(${r}, ${g}, ${b}, ${roundAlpha(baseAlpha * multiplier)})`\n } catch {\n // culori threw on an unrecognised CSS form — fall through.\n return null\n }\n}\n\n/**\n * Expand `#rgb` / `#rrggbb` / `#rrggbbaa` hex to its `{r, g, b, alpha}`\n * components. Returns null when the digit count doesn't match a CSS hex\n * shape.\n * @param digits Hex digits without the leading `#`.\n * @returns Decoded color or null.\n */\nfunction expandHex(digits: string): { r: number; g: number; b: number; alpha: number } | null {\n const {length} = digits\n if (length === 3 || length === 4) {\n const r = Number.parseInt(digits[0]! + digits[0]!, 16)\n const g = Number.parseInt(digits[1]! + digits[1]!, 16)\n const b = Number.parseInt(digits[2]! + digits[2]!, 16)\n const alpha = length === 4 ? Number.parseInt(digits[3]! + digits[3]!, 16) / 255 : 1\n return Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) ? null : { r, g, b, alpha }\n }\n if (length === 6 || length === 8) {\n const r = Number.parseInt(digits.slice(0, 2), 16)\n const g = Number.parseInt(digits.slice(2, 4), 16)\n const b = Number.parseInt(digits.slice(4, 6), 16)\n const alpha = length === 8 ? Number.parseInt(digits.slice(6, 8), 16) / 255 : 1\n return Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) ? null : { r, g, b, alpha }\n }\n return null\n}\n\n/**\n * Strip the matched outer quote characters from a CSS string literal.\n * `--font-sans: 'Inter-Medium'` flows through `var(--font-sans)`\n * substitution as the raw value text — quotes included. Without this\n * step `fontFamily` lands on the RN style as `\"'Inter-Medium'\"` (with\n * literal quote characters), which RN can't match against the registered\n * native font and silently falls back to the system face.\n *\n * Only strips when both ends agree (`'…'` or `\"…\"`) and there are no\n * other top-level quote chars — keeps multi-segment fallbacks like\n * `'Inter', sans-serif` untouched (those get split downstream).\n * @param text Trimmed CSS value.\n * @returns Same text with outer matching quotes removed, or unchanged.\n */\nfunction unquoteCssString(text: string): string {\n if (text.length < 2) return text\n const first = text.codePointAt(0)\n const last = text.codePointAt(text.length - 1)\n if (first === undefined || first !== last) return text\n if (first !== 34 && first !== 39) return text // \" or '\n const inner = text.slice(1, -1)\n // Don't unquote when the inner string itself contains an unescaped\n // matching quote — that means we'd be merging two adjacent literals.\n if (inner.includes(text[0]!)) return text\n return inner\n}\n\n/**\n * Coerce a CSS `font-family` value into the SINGLE typeface name RN wants.\n * CSS font-family is a fallback LIST (`\"Montserrat\", sans-serif`), but RN's\n * `fontFamily` takes one family — so take the first entry and strip its\n * quotes. This is what lets the standard Tailwind convention\n * (`--font-display: \"Name\", sans-serif`) work out of the box: `font-display`\n * resolves to `{ fontFamily: 'Name' }`, not the raw quoted list.\n * @param value Resolved `font-family` value (possibly a quoted list).\n * @returns Bare first-family name.\n */\nexport function coerceFontFamily(value: string): string {\n const first = value.split(',')[0]?.trim() ?? value\n return unquoteCssString(first)\n}\n\n/**\n * Generic CSS font-family keywords — NOT real React Native typefaces. A\n * `font-family` stack made only of these (e.g. the default `font-sans`:\n * `ui-sans-serif, system-ui, sans-serif`) should fall back to RN's system\n * font rather than emit a bogus `fontFamily`.\n */\nconst GENERIC_FONT_FAMILIES: ReadonlySet<string> = new Set([\n 'ui-sans-serif',\n 'ui-serif',\n 'ui-monospace',\n 'ui-rounded',\n 'system-ui',\n 'sans-serif',\n 'serif',\n 'monospace',\n 'cursive',\n 'fantasy',\n 'math',\n 'emoji',\n 'fangsong',\n '-apple-system',\n 'blinkmacsystemfont',\n // Emoji / symbol fonts that Tailwind appends to the default sans stack —\n // never the intended text typeface.\n 'apple color emoji',\n 'segoe ui emoji',\n 'segoe ui symbol',\n 'noto color emoji',\n])\n\n/**\n * Pick the first CONCRETE typeface from a typed `font-family` LIST (a CSS\n * fallback stack). RN takes one family, and generic keywords aren't real\n * faces, so skip them. Returns undefined when the whole stack is generic\n * (→ caller emits nothing → system font).\n * @param families Typed `font-family` value — an array of family-name strings.\n * @returns First concrete family name, or undefined.\n */\nexport function firstConcreteFontFamily(families: readonly unknown[]): string | undefined {\n for (const entry of families) {\n if (typeof entry !== 'string') continue\n const bare = coerceFontFamily(entry)\n if (bare.length > 0 && !GENERIC_FONT_FAMILIES.has(bare.toLowerCase())) return bare\n }\n return undefined\n}\n\n/**\n * Substitute every `var(--name [, fallback])` reference in `text` with\n * the value from `table` (or the fallback clause when the name misses).\n * Paren-balanced so nested `var(…)` refs don't confuse the scanner.\n * Iterates to a fixed point so multi-hop substitutions land in one call\n * (with a safety cap so a malformed self-referential token can't loop).\n * @param text Raw CSS value.\n * @param table var name → resolved value map.\n * @returns Substituted text.\n */\nexport function substituteThemeVars(text: string, table: ReadonlyMap<string, string>): string {\n let current = text\n for (let pass = 0; pass < 8; pass += 1) {\n const next = substitutePass(current, table)\n if (next === current) return next\n current = next\n }\n return current\n}\n"],"names":["cssColorToString","BARE_NUMBER_REGEX","LENGTH_PX_REGEX","LENGTH_REM_REGEX","REM_TO_PX","CALC_RATIO_REGEX","CALC_MUL_REGEX","culoriRgb"],"mappings":"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"}
|
|
@@ -43,6 +43,15 @@ export declare function coerceUnparsedValue(text: string): RNStyleValue | null;
|
|
|
43
43
|
* @returns Bare first-family name.
|
|
44
44
|
*/
|
|
45
45
|
export declare function coerceFontFamily(value: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Pick the first CONCRETE typeface from a typed `font-family` LIST (a CSS
|
|
48
|
+
* fallback stack). RN takes one family, and generic keywords aren't real
|
|
49
|
+
* faces, so skip them. Returns undefined when the whole stack is generic
|
|
50
|
+
* (→ caller emits nothing → system font).
|
|
51
|
+
* @param families Typed `font-family` value — an array of family-name strings.
|
|
52
|
+
* @returns First concrete family name, or undefined.
|
|
53
|
+
*/
|
|
54
|
+
export declare function firstConcreteFontFamily(families: readonly unknown[]): string | undefined;
|
|
46
55
|
/**
|
|
47
56
|
* Substitute every `var(--name [, fallback])` reference in `text` with
|
|
48
57
|
* the value from `table` (or the fallback clause when the name misses).
|
|
@@ -96,39 +96,48 @@ function angleToString(angle) {
|
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Convert a `NumberOrPercentage` to a plain number. Percentages become
|
|
99
|
-
* their fractional equivalent (e.g. `50%` → `0.5`).
|
|
99
|
+
* their fractional equivalent (e.g. `50%` → `0.5`). Rounded so a literal
|
|
100
|
+
* like `scale-[1.7]` doesn't carry lightningcss's f32 noise
|
|
101
|
+
* (`1.7000000476837158`) into the RN `transform` array.
|
|
100
102
|
* @param value Typed value.
|
|
101
103
|
* @returns Plain number.
|
|
102
104
|
*/
|
|
103
105
|
function numberOrPercentageToNumber(value) {
|
|
104
|
-
|
|
105
|
-
return value.value;
|
|
106
|
-
return value.value;
|
|
106
|
+
return roundNumber(value.value);
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
109
|
* Convert a length-or-percentage used by translate into the shape RN
|
|
110
110
|
* accepts (`number` for px, `string` for `%`). Percentages stay as
|
|
111
|
-
* strings so RN layout can resolve them against the element size.
|
|
111
|
+
* strings so RN layout can resolve them against the element size. Pixel
|
|
112
|
+
* values are rounded to shed f32 noise (`3.3px` → `3.299999952…`).
|
|
112
113
|
* @param value Typed length or percentage.
|
|
113
114
|
* @returns RN-style translate value.
|
|
114
115
|
*/
|
|
115
116
|
function lengthOrPercentToNumber(value) {
|
|
116
117
|
if (value.type === 'dimension')
|
|
117
|
-
return length.lengthToPx(value.value);
|
|
118
|
+
return roundNumber(length.lengthToPx(value.value));
|
|
118
119
|
if (value.type === 'value')
|
|
119
|
-
return length.lengthToPx(value.value);
|
|
120
|
+
return roundNumber(length.lengthToPx(value.value));
|
|
120
121
|
if (value.type === 'percentage')
|
|
121
122
|
return `${formatNumber(value.value * 100)}%`;
|
|
122
123
|
return 0;
|
|
123
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Round a number to 4 decimals — sheds lightningcss's f32 representation
|
|
127
|
+
* noise while staying well below subpixel / sub-percent precision.
|
|
128
|
+
* @param value Raw number.
|
|
129
|
+
* @returns Rounded number.
|
|
130
|
+
*/
|
|
131
|
+
function roundNumber(value) {
|
|
132
|
+
return Math.round(value * 10_000) / 10_000;
|
|
133
|
+
}
|
|
124
134
|
/**
|
|
125
135
|
* Render a number without trailing IEEE noise.
|
|
126
136
|
* @param value Number to format.
|
|
127
137
|
* @returns Compact string form.
|
|
128
138
|
*/
|
|
129
139
|
function formatNumber(value) {
|
|
130
|
-
|
|
131
|
-
return String(rounded);
|
|
140
|
+
return String(roundNumber(value));
|
|
132
141
|
}
|
|
133
142
|
/**
|
|
134
143
|
* Convert lightningcss's typed `transform: ...` value into RN's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.cjs","sources":["../../../../../src/core/parser/transform.ts"],"sourcesContent":["import type { Angle, LengthValue, NumberOrPercentage, Rotate, Scale, Transform, Translate } from 'lightningcss'\nimport type { RNEntry } from './types'\nimport { lengthToPx } from './length'\n\ntype RnTransformRecord = Record<string, string | number>\n\ntype DimensionPercent =\n | { type: 'dimension'; value: LengthValue }\n | { type: 'percentage'; value: number }\n | { type: 'calc'; value: unknown }\n\n/**\n * Map a single typed transform function into zero-or-more RN transform\n * operations. Compound ops (like `translate`, `scale`, `skew`) expand\n * into per-axis entries the way RN expects them.\n * @param fn Typed transform function.\n * @returns RN transform operations.\n */\nfunction mapTransformFunction(fn: Transform): RnTransformRecord[] | null {\n switch (fn.type) {\n case 'rotate':\n case 'rotateZ': {\n return [{ rotate: angleToString(fn.value) }]\n }\n case 'rotateX': {\n return [{ rotateX: angleToString(fn.value) }]\n }\n case 'rotateY': {\n return [{ rotateY: angleToString(fn.value) }]\n }\n case 'scale': {\n const [x, y] = fn.value\n return [{ scaleX: numberOrPercentageToNumber(x) }, { scaleY: numberOrPercentageToNumber(y) }]\n }\n case 'scaleX': {\n return [{ scaleX: numberOrPercentageToNumber(fn.value) }]\n }\n case 'scaleY': {\n return [{ scaleY: numberOrPercentageToNumber(fn.value) }]\n }\n case 'translateX': {\n return [{ translateX: lengthOrPercentToNumber(fn.value) }]\n }\n case 'translateY': {\n return [{ translateY: lengthOrPercentToNumber(fn.value) }]\n }\n case 'translate': {\n const [x, y] = fn.value\n const out: RnTransformRecord[] = [{ translateX: lengthOrPercentToNumber(x) }]\n if (y) out.push({ translateY: lengthOrPercentToNumber(y) })\n return out\n }\n case 'translate3d': {\n const [x, y] = fn.value\n return [{ translateX: lengthOrPercentToNumber(x) }, { translateY: lengthOrPercentToNumber(y) }]\n }\n case 'skew': {\n const [x, y] = fn.value\n const out: RnTransformRecord[] = [{ skewX: angleToString(x) }]\n if (y) out.push({ skewY: angleToString(y) })\n return out\n }\n case 'skewX': {\n return [{ skewX: angleToString(fn.value) }]\n }\n case 'skewY': {\n return [{ skewY: angleToString(fn.value) }]\n }\n default: {\n // RN doesn't have a direct equivalent for `matrix()` / `matrix3d()` /\n // `perspective()` at the transform-op level — skip silently. Tailwind's\n // generated transforms stay within rotate/translate/scale/skew.\n return null\n }\n }\n}\n\n/**\n * Serialize a typed angle into the CSS degree string RN accepts\n * (`'45deg'`, `'0.5turn'` → `'180deg'`).\n * @param angle Typed angle.\n * @returns Degree string.\n */\nfunction angleToString(angle: Angle): string {\n switch (angle.type) {\n case 'deg': {\n return `${formatNumber(angle.value)}deg`\n }\n case 'rad': {\n return `${formatNumber((angle.value * 180) / Math.PI)}deg`\n }\n case 'grad': {\n return `${formatNumber((angle.value * 360) / 400)}deg`\n }\n case 'turn': {\n return `${formatNumber(angle.value * 360)}deg`\n }\n default: {\n return '0deg'\n }\n }\n}\n\n/**\n * Convert a `NumberOrPercentage` to a plain number. Percentages become\n * their fractional equivalent (e.g. `50%` → `0.5`).\n * @param value Typed value.\n * @returns Plain number.\n */\nfunction numberOrPercentageToNumber(value: NumberOrPercentage): number {\n if (value.type === 'percentage') return value.value\n return value.value\n}\n\n/**\n * Convert a length-or-percentage used by translate into the shape RN\n * accepts (`number` for px, `string` for `%`). Percentages stay as\n * strings so RN layout can resolve them against the element size.\n * @param value Typed length or percentage.\n * @returns RN-style translate value.\n */\nfunction lengthOrPercentToNumber(value: DimensionPercent | { type: 'value'; value: LengthValue }): number | string {\n if (value.type === 'dimension') return lengthToPx(value.value)\n if (value.type === 'value') return lengthToPx(value.value)\n if (value.type === 'percentage') return `${formatNumber(value.value * 100)}%`\n return 0\n}\n\n/**\n * Render a number without trailing IEEE noise.\n * @param value Number to format.\n * @returns Compact string form.\n */\nfunction formatNumber(value: number): string {\n const rounded = Math.round(value * 10_000) / 10_000\n return String(rounded)\n}\n\n/**\n * Convert lightningcss's typed `transform: ...` value into RN's\n * `transform: [{ op: value }, ...]` array. RN supports a restricted subset\n * of CSS transforms — this function picks out the ones it actually\n * handles and drops the rest.\n *\n * Reanimated v4's CSS engine reads this same array shape, so the output\n * is drop-in for both static RN `style` props and `Animated.View` styles.\n * @param fns Typed transform function list.\n * @returns Zero-or-one RN entry with the `transform` array.\n */\nexport function transformFunctionsToEntries(fns: readonly Transform[]): readonly RNEntry[] {\n const ops: RnTransformRecord[] = []\n for (const fn of fns) {\n const mapped = mapTransformFunction(fn)\n if (mapped) ops.push(...mapped)\n }\n if (ops.length === 0) return []\n return [['transform', ops]]\n}\n\n/**\n * Convert Tailwind v4's typed `rotate: ...` (individual property) into\n * the RN transform array. Tailwind's `rotate-*` utilities emit this\n * property rather than the classic `transform: rotate(...)` shorthand.\n * @param value Typed rotate value.\n * @returns Zero-or-one RN entry.\n */\nexport function rotateToEntries(value: Rotate | 'none'): readonly RNEntry[] {\n if (value === 'none') return []\n return [['transform', [{ rotate: angleToString(value.angle) }]]]\n}\n\n/**\n * Convert Tailwind v4's typed `translate: ...` into the RN transform\n * array. Both axes are emitted as separate ops so each is independently\n * animatable by Reanimated.\n * @param value Typed translate value.\n * @returns Zero-or-one RN entry.\n */\nexport function translateToEntries(value: Translate | 'none'): readonly RNEntry[] {\n if (value === 'none') return []\n const ops: RnTransformRecord[] = [{ translateX: lengthOrPercentToNumber(value.x) }]\n const yNumber = lengthOrPercentToNumber(value.y)\n if (yNumber !== 0) ops.push({ translateY: yNumber })\n return [['transform', ops]]\n}\n\n/**\n * Convert Tailwind v4's typed `scale: ...` into the RN transform array.\n * @param value Typed scale value.\n * @returns Zero-or-one RN entry.\n */\nexport function scaleToEntries(value: Scale | 'none'): readonly RNEntry[] {\n if (value === 'none') return []\n return [['transform', [{ scaleX: numberOrPercentageToNumber(value.x) }, { scaleY: numberOrPercentageToNumber(value.y) }]]]\n}\n"],"names":["lengthToPx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transform.cjs","sources":["../../../../../src/core/parser/transform.ts"],"sourcesContent":["import type { Angle, LengthValue, NumberOrPercentage, Rotate, Scale, Transform, Translate } from 'lightningcss'\nimport type { RNEntry } from './types'\nimport { lengthToPx } from './length'\n\ntype RnTransformRecord = Record<string, string | number>\n\ntype DimensionPercent =\n | { type: 'dimension'; value: LengthValue }\n | { type: 'percentage'; value: number }\n | { type: 'calc'; value: unknown }\n\n/**\n * Map a single typed transform function into zero-or-more RN transform\n * operations. Compound ops (like `translate`, `scale`, `skew`) expand\n * into per-axis entries the way RN expects them.\n * @param fn Typed transform function.\n * @returns RN transform operations.\n */\nfunction mapTransformFunction(fn: Transform): RnTransformRecord[] | null {\n switch (fn.type) {\n case 'rotate':\n case 'rotateZ': {\n return [{ rotate: angleToString(fn.value) }]\n }\n case 'rotateX': {\n return [{ rotateX: angleToString(fn.value) }]\n }\n case 'rotateY': {\n return [{ rotateY: angleToString(fn.value) }]\n }\n case 'scale': {\n const [x, y] = fn.value\n return [{ scaleX: numberOrPercentageToNumber(x) }, { scaleY: numberOrPercentageToNumber(y) }]\n }\n case 'scaleX': {\n return [{ scaleX: numberOrPercentageToNumber(fn.value) }]\n }\n case 'scaleY': {\n return [{ scaleY: numberOrPercentageToNumber(fn.value) }]\n }\n case 'translateX': {\n return [{ translateX: lengthOrPercentToNumber(fn.value) }]\n }\n case 'translateY': {\n return [{ translateY: lengthOrPercentToNumber(fn.value) }]\n }\n case 'translate': {\n const [x, y] = fn.value\n const out: RnTransformRecord[] = [{ translateX: lengthOrPercentToNumber(x) }]\n if (y) out.push({ translateY: lengthOrPercentToNumber(y) })\n return out\n }\n case 'translate3d': {\n const [x, y] = fn.value\n return [{ translateX: lengthOrPercentToNumber(x) }, { translateY: lengthOrPercentToNumber(y) }]\n }\n case 'skew': {\n const [x, y] = fn.value\n const out: RnTransformRecord[] = [{ skewX: angleToString(x) }]\n if (y) out.push({ skewY: angleToString(y) })\n return out\n }\n case 'skewX': {\n return [{ skewX: angleToString(fn.value) }]\n }\n case 'skewY': {\n return [{ skewY: angleToString(fn.value) }]\n }\n default: {\n // RN doesn't have a direct equivalent for `matrix()` / `matrix3d()` /\n // `perspective()` at the transform-op level — skip silently. Tailwind's\n // generated transforms stay within rotate/translate/scale/skew.\n return null\n }\n }\n}\n\n/**\n * Serialize a typed angle into the CSS degree string RN accepts\n * (`'45deg'`, `'0.5turn'` → `'180deg'`).\n * @param angle Typed angle.\n * @returns Degree string.\n */\nfunction angleToString(angle: Angle): string {\n switch (angle.type) {\n case 'deg': {\n return `${formatNumber(angle.value)}deg`\n }\n case 'rad': {\n return `${formatNumber((angle.value * 180) / Math.PI)}deg`\n }\n case 'grad': {\n return `${formatNumber((angle.value * 360) / 400)}deg`\n }\n case 'turn': {\n return `${formatNumber(angle.value * 360)}deg`\n }\n default: {\n return '0deg'\n }\n }\n}\n\n/**\n * Convert a `NumberOrPercentage` to a plain number. Percentages become\n * their fractional equivalent (e.g. `50%` → `0.5`). Rounded so a literal\n * like `scale-[1.7]` doesn't carry lightningcss's f32 noise\n * (`1.7000000476837158`) into the RN `transform` array.\n * @param value Typed value.\n * @returns Plain number.\n */\nfunction numberOrPercentageToNumber(value: NumberOrPercentage): number {\n return roundNumber(value.value)\n}\n\n/**\n * Convert a length-or-percentage used by translate into the shape RN\n * accepts (`number` for px, `string` for `%`). Percentages stay as\n * strings so RN layout can resolve them against the element size. Pixel\n * values are rounded to shed f32 noise (`3.3px` → `3.299999952…`).\n * @param value Typed length or percentage.\n * @returns RN-style translate value.\n */\nfunction lengthOrPercentToNumber(value: DimensionPercent | { type: 'value'; value: LengthValue }): number | string {\n if (value.type === 'dimension') return roundNumber(lengthToPx(value.value))\n if (value.type === 'value') return roundNumber(lengthToPx(value.value))\n if (value.type === 'percentage') return `${formatNumber(value.value * 100)}%`\n return 0\n}\n\n/**\n * Round a number to 4 decimals — sheds lightningcss's f32 representation\n * noise while staying well below subpixel / sub-percent precision.\n * @param value Raw number.\n * @returns Rounded number.\n */\nfunction roundNumber(value: number): number {\n return Math.round(value * 10_000) / 10_000\n}\n\n/**\n * Render a number without trailing IEEE noise.\n * @param value Number to format.\n * @returns Compact string form.\n */\nfunction formatNumber(value: number): string {\n return String(roundNumber(value))\n}\n\n/**\n * Convert lightningcss's typed `transform: ...` value into RN's\n * `transform: [{ op: value }, ...]` array. RN supports a restricted subset\n * of CSS transforms — this function picks out the ones it actually\n * handles and drops the rest.\n *\n * Reanimated v4's CSS engine reads this same array shape, so the output\n * is drop-in for both static RN `style` props and `Animated.View` styles.\n * @param fns Typed transform function list.\n * @returns Zero-or-one RN entry with the `transform` array.\n */\nexport function transformFunctionsToEntries(fns: readonly Transform[]): readonly RNEntry[] {\n const ops: RnTransformRecord[] = []\n for (const fn of fns) {\n const mapped = mapTransformFunction(fn)\n if (mapped) ops.push(...mapped)\n }\n if (ops.length === 0) return []\n return [['transform', ops]]\n}\n\n/**\n * Convert Tailwind v4's typed `rotate: ...` (individual property) into\n * the RN transform array. Tailwind's `rotate-*` utilities emit this\n * property rather than the classic `transform: rotate(...)` shorthand.\n * @param value Typed rotate value.\n * @returns Zero-or-one RN entry.\n */\nexport function rotateToEntries(value: Rotate | 'none'): readonly RNEntry[] {\n if (value === 'none') return []\n return [['transform', [{ rotate: angleToString(value.angle) }]]]\n}\n\n/**\n * Convert Tailwind v4's typed `translate: ...` into the RN transform\n * array. Both axes are emitted as separate ops so each is independently\n * animatable by Reanimated.\n * @param value Typed translate value.\n * @returns Zero-or-one RN entry.\n */\nexport function translateToEntries(value: Translate | 'none'): readonly RNEntry[] {\n if (value === 'none') return []\n const ops: RnTransformRecord[] = [{ translateX: lengthOrPercentToNumber(value.x) }]\n const yNumber = lengthOrPercentToNumber(value.y)\n if (yNumber !== 0) ops.push({ translateY: yNumber })\n return [['transform', ops]]\n}\n\n/**\n * Convert Tailwind v4's typed `scale: ...` into the RN transform array.\n * @param value Typed scale value.\n * @returns Zero-or-one RN entry.\n */\nexport function scaleToEntries(value: Scale | 'none'): readonly RNEntry[] {\n if (value === 'none') return []\n return [['transform', [{ scaleX: numberOrPercentageToNumber(value.x) }, { scaleY: numberOrPercentageToNumber(value.y) }]]]\n}\n"],"names":["lengthToPx"],"mappings":"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"}
|