Design System Contracts

Spec reference

Anatomy & parts

The named part tree — where structure, text, icons, and every styling decision live. One definition; a frame tree and an element tree are both renderings of it.

The part treeGeneratedCurated#

Anatomy is a nested tree of named parts (Record<partName, Part>) — contracts are authored and reviewed by humans, and a tree reads like the component. A root part is mandatory. Part names are unique per contract. Every styling decision lives here as a token binding; there is no handwritten style layer to drift.

A part is structural by default (a frame on the canvas, an element in code, containing parts), or it plays one of the roles on this and the following pages: text content, icon, meter, shape, slot / component ref / repeat template.

descriptionstring

Reviewer-facing note on the part’s purpose.

elementstring

HTML element for this part (code side). Defaults: div structural, span content. Root uses semantics.element.

roleExceptionstring

Named exception to the native-semantics lint — see Semantics.

layoutLayout

Flexbox / auto-layout — see Layout.

layoutByPropLayoutByProp

Per-enum-value layout overrides — see Layout.

stylesWhenStylesWhen[]

Conditional literal styles — see Conditionals.

overlayOverlay

Out-of-flow edge attachment — see Conditionals.

shapeShape

Parametric leaf decor — see Shape parts.

tokensRecord<string, TokenRef>

CSS property → token reference — see Token bindings.

tokensByPropTokensByProp | TokensByProp[]

Per-enum-value token overrides — see Token bindings.

literalsRecord<string, string>
literalsByPropLiteralsByProp[]
declaredRecord<string, string>
declaredStatesRecord<string, Record<string, string>>
hugsBelowMaxWidthboolean
statesRecord<string, Record<string, TokenRef>>

Interaction-state token overrides — see States.

statesByPropArray<{ prop: string; state: string; map: Record<string, Record<string, TokenRef>> }>

Per-state token overrides that also vary by an enum axis — see States.

content{ prop: string }

Text content bound to a declared text prop — see below.

textstring

Static literal text — see below.

textByProp{ prop: string; map: Record<string, string> }

Per-enum-value text overrides merged over text — see text by prop.

meter{ valueProp: string; maxProp: string }

Progress fill geometry — see below.

animation"spin" | "pulse"

CSS-side motion — see Conditionals.

slotSlot

Constrained insertion point — see Composition.

componentComponentRef

Fixed instance of another contract — see Composition.

overridablestring[]

Root-part consent to per-instance overrides — see Composition.

repeatRepeat

Item template over an arrayOf prop — see Composition.

icon{ asset: string; size?: number }

Icon asset part — see below.

attrsRecord<string, string>

HTML/ARIA attributes — see below.

visibleWhenVisibleWhen

Conditional visibility — see Conditionals.

optionalboolean

Optional parts render conditionally (code: when the slot prop is provided; canvas: a “Show X” boolean controls visibility).

partsRecord<string, Part>

Child parts — the tree.

StructureCurated#

Composition rules enforced at build time: part names unique per contract, a mandatory root, cycles and unknown contract references fail the build, and sync scripts emit in dependency order. A duplicate anatomy part name is refused by name.

contracts/banner.contract.json (excerpt · v1.0.0) — shipping contract, loaded at build time · a structural part with content-bound children
{
  "anatomy": {
    "root": {
      "parts": {
        "body": {
          "layout": {
            "direction": "column",
            "grow": true
          },
          "tokens": {
            "gap": "{space.inset-y.sm}"
          },
          "parts": {
            "title": {
              "element": "div",
              "content": {
                "prop": "title"
              },
              "tokens": {
                "font-family": "{font.control.family}",
                "font-size": "{font.control.size.md}",
                "font-weight": "{font.title.weight}"
              }
            },
            "descriptionText": {
              "element": "div",
              "content": {
                "prop": "description"
              },
              "tokens": {
                "font-family": "{font.control.family}",
                "font-size": "{font.control.size.sm}"
              }
            }
          }
        }
      }
    }
  }
}

Text: content & literal textGeneratedCurated#

content: { prop } binds a part’s text to a declared text prop — {title} in the part’s element on the code side, a text node linked to the text property on the canvas. text is static literal text (a page number, an ellipsis) — the same on both surfaces, bound to nothing.

Refusals: Each of these fails the build by name — the generator refuses, it never papers over (source: core/emit-react.ts validateContract, exercised by the C2 eval family).

  • content.prop must name a declared text prop (checked against the prop’s code binding name)
contracts/banner.contract.json (excerpt · v1.0.0) — shipping contract, loaded at build time
{
  "anatomy": {
    "root": {
      "parts": {
        "body": {
          "parts": {
            "title": {
              "element": "div",
              "content": {
                "prop": "title"
              },
              "tokens": {
                "font-family": "{font.control.family}",
                "font-size": "{font.control.size.md}",
                "font-weight": "{font.title.weight}"
              }
            }
          }
        }
      }
    }
  }
}

Text by propGeneratedCurated#

textByProp: { prop, map } — static text selected by an enum value. When a drawn text node’s characters vary as a pure function of one enum axis, the deviating values ride a lookup keyed on that prop’s canonical values — the tokensByProp discipline applied to characters. Requires a base text (the default value’s text); a value absent from the map renders the base. Field cases: the Untitled UI Slider’s value labels ("25%"/"50%"/"75%" keyed on leftControl/rightControl), ProgressBar’s percentage text, SocialButton’s “Sign in with …”.

proprequiredstring

The driving enum prop, by canonical name.

maprequiredRecord<string, string>

enum value → literal text, merged over the base text.

Refusals: Each of these fails the build by name — the generator refuses, it never papers over (source: core/emit-react.ts validateContract, exercised by the C2 eval family).

  • textByProp without a base text
  • an unknown driving prop; a map key outside its canonical values
the Slider’s left value label (committed usage: examples/untitled-ui/storybook/contracts/slider.contract.json) — illustrative, schema-validated at build time
{
  "element": "span",
  "text": "25%",
  "textByProp": {
    "prop": "leftControl",
    "map": {
      "25": "25%",
      "50": "50%",
      "75": "75%"
    }
  }
}

Icon partsGeneratedCurated#

icon: { asset, size? } renders assets/icons/<asset>.svg inline on the code side and as a vector on the canvas. '{prop}' substitutes an enum prop — icon-by-status. Icons are always decorative (aria-hidden).

Refusals: Each of these fails the build by name — the generator refuses, it never papers over (source: core/emit-react.ts validateContract, exercised by the C2 eval family).

  • an icon asset that does not exist on disk — needs icon asset "assets/icons/….svg" which does not exist
contracts/banner.contract.json (excerpt · v1.0.0) — shipping contract, loaded at build time
{
  "anatomy": {
    "root": {
      "parts": {
        "statusIcon": {
          "description": "Leading icon, selected by status. Decorative — hidden from assistive tech.",
          "icon": {
            "asset": "{status}"
          }
        }
      }
    }
  }
}

AttributesGeneratedCurated#

attrs sets HTML/ARIA attributes on the part’s element — literal strings or '{prop}' references (refused when the prop doesn’t exist). Code-side surface; the canvas ignores it. A real <input type="checkbox|radio"> declared this way is recognized as a native checkable control: code surfaces render it as the focusable control (checked state is DOM state, never ARIA), and the canvas draws nothing for it — semantics don’t draw.

contracts/checkbox.contract.json (excerpt · v2.0.0) — shipping contract, loaded at build time
{
  "anatomy": {
    "root": {
      "parts": {
        "box": {
          "parts": {
            "input": {
              "description": "The real checkable control — a native input. Checked and indeterminate are DOM state (checked + el.indeterminate), never ARIA attributes; the wrapping label gives implicit association. Canvas: not drawn (semantics don't draw).",
              "element": "input",
              "attrs": {
                "type": "checkbox"
              }
            }
          }
        }
      }
    }
  }
}

Meter partsGeneratedCurated#

meter: { valueProp, maxProp } — progress fill: width = value/max as a percentage of the parent track. Code computes live; the canvas renders the defaults’ fraction — its honest static state. The same discipline repeats across the spec: where a surface cannot run a live computation, it renders the declared sample and says so.

contracts/progress-bar.contract.json (excerpt · v1.0.1) — shipping contract, loaded at build time
{
  "anatomy": {
    "root": {
      "parts": {
        "track": {
          "layout": {
            "direction": "row",
            "align": "center"
          },
          "tokens": {
            "width": "{size.progress.width}",
            "height": "{size.progress.height}",
            "background-color": "{color.progress.track}",
            "border-radius": "{radius.100}"
          },
          "parts": {
            "fill": {
              "meter": {
                "valueProp": "value",
                "maxProp": "max"
              },
              "tokens": {
                "height": "{size.progress.height}",
                "background-color": "{color.progress.{variant}}",
                "border-radius": "{radius.100}"
              }
            }
          }
        }
      }
    }
  }
}