1# Copyright (c) Jupyter Development Team.
2# Distributed under the terms of the Modified BSD License.
3
4"""Contains the Layout class"""
5
6from traitlets import Unicode, Instance, CaselessStrEnum, validate
7from .widget import Widget, register
8from .._version import __jupyter_widgets_base_version__
9
10CSS_PROPERTIES=['inherit', 'initial', 'unset']
11
12@register
13class Layout(Widget):
14    """Layout specification
15
16    Defines a layout that can be expressed using CSS.  Supports a subset of
17    https://developer.mozilla.org/en-US/docs/Web/CSS/Reference
18
19    When a property is also accessible via a shorthand property, we only
20    expose the shorthand.
21
22    For example:
23    - ``flex-grow``, ``flex-shrink`` and ``flex-basis`` are bound to ``flex``.
24    - ``flex-wrap`` and ``flex-direction`` are bound to ``flex-flow``.
25    - ``margin-[top/bottom/left/right]`` values are bound to ``margin``, etc.
26    """
27
28    _view_name = Unicode('LayoutView').tag(sync=True)
29    _view_module = Unicode('@jupyter-widgets/base').tag(sync=True)
30    _view_module_version = Unicode(__jupyter_widgets_base_version__).tag(sync=True)
31    _model_name = Unicode('LayoutModel').tag(sync=True)
32
33    # Keys
34    align_content = CaselessStrEnum(['flex-start', 'flex-end', 'center', 'space-between',
35        'space-around', 'space-evenly', 'stretch'] + CSS_PROPERTIES, allow_none=True, help="The align-content CSS attribute.").tag(sync=True)
36    align_items = CaselessStrEnum(['flex-start', 'flex-end', 'center',
37        'baseline', 'stretch'] + CSS_PROPERTIES, allow_none=True, help="The align-items CSS attribute.").tag(sync=True)
38    align_self = CaselessStrEnum(['auto', 'flex-start', 'flex-end',
39        'center', 'baseline', 'stretch'] + CSS_PROPERTIES, allow_none=True, help="The align-self CSS attribute.").tag(sync=True)
40    bottom = Unicode(None, allow_none=True, help="The bottom CSS attribute.").tag(sync=True)
41    border = Unicode(None, allow_none=True, help="The border CSS attribute.").tag(sync=True)
42    display = Unicode(None, allow_none=True, help="The display CSS attribute.").tag(sync=True)
43    flex = Unicode(None, allow_none=True, help="The flex CSS attribute.").tag(sync=True)
44    flex_flow = Unicode(None, allow_none=True, help="The flex-flow CSS attribute.").tag(sync=True)
45    height = Unicode(None, allow_none=True, help="The height CSS attribute.").tag(sync=True)
46    justify_content = CaselessStrEnum(['flex-start', 'flex-end', 'center',
47        'space-between', 'space-around'] + CSS_PROPERTIES, allow_none=True, help="The justify-content CSS attribute.").tag(sync=True)
48    justify_items = CaselessStrEnum(['flex-start', 'flex-end', 'center'] + CSS_PROPERTIES,
49        allow_none=True, help="The justify-items CSS attribute.").tag(sync=True)
50    left = Unicode(None, allow_none=True, help="The left CSS attribute.").tag(sync=True)
51    margin = Unicode(None, allow_none=True, help="The margin CSS attribute.").tag(sync=True)
52    max_height = Unicode(None, allow_none=True, help="The max-height CSS attribute.").tag(sync=True)
53    max_width = Unicode(None, allow_none=True, help="The max-width CSS attribute.").tag(sync=True)
54    min_height = Unicode(None, allow_none=True, help="The min-height CSS attribute.").tag(sync=True)
55    min_width = Unicode(None, allow_none=True, help="The min-width CSS attribute.").tag(sync=True)
56    overflow = Unicode(None, allow_none=True, help="The overflow CSS attribute.").tag(sync=True)
57    overflow_x = CaselessStrEnum(['visible', 'hidden', 'scroll', 'auto'] + CSS_PROPERTIES, allow_none=True, help="The overflow-x CSS attribute (deprecated).").tag(sync=True)
58    overflow_y = CaselessStrEnum(['visible', 'hidden', 'scroll', 'auto'] + CSS_PROPERTIES, allow_none=True, help="The overflow-y CSS attribute (deprecated).").tag(sync=True)
59    order = Unicode(None, allow_none=True, help="The order CSS attribute.").tag(sync=True)
60    padding = Unicode(None, allow_none=True, help="The padding CSS attribute.").tag(sync=True)
61    right = Unicode(None, allow_none=True, help="The right CSS attribute.").tag(sync=True)
62    top = Unicode(None, allow_none=True, help="The top CSS attribute.").tag(sync=True)
63    visibility = CaselessStrEnum(['visible', 'hidden']+CSS_PROPERTIES, allow_none=True, help="The visibility CSS attribute.").tag(sync=True)
64    width = Unicode(None, allow_none=True, help="The width CSS attribute.").tag(sync=True)
65
66    object_fit = CaselessStrEnum(['contain', 'cover', 'fill', 'scale-down', 'none'], allow_none=True, help="The object-fit CSS attribute.").tag(sync=True)
67    object_position = Unicode(None, allow_none=True, help="The object-position CSS attribute.").tag(sync=True)
68
69    grid_auto_columns = Unicode(None, allow_none=True, help="The grid-auto-columns CSS attribute.").tag(sync=True)
70    grid_auto_flow = CaselessStrEnum(['column','row','row dense','column dense']+ CSS_PROPERTIES, allow_none=True, help="The grid-auto-flow CSS attribute.").tag(sync=True)
71    grid_auto_rows = Unicode(None, allow_none=True, help="The grid-auto-rows CSS attribute.").tag(sync=True)
72    grid_gap = Unicode(None, allow_none=True, help="The grid-gap CSS attribute.").tag(sync=True)
73    grid_template_rows = Unicode(None, allow_none=True, help="The grid-template-rows CSS attribute.").tag(sync=True)
74    grid_template_columns = Unicode(None, allow_none=True, help="The grid-template-columns CSS attribute.").tag(sync=True)
75    grid_template_areas = Unicode(None, allow_none=True, help="The grid-template-areas CSS attribute.").tag(sync=True)
76    grid_row = Unicode(None, allow_none=True, help="The grid-row CSS attribute.").tag(sync=True)
77    grid_column = Unicode(None, allow_none=True, help="The grid-column CSS attribute.").tag(sync=True)
78    grid_area = Unicode(None, allow_none=True, help="The grid-area CSS attribute.").tag(sync=True)
79
80    @validate('overflow_x', 'overflow_y')
81    def _validate_overflows(self, proposal):
82        if proposal.value is not None:
83            import warnings
84            warnings.warn("Layout properties overflow_x and overflow_y have been deprecated and will be dropped in a future release. Please use the overflow shorthand property instead", DeprecationWarning)
85        return proposal.value
86
87
88class LayoutTraitType(Instance):
89
90    klass = Layout
91
92    def validate(self, obj, value):
93        if isinstance(value, dict):
94            return super(LayoutTraitType, self).validate(obj, self.klass(**value))
95        else:
96            return super(LayoutTraitType, self).validate(obj, value)
97