Skip to content

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 02:17
· 7 commits to main since this release

Added

  • DEFAULT Key for Scalar/Nested Conflicts: Automatically use DEFAULT key when both scalar and nested values exist at the same path
    • Prevents loss of scalar values when nested properties are added
    • Matches Tailwind's color scale convention (blue.DEFAULT, blue.500, etc.)
    • Works across all namespaces (colors, spacing, shadows, etc.)
    • Handles all nesting configurations (maxDepth, flattenMode, consecutiveDashes)
    • Example: --color-card: blue + --color-card-foreground: white{ card: { DEFAULT: 'blue', foreground: 'white' } }
    • Applied in both directions (scalar first or nested first)
    • 13 comprehensive integration tests covering all scenarios
  • Configurable Nesting System: Control how CSS variable names are parsed into nested theme structures
    • New NestingOptions interface for per-namespace nesting configuration
    • maxDepth option to limit nesting levels (after limit, remaining parts flatten to camelCase)
    • consecutiveDashesAsCamelCase flag to treat consecutive dashes (--) as camelCase boundaries
    • Per-namespace configuration with default fallback for global settings
    • Default behavior: Unlimited nesting for all namespaces (colors, shadows, spacing, etc.)
    • Backward compatible: Only applies when explicitly configured
    • Vite plugin support via nesting option
    • CLI support via --nesting-max-depth <number> and --nesting-consecutive-camel flags
    • Runtime API support via nesting parameter in resolveTheme()
    • New parseNestedKey() function with full configuration support
    • 17 comprehensive integration tests covering all nesting scenarios
  • Flatten Mode Option: Control how remaining parts are flattened after maxDepth is reached
    • New flattenMode option in NestingConfig: 'camelcase' (default) or 'literal'
    • 'camelcase' (default): Flatten remaining parts to camelCase (e.g., colors.blue.skyLight50)
    • 'literal': Flatten remaining parts to single kebab-case string key (e.g., colors.blue['sky-light-50'])
    • Only applies when maxDepth is set and reached
    • Vite plugin support via nesting.colors.flattenMode
    • CLI support via --nesting-flatten-mode <mode> flag
    • Runtime API support via nesting.colors.flattenMode
    • Comprehensive test coverage for both flattening modes
  • Exported type guards isConflictReportJSON() and isUnresolvedReportJSON() from reporting modules for safe JSON report parsing

Fixed

  • Keyword Variants in Color Scales: Color scales now support keyword variants (base, dark, light, etc.) creating properly nested structures (#4)
    • Before: --color-green-basecolors.greenBase (flat, incorrect)
    • After: --color-green-basecolors.green.base (nested, correct)
    • Solved via configurable nesting system with unlimited depth by default
    • Works for all keyword variants: base, dark, light, DEFAULT, or any custom keywords
    • Example: --color-green-500, --color-green-base, --color-green-dark all nest under colors.green
  • Variable Resolution with Tailwind Defaults: Fixed chained var() resolution when using nesting configuration with Tailwind defaults
    • Before: Variables like --color-chart-1: var(--chart-1) (in @theme) referencing :root variables that reference defaults would remain unresolved
    • Example: --chart-1: var(--color-blue-300) would show "var(--color-blue-300)" instead of the actual color from defaults
    • Root cause: Nesting transformations changed variable names (e.g., blue-300blue300), breaking var() resolution
    • After: Original CSS variables from Tailwind defaults are preserved alongside transformed theme structure
    • Changed loadTailwindDefaults() to return both theme and original variables array
    • Changed buildThemes() to accept original default variables instead of reconstructed ones
    • Variable resolution now works correctly through the full chain: @theme:rootdefaults
    • All 745 tests passing with zero regressions
  • flattenMode with maxDepth: 0: Fixed bug where flattenMode was ignored when maxDepth: 0. Now correctly respects both 'camelcase' and 'literal' modes when flattening all parts.
    • Before: maxDepth: 0 always used camelCase regardless of flattenMode setting
    • After: maxDepth: 0 with flattenMode: 'literal' creates kebab-case keys (e.g., colors['card-foreground'])
    • After: maxDepth: 0 with flattenMode: 'camelcase' (default) creates camelCase keys (e.g., colors.cardForeground)
    • Applies flattening logic consistently across all maxDepth values

Changed

  • Breaking: Replaced consecutiveDashesAsCamelCase boolean with consecutiveDashes enum for more flexible handling of consecutive dashes in CSS variable names
    • Old API: consecutiveDashesAsCamelCase?: boolean (default: false → preserve consecutive dashes)
    • New API: consecutiveDashes?: 'exclude' | 'nest' | 'camelcase' | 'literal' (default: 'exclude' → matches Tailwind v4)
    • 'exclude' (new default): Skip variables with consecutive dashes entirely (matches Tailwind v4 behavior)
    • 'nest': Treat consecutive dashes as single dash (nesting boundary)
    • 'camelcase': Convert consecutive dashes to camelCase boundary (old true behavior)
    • 'literal': Preserve consecutive dashes in keys (old false behavior)
    • Example: --color-button--primary: #fff;
      • 'exclude' (default): Not included in theme
      • 'nest': colors.button.primary
      • 'camelcase': colors.buttonPrimary
      • 'literal': colors['button-'].primary
    • CLI flag updated: --nesting-consecutive-camel--nesting-consecutive-dashes <mode>
    • Vite plugin option updated: nesting.colors.consecutiveDashesAsCamelCasenesting.colors.consecutiveDashes
    • Runtime API option updated: nesting.colors.consecutiveDashesAsCamelCasenesting.colors.consecutiveDashes
    • Migration: Replace consecutiveDashesAsCamelCase: true with consecutiveDashes: 'camelcase'
    • Migration: Replace consecutiveDashesAsCamelCase: false (or omitted) with consecutiveDashes: 'literal' for old behavior, or omit for new default
  • Breaking: Renamed includeTailwindDefaults to includeDefaults for simpler, shorter API
    • Old API: includeTailwindDefaults?: boolean | TailwindDefaultsOptions
    • New API: includeDefaults?: boolean | TailwindDefaultsOptions
    • Functionality remains identical - same granular control over Tailwind default theme inclusion
    • Migration: Replace all instances of includeTailwindDefaults with includeDefaults in Runtime API, Vite Plugin, and File Generator configurations
  • Documentation: Restructured all documentation with improved navigation and organization
    • Added table of contents to ARCHITECTURE.md, bench/README.md, and CONTRIBUTING.md for easier navigation
    • Improved formatting and section structure in test/README.md
    • Better logical flow with horizontal separators between major sections
    • Consistent structure across all documentation files

Refactored

  • Internal: Reorganized source directory structure from src/v4/parser/ to src/v4/core/ with organized subdirectories
    • core/parser/ - CSS parsing and import resolution
    • core/analysis/ - Conflict and unresolved variable detection
    • core/reporting/ - Report generation (Markdown and JSON)
    • core/theme/ - Theme building and defaults
    • core/extraction/ - CSS rule extraction
    • core/utils/ - Shared utilities and helper functions
    • core/constants/ - Constants and formatting
  • Internal: All files renamed from kebab-case to snake_case convention
    • Source: css-parser.tscss.ts, theme-builder.tsbuilder.ts
    • Tests: {module}.test.ts{module}_test.ts
    • Fixtures: base-theme.cssbase_theme.css
  • Code deduplication through extraction of shared utilities (LRU cache, type guards, formatting helpers)
  • Enhanced type safety with runtime type guards and explicit JSON validation