8.0.0
What's Changed
See the 8.0.0 changelog for a more comprehensive summary of changes. To see the full list of pull requests and issues, see the 8.0 milestone on GitHub, or the full list of changes since 7.x.
Users
Here are some highlights of user-visible changes in ipywidgets 8.0.
Date and time pickers
In addition to the existing DatePicker widget, we now have new DatetimePicker and TimePicker widgets. (#2715)
from ipywidgets import VBox, TimePicker, DatetimePicker
VBox([
TimePicker(description='Time'),
DatetimePicker(description='Date/Time')
])
Tags input widget
The new TagsInput widget provides an easy way to collect and manage tags in a widget. You can drag and drop tags to reorder them, limit them to a set of allowed values, or even prevent making duplicate tags. (#2591, #3272)
from ipywidgets import TagsInput
TagsInput(
value=['pizza', 'fries'],
allowed_tags=['pizza', 'fries', 'tomatoes', 'steak'],
allow_duplicates=False
)
Similarly, the new ColorsInput widget provides a way to select colors as tags
from ipywidgets import ColorsInput
ColorsInput(
value=['red', '#2f6d30'],
# allowed_tags=['red', 'blue', 'green'],
# allow_duplicates=False
)
Stack widget
The new Stack container widget shows only the selected child widget, while other child widgets remain hidden. This can be useful if you want to have a area that displays different widgets depending on some other interaction.
from ipywidgets import Stack, Button, IntSlider, Dropdown, VBox, link
s = Stack([Button(description='Click here'), IntSlider()], selected_index=0)
d = Dropdown(options=['button', 'slider'])
link((dropdown, 'index'), (stacked, 'selected_index'))
VBox([d, s])
File upload widget
The file upload widget has been overhauled to handle multiple files in a more useful format:
- The
.value
attribute is now a list of dictionaries, rather than a dictionary mapping the uploaded name to the content. - The contents of each uploaded file is a memory view in the
.content
key, e.g.,uploader.value[0].content
. - The
.data
attribute has been removed. - The
.metadata
attribute has been removed.
See the user migration guide for details on how to migrate your code.
More styling options
Many style and layout options have been added to core widgets:
- Tooltips are now supported for many core widgets, rather than just a few description tooltips (#2680)
from ipywidgets import Button Button(description="Click me", tooltip='An action')
- Borders can be styled independently with the layout's
border_top
,border_right
,border_bottom
,border_left
attributes (#2757, #3269)from ipywidgets import Button Button(description="Click me", layout={'border_bottom': '3px solid blue'})
- Descriptions are now plain text by default for security, but you can set them to allow HTML with the
description_allow_html
attribute (HTML content is still sanitized for security). (#2785)from ipywidgets import Text Text(description="<b>Name</b>", description_allow_html=True)
- Many other styling attributes can be set on core widgets, such as font family, size, style, weight, text color, and text decoration. See the table in the documentation for a reference. (#2728)
- The SelectionSlider now has a
handle_color
style attribute (#3142) - To control keyboard navigation, widgets can be set to be tabbable or not (i.e., that the tab key will traverse to the widget) (#2640)
Selection container titles
The Accordion, Tab, and Stack widgets now have a .titles
attribute that you can use to get and set titles from the constructor or as an attribute. (#2746, #3296, #3477)
from ipywidgets import Tab, IntSlider, Text
Tab([IntSlider(), Text()], titles=('Slider', 'Text'))
Slider implementation
The slider implementation in the core widgets now uses nouislider. This enables us to fix long-standing bugs and introduce new features, like dragging the range in a RangeSlider. (#2712, #630, #3216, #2834)
Collaboration
By default, ipywidgets 8 enables a collaboration mode, where widget updates from one frontend are reflected back to other frontends, enabling a consistent state between multiple users and fixing synchronization between the kernel and frontend. You may want to disable these update echo messages if they are using too much bandwidth or causing slower interactivity. To disable echo update messages across ipywidgets, set the environment variable JUPYTER_WIDGETS_ECHO
to 0
. For widget authors, to opt a specific attribute of custom widget out of echo updates (for example, if the attribute contains a lot of data that does not need to be synchronized), tag the attribute with echo_update=False
metadata (we do this in core for the FileUpload widget's data
attribute). (#3195, #3343, #3394, #3407)
CDN for html manager
We have made it easier to load widgets from content delivery networks.
- The default CDN is changed from unpkg to jsDelivr (#3121, #1627)
- You can use the
data-jupyter-widgets-cdn-only
attribute to load modules only from CDN (#2792, #2786) - We have updated the webpack public path settings so the HTMLManager and the Jupyter Notebook extensions pull assets from wherever they are loaded, rather than only from CDN. If you author a custom widget, we highly encourage you to apply similar changes to your widget by adapting the changes at https://github.com/jupyter-widgets/widget-cookiecutter/pull/103/files. #3464, #3508
Other changes
Here is a short list of some of the other changes in ipywidgets 8.0.
- Add a cookiecutter-based tutorial to build a custom widget (#2919)
- Change media widgets to use memory views. (#2723)
- Upgrade to FontAwesome 5 in html-manager (#2713)
- Play widget now toggles between play and pause button as needed (#2703, #2671)
- Drop support for mapping types as selection options (#2679, #1958)
- Focus or blur a widget. (#2664, #2692, #2691, #2690)
- Drop notebook dependency from widgetsnbextension (#2590)
- Cast 'value' in range sliders to a tuple (#2441)
- Play widget: expose playing and repeat (#2283, #1897)
- Fix debouncing and throttling code (#3060)
- Fix regression on spinning icons (#2685, #2477)
- Fix selection container default index (#1823)
- Remove deprecated overflow properties (#2688)
- Select: Do not force a selection if there is currently no selection and the options list changes (#3284)
- Add support for localization to the lab extension (#3286)
- Drop support for Python 2.7, 3.4, and 3.5 (#2558, #2655, #3131, #3120)
- Fix character escapes in combobox options (#2972)
- Modify outputs to use a comm if IPython is not available (#2954)
- Bugfix/parameters in the from_file method to be passed along in the media class (#3074)
- Widgetsnbextension: throw error on failure to render (#3280)
- Fix memory leak from Image widget not releasing object urls (#3171, #3170)
- ErrorWidget as fallback when widgets models or views fail - Following up (#3304)
- Fix matplotlib plots in interact (#3277)
- Fix selection equality checking (#2897)
- Remove the
on_displayed
Python callback mechanism (#2021)
Developers
To see an overview of the changes to the core widget model specification, see #3455.
Python
Widget.widgets
andWidget.widget_types
are now private variables (#3122, #3173)- Generate the widget data spec as JSON (#2193)
- Use
_repr_mimebundle_
and require ipython 6.1 or later. (#2021, #1811) - Hold sync during
set_state
+ fix selection widgets flakiness (#3271) - Remove deprecated
handle_kernel
alias (#2694) - Removed deprecated signature of the
register
decorator (#2695)
Javascript
- Fix CSS variable names to match JupyterLab names (#2801, #2062)
- Delete
display_model
anddisplay_view
(#2752, #2751) - Drop underscore usage (#2742)
- Upgrade to es2017 javascript (#2725)
- Split base manager into separate packages (#2710, #2561)
- Change Phosphor to Lumino (#2681, #3267)
- Widgetmanagerbase: improve create_view return type (#2662)
- Refactor the JupyterLab widget manager so it can be reused (#2532)
- Make more of lab manager dependencies optional (#2528)
- Remove class
jupyter-widgets
fromjp-outputarea-output
node (#2500) - Rename
pWidget
toluminoWidget
and deprecatepWidget
(#3118, #3141, #3358,) - Add
layout
,style
, andshown
events (#3300) - Implement
jupyter.widget.control
comm channel (#3313) - Update to TypeScript 4.3 (#3162)
- Add event listener for resize events (#3124)
- Remove
process.cwd
polyfill (#3315) - Make sure buffer is a DataView (#3127)
- Deprecate the overly broad CSS class
widget
and introduce a similarjupyter-widget
CSS class (#3146) - Fetch the full widget state via a control Comm (#3021)
- Export LabWidgetManager and KernelWidgetManager (#3166)
- More helpful semver range message (#3185)
- Make the base widget manager
.get_model()
method always return a Promise, which is rejected if the requested model is not registered. To test if a model is registered, use the new.has_model()
method (#3389)
New Contributors
- @hugovk made their first contribution in #2558
- @rramphal made their first contribution in #2616
- @davidbrochart made their first contribution in #2566
- @astrofrog made their first contribution in #2376
- @jhonsen made their first contribution in #2267
- @bermani made their first contribution in #2544
- @reggied made their first contribution in #2193
- @adam-ah made their first contribution in #2735
- @qzchenwl made their first contribution in #2500
- @alex4200 made their first contribution in #2780
- @ibdafna made their first contribution in #2712
- @Bobgy made their first contribution in #2792
- @umerhasan17 made their first contribution in #2824
- @hickmanw made their first contribution in #2775
- @dependabot made their first contribution in #2857
- @wangsijie made their first contribution in #2851
- @carlobeltrame made their first contribution in #3040
- @MicaelJarniac made their first contribution in #3062
- @marimeireles made their first contribution in #3117
- @casperdcl made their first contribution in #3130
- @kedarisetti made their first contribution in #3074
- @joseph2rs made their first contribution in #3171
- @bsyouness made their first contribution in #3185
- @StefanBrand made their first contribution in #3225
- @smeng9 made their first contribution in #3223
- @joequant made their first contribution in #2954
- @rsheftel made their first contribution in #2927
- @partev made their first contribution in #3242
- @kefirbandi made their first contribution in #2897
- @giswqs made their first contribution in #3246
- @jpn-- made their first contribution in #3142
- @shaperilio made their first contribution in #3277
- @alex-rind made their first contribution in #3317
- @trungleduc made their first contribution in #3304
- @real-slim-chadi made their first contribution in #3326
- @mariobuikhuizen made their first contribution in #3358
- @MrBago made their first contribution in #3370
- @agnat made their first contribution in #3338
- @xiaochen-db made their first contribution in #3367
- @agoose77 made their first contribution in #2975
- @tkrabel made their first contribution in #3393
- @anthonyaag made their first contribution in #3450
- @williamstein made their first contribution in #3462
- @VedangNadkarni made their first contribution in #3456
- @kellietay made their first contribution in #3475
- @jasongrout-db made their first contribution in #3442
Full Changelog: 7.x...8.0.0