dara-components 1.8.5__py3-none-any.whl → 1.22.1__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.
Files changed (92) hide show
  1. dara/components/__init__.py +18 -0
  2. dara/components/_assets/__init__.py +30 -0
  3. dara/components/_assets/auto_js/.gitkeep +0 -0
  4. dara/components/_assets/auto_js/dara.components.css +1494 -0
  5. dara/components/_assets/auto_js/dara.components.umd.js +182837 -0
  6. dara/components/_assets/common/bokeh-3.1.1.min.js +690 -0
  7. dara/components/_assets/common/bokeh-api-3.1.1.min.js +60 -0
  8. dara/components/_assets/common/bokeh-gl-3.1.1.min.js +67 -0
  9. dara/components/_assets/common/bokeh-mathjax-3.1.1.min.js +329 -0
  10. dara/components/_assets/common/bokeh-tables-3.1.1.min.js +132 -0
  11. dara/components/_assets/common/bokeh-widgets-3.1.1.min.js +129 -0
  12. dara/components/_assets/common/pixi-filters.min.js +17 -0
  13. dara/components/_assets/common/pixi.min.js +2214 -0
  14. dara/components/_assets/common/pixi_viewport.js +1 -0
  15. dara/components/_assets/common/plotly.min.js +8 -0
  16. dara/components/common/__init__.py +11 -2
  17. dara/components/common/accordion.py +20 -26
  18. dara/components/common/anchor.py +9 -10
  19. dara/components/common/base_component.py +23 -36
  20. dara/components/common/bullet_list.py +1 -3
  21. dara/components/common/button.py +35 -26
  22. dara/components/common/button_bar.py +25 -20
  23. dara/components/common/card.py +4 -5
  24. dara/components/common/carousel.py +9 -9
  25. dara/components/common/checkbox_group.py +26 -19
  26. dara/components/common/code.py +8 -5
  27. dara/components/common/component_select_list.py +9 -13
  28. dara/components/common/datepicker.py +16 -16
  29. dara/components/common/dropdown_menu.py +161 -0
  30. dara/components/common/dropzone.py +42 -33
  31. dara/components/common/form.py +5 -7
  32. dara/components/common/form_page.py +4 -6
  33. dara/components/common/grid.py +21 -18
  34. dara/components/common/heading.py +5 -4
  35. dara/components/common/icon.py +1 -3
  36. dara/components/common/if_cmp.py +23 -17
  37. dara/components/common/image.py +2 -2
  38. dara/components/common/input.py +9 -11
  39. dara/components/common/label.py +13 -14
  40. dara/components/common/markdown.py +3 -5
  41. dara/components/common/modal.py +2 -2
  42. dara/components/common/overlay.py +8 -14
  43. dara/components/common/paragraph.py +2 -2
  44. dara/components/common/progress_bar.py +6 -8
  45. dara/components/common/radio_group.py +38 -21
  46. dara/components/common/select.py +33 -30
  47. dara/components/common/slider.py +74 -29
  48. dara/components/common/spacer.py +4 -6
  49. dara/components/common/stack.py +7 -4
  50. dara/components/common/switch.py +6 -8
  51. dara/components/common/tabbed_card.py +8 -11
  52. dara/components/common/table.py +224 -73
  53. dara/components/common/text.py +7 -9
  54. dara/components/common/textarea.py +7 -7
  55. dara/components/common/time_utils.py +2 -5
  56. dara/components/common/tooltip.py +4 -6
  57. dara/components/common/utils.py +29 -35
  58. dara/components/graphs/__init__.py +1 -0
  59. dara/components/graphs/components/base_graph_component.py +34 -22
  60. dara/components/graphs/components/causal_graph_viewer.py +13 -15
  61. dara/components/graphs/components/edge_encoder.py +49 -26
  62. dara/components/graphs/components/node_hierarchy_builder.py +17 -16
  63. dara/components/graphs/definitions.py +27 -20
  64. dara/components/graphs/graph_layout.py +90 -53
  65. dara/components/plotting/__init__.py +2 -1
  66. dara/components/plotting/bokeh/bokeh.py +7 -10
  67. dara/components/plotting/bokeh/utils.py +5 -3
  68. dara/components/plotting/plotly/plotly.py +24 -19
  69. dara/components/plotting/plotly/themes.py +7 -5
  70. dara/components/smart/__init__.py +7 -1
  71. dara/components/smart/chat/chat.py +7 -8
  72. dara/components/smart/chat/config.py +1 -1
  73. dara/components/smart/chat/types.py +4 -6
  74. dara/components/smart/code_editor/code_editor.py +18 -4
  75. dara/components/smart/code_editor/util.py +11 -11
  76. dara/components/smart/data_slicer/__init__.py +4 -0
  77. dara/components/smart/data_slicer/data_slicer.py +14 -18
  78. dara/components/smart/data_slicer/data_slicer_modal.py +4 -6
  79. dara/components/smart/data_slicer/extension/data_slicer_filter.py +3 -4
  80. dara/components/smart/data_slicer/extension/filter_status_button.py +1 -3
  81. dara/components/smart/data_slicer/utils/core.py +23 -23
  82. dara/components/smart/data_slicer/utils/data_preview.py +1 -3
  83. dara/components/smart/data_slicer/utils/plotting.py +8 -6
  84. dara/components/smart/hierarchy.py +9 -10
  85. {dara_components-1.8.5.dist-info → dara_components-1.22.1.dist-info}/METADATA +7 -7
  86. dara_components-1.22.1.dist-info/RECORD +100 -0
  87. {dara_components-1.8.5.dist-info → dara_components-1.22.1.dist-info}/WHEEL +1 -1
  88. dara_components-1.22.1.dist-info/entry_points.txt +3 -0
  89. dara/components/umd/dara.components.umd.js +0 -396288
  90. dara/components/umd/style.css +0 -745
  91. dara_components-1.8.5.dist-info/RECORD +0 -86
  92. {dara_components-1.8.5.dist-info → dara_components-1.22.1.dist-info}/LICENSE +0 -0
@@ -17,9 +17,10 @@ limitations under the License.
17
17
 
18
18
  import abc
19
19
  from enum import Enum
20
- from typing import List, Optional, Union
21
20
 
22
- from pydantic import BaseModel, Field
21
+ from pydantic import Field
22
+
23
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
23
24
 
24
25
 
25
26
  class GraphLayoutType(Enum):
@@ -47,7 +48,7 @@ class LayeringAlgorithm(Enum):
47
48
  SIMPLEX = 'simplex'
48
49
 
49
50
 
50
- Number = Union[int, float]
51
+ Number = int | float
51
52
 
52
53
 
53
54
  class GraphLayout(BaseModel, abc.ABC):
@@ -58,25 +59,25 @@ class GraphLayout(BaseModel, abc.ABC):
58
59
  :param node_font_size: node font size in pixels
59
60
  """
60
61
 
61
- node_size: Optional[int] = None
62
- node_font_size: Optional[int] = None
62
+ node_size: int | None = None
63
+ node_font_size: int | None = None
63
64
 
64
65
 
65
66
  class TiersConfig(BaseModel):
66
- """
67
+ r"""
67
68
  TiersConfig provides a way of defining tiers for a graph layout.
68
69
 
69
70
  :param group: Path within node to group property which defines the tier it belong to,
70
- e.g. 'meta.group' would correspond to a group attribute in the meta of the node, 'meta': {'group': 'countries'}
71
+ e.g. 'meta.group' would correspond to a group attribute in the meta of the node, 'meta': \{'group': 'countries'\}
71
72
  :param order_nodes_by: A path to a node property which contains a number defining the order of nodes within a tier,
72
- e.g. 'meta.order' would correspond to an order attribute in the meta of the node, 'meta': {'order': 1}
73
+ e.g. 'meta.order' would correspond to an order attribute in the meta of the node, 'meta': \{'order': 1\}
73
74
  :param rank: A list of group values defining the order they should appear in, e.g. ['countries', 'currency', 'industry']
74
75
  would result in the nodes representing nodes appearing in the first tier, then nodes representing currency in the second tier and finally those representing industry.
75
76
  """
76
77
 
77
78
  group: str
78
- order_nodes_by: Optional[str] = None
79
- rank: Optional[List[str]] = None
79
+ order_nodes_by: str | None = None
80
+ rank: list[str] | None = None
80
81
 
81
82
 
82
83
  class TieringLayout(BaseModel):
@@ -133,8 +134,42 @@ class TieringLayout(BaseModel):
133
134
  :param orientation: Orientation the tiers are displayed in default is horizontal
134
135
  """
135
136
 
136
- tiers: Optional[Union[TiersConfig, List[List[str]]]] = None
137
- orientation: Optional[DirectionType] = DirectionType.HORIZONTAL
137
+ tiers: TiersConfig | list[list[str]] | None = None
138
+ orientation: DirectionType | None = DirectionType.HORIZONTAL
139
+
140
+
141
+ class GroupingLayout(BaseModel):
142
+ """
143
+ GroupingLayout provides a grouping or cluster layout for a graph. It can be used to represent nodes within groups or cluster which are collapsible.
144
+
145
+ You can set the group on the meta of a node and then define the path to this property on the layout:
146
+ ```
147
+ from dara.components import CausalGraphViewer, FcoseLayout
148
+ from cai_causal_graph import CausalGraph
149
+
150
+ cg = CausalGraph()
151
+ cg.add_node(identifier='A', meta={'group': 'group1'})
152
+ cg.add_node(identifier='B', meta={'group': 'group1'})
153
+ cg.add_node(identifier='C', meta={'group': 'group2'})
154
+ cg.add_node(identifier='D', meta={'group': 'group2'})
155
+ cg.add_node(identifier='E', meta={'group': 'group3'})
156
+ cg.add_edge('A', 'C')
157
+ cg.add_edge('B', 'D')
158
+ cg.add_edge('C', 'E')
159
+ cg.add_edge('D', 'E')
160
+
161
+ CausalGraphViewer(
162
+ causal_graph=cg,
163
+ graph_layout=FcoseLayout(
164
+ group='meta.group',
165
+ ),
166
+ )
167
+ ```
168
+
169
+ :param group: Path within node to group property which defines the group it belong to,
170
+ """
171
+
172
+ group: str | None = None
138
173
 
139
174
 
140
175
  class CircularLayout(GraphLayout):
@@ -145,7 +180,7 @@ class CircularLayout(GraphLayout):
145
180
  :param node_size: node size in pixels
146
181
  """
147
182
 
148
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.CIRCULAR, const=True)
183
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.CIRCULAR, frozen=True)
149
184
 
150
185
 
151
186
  class CustomLayout(GraphLayout):
@@ -172,12 +207,12 @@ class CustomLayout(GraphLayout):
172
207
  If not all nodes have coordinates defined, the graph editor will fall back to a default layout.
173
208
  """
174
209
 
175
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.CUSTOM, const=True)
210
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.CUSTOM, frozen=True)
176
211
 
177
212
 
178
- class FcoseLayout(GraphLayout, TieringLayout):
213
+ class FcoseLayout(GraphLayout, TieringLayout, GroupingLayout):
179
214
  """
180
- FcoseLayout utilises `fCoSE` (fast Compound Spring Embedder) algorithm to compute the layout.
215
+ FcoseLayout utilizes `fCoSE` (fast Compound Spring Embedder) algorithm to compute the layout.
181
216
  It works well in most circumstances and is highly configurable.
182
217
 
183
218
  See https://github.com/iVis-at-Bilkent/cytoscape.js-fcose for more details and interactive demos.
@@ -194,23 +229,23 @@ class FcoseLayout(GraphLayout, TieringLayout):
194
229
  :param tier_separation: Separation force between tiers (default value: 200)
195
230
  """
196
231
 
197
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.FCOSE, const=True)
232
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.FCOSE, frozen=True)
198
233
 
199
- edge_elasticity: Optional[Number] = 0.45
200
- edge_length: Optional[Number] = 3
201
- energy: Optional[Number] = 0.1
202
- gravity: Optional[Number] = 35
203
- gravity_range: Optional[Number] = 80
204
- high_quality: Optional[bool] = True
205
- iterations: Optional[int] = 2500
206
- node_repulsion: Optional[Number] = 6_500
207
- node_separation: Optional[Number] = 75
208
- tier_separation: Optional[Number] = 200
234
+ edge_elasticity: Number | None = 0.45
235
+ edge_length: Number | None = 3
236
+ energy: Number | None = 0.1
237
+ gravity: Number | None = 35
238
+ gravity_range: Number | None = 80
239
+ high_quality: bool | None = True
240
+ iterations: int | None = 2500
241
+ node_repulsion: Number | None = 6_500
242
+ node_separation: Number | None = 75
243
+ tier_separation: Number | None = 200
209
244
 
210
245
 
211
246
  class ForceAtlasLayout(GraphLayout):
212
247
  """
213
- ForceAtlas utilises the `ForceAtlas2` algorithm to compute the layout. It is a force-directed layout
248
+ ForceAtlas utilizes the `ForceAtlas2` algorithm to compute the layout. It is a force-directed layout
214
249
  which integrates various optimizations and is highly configurable.
215
250
 
216
251
  See https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0098679 for more details and
@@ -224,7 +259,7 @@ class ForceAtlasLayout(GraphLayout):
224
259
  of the space. Its main purpose is to compensate repulsion for nodes that are far away from the center. (default value:0.2)
225
260
  :param iterations: Number of iterations to run the layout for, per computation (default value: 10_000)
226
261
  :param lin_log_mode: Whether to use LinLog energy model, using logarithmic attraction force. Enabling it makes clusters
227
- tighter but coverges slower. (default value: `True`)
262
+ tighter but converges slower. (default value: `True`)
228
263
  :param outbound_attraction_distribution: Whether to scale the attraction force between nodes according to their degree. (default value: `True`)
229
264
  :param scaling_ratio: Parameter to adjust the size of the produced graph (default value: 8)
230
265
  :param strong_gravity_mode: Whether to use strong gravity mode, which sets a force that attracts the nodes that are distant
@@ -232,16 +267,16 @@ class ForceAtlasLayout(GraphLayout):
232
267
  However, its advantage is to force a very compact layout, which may be useful for certain purposes. (default value: `False`)
233
268
  """
234
269
 
235
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.FORCE_ATLAS, const=True)
270
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.FORCE_ATLAS, frozen=True)
236
271
 
237
- barnes_hut_optimize: Optional[bool] = False
238
- edge_weight_influence: Optional[Number] = 1
239
- gravity: Optional[Number] = 0.2
240
- iterations: Optional[int] = 10_000
241
- lin_log_mode: Optional[bool] = True
242
- outbound_attraction_distribution: Optional[bool] = True
243
- scaling_ratio: Optional[Number] = 8
244
- strong_gravity_mode: Optional[bool] = False
272
+ barnes_hut_optimize: bool | None = False
273
+ edge_weight_influence: Number | None = 1
274
+ gravity: Number | None = 0.2
275
+ iterations: int | None = 10_000
276
+ lin_log_mode: bool | None = True
277
+ outbound_attraction_distribution: bool | None = True
278
+ scaling_ratio: Number | None = 8
279
+ strong_gravity_mode: bool | None = False
245
280
 
246
281
 
247
282
  class MarketingLayout(GraphLayout, TieringLayout):
@@ -254,9 +289,9 @@ class MarketingLayout(GraphLayout, TieringLayout):
254
289
  :param tier_separation: Separation force between tiers (default value: 300)
255
290
  """
256
291
 
257
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.MARKETING, const=True)
258
- target_location: Optional[TargetLocation] = None
259
- tier_separation: Optional[Number] = 300
292
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.MARKETING, frozen=True)
293
+ target_location: TargetLocation | None = None
294
+ tier_separation: Number | None = 300
260
295
 
261
296
 
262
297
  class PlanarLayout(GraphLayout, TieringLayout):
@@ -265,20 +300,20 @@ class PlanarLayout(GraphLayout, TieringLayout):
265
300
  uses d3-dag's sugiyama layout under the hood to minimize edge crossings.
266
301
 
267
302
  :param orientation: Orientation of target node relative to other nodes (horizontal or vertical). (default value: horizontal)
268
- :param layering_algorithm: Algorithm to use for the layering step of sugyiama algorithm. Can choosen between simplex which
303
+ :param layering_algorithm: Algorithm to use for the layering step of sugyiama algorithm. Can chosen between simplex which
269
304
  optimizes for minimum edge length or long path which optimizes for minimum graph height.
270
305
  Do note that if tiers are passed in conjunction to this prop, its value will revert to simplex
271
306
  as tiers are only supported by it (defaults to: simplex)
272
307
  """
273
308
 
274
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.PLANAR, const=True)
275
- layering_algorithm: Optional[LayeringAlgorithm] = LayeringAlgorithm.SIMPLEX
276
- orientation: Optional[DirectionType] = None
309
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.PLANAR, frozen=True)
310
+ layering_algorithm: LayeringAlgorithm | None = LayeringAlgorithm.SIMPLEX
311
+ orientation: DirectionType | None = None
277
312
 
278
313
 
279
- class SpringLayout(GraphLayout, TieringLayout):
314
+ class SpringLayout(GraphLayout, TieringLayout, GroupingLayout):
280
315
  """
281
- SpringLayout provides a simple force-directed graph layout which produces the "spring" behaviour of edges.
316
+ SpringLayout provides a simple force-directed graph layout which produces the "spring" behavior of edges.
282
317
  This is a 'live' layout, which means a simulation keeps running in the background to compute the layout.
283
318
 
284
319
  :param collision_force: Multiplier for collision force between nodes (default value: 2)
@@ -288,12 +323,14 @@ class SpringLayout(GraphLayout, TieringLayout):
288
323
  make the initial render of the graph more stable (i.e. nodes won't move by themselves) but it comes at a
289
324
  small performance cost. (default value: 100)
290
325
  :param tier_separation: Separation force between tiers (default value: 300)
326
+ :param group_repel_strength: Strength of repulsion force between groups (default value: 2000)
291
327
  """
292
328
 
293
- layout_type: GraphLayoutType = Field(default=GraphLayoutType.SPRING, const=True)
329
+ layout_type: GraphLayoutType = Field(default=GraphLayoutType.SPRING, frozen=True)
294
330
 
295
- collision_force: Optional[Number] = 2
296
- gravity: Optional[Number] = -50
297
- link_force: Optional[Number] = 5
298
- warmup_ticks: Optional[Number] = 100
299
- tier_separation: Optional[Number] = 300
331
+ collision_force: Number | None = 2
332
+ gravity: Number | None = -50
333
+ link_force: Number | None = 5
334
+ warmup_ticks: Number | None = 100
335
+ tier_separation: Number | None = 300
336
+ group_repel_strength: Number | None = 2000
@@ -14,8 +14,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
+ # ruff: noqa: F401, F403
17
18
 
18
- import dara.components.plotting.palettes as PALETTES # pylint: disable=unused-import
19
+ import dara.components.plotting.palettes as PALETTES
19
20
  from dara.components.plotting.bokeh import *
20
21
  from dara.components.plotting.matplotlib import *
21
22
  from dara.components.plotting.plotly import *
@@ -16,10 +16,11 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  from json import dumps
19
- from typing import Any, List, Optional, Tuple
19
+ from typing import Any
20
20
 
21
21
  from bokeh.document import Document
22
22
  from bokeh.themes import Theme
23
+ from pydantic import ConfigDict
23
24
 
24
25
  from dara.components.plotting.bokeh.themes import light_theme
25
26
  from dara.core.base_definitions import Action
@@ -28,7 +29,7 @@ from dara.core.definitions import StyledComponentInstance
28
29
  SETTINGS = {'THEME': light_theme}
29
30
 
30
31
 
31
- def _get_theme(theme_input: Optional[dict]):
32
+ def _get_theme(theme_input: dict | None):
32
33
  if theme_input is not None:
33
34
  return Theme(json=theme_input)
34
35
  else:
@@ -51,19 +52,16 @@ class Bokeh(StyledComponentInstance):
51
52
  js_module = '@darajs/components'
52
53
 
53
54
  document: str
54
- events: Optional[List[Tuple[str, Action]]] = None
55
+ events: list[tuple[str, Action]] | None = None
55
56
 
56
- class Config:
57
- arbitrary_types_allowed = True
58
- json_encoders = {Document: lambda v: v.to_json()}
59
- use_enum_values = True
57
+ model_config = ConfigDict(arbitrary_types_allowed=True, use_enum_values=True)
60
58
 
61
59
  def __init__(
62
60
  self,
63
61
  figure: Any = None,
64
62
  document: Any = None,
65
- theme: Optional[dict] = None,
66
- events: Optional[List[Tuple[str, Action]]] = None,
63
+ theme: dict | None = None,
64
+ events: list[tuple[str, Action]] | None = None,
67
65
  **kwargs,
68
66
  ):
69
67
  """
@@ -71,7 +69,6 @@ class Bokeh(StyledComponentInstance):
71
69
  :param document: the document to display
72
70
  """
73
71
  if figure is not None:
74
-
75
72
  doc = Document()
76
73
  doc.theme = _get_theme(theme)
77
74
  doc.add_root(figure)
@@ -35,21 +35,23 @@ def figure_events(fig: figure):
35
35
  :param
36
36
  """
37
37
 
38
- def generate_event(args: dict = {}):
38
+ def generate_event(args: dict | None = None):
39
39
  """
40
40
  Generate a CustomJS event with the code, event name and arguments provided
41
41
 
42
42
  :param args: The arguments to provide to the JS code
43
43
  """
44
+ if args is None:
45
+ args = {}
44
46
  return CustomJS(
45
47
  args=args,
46
48
  code=f"""
47
- function {event_name.replace(' ','')+'__'+fig.id}(cb_obj, args) {{
49
+ function {event_name.replace(' ', '') + '__' + fig.id}(cb_obj, args) {{
48
50
  {code}
49
51
  }}
50
52
 
51
53
  document.dispatchEvent(
52
- new CustomEvent("BOKEH_FIGURE_{event_name}_{fig.id}", {{ detail: {event_name.replace(' ','')+'__'+fig.id}(cb_obj, {{{','.join(args.keys())}}}) }})
54
+ new CustomEvent("BOKEH_FIGURE_{event_name}_{fig.id}", {{ detail: {event_name.replace(' ', '') + '__' + fig.id}(cb_obj, {{{','.join(args.keys())}}}) }})
53
55
  )
54
56
  """,
55
57
  )
@@ -16,17 +16,27 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  from enum import Enum
19
- from typing import Any, List, Optional
19
+ from typing import Any, ClassVar
20
20
 
21
21
  import plotly.graph_objects as go
22
- from pydantic import BaseModel
22
+ import plotly.io as pio
23
+ from pydantic import ConfigDict
23
24
 
24
25
  from dara.components.plotting.plotly.themes import light_theme
25
26
  from dara.core.base_definitions import Action
27
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
26
28
  from dara.core.definitions import StyledComponentInstance
27
29
 
28
30
  SETTINGS = {'THEME': light_theme}
29
31
 
32
+ # We need to set the default theme for plotly so that plotly express when setting traces is able to pick up dara theme colors
33
+ base_template = pio.templates['plotly']
34
+ dara_theme = base_template.layout.update(SETTINGS['THEME']['layout']) # type: ignore
35
+ dara_template = go.layout.Template(layout=dara_theme)
36
+ # Set the default theme for plotly
37
+ pio.templates['dara_theme'] = dara_template
38
+ pio.templates.default = 'dara_theme'
39
+
30
40
 
31
41
  class PlotlyEventName(str, Enum):
32
42
  """
@@ -70,8 +80,8 @@ class PlotlyEvent(BaseModel):
70
80
  """
71
81
 
72
82
  event_name: PlotlyEventName
73
- actions: Optional[List[Action]] = None
74
- custom_js: Optional[str] = None
83
+ actions: list[Action] | None = None
84
+ custom_js: str | None = None
75
85
 
76
86
 
77
87
  class Plotly(StyledComponentInstance):
@@ -91,12 +101,8 @@ class Plotly(StyledComponentInstance):
91
101
  fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species', title='Iris Dataset Scatter Plot')
92
102
 
93
103
 
94
- def plotly_page():
95
- return Plotly(figure=fig, min_height=100)
96
-
97
-
98
104
  config = ConfigurationBuilder()
99
- config.add_page(name='MyPlot', content=plotly_page())
105
+ config.router.add_page(path='my-plot', content=Plotly(figure=fig, min_height=100))
100
106
  ```
101
107
 
102
108
  :param figure: A plotly figure
@@ -106,24 +112,23 @@ class Plotly(StyledComponentInstance):
106
112
  js_module = '@darajs/components'
107
113
 
108
114
  figure: str
109
- events: Optional[List[PlotlyEvent]] = None
115
+ events: list[PlotlyEvent] | None = None
110
116
 
111
- EventName = PlotlyEventName
112
- Event = PlotlyEvent
117
+ EventName: ClassVar[type[PlotlyEventName]] = PlotlyEventName
118
+ Event: ClassVar[type[PlotlyEvent]] = PlotlyEvent
113
119
 
114
- class Config:
115
- arbitrary_types_allowed = True
116
- json_encoders = {go.Figure: lambda v: v.to_json()}
117
- use_enum_values = True
120
+ model_config = ConfigDict(
121
+ arbitrary_types_allowed=True,
122
+ use_enum_values=True,
123
+ )
118
124
 
119
125
  def __init__(
120
126
  self,
121
127
  figure: Any = None,
122
- theme: Optional[dict] = None,
123
- events: Optional[List[PlotlyEvent]] = None,
128
+ theme: dict | None = None,
129
+ events: list[PlotlyEvent] | None = None,
124
130
  **kwargs,
125
131
  ):
126
-
127
132
  if theme is None and figure is not None:
128
133
  figure.update_layout(template=theme if theme is not None else SETTINGS['THEME'])
129
134
 
@@ -15,15 +15,17 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import Any, Dict
18
+ from typing import Any
19
19
 
20
20
  from dara.components.plotting.palettes import CategoricalDark10, CategoricalLight10
21
21
  from dara.core.visual.themes import dark, light
22
22
 
23
23
  light_colors = light.Light.colors
24
+ assert light_colors is not None
24
25
  dark_colors = dark.Dark.colors
26
+ assert dark_colors is not None
25
27
 
26
- light_theme = {
28
+ light_theme: dict[str, dict[str, Any]] = {
27
29
  'layout': {
28
30
  'paper_bgcolor': 'rgba(255,255,255,0)', # Set the background color of the plot
29
31
  'plot_bgcolor': 'rgba(255,255,255,0)', # Set the background color of the plot area
@@ -81,9 +83,9 @@ light_theme = {
81
83
  },
82
84
  },
83
85
  },
84
- } # type: Dict[str, Dict[str, Any]]
86
+ }
85
87
 
86
- dark_theme = {
88
+ dark_theme: dict[str, dict[str, Any]] = {
87
89
  'layout': {
88
90
  'paper_bgcolor': 'rgba(255,255,255,0)', # Set the background color of the plot
89
91
  'plot_bgcolor': 'rgba(255,255,255,0)', # Set the background color of the plot area
@@ -141,4 +143,4 @@ dark_theme = {
141
143
  },
142
144
  },
143
145
  },
144
- } # type: Dict[str, Dict[str, Any]]
146
+ }
@@ -14,16 +14,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
  See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
+ # ruff: noqa: F401, F403
17
18
 
18
19
  from dara.components.smart.chat import Chat
19
20
  from dara.components.smart.code_editor import CodeEditor, run_script
20
- from dara.components.smart.data_slicer import DataSlicer, DataSlicerModal
21
+ from dara.components.smart.data_slicer import (
22
+ DataSlicer,
23
+ DataSlicerModal,
24
+ FilterStatusButton,
25
+ )
21
26
  from dara.components.smart.hierarchy import HierarchySelector, HierarchyViewer
22
27
  from dara.components.smart.hierarchy import Node as HierarchyNode
23
28
 
24
29
  __all__ = [
25
30
  'DataSlicer',
26
31
  'DataSlicerModal',
32
+ 'FilterStatusButton',
27
33
  'HierarchySelector',
28
34
  'HierarchyViewer',
29
35
  'HierarchyNode',
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from pydantic import validator
18
+ from pydantic import field_validator
19
19
 
20
20
  from dara.components.smart.chat.endpoints import on_new_message
21
21
  from dara.core.definitions import StyledComponentInstance
@@ -25,6 +25,8 @@ from dara.core.persistence import BackendStore
25
25
 
26
26
  class Chat(StyledComponentInstance):
27
27
  """
28
+ ![Chat](../../../../../docs/packages/dara-components/common/assets/Chat.png)
29
+
28
30
  A Chat component which can be added anywhere in your page. When added a chat button will appear in the bottom right
29
31
  of your page and when clicked a chat sidebar will appear. This can be added on a page by page basis, with the chat
30
32
  state being store in a Variable.
@@ -48,8 +50,8 @@ class Chat(StyledComponentInstance):
48
50
  config.add_auth(MultiBasicAuthConfig(users={'user': 'password', 'user2': 'password2'}))
49
51
 
50
52
  # Add a page with a chat component, this can be added anywhere within a page
51
- config.add_page(
52
- name='Chat Page',
53
+ config.router.add_page(
54
+ path='chat',
53
55
  content=Stack(
54
56
  Text('This is a page with a chat'),
55
57
  Chat(value=collab_variable),
@@ -65,12 +67,9 @@ class Chat(StyledComponentInstance):
65
67
 
66
68
  value: NonDataVariable
67
69
 
68
- class Config:
69
- extra = 'forbid'
70
-
71
- @validator('value')
70
+ @field_validator('value')
72
71
  @classmethod
73
- def validate_vaeiable(cls, value):
72
+ def validate_variable(cls, value):
74
73
  """
75
74
  Validate that the Variable has a store attached to it.
76
75
  """
@@ -2,7 +2,7 @@
2
2
  Copyright (c) 2023 by Impulse Innovations Ltd. Private and confidential. Part of the causaLens product.
3
3
  """
4
4
 
5
- from typing import Callable
5
+ from collections.abc import Callable
6
6
 
7
7
  from dara.components.smart.chat.types import NewMessageBody
8
8
  from dara.core.definitions import EndpointConfiguration
@@ -2,9 +2,7 @@
2
2
  Copyright (c) 2023 by Impulse Innovations Ltd. Private and confidential. Part of the causaLens product.
3
3
  """
4
4
 
5
- from typing import List, Optional
6
-
7
- from pydantic import BaseModel
5
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
8
6
 
9
7
 
10
8
  class ChatUserData(BaseModel):
@@ -17,9 +15,9 @@ class ChatUserData(BaseModel):
17
15
  :param groups: list of groups user belongs to
18
16
  """
19
17
 
20
- id: Optional[str] = None
18
+ id: str | None = None
21
19
  name: str
22
- email: Optional[str] = None
20
+ email: str | None = None
23
21
 
24
22
 
25
23
  class ChatMessage(BaseModel):
@@ -50,5 +48,5 @@ class NewMessageBody(BaseModel):
50
48
  """
51
49
 
52
50
  app_url: str
53
- users: List[ChatUserData]
51
+ users: list[ChatUserData]
54
52
  content: ChatMessage
@@ -15,20 +15,34 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
+ from typing import Literal
19
+
18
20
  from dara.core.definitions import StyledComponentInstance
19
- from dara.core.interactivity import NonDataVariable
21
+ from dara.core.interactivity import ClientVariable
20
22
 
21
23
 
22
24
  class CodeEditor(StyledComponentInstance):
23
25
  """
24
26
  A code editor component.
25
27
 
28
+ Example usage:
29
+
30
+ ```python
31
+ from dara.components.smart.code_editor import CodeEditor
32
+
33
+ script = Variable('print("Hello, World!")')
34
+
35
+ code_editor = CodeEditor(
36
+ script=script,
37
+ language='python'
38
+ )
39
+ ```
40
+
26
41
  :param script: The script to render
27
42
  """
28
43
 
29
44
  js_module = '@darajs/components'
30
45
 
31
- script: NonDataVariable
46
+ script: ClientVariable
32
47
 
33
- class Config:
34
- extra = 'forbid'
48
+ language: Literal['json'] | Literal['python'] | Literal['markdown'] | Literal['sql'] | None = None