Skip to content

fix(framework): parse space-separated hsl() color values - #307

Open
shuvamk wants to merge 1 commit into
CoreBunch:mainfrom
shuvamk:fix/hsl-space-syntax-color-tokens
Open

fix(framework): parse space-separated hsl() color values#307
shuvamk wants to merge 1 commit into
CoreBunch:mainfrom
shuvamk:fix/hsl-space-syntax-color-tokens

Conversation

@shuvamk

@shuvamk shuvamk commented Jul 29, 2026

Copy link
Copy Markdown

Summary

Color tokens authored with CSS Color-4 space syntaxhsl(0 0% 80%) and hsl(0 0% 80% / 50%) — silently lose every derived variant (transparent steps, shades, tints). Only the bare --<slug> base is emitted, verbatim.

HSLA_RE in src/core/framework/colors.ts only matched the legacy comma form with a number-only alpha:

const HSLA_RE = /^hsla?\(\s*([-+]?\d*\.?\d+)(?:deg)?\s*,\s*([-+]?\d*\.?\d+)%\s*,\s*([-+]?\d*\.?\d+)%(?:\s*,\s*([-+]?\d*\.?\d+))?\s*\)$/i

Space-separated hsl() therefore failed parseColor, fell through to the verbatim base fallback, and produced no channels to derive from. Its sibling RGBA_RE — one line below — already documents and supports "both comma and space syntax, alpha as number or percentage", so the two were asymmetric.

This matters in practice: modern CSS and common import sources (Tailwind) emit space-separated hsl(), and src/core/siteImport/colorTokens.ts even uses hsl(0 0% 80%) as a canonical example of an imported palette entry that becomes a framework color token.

Before → after

Input token lightValue Before After
hsl(0 0% 80%) 1 var (--c verbatim, no variants) base hsla(0, 0%, 80%, 1) + 10 transparent + 2 shades + 2 tints
hsl(0 0% 80% / 50%) dropped base hsla(0, 0%, 80%, 0.5) + variants
hsl(0, 0%, 80%) (comma) worked unchanged

Fix

  • Widen HSLA_RE to the same comma-or-space separator and number-or-percentage / slash-delimited alpha shape RGBA_RE already uses.
  • Extract parseAlpha and share it between the hsl and rgb branches instead of duplicating the number/percentage coercion.

No new behavior for values that already parsed; comma-syntax hsl()/hsla() output is byte-identical.

Verification

  • bun run build
  • bun test (6332 pass, 0 fail; the new test fails on main and passes with the fix)
  • bun run lint

Checklist

  • Tests cover behavior changes — added an hsl(0 0% 80%) + hsl(... / 50%) case alongside the existing rgb(5 5 5 / 78%) space-syntax test.
  • Docs were updated when behavior, config, deployment, or public surfaces changed — n/a (internal parser; no documented surface changes).
  • No compatibility shim was added for old pre-release behavior.
  • No secrets, local databases, uploads, or generated artifacts are included.

CSS Color-4 space syntax (`hsl(0 0% 80%)`, `hsl(0 0% 80% / 50%)`) is what
modern CSS and importers such as Tailwind emit, but HSLA_RE only accepted
the legacy comma form with a number-only alpha. Space-syntax hsl() tokens
fell through parseColor to the verbatim base fallback, so every derived
transparent/shade/tint variant was silently dropped.

Widen HSLA_RE to the same comma-or-space, number-or-percentage-alpha shape
its sibling RGBA_RE already uses, and share the alpha coercion between both
branches via parseAlpha.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@shuvamk
shuvamk marked this pull request as ready for review July 29, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant