Skip to content

Commit 9090b44

Browse files
Merge pull request #2591 from martinRenou/badges
TagsInput widget
2 parents bb1c473 + 250d471 commit 9090b44

File tree

11 files changed

+1388
-2
lines changed

11 files changed

+1388
-2
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# TagsInput widget"
8+
]
9+
},
10+
{
11+
"cell_type": "code",
12+
"execution_count": null,
13+
"metadata": {},
14+
"outputs": [],
15+
"source": [
16+
"from ipywidgets import TagsInput\n",
17+
"\n",
18+
"tags = TagsInput(value=['pizza', 'burger', 'fries', 'nuggets', 'potatoes', 'tomatoes'])\n",
19+
"tags.tag_style = 'primary'\n",
20+
"\n",
21+
"tags"
22+
]
23+
},
24+
{
25+
"cell_type": "code",
26+
"execution_count": null,
27+
"metadata": {},
28+
"outputs": [],
29+
"source": [
30+
"tags.tag_style = 'warning'"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": null,
36+
"metadata": {},
37+
"outputs": [],
38+
"source": [
39+
"tags1 = TagsInput(value=['pizza', 'burger'])\n",
40+
"tags1.tag_style = 'primary'\n",
41+
"tags1.allowed_tags = ['pizza', 'burger', 'fries', 'nuggets', 'potatoes', 'tomatoes', 'ketchup']\n",
42+
"\n",
43+
"tags1"
44+
]
45+
},
46+
{
47+
"cell_type": "markdown",
48+
"metadata": {},
49+
"source": [
50+
"# ColorsInput widget"
51+
]
52+
},
53+
{
54+
"cell_type": "code",
55+
"execution_count": null,
56+
"metadata": {},
57+
"outputs": [],
58+
"source": [
59+
"from ipywidgets import ColorsInput"
60+
]
61+
},
62+
{
63+
"cell_type": "code",
64+
"execution_count": null,
65+
"metadata": {},
66+
"outputs": [],
67+
"source": [
68+
"colortags = ColorsInput(value=['red', 'green', 'rgb(200, 50, 200)', '#32a852'])\n",
69+
"colortags"
70+
]
71+
},
72+
{
73+
"cell_type": "code",
74+
"execution_count": null,
75+
"metadata": {},
76+
"outputs": [],
77+
"source": [
78+
"colortags"
79+
]
80+
},
81+
{
82+
"cell_type": "code",
83+
"execution_count": null,
84+
"metadata": {},
85+
"outputs": [],
86+
"source": [
87+
"colortags1 = ColorsInput(value=['red', 'green'])\n",
88+
"colortags1.allowed_tags = ['red', 'green', 'blue', 'yellow', 'purple']\n",
89+
"\n",
90+
"colortags1"
91+
]
92+
},
93+
{
94+
"cell_type": "markdown",
95+
"metadata": {},
96+
"source": [
97+
"# NumbersInput widget"
98+
]
99+
},
100+
{
101+
"cell_type": "code",
102+
"execution_count": null,
103+
"metadata": {},
104+
"outputs": [],
105+
"source": [
106+
"from ipywidgets import FloatsInput, IntsInput"
107+
]
108+
},
109+
{
110+
"cell_type": "code",
111+
"execution_count": null,
112+
"metadata": {},
113+
"outputs": [],
114+
"source": [
115+
"floatsinput = FloatsInput(value=[1.3, 4.56, 78.90])\n",
116+
"floatsinput.tag_style = 'info'\n",
117+
"\n",
118+
"floatsinput"
119+
]
120+
},
121+
{
122+
"cell_type": "code",
123+
"execution_count": null,
124+
"metadata": {},
125+
"outputs": [],
126+
"source": [
127+
"floatsinput.format = '.2f'"
128+
]
129+
},
130+
{
131+
"cell_type": "code",
132+
"execution_count": null,
133+
"metadata": {},
134+
"outputs": [],
135+
"source": [
136+
"intsinput = IntsInput(value=[1, 4, 22], min=0, max=23)\n",
137+
"intsinput.tag_style = 'danger'\n",
138+
"\n",
139+
"intsinput"
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": null,
145+
"metadata": {},
146+
"outputs": [],
147+
"source": [
148+
"intsinput.format = '.2e'"
149+
]
150+
}
151+
],
152+
"metadata": {
153+
"kernelspec": {
154+
"display_name": "Python 3",
155+
"language": "python",
156+
"name": "python3"
157+
},
158+
"language_info": {
159+
"codemirror_mode": {
160+
"name": "ipython",
161+
"version": 3
162+
},
163+
"file_extension": ".py",
164+
"mimetype": "text/x-python",
165+
"name": "python",
166+
"nbconvert_exporter": "python",
167+
"pygments_lexer": "ipython3",
168+
"version": "3.8.1"
169+
}
170+
},
171+
"nbformat": 4,
172+
"nbformat_minor": 4
173+
}

ipywidgets/widgets/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from .widget_link import jslink, jsdlink
2525
from .widget_layout import Layout
2626
from .widget_media import Image, Video, Audio
27+
from .widget_tagsinput import TagsInput, ColorsInput, FloatsInput, IntsInput
2728
from .widget_style import Style
2829
from .widget_templates import TwoByTwoLayout, AppLayout, GridspecLayout
2930
from .widget_upload import FileUpload
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Copyright(c) Jupyter Development Team.
2+
# Distributed under the terms of the Modified BSD License.
3+
4+
"""TagsInput class.
5+
6+
Represents a list of tags.
7+
"""
8+
9+
from traitlets import (
10+
CaselessStrEnum, CInt, CFloat, Bool, Unicode, List, TraitError, validate
11+
)
12+
13+
from .widget_description import DescriptionWidget
14+
from .valuewidget import ValueWidget
15+
from .widget_core import CoreWidget
16+
from .widget import register
17+
from .trait_types import Color, NumberFormat
18+
19+
20+
class TagsInputBase(DescriptionWidget, ValueWidget, CoreWidget):
21+
_model_name = Unicode('TagsInputBaseModel').tag(sync=True)
22+
value = List().tag(sync=True)
23+
allowed_tags = List().tag(sync=True)
24+
allow_duplicates = Bool(True).tag(sync=True)
25+
26+
@validate('value')
27+
def _validate_value(self, proposal):
28+
if ('' in proposal['value']):
29+
raise TraitError('The value of a TagsInput widget cannot contain blank strings')
30+
31+
if len(self.allowed_tags) == 0:
32+
return proposal['value']
33+
34+
for tag_value in proposal['value']:
35+
if tag_value not in self.allowed_tags:
36+
raise TraitError('Tag value {} is not allowed, allowed tags are {}'.format(tag_value, self.allowed_tags))
37+
38+
return proposal['value']
39+
40+
41+
@register
42+
class TagsInput(TagsInputBase):
43+
"""
44+
List of string tags
45+
"""
46+
_model_name = Unicode('TagsInputModel').tag(sync=True)
47+
_view_name = Unicode('TagsInputView').tag(sync=True)
48+
49+
value = List(Unicode(), help='List of string tags').tag(sync=True)
50+
tag_style = CaselessStrEnum(
51+
values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='',
52+
help="""Use a predefined styling for the tags.""").tag(sync=True)
53+
54+
55+
@register
56+
class ColorsInput(TagsInputBase):
57+
"""
58+
List of color tags
59+
"""
60+
_model_name = Unicode('ColorsInputModel').tag(sync=True)
61+
_view_name = Unicode('ColorsInputView').tag(sync=True)
62+
63+
value = List(Color(), help='List of string tags').tag(sync=True)
64+
65+
66+
class NumbersInputBase(TagsInput):
67+
_model_name = Unicode('NumbersInputBaseModel').tag(sync=True)
68+
min = CFloat(default_value=None, allow_none=True).tag(sync=True)
69+
max = CFloat(default_value=None, allow_none=True).tag(sync=True)
70+
71+
@validate('value')
72+
def _validate_numbers(self, proposal):
73+
for tag_value in proposal['value']:
74+
if self.min is not None and tag_value < self.min:
75+
raise TraitError('Tag value {} should be >= {}'.format(tag_value, self.min))
76+
if self.max is not None and tag_value > self.max:
77+
raise TraitError('Tag value {} should be <= {}'.format(tag_value, self.max))
78+
79+
return proposal['value']
80+
81+
82+
@register
83+
class FloatsInput(NumbersInputBase):
84+
"""
85+
List of float tags
86+
"""
87+
_model_name = Unicode('FloatsInputModel').tag(sync=True)
88+
_view_name = Unicode('FloatsInputView').tag(sync=True)
89+
90+
value = List(CFloat(), help='List of float tags').tag(sync=True)
91+
format = NumberFormat('.1f').tag(sync=True)
92+
93+
94+
@register
95+
class IntsInput(NumbersInputBase):
96+
"""
97+
List of int tags
98+
"""
99+
_model_name = Unicode('IntsInputModel').tag(sync=True)
100+
_view_name = Unicode('IntsInputView').tag(sync=True)
101+
102+
value = List(CInt(), help='List of int tags').tag(sync=True)
103+
format = NumberFormat('.3g').tag(sync=True)
104+
min = CInt(default_value=None, allow_none=True).tag(sync=True)
105+
max = CInt(default_value=None, allow_none=True).tag(sync=True)

0 commit comments

Comments
 (0)