Spectrum Design Data
  • Components
  • Tokens
  • Registry
  • AI
  • Articles
  • 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), platform implementations (implementations), 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.
    implementations array Known platform implementations — see Implementations.
    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/"
    }

    Implementations

    implementations declares the published platform implementations corresponding to this design-system component. It is foundation-owned canonical data so consumers, including Code Connect generators, can resolve an implementation without platform-specific configuration.

    Each entry MUST contain platform and componentName, plus exactly one implementation reference: package for a published package or importPath for an importable module/source path. notes is optional context for consumers. Multiple entries MAY use the same platform when their packages distinguish different implementations for that platform.

    "implementations": [
      {
        "platform": "web",
        "componentName": "Button",
        "package": "@spectrum-web-components/button"
      }
    ]

    Platform manifests do not override implementations in this version. A future extension may add platform-owned overrides after consumers need them; until then, component declarations remain the canonical source of implementation names and references.

    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)."
            }
          ]
        }
      ]
    }