Skip to content

Commit

Permalink
Merge pull request #2591 from martinRenou/badges
Browse files Browse the repository at this point in the history
TagsInput widget
  • Loading branch information
SylvainCorlay committed May 12, 2020
2 parents bb1c473 + 250d471 commit 9090b44
Show file tree
Hide file tree
Showing 11 changed files with 1,388 additions and 2 deletions.
173 changes: 173 additions & 0 deletions docs/source/examples/Widget TagsInput.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TagsInput widget"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ipywidgets import TagsInput\n",
"\n",
"tags = TagsInput(value=['pizza', 'burger', 'fries', 'nuggets', 'potatoes', 'tomatoes'])\n",
"tags.tag_style = 'primary'\n",
"\n",
"tags"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tags.tag_style = 'warning'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tags1 = TagsInput(value=['pizza', 'burger'])\n",
"tags1.tag_style = 'primary'\n",
"tags1.allowed_tags = ['pizza', 'burger', 'fries', 'nuggets', 'potatoes', 'tomatoes', 'ketchup']\n",
"\n",
"tags1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ColorsInput widget"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ipywidgets import ColorsInput"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"colortags = ColorsInput(value=['red', 'green', 'rgb(200, 50, 200)', '#32a852'])\n",
"colortags"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"colortags"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"colortags1 = ColorsInput(value=['red', 'green'])\n",
"colortags1.allowed_tags = ['red', 'green', 'blue', 'yellow', 'purple']\n",
"\n",
"colortags1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# NumbersInput widget"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ipywidgets import FloatsInput, IntsInput"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"floatsinput = FloatsInput(value=[1.3, 4.56, 78.90])\n",
"floatsinput.tag_style = 'info'\n",
"\n",
"floatsinput"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"floatsinput.format = '.2f'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"intsinput = IntsInput(value=[1, 4, 22], min=0, max=23)\n",
"intsinput.tag_style = 'danger'\n",
"\n",
"intsinput"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"intsinput.format = '.2e'"
]
}
],
"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.8.1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
1 change: 1 addition & 0 deletions ipywidgets/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .widget_link import jslink, jsdlink
from .widget_layout import Layout
from .widget_media import Image, Video, Audio
from .widget_tagsinput import TagsInput, ColorsInput, FloatsInput, IntsInput
from .widget_style import Style
from .widget_templates import TwoByTwoLayout, AppLayout, GridspecLayout
from .widget_upload import FileUpload
105 changes: 105 additions & 0 deletions ipywidgets/widgets/widget_tagsinput.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Copyright(c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""TagsInput class.
Represents a list of tags.
"""

from traitlets import (
CaselessStrEnum, CInt, CFloat, Bool, Unicode, List, TraitError, validate
)

from .widget_description import DescriptionWidget
from .valuewidget import ValueWidget
from .widget_core import CoreWidget
from .widget import register
from .trait_types import Color, NumberFormat


class TagsInputBase(DescriptionWidget, ValueWidget, CoreWidget):
_model_name = Unicode('TagsInputBaseModel').tag(sync=True)
value = List().tag(sync=True)
allowed_tags = List().tag(sync=True)
allow_duplicates = Bool(True).tag(sync=True)

@validate('value')
def _validate_value(self, proposal):
if ('' in proposal['value']):
raise TraitError('The value of a TagsInput widget cannot contain blank strings')

if len(self.allowed_tags) == 0:
return proposal['value']

for tag_value in proposal['value']:
if tag_value not in self.allowed_tags:
raise TraitError('Tag value {} is not allowed, allowed tags are {}'.format(tag_value, self.allowed_tags))

return proposal['value']


@register
class TagsInput(TagsInputBase):
"""
List of string tags
"""
_model_name = Unicode('TagsInputModel').tag(sync=True)
_view_name = Unicode('TagsInputView').tag(sync=True)

value = List(Unicode(), help='List of string tags').tag(sync=True)
tag_style = CaselessStrEnum(
values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='',
help="""Use a predefined styling for the tags.""").tag(sync=True)


@register
class ColorsInput(TagsInputBase):
"""
List of color tags
"""
_model_name = Unicode('ColorsInputModel').tag(sync=True)
_view_name = Unicode('ColorsInputView').tag(sync=True)

value = List(Color(), help='List of string tags').tag(sync=True)


class NumbersInputBase(TagsInput):
_model_name = Unicode('NumbersInputBaseModel').tag(sync=True)
min = CFloat(default_value=None, allow_none=True).tag(sync=True)
max = CFloat(default_value=None, allow_none=True).tag(sync=True)

@validate('value')
def _validate_numbers(self, proposal):
for tag_value in proposal['value']:
if self.min is not None and tag_value < self.min:
raise TraitError('Tag value {} should be >= {}'.format(tag_value, self.min))
if self.max is not None and tag_value > self.max:
raise TraitError('Tag value {} should be <= {}'.format(tag_value, self.max))

return proposal['value']


@register
class FloatsInput(NumbersInputBase):
"""
List of float tags
"""
_model_name = Unicode('FloatsInputModel').tag(sync=True)
_view_name = Unicode('FloatsInputView').tag(sync=True)

value = List(CFloat(), help='List of float tags').tag(sync=True)
format = NumberFormat('.1f').tag(sync=True)


@register
class IntsInput(NumbersInputBase):
"""
List of int tags
"""
_model_name = Unicode('IntsInputModel').tag(sync=True)
_view_name = Unicode('IntsInputView').tag(sync=True)

value = List(CInt(), help='List of int tags').tag(sync=True)
format = NumberFormat('.3g').tag(sync=True)
min = CInt(default_value=None, allow_none=True).tag(sync=True)
max = CInt(default_value=None, allow_none=True).tag(sync=True)

0 comments on commit 9090b44

Please sign in to comment.