Skip to content

feat(primitives): support primitive-to-primitive references with forward-reference and cycle diagnostics #31

Description

@Hebilicious

Goal

Support semantic and component token layers through the existing primitives abstraction:

palette / spacing / typography
              ↓
      semantic primitives
              ↓
      component primitives

No separate semantic-token module or configuration DSL is needed.

Current limitation

At 94bf4d8, processPrimitives() creates primitives.* entries in its output map, but supplies only colors, typography, and spacing to reference resolution. The resolver has no primitives case.

Consequently, a reference such as:

variables: {
  action: "primitives.semantic.action.background",
}

reaches the unsupported-module error rather than resolving to the generated custom-property name.

Raw var(--semantic-action-background) references can already be written directly. The missing capability is the configuration-path reference contract, validation, and tooling—not CSS's ability to compose custom properties.

Proposed implementation direction

Use an order-independent registry of token identities. A two-pass approach can first register all primitive paths and generated names, then resolve references and emit declarations. Add graph validation for missing paths and cycles; topological processing is an option, not a requirement to eagerly evaluate CSS.

Preserve var() references in CSS output. Do not flatten aliases into literal values, because that would change native theming and cascade behavior.

Acceptance criteria

  • primitives.<primitive>.<variant>.<property> references resolve through the existing variables map.
  • Forward references and multi-hop primitive references work independent of object insertion order.
  • Existing palette, theme, spacing, and typography references keep working.
  • Unknown references report both the requesting token and the missing path.
  • Self-references and cycles among co-active declarations report a readable path, for example primitives.a.default.x → primitives.b.default.x → primitives.a.default.x.
  • Do not report cycles solely by combining mutually exclusive declarations if conditional primitives are introduced later.
  • Output retains native custom-property aliases and does not introduce runtime styling code.
  • Document semantic primitives as well as component primitives, with a complete palette → semantic → component example and generated output.
  • Coordinate provenance/reference metadata with Add Style Dictionary token output #20 and scope diagnostics with feat(validation): add conservative diagnostics for selector- and condition-scoped token references #30.

Non-goals

A separate semantic module, a prettier hand-authored DSL, arbitrary component-style composition, and TypeScript style bindings in Vue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions