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 CHANGED
@@ -1,5 +1,5 @@
1
1
  """Build webapps using IPywidgets"""
2
- __version__ = "1.6.0"
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
- raise KeyError(f"Some routes are not in route_order: {set(lookup) - set(route_order)}")
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-vuetify2"},
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
 
@@ -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)
@@ -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
- from ..widgets import DataTable as DataTableWidget
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(df, page=0, items_per_page=20, format=None, column_actions: List[ColumnAction] = [], cell_actions: List[CellAction] = [], scrollable=False):
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(df, column_actions: List[ColumnAction] = [], cell_actions: List[CellAction] = []):
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(df, column_actions=column_actions, cell_actions=cell_actions)
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>
@@ -88,3 +88,8 @@ div.highlight {
88
88
  .solara-image {
89
89
  cursor: unset !important;
90
90
  }
91
+
92
+
93
+ .jp-OutputArea-prompt {
94
+ display: none;
95
+ }
@@ -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.6.0-py2.py3-none-any.whl", keep_going=True)
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")
@@ -38,7 +38,6 @@ a:link {
38
38
  color: var(--color-primary);
39
39
  }
40
40
 
41
- pre,
42
41
  .jp-RenderedHTMLCommon pre {
43
42
  background-color: var(--color-grey-light);
44
43
  display: block;
@@ -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(property="twitter:site", content="@solara_dev" + router.path)
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
- from solara.website.utils import apidoc
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
- if vaex is not None:
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
- with solara.Div() as main:
36
- solara.MarkdownIt(
37
- f"""
38
- ## Demo
29
+ solara.MarkdownIt(
30
+ f"""
31
+ ## Demo
39
32
 
40
- Below we show display the titanic dataset, and demonstrate a user colum and cell action. Try clicking on the triple icon when hovering
41
- above a column or cell. And see the following values changes:
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
- * Column action on: `{column}`
44
- * Cell action on: `{cell}`
36
+ * Column action on: `{column}`
37
+ * Cell action on: `{cell}`
45
38
 
46
- """
47
- )
48
- solara.DataFrame(df, column_actions=column_actions, cell_actions=cell_actions)
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.6.0
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.6.0 ; extra == "assets"
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=nnBE3efYg_LR2H9VZ36QQq_Uf16D0h_zCYLig-8vh0g,3038
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=qIP6nkg2Xo-zuWNebuUgajtTUuD971ZB-tnst3aurMU,17748
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=KYMM79y0G0hGmvLS0wi9N1AyheJFI5WijwNmk6ypxiw,4004
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=YQayveky1pPRPS3leC1IaSqWaoxPjQIa7hD6KZ3fKsA,12966
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=OexJKt9BDeHXWBN4nz6zOiNL56F3H2xSh-YXrgpGZNw,13324
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=l7zHlEE4JPhlgLg22lekwc1mVPrhayRDI5fz-mXa1E0,3085
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=p_FBP-NPGRsJOD_xq8HdnFsKW1TXHB1i9KrXKIl5bAQ,1763
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=rAOY_3o9hK8tcWG8j5CH9csARsYLlpr52O3ieUgBDZI,3194
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=tbjPwVtTLHV87HJQPHmN3e8r8eM22xerXi5bEHxbqV0,4528
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=xWnm7Z66dPtzudpSANdcSmnp7gT0d-W4nd0WSS5FhPA,11067
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=cttSnbPz3sHAn9URERZpMq5fw6hRvy8X1Cu5q8kWN7g,1409
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=q16ICDIAil38HyY1_Ae574CO5hW-Atlx9fbaVZfeVac,1135
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=zHThfUd_Ps30S94opVx5Ln8gQcbCzUoSWQghP6427BM,4261
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.6.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json,sha256=3UhTBQi6z7F7pPjmqXxfddv79c8VGR9H7zStDLp6AwY,115
295
- solara-1.6.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json,sha256=D9J-rYxAzyD5GOqWvuPjacGUVFHsYtTfZ4FUbRzRvIA,113
296
- solara-1.6.0.dist-info/entry_points.txt,sha256=AXTWXiaLDBs0LuR81mrek-v6m8xU1J7JYgc-Ob40OoU,47
297
- solara-1.6.0.dist-info/LICENSE,sha256=fFJUz-CWzZ9nEc4QZKu44jMEoDr5fEW-SiqljKpD82E,1086
298
- solara-1.6.0.dist-info/WHEEL,sha256=kdeDBNPvBI0w3meLKPoGgAnEr54n1jzrZWUoaLmGzVY,99
299
- solara-1.6.0.dist-info/METADATA,sha256=JnGGbr_CinyGJaUimwc_4P4ZvqZA4kI6y1VXDzpA0pE,2754
300
- solara-1.6.0.dist-info/RECORD,,
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,,
@@ -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>
File without changes