Form section, save bar and unsaved guard
Long sectioned forms: a numbered section with the 180px label column at compact (stacked on phone), the dark pending-changes bar (dirty · saving · saved · validation summary that jumps to fields · conflict “someone else changed this” with Compare / Reload / Keep mine), and the unsaved-changes guard on shell nav and tab close.
Covers: form-section primitive, form-section designer, save-bar primitive, save-bar designer, unsaved-guard designer. Exports: FormSection, SaveBar, UnsavedGuard.
Anatomy
The component as it sits in the product: English, compact, real data shapes.
Production
States
7 states, left to right, top to bottom. A mock poll never finishes, so each state is drawn on purpose.
Production
Production
Production
Production
Production
Production
Production
Density
The phone shell is always comfortable (POWERUPS #15): 44px tap targets, 16px inputs. Compact exists on desktop only; see the desktop page.
Production
English · 中文
Staff pick en or cn (T001 Q25). Labels arrive localised; CJK falls back to PingFang SC / Noto Sans SC.
Production
生产
Long string · permission denied
The long-string case (PL-063) and what a role without the permission sees (the server decides; T003).
Production
Production
Contract
The @rj/admin-kit API for this family. Mirrored in CONTRACT.md.
- Export
FormSection·@rj/admin-kit- Props
id·n·title·errors·layoutinline|stack ·repeatable- States
- clean · error
- shadcn / Radix
- none (fieldset)
- Package underneath
- react-hook-form
- Accessibility
- fieldset + legend; error count in the legend
- Export
SaveBar·@rj/admin-kit- Props
dirtyFields·onSave·onDiscard·conflict{by, at, version}- States
- hidden · dirty · saving · saved · error (summary) · conflict
- Package underneath
- react-hook-form formState · motion
- Accessibility
- status region; Save is ⌘S
- API operations
- any update; conflict from 409 version_conflict (If-Match / expected_version) e.g. admin.orders.measurements.update
- Phone variant
- full-width bar at the bottom
- Export
UnsavedGuard·@rj/admin-kit- Props
when(isDirty)- States
- closed · open
- shadcn / Radix
- AlertDialog
- Package underneath
- beforeunload + Next router guard
- Accessibility
- focus lands on Stay