Skip to content

feat: add CSS token hoisting with comment-based signal bindings#82

Merged
mohamedmansour merged 1 commit intomainfrom
feat/css-token-hoisting
Mar 7, 2026
Merged

feat: add CSS token hoisting with comment-based signal bindings#82
mohamedmansour merged 1 commit intomainfrom
feat/css-token-hoisting

Conversation

@mohamedmansour
Copy link
Copy Markdown
Contributor

Extract CSS custom property usages (var() calls) at build time across all components and entry page styles. The sorted, deduplicated token names are included in the protocol output, enabling host runtimes to resolve only the design tokens an application actually needs.

Protocol schema:

  • Add 'repeated string tokens = 2' to WebUIProtocol message
  • Add WebUIProtocol::new() and ::with_tokens() constructors
  • Replace all struct literals with constructor calls (109 sites)

CSS token extraction (webui-parser/css_parser.rs):

  • Add CssParser::extract_tokens() for var() usage extraction
  • Add CssParser::extract_definitions() for custom property definitions
  • Add CssParser::extract_tokens_and_definitions() for single-parse path
  • Iterative tree-sitter-css AST walk (no recursion)
  • Handle nested fallbacks: var(--a, var(--b, var(--c))) extracts all three
  • Exclude locally-defined properties (--name: value) from token set
  • Implement Debug for CssParser (tree-sitter Parser lacks it)

Component registry (webui-parser/component_registry.rs):

  • Add css_tokens field to Component struct
  • Extract tokens automatically during register_component() and register_component_from_paths()
  • ComponentRegistry owns a reusable CssParser instance (not per-call)

Token collection during parsing (webui-parser/lib.rs):

  • Add token_store and token_definitions to HtmlParser
  • Merge component css_tokens on first component encounter
  • Extract tokens and definitions from inline <style> tags (single parse)
  • take_tokens() returns sorted tokens with entry definitions excluded
  • Parse HTML comments as Signal fragments

CLI integration (webui-cli):

  • Wire tokens through build_protocol() into protocol output
  • Display 'Discovered N CSS tokens' in build command output
  • Add token_count to BuildOutput

Documentation:

  • Update DESIGN.md with CSS Token Hoisting specification
  • Add docs/guide/concepts/css-tokens.md with sidebar entry

Tests (26 new tests):

  • 18 unit tests for extract_tokens, extract_definitions, combined method, edge cases (malformed var, empty var, definitions-only CSS)
  • 3 component registry tests for token extraction on registration
  • 3 protocol tests for constructors and protobuf roundtrip with tokens
  • 2 build integration tests for token inclusion and entry exclusion

…ings

Extract CSS custom property usages (var() calls) at build time across all
components and entry page styles. The sorted, deduplicated token names are
included in the protocol output, enabling host runtimes to resolve only
the design tokens an application actually needs.

Protocol schema:
- Add 'repeated string tokens = 2' to WebUIProtocol message
- Add WebUIProtocol::new() and ::with_tokens() constructors
- Replace all struct literals with constructor calls (109 sites)

CSS token extraction (webui-parser/css_parser.rs):
- Add CssParser::extract_tokens() for var() usage extraction
- Add CssParser::extract_definitions() for custom property definitions
- Add CssParser::extract_tokens_and_definitions() for single-parse path
- Iterative tree-sitter-css AST walk (no recursion)
- Handle nested fallbacks: var(--a, var(--b, var(--c))) extracts all three
- Exclude locally-defined properties (--name: value) from token set
- Implement Debug for CssParser (tree-sitter Parser lacks it)

Component registry (webui-parser/component_registry.rs):
- Add css_tokens field to Component struct
- Extract tokens automatically during register_component() and
  register_component_from_paths()
- ComponentRegistry owns a reusable CssParser instance (not per-call)

Token collection during parsing (webui-parser/lib.rs):
- Add token_store and token_definitions to HtmlParser
- Merge component css_tokens on first component encounter
- Extract tokens and definitions from inline <style> tags (single parse)
- take_tokens() returns sorted tokens with entry definitions excluded
- Parse <!--{{identifier}}--> HTML comments as Signal fragments

CLI integration (webui-cli):
- Wire tokens through build_protocol() into protocol output
- Display 'Discovered N CSS tokens' in build command output
- Add token_count to BuildOutput

Documentation:
- Update DESIGN.md with CSS Token Hoisting specification
- Add docs/guide/concepts/css-tokens.md with sidebar entry

Tests (26 new tests):
- 18 unit tests for extract_tokens, extract_definitions, combined method,
  edge cases (malformed var, empty var, definitions-only CSS)
- 3 component registry tests for token extraction on registration
- 3 protocol tests for constructors and protobuf roundtrip with tokens
- 2 build integration tests for token inclusion and entry exclusion
@mohamedmansour mohamedmansour requested review from a team, akroshg and janechu March 7, 2026 01:44
@mohamedmansour mohamedmansour merged commit 718f661 into main Mar 7, 2026
10 checks passed
@mohamedmansour mohamedmansour deleted the feat/css-token-hoisting branch March 7, 2026 05:53
@akroshg
Copy link
Copy Markdown
Contributor

akroshg commented Mar 7, 2026

The description does not talk about the handler. Do we handle these tokens at runtime in this PR or this will be separate PR?

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.

3 participants