Problem
Conventions describe one library — the Figma file — and nothing else. A code generator reading a spec has no way to know which of a design system's own components means "text", "glyph", or "container", so it emits host elements: a <span> where the design system requires DsText. Compositions are built almost entirely out of these primitives, so the gap is most of what a composition is.
The same shape has no room for the answer, because it is namespaced figma rather than by platform — and the answer differs per implementation: DsText in React, <ds-text> in Web Components, Text in SwiftUI. Figma is itself one of those implementations, since specs are rendered back onto the canvas.
Two smaller gaps ride along: a spec records every platform a workspace configures rather than the one that produced it, and nothing states the width a component should be shown at when its root resizes to fill a parent it does not have.
Solution
Conventions become platform-keyed, with figma as one implementation among react, web-components and swiftui. Each platform declares which of its components implements each spec primitive, and how the spec's concepts reach that component's props. Each platform is authored as its own file in config/conventions/, named for the platform id.
The spec contract itself does not change: an element stays type: text, and each generator resolves it to its own component at emit time, so one spec serves every implementation.
Acceptance criteria
Problems
- Conventions have no platform axis, so there is nowhere to put a spec-to-code binding
- A generator emits host elements instead of the design system's own components
- Every platform's conventions share one file, with one owner per section and unrelated review cadences
- A spec's metadata carries platforms that had no part in producing it
- A fill-width root has no declared width when shown standalone
Impacted code
specs — packages/schema (landed), packages/cli (loader, templates, migration, ~24 read sites), site/ docsspecs-from-figma — reads the conventions object handed to Component; ~13 source files, ~44 test fixturesfigma-from-specs — Elements, KeyReversal, CodeOnlyPropsreact-from-specs / webcomponents-from-specs — implement primitive resolutionspecs-plugin-2 — one translation point in SpecsController
Related Docs
Notes
ADRs 073–079 and 081, on adr/primitive-composition (PR #363).
Order of implementation is schema → specs-from-figma → CLI, since the CLI depends on the engine. Schema is landed; everything downstream is outstanding, including ADR-078's loader, which has no schema-package surface at all.
Implementation details are tracked internally.
Problem
Conventions describe one library — the Figma file — and nothing else. A code generator reading a spec has no way to know which of a design system's own components means "text", "glyph", or "container", so it emits host elements: a
<span>where the design system requiresDsText. Compositions are built almost entirely out of these primitives, so the gap is most of what a composition is.The same shape has no room for the answer, because it is namespaced
figmarather than by platform — and the answer differs per implementation:DsTextin React,<ds-text>in Web Components,Textin SwiftUI. Figma is itself one of those implementations, since specs are rendered back onto the canvas.Two smaller gaps ride along: a spec records every platform a workspace configures rather than the one that produced it, and nothing states the width a component should be shown at when its root resizes to fill a parent it does not have.
Solution
Conventions become platform-keyed, with
figmaas one implementation amongreact,web-componentsandswiftui. Each platform declares which of its components implements each spec primitive, and how the spec's concepts reach that component's props. Each platform is authored as its own file inconfig/conventions/, named for the platform id.The spec contract itself does not change: an element stays
type: text, and each generator resolves it to its own component at emit time, so one spec serves every implementation.Acceptance criteria
config/conventions/, the filename carrying the platform idconfig/conventions.yamlgets an error naming the directory it should become, not a silent fall back to defaultsspecs generatereads thefigmaentry and produces specs unchanged from todaystylesPropmetadata.conventionsrecords only the platform that produced itProblems
Impacted code
specs—packages/schema(landed),packages/cli(loader, templates, migration, ~24 read sites),site/docsspecs-from-figma— reads the conventions object handed toComponent; ~13 source files, ~44 test fixturesfigma-from-specs—Elements,KeyReversal,CodeOnlyPropsreact-from-specs/webcomponents-from-specs— implement primitive resolutionspecs-plugin-2— one translation point inSpecsControllerRelated Docs
Notes
ADRs 073–079 and 081, on
adr/primitive-composition(PR #363).Order of implementation is schema →
specs-from-figma→ CLI, since the CLI depends on the engine. Schema is landed; everything downstream is outstanding, including ADR-078's loader, which has no schema-package surface at all.