Skip to content

Instantly share code, notes, and snippets.

@oscar6echo
Last active June 21, 2018 14:03
Show Gist options
  • Save oscar6echo/a3244d028968f37898d0231207042730 to your computer and use it in GitHub Desktop.
Save oscar6echo/a3244d028968f37898d0231207042730 to your computer and use it in GitHub Desktop.
ipywidget_unfortunate_tooltip_in_description
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problem: Unwanted tooltip over Label\n",
"\n",
"### Demo\n",
"\n",
"+ Run the 3 cells below\n",
"+ Hover over the text 'My Label' and see the unwanted HTML/CSS\n",
"\n",
"### Explanation\n",
"\n",
"The ipywidgets Label, which is part of Many other core ipywidgets like XSliders, XText, DropDown, etc passes is the 'culprit'. \n",
"It passes the description string as HTML label properties `innerHTML` and `title`. The latter is responsible for the tooltip. \n",
"I would argue that passing the argument to `title` is superfluous at best, and a hindrance when the description contains HTML/CSS that you do not want to show to users - as in the example below.\n",
"\n",
"See source code: https://github.com/jupyter-widgets/ipywidgets/blob/2c8c82b0916707d73796a159a6c59f92cea38613/packages/controls/src/widget_description.ts#L75\n",
"\n",
"### Suggested Remedy\n",
"\n",
"1. **Minimum**: Remove the line above\n",
"1. **Better**: Add new input `tooltip` to widget `Label`. `tooltip` maps to label HTML property `title`. \n",
"If not specified, defaults to `description` i.e. current case.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import re\n",
"import numpy as np\n",
"import ipywidgets as wg"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def replace(dic, text):\n",
" # Create a regex from the dict keys\n",
" regex = re.compile('(%s)' % '|'.join(map(re.escape, dic.keys())))\n",
"\n",
" # For each match, lookup corresponding value in dict\n",
" return regex.sub(lambda mo: dic[mo.string[mo.start():mo.end()]], text)\n",
"\n",
"\n",
"def dot(color, diameter=10):\n",
" uuid = str(np.random.randint(int(1e6)))\n",
" css = \"\"\"\n",
" .dot-__uuid__ {\n",
" height: __diameter__px;\n",
" width: __diameter__px;\n",
" background-color: __color__;\n",
" border-radius: 50%;\n",
" display: inline-block;\n",
" }\"\"\"\n",
" dic = {'__uuid__': uuid,\n",
" '__color__': color,\n",
" '__diameter__': str(diameter)}\n",
" css = replace(dic, css)\n",
" dot = '<style>{}</style><span class=\"dot-{}\"></span>'.format(css, uuid)\n",
" sp = '&nbsp'\n",
" return dot + 2 * sp\n",
"\n",
" \n",
"def dropdown(description='My Label', li_opt=['abd', 'def'], index=0, width='300px', description_width='100px', color='red'):\n",
" description = dot('red') + description + ':'\n",
" layout = wg.Layout(\n",
" width=str(width)+'px'\n",
" )\n",
" style = {'description_width': str(description_width)+'px'}\n",
" w = wg.Dropdown(\n",
" options=li_opt,\n",
" value=li_opt[index],\n",
" description=description,\n",
" layout=layout,\n",
" style=style\n",
" )\n",
" return w"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d3981d803aee4b23a97d82a778b7b672",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Dropdown(description='<style>\\n .dot-955017 {\\n height: 10px;\\n width: 10px;\\n backgro…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"dropdown()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.6.3"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {
"6e92790f418541358b0a1d91400930cb": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "1.0.0",
"model_name": "LayoutModel",
"state": {
"width": "300pxpx"
}
},
"8bfd25ea0bcc49bab1ed2fc3dff9854e": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "1.2.0",
"model_name": "DescriptionStyleModel",
"state": {
"description_width": "100pxpx"
}
},
"bf0299c91df3406fbc5470027bdffab1": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "1.2.0",
"model_name": "DescriptionStyleModel",
"state": {
"description_width": "100pxpx"
}
},
"d3981d803aee4b23a97d82a778b7b672": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "1.2.0",
"model_name": "DropdownModel",
"state": {
"_options_labels": [
"abd",
"def"
],
"description": "<style>\n .dot-955017 {\n height: 10px;\n width: 10px;\n background-color: red;\n border-radius: 50%;\n display: inline-block;\n }</style><span class=\"dot-955017\"></span>&nbsp&nbspMy Label:",
"index": 0,
"layout": "IPY_MODEL_eb35fe554b9c4afbbcf7389782bd29e7",
"style": "IPY_MODEL_bf0299c91df3406fbc5470027bdffab1"
}
},
"e3cc7c3ed9cf4543bafde027624babcc": {
"model_module": "@jupyter-widgets/controls",
"model_module_version": "1.2.0",
"model_name": "DropdownModel",
"state": {
"_options_labels": [
"abd",
"def"
],
"description": "<style>\n .dot-447086 {\n height: 10px;\n width: 10px;\n background-color: red;\n border-radius: 50%;\n display: inline-block;\n }</style><span class=\"dot-447086\"></span>&nbsp&nbspMy Label:",
"index": 0,
"layout": "IPY_MODEL_6e92790f418541358b0a1d91400930cb",
"style": "IPY_MODEL_8bfd25ea0bcc49bab1ed2fc3dff9854e"
}
},
"eb35fe554b9c4afbbcf7389782bd29e7": {
"model_module": "@jupyter-widgets/base",
"model_module_version": "1.0.0",
"model_name": "LayoutModel",
"state": {
"width": "300pxpx"
}
}
},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment