solara 1.6.0__py2.py3-none-any.whl → 1.7.0__py2.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.
- solara/__init__.py +2 -1
- solara/autorouting.py +2 -1
- solara/checks.py +1 -1
- solara/components/applayout.py +1 -1
- solara/components/cross_filter.py +2 -2
- solara/components/datatable.py +138 -6
- solara/components/datatable.vue +175 -0
- solara/server/assets/style.css +5 -0
- solara/server/static/solara_bootstrap.py +1 -1
- solara/website/assets/custom.css +0 -1
- solara/website/pages/__init__.py +5 -1
- solara/website/pages/api/dataframe.py +13 -21
- solara/website/pages/api/warning.py +7 -0
- solara/widgets/widgets.py +0 -57
- {solara-1.6.0.dist-info → solara-1.7.0.dist-info}/METADATA +2 -2
- {solara-1.6.0.dist-info → solara-1.7.0.dist-info}/RECORD +21 -21
- solara/widgets/vue/datatable.vue +0 -173
- {solara-1.6.0.data → solara-1.7.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
- {solara-1.6.0.data → solara-1.7.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
- {solara-1.6.0.dist-info → solara-1.7.0.dist-info}/LICENSE +0 -0
- {solara-1.6.0.dist-info → solara-1.7.0.dist-info}/WHEEL +0 -0
- {solara-1.6.0.dist-info → solara-1.7.0.dist-info}/entry_points.txt +0 -0
solara/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""Build webapps using IPywidgets"""
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.7.0"
|
|
3
3
|
github_url = "https://github.com/widgetti/solara"
|
|
4
4
|
git_branch = "master"
|
|
5
5
|
|
|
@@ -35,6 +35,7 @@ from reacton import (
|
|
|
35
35
|
use_state,
|
|
36
36
|
use_state_widget,
|
|
37
37
|
) # noqa: F403, F401
|
|
38
|
+
from reacton.core import Element # noqa: F403, F401
|
|
38
39
|
from . import util
|
|
39
40
|
|
|
40
41
|
# flake8: noqa: F402
|
solara/autorouting.py
CHANGED
|
@@ -3,6 +3,7 @@ import importlib
|
|
|
3
3
|
import inspect
|
|
4
4
|
import pkgutil
|
|
5
5
|
import re
|
|
6
|
+
import warnings
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from types import ModuleType
|
|
8
9
|
from typing import Any, Callable, List, Optional, cast
|
|
@@ -356,7 +357,7 @@ def generate_routes(module: ModuleType) -> List[solara.Route]:
|
|
|
356
357
|
raise KeyError(f"Route {k!r} listen in route_order not found in {module}")
|
|
357
358
|
routes = [lookup[k] for k in route_order]
|
|
358
359
|
if set(lookup) - set(route_order):
|
|
359
|
-
|
|
360
|
+
warnings.warn(f"Some routes are not in route_order: {set(lookup) - set(route_order)}")
|
|
360
361
|
|
|
361
362
|
else:
|
|
362
363
|
children = getattr(module, "routes", [])
|
solara/checks.py
CHANGED
|
@@ -62,7 +62,7 @@ def get_server_python_executable(silent: bool = False):
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
libraries_minimal = [
|
|
65
|
-
{"python": "ipyvuetify", "classic": "jupyter-vuetify/extension", "lab": "jupyter-
|
|
65
|
+
{"python": "ipyvuetify", "classic": "jupyter-vuetify/extension", "lab": "jupyter-vuetify"},
|
|
66
66
|
{"python": "ipyvue", "classic": "jupyter-vue/extension", "lab": "jupyter-vue"},
|
|
67
67
|
]
|
|
68
68
|
|
solara/components/applayout.py
CHANGED
|
@@ -218,7 +218,7 @@ def AppLayout(
|
|
|
218
218
|
|
|
219
219
|
title = t.use_title_get() or title
|
|
220
220
|
|
|
221
|
-
show_app_bar = title or routes or children_appbar or use_drawer
|
|
221
|
+
show_app_bar = title or (routes and navigation) or children_appbar or use_drawer
|
|
222
222
|
if not show_app_bar and not children_sidebar and len(children) == 1:
|
|
223
223
|
return children[0]
|
|
224
224
|
if embedded_mode and not fullscreen:
|
|
@@ -315,7 +315,7 @@ def CrossFilterSlider(
|
|
|
315
315
|
|
|
316
316
|
|
|
317
317
|
@solara.component
|
|
318
|
-
def CrossFilterDataFrame(df, column_actions: List[ColumnAction] = [], cell_actions: List[CellAction] = []):
|
|
318
|
+
def CrossFilterDataFrame(df, items_per_page=20, column_actions: List[ColumnAction] = [], cell_actions: List[CellAction] = [], scrollable=False):
|
|
319
319
|
"""Display a DataFrame with filters applied from the cross filter.
|
|
320
320
|
|
|
321
321
|
This component wraps [DataFrame](/api/dataframe).
|
|
@@ -333,4 +333,4 @@ def CrossFilterDataFrame(df, column_actions: List[ColumnAction] = [], cell_actio
|
|
|
333
333
|
filter, set_filter = solara.use_cross_filter(id(df), "dataframe")
|
|
334
334
|
if filter is not None:
|
|
335
335
|
dff = df[filter]
|
|
336
|
-
return solara.DataFrame(dff)
|
|
336
|
+
return solara.DataFrame(dff, items_per_page=items_per_page, scrollable=scrollable, column_actions=column_actions, cell_actions=cell_actions)
|
solara/components/datatable.py
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import dataclasses
|
|
1
2
|
import math
|
|
3
|
+
import os
|
|
2
4
|
from dataclasses import replace
|
|
3
|
-
from typing import List
|
|
5
|
+
from typing import Callable, List, Optional
|
|
6
|
+
|
|
7
|
+
import ipyvuetify as v
|
|
8
|
+
import ipywidgets
|
|
9
|
+
import traitlets
|
|
4
10
|
|
|
5
11
|
import solara
|
|
6
12
|
import solara.hooks.dataframe
|
|
@@ -9,7 +15,61 @@ from solara.lab.hooks.dataframe import use_df_column_names
|
|
|
9
15
|
from solara.lab.utils.dataframe import df_type
|
|
10
16
|
|
|
11
17
|
from .. import CellAction, ColumnAction
|
|
12
|
-
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _ensure_dict(d):
|
|
21
|
+
if dataclasses.is_dataclass(d):
|
|
22
|
+
return dataclasses.asdict(d)
|
|
23
|
+
return d
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _drop_keys_from_list_of_mappings(drop):
|
|
27
|
+
def closure(list_of_dicts, widget):
|
|
28
|
+
return [{k: v for k, v in _ensure_dict(d).items() if k not in drop} for d in list_of_dicts]
|
|
29
|
+
|
|
30
|
+
return closure
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class DataTableWidget(v.VuetifyTemplate):
|
|
34
|
+
template_file = os.path.realpath(os.path.join(os.path.dirname(__file__), "datatable.vue"))
|
|
35
|
+
|
|
36
|
+
total_length = traitlets.CInt().tag(sync=True)
|
|
37
|
+
checked = traitlets.List([]).tag(sync=True) # indices of which rows are selected
|
|
38
|
+
column_actions = traitlets.List(trait=traitlets.Instance(ColumnAction), default_value=[]).tag(
|
|
39
|
+
sync=True, to_json=_drop_keys_from_list_of_mappings(["on_click"])
|
|
40
|
+
)
|
|
41
|
+
_column_actions_callbacks = traitlets.List(trait=traitlets.Callable(), default_value=[])
|
|
42
|
+
cell_actions = traitlets.List(trait=traitlets.Instance(CellAction), default_value=[]).tag(sync=True, to_json=_drop_keys_from_list_of_mappings(["on_click"]))
|
|
43
|
+
_cell_actions_callbacks = traitlets.List(trait=traitlets.Callable(), default_value=[])
|
|
44
|
+
items = traitlets.Any().tag(sync=True) # the data, a list of dict
|
|
45
|
+
headers = traitlets.Any().tag(sync=True)
|
|
46
|
+
headers_selections = traitlets.Any().tag(sync=True)
|
|
47
|
+
options = traitlets.Any().tag(sync=True)
|
|
48
|
+
items_per_page = traitlets.CInt(11).tag(sync=True)
|
|
49
|
+
selections = traitlets.Any([]).tag(sync=True)
|
|
50
|
+
selection_colors = traitlets.Any([]).tag(sync=True)
|
|
51
|
+
selection_enabled = traitlets.Bool(True).tag(sync=True)
|
|
52
|
+
highlighted = traitlets.Int(None, allow_none=True).tag(sync=True)
|
|
53
|
+
scrollable = traitlets.Bool(False).tag(sync=True)
|
|
54
|
+
|
|
55
|
+
# for use with scrollable, when used in the default UI
|
|
56
|
+
height = traitlets.Unicode(None, allow_none=True).tag(sync=True)
|
|
57
|
+
|
|
58
|
+
hidden_components = traitlets.List([]).tag(sync=False)
|
|
59
|
+
column_header_hover = traitlets.Unicode(allow_none=True).tag(sync=True)
|
|
60
|
+
column_header_widget = traitlets.Any(allow_none=True).tag(sync=True, **ipywidgets.widget_serialization)
|
|
61
|
+
|
|
62
|
+
def vue_on_column_action(self, data):
|
|
63
|
+
header_value, action_index = data
|
|
64
|
+
on_click = self._column_actions_callbacks[action_index]
|
|
65
|
+
if on_click:
|
|
66
|
+
on_click(header_value)
|
|
67
|
+
|
|
68
|
+
def vue_on_cell_action(self, data):
|
|
69
|
+
row, header_value, action_index = data
|
|
70
|
+
on_click = self._cell_actions_callbacks[action_index]
|
|
71
|
+
if on_click:
|
|
72
|
+
on_click(header_value, row)
|
|
13
73
|
|
|
14
74
|
|
|
15
75
|
def format_default(df, column, row_index, value):
|
|
@@ -19,7 +79,17 @@ def format_default(df, column, row_index, value):
|
|
|
19
79
|
|
|
20
80
|
|
|
21
81
|
@solara.component
|
|
22
|
-
def DataTable(
|
|
82
|
+
def DataTable(
|
|
83
|
+
df,
|
|
84
|
+
page=0,
|
|
85
|
+
items_per_page=20,
|
|
86
|
+
format=None,
|
|
87
|
+
column_actions: List[ColumnAction] = [],
|
|
88
|
+
cell_actions: List[CellAction] = [],
|
|
89
|
+
scrollable=False,
|
|
90
|
+
on_column_header_hover: Optional[Callable[[Optional[str]], None]] = None,
|
|
91
|
+
column_header_info: Optional[solara.Element] = None,
|
|
92
|
+
):
|
|
23
93
|
total_length = len(df)
|
|
24
94
|
options = {"descending": False, "page": page + 1, "itemsPerPage": items_per_page, "sortBy": [], "totalItems": total_length}
|
|
25
95
|
options, set_options = solara.use_state(options, key="options")
|
|
@@ -69,20 +139,82 @@ def DataTable(df, page=0, items_per_page=20, format=None, column_actions: List[C
|
|
|
69
139
|
cell_actions=cell_actions,
|
|
70
140
|
_column_actions_callbacks=column_actions_callbacks,
|
|
71
141
|
_cell_actions_callbacks=cell_actions_callbacks,
|
|
142
|
+
on_column_header_hover=on_column_header_hover,
|
|
143
|
+
column_header_widget=column_header_info,
|
|
72
144
|
)
|
|
73
145
|
|
|
74
146
|
|
|
75
147
|
@solara.component
|
|
76
|
-
def DataFrame(
|
|
148
|
+
def DataFrame(
|
|
149
|
+
df,
|
|
150
|
+
items_per_page=20,
|
|
151
|
+
column_actions: List[ColumnAction] = [],
|
|
152
|
+
cell_actions: List[CellAction] = [],
|
|
153
|
+
scrollable=False,
|
|
154
|
+
on_column_header_hover: Optional[Callable[[Optional[str]], None]] = None,
|
|
155
|
+
column_header_info: Optional[solara.Element] = None,
|
|
156
|
+
):
|
|
77
157
|
"""Displays a Pandas dataframe in a table.
|
|
78
158
|
|
|
159
|
+
Pass in a dataframe as first argument, and optionally how many items per page to display.
|
|
160
|
+
|
|
161
|
+
```solara
|
|
162
|
+
import solara
|
|
163
|
+
import pandas as pd
|
|
164
|
+
import plotly
|
|
165
|
+
|
|
166
|
+
df = plotly.data.iris()
|
|
167
|
+
|
|
168
|
+
@solara.component
|
|
169
|
+
def Page():
|
|
170
|
+
solara.DataFrame(df, items_per_page=5)
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
# Custom column header info
|
|
175
|
+
|
|
176
|
+
Use the `column_header_info` argument to display a custom component on the column header when
|
|
177
|
+
the user hover above it. In this case we display the value counts for the column.
|
|
178
|
+
|
|
179
|
+
```solara
|
|
180
|
+
import solara
|
|
181
|
+
import pandas as pd
|
|
182
|
+
import plotly
|
|
183
|
+
|
|
184
|
+
df = plotly.data.iris()
|
|
185
|
+
|
|
186
|
+
@solara.component
|
|
187
|
+
def Page():
|
|
188
|
+
column_hover, set_column_hover = solara.use_state(None)
|
|
189
|
+
|
|
190
|
+
with solara.Column(margin=4) as column_header_info:
|
|
191
|
+
if column_hover:
|
|
192
|
+
solara.Text("Value counts for " + column_hover)
|
|
193
|
+
display(df[column_hover].value_counts())
|
|
194
|
+
# if no column is hovered above, we provide an empty container
|
|
195
|
+
# so we always see the triple dot icon on the column header
|
|
196
|
+
|
|
197
|
+
solara.DataFrame(df, column_header_info=column_header_info, on_column_header_hover=set_column_hover)
|
|
198
|
+
```
|
|
199
|
+
|
|
79
200
|
|
|
80
201
|
## Arguments
|
|
81
202
|
|
|
82
203
|
* `df` - `DataFrame` - a Pandas dataframe.
|
|
204
|
+
* `items_per_page` - `int` - number of items per page.
|
|
83
205
|
* `column_actions` - Triggered via clicking on the triple dot icon on the headers (visible when hovering).
|
|
84
206
|
* `cell_actions` - Triggered via clicking on the triple dot icon in the cell (visible when hovering).
|
|
85
|
-
|
|
207
|
+
* `on_column_header_hover` - Optional callback when the user hovers over the triple dot icon on a header.
|
|
208
|
+
* `column_header_info` - Element to display in the column menu popup (visible when hovering), provide an
|
|
209
|
+
empty container element (like [Column](/api/column)) to force showing the trigle dot icon (see example).
|
|
86
210
|
|
|
87
211
|
"""
|
|
88
|
-
return DataTable(
|
|
212
|
+
return DataTable(
|
|
213
|
+
df,
|
|
214
|
+
items_per_page=items_per_page,
|
|
215
|
+
column_actions=column_actions,
|
|
216
|
+
cell_actions=cell_actions,
|
|
217
|
+
scrollable=scrollable,
|
|
218
|
+
on_column_header_hover=on_column_header_hover,
|
|
219
|
+
column_header_info=column_header_info,
|
|
220
|
+
)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-slide-x-transition appear>
|
|
3
|
+
<div class="solara-data-table__viewport">
|
|
4
|
+
<v-data-table dense hide-default-header :headers="[...headers]" :items="items"
|
|
5
|
+
:footer-props="{ 'items-per-page-options': [10, 20, 50, 100] }" :options.sync="options"
|
|
6
|
+
:items_per_page.sync="items_per_page" :server-items-length="total_length" :class="[
|
|
7
|
+
'elevation-1',
|
|
8
|
+
'solara-data-table',
|
|
9
|
+
scrollable && 'solara-data-table--scrollable',
|
|
10
|
+
]" :style="scrollable && height != null && `height: ${height}`">
|
|
11
|
+
<template v-slot:header="props">
|
|
12
|
+
<thead>
|
|
13
|
+
<tr>
|
|
14
|
+
<th style="padding: 0 10px; width: 40px">#</th>
|
|
15
|
+
<th style="padding: 0 1px; width: 30px" v-if="selection_enabled">
|
|
16
|
+
<v-btn icon color="primary" text small @click="apply_filter">
|
|
17
|
+
<v-icon>filter_list</v-icon>
|
|
18
|
+
</v-btn>
|
|
19
|
+
</th>
|
|
20
|
+
<th style="padding: 0 1px" v-for="(header, index) in headers_selections" :key="header.text">
|
|
21
|
+
<v-icon style="padding: 0 1px" :key="index" :color="selection_colors[index]">brightness_1</v-icon>
|
|
22
|
+
</th>
|
|
23
|
+
<v-slide-x-transition :key="header.text" v-for="header in headers">
|
|
24
|
+
<th class="text-no-wrap">
|
|
25
|
+
{{ header.text }}
|
|
26
|
+
<v-menu open-on-hover bottom offset-y @input="isOpen => onHeaderHover({ isOpen, header })"
|
|
27
|
+
v-if="(column_actions && column_actions.length) || column_header_widget">
|
|
28
|
+
<template v-slot:activator="{ on, attrs }">
|
|
29
|
+
<v-icon v-bind="attrs" v-on="on" small class="solara-data-table-menu">mdi-dots-vertical</v-icon>
|
|
30
|
+
</template>
|
|
31
|
+
<v-sheet v-if="header.value === column_header_hover" class="solara-data-table-column-header-sheet">
|
|
32
|
+
<jupyter-widget v-if="column_header_widget" :widget="column_header_widget"></jupyter-widget>
|
|
33
|
+
</v-sheet>
|
|
34
|
+
<v-list v-if="column_actions && column_actions.length">
|
|
35
|
+
<v-subheader>Actions:</v-subheader>
|
|
36
|
+
<v-list-item link @click="on_column_action([header.value, index])"
|
|
37
|
+
v-for="(action, index) in column_actions" :key="index">
|
|
38
|
+
<v-list-item-icon><v-icon>{{ action.icon }}</v-icon></v-list-item-icon>
|
|
39
|
+
<v-list-item-title>{{ action.name }}</v-list-item-title>
|
|
40
|
+
</v-list-item>
|
|
41
|
+
</v-list>
|
|
42
|
+
</v-menu>
|
|
43
|
+
</th>
|
|
44
|
+
</v-slide-x-transition>
|
|
45
|
+
</tr>
|
|
46
|
+
</thead>
|
|
47
|
+
</template>
|
|
48
|
+
<template v-slot:item="props">
|
|
49
|
+
<!-- @click="on_row_clicked(props.item.__row__)" -->
|
|
50
|
+
<tr :class="{ highlightedRow: props.item.__row__ === highlighted }">
|
|
51
|
+
<td style="padding: 0 10px" class="text-xs-left">
|
|
52
|
+
<i>{{ props.item.__row__ }}</i>
|
|
53
|
+
</td>
|
|
54
|
+
<td style="padding: 0 1px" class="text-xs-left" v-if="selection_enabled">
|
|
55
|
+
<v-checkbox hide-details style="margin-top: 0; padding-top: 0"
|
|
56
|
+
:input-value="checked.indexOf(props.item.__row__) != -1" :key="props.item.__row__"
|
|
57
|
+
@change="(value) => select({ checked: value, row: props.item.__row__ })" />
|
|
58
|
+
</td>
|
|
59
|
+
<td style="padding: 0 1px" :key="header.text" v-for="(header, index) in headers_selections">
|
|
60
|
+
<v-fade-transition leave-absolute>
|
|
61
|
+
<v-icon v-if="props.item[header.value]" v-model="props.item[header.value]"
|
|
62
|
+
:color="selection_colors[index]">brightness_1</v-icon>
|
|
63
|
+
</v-fade-transition>
|
|
64
|
+
</td>
|
|
65
|
+
<td v-for="header in headers" class="text-truncate text-no-wrap" :key="header.text"
|
|
66
|
+
:title="props.item[header.value]">
|
|
67
|
+
<v-slide-x-transition appear>
|
|
68
|
+
<!-- <span @click="on_item_click([props.item.__row__, header.value])">{{ props.item[header.value] }}</span> -->
|
|
69
|
+
<span>
|
|
70
|
+
{{ props.item[header.value] }}
|
|
71
|
+
<v-menu open-on-hover bottom offset-y v-if="cell_actions.length">
|
|
72
|
+
<template v-slot:activator="{ on, attrs }">
|
|
73
|
+
<v-icon v-bind="attrs" v-on="on" small class="solara-data-table-menu">mdi-dots-vertical</v-icon>
|
|
74
|
+
</template>
|
|
75
|
+
<v-list v-for="(action, index) in cell_actions" :key="index">
|
|
76
|
+
<v-list-item link @click="on_cell_action([props.item.__row__, header.value, index])">
|
|
77
|
+
<v-list-item-icon><v-icon>{{ action.icon }}</v-icon></v-list-item-icon>
|
|
78
|
+
<v-list-item-title>{{ action.name }}</v-list-item-title>
|
|
79
|
+
</v-list-item>
|
|
80
|
+
</v-list>
|
|
81
|
+
</v-menu>
|
|
82
|
+
</span>
|
|
83
|
+
|
|
84
|
+
</v-slide-x-transition>
|
|
85
|
+
</td>
|
|
86
|
+
</tr>
|
|
87
|
+
</template>
|
|
88
|
+
</v-data-table>
|
|
89
|
+
</div>
|
|
90
|
+
</v-slide-x-transition>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<script>
|
|
94
|
+
module.exports = {
|
|
95
|
+
methods: {
|
|
96
|
+
onHeaderHover({ header, isOpen }) {
|
|
97
|
+
if (isOpen) {
|
|
98
|
+
// if isOpen is true, we clicked, and we set it header.value
|
|
99
|
+
this.column_header_hover = header.value
|
|
100
|
+
} else {
|
|
101
|
+
// if false, we only 'unset' if the current header equals the current open menu
|
|
102
|
+
// because sometimes the menu from another column is closed after opening the new one
|
|
103
|
+
if (this.column_header_hover == header.value) {
|
|
104
|
+
this.column_header_hover = null
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
</script>
|
|
111
|
+
<style id="solara_table">
|
|
112
|
+
.highlightedRow {
|
|
113
|
+
background-color: #e3f2fd;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.solara-data-table table {
|
|
117
|
+
table-layout: fixed;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.solara-data-table--scrollable .v-data-table__wrapper {
|
|
121
|
+
overflow-y: auto;
|
|
122
|
+
height: calc(100% - 59px);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.solara-data-table--scrollable thead>tr {
|
|
126
|
+
position: sticky;
|
|
127
|
+
top: 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.solara-data-table--scrollable .v-data-table__wrapper,
|
|
131
|
+
.solara-data-table--scrollable .v-data-table__wrapper>table,
|
|
132
|
+
.solara-data-table--scrollable .v-data-table__wrapper>table thead,
|
|
133
|
+
.solara-data-table--scrollable .v-data-table__wrapper>table thead * {
|
|
134
|
+
background-color: inherit;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* prevent checkboxes overlaying the table header */
|
|
138
|
+
.solara-data-table--scrollable .v-data-table__wrapper>table thead {
|
|
139
|
+
position: relative;
|
|
140
|
+
z-index: 1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* avoid margins to collapse, to avoid a white background */
|
|
144
|
+
.solara-data-table-column-header-sheet {
|
|
145
|
+
overflow: auto;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.solara-data-table.v-data-table th,
|
|
149
|
+
.solara-data-table.v-data-table td {
|
|
150
|
+
padding-left: 4px;
|
|
151
|
+
padding-right: 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.v-data-table .solara-data-table-menu {
|
|
155
|
+
opacity: 0;
|
|
156
|
+
transition: opacity 0.5s;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.v-data-table th:hover .solara-data-table-menu,
|
|
160
|
+
.v-data-table td:hover .solara-data-table-menu {
|
|
161
|
+
opacity: 1;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.solara-data-table__viewport {
|
|
165
|
+
overflow-x: auto;
|
|
166
|
+
width: 100%;
|
|
167
|
+
max-height: 100%;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.solara-data-table.v-data-table,
|
|
171
|
+
.solara-data-table.v-data-table table {
|
|
172
|
+
max-width: unset;
|
|
173
|
+
width: unset;
|
|
174
|
+
}
|
|
175
|
+
</style>
|
solara/server/assets/style.css
CHANGED
|
@@ -119,7 +119,7 @@ async def main():
|
|
|
119
119
|
]
|
|
120
120
|
for dep in requirements:
|
|
121
121
|
await micropip.install(dep, keep_going=True)
|
|
122
|
-
await micropip.install("/wheels/solara-1.
|
|
122
|
+
await micropip.install("/wheels/solara-1.7.0-py2.py3-none-any.whl", keep_going=True)
|
|
123
123
|
import solara
|
|
124
124
|
|
|
125
125
|
el = solara.Warning("lala")
|
solara/website/assets/custom.css
CHANGED
solara/website/pages/__init__.py
CHANGED
|
@@ -81,7 +81,9 @@ def Layout(children=[]):
|
|
|
81
81
|
return children[0]
|
|
82
82
|
with solara.VBox(grow=False) as main:
|
|
83
83
|
Title(title="Solara documentation")
|
|
84
|
-
solara.Meta(
|
|
84
|
+
solara.Meta(name="twitter:card", content="summary_large_image")
|
|
85
|
+
solara.Meta(name="twitter:site", content="@solara_dev")
|
|
86
|
+
solara.Meta(name="twitter:image", content="https://solara.dev/static/assets/images/logo-small.png")
|
|
85
87
|
solara.Meta(property="og:url", content="https://solara.dev" + router.path)
|
|
86
88
|
solara.Meta(property="og:image", content="https://solara.dev/static/assets/images/logo-small.png")
|
|
87
89
|
solara.Meta(property="og:type", content="website")
|
|
@@ -101,7 +103,9 @@ def Layout(children=[]):
|
|
|
101
103
|
description = "Use ipywidgets with Solara to build powerful and scalable web apps for Jupyter and production in Python."
|
|
102
104
|
# both tags in one
|
|
103
105
|
solara.Meta(name="description", property="og:description", content=description)
|
|
106
|
+
solara.Meta(name="twitter:description", content=description)
|
|
104
107
|
solara.Meta(property="og:title", content="Solara documentation")
|
|
108
|
+
solara.Meta(name="twitter:title", content="Solara documentation")
|
|
105
109
|
|
|
106
110
|
with rv.Row(class_="ma-2"):
|
|
107
111
|
with rv.Col(md=4, offset_md=2, sm=5, offset_sm=1):
|
|
@@ -5,18 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
from typing import Any, Dict, Optional, cast
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import plotly
|
|
9
9
|
|
|
10
|
-
try:
|
|
11
|
-
import vaex
|
|
12
|
-
except ImportError:
|
|
13
|
-
vaex = None
|
|
14
10
|
import solara
|
|
11
|
+
from solara.website.utils import apidoc
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
df = vaex.datasets.titanic()
|
|
18
|
-
else:
|
|
19
|
-
df = None
|
|
13
|
+
df = plotly.data.iris()
|
|
20
14
|
|
|
21
15
|
|
|
22
16
|
@solara.component
|
|
@@ -32,21 +26,19 @@ def Page():
|
|
|
32
26
|
|
|
33
27
|
column_actions = [solara.ColumnAction(icon="mdi-sunglasses", name="User column action", on_click=on_action_column)]
|
|
34
28
|
cell_actions = [solara.CellAction(icon="mdi-white-balance-sunny", name="User cell action", on_click=on_action_cell)]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## Demo
|
|
29
|
+
solara.MarkdownIt(
|
|
30
|
+
f"""
|
|
31
|
+
## Demo
|
|
39
32
|
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
Below we show display the titanic dataset, and demonstrate a user colum and cell action. Try clicking on the triple icon when hovering
|
|
34
|
+
above a column or cell. And see the following values changes:
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
* Column action on: `{column}`
|
|
37
|
+
* Cell action on: `{cell}`
|
|
45
38
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return main
|
|
39
|
+
"""
|
|
40
|
+
)
|
|
41
|
+
solara.DataFrame(df, column_actions=column_actions, cell_actions=cell_actions)
|
|
50
42
|
|
|
51
43
|
|
|
52
44
|
__doc__ += apidoc(solara.DataFrame.f) # type: ignore
|
|
@@ -34,6 +34,13 @@ def Page():
|
|
|
34
34
|
outlined=outlined,
|
|
35
35
|
icon=icon,
|
|
36
36
|
)
|
|
37
|
+
solara.Warning(
|
|
38
|
+
f"This is solara.Warning(label='...', text={text}, dense={dense}, outlined={outlined}, icon={icon})",
|
|
39
|
+
text=text,
|
|
40
|
+
dense=dense,
|
|
41
|
+
outlined=outlined,
|
|
42
|
+
icon=icon,
|
|
43
|
+
)
|
|
37
44
|
return main
|
|
38
45
|
|
|
39
46
|
|
solara/widgets/widgets.py
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import dataclasses
|
|
2
1
|
import os
|
|
3
2
|
|
|
4
3
|
import ipyvuetify as v
|
|
5
4
|
import ipywidgets
|
|
6
5
|
import traitlets
|
|
7
6
|
|
|
8
|
-
from ..datatypes import CellAction, ColumnAction
|
|
9
|
-
|
|
10
7
|
__all__ = [
|
|
11
|
-
"DataTable",
|
|
12
8
|
"VegaLite",
|
|
13
9
|
"Navigator",
|
|
14
10
|
"GridLayout",
|
|
@@ -17,59 +13,6 @@ __all__ = [
|
|
|
17
13
|
]
|
|
18
14
|
|
|
19
15
|
|
|
20
|
-
def _ensure_dict(d):
|
|
21
|
-
if dataclasses.is_dataclass(d):
|
|
22
|
-
return dataclasses.asdict(d)
|
|
23
|
-
return d
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _drop_keys_from_list_of_mappings(drop):
|
|
27
|
-
def closure(list_of_dicts, widget):
|
|
28
|
-
return [{k: v for k, v in _ensure_dict(d).items() if k not in drop} for d in list_of_dicts]
|
|
29
|
-
|
|
30
|
-
return closure
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class DataTable(v.VuetifyTemplate):
|
|
34
|
-
template_file = os.path.realpath(os.path.join(os.path.dirname(__file__), "vue/datatable.vue"))
|
|
35
|
-
|
|
36
|
-
total_length = traitlets.CInt().tag(sync=True)
|
|
37
|
-
checked = traitlets.List([]).tag(sync=True) # indices of which rows are selected
|
|
38
|
-
column_actions = traitlets.List(trait=traitlets.Instance(ColumnAction), default_value=[]).tag(
|
|
39
|
-
sync=True, to_json=_drop_keys_from_list_of_mappings(["on_click"])
|
|
40
|
-
)
|
|
41
|
-
_column_actions_callbacks = traitlets.List(trait=traitlets.Callable(), default_value=[])
|
|
42
|
-
cell_actions = traitlets.List(trait=traitlets.Instance(CellAction), default_value=[]).tag(sync=True, to_json=_drop_keys_from_list_of_mappings(["on_click"]))
|
|
43
|
-
_cell_actions_callbacks = traitlets.List(trait=traitlets.Callable(), default_value=[])
|
|
44
|
-
items = traitlets.Any().tag(sync=True) # the data, a list of dict
|
|
45
|
-
headers = traitlets.Any().tag(sync=True)
|
|
46
|
-
headers_selections = traitlets.Any().tag(sync=True)
|
|
47
|
-
options = traitlets.Any().tag(sync=True)
|
|
48
|
-
items_per_page = traitlets.CInt(11).tag(sync=True)
|
|
49
|
-
selections = traitlets.Any([]).tag(sync=True)
|
|
50
|
-
selection_colors = traitlets.Any([]).tag(sync=True)
|
|
51
|
-
selection_enabled = traitlets.Bool(True).tag(sync=True)
|
|
52
|
-
highlighted = traitlets.Int(None, allow_none=True).tag(sync=True)
|
|
53
|
-
scrollable = traitlets.Bool(False).tag(sync=True)
|
|
54
|
-
|
|
55
|
-
# for use with scrollable, when used in the default UI
|
|
56
|
-
height = traitlets.Unicode(None, allow_none=True).tag(sync=True)
|
|
57
|
-
|
|
58
|
-
hidden_components = traitlets.List([]).tag(sync=False)
|
|
59
|
-
|
|
60
|
-
def vue_on_column_action(self, data):
|
|
61
|
-
header_value, action_index = data
|
|
62
|
-
on_click = self._column_actions_callbacks[action_index]
|
|
63
|
-
if on_click:
|
|
64
|
-
on_click(header_value)
|
|
65
|
-
|
|
66
|
-
def vue_on_cell_action(self, data):
|
|
67
|
-
row, header_value, action_index = data
|
|
68
|
-
on_click = self._cell_actions_callbacks[action_index]
|
|
69
|
-
if on_click:
|
|
70
|
-
on_click(header_value, row)
|
|
71
|
-
|
|
72
|
-
|
|
73
16
|
class VegaLite(v.VuetifyTemplate):
|
|
74
17
|
template_file = os.path.realpath(os.path.join(os.path.dirname(__file__), "vue/vegalite.vue"))
|
|
75
18
|
spec = traitlets.Dict().tag(sync=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: solara
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Build webapps using IPywidgets
|
|
5
5
|
Author-email: "Maarten A. Breddels" <maartenbreddels@gmail.com>
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -33,7 +33,7 @@ Requires-Dist: jupyter_client>=7.0.0
|
|
|
33
33
|
Requires-Dist: watchdog
|
|
34
34
|
Requires-Dist: requests
|
|
35
35
|
Requires-Dist: pygments==2.10; python_version < '3.7'
|
|
36
|
-
Requires-Dist: solara-assets==1.
|
|
36
|
+
Requires-Dist: solara-assets==1.7.0 ; extra == "assets"
|
|
37
37
|
Requires-Dist: flake8 ; extra == "dev"
|
|
38
38
|
Requires-Dist: bqplot ; extra == "dev"
|
|
39
39
|
Requires-Dist: bqplot-image-gl ; extra == "dev"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
solara/__init__.py,sha256=
|
|
1
|
+
solara/__init__.py,sha256=O_Pl62uZgKDjJ9gmMfgS2Od0EowPjjINmSmX2bxWrRg,3091
|
|
2
2
|
solara/__main__.py,sha256=ztXaMuWiQdyc4hEmws7ABy-E-CuaRkKhiArMP72M7ak,21260
|
|
3
3
|
solara/alias.py,sha256=9vfLzud77NP8in3OID9b5mmIO8NyrnFjN2_aE0lSb1k,216
|
|
4
|
-
solara/autorouting.py,sha256=
|
|
4
|
+
solara/autorouting.py,sha256=njdkEoJMSAPJlG1R2sj3c9aFfzi0tqIF5t4oVm7OYYw,17763
|
|
5
5
|
solara/cache.py,sha256=lEXpHBCV4iEI4O9K-5MYhitMKtbMU-XSlx--6sB7Ptg,10743
|
|
6
6
|
solara/checks.html,sha256=nYlcFNbqTdzpr0eaFxuu_-sXTC8nXJn0hGGfemzl2jQ,3254
|
|
7
|
-
solara/checks.py,sha256=
|
|
7
|
+
solara/checks.py,sha256=brNdeZFlMKk8wMCjTjJWqZ9nT1X42d8cR7BeBOnXmRs,4003
|
|
8
8
|
solara/datatypes.py,sha256=5l0npGj0Rlv9w5PdqPacMSNMVpbmBpkWtjXet_h8Ecw,4150
|
|
9
9
|
solara/express.py,sha256=dW1uq74Lyf8DomnaeGtIg9OmFy8tRkv7uYHCIvnDat0,6781
|
|
10
10
|
solara/kitchensink.py,sha256=RUx3kW6CQAz9PMxB1sPI03IH5xJfsaaXq3w9bBuC6rg,249
|
|
@@ -15,15 +15,16 @@ solara/settings.py,sha256=558Ry_35nyw8xpe1b_sVBGXnilXktAF9AIFhOjJW2C4,1120
|
|
|
15
15
|
solara/util.py,sha256=jgKkxEG-l-60GdpmTTJ_aCEdV-PGyzdwwwuz4hcoY8M,3834
|
|
16
16
|
solara/components/__init__.py,sha256=AfrQ6mD3-8iU7L07Lx_mtphmAxCK6SGdMBet9seHHBs,2288
|
|
17
17
|
solara/components/alert.py,sha256=REo6uSv8ffyU85h-_ZQvhKfyzi_f6IlzQDoNcNfAkjM,4639
|
|
18
|
-
solara/components/applayout.py,sha256=
|
|
18
|
+
solara/components/applayout.py,sha256=Lr4TD8yuHMJhjVjLLmmjblzRiNIDZZNfXkEZUzyk-KA,12983
|
|
19
19
|
solara/components/button.py,sha256=b7TK8_xE1hPPgUbw3pW0B__Lfio1AlNn3KVwGnU8d6o,1791
|
|
20
20
|
solara/components/checkbox.py,sha256=zzp0N4DP3_6qQmhkiGtY_rJsfIKK1zryOIGszOCSlI8,890
|
|
21
21
|
solara/components/code_highlight_css.py,sha256=J0fZHuEu8jeEKAq_HKbzgiMR1-VwMVnKA4dAOKE0AQU,235
|
|
22
22
|
solara/components/code_highlight_css.vue,sha256=UX4jtEetV1W25Uvu8xQ-TbEaBzbp_7DlXtXDO9SdZfY,5776
|
|
23
23
|
solara/components/columns.py,sha256=U3b5-XkVla_2A7MMGmVOUVMUCwGoNlhBaWYXFOVpNio,4698
|
|
24
|
-
solara/components/cross_filter.py,sha256=
|
|
24
|
+
solara/components/cross_filter.py,sha256=_PaPtAkqFa714SnFjo5_jVpzG4nQ_0S2F5JBRREKe8o,13473
|
|
25
25
|
solara/components/dataframe.py,sha256=9k4h3wvUjv4JrlfQQCzfCHDc_OLF8D7MOH1r3jX24i0,21030
|
|
26
|
-
solara/components/datatable.py,sha256=
|
|
26
|
+
solara/components/datatable.py,sha256=uKXAEfoHLISQmAgzlLjPCCcnH-4ZlEKwV7B9C8Ni94A,7869
|
|
27
|
+
solara/components/datatable.vue,sha256=xoIT7tS2QSKgJHt0kHRODsDx81S9SEwk1EoVM9sgFWg,7061
|
|
27
28
|
solara/components/details.py,sha256=x8wB4fCsO0TwACnidW0q-tUcPByC7SqurU50Yz_YTJU,675
|
|
28
29
|
solara/components/download.vue,sha256=xdh4olwVvGkQwGNRMU5eVUW1FGvcXrYrCyjddJbvH7E,1069
|
|
29
30
|
solara/components/echarts.py,sha256=JP4PbcOtqr7uoto0XBrFNZzNGcsbn_1LXCslwdEcghU,2589
|
|
@@ -92,7 +93,7 @@ solara/server/assets/custom.css,sha256=4p04-uxHTobfr6Xkvf1iOrYiks8NciWLT_EwHZSy6
|
|
|
92
93
|
solara/server/assets/custom.js,sha256=YT-UUYzA5uI5-enmbIsrRhofY_IJAO-HanaMwiNUEos,16
|
|
93
94
|
solara/server/assets/favicon.png,sha256=Ssgmi5eZeGIGABOrxW8AH3hyvy5a9avdDIDYsmEUMpM,1924
|
|
94
95
|
solara/server/assets/favicon.svg,sha256=HXAji-JQGBaGi2_iyk3vHgEDgdFYtsWTVqOE6QmVLKc,1240
|
|
95
|
-
solara/server/assets/style.css,sha256=
|
|
96
|
+
solara/server/assets/style.css,sha256=cgjSWYuQpNYXcpQAH00h_HItF3d9lBuAgzPE254TBkU,1810
|
|
96
97
|
solara/server/assets/theme.js,sha256=kwXC-5gj9JKcwb8JMaV2sZ5t_F26c6ypqfozLZZ8Izo,21
|
|
97
98
|
solara/server/jupyter/__init__.py,sha256=OF6ZXyQUymQzx70eDytS3aU-NDDsltwi1pJIKy6mUcE,137
|
|
98
99
|
solara/server/jupyter/cdn_handler.py,sha256=L9i_Hv9BFfrLwxq76lKhhxAv_EJzNecgIlb1wvkCHf8,835
|
|
@@ -102,7 +103,7 @@ solara/server/static/highlight-dark.css,sha256=gmC3pr3x2BqJgTswNoN6AkqfEhBk24hPF
|
|
|
102
103
|
solara/server/static/highlight.css,sha256=k8ZdT5iwrGQ5tXTQHAXuxvZrSUq3kwCdEpy3mlFoZjs,2637
|
|
103
104
|
solara/server/static/main-vuetify.js,sha256=-twJ3DaObXPToFk-s4guHtXrMtlrtFUVhnAuOSSHFbk,7981
|
|
104
105
|
solara/server/static/main.js,sha256=mcx4JNQ4Lg4pNdUIqMoZos1mZyYFS48yd_JNFFJUqIE,5679
|
|
105
|
-
solara/server/static/solara_bootstrap.py,sha256=
|
|
106
|
+
solara/server/static/solara_bootstrap.py,sha256=v0ygQ0hQaGPx20ZFm1-1qY7EcuBsu501oP-hXlaMsQ0,3194
|
|
106
107
|
solara/server/static/sun.svg,sha256=jEKBAGCr7b9zNYv0VUb7lMWKjnU2dX69_Ye_DZWGXJI,6855
|
|
107
108
|
solara/server/static/webworker.js,sha256=cjAFz7-SygStHJnYlJUlJs-gE_7YQeQ-WBDcmKYyjvo,1372
|
|
108
109
|
solara/server/templates/index.html.j2,sha256=JXQo1M-STFHLBOFetgG7509cAq8xUP0VAEtYDzz35fY,31
|
|
@@ -136,7 +137,7 @@ solara/template/portal/solara_portal/pages/viz/__init__.py,sha256=kp0rNqphYDWwVf
|
|
|
136
137
|
solara/template/portal/solara_portal/pages/viz/overview.py,sha256=GPlzFxUR0LRQhR96a_CVWquGTjHhDehL1PR03Tcm3gs,365
|
|
137
138
|
solara/website/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
139
|
solara/website/utils.py,sha256=TfoExocZ8ko2hTcA7XDKI5FfKZ4gi3JTc_f9Oi5L7Fs,855
|
|
139
|
-
solara/website/assets/custom.css,sha256=
|
|
140
|
+
solara/website/assets/custom.css,sha256=08jHPRHNdnLrirdUygraGNREOcrE-Riv0ioWtOGQ1OE,4523
|
|
140
141
|
solara/website/assets/theme.js,sha256=8OUdIaPI3BG4WiIFZhRyXDJumMvdL9LPy1KhDmMeV9A,67
|
|
141
142
|
solara/website/assets/images/logo-small.png,sha256=mCYtNOyEPoeAFm20Hkm6JJ2Rv1fncVyeXrLdqb1rYi0,86383
|
|
142
143
|
solara/website/assets/images/logo.svg,sha256=mKyJWZ2cx0PhslMn4wjkyFTrHbulwJiVQPyL-F1-WWg,4858
|
|
@@ -144,7 +145,7 @@ solara/website/components/__init__.py,sha256=FeSyrGA04nx58CnUue7u60Pb2c9UlBYqYrK
|
|
|
144
145
|
solara/website/components/header.py,sha256=z4R4IOUsNkQMdjuLNXogeqIMlEfd-wW-WV8TnRIeJbg,1940
|
|
145
146
|
solara/website/components/hero.py,sha256=IsidQOb01jaD7VPARJwKaehxIjoWEwznNlaQCifWvmA,670
|
|
146
147
|
solara/website/pages/README.md,sha256=thMtiNPvhesbT8bLMurbi5Kbu72_kLY7MweQfxpDpTk,1192
|
|
147
|
-
solara/website/pages/__init__.py,sha256=
|
|
148
|
+
solara/website/pages/__init__.py,sha256=D4dFMCi-Ub2tAfun-G7bPjYaMr3wuoR6sJH8dtIArlc,11388
|
|
148
149
|
solara/website/pages/doc_use_download.py,sha256=Wewj7CLhU4IXNmwYNUK0ufEWkoqiGhbARTsZF9dRL6Y,3131
|
|
149
150
|
solara/website/pages/docutils.py,sha256=aN8ohcr0upT4_Gr_IuqiG9dNBUMawCDp2g4EPxqCBgM,742
|
|
150
151
|
solara/website/pages/api/__init__.py,sha256=6yqt8BW7Yy-Bct1RxRkN_YpARLyhwPyWclz5MnkHlUc,7876
|
|
@@ -161,7 +162,7 @@ solara/website/pages/api/cross_filter_dataframe.py,sha256=ouPRh8Monv_tawnJn-fJoY
|
|
|
161
162
|
solara/website/pages/api/cross_filter_report.py,sha256=2iiSTOsyNhl0qsRs0TzpP9jgnLDWQi5ymP9Q9GvZVto,485
|
|
162
163
|
solara/website/pages/api/cross_filter_select.py,sha256=bXxXOi8aLi-6VX6JYnKFHIywTil0Ua1ADjrYhaN03rY,461
|
|
163
164
|
solara/website/pages/api/cross_filter_slider.py,sha256=AShpfouYjb_N8RNL1wk3vXfplrq1d5U6yb1Nevr7QRE,491
|
|
164
|
-
solara/website/pages/api/dataframe.py,sha256=
|
|
165
|
+
solara/website/pages/api/dataframe.py,sha256=BHukqtQU6vNMYdDAdUakXJfaPgpIUVWPbYI9bdAVseE,1229
|
|
165
166
|
solara/website/pages/api/default_layout.py,sha256=-OaezKcSSdjHFMNlo1d65yDftsRLx7NwdRt5sddSna0,355
|
|
166
167
|
solara/website/pages/api/display.py,sha256=HpKxJ2_wN5Uft-vmpcXd0iiDg66bJBIMP1CajSLQunA,182
|
|
167
168
|
solara/website/pages/api/echarts.py,sha256=4JWNB-V3BFPD5fK38xwWVguc04ZdsgNjF6VJMfMqK4Y,2595
|
|
@@ -208,7 +209,7 @@ solara/website/pages/api/use_state_or_update.py,sha256=xG4qAzsbW0OP2OZw-q4cUX0wb
|
|
|
208
209
|
solara/website/pages/api/use_thread.md,sha256=lSeBPZtI3qSR7qEweefqxi37v_5_OsdYfo50P8mYbak,2251
|
|
209
210
|
solara/website/pages/api/use_thread.py,sha256=MYB7qoz3-u1b2krBgoRJiv_kD26tcVeeKzts29XHdTE,1473
|
|
210
211
|
solara/website/pages/api/vbox.py,sha256=pLKfhiMe71F9DYN21IkJ099GzNOe5U8AI2U-zQ9wtA4,348
|
|
211
|
-
solara/website/pages/api/warning.py,sha256=
|
|
212
|
+
solara/website/pages/api/warning.py,sha256=0KHwASH-_-qnMqLEwkHZRC0x3DejmpSG_NflxaEkVMk,1385
|
|
212
213
|
solara/website/pages/api/widget.py,sha256=DIfyIGWgV-Gidl9ClWNEqd5C9wPiSHDb9CcuZvnaMOw,2744
|
|
213
214
|
solara/website/pages/apps/__init__.py,sha256=lBJiio7_EjEbMoDxkKPdzyJcPcuBzuD3AwcRo-6DZm4,189
|
|
214
215
|
solara/website/pages/apps/layout-demo.py,sha256=tcmqY7ILpfulWDEcO3VZIMYYV-FECP_GUX_T3wshHRk,1675
|
|
@@ -285,16 +286,15 @@ solara/website/public/landing/python-love-react.png,sha256=lCNC1IIRSVSV7SJAOWg0S
|
|
|
285
286
|
solara/website/public/landing/what.png,sha256=gy4vnO_fnPZs9Ie6wBh0YSyOL3ggvBQNxaqFOArx36o,591427
|
|
286
287
|
solara/website/templates/index.html.j2,sha256=aW27n_enOp2BSFvnuExjmNAicZ5Ywhysz1xQMt4QVuM,1470
|
|
287
288
|
solara/widgets/__init__.py,sha256=D3RfEez9dllmst64_nyzzII-NZXoNMEPDnEog4ov3VE,43
|
|
288
|
-
solara/widgets/widgets.py,sha256=
|
|
289
|
-
solara/widgets/vue/datatable.vue,sha256=EksXC8FH8Rm5lLnddRJhHFiWM3Zx17FiWGDBnbs9oEs,6138
|
|
289
|
+
solara/widgets/widgets.py,sha256=dZNRxJp1JRh3S5HRUR3FnN_dsYX45139kf5kEJiJ98Q,1894
|
|
290
290
|
solara/widgets/vue/gridlayout.vue,sha256=EGeq8RmdRSd8AD2Us6L80zGFefh7TaQqJSnazX7YyDw,3559
|
|
291
291
|
solara/widgets/vue/html.vue,sha256=9vaHrddQU1J9zgnhy0W1-YXJ0JH68fet1rDEHoe539Q,404
|
|
292
292
|
solara/widgets/vue/navigator.vue,sha256=JIC8y329MBZrMV1SEVjr7nH025dkQod0ESK6ss8EUDk,3120
|
|
293
293
|
solara/widgets/vue/vegalite.vue,sha256=Dr4i6fXayDxdo8FqByTlJshQSQ6vawecDq7AHZL93TI,3231
|
|
294
|
-
solara-1.
|
|
295
|
-
solara-1.
|
|
296
|
-
solara-1.
|
|
297
|
-
solara-1.
|
|
298
|
-
solara-1.
|
|
299
|
-
solara-1.
|
|
300
|
-
solara-1.
|
|
294
|
+
solara-1.7.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json,sha256=3UhTBQi6z7F7pPjmqXxfddv79c8VGR9H7zStDLp6AwY,115
|
|
295
|
+
solara-1.7.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json,sha256=D9J-rYxAzyD5GOqWvuPjacGUVFHsYtTfZ4FUbRzRvIA,113
|
|
296
|
+
solara-1.7.0.dist-info/entry_points.txt,sha256=AXTWXiaLDBs0LuR81mrek-v6m8xU1J7JYgc-Ob40OoU,47
|
|
297
|
+
solara-1.7.0.dist-info/LICENSE,sha256=fFJUz-CWzZ9nEc4QZKu44jMEoDr5fEW-SiqljKpD82E,1086
|
|
298
|
+
solara-1.7.0.dist-info/WHEEL,sha256=kdeDBNPvBI0w3meLKPoGgAnEr54n1jzrZWUoaLmGzVY,99
|
|
299
|
+
solara-1.7.0.dist-info/METADATA,sha256=zWsa_AKwSlFY1eavg7o0e-nMO3R552WlDv_RC__l8t8,2754
|
|
300
|
+
solara-1.7.0.dist-info/RECORD,,
|
solara/widgets/vue/datatable.vue
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-slide-x-transition appear>
|
|
3
|
-
<div class="solara-data-table__viewport">
|
|
4
|
-
<v-data-table
|
|
5
|
-
dense
|
|
6
|
-
hide-default-header
|
|
7
|
-
:headers="[...headers]"
|
|
8
|
-
:items="items"
|
|
9
|
-
:footer-props="{ 'items-per-page-options': [10, 20, 50, 100] }"
|
|
10
|
-
:options.sync="options"
|
|
11
|
-
:items_per_page.sync="items_per_page"
|
|
12
|
-
:server-items-length="total_length"
|
|
13
|
-
:class="[
|
|
14
|
-
'elevation-1',
|
|
15
|
-
'solara-data-table',
|
|
16
|
-
scrollable && 'solara-data-table--scrollable',
|
|
17
|
-
]"
|
|
18
|
-
:style="scrollable && height != null && `height: ${height}`"
|
|
19
|
-
>
|
|
20
|
-
<template v-slot:header="props">
|
|
21
|
-
<thead>
|
|
22
|
-
<tr>
|
|
23
|
-
<th style="padding: 0 10px; width: 40px">#</th>
|
|
24
|
-
<th style="padding: 0 1px; width: 30px" v-if="selection_enabled">
|
|
25
|
-
<v-btn icon color="primary" text small @click="apply_filter">
|
|
26
|
-
<v-icon>filter_list</v-icon>
|
|
27
|
-
</v-btn>
|
|
28
|
-
</th>
|
|
29
|
-
<th
|
|
30
|
-
style="padding: 0 1px"
|
|
31
|
-
v-for="(header, index) in headers_selections"
|
|
32
|
-
:key="header.text"
|
|
33
|
-
>
|
|
34
|
-
<v-icon style="padding: 0 1px" :key="index" :color="selection_colors[index]"
|
|
35
|
-
>brightness_1</v-icon
|
|
36
|
-
>
|
|
37
|
-
</th>
|
|
38
|
-
<v-slide-x-transition :key="header.text" v-for="header in headers">
|
|
39
|
-
<th class="text-no-wrap">
|
|
40
|
-
{{ header.text }}
|
|
41
|
-
<v-menu open-on-hover bottom offset-y v-if="column_actions.length">
|
|
42
|
-
<template v-slot:activator="{ on, attrs }">
|
|
43
|
-
<v-icon v-bind="attrs" v-on="on" small class="solara-data-table-menu">mdi-dots-vertical</v-icon>
|
|
44
|
-
</template>
|
|
45
|
-
<v-list v-for="(action, index) in column_actions" :key="index">
|
|
46
|
-
<v-list-item link @click="on_column_action([header.value, index])">
|
|
47
|
-
<v-list-item-icon><v-icon>{{action.icon}}</v-icon></v-list-item-icon>
|
|
48
|
-
<v-list-item-title>{{action.name}}</v-list-item-title>
|
|
49
|
-
</v-list-item>
|
|
50
|
-
</v-list>
|
|
51
|
-
</v-menu>
|
|
52
|
-
</th>
|
|
53
|
-
</v-slide-x-transition>
|
|
54
|
-
</tr>
|
|
55
|
-
</thead>
|
|
56
|
-
</template>
|
|
57
|
-
<template v-slot:item="props">
|
|
58
|
-
<!-- @click="on_row_clicked(props.item.__row__)" -->
|
|
59
|
-
<tr
|
|
60
|
-
:class="{ highlightedRow: props.item.__row__ === highlighted }"
|
|
61
|
-
>
|
|
62
|
-
<td style="padding: 0 10px" class="text-xs-left">
|
|
63
|
-
<i>{{ props.item.__row__ }}</i>
|
|
64
|
-
</td>
|
|
65
|
-
<td style="padding: 0 1px" class="text-xs-left" v-if="selection_enabled">
|
|
66
|
-
<v-checkbox
|
|
67
|
-
hide-details
|
|
68
|
-
style="margin-top: 0; padding-top: 0"
|
|
69
|
-
:input-value="checked.indexOf(props.item.__row__) != -1"
|
|
70
|
-
:key="props.item.__row__"
|
|
71
|
-
@change="(value) => select({ checked: value, row: props.item.__row__ })"
|
|
72
|
-
/>
|
|
73
|
-
</td>
|
|
74
|
-
<td
|
|
75
|
-
style="padding: 0 1px"
|
|
76
|
-
:key="header.text"
|
|
77
|
-
v-for="(header, index) in headers_selections"
|
|
78
|
-
>
|
|
79
|
-
<v-fade-transition leave-absolute>
|
|
80
|
-
<v-icon
|
|
81
|
-
v-if="props.item[header.value]"
|
|
82
|
-
v-model="props.item[header.value]"
|
|
83
|
-
:color="selection_colors[index]"
|
|
84
|
-
>brightness_1</v-icon
|
|
85
|
-
>
|
|
86
|
-
</v-fade-transition>
|
|
87
|
-
</td>
|
|
88
|
-
<td
|
|
89
|
-
v-for="header in headers"
|
|
90
|
-
class="text-truncate text-no-wrap"
|
|
91
|
-
:key="header.text"
|
|
92
|
-
:title="props.item[header.value]"
|
|
93
|
-
>
|
|
94
|
-
<v-slide-x-transition appear>
|
|
95
|
-
<!-- <span @click="on_item_click([props.item.__row__, header.value])">{{ props.item[header.value] }}</span> -->
|
|
96
|
-
<span>
|
|
97
|
-
{{ props.item[header.value] }}
|
|
98
|
-
<v-menu open-on-hover bottom offset-y v-if="cell_actions.length">
|
|
99
|
-
<template v-slot:activator="{ on, attrs }">
|
|
100
|
-
<v-icon v-bind="attrs" v-on="on" small class="solara-data-table-menu">mdi-dots-vertical</v-icon>
|
|
101
|
-
</template>
|
|
102
|
-
<v-list v-for="(action, index) in cell_actions" :key="index">
|
|
103
|
-
<v-list-item link @click="on_cell_action([props.item.__row__, header.value, index])">
|
|
104
|
-
<v-list-item-icon><v-icon>{{action.icon}}</v-icon></v-list-item-icon>
|
|
105
|
-
<v-list-item-title>{{action.name}}</v-list-item-title>
|
|
106
|
-
</v-list-item>
|
|
107
|
-
</v-list>
|
|
108
|
-
</v-menu>
|
|
109
|
-
</span>
|
|
110
|
-
|
|
111
|
-
</v-slide-x-transition>
|
|
112
|
-
</td>
|
|
113
|
-
</tr>
|
|
114
|
-
</template>
|
|
115
|
-
</v-data-table>
|
|
116
|
-
</div>
|
|
117
|
-
</v-slide-x-transition>
|
|
118
|
-
</template>
|
|
119
|
-
|
|
120
|
-
<style id="solara_table">
|
|
121
|
-
.highlightedRow {
|
|
122
|
-
background-color: #e3f2fd;
|
|
123
|
-
}
|
|
124
|
-
.solara-data-table table {
|
|
125
|
-
table-layout: fixed;
|
|
126
|
-
}
|
|
127
|
-
.solara-data-table--scrollable .v-data-table__wrapper {
|
|
128
|
-
overflow-y: auto;
|
|
129
|
-
height: calc(100% - 59px);
|
|
130
|
-
}
|
|
131
|
-
.solara-data-table--scrollable thead > tr {
|
|
132
|
-
position: sticky;
|
|
133
|
-
top: 0;
|
|
134
|
-
}
|
|
135
|
-
.solara-data-table--scrollable .v-data-table__wrapper,
|
|
136
|
-
.solara-data-table--scrollable .v-data-table__wrapper > table,
|
|
137
|
-
.solara-data-table--scrollable .v-data-table__wrapper > table thead,
|
|
138
|
-
.solara-data-table--scrollable .v-data-table__wrapper > table thead * {
|
|
139
|
-
background-color: inherit;
|
|
140
|
-
}
|
|
141
|
-
/* prevent checkboxes overlaying the table header */
|
|
142
|
-
.solara-data-table--scrollable .v-data-table__wrapper > table thead {
|
|
143
|
-
position: relative;
|
|
144
|
-
z-index: 1;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.solara-data-table.v-data-table th,
|
|
148
|
-
.solara-data-table.v-data-table td {
|
|
149
|
-
padding-left: 4px;
|
|
150
|
-
padding-right: 0;
|
|
151
|
-
}
|
|
152
|
-
.v-data-table .solara-data-table-menu {
|
|
153
|
-
opacity: 0;
|
|
154
|
-
transition: opacity 0.5s;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.v-data-table th:hover .solara-data-table-menu,
|
|
158
|
-
.v-data-table td:hover .solara-data-table-menu {
|
|
159
|
-
opacity: 1;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.solara-data-table__viewport {
|
|
163
|
-
overflow-x: auto;
|
|
164
|
-
width: 100%;
|
|
165
|
-
max-height: 100%;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
.solara-data-table.v-data-table,
|
|
169
|
-
.solara-data-table.v-data-table table {
|
|
170
|
-
max-width: unset;
|
|
171
|
-
width: unset;
|
|
172
|
-
}
|
|
173
|
-
</style>
|
{solara-1.6.0.data → solara-1.7.0.data}/data/etc/jupyter/jupyter_notebook_config.d/solara.json
RENAMED
|
File without changes
|
{solara-1.6.0.data → solara-1.7.0.data}/data/etc/jupyter/jupyter_server_config.d/solara.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|