App design principles
Every Conduction app — OpenRegister, OpenCatalogi, Procest, Pipelinq, MyDash, the dozen others — looks and works the same way on first sight. Same five structural pieces, same place, same behaviour. That recognisability isn't an accident: it's what @conduction/nextcloud-vue enforces, and what makes a user who's learnt one app productive in any of the others within minutes.
This page explains the chassis — the abstract layout shared by every app — the five atoms that make up the chassis, and the stacked views the library composes on top so you don't have to lay each atom out by hand.
The chassis: one shape, every app
Every Conduction product surface is built on the same three-region chassis: a topbar across the top, a left navigation down the side, and a main column filling the rest. The contents differ wildly — a register browser, a process inbox, a dashboard, a chat archive — but the bones are identical, so the user never has to relearn where things live.
Three different apps. Same shape: topbar with the user menu, left nav with the app sections, main column with whatever the page is doing. That's the chassis. @conduction/nextcloud-vue is what gives you that shape with one component (CnAppRoot) plus a JSON manifest.
Five atoms, one chassis
Inside the chassis sit five recurring building blocks. Every page in every app composes some subset of these — they are the atoms of the design system. Each card below focuses on one atom: the focused zone is at full opacity with a KNVB-orange outline, the rest fades to 25% so you see where the atom sits, not just what it is.
.topbarTopbar
App · Desk · alwaysThe Nextcloud chrome row. Sits across every page unconditionally because every Conduction app lives inside Nextcloud's workspace. The shelf icons are the cross-app navigation; per-app links never go here.
.navLeft navigation
App · required · Desk: neverThe per-app sidebar. Carries this app's own primary navigation, plus a footer pinned to the bottom for global access (Settings, Feedback). The active item is the only place cobalt-100 backgrounds a row.
.colMain column
App · Desk · alwaysThe work surface. In an App pattern, the column opens with a .pageHeader (title + actions), then KPI strip and panels. In a Desk pattern, .col nests inside .grid to become a full-bleed widget canvas with no page header.
.pageHeaderPage header
Index · Detail · Desk: neverThe first row of .col on every Index and Detail template. Carries the page title (left) and exactly two action buttons (right): one ghost (secondary), one primary (filled cobalt). The header tracks .col's width: full-spread when the sidebar is closed, constrained when it is open.
.detailSidebar
App · optional · Desk: neverThe right-hand sidebar. Optional, dismissible, anchored to the active record or the active view. Carries an icon + title + description in a header, then a tabbed body (Search / Columns by default). Class stays .detail for code; we call it the Sidebar in copy.
Mapped to the library's components:
| Atom | Library component | Notes |
|---|---|---|
| Topbar | Inherited from Nextcloud's NcAppHeader | The library doesn't own this atom — it inherits the cross-app shelf, search, and user menu from the workspace. |
| Left navigation | CnAppNav | Driven by manifest.menu[]. One level of nesting, permission-filtered, sortable via order. |
| Main column | A stacked view (CnIndexPage, CnDetailPage, CnDashboardPage, CnSettingsPage) | Whatever the active route renders. |
| Page header | CnPageHeader | Title + description + icon + per-page action buttons. Uniform across Index and Detail pages. |
| Sidebar | CnIndexSidebar on Index, CnObjectSidebar on Detail | Toggleable, never required. |
These five atoms cover almost every screen Conduction ships. New apps don't invent new atoms — they compose the existing ones in the right shape.
Stacked views: the library's job
Wiring the five atoms together by hand on every page would be repetitive and inconsistent. @conduction/nextcloud-vue exposes them as stacked views — opinionated higher-level components that arrange the atoms for the most common page shapes:
- CnIndexPage — Topbar + Left nav + Page header + Main (table/cards + filter bar + pagination + CRUD dialogs) + Sidebar (search + facets). Schema-driven: feed it a JSON Schema and you get a sortable, filterable, editable list page in one prop.
- CnDetailPage — Topbar + Left nav + Page header + Main (stats / charts / cards) + Sidebar (object metadata, files, notes, audit trail). For pages that show one thing in depth.
- CnDashboardPage — Topbar + Left nav + Page header + Main (drag-and-drop widget grid). For high-level overviews with KPIs, charts, tile-shortcuts.
- CnSettingsPage — Topbar + Left nav + Page header + Main (sectioned forms wired to
IAppConfig). For admin / configuration screens.
Pick the stacked view that matches the page's purpose; the chassis comes free. Per-page customisation happens through slots and props, never through re-laying-out the atoms.
Why this matters
Three things follow from the chassis-plus-atoms-plus-views discipline:
- Cross-app muscle memory. A user who learnt where things are in OpenRegister navigates Procest the first time without reading docs.
- Consistent accessibility, theming, i18n. All five atoms inherit Nextcloud's CSS variables, NL Design System tokens, and standard ARIA — no per-app drift.
- Composability stays cheap. A new app describes its content in a JSON manifest and a schema; the chassis renders it.
Where to next
- App manifest — the JSON contract that fills and configures the atoms.
- Schemas and registers — how data structure flows from the backend register into the frontend stacked views.
- Component reference — every
Cn*component used by the stacked views, with live demos.