# @colineapp/ui
The Coline design system for tier-2 (React) Coline Apps — the same components
the Coline platform itself uses, themed live by the host workspace. Your app
automatically matches the user's theme, including dark mode and brand
accents, with no theme code of your own.
[Docs](https://docs.coline.app/sdk/ui) ·
[Source](https://upstream.codes/coline/ui) ·
[npm](https://www.npmjs.com/package/@colineapp/ui)
```sh
npm install @colineapp/ui
```
```tsx
import {
Button,
Card,
ColineAppProvider,
Input,
useColine,
useColineQuery,
} from "@colineapp/ui";
import "@colineapp/ui/styles.css";
function NotesList() {
const coline = useColine();
const notes = useColineQuery(
(c) => c.files.list({ typeKey: "notes.note" }),
[],
);
return (
{notes.data?.files.map((file) => (
))}
);
}
export default function App() {
return (
);
}
```
## On a Coline Site
Sites are public websites with no Coline host around them. Use
`ColineSiteProvider` instead of `ColineAppProvider`: it follows the visitor's
light or dark preference. Give the site's Tailwind the same token names with
`theme.css`.
```tsx
// site/main.tsx
import { Button, Card, ColineSiteProvider } from "@colineapp/ui";
import "@colineapp/ui/styles.css";
import "./app.css"; // @import "tailwindcss"; @import "@colineapp/ui/theme.css";
createRoot(root).render(
,
);
```
A site looks like Coline. Use the components as they ship (`className` only
for layout), with no custom fonts, no palette of your own and `Tabs` or
`SegmentedControl` for navigation. The one choice a site makes is an accent
color: `` recolors selection, radio
choices, the selected date, steps, info badges and the first chart series in
light and dark (checkboxes, switches and buttons stay Coline's neutral),
and `bg-action` / `text-action` use it in your own layout. `coline-app check`
warns about anything else.
Every component works on a site except the ones that need a workspace:
`FilePreview`, `FileDropzone`, `SaveAsButton`, `useFilePicker`,
`ConnectButton`, `useColine`, `useColineContext`, `useColineQuery`,
`useColorScheme` and `useToast`. Read data with the site hooks from
`@colineapp/sdk/site/react` instead.
## What's inside
- Components: Button, Card, Dialog, Sheet, Input, Textarea, Select, Combobox,
Checkbox, Switch, Tabs, SegmentedControl, Table, DataGrid, Badge, Avatar,
Tooltip, DropdownMenu, Popover, Calendar, DatePicker, charts, Kanban,
Timeline, Steps, EmptyState and more — Radix-based, accessible,
keyboard-friendly.
- `ColineAppProvider` — connects the sandbox bridge and provides context.
- `ColineSiteProvider` — light and dark for a Coline Site.
- Hooks: `useColine` (the capability API), `useColineContext` (workspace /
surface / file context), `useColineQuery` (data fetching with
loading/error state), `useColorScheme`.
- `styles.css` — the compiled stylesheet; theme tokens are overridden at
runtime by the host, so one CSS file serves every workspace theme.
Used inside a Coline App's react-tier surface (`{ tier: "react", entry:
"main.tsx" }` in the manifest). Scaffold a working app with
`npx create-coline-app my-app`.
## Docs
Full guides at [docs.coline.app](https://docs.coline.app): [UI](https://docs.coline.app/sdk/ui),
[Sites](https://docs.coline.app/sites).
## Workflow
Run `coline-app check` before pushing: it checks types, the manifest, hosted logic,
and the React bundle without uploading. `dev --internal` updates one development
version; install it in the workspace and reload after changes. The CLI bundles
from the app's installed dependencies and preserves imported CSS and inline assets.
App-specific Tailwind v4 utilities compile automatically with CLI 2.5. Import
`@colineapp/ui/styles.css` and then `./app.css`; use complete class names.
The starter includes a React home and editor, tree mobile fallback, and a tool.
Use `coline.tools.invoke` or `actions.invokeTool` to run the same declared tool
from UI that Kairo runs. Save with `expectedVersion` to detect concurrent edits.
Homes/editors can write within grants; previews and server render handlers cannot.
`createTestWorkspace(app).client()` tests the interactive contract and
`grantedPermissions` simulates revoked consent.
New `tasks`, `calendar`, `messages`, and `references` capabilities require their
explicit manifest permissions and retain the invoking user's workspace access.
Use `files.list({ scope: "workspace" })` for shared files; document writes stay
with the owning app. Collections are install-private. A native mobile React runtime is separate
work; Coline Code builds and publishes apps (see [full-stack apps](https://docs.coline.app/sdk/full-stack)).
### Live data
`useLiveCollection("collection", { where, orderBy, limit })` returns
`records`, `pending`, `status`, `error`, `nextCursor`, `insert`, `update`, `delete`,
`setAccess`, and `refresh`. Inline query objects are supported. Mutations update
local UI immediately and reject on conflicts or permission failures; catch their
promises to present the error. The hook owns subscription cleanup and reconnect
recovery. Use filtered/paged views (at most 200 records), not an entire workspace
in one hook. Structured-record sync does not imply CRDT text editing or offline
write persistence.
## Screen patterns
Use `AppPage` and `PageToolbar` for consistent hierarchy, `RecordTable` with
`SplitView`/`DetailPanel` for queues, `Board`/`BoardColumn`/`BoardCard` for stages,
and `SettingsSection` for configuration. `EmptyState`, `AppErrorState`,
`AppLoadingState`, and `StatusBadge` cover common states. Their CSS ships in
`@colineapp/ui/styles.css`; they require no app-side utility generation.
Patterns compose around your domain and capabilities. They do not supply data,
routing, drag-and-drop, or persistence. `RecordTable` provides a first-cell button
when `onOpen` is set (don't nest a second control there); secondary columns hide
at narrow widths. Split details stack on mobile; the app owns focus management.
See the scaffold's `examples/` for complete interactive references.
## Shared controls and motion
`Tabs` uses the same raised selection as Coline and Upstream. Selection springs
and content transitions are automatic; no indicator or animation wrapper is
required. Each tabs group owns its indicator so multiple groups never collide.
`TabsIndicator` remains available for existing custom compositions.
```tsx
Inbox
Roadmap
{/* Inbox */}
{/* Roadmap */}
```
`FilterMenu` composes the exact Coline `DropdownMenu` radio group, surface, and
sliding highlight. Use `DropdownMenu` directly for action menus. `PageToolbar`
is borderless. `RecordTable` uses separated, rounded selection/hover rows.
Dialogs and menus include their animation CSS; the provider respects reduced
motion, including portals. Buttons default to `type="button"`; use
`type="submit"` for a form's submit action.
Use component defaults rather than copying their CSS into the app. Custom CSS
variables scoped to `AppPage` do not reach portalled dialogs/menus. Keep decorative
app variables at `:root` when they must cross portals, and retain host theme tokens.
App bundles include their dependencies: upgrade, rebuild and push to adopt a UI
release. Updating npm does not rewrite already-published app bundles.
The stylesheet includes the Latin Geist variable font and its SIL Open Font
License in `dist/fonts`. The CLI embeds the font in the app bundle, so sandbox
text uses Coline typography without remote font requests. Other scripts use the
system fallback. Keep font assets and their license in release tarballs.
## Tokens and components
Rebuilt in 0.6 on host tokens with one motion vocabulary (`transitions`,
`staggerDelay`; `motion` and `AnimatePresence` are re-exported) and
reduced-motion support. New components: `DataGrid`, `KanbanBoard`, charts
(`LineChart`, `AreaChart`, `BarChart`, `DonutChart`, `Sparkline`), `Stat`,
`StatGrid`, `AnimatedNumber`, `PropertyList`, `Timeline`, `Steps`,
`Pagination`, `Breadcrumbs`, `Calendar`, `DatePicker`, `CommandList`,
`Combobox`, `SegmentedControl`, `RadioGroup`, `SearchInput`, `Accordion`,
`Sheet`, `Banner`, `Presence`, `Avatar`, `AvatarGroup`, `Spinner`, `Kbd`,
`FilePreview`, `FileDropzone`, `SaveAsButton`, `ConnectButton`,
`ConfirmButton`. Hooks: `useColineMutation`, `useJob`, `useConnection`,
`useDebouncedValue`, `useToast`. Page patterns now use tokens and animation;
`patterns.css` is gone. Status colors are `positive`, `attention`, `risk`,
`action`, and `chart-1`…`chart-5`.
## Development
```sh
git clone https://git.coline.app/coline/ui.git
cd ui
npm install
npm run typecheck
npm run build
```
The stylesheet is generated; published installs already include it. In
Coline's monorepo, run `pnpm --filter @colineapp/ui build` before source-based
AX fixtures; there the build also checks that the dropdown menu and its shared
style helpers match Coline's own. `typescript` is TypeScript 6 because tsup's
declaration build needs TypeScript's JavaScript API, which TypeScript 7 doesn't
ship yet; `tsrs` is the TypeScript 7 type checker.
## Source
The repository is [coline/ui](https://upstream.codes/coline/ui) on
upstream.codes. The package is developed inside Coline's monorepo, at
`packages/coline-ui`, next to the app whose components it shares, and this
repository is published from there. Issues and change requests are welcome
here and get ported back. In the monorepo, `scripts/sync-package-repos.mjs ui`
republishes it: it splits `packages/coline-ui` out of `origin/main` the way
`git subtree split` does, which gives the same commits every time, and pushes
the result here as `main`, so every sync is a fast-forward. The monorepo links
`@colineapp/sdk` and `@colineapp/app-runtime` from its own folders; here
`package.json` names the versions those were, as `pnpm publish` writes them.
## License
MIT © Coline