# @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