Spectrum Design Data
  • Components
  • Tokens
  • Registry
  • AI
  • Specification
  • Tools
  • Draft Specification (v1.0.0-draft) — This specification is under active development. Normative text and schemas may change before the stable 1.0.0 release.

    Component format

    Spec version: 1.0.0-draft (see Overview)

    This document defines the normative component declaration object: identity ($id, name, displayName), component metadata (meta), API options (options), named content slots (slots), anatomy parts (anatomy), state model (states), and lifecycle metadata.

    Component declarations close the structural gap between the token name-object's component, variant, anatomy, and state fields and the declared surface of each component. Before this chapter, a token referencing component: "button" with variant: "foo" was undetectable as invalid because no machine-readable component contract existed in the same spec. After this chapter, validators enforce cross-reference rules (see SPEC rules).

    Scoped under RFC-A — Component Contract in Design Data Spec. See also rfc-coordination.md.

    Document shape

    A component declaration is a single JSON object in a .json file. One file per component. Files live under a components/ directory within a design-data package.

    NORMATIVE: Each component declaration file MUST validate against the Layer 1 schema component.schema.json (canonical $id: https://opensource.adobe.com/spectrum-design-data/schemas/v0/component.schema.json). Layer 1 and Layer 2 validation are defined in the validation layers section of the overview.

    Component object

    Required fields

    A component declaration MUST contain:

    Field Type Description
    $id URI string Canonical identifier for this component declaration.
    name kebab-case string Machine identifier; used as the value of the component field in token name objects.
    displayName string Human-readable component name (e.g. "Button").
    meta object Category and documentation link — see Meta.

    Optional fields

    Field Type Description
    specVersion string Declares which spec version this document targets. Currently "1.0.0-draft"; future stable releases will accept their own version string.
    description string Plain-text description of the component's purpose.
    options object Component API options — see Options.
    slots array Named content injection points — see Slots.
    anatomy array Named anatomy parts — see Anatomy (stub).
    states array Per-component state declarations — see States (stub).
    lifecycle object Version lifecycle metadata — see Lifecycle.
    tokenBindings array Tokens this component uses — see Token bindings (Phase 6.7).
    documentBlocks array Typed prose blocks for this component — see Document blocks (Phase 9).
    accessibility object Semantic accessibility vocabulary — see Accessibility (Phase 7).

    NORMATIVE: No properties beyond those listed above are permitted at the top level of a component declaration. Additional fields MUST cause a Layer 1 schema error.

    $id

    NORMATIVE: The $id MUST be a valid URI identifying this component declaration document. The recommended pattern is:

    https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/{name}.json
    

    where {name} matches the component's name field.

    name

    NORMATIVE: name MUST match the pattern ^[a-z][a-z0-9-]*$ — lower-case kebab-case, non-empty.

    NORMATIVE: name MUST be unique within a dataset. No two component declarations in the same design-data package may share a name value.

    NORMATIVE: Token name-object component field values MUST match the name of a declared component in the dataset (rule SPEC-018). An undeclared component value is a validation error.

    Meta

    NORMATIVE: meta MUST contain:

    Field Type Values
    category string (enum) actions, containers, data visualization, feedback, inputs, navigation, status, typography
    documentationUrl URI string Link to the component's documentation page.
    "meta": {
      "category": "actions",
      "documentationUrl": "https://spectrum.adobe.com/page/button/"
    }
    

    Options

    The options block declares the component's API surface — the configurable properties that affect its appearance or behavior. It mirrors the shape of @adobe/spectrum-component-api-schemas for backward compatibility.

    NORMATIVE: options MUST be a JSON object. Each key is an option name; each value is an option descriptor.

    Option descriptor

    An option descriptor is a JSON object with the following fields:

    Field Type Required Description
    type string or array OPTIONAL JSON Schema primitive type(s): "string", "boolean", "number", "integer".
    values array OPTIONAL Exhaustive list of permitted values, each an optionValue object. Use this instead of JSON Schema's enum keyword so per-value lifecycle metadata can be expressed without a separate sidecar map.
    default any OPTIONAL Default value when the option is not specified.
    description string OPTIONAL Plain-text description of what the option controls.
    $ref URI string OPTIONAL Reference to a shared type schema (e.g. workflow-icon.json).

    optionValue

    Each entry in values is an object:

    Field Type Required Description
    value any REQUIRED The permitted option value.
    description string OPTIONAL Plain-text description of what this value means.
    lifecycle object OPTIONAL Version lifecycle metadata. Set lifecycle.deprecated to signal migration via SPEC-037.

    NORMATIVE: Each key in options MUST be camelCase.

    NORMATIVE: Boolean option names MUST begin with is or has (e.g. isDisabled, hasIcon).

    NORMATIVE: When values is present, token name-object variant field values referencing this component MUST be drawn from the declared variant option values list (rule SPEC-019, Error). Token name-object keys matching any other declared option's values list SHOULD be drawn from that list (rule SPEC-040, Warning). Both rules are silent when no values array is declared for the option.

    ADVISORY: When a value in values carries a lifecycle.deprecated string and a non-deprecated token references that value via its name object field, SPEC-037 fires an advisory warning prompting migration or token deprecation.

    Example with a deprecated option value:

    "variant": {
      "type": "string",
      "values": [
        { "value": "primary" },
        { "value": "secondary" },
        {
          "value": "cta",
          "lifecycle": {
            "deprecated": "1.0.0-draft",
            "deprecatedComment": "Use primary instead."
          }
        }
      ]
    }
    
    "options": {
      "variant": {
        "type": "string",
        "values": [
          { "value": "accent" },
          { "value": "negative" },
          { "value": "primary" },
          { "value": "secondary" }
        ],
        "default": "accent",
        "description": "Visual emphasis level."
      },
      "size": {
        "type": "string",
        "values": [
          { "value": "s" },
          { "value": "m" },
          { "value": "l" },
          { "value": "xl" }
        ],
        "default": "m"
      },
      "isDisabled": {
        "type": "boolean",
        "default": false
      },
      "icon": {
        "$ref": "https://opensource.adobe.com/spectrum-design-data/schemas/types/workflow-icon.json",
        "description": "Icon placed at the start of the button. Required when hideLabel is true."
      }
    }
    

    Slots

    The slots block declares the component's named content injection points — the positions where consumers place child content. Slot declarations are derived from the cross-platform audit in audits/slots.audit.md.

    NORMATIVE: slots MUST be a JSON array. Each element is a slot declaration.

    Slot declaration

    Field Type Required Description
    name string REQUIRED Slot identifier. SHOULD come from the canonical vocabulary (see below).
    description string OPTIONAL Plain-text description of what content goes in this slot.
    required boolean OPTIONAL Whether consumers MUST populate this slot. Default: false.

    Canonical slot vocabulary

    The following slot names are defined by the cross-platform audit and SHOULD be used in preference to custom names:

    Name Semantics
    default Primary content (text, children). The main content slot.
    icon Decorative icon at the leading edge of the component.
    label Human-readable identifier / placeholder text (distinct from default).
    help-text Non-error guidance text below a form field.
    negative-help-text Validation error message for a form field.
    action Secondary interactive button or call-to-action.
    heading Section or dialog heading.
    description Section or dialog body text (distinct from help-text).
    hero Large header media (e.g. dialog hero image).
    footer Below-content supplemental area (e.g. dialog footer).
    tooltip Floating annotation attached to the component.

    NORMATIVE: Custom slot names are permitted but SHOULD be documented in the slot's description field (rule SPEC-021 fires a warning for undocumented custom names).

    RECOMMENDED: Components SHOULD declare a default slot when they accept primary child content.

    "slots": [
      {
        "name": "default",
        "description": "Text label of the button.",
        "required": false
      },
      {
        "name": "icon",
        "description": "Icon placed at the start of the button. Required when isLabelHidden is true."
      }
    ]
    

    Anatomy (stub)

    The anatomy block declares the component's named visual parts — the anatomy terms used in token name-object anatomy fields. Full normative definition is in spec/anatomy-format.md (Phase 6.2).

    NORMATIVE: anatomy MUST be a JSON array. Each element is an anatomy part object.

    NORMATIVE: Token name-object anatomy field values referencing this component MUST match the name of a declared anatomy part (rule SPEC-020).

    Each anatomy part carries at minimum:

    Field Type Required Description
    name string REQUIRED Anatomy part identifier (e.g. icon, label, handle).
    description string OPTIONAL Plain-text description of the part.
    required boolean OPTIONAL Whether this part is always present. Default: false.
    contains array of strings OPTIONAL Informative: other anatomy part names nested within this part.
    lifecycle object OPTIONAL Version lifecycle metadata for this part. When lifecycle.deprecated is set, SPEC-037 fires on referencing tokens.

    See spec/anatomy-format.md for constraints, cross-field validation, and the full anatomy part schema.

    "anatomy": [
      { "name": "icon", "description": "Leading icon." },
      { "name": "label", "description": "Button text.", "required": true }
    ]
    

    States (stub)

    The states block declares the component's interactive and semantic states — the state terms used in token name-object state fields. Full normative definition is in spec/state-model.md (Phase 6.3).

    NORMATIVE: states MUST be a JSON array. Each element is a state declaration object.

    Each state carries at minimum:

    Field Type Required Description
    name string REQUIRED State identifier (e.g. hover, focus, disabled).
    trigger string OPTIONAL "prop" for persistent prop-driven states (e.g. isDisabled) or "interaction" for runtime interaction states (hover, focus, pressed).
    precedence integer OPTIONAL Resolution precedence; higher integer wins when multiple states are active.
    layered boolean OPTIONAL true for states that compose with others (e.g. focus ring over hover). Default: false.
    lifecycle object OPTIONAL Version lifecycle metadata for this state. When lifecycle.deprecated is set, SPEC-037 fires on referencing tokens.

    See spec/state-model.md for the full state resolution algorithm, trigger semantics, and precedence rules.

    "states": [
      { "name": "hover",    "trigger": "interaction", "precedence": 50 },
      { "name": "focus",    "trigger": "interaction", "precedence": 60, "layered": true },
      { "name": "disabled", "trigger": "prop",        "precedence": 100 }
    ]
    

    Lifecycle

    The lifecycle block tracks a component declaration's version history. It mirrors the per-token lifecycle pattern from spec/token-format.md.

    Field Type Description
    introduced string Spec version when this component declaration was added (e.g. "1.0.0-draft").
    deprecated string Spec version when this component was deprecated. Truthy = deprecated.
    deprecatedComment string Human-readable explanation of the deprecation and migration path.
    replacedBy string or array name value(s) of the replacement component(s).
    "lifecycle": {
      "introduced": "1.0.0-draft"
    }
    

    Token bindings

    The optional tokenBindings array declares which tokens a component uses, including foundation and structure tokens that do not carry the component name in their name-object. This is the component-declares-usage direction; the token-declares-scope direction is expressed via name-object component/anatomy/state fields and validated by SPEC-018–022.

    "tokenBindings": [
      { "token": "component-height-100",         "context": "Minimum height" },
      { "token": "corner-radius-full",           "context": "Rounding" },
      { "token": "button-background-color-accent", "context": "Fill background" }
    ]
    

    Each entry contains:

    Field Required Type Description
    token yes string Token name. MUST resolve to a declared token in the dataset when the dataset is present (rule SPEC-027). May reference structure/foundation tokens.
    context no string Human-readable label for how this token is used (maps to the Figma Token Group label in the S2 Token Specs Figma file).

    NORMATIVE: When the dataset includes token declarations, each tokenBindings[].token value MUST match the name of a declared token (rule SPEC-027). A missing token reference is a validation error.

    The context field is informative. It is used by describe_component (Phase 8 agent surface) to present token usage in grouped, human-readable form.

    SPEC rules

    The following rules are added to the Layer 2 rule catalog (rules/rules.yaml) by this chapter. New component cross-reference rules start at SPEC-018 to avoid collision with existing token rules (SPEC-001–SPEC-017).

    Rule ID Name Severity Assert
    SPEC-018 component-name-exists error Token component field value MUST match the name of a declared component in the dataset.
    SPEC-019 component-variant-valid error Token variant field value MUST match a value in the declared variant option values list for the referenced component (when that list exists).
    SPEC-020 component-anatomy-valid error Token anatomy field value MUST match the name of a declared anatomy part on the referenced component.
    SPEC-021 component-slot-vocabulary warning Component slots entries with a name outside the canonical vocabulary SHOULD include a description. Custom slot names without descriptions are surfaced as warnings.
    SPEC-022 component-state-valid error Token state field value MUST match the name of a declared state on the referenced component (when state declarations are present).
    SPEC-027 token-binding-token-exists error Each tokenBindings[].token value MUST match the name of a declared token in the dataset (Phase 6.7).
    SPEC-036 component-deprecation-cascade warning A non-deprecated token SHOULD NOT reference a deprecated component via name.component. Advisory warning prompts updating the component reference or marking the token deprecated.
    SPEC-037 sub-entity-deprecation-cascade warning A non-deprecated token SHOULD NOT reference a deprecated anatomy part, state, or option value via name.*. Advisory warning prompts migration. Requires lifecycle on anatomy/state or lifecycle on the matching values entry on the option descriptor.
    SPEC-038 option-enum-obsolete warning An option descriptor SHOULD NOT use the JSON Schema enum keyword. additionalProperties: true silently accepts enum at Layer 1; SPEC-038 flags it at Layer 2 so authors replace it with the values array.
    SPEC-040 component-option-field-valid warning Token name-object keys that match a declared options.<key> with a values[] list SHOULD use a value drawn from that list. Generalises SPEC-019 to non-variant option fields (e.g. style, size, staticColor). Advisory; silent when no values declared.

    Full example

    A complete button component declaration:

    {
      "$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/component.schema.json",
      "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/button.json",
      "specVersion": "1.0.0-draft",
      "name": "button",
      "displayName": "Button",
      "description": "Buttons allow users to perform an action or to navigate to another page.",
      "meta": {
        "category": "actions",
        "documentationUrl": "https://spectrum.adobe.com/page/button/"
      },
      "options": {
        "variant": {
          "type": "string",
          "values": [
            { "value": "accent" },
            { "value": "negative" },
            { "value": "primary" },
            { "value": "secondary" }
          ],
          "default": "accent",
          "description": "Visual emphasis level."
        },
        "style": {
          "type": "string",
          "values": [{ "value": "fill" }, { "value": "outline" }],
          "default": "fill"
        },
        "size": {
          "type": "string",
          "values": [
            { "value": "s" },
            { "value": "m" },
            { "value": "l" },
            { "value": "xl" }
          ],
          "default": "m"
        },
        "isDisabled": { "type": "boolean", "default": false },
        "isPending": { "type": "boolean", "default": false },
        "isLabelHidden": { "type": "boolean", "default": false },
        "icon": {
          "$ref": "https://opensource.adobe.com/spectrum-design-data/schemas/types/workflow-icon.json",
          "description": "Icon placed at the start of the button. Required when isLabelHidden is true."
        },
        "staticColor": {
          "type": "string",
          "values": [{ "value": "white" }, { "value": "black" }],
          "description": "Static color for use on colored backgrounds. Must not be set for the default variant."
        }
      },
      "slots": [
        {
          "name": "default",
          "description": "Text label of the button.",
          "required": false
        },
        {
          "name": "icon",
          "description": "Icon placed at the start of the button."
        }
      ],
      "anatomy": [
        { "name": "icon",  "description": "Leading icon." },
        { "name": "label", "description": "Button text.", "required": true }
      ],
      "states": [
        { "name": "hover",    "trigger": "interaction", "precedence": 50 },
        { "name": "focus",    "trigger": "interaction", "precedence": 60, "layered": true },
        { "name": "disabled", "trigger": "prop",        "precedence": 100 }
      ],
      "lifecycle": {
        "introduced": "1.0.0-draft"
      }
    }
    

    Accessibility

    Phase 7. Component declarations MAY carry an accessibility object at the top level. State declarations MAY carry announce, communicates, and blocksInteraction fields. See spec/accessibility.md for the full vocabulary, SPEC rules, and examples.

    {
      "name": "button",
      "displayName": "Button",
      "meta": { "category": "actions", "documentationUrl": "https://spectrum.adobe.com/page/button/" },
      "accessibility": {
        "role": "button",
        "intents": ["trigger"],
        "focusable": true,
        "keyboardIntents": ["activate"],
        "wcag": [
          { "criterion": "4.1.2", "level": "A", "title": "Name, Role, Value" }
        ]
      },
      "states": [
        {
          "name": "disabled",
          "trigger": "prop",
          "precedence": 100,
          "announce": "Button disabled",
          "communicates": "disabled",
          "blocksInteraction": true
        }
      ]
    }
    

    Document blocks

    Phase 9. Component declarations MAY carry a documentBlocks array at the top level, and individual anatomy parts MAY carry their own documentBlocks arrays. See spec/document-blocks.md for the full block schema, type vocabulary, and SPEC rules.

    {
      "name": "button",
      "displayName": "Button",
      "meta": { "category": "actions", "documentationUrl": "https://spectrum.adobe.com/page/button/" },
      "documentBlocks": [
        {
          "type": "purpose",
          "content": "Buttons trigger a discrete action or event.",
          "agents": "Use Button when the user must trigger an action. For navigation, use Link."
        }
      ],
      "anatomy": [
        {
          "name": "label",
          "required": true,
          "documentBlocks": [
            {
              "type": "guideline",
              "content": "Button labels should be action verbs (Save, Delete, Submit)."
            }
          ]
        }
      ]
    }