google-labs-code / google-labs-code/design.md

No way to declare intentional component sub-tokens, so every recipe warns

Open
#171 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
28k
Forks
2.3k
PR merge metrics
No merged PRs in 30d

Description

Custom component sub-tokens already work: they parse, their token references resolve, and they survive into the resolved model, so a project can build on them. design.md lint exits 0. The gap is that there's no way to tell the linter which ones are intentional, so broken-ref warns once per recipe, forever.

Our design system records two sub-tokens per recipe that the exporter schema doesn't define: owner, the canonical code module implementing the recipe, and gap, a resolved spacing value for compositions that own the spacing between their children. Our build step reads the linter's resolved model and generates a typed contract from both.

That's 49 of our 62 warnings today, growing with every component. The cost isn't the volume, it's that a misspelled sub-token produces a warning that reads identically to the 48 expected ones — the check's real value is buried by its own false positives.

Blanket suppression isn't what we want, and it isn't really available anyway: the sub-token check lives inside broken-ref alongside dangling-reference errors, so deselecting the rule through LintOptions.rules would silence genuine errors. Since 0.4.0 we post-process the report instead, matching finding.rule plus the token path against a list of extensions we declare ourselves — which works, but means we maintain the typo defense the linter could be providing.

What would solve it, in order of preference:

  1. Per-rule options. A way to pass configuration to a rule — for broken-ref, the set of sub-token names the project owns. Validation then runs against the union, and anything unlisted still warns. This generalizes past our case; sub-tokens just happen to be where we hit it first.
  2. A frontmatter declaration, so the extension names live next to the recipes that use them and travel with the document.
  3. A documented extension prefix such as x-owner, treated as always-valid. Cheapest to implement, but it renames keys in every recipe and in the resolved model.

Any of these lets a project keep the typo detection instead of reimplementing it. Happy to send a PR in whichever direction you prefer.

Checked in 0.3.0 and 0.4.0: VALID_COMPONENT_SUB_TOKENS, the broken-ref implementation, and LintOptions are identical. loadSpecConfig(filePath?) accepts a path but getSpecConfig() calls it with no argument and it isn't exported. The 0.4.0 omitted: key covers section-level omissions, not sub-tokens.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the broken-ref implementation, VALID_COMPONENT_SUB_TOKENS, and LintOptions, then inspect how design.md lint produces resolved-model findings. Determine how per-rule configuration could declare owned sub-token names while preserving warnings for unlisted names and dangling references. Done means intentional sub-tokens no longer produce repeated warnings, while misspelled or unresolved references still do.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.