Controls
Hosanna UI controls are regular Hosanna views with a helpful opinionated API. They inherit the same lifecycle, state model, layout, and styling mechanisms as other views, then add control-specific behavior (events, keyboard handling, composition).
How Controls Work
- They extend views: Controls subclass the same
BaseViewas primitives and groups. You use them declaratively ingetViews(). - Stateful styling: Controls read styles via
styleKey, and apply the correct sub-style based onViewStatus(e.g.,normal,focused,selected). - Focus-aware: Each view has
isFocused; the focus system updates it automatically.ViewStatustracks high-level interaction state and drives styles. - Custom data: Use
customData(...)to attach arbitrary data. Retrieve it strongly typed at runtime withview.getCustomData<T>().
Most controls accept text, style keys, and event callbacks. Add features incrementally to keep performance predictable.
Styling Controls with Stateful Styles
Controls use the same AppConfig style system as all views. A styleKey points to a style entry in assets/meta/app.config.json. Control styles typically live under controls.<ControlType>.<subStyle> and contain per-status dictionaries:
{
"controls": {
"Button": {
"default": {
"normal": { "color": "~theme.colors.white" },
"focused": { "color": "~theme.colors.red" },
"selected": { "opacity": 0.9 }
},
"primary": {
"normal": { "titleFontKey": "~theme.fonts.text-bold-20" }
}
}
}
}
- styleKey: For example,
controls.Button.defaultorcontrols.Button.primary. - Stateful: Sub-keys such as
normal,focused,selected,disabled,error,focusSelectedmap toViewStatusvalues. - Auto-application: When focus changes, the framework switches the active style sub-dictionary automatically.
Use controls.<ControlType>.<subStyle> for control styles (e.g., controls.Button.default). Keep tokens (~theme.colors.*, ~theme.fonts.*) for portability.
Focus, ViewStatus, and Styles
isFocusedis updated by the focus system. You do not set it manually.ViewStatuscan be controlled when needed (e.g., programmatically select a control), and the style engine uses it to pick the right sub-style.- Typical statuses:
normal,focused,selected,disabled,error,focusSelected.
Avoid changing view state inside animation ticks. Let the animator finish, then persist the final logical state.
Custom Data on Controls
Attach context to any view/control and retrieve it later without type assertions scattered across your code:
Button({ text: 'Details', styleKey: 'controls.Button.primary' })
.customData({ productId: item.id })
.onClick((event) => {
const data = event.view.getCustomData<{ productId: string }>();
this.openDetails(data.productId);
});
Example: Button + Stateful Styles
Button({
text: 'Click me',
styleKey: 'controls.Button.default',
width: 300,
height: 50,
})
.onClick(() => this.count++)
.customData({ kind: 'primary-action' });
- On focus,
ViewStatusbecomesfocused, and the style engine applies thefocusedstyle automatically. - You can set
viewStatus(ViewStatus.Selected)when you need a selected visual state.
Controls Index
Use the pages below for focused guides and reference notes:
| Control | Use it for |
|---|---|
| Button | Focusable click actions with text, icon, and background styling. |
| ButtonGroup | Data-driven groups of buttons. |
| CheckBox | Boolean toggle choices. |
| ComboBox | Single-choice dropdown selection. |
| ComboBoxButton | ComboBox button surface for custom dropdown work. |
| ComboBoxCard | ComboBox dropdown item surface for custom dropdown work. |
| FragmentView | Control wrapper for mounting a shared AppConfig fragment outside CollectionView. |
| LabelList | Small read-only text lists. |
| MiniKeyboard | Compact native keyboard entry. |
| NativeVoiceTextEditBox | Native text editing with voice input. |
| PinPad | PIN and short numeric entry. |
| Popup | Overlay content and modal interaction surfaces. |
| ScrollContainer | Lower-level scroll surfaces with custom scrollbar control. |
| ScrollView | Common scrollable layouts that follow focus. |
| TabSelector | Selectable tab rows. |
| Tag | Badge/status text with styled background. |
| TextEditBox | Direct native text edit box usage. |
| TextInput | App-level text input with keyboard dialog behavior. |
| VoiceTextButton | Button-style voice text entry. |