nova-trame 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nova/__init__.py +0 -0
- nova/trame/__init__.py +3 -0
- nova/trame/model/remote_file_input.py +98 -0
- nova/trame/view/components/__init__.py +4 -0
- nova/trame/view/components/input_field.py +273 -0
- nova/trame/view/components/remote_file_input.py +193 -0
- nova/trame/view/components/visualization/__init__.py +3 -0
- nova/trame/view/components/visualization/interactive_2d_plot.py +85 -0
- nova/trame/view/layouts/__init__.py +5 -0
- nova/trame/view/layouts/grid.py +148 -0
- nova/trame/view/layouts/hbox.py +79 -0
- nova/trame/view/layouts/vbox.py +79 -0
- nova/trame/view/theme/__init__.py +3 -0
- nova/trame/view/theme/assets/core_style.scss +30 -0
- nova/trame/view/theme/assets/favicon.png +0 -0
- nova/trame/view/theme/assets/vuetify_config.json +182 -0
- nova/trame/view/theme/theme.py +262 -0
- nova/trame/view/utilities/local_storage.py +102 -0
- nova/trame/view_model/remote_file_input.py +85 -0
- nova_trame-0.8.0.dist-info/LICENSE +21 -0
- nova_trame-0.8.0.dist-info/METADATA +40 -0
- nova_trame-0.8.0.dist-info/RECORD +24 -0
- nova_trame-0.8.0.dist-info/WHEEL +4 -0
- nova_trame-0.8.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,148 @@
|
|
1
|
+
"""Trame implementation of the GridLayout class."""
|
2
|
+
|
3
|
+
from typing import Any, Optional, Union
|
4
|
+
|
5
|
+
from trame.widgets import html
|
6
|
+
from trame_client.widgets.core import AbstractElement
|
7
|
+
|
8
|
+
|
9
|
+
class GridLayout(html.Div):
|
10
|
+
"""Creates a grid with a specified number of rows and columns."""
|
11
|
+
|
12
|
+
def __init__(
|
13
|
+
self,
|
14
|
+
columns: int = 1,
|
15
|
+
height: Optional[Union[int, str]] = None,
|
16
|
+
width: Optional[Union[int, str]] = None,
|
17
|
+
halign: Optional[str] = None,
|
18
|
+
valign: Optional[str] = None,
|
19
|
+
**kwargs: Any,
|
20
|
+
) -> None:
|
21
|
+
"""Constructor for GridLayout.
|
22
|
+
|
23
|
+
Parameters
|
24
|
+
----------
|
25
|
+
columns : int
|
26
|
+
The number of columns in the grid.
|
27
|
+
height : optional[int | str]
|
28
|
+
The height of this grid. If an integer is provided, it is interpreted as pixels. If a string is provided,
|
29
|
+
the string is treated as a CSS value.
|
30
|
+
width : optional[int | str]
|
31
|
+
The width of this grid. If an integer is provided, it is interpreted as pixels. If a string is provided,
|
32
|
+
the string is treated as a CSS value.
|
33
|
+
halign : optional[str]
|
34
|
+
The horizontal alignment of items in the grid. See `MDN
|
35
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items>`__ for available options.
|
36
|
+
valign : optional[str]
|
37
|
+
The vertical alignment of items in the grid. See `MDN
|
38
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/align-items>`__ for available options.
|
39
|
+
kwargs : Any
|
40
|
+
Additional keyword arguments to pass to html.Div.
|
41
|
+
|
42
|
+
Returns
|
43
|
+
-------
|
44
|
+
None
|
45
|
+
|
46
|
+
Examples
|
47
|
+
--------
|
48
|
+
Basic usage:
|
49
|
+
|
50
|
+
.. literalinclude:: ../tests/gallery/app.py
|
51
|
+
:start-after: setup grid
|
52
|
+
:end-before: setup grid complete
|
53
|
+
:dedent:
|
54
|
+
|
55
|
+
Building a custom left-middle-right layout:
|
56
|
+
|
57
|
+
.. literalinclude:: ../tests/test_layouts.py
|
58
|
+
:start-after: setup complex layout example
|
59
|
+
:end-before: setup complex layout example complete
|
60
|
+
:dedent:
|
61
|
+
"""
|
62
|
+
classes = kwargs.pop("classes", [])
|
63
|
+
if isinstance(classes, list):
|
64
|
+
classes = " ".join(classes)
|
65
|
+
classes += " d-grid"
|
66
|
+
|
67
|
+
style = self.get_root_styles(columns, height, width, halign, valign) | kwargs.pop("style", {})
|
68
|
+
|
69
|
+
super().__init__(classes=classes, style=style, **kwargs)
|
70
|
+
|
71
|
+
def get_root_styles(
|
72
|
+
self,
|
73
|
+
columns: int,
|
74
|
+
height: Optional[Union[int, str]],
|
75
|
+
width: Optional[Union[int, str]],
|
76
|
+
halign: Optional[str],
|
77
|
+
valign: Optional[str],
|
78
|
+
) -> dict[str, str]:
|
79
|
+
height = f"{height}px" if isinstance(height, int) else height
|
80
|
+
width = f"{width}px" if isinstance(width, int) else width
|
81
|
+
|
82
|
+
styles = {
|
83
|
+
"grid-template-columns": f"repeat({columns}, 1fr)",
|
84
|
+
}
|
85
|
+
|
86
|
+
if height:
|
87
|
+
styles["height"] = height
|
88
|
+
if width:
|
89
|
+
styles["width"] = width
|
90
|
+
if halign:
|
91
|
+
styles["justify-items"] = halign
|
92
|
+
if valign:
|
93
|
+
styles["align-items"] = valign
|
94
|
+
|
95
|
+
return styles
|
96
|
+
|
97
|
+
def get_row_style(self, row_span: int) -> str:
|
98
|
+
return f"grid-row-end: span {row_span};"
|
99
|
+
|
100
|
+
def get_column_style(self, column_span: int) -> str:
|
101
|
+
return f"grid-column-end: span {column_span};"
|
102
|
+
|
103
|
+
def add_child(self, child: Union[AbstractElement, str]) -> AbstractElement:
|
104
|
+
"""Add a child to the grid.
|
105
|
+
|
106
|
+
Do not call this directly. Instead, use Trame's `with` syntax, which will call this method internally. This
|
107
|
+
method is documented here as a reference for the span parameters.
|
108
|
+
|
109
|
+
Parameters
|
110
|
+
----------
|
111
|
+
child : `AbstractElement \
|
112
|
+
<https://trame.readthedocs.io/en/latest/core.widget.html#trame_client.widgets.core.AbstractElement>`_ | str
|
113
|
+
The child to add to the grid.
|
114
|
+
row_span : int
|
115
|
+
The number of rows this child should span.
|
116
|
+
column_span : int
|
117
|
+
The number of columns this child should span.
|
118
|
+
|
119
|
+
Returns
|
120
|
+
-------
|
121
|
+
None
|
122
|
+
|
123
|
+
Example
|
124
|
+
-------
|
125
|
+
.. literalinclude:: ../tests/gallery/app.py
|
126
|
+
:start-after: grid row and column span example
|
127
|
+
:end-before: grid row and column span example end
|
128
|
+
:dedent:
|
129
|
+
"""
|
130
|
+
if isinstance(child, str):
|
131
|
+
child = html.Div(child)
|
132
|
+
|
133
|
+
row_span = 1
|
134
|
+
column_span = 1
|
135
|
+
if "row_span" in child._py_attr:
|
136
|
+
row_span = child._py_attr["row_span"]
|
137
|
+
if "column_span" in child._py_attr:
|
138
|
+
column_span = child._py_attr["column_span"]
|
139
|
+
|
140
|
+
if "style" not in child._py_attr or child.style is None:
|
141
|
+
child.style = ""
|
142
|
+
child.style += f"; {self.get_row_style(row_span)} {self.get_column_style(column_span)}"
|
143
|
+
|
144
|
+
if "classes" not in child._py_attr or child.classes is None:
|
145
|
+
child.classes = ""
|
146
|
+
child.classes += " d-grid-item"
|
147
|
+
|
148
|
+
super().add_child(child)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"""Trame implementation of the HBoxLayout class."""
|
2
|
+
|
3
|
+
from typing import Any, Optional, Union
|
4
|
+
|
5
|
+
from trame.widgets import html
|
6
|
+
|
7
|
+
|
8
|
+
class HBoxLayout(html.Div):
|
9
|
+
"""Creates an element that horizontally stacks its children."""
|
10
|
+
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
height: Optional[Union[int, str]] = None,
|
14
|
+
width: Optional[Union[int, str]] = None,
|
15
|
+
halign: Optional[str] = None,
|
16
|
+
valign: Optional[str] = None,
|
17
|
+
**kwargs: Any,
|
18
|
+
) -> None:
|
19
|
+
"""Constructor for HBoxLayout.
|
20
|
+
|
21
|
+
Parameters
|
22
|
+
----------
|
23
|
+
height : optional[int | str]
|
24
|
+
The height of this box. If an integer is provided, it is interpreted as pixels. If a string is provided,
|
25
|
+
the string is treated as a CSS value.
|
26
|
+
width : optional[int | str]
|
27
|
+
The width of this box. If an integer is provided, it is interpreted as pixels. If a string is provided,
|
28
|
+
the string is treated as a CSS value.
|
29
|
+
halign : optional[str]
|
30
|
+
The horizontal alignment of items in the grid. See `MDN
|
31
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items>`__ for available options.
|
32
|
+
valign : optional[str]
|
33
|
+
The vertical alignment of items in the grid. See `MDN
|
34
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/align-items>`__ for available options.
|
35
|
+
kwargs : Any
|
36
|
+
Additional keyword arguments to pass to html.Div.
|
37
|
+
|
38
|
+
Returns
|
39
|
+
-------
|
40
|
+
None
|
41
|
+
|
42
|
+
Example
|
43
|
+
-------
|
44
|
+
.. literalinclude:: ../tests/gallery/app.py
|
45
|
+
:start-after: setup hbox
|
46
|
+
:end-before: setup hbox complete
|
47
|
+
:dedent:
|
48
|
+
"""
|
49
|
+
classes = kwargs.pop("classes", [])
|
50
|
+
if isinstance(classes, list):
|
51
|
+
classes = " ".join(classes)
|
52
|
+
classes += " d-flex flex-row"
|
53
|
+
|
54
|
+
style = self.get_root_styles(height, width, halign, valign) | kwargs.pop("style", {})
|
55
|
+
|
56
|
+
super().__init__(classes=classes, style=style, **kwargs)
|
57
|
+
|
58
|
+
def get_root_styles(
|
59
|
+
self,
|
60
|
+
height: Optional[Union[int, str]],
|
61
|
+
width: Optional[Union[int, str]],
|
62
|
+
halign: Optional[str],
|
63
|
+
valign: Optional[str],
|
64
|
+
) -> dict:
|
65
|
+
height = f"{height}px" if isinstance(height, int) else height
|
66
|
+
width = f"{width}px" if isinstance(width, int) else width
|
67
|
+
|
68
|
+
styles = {}
|
69
|
+
|
70
|
+
if height:
|
71
|
+
styles["height"] = height
|
72
|
+
if width:
|
73
|
+
styles["width"] = width
|
74
|
+
if halign:
|
75
|
+
styles["justify-content"] = halign
|
76
|
+
if valign:
|
77
|
+
styles["align-items"] = valign
|
78
|
+
|
79
|
+
return styles
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"""Trame implementation of the VBoxLayout class."""
|
2
|
+
|
3
|
+
from typing import Any, Optional, Union
|
4
|
+
|
5
|
+
from trame.widgets import html
|
6
|
+
|
7
|
+
|
8
|
+
class VBoxLayout(html.Div):
|
9
|
+
"""Creates an element that vertically stacks its children."""
|
10
|
+
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
height: Optional[Union[int, str]] = None,
|
14
|
+
width: Optional[Union[int, str]] = None,
|
15
|
+
halign: Optional[str] = None,
|
16
|
+
valign: Optional[str] = None,
|
17
|
+
**kwargs: Any,
|
18
|
+
) -> None:
|
19
|
+
"""Constructor for VBoxLayout.
|
20
|
+
|
21
|
+
Parameters
|
22
|
+
----------
|
23
|
+
height : optional[int | str]
|
24
|
+
The height of this box. If an integer is provided, it is interpreted as pixels. If a string is provided,
|
25
|
+
the string is treated as a CSS value.
|
26
|
+
width : optional[int | str]
|
27
|
+
The width of this box. If an integer is provided, it is interpreted as pixels. If a string is provided,
|
28
|
+
the string is treated as a CSS value.
|
29
|
+
halign : optional[str]
|
30
|
+
The horizontal alignment of items in the grid. See `MDN
|
31
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/align-items>`__ for available options.
|
32
|
+
valign : optional[str]
|
33
|
+
The vertical alignment of items in the grid. See `MDN
|
34
|
+
<https://developer.mozilla.org/en-US/docs/Web/CSS/justify-items>`__ for available options.
|
35
|
+
kwargs : Any
|
36
|
+
Additional keyword arguments to pass to html.Div.
|
37
|
+
|
38
|
+
Returns
|
39
|
+
-------
|
40
|
+
None
|
41
|
+
|
42
|
+
Example
|
43
|
+
-------
|
44
|
+
.. literalinclude:: ../tests/gallery/app.py
|
45
|
+
:start-after: setup vbox
|
46
|
+
:end-before: setup vbox complete
|
47
|
+
:dedent:
|
48
|
+
"""
|
49
|
+
classes = kwargs.pop("classes", [])
|
50
|
+
if isinstance(classes, list):
|
51
|
+
classes = " ".join(classes)
|
52
|
+
classes += " d-flex flex-column"
|
53
|
+
|
54
|
+
style = self.get_root_styles(height, width, halign, valign) | kwargs.pop("style", {})
|
55
|
+
|
56
|
+
super().__init__(classes=classes, style=style, **kwargs)
|
57
|
+
|
58
|
+
def get_root_styles(
|
59
|
+
self,
|
60
|
+
height: Optional[Union[int, str]],
|
61
|
+
width: Optional[Union[int, str]],
|
62
|
+
halign: Optional[str],
|
63
|
+
valign: Optional[str],
|
64
|
+
) -> dict:
|
65
|
+
height = f"{height}px" if isinstance(height, int) else height
|
66
|
+
width = f"{width}px" if isinstance(width, int) else width
|
67
|
+
|
68
|
+
styles = {}
|
69
|
+
|
70
|
+
if height:
|
71
|
+
styles["height"] = height
|
72
|
+
if width:
|
73
|
+
styles["width"] = width
|
74
|
+
if halign:
|
75
|
+
styles["align-items"] = halign
|
76
|
+
if valign:
|
77
|
+
styles["justify-content"] = valign
|
78
|
+
|
79
|
+
return styles
|
@@ -0,0 +1,30 @@
|
|
1
|
+
html {
|
2
|
+
overflow-y: auto;
|
3
|
+
}
|
4
|
+
|
5
|
+
.d-grid {
|
6
|
+
display: grid;
|
7
|
+
gap: 0.25em;
|
8
|
+
grid-auto-rows: auto;
|
9
|
+
}
|
10
|
+
|
11
|
+
@media only screen and (max-width: 959px) {
|
12
|
+
.d-grid {
|
13
|
+
grid-template-columns: repeat(1, 1fr) !important;
|
14
|
+
}
|
15
|
+
|
16
|
+
.d-grid-item {
|
17
|
+
grid-column: 1 / 1 !important;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
/* Global font sizes can't be set through the Vuetify configuration. */
|
22
|
+
.v-theme--CompactTheme {
|
23
|
+
font-size: 0.85rem;
|
24
|
+
|
25
|
+
.v-card-title,
|
26
|
+
.v-list-item-title,
|
27
|
+
.v-toolbar-title {
|
28
|
+
font-size: 1rem;
|
29
|
+
}
|
30
|
+
}
|
Binary file
|
@@ -0,0 +1,182 @@
|
|
1
|
+
{
|
2
|
+
"defaults": {
|
3
|
+
"global": {
|
4
|
+
"hideDetails": "auto",
|
5
|
+
"hideSpinButtons": true,
|
6
|
+
"persistentPlaceholder": true
|
7
|
+
},
|
8
|
+
"VAlert": {
|
9
|
+
"color": "secondary"
|
10
|
+
},
|
11
|
+
"VAppBar": {
|
12
|
+
"color": "primary",
|
13
|
+
"VBtn": {
|
14
|
+
"color": false
|
15
|
+
}
|
16
|
+
},
|
17
|
+
"VBadge": {
|
18
|
+
"color": "secondary"
|
19
|
+
},
|
20
|
+
"VBtn": {
|
21
|
+
"color": "primary"
|
22
|
+
},
|
23
|
+
"VBtnToggle": {
|
24
|
+
"color": "primary",
|
25
|
+
"VBtn": {
|
26
|
+
"class": "border-primary border-sm"
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"VCard": {
|
30
|
+
"VCardSubtitle": {
|
31
|
+
"style": {
|
32
|
+
"white-space": "normal"
|
33
|
+
}
|
34
|
+
},
|
35
|
+
"VCardTitle": {
|
36
|
+
"style": {
|
37
|
+
"line-height": 1.2,
|
38
|
+
"white-space": "normal"
|
39
|
+
}
|
40
|
+
}
|
41
|
+
},
|
42
|
+
"VCardSubtitle": {
|
43
|
+
"opacity": 0.8
|
44
|
+
},
|
45
|
+
"VCheckbox": {
|
46
|
+
"color": "primary"
|
47
|
+
},
|
48
|
+
"VChip": {
|
49
|
+
"color": "primary"
|
50
|
+
},
|
51
|
+
"VDivider": {
|
52
|
+
"color": "primary"
|
53
|
+
},
|
54
|
+
"VExpansionPanels": {
|
55
|
+
"color": "primary"
|
56
|
+
},
|
57
|
+
"VFileInput": {
|
58
|
+
"color": "primary",
|
59
|
+
"prependIcon": false
|
60
|
+
},
|
61
|
+
"VLabel": {
|
62
|
+
"style": {
|
63
|
+
"opacity": 1.0
|
64
|
+
}
|
65
|
+
},
|
66
|
+
"VList": {
|
67
|
+
"VListItemAction": {
|
68
|
+
"VBtn": {
|
69
|
+
"class": "ml-2"
|
70
|
+
},
|
71
|
+
"VProgressCircular": {
|
72
|
+
"class": "ml-2"
|
73
|
+
}
|
74
|
+
}
|
75
|
+
},
|
76
|
+
"VListItem": {
|
77
|
+
"VBtn": {
|
78
|
+
"color": "secondary"
|
79
|
+
}
|
80
|
+
},
|
81
|
+
"VListItemSubtitle": {
|
82
|
+
"opacity": 0.8
|
83
|
+
},
|
84
|
+
"VProgressCircular": {
|
85
|
+
"color": "secondary"
|
86
|
+
},
|
87
|
+
"VProgressLinear": {
|
88
|
+
"color": "secondary"
|
89
|
+
},
|
90
|
+
"VRadioGroup": {
|
91
|
+
"color": "primary"
|
92
|
+
},
|
93
|
+
"VSelect": {
|
94
|
+
"color": "primary"
|
95
|
+
},
|
96
|
+
"VSlider": {
|
97
|
+
"color": "primary"
|
98
|
+
},
|
99
|
+
"VSnackbar": {
|
100
|
+
"color": "primary",
|
101
|
+
"VBtn": {
|
102
|
+
"color": false
|
103
|
+
}
|
104
|
+
},
|
105
|
+
"VSwitch": {
|
106
|
+
"color": "primary"
|
107
|
+
},
|
108
|
+
"VTextarea": {
|
109
|
+
"color": "primary"
|
110
|
+
},
|
111
|
+
"VTextField": {
|
112
|
+
"color": "primary"
|
113
|
+
},
|
114
|
+
"VWindowItem": {
|
115
|
+
"reverseTransition": "fade-transition",
|
116
|
+
"transition": "fade-transition"
|
117
|
+
}
|
118
|
+
},
|
119
|
+
"theme": {
|
120
|
+
"defaultTheme": "ModernTheme",
|
121
|
+
"themes": {
|
122
|
+
"ModernTheme": {
|
123
|
+
"colors": {
|
124
|
+
"background": "#f0f0f0",
|
125
|
+
"primary": "#007833",
|
126
|
+
"secondary": "#f48e5c"
|
127
|
+
},
|
128
|
+
"defaults": {
|
129
|
+
"VCard": {
|
130
|
+
"class": "pa-4",
|
131
|
+
"VListItem": {
|
132
|
+
"class": "border-primary border-sm",
|
133
|
+
"style": {
|
134
|
+
"background-color": "rgba(var(--v-theme-primary), 0.1)"
|
135
|
+
}
|
136
|
+
}
|
137
|
+
},
|
138
|
+
"VCol": {
|
139
|
+
"VCard": {
|
140
|
+
"class": "border-primary border-sm pa-4",
|
141
|
+
"style": {
|
142
|
+
"background-color": "rgba(var(--v-theme-primary), 0.1)"
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
},
|
147
|
+
"title": "Modern",
|
148
|
+
"value": "ModernTheme"
|
149
|
+
},
|
150
|
+
"CompactTheme": {
|
151
|
+
"colors": {
|
152
|
+
"background": "#f0f0f0",
|
153
|
+
"primary": "#007833",
|
154
|
+
"secondary": "#f48e5c"
|
155
|
+
},
|
156
|
+
"defaults": {
|
157
|
+
"global": {
|
158
|
+
"density": "compact"
|
159
|
+
},
|
160
|
+
"VBadge": {
|
161
|
+
"dot": true
|
162
|
+
},
|
163
|
+
"VBtn": {
|
164
|
+
"density": "default"
|
165
|
+
},
|
166
|
+
"VTextField": {
|
167
|
+
"VBtn": {
|
168
|
+
"size": "small"
|
169
|
+
}
|
170
|
+
}
|
171
|
+
},
|
172
|
+
"title": "Compact",
|
173
|
+
"value": "CompactTheme"
|
174
|
+
}
|
175
|
+
},
|
176
|
+
"variations": {
|
177
|
+
"colors": ["primary", "secondary", "accent"],
|
178
|
+
"darken": 5,
|
179
|
+
"lighten": 5
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|