From e13e0f59db4219db0eeb58fd1aa48bbcb54545b6 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 22 May 2017 11:32:42 -0400 Subject: [PATCH 1/6] Initial implementation of description_width styling. Fixes #1373 --- ipywidgets/widgets/domwidget.py | 10 ++- ipywidgets/widgets/widget_int.py | 7 +- jupyter-js-widgets/css/widgets-base.css | 6 +- jupyter-js-widgets/src/index.ts | 1 + jupyter-js-widgets/src/widget.ts | 38 ----------- jupyter-js-widgets/src/widget_bool.ts | 16 +++-- jupyter-js-widgets/src/widget_color.ts | 10 +-- jupyter-js-widgets/src/widget_core.ts | 10 ++- jupyter-js-widgets/src/widget_date.ts | 12 ++-- jupyter-js-widgets/src/widget_description.ts | 70 ++++++++++++++++++++ jupyter-js-widgets/src/widget_float.ts | 8 +-- jupyter-js-widgets/src/widget_int.ts | 30 +++++---- jupyter-js-widgets/src/widget_selection.ts | 20 +++--- jupyter-js-widgets/src/widget_string.ts | 18 ++--- jupyter-js-widgets/src/widget_style.ts | 6 +- 15 files changed, 157 insertions(+), 105 deletions(-) create mode 100644 jupyter-js-widgets/src/widget_description.ts diff --git a/ipywidgets/widgets/domwidget.py b/ipywidgets/widgets/domwidget.py index 6584220874..f7018e6fdd 100644 --- a/ipywidgets/widgets/domwidget.py +++ b/ipywidgets/widgets/domwidget.py @@ -7,6 +7,7 @@ from .widget import Widget, widget_serialization from .trait_types import Color, InstanceDict from .widget_layout import Layout +from .widget_style import Style class DOMWidget(Widget): @@ -37,8 +38,15 @@ def remove_class(self, className): return self +class DescriptionStyle(Style, Widget): + """Button style widget.""" + _model_name = Unicode('SliderStyleModel').tag(sync=True) + description_width = Unicode().tag(sync=True) + + class LabeledWidget(DOMWidget): """Widget that has a description label to the side.""" - _model_name = Unicode('LabeledWidgetModel').tag(sync=True) + _model_name = Unicode('DescriptionModel').tag(sync=True) description = Unicode('', help="Description of the control.").tag(sync=True) + style = InstanceDict(DescriptionStyle).tag(sync=True, **widget_serialization) diff --git a/ipywidgets/widgets/widget_int.py b/ipywidgets/widgets/widget_int.py index a526da865f..630d0de9eb 100644 --- a/ipywidgets/widgets/widget_int.py +++ b/ipywidgets/widgets/widget_int.py @@ -6,11 +6,10 @@ Represents an unbounded int using a widget. """ -from .domwidget import LabeledWidget +from .domwidget import LabeledWidget, DescriptionStyle from .valuewidget import ValueWidget from .widget import register, widget_serialization from .widget_core import CoreWidget -from .widget_style import Style from traitlets import Instance from .trait_types import Color, InstanceDict from traitlets import ( @@ -143,7 +142,7 @@ class BoundedIntText(_BoundedInt): @register -class SliderStyle(Style, CoreWidget): +class SliderStyle(DescriptionStyle, CoreWidget): """Button style widget.""" _model_name = Unicode('SliderStyleModel').tag(sync=True) handle_color = Color(None, allow_none=True).tag(sync=True) @@ -167,7 +166,7 @@ class IntSlider(_BoundedInt): @register -class ProgressStyle(Style, CoreWidget): +class ProgressStyle(DescriptionStyle, CoreWidget): """Button style widget.""" _model_name = Unicode('ProgressStyleModel').tag(sync=True) bar_color = Color(None, allow_none=True).tag(sync=True) diff --git a/jupyter-js-widgets/css/widgets-base.css b/jupyter-js-widgets/css/widgets-base.css index 6468291fe8..0536f8ba30 100644 --- a/jupyter-js-widgets/css/widgets-base.css +++ b/jupyter-js-widgets/css/widgets-base.css @@ -21,8 +21,7 @@ --jp-widgets-inline-width-short: calc(var(--jp-widgets-inline-width) / 2 - var(--jp-widgets-margin)); --jp-widgets-inline-width-tiny: calc(var(--jp-widgets-inline-width-short) / 2 - var(--jp-widgets-margin)); --jp-widgets-inline-margin: 4px; /* margin between inline elements */ - --jp-widgets-inline-label-min-width: 80px; - --jp-widgets-inline-label-max-width: calc(var(--jp-widgets-inline-width) - var(--jp-widgets-inline-margin) - var(--jp-widgets-inline-width-short)); + --jp-widgets-inline-label-width: 80px; --jp-widgets-border-width: var(--jp-border-width); --jp-widgets-vertical-height: 200px; --jp-widgets-horizontal-tab-height: 24px; @@ -288,8 +287,7 @@ color: var(--jp-widgets-label-color); text-align: right; margin-right: calc( var(--jp-widgets-inline-margin) * 2 ); - max-width: var(--jp-widgets-inline-label-max-width); - min-width: var(--jp-widgets-inline-label-min-width); + width: var(--jp-widgets-inline-label-width); flex-shrink: 0; } diff --git a/jupyter-js-widgets/src/index.ts b/jupyter-js-widgets/src/index.ts index b9192230f8..120adda433 100644 --- a/jupyter-js-widgets/src/index.ts +++ b/jupyter-js-widgets/src/index.ts @@ -20,6 +20,7 @@ export * from "./widget_controller"; export * from "./widget_selection"; export * from "./widget_selectioncontainer"; export * from "./widget_string"; +export * from "./widget_description"; export const version = (require('../package.json') as any).version; diff --git a/jupyter-js-widgets/src/widget.ts b/jupyter-js-widgets/src/widget.ts index ef037bb1dd..765829ef91 100644 --- a/jupyter-js-widgets/src/widget.ts +++ b/jupyter-js-widgets/src/widget.ts @@ -953,41 +953,3 @@ class DOMWidgetView extends WidgetView { layoutPromise: Promise; stylePromise: Promise; } - - -export -class LabeledDOMWidgetModel extends DOMWidgetModel { - defaults() { - return _.extend(super.defaults(), { - description: '', - }); - } -} - -export -class LabeledDOMWidgetView extends DOMWidgetView { - - render() { - this.label = document.createElement('div'); - this.el.appendChild(this.label); - this.label.className = 'widget-label'; - this.label.style.display = 'none'; - - this.listenTo(this.model, 'change:description', this.updateDescription); - this.updateDescription(); - } - - updateDescription() { - let description = this.model.get('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; - } - - label: HTMLDivElement; -} diff --git a/jupyter-js-widgets/src/widget_bool.ts b/jupyter-js-widgets/src/widget_bool.ts index 29972009b2..788d3a35a9 100644 --- a/jupyter-js-widgets/src/widget_bool.ts +++ b/jupyter-js-widgets/src/widget_bool.ts @@ -2,18 +2,22 @@ // Distributed under the terms of the Modified BSD License. import { - CoreLabeledDOMWidgetModel + CoreDescriptionModel } from './widget_core'; import { - DOMWidgetView, LabeledDOMWidgetView + DOMWidgetView } from './widget'; +import { + DescriptionView +} from './widget_description'; + import * as _ from 'underscore'; export -class BoolModel extends CoreLabeledDOMWidgetModel { +class BoolModel extends CoreDescriptionModel { defaults() { return _.extend(super.defaults(), { value: false, @@ -24,7 +28,7 @@ class BoolModel extends CoreLabeledDOMWidgetModel { } export -class CheckboxModel extends CoreLabeledDOMWidgetModel { +class CheckboxModel extends CoreDescriptionModel { defaults() { return _.extend(super.defaults(), { indent: true, @@ -35,7 +39,7 @@ class CheckboxModel extends CoreLabeledDOMWidgetModel { } export -class CheckboxView extends LabeledDOMWidgetView { +class CheckboxView extends DescriptionView { /** * Called when view is rendered. */ @@ -261,7 +265,7 @@ class ValidModel extends BoolModel { } export -class ValidView extends LabeledDOMWidgetView { +class ValidView extends DescriptionView { /** * Called when view is rendered. */ diff --git a/jupyter-js-widgets/src/widget_color.ts b/jupyter-js-widgets/src/widget_color.ts index 56380e4f45..7f80333e91 100644 --- a/jupyter-js-widgets/src/widget_color.ts +++ b/jupyter-js-widgets/src/widget_color.ts @@ -2,18 +2,18 @@ // Distributed under the terms of the Modified BSD License. import { - LabeledDOMWidgetView -} from './widget'; + DescriptionView +} from './widget_description'; import { - CoreLabeledDOMWidgetModel + CoreDescriptionModel } from './widget_core'; import * as _ from 'underscore'; export -class ColorPickerModel extends CoreLabeledDOMWidgetModel { +class ColorPickerModel extends CoreDescriptionModel { defaults() { return _.extend(super.defaults(), { value: 'black', @@ -25,7 +25,7 @@ class ColorPickerModel extends CoreLabeledDOMWidgetModel { } export -class ColorPickerView extends LabeledDOMWidgetView { +class ColorPickerView extends DescriptionView { render() { super.render(); this.el.classList.add('jupyter-widgets'); diff --git a/jupyter-js-widgets/src/widget_core.ts b/jupyter-js-widgets/src/widget_core.ts index 926f244db8..53ccd7253b 100644 --- a/jupyter-js-widgets/src/widget_core.ts +++ b/jupyter-js-widgets/src/widget_core.ts @@ -5,9 +5,13 @@ // that are not to be used directly by third-party widget authors. import { - DOMWidgetModel, WidgetModel, LabeledDOMWidgetModel + DOMWidgetModel, WidgetModel } from './widget'; +import { + DescriptionModel +} from './widget_description'; + import * as _ from 'underscore'; export @@ -29,10 +33,10 @@ class CoreDOMWidgetModel extends DOMWidgetModel { } export -class CoreLabeledDOMWidgetModel extends LabeledDOMWidgetModel { +class CoreDescriptionModel extends DescriptionModel { defaults() { return _.extend(super.defaults(), { - _model_name: 'CoreLabeledDOMWidgetModel', + _model_name: 'CoreDescriptionModel', }); } } diff --git a/jupyter-js-widgets/src/widget_date.ts b/jupyter-js-widgets/src/widget_date.ts index aff96406fc..89886b0cb4 100644 --- a/jupyter-js-widgets/src/widget_date.ts +++ b/jupyter-js-widgets/src/widget_date.ts @@ -2,11 +2,11 @@ // Distributed under the terms of the Modified BSD License. import { - LabeledDOMWidgetView -} from './widget'; + DescriptionView +} from './widget_description'; import { - CoreLabeledDOMWidgetModel + CoreDescriptionModel } from './widget_core'; import { @@ -58,9 +58,9 @@ function deserialize_date(value: SerializedDate) { }; export -class DatePickerModel extends CoreLabeledDOMWidgetModel { +class DatePickerModel extends CoreDescriptionModel { static serializers = { - ...CoreLabeledDOMWidgetModel.serializers, + ...CoreDescriptionModel.serializers, value: { serialize: serialize_date, deserialize: deserialize_date @@ -77,7 +77,7 @@ class DatePickerModel extends CoreLabeledDOMWidgetModel { } export -class DatePickerView extends LabeledDOMWidgetView { +class DatePickerView extends DescriptionView { render() { super.render(); this.el.classList.add('jupyter-widgets'); diff --git a/jupyter-js-widgets/src/widget_description.ts b/jupyter-js-widgets/src/widget_description.ts new file mode 100644 index 0000000000..35a8a4d872 --- /dev/null +++ b/jupyter-js-widgets/src/widget_description.ts @@ -0,0 +1,70 @@ +// Copyright (c) Jupyter Development Team. +// Distributed under the terms of the Modified BSD License. + +import { + DOMWidgetModel, DOMWidgetView +} from './widget'; + +import { + StyleModel +} from './widget_style'; + +export +class DescriptionStyleModel extends StyleModel { + defaults() { + return {...super.defaults(), + _model_name: 'DescriptionStyleModel', + }; + } + + public static styleProperties = { + description_width: { + selector: '.widget-label', + attribute: 'width', + default: null + }, + }; +} + +export +class DescriptionModel extends DOMWidgetModel { + defaults() { + return {...super.defaults(), + description: '', + }; + } +} + +export +class DescriptionView extends DOMWidgetView { + + render() { + this.label = document.createElement('div'); + this.el.appendChild(this.label); + this.label.className = 'widget-label'; + this.label.style.display = 'none'; + + this.listenTo(this.model, 'change:description', this.updateDescription); + this.updateDescription(); + } + + updateDescription() { + let description = this.model.get('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; + } + + label: HTMLDivElement; +} + +export +class LabeledDOMWidgetModel extends DescriptionModel {}; + +export +class LabeledDOMWidgetView extends DescriptionView {}; \ No newline at end of file diff --git a/jupyter-js-widgets/src/widget_float.ts b/jupyter-js-widgets/src/widget_float.ts index 2be8d6da70..ad690b8ba4 100644 --- a/jupyter-js-widgets/src/widget_float.ts +++ b/jupyter-js-widgets/src/widget_float.ts @@ -2,11 +2,11 @@ // Distributed under the terms of the Modified BSD License. import { - LabeledDOMWidgetView -} from './widget'; + DescriptionView +} from './widget_description'; import { - CoreLabeledDOMWidgetModel + CoreDescriptionModel } from './widget_core'; import * as _ from 'underscore'; @@ -19,7 +19,7 @@ import { var d3format: any = (require('d3-format') as any).format; export -class FloatModel extends CoreLabeledDOMWidgetModel { +class FloatModel extends CoreDescriptionModel { defaults() { return _.extend(super.defaults(), { _model_name: "FloatModel", diff --git a/jupyter-js-widgets/src/widget_int.ts b/jupyter-js-widgets/src/widget_int.ts index b2bd4f6c49..60fe8b6573 100644 --- a/jupyter-js-widgets/src/widget_int.ts +++ b/jupyter-js-widgets/src/widget_int.ts @@ -2,16 +2,16 @@ // Distributed under the terms of the Modified BSD License. import { - CoreLabeledDOMWidgetModel + CoreDescriptionModel } from './widget_core'; import { - DOMWidgetView, LabeledDOMWidgetView + DOMWidgetView } from './widget'; import { - StyleModel -} from './widget_style'; + DescriptionView, DescriptionStyleModel +} from './widget_description'; import * as _ from 'underscore'; import * as $ from 'jquery'; @@ -20,7 +20,7 @@ import 'jquery-ui/ui/widgets/slider'; var d3format: any = (require('d3-format') as any).format; export -class IntModel extends CoreLabeledDOMWidgetModel { +class IntModel extends CoreDescriptionModel { defaults() { return _.extend(super.defaults(), { _model_name: 'IntModel', @@ -42,14 +42,15 @@ class BoundedIntModel extends IntModel { } export -class SliderStyleModel extends StyleModel { +class SliderStyleModel extends DescriptionStyleModel { defaults() { - return _.extend(super.defaults(), { + return {...super.defaults(), _model_name: 'SliderStyleModel', - }); + }; } public static styleProperties = { + ...DescriptionStyleModel.styleProperties, handle_color: { selector: '.ui-slider-handle', attribute: 'background-color', @@ -87,7 +88,7 @@ export class IntRangeSliderModel extends IntSliderModel {} export -abstract class BaseIntSliderView extends LabeledDOMWidgetView { +abstract class BaseIntSliderView extends DescriptionView { render() { super.render(); this.el.classList.add('jupyter-widgets'); @@ -475,7 +476,7 @@ class BoundedIntTextModel extends BoundedIntModel { } export -class IntTextView extends LabeledDOMWidgetView { +class IntTextView extends DescriptionView { render() { super.render(); this.el.classList.add('jupyter-widgets'); @@ -600,14 +601,15 @@ class IntTextView extends LabeledDOMWidgetView { export -class ProgressStyleModel extends StyleModel { +class ProgressStyleModel extends DescriptionStyleModel { defaults() { - return _.extend(super.defaults(), { + return {...super.defaults(), _model_name: 'ProgressStyleModel', - }); + }; } public static styleProperties = { + ...DescriptionStyleModel.styleProperties, bar_color: { selector: '.progress-bar', attribute: 'background-color', @@ -632,7 +634,7 @@ class IntProgressModel extends BoundedIntModel { export -class ProgressView extends LabeledDOMWidgetView { +class ProgressView extends DescriptionView { initialize(parameters) { super.initialize(parameters); this.listenTo(this.model, 'change:bar_style', this.update_bar_style); diff --git a/jupyter-js-widgets/src/widget_selection.ts b/jupyter-js-widgets/src/widget_selection.ts index b068f32373..613347c97e 100644 --- a/jupyter-js-widgets/src/widget_selection.ts +++ b/jupyter-js-widgets/src/widget_selection.ts @@ -2,13 +2,17 @@ // Distributed under the terms of the Modified BSD License. import { - CoreLabeledDOMWidgetModel, + CoreDescriptionModel, } from './widget_core'; import { - LabeledDOMWidgetView, unpack_models, ViewList + unpack_models, ViewList } from './widget'; +import { + DescriptionView +} from './widget_description'; + import * as _ from 'underscore'; import * as utils from './utils'; import * as $ from 'jquery'; @@ -24,7 +28,7 @@ function scrollIfNeeded(area, elem) { } export -class SelectionModel extends CoreLabeledDOMWidgetModel { +class SelectionModel extends CoreDescriptionModel { defaults() { return {...super.defaults(), _model_name: 'SelectionModel', @@ -54,7 +58,7 @@ class DropdownModel extends SelectionModel { // For the old code, see commit f68bfbc566f3a78a8f3350b438db8ed523ce3642 export -class DropdownView extends LabeledDOMWidgetView { +class DropdownView extends DescriptionView { /** * Public constructor. */ @@ -136,7 +140,7 @@ class SelectModel extends SelectionModel { } export -class SelectView extends LabeledDOMWidgetView { +class SelectView extends DescriptionView { /** * Public constructor. */ @@ -223,7 +227,7 @@ class RadioButtonsModel extends SelectionModel { export -class RadioButtonsView extends LabeledDOMWidgetView { +class RadioButtonsView extends DescriptionView { /** * Called when view is rendered. */ @@ -361,7 +365,7 @@ class ToggleButtonsModel extends SelectionModel { export -class ToggleButtonsView extends LabeledDOMWidgetView { +class ToggleButtonsView extends DescriptionView { initialize(options) { this._css_state = {}; super.initialize(options); @@ -546,7 +550,7 @@ class SelectionSliderModel extends SelectionModel { export -class SelectionSliderView extends LabeledDOMWidgetView { +class SelectionSliderView extends DescriptionView { /** * Called when view is rendered. */ diff --git a/jupyter-js-widgets/src/widget_string.ts b/jupyter-js-widgets/src/widget_string.ts index 4cdd80afa7..36cf35455c 100644 --- a/jupyter-js-widgets/src/widget_string.ts +++ b/jupyter-js-widgets/src/widget_string.ts @@ -2,18 +2,18 @@ // Distributed under the terms of the Modified BSD License. import { - LabeledDOMWidgetView -} from './widget'; + DescriptionView +} from './widget_description'; import { - CoreLabeledDOMWidgetModel + CoreDescriptionModel } from './widget_core'; import * as _ from 'underscore'; export -class StringModel extends CoreLabeledDOMWidgetModel { +class StringModel extends CoreDescriptionModel { defaults() { return _.extend(super.defaults(), { value: '', @@ -35,7 +35,7 @@ class HTMLModel extends StringModel { } export -class HTMLView extends LabeledDOMWidgetView { +class HTMLView extends DescriptionView { /** * Called when view is rendered. */ @@ -76,7 +76,7 @@ class HTMLMathModel extends StringModel { } export -class HTMLMathView extends LabeledDOMWidgetView { +class HTMLMathView extends DescriptionView { /** * Called when view is rendered. */ @@ -114,7 +114,7 @@ class LabelModel extends StringModel { } export -class LabelView extends LabeledDOMWidgetView { +class LabelView extends DescriptionView { /** * Called when view is rendered. */ @@ -149,7 +149,7 @@ class TextareaModel extends StringModel { } export -class TextareaView extends LabeledDOMWidgetView { +class TextareaView extends DescriptionView { /** * Called when view is rendered. */ @@ -267,7 +267,7 @@ class TextModel extends StringModel { } export -class TextView extends LabeledDOMWidgetView { +class TextView extends DescriptionView { /** * Called when view is rendered. */ diff --git a/jupyter-js-widgets/src/widget_style.ts b/jupyter-js-widgets/src/widget_style.ts index 97f4895e36..3fdcc83af3 100644 --- a/jupyter-js-widgets/src/widget_style.ts +++ b/jupyter-js-widgets/src/widget_style.ts @@ -6,13 +6,13 @@ import { } from './widget'; import { - CoreWidgetModel -} from './widget_core'; + WidgetModel +} from './widget'; import * as _ from 'underscore'; export -class StyleModel extends CoreWidgetModel { +class StyleModel extends WidgetModel { defaults() { let Derived = this.constructor as typeof StyleModel; return _.extend(super.defaults(), { From 248589f1f64346842ba6c12cbe36bf77a875d857 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 22 May 2017 11:34:02 -0400 Subject: [PATCH 2/6] Ignore test coverage files. --- jupyter-js-widgets/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/jupyter-js-widgets/.gitignore b/jupyter-js-widgets/.gitignore index cfedd285e0..480518321b 100644 --- a/jupyter-js-widgets/.gitignore +++ b/jupyter-js-widgets/.gitignore @@ -2,3 +2,4 @@ css/widgets.built.css lib-embed/ docs-embed/ dist/ +test/coverage/ \ No newline at end of file From efa2a48d34a057b894b6a66e5f5f072f3f0d92b2 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 22 May 2017 11:43:58 -0400 Subject: [PATCH 3/6] Fix class name. Thanks to @blink1073 for pointing this out. --- ipywidgets/widgets/domwidget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipywidgets/widgets/domwidget.py b/ipywidgets/widgets/domwidget.py index f7018e6fdd..fccd2f3d53 100644 --- a/ipywidgets/widgets/domwidget.py +++ b/ipywidgets/widgets/domwidget.py @@ -40,7 +40,7 @@ def remove_class(self, className): class DescriptionStyle(Style, Widget): """Button style widget.""" - _model_name = Unicode('SliderStyleModel').tag(sync=True) + _model_name = Unicode('DescriptionStyleModel').tag(sync=True) description_width = Unicode().tag(sync=True) From 39127d491a7b21431a41be2b532932ff78ab890d Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 22 May 2017 13:32:47 -0400 Subject: [PATCH 4/6] Clean up --- ipywidgets/widgets/domwidget.py | 12 +++++++----- jupyter-js-widgets/src/widget_bool.ts | 8 ++++---- jupyter-js-widgets/src/widget_color.ts | 8 ++++---- jupyter-js-widgets/src/widget_description.ts | 12 +++++++++++- jupyter-js-widgets/src/widget_float.ts | 8 ++++---- jupyter-js-widgets/src/widget_int.ts | 8 ++++---- jupyter-js-widgets/src/widget_selection.ts | 8 ++++---- jupyter-js-widgets/src/widget_string.ts | 7 +++---- 8 files changed, 41 insertions(+), 30 deletions(-) diff --git a/ipywidgets/widgets/domwidget.py b/ipywidgets/widgets/domwidget.py index fccd2f3d53..f86b4ced70 100644 --- a/ipywidgets/widgets/domwidget.py +++ b/ipywidgets/widgets/domwidget.py @@ -3,9 +3,9 @@ """Contains the DOMWidget class""" -from traitlets import Unicode, Bool, Tuple, default +from traitlets import Unicode, Tuple from .widget import Widget, widget_serialization -from .trait_types import Color, InstanceDict +from .trait_types import InstanceDict from .widget_layout import Layout from .widget_style import Style @@ -39,14 +39,16 @@ def remove_class(self, className): class DescriptionStyle(Style, Widget): - """Button style widget.""" + """Description style widget.""" _model_name = Unicode('DescriptionStyleModel').tag(sync=True) description_width = Unicode().tag(sync=True) -class LabeledWidget(DOMWidget): +class DescriptionWidget(DOMWidget): """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) style = InstanceDict(DescriptionStyle).tag(sync=True, **widget_serialization) + +# For backwards compatibility to ipywidgets 6.0 +LabeledWidget = DescriptionWidget diff --git a/jupyter-js-widgets/src/widget_bool.ts b/jupyter-js-widgets/src/widget_bool.ts index 788d3a35a9..22b19e6dd7 100644 --- a/jupyter-js-widgets/src/widget_bool.ts +++ b/jupyter-js-widgets/src/widget_bool.ts @@ -5,14 +5,14 @@ import { CoreDescriptionModel } from './widget_core'; -import { - DOMWidgetView -} from './widget'; - import { DescriptionView } from './widget_description'; +import { + DOMWidgetView +} from './widget'; + import * as _ from 'underscore'; diff --git a/jupyter-js-widgets/src/widget_color.ts b/jupyter-js-widgets/src/widget_color.ts index 7f80333e91..7d29c51d16 100644 --- a/jupyter-js-widgets/src/widget_color.ts +++ b/jupyter-js-widgets/src/widget_color.ts @@ -1,14 +1,14 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { - DescriptionView -} from './widget_description'; - import { CoreDescriptionModel } from './widget_core'; +import { + DescriptionView +} from './widget_description'; + import * as _ from 'underscore'; diff --git a/jupyter-js-widgets/src/widget_description.ts b/jupyter-js-widgets/src/widget_description.ts index 35a8a4d872..b1ee11bc6f 100644 --- a/jupyter-js-widgets/src/widget_description.ts +++ b/jupyter-js-widgets/src/widget_description.ts @@ -63,8 +63,18 @@ class DescriptionView extends DOMWidgetView { label: HTMLDivElement; } +/** + * For backwards compatibility with jupyter-js-widgets 2.x. + * + * Use DescriptionModel instead. + */ export class LabeledDOMWidgetModel extends DescriptionModel {}; +/** + * For backwards compatibility with jupyter-js-widgets 2.x. + * + * Use DescriptionView instead. + */ export -class LabeledDOMWidgetView extends DescriptionView {}; \ No newline at end of file +class LabeledDOMWidgetView extends DescriptionView {}; diff --git a/jupyter-js-widgets/src/widget_float.ts b/jupyter-js-widgets/src/widget_float.ts index ad690b8ba4..b451c8f5b6 100644 --- a/jupyter-js-widgets/src/widget_float.ts +++ b/jupyter-js-widgets/src/widget_float.ts @@ -1,14 +1,14 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { - DescriptionView -} from './widget_description'; - import { CoreDescriptionModel } from './widget_core'; +import { + DescriptionView +} from './widget_description'; + import * as _ from 'underscore'; import { diff --git a/jupyter-js-widgets/src/widget_int.ts b/jupyter-js-widgets/src/widget_int.ts index 60fe8b6573..971d4d385a 100644 --- a/jupyter-js-widgets/src/widget_int.ts +++ b/jupyter-js-widgets/src/widget_int.ts @@ -5,14 +5,14 @@ import { CoreDescriptionModel } from './widget_core'; -import { - DOMWidgetView -} from './widget'; - import { DescriptionView, DescriptionStyleModel } from './widget_description'; +import { + DOMWidgetView +} from './widget'; + import * as _ from 'underscore'; import * as $ from 'jquery'; import 'jquery-ui/ui/widgets/slider'; diff --git a/jupyter-js-widgets/src/widget_selection.ts b/jupyter-js-widgets/src/widget_selection.ts index 613347c97e..2ea76567ef 100644 --- a/jupyter-js-widgets/src/widget_selection.ts +++ b/jupyter-js-widgets/src/widget_selection.ts @@ -5,14 +5,14 @@ import { CoreDescriptionModel, } from './widget_core'; -import { - unpack_models, ViewList -} from './widget'; - import { DescriptionView } from './widget_description'; +import { + unpack_models, ViewList +} from './widget'; + import * as _ from 'underscore'; import * as utils from './utils'; import * as $ from 'jquery'; diff --git a/jupyter-js-widgets/src/widget_string.ts b/jupyter-js-widgets/src/widget_string.ts index 36cf35455c..6e19d12508 100644 --- a/jupyter-js-widgets/src/widget_string.ts +++ b/jupyter-js-widgets/src/widget_string.ts @@ -1,14 +1,13 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { - DescriptionView -} from './widget_description'; - import { CoreDescriptionModel } from './widget_core'; +import { + DescriptionView +} from './widget_description'; import * as _ from 'underscore'; From fa7a40c17d230211ebb8730f6456e4b13d6661b8 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 22 May 2017 13:32:54 -0400 Subject: [PATCH 5/6] Add newline --- jupyter-js-widgets/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jupyter-js-widgets/.gitignore b/jupyter-js-widgets/.gitignore index 480518321b..6ef1d5f4da 100644 --- a/jupyter-js-widgets/.gitignore +++ b/jupyter-js-widgets/.gitignore @@ -2,4 +2,4 @@ css/widgets.built.css lib-embed/ docs-embed/ dist/ -test/coverage/ \ No newline at end of file +test/coverage/ From 2fe194ef2f89258f989cf0a4ad8aacfe687b4071 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Mon, 22 May 2017 14:03:58 -0400 Subject: [PATCH 6/6] Make the description label an HTML label element. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, set the ‘for’ attribute correctly for accessibility. --- jupyter-js-widgets/css/widgets-base.css | 5 +++++ jupyter-js-widgets/src/widget_color.ts | 5 +++++ jupyter-js-widgets/src/widget_date.ts | 6 ++++++ jupyter-js-widgets/src/widget_description.ts | 4 ++-- jupyter-js-widgets/src/widget_int.ts | 5 +++++ jupyter-js-widgets/src/widget_selection.ts | 6 ++++++ jupyter-js-widgets/src/widget_string.ts | 6 ++++++ 7 files changed, 35 insertions(+), 2 deletions(-) diff --git a/jupyter-js-widgets/css/widgets-base.css b/jupyter-js-widgets/css/widgets-base.css index 0536f8ba30..a57d3d8191 100644 --- a/jupyter-js-widgets/css/widgets-base.css +++ b/jupyter-js-widgets/css/widgets-base.css @@ -261,6 +261,11 @@ /* Widget Label Styling */ +/* Override Bootstrap label css */ +.jupyter-widgets label.widget-label { + margin-bottom: initial; +} + .widget-label-basic { /* Basic Label */ color: var(--jp-widgets-label-color); diff --git a/jupyter-js-widgets/src/widget_color.ts b/jupyter-js-widgets/src/widget_color.ts index 7d29c51d16..483d11c149 100644 --- a/jupyter-js-widgets/src/widget_color.ts +++ b/jupyter-js-widgets/src/widget_color.ts @@ -9,6 +9,10 @@ import { DescriptionView } from './widget_description'; +import { + uuid +} from './utils'; + import * as _ from 'underscore'; @@ -38,6 +42,7 @@ class ColorPickerView extends DescriptionView { this._textbox = document.createElement('input'); this._textbox.setAttribute('type', 'text'); + this._textbox.id = this.label.htmlFor = uuid(); this._color_container.appendChild(this._textbox); this._textbox.value = this.model.get('value'); diff --git a/jupyter-js-widgets/src/widget_date.ts b/jupyter-js-widgets/src/widget_date.ts index 89886b0cb4..70c71d01c3 100644 --- a/jupyter-js-widgets/src/widget_date.ts +++ b/jupyter-js-widgets/src/widget_date.ts @@ -9,6 +9,10 @@ import { CoreDescriptionModel } from './widget_core'; +import { + uuid +} from './utils'; + import { ManagerBase } from './manager-base' @@ -86,6 +90,8 @@ class DatePickerView extends DescriptionView { this._datepicker = document.createElement('input'); this._datepicker.setAttribute('type', 'date'); + this._datepicker.id = this.label.htmlFor = uuid(); + this.el.appendChild(this._datepicker); this.listenTo(this.model, 'change:value', this._update_value); diff --git a/jupyter-js-widgets/src/widget_description.ts b/jupyter-js-widgets/src/widget_description.ts index b1ee11bc6f..affdb9f899 100644 --- a/jupyter-js-widgets/src/widget_description.ts +++ b/jupyter-js-widgets/src/widget_description.ts @@ -39,7 +39,7 @@ export class DescriptionView extends DOMWidgetView { render() { - this.label = document.createElement('div'); + this.label = document.createElement('label'); this.el.appendChild(this.label); this.label.className = 'widget-label'; this.label.style.display = 'none'; @@ -60,7 +60,7 @@ class DescriptionView extends DOMWidgetView { this.label.title = description; } - label: HTMLDivElement; + label: HTMLLabelElement; } /** diff --git a/jupyter-js-widgets/src/widget_int.ts b/jupyter-js-widgets/src/widget_int.ts index 971d4d385a..51583f1b56 100644 --- a/jupyter-js-widgets/src/widget_int.ts +++ b/jupyter-js-widgets/src/widget_int.ts @@ -13,6 +13,10 @@ import { DOMWidgetView } from './widget'; +import { + uuid +} from './utils'; + import * as _ from 'underscore'; import * as $ from 'jquery'; import 'jquery-ui/ui/widgets/slider'; @@ -485,6 +489,7 @@ class IntTextView extends DescriptionView { this.textbox = document.createElement('input'); this.textbox.setAttribute('type', 'text'); + this.textbox.id = this.label.htmlFor = uuid(); this.el.appendChild(this.textbox); this.update(); // Set defaults. diff --git a/jupyter-js-widgets/src/widget_selection.ts b/jupyter-js-widgets/src/widget_selection.ts index 2ea76567ef..a8d0f4a165 100644 --- a/jupyter-js-widgets/src/widget_selection.ts +++ b/jupyter-js-widgets/src/widget_selection.ts @@ -9,6 +9,10 @@ import { DescriptionView } from './widget_description'; +import { + uuid +} from './utils'; + import { unpack_models, ViewList } from './widget'; @@ -78,6 +82,7 @@ class DropdownView extends DescriptionView { this.el.classList.add('widget-dropdown'); this.listbox = document.createElement('select'); + this.listbox.id = this.label.htmlFor = uuid(); this.el.appendChild(this.listbox); this._updateOptions(); this.update(); @@ -160,6 +165,7 @@ class SelectView extends DescriptionView { this.el.classList.add('widget-select'); this.listbox = document.createElement('select'); + this.listbox.id = this.label.htmlFor = uuid(); this.el.appendChild(this.listbox); this._updateOptions(); this.update(); diff --git a/jupyter-js-widgets/src/widget_string.ts b/jupyter-js-widgets/src/widget_string.ts index 6e19d12508..883c26ca7f 100644 --- a/jupyter-js-widgets/src/widget_string.ts +++ b/jupyter-js-widgets/src/widget_string.ts @@ -9,6 +9,10 @@ import { DescriptionView } from './widget_description'; +import { + uuid +} from './utils'; + import * as _ from 'underscore'; export @@ -160,6 +164,7 @@ class TextareaView extends DescriptionView { this.textbox = document.createElement('textarea'); this.textbox.setAttribute('rows', '5'); + this.textbox.id = this.label.htmlFor = uuid(); this.el.appendChild(this.textbox); this.update(); // Set defaults. @@ -278,6 +283,7 @@ class TextView extends DescriptionView { this.textbox = document.createElement('input'); this.textbox.setAttribute('type', this.inputType); + this.textbox.id = this.label.htmlFor = uuid(); this.el.appendChild(this.textbox); this.update(); // Set defaults.