Components

One design system, drawn natively everywhere

Every OpenVibe component is described by what it is: its parts, the tokens they wear, its states, and how it reads to a screen reader. The web draws it with the kit; an Android or iOS app draws the same component with its own views, so an app is never a web page in a frame.

Rail

A row of cards that scrolls sideways and snaps, with its heading and one See all link. From 760 px it can wrap into a grid.

Parts and their tokens

  • headsizetype.size.leadweighttype.weight.heavythe title and See all (44 px to the touch)
  • trackgapspace.mdsnaps to each card; bleeds to the screen's edge on a phone
  • arrows optional‹ › on computers only, each hidden at its end

How it behaves

Role
region named by its heading; a list of cards
Props
id title more size wrap label * required
States
default · empty · loading
Name
its title
Keys
Tab moves card to card; the arrows are buttons
Target
See all 44 px
Phone
about 1.2 cards showing, swiped
Computer
arrows, or a grid with wrap
size
s square things (memes, deals), 190 px
m 16:9 pictures, 280 px
l wide features, 400 px

Code

The same component as data: a server sends this, the web renders it with kit.rail, and a native app with its own view.

// A kit document (JSON). The web renders it with openvibe-shared/components:
//   components.render(doc, kit)  →  kit.rail(…)
{
  "type": "rail",
  "props": {
    "id": "sample-rail",
    "title": "Live now",
    "more": {
      "href": "/components?c=rail",
      "label": "See all"
    }
  },
  "children": [
    {
      "type": "card",
      "props": {
        "href": "/components?c=card#1",
        "title": "Seattle at night",
        "type": "stream",
        "live": true,
        "who": "goosely"
      }
    },
    {
      "type": "card",
      "props": {
        "href": "/components?c=card#2",
        "title": "Surf race on Utopia",
        "type": "stream",
        "who": "kiwi",
        "corner": "3 laps"
      }
    },
    {
      "type": "card",
      "props": {
        "href": "/components?c=card#3",
        "title": "Building a robot arm",
        "type": "stream",
        "who": "maru",
        "badge": "NEW"
      }
    }
  ]
}

Shared interfaces

Web, Android and iOS definitions for the navigation, composer, sheets, settings and motion used across OpenVibe. See the whole registry, or read it as JSON at /api/v1/components.

Kit documents: screens as data

A screen can be sent as a tree of these components, for example { "type": "rail", "children": [{ "type": "card", … }] }. Every OpenVibe client renders the same document with its own views, so a screen can change without an app release (the server-driven UI pattern of Airbnb and DivKit). Documents are checked strictly: known components and props only, typed values, which children each takes, a size limit, and https or same-site links.

The specs as JSON The tokens they wear