The OpenVibe Kit · v4.235.0 · MIT

Every piece an OpenVibe page is made of

50 parts, each one function call that returns plain HTML: escaped, phone first, on the site's own theme. Pages work without JavaScript; one small file adds the menus, copy buttons and sheets. All of it is 17.8 KB of CSS. How closely each OpenVibe site follows it, read from its code: design health.

New in 4.78Layout without breakpointsA fluid type and space scale, eight primitives that lay out by their own width, and a classless base. 3.2 KB.

Use it

On your server

Every builder returns a string of HTML with its text escaped. The page is whole before any script runs.

// npm i https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.235.0
const kit = require('openvibe-shared/kit');

res.send(kit.head({ title: 'Rooms' })
  + kit.list(rooms.map((r) => kit.row({ href: `/r/${r.slug}`, title: r.name, sub: r.topic }))));

In a page that draws itself

The same builders on window.OpenVibeKit, from the CDN with open CORS. Call enhance after adding markup.

<link rel="stylesheet" href="https://openvibe.network/shared/kit.css">
<script src="https://openvibe.network/shared/kit.js"></script>
<script src="https://openvibe.network/shared/kit-web.js" defer></script>

<script>
  const box = document.querySelector('#rooms');
  box.innerHTML = OpenVibeKit.list(rooms.map((r) => OpenVibeKit.row({ title: r.name, sub: r.topic })));
  OpenVibeKit.enhance(box);
</script>

Copy the HTML

Each part's page prints the HTML its call returns. Keep kit.css and it looks the same; without OpenVibe's theme, set --bg-*, --text-* and --accent yourself.

  • kit.css12.2 KB
  • kit-web.js6.8 KB
  • kit-data.css5.6 KB
  • kit-data-web.js3.0 KB
  • kit.js33.7 KB

Actions

8

Buttons, menus and the small marks beside them.

  • Buttonkit.button()

    One clear action: primary, quiet, ghost or danger. A link with href, a form button without.

    1.5 KB of CSS

  • Icon buttonkit.iconButton()

    An action that is only an icon. Its label is what a screen reader says and what the tooltip shows.

    1.0 KB of CSS

  • Actionkit.action()

    A button that posts, with an optional confirm: leave, remove, stop.

    1.4 KB of CSS · uses kit-web.js

  • More menukit.more()

    The rest of a row's actions, behind one button. Dangerous ones confirm.

    1.2 KB of CSS · uses kit-web.js

  • Sharekit.share()

    The one Share button: it opens the network's Share sheet, or copies the link where there is no sheet.

    1.4 KB of CSS · uses kit-web.js

  • Badgekit.badge()

    A word beside a title: live, new, a state. Five tones.

    257 B of CSS

  • Unread dotkit.dot()

    How many are new. Nothing at zero; 9+ past nine.

    138 B of CSS

  • Ask your agentkit.askAgent()

    The chip that asks: a tap hands the question to your own agent in the Dock, with this page's context, and it never sends for you.

    1.5 KB of CSS · needs the shared navbar

Content

6

Cards, rails, pictures of people and what a page says when it has nothing.

  • Cardkit.card()

    A stream, a clip, a room or a place: picture first, the title, who, and one line.

    1.3 KB of CSS

  • Railkit.rail()

    A row of cards that scrolls sideways on a phone and wraps on a computer when asked. A long list never makes a long page.

    1.3 KB of CSS

  • Markkit.mark()

    A person or a place: their picture, or up to two letters on a colour that comes from the name.

    199 B of CSS

  • Empty statekit.empty()

    What a page says when there is nothing yet, and the one thing to do about it.

    1.5 KB of CSS

  • Snippetkit.snippet()

    Code to copy, with a copy button in the corner.

    1.1 KB of CSS · uses kit-web.js

  • Sheetkit.sheet()

    More choices without leaving the page: up from the bottom on a phone, a dialog on a computer.

    1.9 KB of CSS · uses kit-web.js

Layout

9

The shape of a page: its head, tabs, lists, sections and folds.

  • Headkit.head()

    The top of an app page: back, the title, one muted line, icon actions and the tabs. It sticks under the navbar.

    1.5 KB of CSS

  • Tabskit.tabs()

    Links, so they work without JavaScript. For settings and explainers, never to hide content.

    313 B of CSS

  • Listkit.list()

    Rows under a title, with a link to all of them.

    707 B of CSS

  • Rowkit.row()

    A mark, the title with a badge and the time on one line, one muted line under it. The whole row is the link.

    607 B of CSS

  • Page headkit.pageHead()

    The top of a page: the way back, the page's icon and title, its actions, and one line saying what it is for.

    1.5 KB of CSS

  • Sectionkit.section()

    A titled block of a page, with its count and one quiet note.

    745 B of CSS

  • Foldkit.fold()

    A card that opens: setup, extras, the danger zone. It says what is inside and how much.

    1.5 KB of CSS

  • Sidebarkit.sidebar()

    Navigation down the left on a computer, a drawer on a phone.

    1.7 KB of CSS · uses kit-web.js

  • Pagekit.page()

    The whole shape of an app page in one call; the side column sits beside the content from 1024 px, under it below.

    1.1 KB of CSS

Forms

10

Settings rows, search, the composer and the file drop.

  • Findkit.find()

    A search, or "add by name": a pill with an icon, the field and a round button.

    518 B of CSS

  • Composerkit.dock()

    The one thing you type, pinned at the bottom. Enter sends; it grows as you write.

    647 B of CSS · uses kit-web.js

  • Switch rowkit.switchRow()

    An on/off setting: the label and a hint on the left, the switch on the right.

    586 B of CSS

  • Range rowkit.rangeRow()

    An amount: the label, the slider and its value.

    463 B of CSS

  • Select rowkit.selectRow()

    One choice of several, as a row.

    429 B of CSS

  • Segmentedkit.seg()

    Two to four choices you can see at once.

    423 B of CSS

  • Segmented, full widthkit.segmented()

    Three or four equal choices filling the row, each with an icon; the radios post without JavaScript.

    437 B of CSS

  • Chipskit.chips()

    Filters you can turn on and off, or one of a few.

    432 B of CSS

  • Save barkit.saveBar()

    The save button of a settings form, kept in reach above the phone's app bar.

    1.3 KB of CSS

  • Dropkit.drop()

    Where a file goes: a real file input, plus drag and drop, paste and the phone's camera.

    1.7 KB of CSS · uses kit-web.js

Data

8

Numbers, steps, tables, charts, rankings and meters.

  • Labelskit.labels()

    What a stream, recording, picture or post carries (nudity, strong language, graphic, 18+, flashing lights, spoilers), in words. Only the labels in force: a suggestion is the creator's to confirm. The page marks the thing itself with kit.labelsAttr so each viewer's own choice (show, blur, hide) applies.

    271 B of CSS

  • Numberskit.stats()

    A strip of numbers that matter. Zero and unknown are left out; it scrolls sideways on a phone.

    436 B of CSS

  • Numberkit.num()

    A number the way a reader wants it: money, compact, percent, time. Missing is "–", never 0.

    No CSS of its own

  • Stepskit.steps()

    A flow of a few steps. Done steps link back; later ones never link ahead.

    742 B of CSS

  • Tablekit.table()

    Plans, prices, endpoints: anything compared across columns. On a phone each row becomes a card.

    615 B of CSS

  • Chartkit.chart()

    Line, area, bar or scatter. Text stays its real size at every width, and a table with the same numbers sits behind it.

    845 B of CSS · uses kit-web.js

  • Rankingkit.rank()

    A leaderboard: the place, the name, the value with its interval, the change, a bar in proportion.

    714 B of CSS

  • Meterkit.meter()

    How full something is. With tone auto, a limit turns amber from 75 % and red from 90 %.

    164 B of CSS

Tools

6

One order for every tool page: what it does, the input, the answer, the family.

  • Tool headkit.toolHead()

    What the tool does, in its colour, with the facts that matter (free, no sign-in, what is kept).

    571 B of CSS

  • Tool inputkit.toolInput()

    The one field a tool needs, its button, and examples to try.

    1.8 KB of CSS

  • Answerkit.answer()

    The answer first, then its rows, then what to do next.

    1.6 KB of CSS

  • Familykit.family()

    The tools next to this one.

    459 B of CSS

  • Tool framekit.tool()

    One order for every tool page: head, input, answer, family, folds, related.

    2.5 KB of CSS

  • Trieskit.tries()

    Examples a person can run with one tap.

    308 B of CSS

Feedback

3

Notices, receipts and the shape of a page while it loads.

  • Noticekit.notice()

    A sentence about what just happened: ok, info, warn or error. Errors are announced.

    438 B of CSS

  • Receiptkit.receipt()

    A result and what it took: the answer first, then one quiet line of facts.

    1.5 KB of CSS

  • Skeletonkit.skeleton()

    The shape of what is coming, so nothing jumps when it arrives. It never spins.

    322 B of CSS

Helpers

10

Small functions with nothing to draw.

kit.esc(text)
Escapes text for HTML. Every builder already does it for its text arguments.
kit.labelsAttr(labels)
The data-ov-labels attribute for the labelled thing, so ov-labels.js (loaded by the navbar) applies each viewer's show, blur or hide.
kit.LABEL_NAMES
The six content labels and their names in words.
kit.url(href)
Keeps http(s) and same-site links; anything else becomes #.
kit.mediaW(url, width)
A Media picture at a width from its resize ladder (64, 96, 160, 320, 480, 640), so an avatar is not its full upload; any other URL as kit.url gives it.
kit.icon(name)
One of kit.ICONS as inline SVG, in the text's colour. The full set is at /icons.
kit.when(ts)
{ iso, text }: 14:05 today, Yesterday, a weekday this week, Oct 20 this year, else the date.
kit.hueOf(key)
The colour a mark wears for a name: the same name, the same hue, everywhere.
kit.tabOf(query, keys)
The open tab: a known key from the query, else the first.
kit.enhance(el)
After a page inserts markup itself: wires copy buttons, menus, sheets and the composer.

Eleven parts are also drawn natively, in Jetpack Compose and SwiftUI: see Components. The icons are at Icons.