Updated: 2026-06-26
Audited: 2026-06-26
node 229:152) is reused across every data-input and list-row context in the app. Variant
is determined by which slots are populated and which background/border tokens are applied — not by separate
Figma components. The four variants are: search (white bg, leading icon + trailing clear),
result-row (border-bottom only, text only — autocomplete suggestions),
nav-row (border-bottom + trailing chevron — Airline Policies list),
and labeled (label above + white box — Flight Finder inputs on blue bg).
psH738AqHDxuMyFm897f9r ·
Search screen (4951:11891) · Airline Policies (4713:25321) · Flight Finder (4713:25117) ·
captured 2026-06-26
| Variant | CSS modifier | Background | Border | Icons | Used in |
|---|---|---|---|---|---|
| Search input | --search | white (interactive/fields) | 1px solid white (invisible) | Leading: search mag, Trailing: × clear | Search screen top bar |
| Result row | --result-row | none (inherits page) | border-bottom 1px #d2d4d6 | None | Search autocomplete list |
| Nav row | --nav-row | none (inherits page) | border-bottom 1px #d2d4d6 | Trailing: chevron-right | Airline Policies list |
| Labeled | --labeled | white (interactive/fields) | 1px solid white (invisible) | Optional leading/trailing | Flight Finder date/airport inputs |
New ViewModel needed — not yet in ComponentViewModels.cs. Add FormFieldViewModel
and FormFieldVariant enum alongside existing types.
| Screen | Node | Variant | Notes |
|---|---|---|---|
| Search | 4951:11895 | Search | Top bar; mag leading + × trailing; white floating on #f5f7fa page bg |
| Search — autocomplete | 4951:11899–11908 | ResultRow | Thin gray bottom border; text only; Afacad SemiBold 18px |
| Airline Policies | 4713:25324–25333 | NavRow | Airline name left + chevron right; each row navigates to that airline's policy doc |
| Flight Finder | 4713:25117 | Labeled | Label above (white text on blue container bg) + white input box; used for date, departure/arrival airport fields |
border: 1px solid var(--interactive/fields, white). Both the border and the bg resolve to the same white token, making the border structurally present but visually invisible against the white box. Do not remove it — it maintains the spec contract for accessibility overlays.border-bottom: 1px solid #d2d4d6. The only difference is cursor:pointer + a trailing chevron icon on nav-row, and the nav-row wires to a navigation service via Link. The result-row fires a search event (OnResultSelected callback).#007bc2). The white input box has the same invisible-border pattern as Search. The consumer page/section owns the blue background — this component does not set it.<input type="text"> bound via @bind-value="Vm.Value" with @bind-value:event="oninput" for live autocomplete. For nav-row and result-row, use a <span> (read-only text display) rather than an input.HasLeadingIcon / HasClearButton booleans to show/hide slots rather than null-checking icon paths — this keeps the layout stable while the icon set is finalized.Target home: ALPAMobile.HybridUi. Component file: FormField.razor. New ViewModel required: FormFieldViewModel.
| Parameter | Type | Required | Description |
|---|---|---|---|
Vm | FormFieldViewModel | Yes | All field data including variant, value, placeholder, icons. |
OnValueChanged | EventCallback<string> | No | Fires on every keystroke (Search variant — drives autocomplete). |
OnClear | EventCallback | No | Fires when × button tapped (Search variant). |
OnResultSelected | EventCallback<FormFieldViewModel> | No | Fires when result-row row is tapped. |
OnNavTap | EventCallback<FormFieldViewModel> | No | Fires when nav-row is tapped; consumer calls nav service with Vm.Link. |
@* Search input bar *@
<AlpaFormField Vm="@searchField"
OnValueChanged="@HandleSearchInput"
OnClear="@ClearSearch" />
@* Autocomplete result rows *@
@foreach (var result in SearchResults)
{
<AlpaFormField Vm="@result"
OnResultSelected="@SelectResult" />
}
@* Airline Policies nav list *@
@foreach (var airline in Airlines)
{
<AlpaFormField Vm="@airline"
OnNavTap="@NavigateToPolicy" />
}
Classes will live in ALPAMobile.HybridUi/wwwroot/css/alpa-components.css under the alpa-form-field BEM block.
| Class | Scope | Key rules |
|---|---|---|
.alpa-form-field | Root wrapper | display:flex; flex-direction:column; gap:4px; width:100% |
.alpa-form-field__label | Above-field label | font-family:var(--font-family/alt); font-weight:600; font-size:16px; line-height:1.3 · color inherits from container context |
.alpa-form-field__input-row | Icon + text row | display:flex; align-items:center; gap:12px; padding:16px |
.alpa-form-field__icon | Leading or trailing icon slot | width:18px; height:18px; display:flex; align-items:center; justify-content:center; flex-shrink:0 |
.alpa-form-field__text | Input or read-only text | flex:1; font-family:var(--font-family/alt); font-weight:600; font-size:18px; color:var(--text-primary); border:none; background:transparent; outline:none |
.alpa-form-field--search | Search variant modifier | .alpa-form-field__input-row { background:white; border:1px solid white } |
.alpa-form-field--result-row | Autocomplete row modifier | .alpa-form-field__input-row { border-bottom:1px solid var(--border-default, #d2d4d6) } |
.alpa-form-field--nav-row | Navigation list row modifier | cursor:pointer · .alpa-form-field__input-row { border-bottom:1px solid var(--border-default, #d2d4d6) } |
.alpa-form-field--labeled | Labeled Flight Finder modifier | .alpa-form-field__input-row { background:white; border:1px solid white } |