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 | A fixed four-slot data-driven button group. |
| 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 | A fixed four-slot label group without selection events. |
| MiniKeyboard | Thin native keyboard wrapper with a current callback-wiring caveat. |
| NativeVoiceTextEditBox | Native text editing with voice input. |
| PinPad | Thin native PIN-pad wrapper with fixed embedded settings. |
| 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 input that selects TV, web, or mobile editing. |
| VoiceTextButton | Fixed voice-text prototype; it is not an actionable Button. |