Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styling Button, Label, Text, Textarea, Combobox,ToggleButton, Checkbox & Valid.Adapted CSS attributes. #2730

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a6dd8df
Styling buttons.
Jan 10, 2020
fa92769
Generate schema and remove test file.
Jan 13, 2020
d2c55bf
BoolStyle, ToggleButtonStyle.
Jan 13, 2020
bb9db91
Remove test file.
Jan 13, 2020
2d1ac7d
typo.
Jan 13, 2020
0881e10
Styling buttons.
Jan 10, 2020
9f10187
Generate schema and remove test file.
Jan 13, 2020
7f46e5d
Merge branch 'buttonstyling' of github.com:zerline/ipywidgets into bu…
Jan 14, 2020
d8a5106
BoolStyle, ToggleButtonStyle.
Jan 13, 2020
d7f25e8
Remove test file.
Jan 13, 2020
afe3e79
typo.
Jan 13, 2020
d831e5e
Merge branch 'boolstyling' of github.com:zerline/ipywidgets into bool…
Jan 14, 2020
a74d638
Merge branch 'master' into buttonstyling
zerline Jan 15, 2020
f10d1ff
Styling buttons.
Jan 10, 2020
9421ae7
Generate schema and remove test file.
Jan 13, 2020
a108f35
Merge branch 'buttonstyling' of github.com:zerline/ipywidgets into bu…
Jan 18, 2020
944a945
Confusion while merging.
Jan 18, 2020
06172ee
Using booleans ('italic') instead of strings ('text-style').
Jan 18, 2020
bff07db
Final schema.
Jan 18, 2020
2c746b4
This is not needed.
Jan 18, 2020
966578d
String widgets styling. New formatting to comply with master.
Jan 10, 2020
56c6a2f
Generate schema and remove test file.
Jan 13, 2020
00809f3
Removing font-variant. Not sure what to do.
Jan 21, 2020
f88ad87
Our 3 CSS adapting functions better located in widget_style.
Jan 22, 2020
063ad4f
Use 'bold', 'italic' and 'underline' booleans.
Jan 22, 2020
cf6caed
Merge branch 'buttonstyling' into boolstyling
Jan 22, 2020
5dc1a71
Use 'bold', 'italic' and 'underline' booleans.
Jan 22, 2020
7f90b2d
Merge branch 'textstyling' into boolstyling
Jan 22, 2020
8336fbf
Adding test_buttonstyle NB.
Jan 22, 2020
0cf44aa
Remove test files.
Jan 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions ipywidgets/widgets/widget_bool.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,43 @@
Represents a boolean using a widget.
"""

from .widget_description import DescriptionWidget
from .widget_description import DescriptionStyle, DescriptionWidget
from .widget_core import CoreWidget
from .valuewidget import ValueWidget
from .widget import register
from .widget import register, widget_serialization
from .trait_types import Color, InstanceDict
from .._version import __jupyter_widgets_controls_version__

from traitlets import Unicode, Bool, CaselessStrEnum


class _BoolStyle(DescriptionStyle, CoreWidget):
"""_Bool widget style."""
_model_name = Unicode('BoolStyleModel').tag(sync=True)
background_color = Color(None, allow_none=True, help="Background color").tag(sync=True)


@register
class ToggleButtonStyle(_BoolStyle, CoreWidget):
"""ToggleButton widget style."""
_model_name = Unicode('ToggleButtonStyleModel').tag(sync=True)
_view_name = Unicode('ToggleButtonStyleView').tag(sync=True)
_view_module = Unicode('@jupyter-widgets/controls').tag(sync=True)
_view_module_version = Unicode(__jupyter_widgets_controls_version__).tag(sync=True)
bold = Bool(None, allow_none=True, help="Toggle button text bold.").tag(sync=True)
button_color = Color(None, allow_none=True, help="Background color").tag(sync=True)
font_family = Unicode(help="Toggle button text font family.").tag(sync=True)
font_size = Unicode(help="Button text font size.").tag(sync=True)
italic = Bool(None, allow_none=True, help="Toggle button text italic.").tag(sync=True)
underline = Bool(None, allow_none=True, help="Toggle button text underline.").tag(sync=True)
text_color = Color(None, allow_none=True, help="Text color").tag(sync=True)


class _Bool(DescriptionWidget, ValueWidget, CoreWidget):
"""A base class for creating widgets that represent booleans."""
value = Bool(False, help="Bool value").tag(sync=True)
disabled = Bool(False, help="Enable or disable user changes.").tag(sync=True)
style = InstanceDict(_BoolStyle, help="Styling customizations").tag(sync=True, **widget_serialization)

def __init__(self, value=None, **kwargs):
if value is not None:
Expand Down Expand Up @@ -65,6 +91,7 @@ class ToggleButton(_Bool):
button_style = CaselessStrEnum(
values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='',
help="""Use a predefined styling for the button.""").tag(sync=True)
style = InstanceDict(ToggleButtonStyle, help="Styling customizations").tag(sync=True, **widget_serialization)


@register
Expand Down
11 changes: 10 additions & 1 deletion ipywidgets/widgets/widget_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .widget_core import CoreWidget
from .widget_style import Style
from .trait_types import Color, InstanceDict
from .._version import __jupyter_widgets_controls_version__

from traitlets import Unicode, Bool, CaselessStrEnum, Instance, validate, default
import warnings
Expand All @@ -21,8 +22,16 @@
class ButtonStyle(Style, CoreWidget):
"""Button style widget."""
_model_name = Unicode('ButtonStyleModel').tag(sync=True)
_view_name = Unicode('ButtonStyleView').tag(sync=True)
_view_module = Unicode('@jupyter-widgets/controls').tag(sync=True)
_view_module_version = Unicode(__jupyter_widgets_controls_version__).tag(sync=True)
bold = Bool(None, allow_none=True, help="Button text bold.").tag(sync=True)
button_color = Color(None, allow_none=True, help="Color of the button").tag(sync=True)
font_weight = Unicode(help="Button text font weight.").tag(sync=True)
font_family = Unicode(None, allow_none=True, help="Button text font family.").tag(sync=True)
font_size = Unicode(help="Button text font size.").tag(sync=True)
italic = Bool(None, allow_none=True, help="Button text italic.").tag(sync=True)
text_color = Unicode(help="Button text color.").tag(sync=True)
underline = Bool(None, allow_none=True, help="Button text underline.").tag(sync=True)


@register
Expand Down
42 changes: 38 additions & 4 deletions ipywidgets/widgets/widget_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,44 @@
Represents a unicode string using a widget.
"""

from .widget_description import DescriptionWidget
from .widget_description import DescriptionStyle, DescriptionWidget
from .valuewidget import ValueWidget
from .widget import CallbackDispatcher, register
from .widget import CallbackDispatcher, register, widget_serialization
from .widget_core import CoreWidget
from .trait_types import TypedTuple
from .trait_types import Color, InstanceDict, TypedTuple
from .._version import __jupyter_widgets_controls_version__
from traitlets import Unicode, Bool, Int
from warnings import warn


@register
class _StringStyle(DescriptionStyle, CoreWidget):
"""Text input style widget."""
_model_name = Unicode('StringStyleModel').tag(sync=True)
background_color = Color(None, allow_none=True, help="Background color").tag(sync=True)
font_size = Unicode(help="Text font size.").tag(sync=True)
text_color = Color(None, allow_none=True, help="Text color").tag(sync=True)


@register
class LabelStyle(_StringStyle, CoreWidget):
"""Label style widget."""
_model_name = Unicode('LabelStyleModel').tag(sync=True)
_view_name = Unicode('LabelStyleView').tag(sync=True)
_view_module = Unicode('@jupyter-widgets/controls').tag(sync=True)
_view_module_version = Unicode(__jupyter_widgets_controls_version__).tag(sync=True)
bold = Bool(None, allow_none=True, help="Label text bold.").tag(sync=True)
font_family = Unicode(help="Label text font family.").tag(sync=True)
italic = Bool(None, allow_none=True, help="Label text italic.").tag(sync=True)
underline = Bool(None, allow_none=True, help="Label text underline.").tag(sync=True)


@register
class TextStyle(_StringStyle, CoreWidget):
"""Text input style widget."""
_model_name = Unicode('TextStyleModel').tag(sync=True)


class _String(DescriptionWidget, ValueWidget, CoreWidget):
"""Base class used to create widgets that represent a string."""

Expand All @@ -24,7 +53,7 @@ class _String(DescriptionWidget, ValueWidget, CoreWidget):
# the text, not the bottom margin. See the last paragraph of
# https://www.w3.org/TR/CSS2/visudet.html#leading
placeholder = Unicode('\u200b', help="Placeholder text to display when nothing has been typed").tag(sync=True)

style = InstanceDict(_StringStyle).tag(sync=True, **widget_serialization)

def __init__(self, value=None, **kwargs):
if value is not None:
Expand All @@ -40,6 +69,7 @@ class HTML(_String):
_view_name = Unicode('HTMLView').tag(sync=True)
_model_name = Unicode('HTMLModel').tag(sync=True)


@register
class HTMLMath(_String):
"""Renders the string `value` as HTML, and render mathematics."""
Expand All @@ -56,6 +86,7 @@ class Label(_String):
"""
_view_name = Unicode('LabelView').tag(sync=True)
_model_name = Unicode('LabelModel').tag(sync=True)
style = InstanceDict(LabelStyle).tag(sync=True, **widget_serialization)


@register
Expand All @@ -66,6 +97,8 @@ class Textarea(_String):
rows = Int(None, allow_none=True, help="The number of rows to display.").tag(sync=True)
disabled = Bool(False, help="Enable or disable user changes").tag(sync=True)
continuous_update = Bool(True, help="Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away.").tag(sync=True)
style = InstanceDict(TextStyle).tag(sync=True, **widget_serialization)


@register
class Text(_String):
Expand All @@ -74,6 +107,7 @@ class Text(_String):
_model_name = Unicode('TextModel').tag(sync=True)
disabled = Bool(False, help="Enable or disable user changes").tag(sync=True)
continuous_update = Bool(True, help="Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away.").tag(sync=True)
style = InstanceDict(TextStyle).tag(sync=True, **widget_serialization)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down
19 changes: 19 additions & 0 deletions packages/base/src/widget_style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ import { assign } from './utils';

import { WidgetModel, WidgetView, DOMWidgetView } from './widget';

/**
* Three functions to adapt some CSS attributes and make them easier to use.
*/
export function bold_to_weight(value: boolean): string | null {
if (value == true) return 'bold';
if (value == false) return 'normal';
return null;
}
export function italic_to_style(value: boolean): string | null {
if (value == true) return 'italic';
if (value == false) return 'normal';
return null;
}
export function underline_to_decoration(value: boolean): string | null {
if (value == true) return 'underline';
if (value == false) return 'none';
return null;
}

export class StyleModel extends WidgetModel {
defaults(): Backbone.ObjectHash {
const Derived = this.constructor as typeof StyleModel;
Expand Down
123 changes: 120 additions & 3 deletions packages/controls/src/widget_bool.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,134 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import {
DOMWidgetView,
StyleModel,
StyleView,
bold_to_weight,
italic_to_style,
underline_to_decoration
} from '@jupyter-widgets/base';

import { CoreDescriptionModel } from './widget_core';

import { DescriptionView } from './widget_description';
import { DescriptionStyleModel, DescriptionView } from './widget_description';

import { JUPYTER_CONTROLS_VERSION } from './version';

export class BoolStyleModel extends DescriptionStyleModel {
defaults(): Backbone.ObjectHash {
return {
...super.defaults(),
_model_name: 'BoolStyleModel',
_model_module: '@jupyter-widgets/controls',
_model_module_version: JUPYTER_CONTROLS_VERSION
};
}

public static styleProperties = {
...DescriptionStyleModel.styleProperties,
background_color: {
selector: '',
attribute: 'background-color',
default: null as any
}
};
}

export class ToggleButtonStyleModel extends BoolStyleModel {
defaults(): Backbone.ObjectHash {
return {
...super.defaults(),
_model_name: 'ToggleButtonStyleModel',
_view_name: 'ToggleButtonStyleView',
_view_module: '@jupyter-widgets/controls',
_view_module_version: JUPYTER_CONTROLS_VERSION
};
}

public static styleProperties = {
...BoolStyleModel.styleProperties,
bold: {
selector: '',
attribute: 'font-weight',
default: ''
},
button_color: {
selector: '',
attribute: 'background-color',
default: null as any
},
font_family: {
selector: '',
attribute: 'font-family',
default: ''
},
font_size: {
selector: '',
attribute: 'font-size',
default: ''
},
italic: {
selector: '',
attribute: 'font-style',
default: ''
},
text_color: {
selector: '',
attribute: 'color',
default: ''
},
underline: {
selector: '',
attribute: 'text-decoration',
default: ''
}
};
}

import { DOMWidgetView } from '@jupyter-widgets/base';
export class ToggleButtonStyleView extends StyleView {
/**
* Handles when a trait value changes
*/
handleChange(trait: string, value: any): void {
// should be synchronous so that we can measure later.
const parent = this.options.parent as DOMWidgetView;
if (parent) {
const ModelType = this.model.constructor as typeof StyleModel;
const styleProperties = ModelType.styleProperties;
const attribute = styleProperties[trait].attribute;
const selector = styleProperties[trait].selector;
const elements = selector
? parent.el.querySelectorAll<HTMLElement>(selector)
: [parent.el];
let transform = undefined;
if (trait == 'bold') transform = bold_to_weight;
if (trait == 'italic') transform = italic_to_style;
if (trait == 'underline') transform = underline_to_decoration;
if (transform !== undefined) value = transform(value);
if (value === null) {
for (let i = 0; i !== elements.length; ++i) {
elements[i].style.removeProperty(attribute);
}
} else {
for (let i = 0; i !== elements.length; ++i) {
elements[i].style.setProperty(attribute, value);
}
}
} else {
console.warn('Style not applied because a parent view does not exist');
}
}
}

export class BoolModel extends CoreDescriptionModel {
defaults(): Backbone.ObjectHash {
return {
...super.defaults(),
value: false,
disabled: false,
style: null,
_model_name: 'BoolModel'
};
}
Expand Down Expand Up @@ -177,7 +293,8 @@ export class ToggleButtonModel extends BoolModel {
_model_name: 'ToggleButtonModel',
tooltip: '',
icon: '',
button_style: ''
button_style: '',
style: null
};
}
}
Expand Down
Loading