Skip to content

Commit

Permalink
Merge pull request #2680 from zerline/zerline/tooltip2
Browse files Browse the repository at this point in the history
Tooltips everywhere
  • Loading branch information
vidartf authored Jan 8, 2020
2 parents 367bbcc + 29a1dc1 commit b77d2f0
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 81 deletions.
11 changes: 10 additions & 1 deletion ipywidgets/widgets/domwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,20 @@


class DOMWidget(Widget):
"""Widget that can be inserted into the DOM"""
"""Widget that can be inserted into the DOM
Parameters
----------
tooltip: str
tooltip caption
layout: InstanceDict(Layout)
widget layout
"""

_model_name = Unicode('DOMWidgetModel').tag(sync=True)
_dom_classes = TypedTuple(trait=Unicode(), help="CSS classes applied to widget DOM element").tag(sync=True)
tabbable = Bool(help="Is widget tabbable?", allow_none=True, default_value=None).tag(sync=True)
tooltip = Unicode(None, allow_none=True, help="A tooltip caption.").tag(sync=True)
layout = InstanceDict(Layout).tag(sync=True, **widget_serialization)

def add_class(self, className):
Expand Down
5 changes: 1 addition & 4 deletions ipywidgets/widgets/widget_bool.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,13 @@ class ToggleButton(_Bool):
value : {True,False}
value of the toggle button: True-pressed, False-unpressed
description : str
description displayed next to the button
tooltip: str
tooltip caption of the toggle button
description displayed next to the button
icon: str
font-awesome icon name
"""
_view_name = Unicode('ToggleButtonView').tag(sync=True)
_model_name = Unicode('ToggleButtonModel').tag(sync=True)

tooltip = Unicode(help="Tooltip caption of the toggle button.").tag(sync=True)
icon = Unicode('', help= "Font-awesome icon.").tag(sync=True)

button_style = CaselessStrEnum(
Expand Down
3 changes: 0 additions & 3 deletions ipywidgets/widgets/widget_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ class Button(DOMWidget, CoreWidget):
----------
description: str
description displayed next to the button
tooltip: str
tooltip caption of the toggle button
icon: str
font-awesome icon names, without the 'fa-' prefix
disabled: bool
Expand All @@ -47,7 +45,6 @@ class Button(DOMWidget, CoreWidget):
_model_name = Unicode('ButtonModel').tag(sync=True)

description = Unicode(help="Button label.").tag(sync=True)
tooltip = Unicode(help="Tooltip caption of the button.").tag(sync=True)
disabled = Bool(False, help="Enable or disable user changes.").tag(sync=True)
icon = Unicode('', help="Font-awesome icon names, without the 'fa-' prefix.").tag(sync=True)

Expand Down
1 change: 0 additions & 1 deletion ipywidgets/widgets/widget_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class DescriptionWidget(DOMWidget, CoreWidget):
"""Widget that has a description label to the side."""
_model_name = Unicode('DescriptionModel').tag(sync=True)
description = Unicode('', help="Description of the control.").tag(sync=True)
description_tooltip = Unicode(None, allow_none=True, help="Tooltip for the description (defaults to description).").tag(sync=True)
style = InstanceDict(DescriptionStyle, help="Styling customizations").tag(sync=True, **widget_serialization)

def _repr_keys(self):
Expand Down
15 changes: 14 additions & 1 deletion packages/base/src/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,8 @@ class DOMWidgetModel extends WidgetModel {
defaults() {
return utils.assign(super.defaults(), {
_dom_classes: [],
tabbable: null
tabbable: null,
tooltip: null
// We do not declare defaults for the layout and style attributes.
// Those defaults are constructed on the kernel side and synced here
// as needed, and our code here copes with those attributes being
Expand Down Expand Up @@ -835,6 +836,8 @@ class DOMWidgetView extends WidgetView {
this.listenTo(this.model, 'comm_live_update', () => {
this._comm_live_update();
});
this.listenTo(this.model, 'change:tooltip', this.updateTooltip);
this.updateTooltip();
}

setLayout(layout: WidgetModel, oldLayout?: WidgetModel) {
Expand Down Expand Up @@ -885,6 +888,16 @@ class DOMWidgetView extends WidgetView {
}
}

updateTooltip() {
let title = this.model.get('tooltip')
if (!title) {
this.el.removeAttribute('title');
} else if (this.model.get('description').length === 0) {
this.el.setAttribute('title', title);
}
}


/**
* Update the DOM classes applied to an element, default to this.el.
*/
Expand Down
11 changes: 11 additions & 0 deletions packages/controls/src/widget_bool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class CheckboxView extends DescriptionView {
this.updateDescription();
this.updateIndent();
this.updateTabindex();
this.updateTooltip();
}

/**
Expand Down Expand Up @@ -117,6 +118,16 @@ class CheckboxView extends DescriptionView {
}
}

updateTooltip() {
if (!this.checkbox) return; // we might be constructing the parent
let title = this.model.get('tooltip');
if (!title) {
this.checkbox.removeAttribute('title');
} else if (this.model.get('description').length === 0) {
this.checkbox.setAttribute('title', title);
}
}

events(): {[e: string]: string} {
return {
'click input[type="checkbox"]': '_handle_click'
Expand Down
16 changes: 7 additions & 9 deletions packages/controls/src/widget_description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ class DescriptionModel extends DOMWidgetModel {
_model_module: '@jupyter-widgets/controls',
_view_module_version: JUPYTER_CONTROLS_VERSION,
_model_module_version: JUPYTER_CONTROLS_VERSION,
description: '',
description_tooltip: null,
description: ''
};
}
}
Expand All @@ -57,10 +56,10 @@ class DescriptionView extends DOMWidgetView {
this.label.style.display = 'none';

this.listenTo(this.model, 'change:description', this.updateDescription);
this.listenTo(this.model, 'change:description_tooltip', this.updateDescription);
this.listenTo(this.model, 'change:tabbable', this.updateTabindex);
this.updateDescription();
this.updateTabindex();
this.updateTooltip();
}

typeset(element: HTMLElement, text?: string){
Expand All @@ -69,19 +68,18 @@ class DescriptionView extends DOMWidgetView {

updateDescription() {
let description = this.model.get('description');
let description_tooltip = this.model.get('description_tooltip');
if (description_tooltip === null) {
description_tooltip = description;
}

if (description.length === 0) {
this.label.style.display = 'none';
} else {
this.label.innerHTML = description;
this.typeset(this.label);
this.label.style.display = '';
}
this.label.title = description_tooltip;
}

updateTooltip() {
if (!this.label) return;
this.label.title = this.model.get('tooltip');
}

label: HTMLLabelElement;
Expand Down
11 changes: 11 additions & 0 deletions packages/controls/src/widget_selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class SelectionView extends DescriptionView {

// Set tabindex
this.updateTabindex();
this.updateTooltip();
}

updateTabindex() {
Expand All @@ -72,6 +73,16 @@ class SelectionView extends DescriptionView {
}
}

updateTooltip() {
if (!this.listbox) return; // we might be constructing the parent
let title = this.model.get('tooltip');
if (!title) {
this.listbox.removeAttribute('title');
} else if (this.model.get('description').length === 0) {
this.listbox.setAttribute('title', title);
}
}

listbox: HTMLSelectElement;
}

Expand Down
77 changes: 50 additions & 27 deletions packages/controls/src/widget_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ class StringModel extends CoreDescriptionModel {
}
}

export
class StringView extends DescriptionView {
/**
* Called when view is rendered.
*/
render() {
super.render(); // Incl. setting some defaults.
this.el.classList.add('jupyter-widgets');
this.el.classList.add('widget-inline-hbox');
}

/**
* Update the contents of this view
*
* Called when the model is changed. The model may have been
* changed by another view or by a state update from the back-end.
*/

content: HTMLDivElement;
}

export
class HTMLModel extends StringModel {
defaults() {
Expand All @@ -45,14 +66,12 @@ class HTMLModel extends StringModel {
}

export
class HTMLView extends DescriptionView {
class HTMLView extends StringView {
/**
* Called when view is rendered.
*/
render() {
super.render();
this.el.classList.add('jupyter-widgets');
this.el.classList.add('widget-inline-hbox');
this.el.classList.add('widget-html');
this.content = document.createElement('div');
this.content.classList.add('widget-html-content');
Expand Down Expand Up @@ -97,14 +116,12 @@ class HTMLMathModel extends StringModel {
}

export
class HTMLMathView extends DescriptionView {
class HTMLMathView extends StringView {
/**
* Called when view is rendered.
*/
render() {
super.render();
this.el.classList.add('jupyter-widgets');
this.el.classList.add('widget-inline-hbox');
this.el.classList.add('widget-htmlmath');
this.content = document.createElement('div');
this.content.classList.add('widget-htmlmath-content');
Expand Down Expand Up @@ -146,13 +163,12 @@ class LabelModel extends StringModel {
}

export
class LabelView extends DescriptionView {
class LabelView extends StringView {
/**
* Called when view is rendered.
*/
render() {
super.render();
this.el.classList.add('jupyter-widgets');
this.el.classList.add('widget-label');
this.update(); // Set defaults.
}
Expand Down Expand Up @@ -182,14 +198,12 @@ class TextareaModel extends StringModel {
}

export
class TextareaView extends DescriptionView {
class TextareaView extends StringView {
/**
* Called when view is rendered.
*/
render() {
super.render();
this.el.classList.add('jupyter-widgets');
this.el.classList.add('widget-inline-hbox');
this.el.classList.add('widget-textarea');

this.textbox = document.createElement('textarea');
Expand All @@ -205,6 +219,7 @@ class TextareaView extends DescriptionView {
});

this.update_placeholder();
this.updateTooltip();
}

update_placeholder(value?: string) {
Expand All @@ -229,6 +244,7 @@ class TextareaView extends DescriptionView {
this.textbox.disabled = this.model.get('disabled');
}
this.updateTabindex();
this.updateTooltip();
return super.update();
}

Expand All @@ -246,6 +262,16 @@ class TextareaView extends DescriptionView {
}
}

updateTooltip() {
if (!this.textbox) return; // we might be constructing the parent
let title = this.model.get('tooltip');
if (!title) {
this.textbox.removeAttribute('title');
} else if (this.model.get('description').length === 0) {
this.textbox.setAttribute('title', title);
}
}

events() {
return {
'keydown input': 'handleKeyDown',
Expand Down Expand Up @@ -319,14 +345,12 @@ class TextModel extends StringModel {
}

export
class TextView extends DescriptionView {
class TextView extends StringView {
/**
* Called when view is rendered.
*/
render() {
super.render();
this.el.classList.add('jupyter-widgets');
this.el.classList.add('widget-inline-hbox');
this.el.classList.add('widget-text');

this.textbox = document.createElement('input');
Expand All @@ -338,27 +362,15 @@ class TextView extends DescriptionView {
this.listenTo(this.model, 'change:placeholder', (model, value, options) => {
this.update_placeholder(value);
});
this.listenTo(this.model, 'change:description_tooltip', this.update_title);
this.listenTo(this.model, 'change:description', this.update_title);

this.update_placeholder();
this.update_title();
this.updateTabindex();
this.updateTooltip();
}

update_placeholder(value?: string) {
this.textbox.setAttribute('placeholder', value || this.model.get('placeholder'));
}

update_title() {
let title = this.model.get('description_tooltip');
if (!title) {
this.textbox.removeAttribute('title');
} else if (this.model.get('description').length === 0) {
this.textbox.setAttribute('title', title);
}
}

updateTabindex() {
if (!this.textbox) {
return; // we might be constructing the parent
Expand All @@ -373,6 +385,16 @@ class TextView extends DescriptionView {
}
}

updateTooltip() {
if (!this.textbox) return; // we might be constructing the parent
let title = this.model.get('tooltip');
if (!title) {
this.textbox.removeAttribute('title');
} else if (this.model.get('description').length === 0) {
this.textbox.setAttribute('title', title);
}
}

update(options?: any) {
/**
* Update the contents of this view
Expand Down Expand Up @@ -503,6 +525,7 @@ class ComboboxView extends TextView {

this.textbox.setAttribute('list', this.datalist.id);
this.el.appendChild(this.datalist);
this.updateTooltip();
}

update(options?: any) {
Expand Down
1 change: 0 additions & 1 deletion packages/controls/src/widget_upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export class FileUploadModel extends CoreDOMWidgetModel {
_counter: 0,
accept: '',
description: 'Upload',
tooltip: '',
disabled: false,
icon: 'upload',
button_style: '',
Expand Down
Loading

0 comments on commit b77d2f0

Please sign in to comment.