-
-
Notifications
You must be signed in to change notification settings - Fork 484
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Alert pane: Allows providing contextual feedback messages for typical…
… user actions (#1181)
- Loading branch information
1 parent
ef17e4d
commit 626ac27
Showing
5 changed files
with
369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import panel as pn\n", | ||
"pn.extension()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Alert Pane\n", | ||
"\n", | ||
"The ``Alert`` pane allows providing **contextual feedback messages** for typical user actions with the handful of available and flexible alert messages.\n", | ||
"\n", | ||
"It's heavily inspired by the [Bootstrap Alert](https://getbootstrap.com/docs/4.0/components/alerts/).\n", | ||
"\n", | ||
"#### Parameters:\n", | ||
"\n", | ||
"For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n", | ||
"\n", | ||
"* **``text``** (str): The contextual feedback message.\n", | ||
"* **``alert_type``** (str): The type of Alert and one of `primary`, `secondary`, `success`, `danger`, `warning`, `info`, `light`, `dark`.\n", | ||
"\n", | ||
"___" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"alert_primary=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **primary** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"primary\")\n", | ||
"alert_secondary=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **secondary** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"secondary\")\n", | ||
"alert_success=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **success** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"success\")\n", | ||
"alert_danger=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **danger** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"danger\")\n", | ||
"alert_warning=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **warning** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"warning\")\n", | ||
"alert_info=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **info** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"info\")\n", | ||
"alert_light=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **light** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"light\")\n", | ||
"alert_dark=pn.pane.Alert(text=f\"\"\"\\\n", | ||
" This is a **dark** alert with [an example link](https://panel.holoviz.org/).\n", | ||
" Give it a click if you like.\"\"\", alert_type=\"dark\")\n", | ||
"\n", | ||
"pn.Column(\n", | ||
" alert_primary,\n", | ||
" alert_secondary,\n", | ||
" alert_success,\n", | ||
" alert_danger,\n", | ||
" alert_warning,\n", | ||
" alert_info,\n", | ||
" alert_light,\n", | ||
" alert_dark,\n", | ||
" sizing_mode=\"stretch_width\",\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Additional Content" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"text = \"\"\"\\\n", | ||
"#### Well done!\n", | ||
"\n", | ||
"Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.\n", | ||
"<hr>\n", | ||
"\n", | ||
"Did you notice the use of the divider?\n", | ||
"\"\"\"\n", | ||
"pn.pane.Alert(text=text,alert_type=\"success\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "panel", | ||
"language": "python", | ||
"name": "panel" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.7.4" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
.bk.alert { | ||
padding: 0.75rem 1.25rem; | ||
border: 1px solid transparent; | ||
border-radius: 0.25rem; | ||
/* Don't set margin because that will not render correctly! */ | ||
/* margin-bottom: 1rem; */ | ||
margin-top: 15px; | ||
margin-bottom: 15px; | ||
} | ||
.bk.alert a { | ||
color: rgb(11, 46, 19); /* #002752; */ | ||
font-weight: 700; | ||
text-decoration: rgb(11, 46, 19); | ||
text-decoration-color: rgb(11, 46, 19); | ||
text-decoration-line: none; | ||
text-decoration-style: solid; | ||
text-decoration-thickness: auto; | ||
} | ||
.bk.alert a:hover { | ||
color: rgb(11, 46, 19); | ||
font-weight: 700; | ||
text-decoration: underline; | ||
} | ||
|
||
.bk.alert-primary { | ||
color: #004085; | ||
background-color: #cce5ff; | ||
border-color: #b8daff; | ||
} | ||
.bk.alert-primary hr { | ||
border-top-color: #9fcdff; | ||
} | ||
|
||
.bk.alert-secondary { | ||
color: #383d41; | ||
background-color: #e2e3e5; | ||
border-color: #d6d8db; | ||
} | ||
.bk.alert-secondary hr { | ||
border-top-color: #c8cbcf; | ||
} | ||
|
||
.bk.alert-success { | ||
color: #155724; | ||
background-color: #d4edda; | ||
border-color: #c3e6cb; | ||
} | ||
|
||
.bk.alert-success hr { | ||
border-top-color: #b1dfbb; | ||
} | ||
|
||
.bk.alert-info { | ||
color: #0c5460; | ||
background-color: #d1ecf1; | ||
border-color: #bee5eb; | ||
} | ||
.bk.alert-info hr { | ||
border-top-color: #abdde5; | ||
} | ||
|
||
.bk.alert-warning { | ||
color: #856404; | ||
background-color: #fff3cd; | ||
border-color: #ffeeba; | ||
} | ||
|
||
.bk.alert-warning hr { | ||
border-top-color: #ffe8a1; | ||
} | ||
|
||
.bk.alert-danger { | ||
color: #721c24; | ||
background-color: #f8d7da; | ||
border-color: #f5c6cb; | ||
} | ||
.bk.alert-danger hr { | ||
border-top-color: #f1b0b7; | ||
} | ||
|
||
.bk.alert-light { | ||
color: #818182; | ||
background-color: #fefefe; | ||
border-color: #fdfdfe; | ||
} | ||
.bk.alert-light hr { | ||
border-top-color: #ececf6; | ||
} | ||
|
||
.bk.alert-dark { | ||
color: #1b1e21; | ||
background-color: #d6d8d9; | ||
border-color: #c6c8ca; | ||
} | ||
.bk.alert-dark hr { | ||
border-top-color: #b9bbbe; | ||
} | ||
|
||
|
||
/* adjfæl */ | ||
|
||
.bk.alert-primary a { | ||
color: #002752; | ||
} | ||
|
||
.bk.alert-secondary a { | ||
color: #202326; | ||
} | ||
|
||
|
||
.bk.alert-success a { | ||
color: #0b2e13; | ||
} | ||
|
||
|
||
.bk.alert-info a { | ||
color: #062c33; | ||
} | ||
|
||
|
||
.bk.alert-warning a { | ||
color: #533f03; | ||
} | ||
|
||
|
||
.bk.alert-danger a { | ||
color: #491217; | ||
} | ||
|
||
.bk.alert-light a { | ||
color: #686868; | ||
} | ||
|
||
.bk.alert-dark a { | ||
color: #040505; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""Bootstrap inspired Alerts | ||
See https://getbootstrap.com/docs/4.0/components/alerts/ | ||
""" | ||
import param | ||
|
||
from panel.pane.markup import Markdown | ||
|
||
ALERT_TYPES = ["primary", "secondary", "success", "danger", "warning", "info", "light", "dark"] | ||
|
||
|
||
class Alert(Markdown): | ||
""" | ||
An Alert that renders Markdown | ||
- CSS Styling is done via the classes `alert` and `alert-TYPE`, where TYPE is the alert_type. | ||
- sizing_mode is set to `stretch_width` by default | ||
""" | ||
|
||
alert_type = param.ObjectSelector("primary", objects=ALERT_TYPES) | ||
|
||
def __init__(self, text: str, **kwargs): | ||
"""An Primary Alert that renders Markdown | ||
- CSS Styling is done via the classes `alert` and `alert-primary`. | ||
- sizing_mode is set to `stretch_width` by default | ||
Arguments: | ||
text {str} -- Some MarkDown text | ||
""" | ||
if "margin" not in kwargs: | ||
kwargs["margin"] = (0, 0, 25, 0) | ||
if "sizing_mode" not in kwargs: | ||
kwargs["sizing_mode"] = "stretch_width" | ||
|
||
super().__init__(text, **kwargs) | ||
|
||
self._set_css_classes() | ||
|
||
@param.depends("alert_type", watch=True) | ||
def _set_css_classes(self): | ||
css_classes = [] | ||
if self.css_classes: | ||
for class_ in self.css_classes: | ||
if class_ != "alert" and not class_.startswith("alert-"): | ||
css_classes.append(class_) | ||
|
||
css_classes.append("alert") | ||
css_classes.append(f"alert-{self.alert_type}") | ||
|
||
self.css_classes = css_classes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""In this module we test the functionality of the alerts""" | ||
import pytest | ||
|
||
import panel as pn | ||
from panel.pane import Alert | ||
from panel.pane.alert import ALERT_TYPES | ||
|
||
|
||
def test_constructor(): | ||
"""Test that an Alert can be instantiated""" | ||
alert = Alert(text="This is some text") | ||
# pylint: disable=no-member | ||
assert set(alert.css_classes) == {"alert", f"alert-{Alert.param.alert_type.default}"} | ||
# pylint: enable=no-member | ||
|
||
|
||
@pytest.mark.parametrize(["alert_type"], [(alert_type,) for alert_type in ALERT_TYPES]) | ||
def test_alert_type_change(alert_type): | ||
"""Test that an alert can change alert_type""" | ||
alert = Alert(text="This is some text") | ||
|
||
alert.alert_type = alert_type | ||
assert set(alert.css_classes) == {"alert", f"alert-{alert_type}"} | ||
|
||
def test_existing_css_classes(): | ||
"""Test that an alert can change alert_type""" | ||
alert = Alert(text="This is some text", css_classes=["important"]) | ||
assert set(alert.css_classes) == {"alert", f"alert-{Alert.param.alert_type.default}", "important"} | ||
|
||
alert.alert_type="info" | ||
assert set(alert.css_classes) == {"alert", f"alert-info", "important"} | ||
|
||
|
||
def test_all_view(): | ||
"""Test that we can construct and view all Alerts""" | ||
alerts = [] | ||
for alert_type in ALERT_TYPES: | ||
text = f"""\ | ||
This is a **{alert_type}** alert with [an example link](https://panel.holoviz.org/). | ||
Give it a click if you like.""" | ||
alert = Alert(text=text, alert_type=alert_type) | ||
alerts.append(alert) | ||
|
||
assert "alert" in alert.css_classes | ||
assert f"alert-{alert_type}" in alert.css_classes | ||
|
||
return pn.Column(*alerts, sizing_mode="stretch_width") | ||
|
||
|
||
if __name__.startswith("bk"): | ||
test_all_view().servable() |