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.

Empty state

What an empty list says: a title, one line, and the one thing to do next.

No public rooms yet

Start the first one: public, or private to the people you invite.

Start a room

Parts and their tokens

  • icon optionalcolorcolor.accent.base
  • titleweighttype.weight.bold
  • text optionalcolorcolor.text.muted
  • action optionala primary button

How it behaves

Role
status
Props
title* text icon action * required
States
default
Name
its title and line
Keys
the action is one Tab stop
Target
44 px
Phone
centred in the space
Computer
the same

Code

Jetpack Compose, on the theme file from Tokens (Android): Material 3 roles for colour, OvScale for sizes.

// OpenVibe kit for Jetpack Compose: add the theme file from openvibe.design/tokens (Android) and wrap the app in
// MaterialTheme(colorScheme = if (isSystemInDarkTheme()) VibeDarkColorScheme else VibeLightColorScheme) { … }
enum class OvKind { Primary, Quiet, Danger }
enum class OvNoticeKind { Ok, Info, Warn, Error }

@Composable
fun OvEmpty(title: String, text: String? = null, action: Pair<String, () -> Unit>? = null) {
    Column(Modifier.fillMaxWidth().padding(OvScale.SpaceXl), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(OvScale.SpaceSm)) {
        Text(title, fontWeight = FontWeight.Bold)
        if (text != null) Text(text, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center)
        if (action != null) OvButton(action.first, action.second)
    }
}

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