Toast - A pop up notification

I was thinking that Panel needs a Toast (pop up notification) component. So here is a first prototype is should already be quite useable for a variety of use cases. Its based on Notyf

toast

Implementation

Implemented using Panels ReactiveHTML

import panel as pn
import param
from panel.reactive import ReactiveHTML

class Notyf(ReactiveHTML):
    _template = """<div id="toast"></div>"""

    duration = param.Integer(2000, bounds=(0,15000))
    ripple = param.Boolean(True)
    position_x = param.Selector(default="right", objects=["left", "right"])
    position_y = param.Selector(default="bottom", objects=["bottom", "top"])
    dismissible = param.Boolean(False)
    types = param.List([])

    _dismiss_all = param.Integer()

    _error = param.String("")
    _success = param.String("")

    def error(self, message):
      self._error = message

    def success(self, message):
      self._success = message

    def dismiss_all(self):
      self._dismiss_all += 1

    def __init__(self, **params):
      if not params:
        params={}
      params["height"]=params["width"]=params["margin"]=0
      params["sizing_mode"]="fixed"
      super().__init__(**params)

    __css__ = ["https://cdn.jsdelivr.net/npm/notyf@3/notyf.min.css"]
    __javascript__ = ["https://cdn.jsdelivr.net/npm/notyf@3/notyf.min.js"]

    _scripts = {
      "render": """
function newNotyf(data) {
  var config = {
    duration: data.duration,
    ripple: data.ripple,
    position: {x: data.position_x, y: data.position_y},
    dismissible: data.dismissible,
    types: data.types
  }
  window.panelNotyf = new Notyf( config )
}
state.newNotyf=newNotyf
state.newNotyf(data)
""",
      "_error": """if ( data._error !==""){window.panelNotyf.error( data._error );data._error="";}""",
      "_success": """if ( data._success !==""){window.panelNotyf.success( data._success );data._success="";}""",
      "_dismiss_all": """window.panelNotyf.dismissAll();""",
      "duration": """state.newNotyf(data)""",
      "ripple": """state.newNotyf(data)""",
      "position_x": """state.newNotyf(data)""",
      "position_y": """state.newNotyf(data)""",
      "dismissible": """state.newNotyf(data)""",
      "types": """state.newNotyf(data)""",
    }

Use

pn.extension(sizing_mode="stretch_width")

ACCENT_COLOR = "#db7093"
# ACCENT_COLOR = "#1e90ff"

notyf = Notyf(types=[{"type": "error", "background": "red"}, {"type": "success", "background": ACCENT_COLOR}])

success_button = pn.widgets.Button(name="Success", button_type="primary")
@pn.depends(clicks=success_button.param.clicks, watch=True)
def _update_success(clicks):
  notyf.success( str(clicks) + " success clicks" )

error_button = pn.widgets.Button(name="Error", button_type="primary")
@pn.depends(clicks=error_button.param.clicks, watch=True)
def _update_error(clicks):
  notyf.error( str(clicks) + " error clicks" )

dismiss_all_button = pn.widgets.Button(name="Dismiss All", button_type="success")
@pn.depends(clicks=dismiss_all_button.param.clicks, watch=True)
def _update_dismiss_all(clicks):
  notyf.dismiss_all()

pn.template.FastListTemplate(
  site="Awesome Panel",
  title="Toast",
  main=[
    pn.Row(notyf, success_button, error_button, dismiss_all_button),
    pn.Param(notyf.param, parameters=["duration", "ripple", "position_x", "position_y", "dismissible", "types"])
  ],
  header_background=ACCENT_COLOR,
  accent_base_color=ACCENT_COLOR,
).servable()

Serve it using panel serve name_of_script.py (or .ipynb).

7 Likes

I’ve added a Feature Request Toast Widget · Issue #2802.

Please add your use cases, requirements and other comments.