o Gobito Orbit
Search Orbit ⌘K
{{ crumb }}
@gobito/orbit · React · Next.js

The shared interface layer for gobito.one — and every app after it.

Small, typed, token-driven components. One package, one look, one set of rules for the people and agents building Gobito.

Sample app: Gobito Hub
OverviewActivitySettings
Live Draft
Notifications
{{ e.title }}

{{ e.body }}

Principles
Small by default

One package, no runtime dependencies, tree-shaken ESM. Apps ship only the components they import.

Accessible by default

Focus traps, roving arrow keys, Escape layering and ARIA wiring live inside the components, not in each app.

One source of truth

Tokens drive CSS, TypeScript and the docs. Change one value, every app follows.

Getting started

One package — @gobito/orbit — and one stylesheet. Works in Next.js (App Router) and Vite, React 18.2 or 19. No runtime dependencies.

1

Get the package

{{ installNote }}

terminal
{{ code.install.text }}
2

Wire up your app

{{ b.file }}
{{ b.text }}

{{ setupNote }}

3

Use components

Import from @gobito/orbit. Only what you import ships. Files that call Orbit hooks need 'use client'; rendering components from Server Components is fine.

app/documents/empty-library.tsx
{{ code.use.text }}

Dark and light

ThemeProvider follows the system by default, remembers the user's choice and syncs across tabs. Every component reads --orb-* variables, so a product retunes the accent without forking.

appearance.tsx
{{ code.theme.text }}

What's in the package

EntryContents
{{ b.entry }}{{ b.what }}

Build and release

Bump version in package.json, tag it, and apps pick it up through their install route.

gobito-orbit/
{{ code.build.text }}

Foundations

The visual decisions every component inherits. Each value here is a token — reference it, never copy it.

Color

One accent, used as a line and a glow. Contrast comes from the neutral ramp. Ramps share a perceptual lightness scale, so step 700 of any role carries the same weight.

{{ c.name }}
{{ c.token }}
{{ rm.name }}
{{ s.step }}

Typography

Inter throughout, headings at 500. Hierarchy is size and space — never bolder weights.

{{ ty.name }} {{ ty.sample }} {{ ty.size }} / {{ ty.weight }}

Spacing

A compact 0.7× scale. Orbit is dense on purpose — product screens, not marketing pages.

{{ sp.token }} {{ sp.value }}

Radius and elevation

Elevation is an edge plus ambient darkness. Use three steps; never stack them.

shadow-sm · radius-smInputs, tags, resting cards
shadow-md · radius-mdMenus, popovers, hovered cards
shadow-lg · radius-lgDialogs, drawers, app switcher

Icons

The full Phosphor set — 1,500+ icons in six weights — ships as @gobito/orbit/icons (tree-shaken; add the optional peer @phosphor-icons/react). Regular weight on currentColor; 16px inline, 18–20px in nav and buttons. Wrap with <Icon icon={FolderSimple} label="…" /> when an icon carries meaning. Click any icon to copy its JSX.

Components

{{ compCount }} components, all imported from @gobito/orbit. Open any card for its preview, props and rules.

{{ c.name }}{{ c.status }}
{{ c.cat }} · {{ c.size }}

Button

Starts an action. Use one primary button per view; everything else is secondary or ghost.

import { Button } from '@gobito/orbit' forwardRef · native button Style a Next.js Link with buttonClass() Stable
Variant
Size
{{ code.button.text }}

Props

PropTypeDefaultDescription
{{ p.name }}{{ p.type }}{{ p.def }}{{ p.desc }}

Usage

Do

Label with a verb that says what happens. Pair one primary with a quieter alternative.

Don't

Two primaries compete. Vague labels force people to read the surrounding text.

Accessibility

Renders a native button. Enter and Space activate; focus shows the 2px accent ring.
While loading, sets aria-busy and keeps its width so the layout doesn't jump.
Icon-only buttons require aria-label — the types enforce it.

App switcher

Moves people between Gobito apps. One per app, first in the top bar. The current app is marked; recent items follow.

import { AppSwitcher } from '@gobito/orbit' Enter · ↑ ↓ · Home · End · Esc Stable
Gobito {{ demoCurName }}
Switch to
{{ a.name }} {{ a.desc }}
Recent
{{ r.title }}{{ r.app }}
No apps match.
Manage apps
Current app
{{ code.switcher.text }}

Props

PropTypeDefaultDescription
{{ p.name }}{{ p.type }}{{ p.def }}{{ p.desc }}

Behaviour

Click, Enter or Space opens it. Focus lands on search, or on the current app when there is no search.
↑ ↓ move through apps and recent items; ↑ from the first item returns to search. Home and End jump.
Escape, a click outside, or Tab past the end closes it and returns focus to the trigger. Search resets on close.
Stays inside the viewport: flips above the trigger and clamps to the edges on small screens.

Usage

Do

Feed every app the same registry, in the same order, so the list never shifts between apps.

Don't

Hide apps the user can't access by greying them out — leave them out of the list instead.

{{ doc.name }}

{{ doc.desc }}

{{ doc.imp }}
{{ m }} Stable
{{ docCode.text }}

Props

PropTypeDefaultDescription
{{ p.name }}{{ p.type }}{{ p.def }}{{ p.desc }}

Usage

Do

{{ doc.do }}

Don't

{{ doc.dont }}

Accessibility

{{ a.text }}

Patterns

Components assembled into the screens Gobito apps repeat. Copy the composition, not the pixels.

Forms

01Labels sit above fields. No placeholder-as-label.
02Actions align left, under the last field, primary first.
03Validate on blur; show the message under the field, never in a toast.
04Three choices or fewer: segmented control. More: select.

Data tables

Empty states

Say what belongs here, why it's empty, and offer the one action that fills it.

Project overview

GroupHeader + ProjectCard: identity, status, progress, key numbers and what's in flight. Pin on hover, the whole card opens the project, and empty values stay calm instead of showing 0 of 0.

Comments with mentions

RichTextEditor + RichText. Type @ for people, # for issues; ⌘↵ posts. Stored HTML is sanitized on the way in and on the way out.

Calls to action

One CtaCard per view for the thing that matters most (an upgrade, a setup step); quiet subtle cards for secondary nudges. Always dismissible unless it blocks work.

Calendar

EventCalendar: month, week, day and agenda in one component. Overlapping events sit side by side, the now line updates every minute; click an empty slot (or double-click a day) to create, an event to see details and RSVP.

Mail client

MailList + MessageView + Composer. j/k or ↑/↓ move, Enter opens, x selects, s stars; hover shows row actions. Reply opens an inline composer with recipient chips, Cc/Bcc, attachments and ⌘↵ to send.

Document management

FolderTree (drop files on folders), FileTile grid or table, StorageMeter, SharePanel in a Dialog and VersionHistory in a Drawer — open any tile’s ⋯ menu.

AI assistant

ChatPanel with live answers: steps while it works, streamed text with a stop button, cited sources, copy / feedback / regenerate. Below: the same assistant as a copilot Drawer, and an AiSummary inside a page.

Theme playground

Change accent, font, corners, density and surface tint — every Orbit demo on the site follows, and the choice is remembered. Copy CSS hands the theme to engineering. The palette button bottom-right opens the same panel from any page.

Tokens

CSS variables from @gobito/orbit/styles.css. Override them per product under [data-theme]; never edit component classes.

TokenDarkLight
{{ t.css }} {{ t.value }} {{ t.ts }}

Machine-readable docs

Every page on this site has a plain-text twin, so coding agents read the same rules people do.

{{ x.path }} {{ x.desc }}

Rules file

Drop this into the repo root of any Gobito app.

AGENTS.md
{{ code.agents.text }}

Component spec

components.json → Button
{{ code.spec.text }}