Implement reliable agent apply, telemetry v2, analytics retention, guarded rollouts, enrollment, labels and webhooks. Improve ReUI frontend data safety and bounded list loading, and add Docker smoke, recovery and resource checks. Document local verification and pending native acceptance.
5.7 KiB
Compose a screen
Read this before you build any screen or section, then write the router's 7-line plan in your reply (Surface, Archetype, Container family, Density, Regions, States, Motion) and build exactly that plan. Style it with the topics the screen touches: layout.md (house defaults), color.md, motion.md.
If the brief names a layout or a motion (a left nav, 2 entrances), follow the brief and name the default you overrode. Several entrances run as 1 stagger: at most 6 items, 50ms apart, never on table rows or lists of 20 or more.
Surface
- Operational: a screen people work in every day (dashboard, records, settings, admin tools). Frame-led, dense (
size="sm"on controls that take it), no hero, no page-load motion. - Marketing: a page a visitor reads once (landing, pricing, features). Card-led sections on the spine below, default density.
- Flow: a task people finish and leave (sign in, onboarding, checkout). 1 centered Card or a Dialog, 1 primary action per step.
Archetypes: pick 1 per screen
- Vertical rail settings (3 to 6 sections): a section rail on the left, 1 content column, 1 section at a time; the rail turns horizontal below
md. - Horizontal tabs (5 to 8 views of 1 object): a full-width
Tabsrail under the header that scrolls sideways when it overflows, 1 content column. - Frame stack: stacked Frames, each 1 focused group of settings or records; a flat page split by
Separatorrows when it should feel lighter. - Table-backed management: header, toolbar (search,
filters), then adata-gridwith row actions and pagination, all in 1 Frame. - Dashboard grid: a KPI row, then 1 or 2 chart or list panels, then the table.
- Board: header and filters, then a
kanbanboard;KanbanBoardstacks its columns belowsm, and a wider board scrolls inside its own region. - Record detail: header (title, status
Badge, actions), a main column of sections, a side column of facts that stacks under it belowlg. - Marketing spine: optional
Badgeeyebrow, headline (the only loud element), 1-clause subhead, action row (1 primaryButton, a secondvariant="outline", a third a text link), specific proof beside it ("27 reviews"), media. Omit parts; never reorder them. - Auth card: 1 centered
Cardatmax-w-sm: title, fields, 1 full-width primaryButton, a text link to the other flow. - Wizard dialog: a
Dialogholding astepper, 1 step visible, Back (variant="outline") and Next (primary) in its footer.
An app shell around any of them is the shadcn Sidebar, which turns into a Sheet below md by itself.
Fill each region in this order
- The ReUI component that owns the job: the router's Owners (
data-grid,filters,kanban),useFileUploadfrom@/hooks/use-file-uploadfor file drop, or the one whose contract in components.md matches. - A shadcn/ui component (
Tabs,Dialog,AlertDialog,Sheet,Empty,Skeleton,sonner). - A free
c-*example fromget_examplesthat already composes it: install it and adapt. - Your own composition of those parts. Never a hand-rolled table, modal or tabs.
Import ReUI parts file by file: data-grid, filters, cascader, event-calendar and gantt are folders with no index file. data-grid: the import line in components.md. filters, each from @/components/reui/filters/<file>: Filters from filters, createFilterQuery and flattenFilterConditions (1 argument, the query) from filters-query, the types FilterField and FilterQuery from filters-types.
Wiring that works
data-grid: columns areColumnDef<DataGridFeatures, Order>[], a sortable header rendersDataGridColumnHeader, and server paging needsmanualPagination: trueandrowCount.filters: apply each condition by itsoperator. Negate swaps a rule to its inverse (isandis_not,containsandnot_contains,is_any_ofandis_none_of,emptyandnot_empty) and setsnegatedonly when there is none: honour both.- A Base UI
Buttonthat navigates:<Button nativeButton={false} render={<Link href="/x" />}>. - shadcn's
CommandDialoghas noCommandinside, unlike older shadcn: wrapCommandInputandCommandListin one.CommandItemsearch matches itsvalue: omit it (text is used) or use the label; ids inonSelect.
Headers
A page or panel header puts the title (1 to 3 words) and a 1-clause description on the left and the actions on the right: 1 primary Button, the rest variant="outline", row actions variant="ghost".
Responsive
- No horizontal page scroll at 390px: grids drop to 1 column, side columns stack,
min-w-0on every shrinking parent. - A KPI row is
grid-cols-1 sm:grid-cols-2 xl:grid-cols-4. - Every header and toolbar action stays reachable at every width: a control hidden below a breakpoint moves into a menu shown only there.
- A table scrolls sideways inside its Frame, never the page (the
data-gridcontract in components.md).
States and motion
- Each data region owns its states: empty (shadcn
Emptywith a title, 1 line and the primary action), loading (Skeletonin the real layout;data-gridtakesisLoading) and error (inline in the region, with Retry). Never 1 spinner for the whole page. - Motion: none, or the 1 entrance per view; installed parts keep their own motion, and hover and press follow motion.md. An Alert, field error, notice or data that appears after an action or a load is a reveal, not an entrance: fade it in with the reveal row.
Remove first
Overloaded? Remove, in order: decorative summaries, duplicate context, extra badges, long descriptions, secondary actions, mismatched icon treatments. Add a region only when the brief needs it.