---
title: "design.component@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/design.component"
updated: null
---

# design.component@1 · OpenVibe.Services

HTML: [design.component@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/design.component)

# DesignComponent `design.component@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: design
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/design/component.v1.json`](/docs/contracts/design.component.json)

design.component@1: a platform-neutral OpenVibe interface definition served by openvibe.design/api/v1/components.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `schema` | const | yes |  | - `= "design.component@1"` |
| `name` | string | yes |  | - `pattern ^[a-z][a-z0-9-]{0,63}$` |
| `title` | string | yes |  | - `minLength 1`<br>- `maxLength 120` |
| `summary` | string | yes |  | - `minLength 1`<br>- `maxLength 500` |
| `anatomy` | array of object | yes |  | - `minItems 1`<br>- `maxItems 32`<br>- `items: no other fields` |
| `anatomy[].part` | string | yes |  | - `minLength 1`<br>- `maxLength 80` |
| `anatomy[].role` | string | yes |  | - `minLength 1`<br>- `maxLength 300` |
| `props` | object | yes |  |  |
| `states` | array of string | yes |  | - `minItems 1`<br>- `maxItems 30`<br>- `unique items`<br>- `items: minLength 1`<br>- `items: maxLength 80` |
| `tokens` | array of string | yes |  | - `minItems 1`<br>- `maxItems 50`<br>- `unique items`<br>- `items: minLength 1`<br>- `items: maxLength 100` |
| `behaviors` | object | yes |  | - `no other fields` |
| `behaviors.keyboardAware` | boolean | yes |  |  |
| `behaviors.outsideTapCloses` | boolean | yes |  |  |
| `behaviors.scrollLock` | boolean | yes |  |  |
| `behaviors.reducedMotion` | string | yes |  | - `minLength 1`<br>- `maxLength 300` |
| `accessibility` | object | yes |  | - `no other fields` |
| `accessibility.name` | string | yes |  | - `minLength 1`<br>- `maxLength 300` |
| `accessibility.target` | string | yes |  | - `minLength 1`<br>- `maxLength 300` |
| `accessibility.focus` | string | yes |  | - `minLength 1`<br>- `maxLength 300` |
| `platforms` | object | yes |  | - `no other fields` |
| `platforms.web` | object | yes |  | - `no other fields` |
| `platforms.web.module` | string | yes |  | - `minLength 1` |
| `platforms.web.markup` | string | yes |  | - `minLength 1` |
| `platforms.web.demo` | string | yes |  | - `pattern ^/components/[a-z0-9-]+$` |
| `platforms.android` | object | yes |  | - `no other fields` |
| `platforms.android.toolkit` | const | yes |  | - `= "Jetpack Compose"` |
| `platforms.android.material3` | string | yes |  | - `minLength 1` |
| `platforms.android.specification` | string | yes |  | - `minLength 1` |
| `platforms.ios` | object | yes |  | - `no other fields` |
| `platforms.ios.toolkit` | const | yes |  | - `= "SwiftUI"` |
| `platforms.ios.specification` | string | yes |  | - `minLength 1` |
| `examples` | array of object | yes |  | - `minItems 1`<br>- `maxItems 20`<br>- `items: no other fields` |
| `examples[].title` | string | yes |  | - `minLength 1` |
| `examples[].props` | object | yes |  |  |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: sheet

~~~~
{
  "schema": "design.component@1",
  "name": "sheet",
  "title": "Sheet",
  "summary": "A modal task surface: one heading, one close action and scrollable content.",
  "anatomy": [
    {
      "part": "handle",
      "role": "touch affordance"
    },
    {
      "part": "header",
      "role": "title and close"
    },
    {
      "part": "body",
      "role": "task controls"
    }
  ],
  "props": {
    "title": "string",
    "open": "boolean",
    "body": "content"
  },
  "states": [
    "closed",
    "opening",
    "open",
    "closing"
  ],
  "tokens": [
    "color.bg.card",
    "color.line.strong",
    "radius.lg"
  ],
  "behaviors": {
    "keyboardAware": true,
    "outsideTapCloses": true,
    "scrollLock": true,
    "reducedMotion": "Remove movement; keep the state change."
  },
  "accessibility": {
    "name": "Sheet",
    "target": "At least 44 × 44 dp or pt for every touch action",
    "focus": "Trap focus while open; Escape closes and returns focus"
  },
  "platforms": {
    "web": {
      "module": "openvibe-shared/kit",
      "markup": "kit.sheet({ id, title, body })",
      "demo": "/components/sheet"
    },
    "android": {
      "toolkit": "Jetpack Compose",
      "material3": "SurfaceContainerHigh",
      "specification": "Use ModalBottomSheet with a heading, close control and sheet state."
    },
    "ios": {
      "toolkit": "SwiftUI",
      "specification": "Use .sheet with a NavigationStack and a toolbar close button."
    }
  },
  "examples": [
    {
      "title": "Default",
      "props": {
        "title": "Add a site"
      }
    }
  ]
}
~~~~

Rejected: no-android

~~~~
{
  "schema": "design.component@1",
  "name": "sheet",
  "title": "Sheet",
  "summary": "A modal task surface: one heading, one close action and scrollable content.",
  "anatomy": [
    {
      "part": "handle",
      "role": "touch affordance"
    },
    {
      "part": "header",
      "role": "title and close"
    },
    {
      "part": "body",
      "role": "task controls"
    }
  ],
  "props": {
    "title": "string",
    "open": "boolean",
    "body": "content"
  },
  "states": [
    "closed",
    "opening",
    "open",
    "closing"
  ],
  "tokens": [
    "color.bg.card",
    "color.line.strong",
    "radius.lg"
  ],
  "behaviors": {
    "keyboardAware": true,
    "outsideTapCloses": true,
    "scrollLock": true,
    "reducedMotion": "Remove movement; keep the state change."
  },
  "accessibility": {
    "name": "Sheet",
    "target": "At least 44 × 44 dp or pt for every touch action",
    "focus": "Trap focus while open; Escape closes and returns focus"
  },
  "platforms": {
    "web": {
      "module": "openvibe-shared/kit",
      "markup": "kit.sheet({ id, title, body })",
      "demo": "/components/sheet"
    },
    "ios": {
      "toolkit": "SwiftUI",
      "specification": "Use .sheet with a NavigationStack and a toolbar close button."
    }
  },
  "examples": [
    {
      "title": "Default",
      "props": {
        "title": "Add a site"
      }
    }
  ]
}
~~~~

Rejected: no-ios

~~~~
{
  "schema": "design.component@1",
  "name": "sheet",
  "title": "Sheet",
  "summary": "A modal task surface: one heading, one close action and scrollable content.",
  "anatomy": [
    {
      "part": "handle",
      "role": "touch affordance"
    },
    {
      "part": "header",
      "role": "title and close"
    },
    {
      "part": "body",
      "role": "task controls"
    }
  ],
  "props": {
    "title": "string",
    "open": "boolean",
    "body": "content"
  },
  "states": [
    "closed",
    "opening",
    "open",
    "closing"
  ],
  "tokens": [
    "color.bg.card",
    "color.line.strong",
    "radius.lg"
  ],
  "behaviors": {
    "keyboardAware": true,
    "outsideTapCloses": true,
    "scrollLock": true,
    "reducedMotion": "Remove movement; keep the state change."
  },
  "accessibility": {
    "name": "Sheet",
    "target": "At least 44 × 44 dp or pt for every touch action",
    "focus": "Trap focus while open; Escape closes and returns focus"
  },
  "platforms": {
    "web": {
      "module": "openvibe-shared/kit",
      "markup": "kit.sheet({ id, title, body })",
      "demo": "/components/sheet"
    },
    "android": {
      "toolkit": "Jetpack Compose",
      "material3": "SurfaceContainerHigh",
      "specification": "Use ModalBottomSheet with a heading, close control and sheet state."
    }
  },
  "examples": [
    {
      "title": "Default",
      "props": {
        "title": "Add a site"
      }
    }
  ]
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('design.component@1', value);   // { valid, errors: [{ path, message }] }
~~~~
