from typing import Any, Literal, Optional, Union from typing_extensions import Self from ..context import context from ..element import Element from ..events import Handler, UiEventArguments, handle_event NotificationPosition = Literal[ 'top-left', 'top-right', 'bottom-left', 'bottom-right', 'top', 'bottom', 'left', 'right', 'center', ] NotificationType = Optional[Literal[ 'positive', 'negative', 'warning', 'info', 'ongoing', ]] class Notification(Element, component='notification.js'): def __init__(self, message: Any = '', *, position: NotificationPosition = 'bottom', close_button: Union[bool, str] = False, type: NotificationType = None, # pylint: disable=redefined-builtin color: Optional[str] = None, multi_line: bool = False, icon: Optional[str] = None, spinner: bool = False, timeout: Optional[float] = 5.0, on_dismiss: Optional[Handler[UiEventArguments]] = None, options: Optional[dict] = None, **kwargs: Any, ) -> None: """Notification element Displays a notification on the screen. In contrast to `ui.notify`, this element allows to update the notification message and other properties once the notification is displayed. The notification can be removed with `dismiss()`. :param message: content of the notification :param position: position on the screen ("top-left", "top-right", "bottom-left", "bottom-right", "top", "bottom", "left", "right" or "center", default: "bottom") :param close_button: optional label of a button to dismiss the notification (default: `False`) :param type: optional type ("positive", "negative", "warning", "info" or "ongoing") :param color: optional color name :param multi_line: enable multi-line notifications :param icon: optional name of an icon to be displayed in the notification (default: `None`) :param spinner: display a spinner in the notification (default: False) :param timeout: optional timeout in seconds after which the notification is dismissed (default: 5.0) :param on_dismiss: optional callback to be invoked when the notification is dismissed :param options: optional dictionary with all options (overrides all other arguments) Note: You can pass additional keyword arguments according to `Quasar's Notify API `_. """ with context.client.layout: super().__init__() self._update_method = 'update_notification' if options: self._props['options'] = options else: self._props['options'] = { 'message': str(message), 'position': position, 'multiLine': multi_line, 'spinner': spinner, 'closeBtn': close_button, 'timeout': (timeout or 0) * 1000, 'group': False, } if type is not None: self._props['options']['type'] = type if color is not None: self._props['options']['color'] = color if icon is not None: self._props['options']['icon'] = icon self._props['options'].update(kwargs) if on_dismiss: self.on_dismiss(on_dismiss) async def handle_dismiss() -> None: if not self._deleted: self.clear() self.delete() self.on('dismiss', handle_dismiss) @property def message(self) -> str: """Message text.""" return self._props['options']['message'] @message.setter def message(self, value: Any) -> None: self._props['options']['message'] = str(value) @property def position(self) -> NotificationPosition: """Position on the screen.""" return self._props['options']['position'] @position.setter def position(self, value: NotificationPosition) -> None: self._props['options']['position'] = value @property def type(self) -> NotificationType: """Type of the notification.""" return self._props['options'].get('type') @type.setter def type(self, value: NotificationType) -> None: if value is None: self._props['options'].pop('type', None) else: self._props['options']['type'] = value @property def color(self) -> Optional[str]: """Color of the notification.""" return self._props['options'].get('color') @color.setter def color(self, value: Optional[str]) -> None: if value is None: self._props['options'].pop('color', None) else: self._props['options']['color'] = value @property def multi_line(self) -> bool: """Whether the notification is multi-line.""" return self._props['options']['multiLine'] @multi_line.setter def multi_line(self, value: bool) -> None: self._props['options']['multiLine'] = value @property def icon(self) -> Optional[str]: """Icon of the notification.""" return self._props['options'].get('icon') @icon.setter def icon(self, value: Optional[str]) -> None: if value is None: self._props['options'].pop('icon', None) else: self._props['options']['icon'] = value @property def spinner(self) -> bool: """Whether the notification is a spinner.""" return self._props['options']['spinner'] @spinner.setter def spinner(self, value: bool) -> None: self._props['options']['spinner'] = value @property def timeout(self) -> float: """Timeout of the notification in seconds. *Added in version 2.13.0* """ return self._props['options']['timeout'] / 1000 @timeout.setter def timeout(self, value: Optional[float]) -> None: self._props['options']['timeout'] = (value or 0) * 1000 @property def close_button(self) -> Union[bool, str]: """Whether the notification has a close button.""" return self._props['options']['closeBtn'] @close_button.setter def close_button(self, value: Union[bool, str]) -> None: self._props['options']['closeBtn'] = value def on_dismiss(self, callback: Handler[UiEventArguments]) -> Self: """Add a callback to be invoked when the notification is dismissed.""" self.on('dismiss', lambda _: handle_event(callback, UiEventArguments(sender=self, client=self.client)), []) return self def dismiss(self) -> None: """Dismiss the notification.""" self.run_method('dismiss') def set_visibility(self, visible: bool) -> None: raise NotImplementedError('Use `dismiss()` to remove the notification. See #3670 for more information.')