CFX UI sandbox
A development surface for the shared primitives in packages/ui. Every page renders real components against fixtures — no auth, no database, no Doppler, no credentials of any kind.
Pages
Each page answers a specific question about a component under conditions a dashboard makes hard to reproduce on demand: an error, an empty result, a slow page, a 400-option list, a 320px viewport.
Selectors
Every paginated-combobox surface — the form field, the multi-select filter editor, the bounded enum, both facet kinds, the applied-filter bar, and the list-page hero — against a fixture source with real latency, paging and failure.
- InfiniteCombobox
- InfiniteComboboxSingle
- StaticComboboxSingle
- FacetPill
- FacetOptionList
- FacetTogglePill
- FilterBar
- CommandSearch
PhoneInput
One specimen per state, then the five form shapes it ships into — real validation, real submit, so alignment and popover containment are visible rather than imagined.
- PhoneInput
Onboarding
The self-serve application end to end: sign-up and every login state, join or create, six sections that autosave as you go and finish in any order, the review gate, submit, and the verification roster, with the verification partner's webhooks played from the harness.
- SignUpForm
- ApplyStart
- ApplicationRail
- CompanySection
- OwnersSection
- DocumentsSection
- ReviewSection
- VerificationRoster
Onboarding states
Every onboarding screen in the state the walk-through can't reach on demand: a taken short name, a personal email domain, a second person at the same company, an owner missing a date of birth, a rejected upload, a retake request, a declined business, and a 320px column.
- TwoFactorEnrollmentRequired
- ConfirmEmailPanel
- ScreeningSection
- AddressesSection
- ActivitySection
- ScreenedOutNotice
- IdentityCheckPanel
Static combobox paging
The `staticOptionsPage` paging check: open a ~400-option list and scroll. Rows must arrive in pages rather than all mounting on open.
- StaticComboboxSingle
Team
The in-app roster: a 30-person page over MembersTable with real paging, an Admin actor's permission-shaped rows (unmanageable Owners, an unmanageable self), the read-only and single-member edges, pending invites, and the invite / role-change failure states.
- MembersTable
- PendingInvitesTable
- InviteMemberDialog
Account
The in-app account-security surface: name, email and password forms, every 2FA state including the frontend-API loading gap and a wrong-code rejection, and the manage-elsewhere fallback for hosts the frontend API can't reach.
- ProfileNameForm
- ChangeEmailForm
- ChangePasswordForm
- TwoFactorSection
- ManageOnSignInSite
Workspace
Renaming the PropelAuth org, with the fixed copy the dashboards show for a rejected name, and the shared logo dialog both dashboards use: a company logo and a bank's light/dark theme logos, including the size rejection.
- WorkspaceNameForm
- LogoUploadDialog
Settings layout
The register both dashboards' settings pages are built from: one h1 per page, all-caps muted section labels, and a label/content row that carries a plain value, a copyable ID or a whole form. Includes the container width where the two columns stop fitting side by side.
- SettingsPage
- SettingsPageHeader
- SettingsSection
- SettingsRows
- SettingsRow
Running it
Both commands are equivalent here — this package is tagged no-doppler, so doppler-serve runs the plain serve rather than wrapping it in a doppler run against a project that does not exist.
nx serve ui-sandbox nx doppler-serve ui-sandbox
Where this runs
Deployed from main by the same SST + OpenNext CD the dashboards use. A per-PR pr-<N> stage is also deployed on any PR that touches it, on the raw CloudFront URL — those are the previews, and they are why this app is called a sandbox rather than one.
prod https://ui-sandbox.cfx.to dev https://ui-sandbox.dev.cfx.to