Styling and texts¶
Three cascades: the chrome around a component, the fields inside it, and every string niceview says out loud. Concepts explains how they fit together, Components how to use them.
Chrome¶
style
¶
Chrome styling: the shared look of everything the wrappers draw around a form, grid or list — the title row, its buttons, the dialogs, the title of an embedded section, and the rows of a ModelList (which is chrome all the way down: the item's own fields are just text in it).
Two axes, because they are orthogonal — every chrome button sits in exactly one place and carries exactly one role:
{place}_button_props → shape → {role}_button_props
The place is where the button sits ('toolbar' at the top level, 'form' for a widget embedded in a form, 'dialog' in a dialog footer). The shape follows the button itself — icon-only or labelled — and a place may override it. The role is what the button means (add, delete, ok, …) and has the last word.
There is deliberately no base layer below the places: "every button of this application looks
like that" is a type statement, and NiceGUI already owns it —
ui.button.default_props('dense flat'). niceview only styles what NiceGUI cannot see.
Field styling is the second cascade (FieldStyle below). It is separate because it is keyed by widget category, not by place or role — but it follows the same idea: an application-wide default, a per-form layer, and the field itself.
Merge semantics, readable off the type:
str additive layer — props merge per key, the later layer wins
str | None replacing layer — None inherits, '' suppresses, a value replaces
*_classes replaces wholesale (a CSS class has no key to merge on)
set_chrome_style(toolbar_button_props='dense flat') # application-wide default
EditGridWrapper.from_list(..., chrome_style=ChromeStyle.derived(tooltips=False))
Place
module-attribute
¶
Place = Literal['toolbar', 'form', 'dialog']
Where a chrome button sits. 'toolbar' is a wrapper's own action row, 'form' the same row for a wrapper embedded in a form, 'dialog' a dialog footer. A ModelList row and a ModelGrid row are not places: the list row navigates (that is its whole job) and a grid cell lives client-side in AG Grid, where Quasar props do not reach.
NotifyKind
module-attribute
¶
NotifyKind = Literal[
"positive", "negative", "warning", "info"
]
Quasar's notification types. type= rather than color=: it brings the matching icon.
NotifyPosition
module-attribute
¶
NotifyPosition = Literal[
"top-left",
"top-right",
"bottom-left",
"bottom-right",
"top",
"bottom",
"left",
"right",
"center",
]
Where a notification appears — NiceGUI's own set of positions.
ChromeStyle
dataclass
¶
The look of the wrapper chrome. Instances are immutable — derive one with replace(), or from the application-wide default with ChromeStyle.derived().
Source code in niceview/style.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | |
title_row_classes
class-attribute
instance-attribute
¶
title_row_classes: str = 'w-full items-center flex-nowrap'
Classes of the title row (ui.row) of every wrapper.
title_classes
class-attribute
instance-attribute
¶
title_classes: str = 'text-h6 grow'
Classes of the title label. 'grow' pushes the buttons to the right edge.
card_title_classes
class-attribute
instance-attribute
¶
card_title_classes: str = 'text-subtitle2'
Classes of a layout section's title that draws a card ('# …').
section_title_classes
class-attribute
instance-attribute
¶
section_title_classes: str = 'text-subtitle2'
Classes of a title inside a form without a card ('## …'), and of the label of an embedded grid. One step below title_classes — it is a section, not the page heading.
form_row_classes
class-attribute
instance-attribute
¶
form_row_classes: str = 'w-full items-start gap-4'
Default classes of a layout row (a nested list). A ':classes' first element of the row replaces this — a class list has no key to merge on, so it is all-or-nothing.
form_column_classes
class-attribute
instance-attribute
¶
form_column_classes: str = 'w-full gap-4'
Default classes of a layout column — the plain default container and the body of a '## …' section. Replaced by a ':classes' first element, like form_row_classes.
form_card_classes
class-attribute
instance-attribute
¶
form_card_classes: str = 'w-full'
Default classes of a '# …' section card. Replaced by a ':classes' first element.
form_card_props
class-attribute
instance-attribute
¶
form_card_props: str = 'flat bordered'
Props of a '# …' section card.
toolbar_button_props
class-attribute
instance-attribute
¶
toolbar_button_props: str = ''
Props of the buttons in a wrapper's own action row. Empty: the chrome brings no look of its own, the buttons are Quasar's. Set it once for the application, e.g. 'dense flat'.
form_button_props
class-attribute
instance-attribute
¶
form_button_props: str = ''
Props of the buttons of a wrapper embedded in a form — chrome of a section, not of a page. Falls back to nothing, not to toolbar_button_props: the places are separate.
dialog_button_props
class-attribute
instance-attribute
¶
dialog_button_props: str = ''
Props of the buttons in a dialog footer.
icon_button_props
class-attribute
instance-attribute
¶
icon_button_props: str = ''
Props of a button that shows only its icon (label ''). Its shape follows the button itself, not where it sits — except inside a button group, see shape_in_group, and where a place overrides it below. Empty; 'round' is the usual choice.
labelled_button_props
class-attribute
instance-attribute
¶
labelled_button_props: str = ''
Props of a button that carries a label.
toolbar_icon_button_props
class-attribute
instance-attribute
¶
toolbar_icon_button_props: str | None = None
Icon shape in the toolbar. None inherits icon_button_props, '' suppresses the shape entirely, a value replaces it. Replacing rather than adding, because Quasar's shapes are separate boolean props: 'round' and 'rounded' are two keys, so a later layer cannot cancel an earlier one by setting a different one.
form_icon_button_props
class-attribute
instance-attribute
¶
form_icon_button_props: str | None = None
Icon shape for a wrapper embedded in a form. See toolbar_icon_button_props.
dialog_icon_button_props
class-attribute
instance-attribute
¶
dialog_icon_button_props: str | None = None
Icon shape in a dialog footer. See toolbar_icon_button_props.
shape_in_group
class-attribute
instance-attribute
¶
shape_in_group: bool = False
Whether the shape layer applies inside a ui.button_group as well. Off, because a group joins straight edges and a circle has none: 'round' children turn a group into circles with a border segment glued on. Turn it on if your shape props survive being joined (Quasar's 'rounded' does, 'round' does not) — or set button_group=False to get round icon buttons everywhere. Joined or round, not both.
add_button_props
class-attribute
instance-attribute
¶
add_button_props: str = ''
Props of the Add button.
edit_button_props
class-attribute
instance-attribute
¶
edit_button_props: str = ''
Props of the Edit button.
delete_button_props
class-attribute
instance-attribute
¶
delete_button_props: str = 'color=negative'
The only default in the whole style — and only because it is meaning, not taste.
save_button_props
class-attribute
instance-attribute
¶
save_button_props: str = ''
Props of the Save button.
refresh_button_props
class-attribute
instance-attribute
¶
refresh_button_props: str = ''
Props of the Refresh button.
back_button_props
class-attribute
instance-attribute
¶
back_button_props: str = ''
Props of the Back button.
ok_button_props
class-attribute
instance-attribute
¶
ok_button_props: str = ''
Props of a dialog's confirm button.
cancel_button_props
class-attribute
instance-attribute
¶
cancel_button_props: str = ''
Props of a dialog's cancel button.
button_group
class-attribute
instance-attribute
¶
button_group: bool = True
Whether chrome buttons that show at the same time are joined in a ui.button_group.
button_group_style
class-attribute
instance-attribute
¶
button_group_style: str = 'width: fit-content; flex: none'
Inline style of that group — it must not stretch or shrink with the title.
button_row_classes
class-attribute
instance-attribute
¶
button_row_classes: str = (
"flex items-center gap-1 w-fit flex-none"
)
Classes of the container used instead of the group: for a single button, or when button_group is off. Same job as button_group_style — hold the buttons at their own width at the right edge — plus the gap the group does not need.
tooltips
class-attribute
instance-attribute
¶
tooltips: bool = True
Whether the chrome buttons carry their default tooltips. What those tooltips say is niceview.text.ChromeText.
dialog_props
class-attribute
instance-attribute
¶
dialog_props: str = ':maximized="$q.screen.lt.md" transition-show="slide-up" transition-hide="slide-down"'
Props of every dialog niceview opens. Maximized on a small screen, sliding in from the bottom — the phone behaviour; a wide screen gets a plain centered card.
dialog_style
class-attribute
instance-attribute
¶
dialog_style: str = 'width: 400px'
Inline style of the dialog.
dialog_card_classes
class-attribute
instance-attribute
¶
dialog_card_classes: str = 'w-full'
Classes of the ui.card inside the dialog.
dialog_title_classes
class-attribute
instance-attribute
¶
dialog_title_classes: str = 'text-h6'
Classes of the dialog's title label.
dialog_button_row_classes
class-attribute
instance-attribute
¶
dialog_button_row_classes: str = 'w-full place-content-end'
Classes of the dialog's button row: cancel first, confirm last, right-aligned.
notify_position
class-attribute
instance-attribute
¶
notify_position: NotifyPosition = 'bottom'
Where niceview's notifications appear. Quasar's positions ('top', 'bottom-right', …).
notify_timeout
class-attribute
instance-attribute
¶
notify_timeout: float = 5.0
How long they stay, in seconds. 0 keeps them until dismissed.
notify_close_button
class-attribute
instance-attribute
¶
notify_close_button: bool = False
Whether they carry a close button.
notify
class-attribute
instance-attribute
¶
notify: Callable[[str, NotifyKind], None] | None = None
Hook for an application with a notification system of its own: called with the message and its kind instead of ui.notify. None uses ui.notify with the three options above.
list_props
class-attribute
instance-attribute
¶
list_props: str = 'dense separator'
Props of a ModelList's ui.list.
list_item_classes
class-attribute
instance-attribute
¶
list_item_classes: str = 'cursor-pointer'
Classes of one ui.item. The list rows are clickable, hence the pointer.
list_title_props
class-attribute
instance-attribute
¶
list_title_props: str = ''
Props of an item's title ui.item_label.
list_subtitle_props
class-attribute
instance-attribute
¶
list_subtitle_props: str = 'caption'
Props of an item's subtitle ui.item_label.
list_chevron_icon
class-attribute
instance-attribute
¶
list_chevron_icon: str | None = 'chevron_right'
Icon at the right edge of a row, hinting at the detail view behind it. None renders no icon and no section for it — for a list that is not a drill-down.
list_chevron_classes
class-attribute
instance-attribute
¶
list_chevron_classes: str = 'text-grey'
Classes of that icon.
replace
¶
derived
classmethod
¶
derived(**overrides: Any) -> ChromeStyle
The application-wide style with the given attributes changed — the usual way to build
the chrome_style= of a single widget, which replaces the default rather than adding
to it:
EditGridWrapper.from_list(..., chrome_style=ChromeStyle.derived(button_group=False))
Deriving is not avoidable by merging a partial style: a fresh dataclass carries defaults, not "unset", so ChromeStyle(button_group=False) could not be told apart from "every other value deliberately at its default".
Source code in niceview/style.py
get_chrome_style
¶
get_chrome_style() -> ChromeStyle
set_chrome_style
¶
set_chrome_style(
style: ChromeStyle | None = None, **overrides: Any
) -> ChromeStyle
Set the application-wide chrome style and return it. Call with a complete ChromeStyle, or with keyword arguments to change single attributes of the current one:
set_chrome_style(toolbar_button_props='dense', tooltips=False)
Wrappers read the style when they render, so this takes effect for everything rendered afterwards — call it once at startup, before the first page is built.
Source code in niceview/style.py
Fields¶
FieldStyle
dataclass
¶
Application-wide defaults for the fields niceview renders — in a ModelForm and in the model-free render_field() alike — by widget category.
Two categories, because that is what the practice asks for: an input and a select take the same props, a switch does not ('outlined' says nothing to a checkbox). A category is niceview's vocabulary — NiceGUI can only say "every ui.input", which would make the application enumerate ten widget types.
The cascade below this: ModelForm(base_props=…) for one form, FieldInfo(props=…) for one field. Props are additive per key, the narrower layer wins; classes replace wholesale.
Source code in niceview/style.py
input_props
class-attribute
instance-attribute
¶
input_props: str = ''
Props for the QInput/QSelect based widgets — see widgets.INPUT_BASED_WIDGETS.
control_props
class-attribute
instance-attribute
¶
control_props: str = ''
Props for checkbox, switch, radio, toggle, checkbox_group, slider, rating — see widgets.CONTROL_WIDGETS.
default_classes
class-attribute
instance-attribute
¶
default_classes: str = ''
Classes for every field that brings none of its own (in a ModelForm, only when the form sets no default_classes of its own either).
caption_classes
class-attribute
instance-attribute
¶
caption_classes: str = 'text-caption'
Classes of the caption label placed above widgets that have no label slot of their own — radio, toggle, checkbox_group, slider, rating.
checkbox_group_classes
class-attribute
instance-attribute
¶
checkbox_group_classes: str = 'gap-x-4 gap-y-1'
Classes of the checkbox_group's inner container that holds the checkboxes.
replace
¶
derived
classmethod
¶
derived(**overrides: Any) -> FieldStyle
The application-wide field style with the given attributes changed.
get_field_style
¶
get_field_style() -> FieldStyle
set_field_style
¶
set_field_style(
style: FieldStyle | None = None, **overrides: Any
) -> FieldStyle
Set the application-wide field style and return it:
set_field_style(input_props='outlined dense', default_classes='w-full')
Source code in niceview/style.py
Texts¶
ChromeText
dataclass
¶
The texts of the chrome. Immutable — derive one with replace() or ChromeText.derived().
Source code in niceview/text.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
add_tooltip
class-attribute
instance-attribute
¶
add_tooltip: TextValue = 'Add a new item'
Tooltip of the Add button.
edit_tooltip
class-attribute
instance-attribute
¶
edit_tooltip: TextValue = 'Edit item'
Tooltip of the Edit button.
delete_tooltip
class-attribute
instance-attribute
¶
delete_tooltip: TextValue = 'Delete selected item'
The grid's Delete acts on the selected row.
delete_item_tooltip
class-attribute
instance-attribute
¶
delete_item_tooltip: TextValue = 'Delete this item'
The drill-down's Delete acts on the item that is open.
refresh_tooltip
class-attribute
instance-attribute
¶
refresh_tooltip: TextValue = 'Refresh'
Tooltip of the Refresh button.
save_tooltip
class-attribute
instance-attribute
¶
save_tooltip: TextValue = 'Save'
Tooltip of the Save button.
back_tooltip
class-attribute
instance-attribute
¶
back_tooltip: TextValue = 'Back'
Tooltip of the Back button.
search_placeholder
class-attribute
instance-attribute
¶
search_placeholder: TextValue = 'Search'
Placeholder of the search input (EditGridWrapper's search=True).
ok_label
class-attribute
instance-attribute
¶
ok_label: TextValue = 'OK'
Confirm button label in a dialog.
cancel_label
class-attribute
instance-attribute
¶
cancel_label: TextValue = 'Cancel'
Cancel button label in a dialog.
create_label
class-attribute
instance-attribute
¶
create_label: TextValue = 'Create'
Confirm button label of the create dialog.
delete_label
class-attribute
instance-attribute
¶
delete_label: TextValue = 'Delete'
Confirm button label of a delete confirmation.
delete_selected_title
class-attribute
instance-attribute
¶
delete_selected_title: TextValue = 'Confirm Deletion'
Title of the grid's delete-confirmation dialog.
delete_selected_message
class-attribute
instance-attribute
¶
delete_selected_message: TextValue = "Are you sure you want to delete the selected item *{key}*?"
Message of the grid's delete-confirmation dialog; {key} is the selected row's key.
delete_item_title
class-attribute
instance-attribute
¶
delete_item_title: TextValue = 'Delete'
Title of the drill-down's delete-confirmation dialog.
delete_item_message
class-attribute
instance-attribute
¶
delete_item_message: TextValue = (
"Delete this item? This cannot be undone."
)
Message of the drill-down's delete-confirmation dialog.
invalid_input
class-attribute
instance-attribute
¶
invalid_input: TextValue = 'Invalid input'
Shown when a value fails validation.
unknown_selection
class-attribute
instance-attribute
¶
unknown_selection: TextValue = (
"Unknown selection — no longer in the list"
)
Shown when the selected row is no longer in the collection.
item_created
class-attribute
instance-attribute
¶
item_created: TextValue = 'Item created'
Notification after a successful create.
item_updated
class-attribute
instance-attribute
¶
item_updated: TextValue = 'Item updated'
Notification after a successful update.
item_deleted
class-attribute
instance-attribute
¶
item_deleted: TextValue = 'Item deleted'
Notification after a successful delete.
create_cancelled
class-attribute
instance-attribute
¶
create_cancelled: TextValue = 'Item creation cancelled'
Notification when the create dialog is cancelled.
update_cancelled
class-attribute
instance-attribute
¶
update_cancelled: TextValue = 'Item update cancelled'
Notification when an update dialog is cancelled.
delete_cancelled
class-attribute
instance-attribute
¶
delete_cancelled: TextValue = 'Item deletion cancelled'
Notification when a delete confirmation is cancelled.
create_error
class-attribute
instance-attribute
¶
create_error: TextValue = 'Error creating item: {error}'
Notification when create fails; {error} is the exception.
update_error
class-attribute
instance-attribute
¶
update_error: TextValue = 'Error updating item: {error}'
Notification when update fails; {error} is the exception.
delete_error
class-attribute
instance-attribute
¶
delete_error: TextValue = (
"Error deleting item {key}: {error}"
)
Notification when a grid's delete fails; {key} and {error} name the row and exception.
delete_failed
class-attribute
instance-attribute
¶
delete_failed: TextValue = 'Error deleting item: {error}'
Deleting the open item in a drill-down, where the key is not worth naming again.
save_error
class-attribute
instance-attribute
¶
save_error: TextValue = 'Error saving change: {error}'
Notification when an autosaving form's save fails; {error} is the exception.
select_row_first
class-attribute
instance-attribute
¶
select_row_first: TextValue = 'Please select a row first!'
Notification when an action needs a selected row but none is selected.
select_row_to_delete
class-attribute
instance-attribute
¶
select_row_to_delete: TextValue = (
"Please select a row for deletion!"
)
Notification when Delete is clicked with no row selected.
item_not_found
class-attribute
instance-attribute
¶
item_not_found: TextValue = 'Item with key {key} not found'
Notification when {key} no longer exists in the collection.
row_not_found
class-attribute
instance-attribute
¶
row_not_found: TextValue = "Row {key} not found — try again"
Notification when a grid row's key no longer exists.
conflict
class-attribute
instance-attribute
¶
conflict: TextValue = "This item was changed by another user. The list has been refreshed — please edit again."
Notification when a save loses an optimistic-lock conflict to another writer.
invalid_value
class-attribute
instance-attribute
¶
invalid_value: TextValue = (
"Invalid value {value!r}: {errors}"
)
Notification for an invalid value outside a form (e.g. an inline grid edit).
validation_errors
class-attribute
instance-attribute
¶
validation_errors: TextValue = (
"Cannot save form: validation errors present"
)
Notification when Save is blocked by validation errors.
form_refreshed
class-attribute
instance-attribute
¶
form_refreshed: TextValue = 'Form refreshed'
Notification after Refresh reloads a form.
form_saved
class-attribute
instance-attribute
¶
form_saved: TextValue = 'Form saved'
Notification after a non-autosaving form saves.
no_items
class-attribute
instance-attribute
¶
no_items: TextValue = 'No items yet.'
Shown in an empty list view.
detail_not_found
class-attribute
instance-attribute
¶
detail_not_found: TextValue = 'Item {key!r} not found.'
Shown in the detail view when {key} no longer exists.
required_marker
class-attribute
instance-attribute
¶
required_marker: TextValue = ' *'
Appended to the label of a required field. A form may still set None to render none.
required_message
class-attribute
instance-attribute
¶
required_message: TextValue = 'Required'
Validation message of an empty required field.
replace
¶
derived
classmethod
¶
derived(**overrides: Any) -> ChromeText
The application-wide texts with the given ones changed — for a single widget's
chrome_text=, which replaces the default rather than adding to it.
Source code in niceview/text.py
TextValue
module-attribute
¶
A text: either the string itself, or a callable returning it. The callable is invoked every time the text is rendered, so it can resolve the current client's language.
text_of
¶
Resolve a text: call it if it is a callable, then fill in its named placeholders.
Without params the template is returned unchanged, so a text containing braces of its own survives (formatting it would raise).
Source code in niceview/text.py
get_chrome_text
¶
get_chrome_text() -> ChromeText
set_chrome_text
¶
set_chrome_text(
text: ChromeText | None = None, **overrides: Any
) -> ChromeText
Set the application-wide chrome texts and return them. Call with a complete ChromeText, or with keyword arguments to change single texts of the current one:
set_chrome_text(add_tooltip='Neuen Eintrag anlegen', ok_label='Ok')
Widgets read the texts when they render, so this takes effect for everything rendered afterwards — call it once at startup.
Source code in niceview/text.py
Building blocks¶
What the wrappers are made of. An application rarely calls these — they are here because a custom wrapper that wants to look like niceview's own has to.
Chrome styling: the shared look of everything the wrappers draw around a form, grid or list — the title row, its buttons, the dialogs, the title of an embedded section, and the rows of a ModelList (which is chrome all the way down: the item's own fields are just text in it).
Two axes, because they are orthogonal — every chrome button sits in exactly one place and carries exactly one role:
{place}_button_props → shape → {role}_button_props
The place is where the button sits ('toolbar' at the top level, 'form' for a widget embedded in a form, 'dialog' in a dialog footer). The shape follows the button itself — icon-only or labelled — and a place may override it. The role is what the button means (add, delete, ok, …) and has the last word.
There is deliberately no base layer below the places: "every button of this application looks
like that" is a type statement, and NiceGUI already owns it —
ui.button.default_props('dense flat'). niceview only styles what NiceGUI cannot see.
Field styling is the second cascade (FieldStyle below). It is separate because it is keyed by widget category, not by place or role — but it follows the same idea: an application-wide default, a per-form layer, and the field itself.
Merge semantics, readable off the type:
str additive layer — props merge per key, the later layer wins
str | None replacing layer — None inherits, '' suppresses, a value replaces
*_classes replaces wholesale (a CSS class has no key to merge on)
set_chrome_style(toolbar_button_props='dense flat') # application-wide default
EditGridWrapper.from_list(..., chrome_style=ChromeStyle.derived(tooltips=False))
chrome_row
¶
chrome_row(style: ChromeStyle) -> row
chrome_title
¶
chrome_title(text: str, style: ChromeStyle) -> label
chrome_buttons
¶
chrome_buttons(
style: ChromeStyle, count: int
) -> Iterator[element]
The container for the chrome buttons.
count is how many of them are visible at the same time — not how many the wrapper
builds. Quasar styles a button group as one joined control (squared-off inner edges, a
shared border), which only says something with a second button to join: a group of one
is a button wearing a group's clothes. So one button, or button_group=False, goes into a
plain flex container instead.
Source code in niceview/style.py
chrome_button
¶
chrome_button(
kind: str | None,
label: str,
icon: str | None,
tooltip: str,
style: ChromeStyle,
on_click: Callable[..., Any] | None = None,
place: Place = "toolbar",
) -> button
One chrome button, built from three layers of props: the props of its place, the shape
the label asks for (icon-only or labelled), and the props of its kind ('add', 'delete',
…). label is the caller's '' (icon only) or its own text.
The shape depends on the button rather than on where it sits, with two exceptions: a place may replace the icon shape (a dialog wants squared-off buttons where a lone toolbar button is round), and inside a button group there is nothing to round, so the layer is skipped there unless the style says otherwise.
kind is None for an application's own action (niceview.FormAction): the roles are a closed
vocabulary of what niceview itself means by a button, so an action skips that layer and
brings its own props instead. Place and shape still apply — it sits among the others.
Source code in niceview/style.py
chrome_dialog
¶
chrome_dialog(style: ChromeStyle) -> Iterator[dialog]
The shell of every dialog niceview opens: the ui.dialog and the ui.card inside it, entered as the current context. The caller fills the card and awaits the yielded dialog.
Source code in niceview/style.py
chrome_dialog_title
¶
chrome_dialog_title(text: str, style: ChromeStyle) -> label
chrome_dialog_buttons
¶
chrome_dialog_buttons(style: ChromeStyle) -> row
The button row of a dialog. Use as a context manager: cancel first, confirm last.
chrome_notify
¶
chrome_notify(
message: str, kind: NotifyKind, style: ChromeStyle
) -> None
Show one of niceview's notifications. Routed to the style's notify hook if the
application brought one, otherwise to ui.notify with the style's options.
kind is Quasar's semantic type, not a color — niceview never spells a color of its own.
Source code in niceview/style.py
Dialogs¶
field_stores_model
¶
True when a modelselect field's declared type is a model itself (a relationship/object,
e.g. author: Author), False for a scalar key (e.g. author: str | None). This selects
the modelselect mode: object-select (store/return the related object, sync a {name}_id
companion) vs. key-select (store the repository key directly in the field).
Source code in niceview/util.py
resolve_repository
¶
Look up the repository for a modelselect field.
Repositories may be keyed by field name (preferred: two fields can reference the same model through different collections) or, for backward compatibility, by the related model type (the SQLModel-relationship style). Field name wins. Returns None when neither matches.
Source code in niceview/util.py
meta_option
¶
meta_option(
item_type: type,
kwargs: Any,
key: str,
default: Any,
*,
meta_key: str | None = None,
) -> Any
Resolve a wrapper option from (descending priority) kwargs, the model's Meta, or default.
Pops key from kwargs: an explicitly passed value (even None) wins over Meta, mirroring
how ModelForm reads its own Meta options. meta_key reads a differently named Meta attribute
(e.g. a collection wrapper's title kwarg defaulting from Meta.title_plural).
kwargs is typed Any rather than dict: callers pass their **kwargs: Unpack[SomeTypedDict]
directly, and a TypedDict is not assignable to dict[Any, Any] under mypy (it may reject
arbitrary key mutation), even though .pop() on an optional key is safe at runtime.
Source code in niceview/util.py
maybe_await
async
¶
Await result if it is awaitable, pass it through otherwise.
Calling an async def handler returns a coroutine; dropping it does nothing at all except
emit a RuntimeWarning, which is the worst way for a click handler to fail. Every place that
invokes a caller-supplied callback directly (rather than through NiceGUI's handle_event,
which does the same thing for callbacks that take an event argument) goes through here, so
def and async def are equally valid there.
Source code in niceview/util.py
confirm_dialog
async
¶
confirm_dialog(
title: str,
message: str,
*,
ok_label: str | None = None,
cancel_label: str | None = None,
ok_role: str = "ok",
chrome_style: ChromeStyle | None = None,
chrome_text: ChromeText | None = None,
) -> bool
Show a confirmation dialog. Returns True if confirmed, False if cancelled.
ok_role picks the role layer of the chrome cascade for the confirm button rather than a
color: 'delete' makes it negative, and an application that restyles its delete buttons
restyles this one with them.
Usage: if not await confirm_dialog('Delete Device', f'Delete {name!r}? Irreversible.', ok_label='Delete', ok_role='delete'): return
Source code in niceview/util.py
input_dialog
async
¶
input_dialog(
title: str,
*,
label: str,
placeholder: str = "",
value: str = "",
validator: Callable[[str], bool | Awaitable[bool]]
| None = None,
error_message: str | None = None,
chrome_style: ChromeStyle | None = None,
chrome_text: ChromeText | None = None,
) -> str | None
Show an input dialog. Returns the entered string, or None if cancelled.
The validator may be sync or async — async is what you want when the answer lives elsewhere ("is this name still free?"), and it gates the OK button just as a sync one does.
Usage: name = await input_dialog('Create Project', label='Project Name', placeholder='my-project', validator=is_valid_filename, error_message='Only letters, digits, _ - + allowed') if name is None: return # cancelled create_project(name)
Source code in niceview/util.py
submit_dialog
async
¶
submit_dialog(
title: str,
message: str,
buttons: tuple[str, ...] | list[str] = ("Cancel", "OK"),
*,
chrome_style: ChromeStyle | None = None,
) -> str | None
Show a dialog with a title, message and buttons; returns the text of the pressed button, or None if the dialog was dismissed (e.g. Escape key). Buttons can be prefixed with a character for formatting and to set the color: - '|': space before button (also in combination with color) - '1': primary - '2': secondary - 'a': accent - 'd': dark - '+': positive - '-': negative - 'i': info - 'w': warning
Usage: result = await submit_dialog('Title', 'Message', ['|dCancel', 'OK'])