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
@@ -15,14 +15,49 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from decimal import Decimal
19
- from typing import Any, Dict, List, Optional, Union
18
+ from decimal import ROUND_FLOOR, Decimal
19
+ from typing import Any
20
20
 
21
- from pydantic import validator
21
+ from pydantic import Field, ValidationInfo, field_validator
22
22
 
23
23
  from dara.components.common.base_component import FormComponent
24
24
  from dara.core.base_definitions import Action
25
- from dara.core.interactivity import UrlVariable, Variable
25
+ from dara.core.interactivity import Variable
26
+
27
+
28
+ def compute_step(difference: Decimal) -> Decimal:
29
+ """
30
+ Compute what step should be used for the given domain difference.
31
+
32
+ The step is computed as:
33
+ step = 10^(floor(log10(difference))) / 10
34
+
35
+ For cases where the step is a decimal (i.e. when the log10 is negative),
36
+ the result is quantized to a fixed number of decimal places to avoid
37
+ floating point imprecision.
38
+
39
+ :param difference: The domain difference (must be positive).
40
+ :return: The computed step.
41
+ """
42
+ if difference <= 0:
43
+ raise ValueError('difference must be a positive Decimal.')
44
+
45
+ # Compute the base-10 logarithm of the difference
46
+ log_value = difference.log10()
47
+ # Get the integer part via floor
48
+ log_int = int(log_value.to_integral_value(rounding=ROUND_FLOOR))
49
+
50
+ # Compute 10^(floor(log10(difference))) / 10
51
+ step = (Decimal(10) ** log_int) / Decimal(10)
52
+
53
+ # If the logarithm is negative, quantize the step to prevent
54
+ # precision errors. The precision is set to abs(log_int) + 1 decimal places.
55
+ if log_int < 0:
56
+ num_decimals = abs(log_int) + 1
57
+ quantizer = Decimal(f'1e-{num_decimals}')
58
+ step = step.quantize(quantizer)
59
+
60
+ return step
26
61
 
27
62
 
28
63
  class Slider(FormComponent):
@@ -36,25 +71,26 @@ class Slider(FormComponent):
36
71
  A simple Slider component with a single handle that tracks the selected value over a given range is created via:
37
72
 
38
73
  ```python
39
-
40
74
  from dara.core import Variable
41
75
  from dara.components.common import Slider
42
76
 
77
+ value_var = Variable(0.5)
78
+
43
79
  Slider(
44
80
  domain=[0.0, 1.0],
45
- value=Variable(0.5),
81
+ value=value_var,
46
82
  )
47
-
48
83
  ```
49
84
 
50
85
  A more complex example with multiple handles, a set step size, specified ticks, a right hand rail and a track label
51
86
  is created via:
52
87
 
53
88
  ```python
54
-
55
89
  from dara.core import Variable
56
90
  from dara.components.common import Slider
57
91
 
92
+ value_var = Variable([-3, 6, 8])
93
+
58
94
  Slider(
59
95
  domain=[-10, 10],
60
96
  step=2,
@@ -62,24 +98,23 @@ class Slider(FormComponent):
62
98
  rail_labels=['My Slider'],
63
99
  rail_to_end=True,
64
100
  ticks=[-9, -5, -1, 1, 5, 9],
65
- value=Variable([-3, 6, 8]),
101
+ value=value_var,
66
102
  )
67
-
68
103
  ```
69
104
 
70
105
  Setting the disable_input_alternative to True removes the switch for changing the slider to a numerical input box:
71
106
 
72
107
  ```python
73
-
74
108
  from dara.core.definitions import Variable
75
109
  from dara.components.common import Slider
76
110
 
111
+ value_var = Variable(0.5)
112
+
77
113
  Slider(
78
114
  domain=[0.0, 1.0],
79
- value=Variable(0.5),
115
+ value=value_var,
80
116
  disable_input_alternative=True,
81
117
  )
82
-
83
118
  ```
84
119
 
85
120
  :param domain: The range of the slider
@@ -88,26 +123,28 @@ class Slider(FormComponent):
88
123
  :param rail_from_start: Boolean, if True the track is rendered from leftmost handle to the end
89
124
  :param rail_labels: A label for the track
90
125
  :param rail_to_end: Boolean, if True the track is rendered from rightmost handle to the end
126
+ :param thumb_labels: A list of labels for the slider's thumbs
91
127
  :param ticks: List specifying the position of the ticks
92
128
  :param value: A Variable instance recording the component's state; can be a single number for single-handle Slider, or an N-length array for a Slider with N handles
93
129
  :param disable_input_alternative: Boolean, if True disable the rendering of the input alternative switch
94
130
  :param id: the key to be used if this component is within a form
95
131
  """
96
132
 
97
- domain: List[float]
98
- onchange: Optional[Action] = None
99
- step: Optional[float] = None
133
+ domain: list[float]
134
+ onchange: Action | None = None
135
+ step: float | None = Field(None, validate_default=True)
100
136
  rail_from_start: bool = True
101
- rail_labels: Optional[List[str]] = None
137
+ rail_labels: list[str] | None = None
102
138
  rail_to_end: bool = False
103
- ticks: Optional[List[Union[float, int]]] = None
104
- value: Optional[Union[Variable[Any], UrlVariable[Any]]] = None
139
+ thumb_labels: list[str] | None = None
140
+ ticks: list[float | int] | None = None
141
+ value: Variable[Any] | None = None
105
142
  disable_input_alternative: bool = False
106
- id: Optional[str] = None
143
+ id: str | None = None
107
144
 
108
- @validator('domain')
145
+ @field_validator('domain')
109
146
  @classmethod
110
- def domain_valid(cls, v: List[float]) -> List[float]:
147
+ def domain_valid(cls, v: list[float]) -> list[float]:
111
148
  if len(v) != 2:
112
149
  raise ValueError(f'Domain must be a list of length two [min, max], found {v}')
113
150
 
@@ -116,22 +153,30 @@ class Slider(FormComponent):
116
153
 
117
154
  return v
118
155
 
119
- @validator('step')
156
+ @field_validator('step')
120
157
  @classmethod
121
- def step_valid(cls, v: Optional[float], values: Dict[str, Any]) -> Optional[float]:
122
- if v is None:
158
+ def step_valid(cls, v: float | None, info: ValidationInfo) -> float | None:
159
+ # domain validation must have failed, skip
160
+ if 'domain' not in info.data:
123
161
  return v
124
162
 
125
- # both step and domain are set, make sure they are compatible
163
+ # make sure step and domain are compatible
126
164
  # using Decimal to avoid floating point errors
127
- domain = values['domain']
165
+ domain = info.data['domain']
128
166
  domain_range = Decimal(str(domain[1])) - Decimal(str(domain[0]))
129
- step = Decimal(str(v))
167
+
168
+ # If step is not provided, run inference to check if the
169
+ # client-side computed step is compatible with the domain range.
170
+ # The actual step is computed in the client-side but we check it here to fail early.
171
+ step = compute_step(domain_range) if v is None else Decimal(str(v))
130
172
 
131
173
  # Not divisible
132
174
  if domain_range % step != 0:
175
+ step_string = f'Step {step}'
176
+ if v is None:
177
+ step_string += ' (inferred from domain range)'
133
178
  raise ValueError(
134
- f'Step {v} is not compatible with domain {domain}. The domain range must be divisible by the step provided.'
179
+ f'{step_string} is not compatible with domain {domain}. The domain range must be divisible by the step.'
135
180
  )
136
181
 
137
182
  return v
@@ -15,9 +15,7 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import Union
19
-
20
- from pydantic import validator
18
+ from pydantic import field_validator
21
19
 
22
20
  from dara.components.common.base_component import ContentComponent
23
21
 
@@ -84,10 +82,10 @@ class Spacer(ContentComponent):
84
82
  """
85
83
 
86
84
  line: bool = False
87
- size: Union[int, str] = '0.75rem'
88
- inset: Union[int, str] = '0rem'
85
+ size: int | str = '0.75rem'
86
+ inset: int | str = '0rem'
89
87
 
90
- @validator('size', 'inset')
88
+ @field_validator('size', 'inset')
91
89
  @classmethod
92
90
  def validate_dimension(cls, value):
93
91
  if isinstance(value, int):
@@ -16,7 +16,6 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  import logging
19
- from typing import Union
20
19
 
21
20
  from dara.components.common.base_component import LayoutComponent
22
21
  from dara.core.definitions import ComponentInstance
@@ -123,6 +122,10 @@ class Stack(LayoutComponent):
123
122
 
124
123
  ```
125
124
 
125
+ Important: when using `For` component with `virtualization` enabled, do not use the Stack `scroll` argument,
126
+ as it is redundant and will result in unexpected behavior. The `For` component will automatically handle scrolling
127
+ for you.
128
+
126
129
  :param direction: The direction to stack children, can be 'vertical' or 'horizontal', default is 'vertical'
127
130
  :param collapsed: Whether to collapse the stack
128
131
  :param justify: How to justify the content of the stack, accepts any flexbox justifications
@@ -131,11 +134,11 @@ class Stack(LayoutComponent):
131
134
  :param scroll: Whether to scroll the content of the stack, defaults to False
132
135
  """
133
136
 
134
- collapsed: Union[Variable[bool], bool] = False
137
+ collapsed: Variable[bool] | bool = False
135
138
  direction: Direction = Direction.VERTICAL
136
- hug: bool = False
139
+ hug: bool | None = False
137
140
  scroll: bool = False
138
141
 
139
142
  # Dummy init that just passes through arguments to superclass, fixes Pylance complaining about types
140
- def __init__(self, *args: ComponentInstance, **kwargs):
143
+ def __init__(self, *args: ComponentInstance | None, **kwargs):
141
144
  super().__init__(*args, **kwargs)
@@ -15,11 +15,9 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import Optional, Union
19
-
20
18
  from dara.components.common.base_component import FormComponent
21
19
  from dara.core.base_definitions import Action
22
- from dara.core.interactivity import UrlVariable, Variable
20
+ from dara.core.interactivity import Variable
23
21
 
24
22
 
25
23
  class Switch(FormComponent):
@@ -31,12 +29,12 @@ class Switch(FormComponent):
31
29
  A Switch component is created via:
32
30
 
33
31
  ```python
34
-
35
32
  from dara.core import Variable
36
33
  from dara.components.common import Switch
37
34
 
38
- Switch(value=Variable(default=True))
35
+ value_var = Variable(default=True)
39
36
 
37
+ Switch(value=value_var)
40
38
  ```
41
39
 
42
40
  :param value: Boolean Variable instance recording the component's state
@@ -44,6 +42,6 @@ class Switch(FormComponent):
44
42
  :param id: the key to be used if this component is within a form
45
43
  """
46
44
 
47
- value: Optional[Union[Variable[bool], UrlVariable[bool]]] = None
48
- onchange: Optional[Action] = None
49
- id: Optional[str] = None
45
+ value: Variable[bool] | None = None
46
+ onchange: Action | None = None
47
+ id: str | None = None
@@ -15,10 +15,8 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import Optional
19
-
20
18
  from dara.components.common.base_component import LayoutComponent
21
- from dara.core.interactivity import NonDataVariable
19
+ from dara.core.interactivity import ClientVariable
22
20
 
23
21
 
24
22
  class TabbedCard(LayoutComponent):
@@ -29,8 +27,7 @@ class TabbedCard(LayoutComponent):
29
27
 
30
28
  A tabbed card component can be created via:
31
29
 
32
- ```python
33
-
30
+ ```python
34
31
  from dara.components.common import Tab, TabbedCard, Text
35
32
 
36
33
  TabbedCard(
@@ -43,8 +40,7 @@ class TabbedCard(LayoutComponent):
43
40
  title='Tab 2'
44
41
  )
45
42
  )
46
-
47
- ```
43
+ ```
48
44
 
49
45
  A tabbed card component where the tab is controlled by a Variable:
50
46
 
@@ -52,20 +48,21 @@ class TabbedCard(LayoutComponent):
52
48
  from dara.core import Variable
53
49
  from dara.components.common import Tab, TabbedCard, Text
54
50
 
51
+ tab_var = Variable('Tab 2')
52
+
55
53
  TabbedCard(
56
54
  Tab(Text('Some Text'), title='Tab 1'),
57
55
  Tab(Text('Some Text'), title='Tab 2'),
58
- selected_tab=Variable('Tab 2'),
56
+ selected_tab=tab_var,
59
57
  )
60
-
61
58
  ```
62
59
 
63
60
  :param initial_tab: Optional title of the tab to initially render, defaults to the first
64
61
  :param selected_tab: Optional selected tab mapped to a variable so that the selected tab can be easily accessed
65
62
  """
66
63
 
67
- initial_tab: Optional[str] = None
68
- selected_tab: Optional[NonDataVariable] = None
64
+ initial_tab: str | None = None
65
+ selected_tab: ClientVariable | None = None
69
66
 
70
67
 
71
68
  class Tab(LayoutComponent):