Settings
A traditional settings page composition: a single, vertically-stacked form
constrained to a comfortable reading width, broken into titled sections.
Built on the Form component (TanStack Form + Zod) with
PageHeader, Field (and friends), Input, Textarea, Select,
RadioGroup, Switch, and Button. Intended to render inside an
ApolloShell.
Composition
From top to bottom the template stacks:
Shell(outer) — provides the chrome (sidebar, header, auth, theme). Wrap the rest of the page insideApolloShell.PageHeader— page title.- Sections — four titled
<section>s (Profile, Notifications, Regional, Privacy & security) wrapped by a small in-fileSectionhelper. Each section starts with anh2+ description header, then aFieldGroupofFields. Sections usemb-8for vertical rhythm. - Field stack — within each
Field, content stacksFieldLabel→FieldDescription→ control (Input, Textarea, Select, RadioGroup). Toggle rows useorientation="horizontal"so the label sits left and theSwitchsits right. - Action footer — right-aligned
Reset to defaults(outline) andSave changes(primary)Buttons.Savesubscribes to the form’sisDirtystate and stays disabled until there are unsaved changes.
Grid
The page uses the foundation grid:
- Outer container has
px-4 sm:px-6 lg:px-8margins matching the defaultPageHeader, and agrid grid-cols-4 sm:grid-cols-8 lg:grid-cols-12 gap-4row. - The form column spans
col-span-4 sm:col-span-8 lg:col-span-7— full width on mobile/tablet, ~58% width on desktop. This keeps line lengths readable (~600–760px depending on viewport) instead of letting the form stretch edge-to-edge on wide monitors. - Within Regional, Language and Timezone share a nested
grid grid-cols-1 sm:grid-cols-2 gap-4so they pair on one row from tablet up.
| Breakpoint | Form column |
|---|---|
Mobile (grid-cols-4) | col-span-4 (full width) |
Tablet (sm:grid-cols-8) | sm:col-span-8 (full width) |
Desktop (lg:grid-cols-12) | lg:col-span-7 (~58%) |
Sections inside the form column are separated vertically with mb-8 (32px)
on each section.
Source: templates/settings/WorkspaceSettings.tsx
Installation
The composition itself is a pattern — copy the source from
templates/settings/WorkspaceSettings.tsx into your app, wrap it in
ApolloShell, and swap in your own state/persistence. The underlying
components install from the registry:
npx shadcn@latest add @uipath/shell
npx shadcn@latest add @uipath/page-header
npx shadcn@latest add @uipath/form
npx shadcn@latest add @uipath/field
npx shadcn@latest add @uipath/input
npx shadcn@latest add @uipath/textarea
npx shadcn@latest add @uipath/select
npx shadcn@latest add @uipath/radio-group
npx shadcn@latest add @uipath/switch
npx shadcn@latest add @uipath/buttonCustomizing
- Form width —
lg:col-span-7matches the comfortable form line length used across the Vertex apps. Bump tolg:col-span-8for slightly wider controls orlg:col-span-6for tighter forms. Stay within the 12-column grid so margins line up with thePageHeader. - Persistence — form state is owned by the
Formcomponent (useAppForm).onSubmitreceives the validated values; the template resets the form to those values so it returns to a pristine state. SwaponSubmitfor a call to your own store, server action, or settings API, and add toast feedback withSonnerfrom the registry. - Categorical fields —
emailFrequencyandvisibilityarez.enummembers in the Zod schema, rendered withRadioGroupField. The schema keeps their values type-safe end-to-end. Follow the same pattern when adding more categorical settings. - Date format — the
dateFormatoption values (short,medium,long) map directly toIntl.DateTimeFormat({ dateStyle })so they render without a date library. Swap indate-fnsformat strings or your own enum if you need finer control. - Sub-page navigation — settings UIs often have multiple sub-sections
routed independently (e.g.
/settings/profile,/settings/notifications). Move each<Section>to its own route and add a left-rail nav with verticalTabsor a sidebar. - Field orientation —
Fieldacceptsorientation="horizontal"(label left, control right) or"vertical"(label above control). The template uses horizontal forSwitchrows and vertical for everything else. - Pairing fields — wrap a couple of
Fields in a nestedgrid grid-cols-1 sm:grid-cols-2 gap-4to lay them side-by-side from tablet up (as Language + Timezone do here). - Validation — the whole-form Zod schema is passed to the
Form’svalidators.onChange. Each field renders its own translatable errors, andFormErrorSummarycan list them all in one accessible block. - i18n — wrap your app in
ApolloShell(which initializes i18n viaLocaleProvider) or provide your ownI18nextProviderso any registry-component strings render correctly.