dara-components 1.21.9__py3-none-any.whl → 1.21.23__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 (66) hide show
  1. dara/components/__init__.py +2 -1
  2. dara/components/common/accordion.py +11 -17
  3. dara/components/common/anchor.py +6 -5
  4. dara/components/common/base_component.py +5 -5
  5. dara/components/common/bullet_list.py +1 -3
  6. dara/components/common/button.py +11 -6
  7. dara/components/common/button_bar.py +6 -6
  8. dara/components/common/card.py +3 -5
  9. dara/components/common/carousel.py +5 -5
  10. dara/components/common/checkbox_group.py +8 -8
  11. dara/components/common/code.py +3 -3
  12. dara/components/common/component_select_list.py +6 -8
  13. dara/components/common/datepicker.py +6 -6
  14. dara/components/common/dropdown_menu.py +9 -9
  15. dara/components/common/dropzone.py +11 -14
  16. dara/components/common/form.py +3 -5
  17. dara/components/common/form_page.py +2 -4
  18. dara/components/common/grid.py +13 -13
  19. dara/components/common/heading.py +2 -3
  20. dara/components/common/icon.py +1 -3
  21. dara/components/common/if_cmp.py +8 -8
  22. dara/components/common/input.py +5 -7
  23. dara/components/common/label.py +3 -5
  24. dara/components/common/markdown.py +2 -4
  25. dara/components/common/overlay.py +1 -3
  26. dara/components/common/progress_bar.py +2 -4
  27. dara/components/common/radio_group.py +8 -8
  28. dara/components/common/select.py +10 -10
  29. dara/components/common/slider.py +11 -11
  30. dara/components/common/spacer.py +2 -4
  31. dara/components/common/stack.py +3 -4
  32. dara/components/common/switch.py +3 -5
  33. dara/components/common/tabbed_card.py +2 -4
  34. dara/components/common/table.py +38 -34
  35. dara/components/common/text.py +3 -5
  36. dara/components/common/textarea.py +5 -5
  37. dara/components/common/time_utils.py +1 -2
  38. dara/components/common/tooltip.py +3 -5
  39. dara/components/common/utils.py +22 -22
  40. dara/components/graphs/components/base_graph_component.py +19 -19
  41. dara/components/graphs/components/causal_graph_viewer.py +2 -4
  42. dara/components/graphs/components/edge_encoder.py +13 -13
  43. dara/components/graphs/components/node_hierarchy_builder.py +12 -12
  44. dara/components/graphs/definitions.py +21 -16
  45. dara/components/graphs/graph_layout.py +36 -37
  46. dara/components/plotting/bokeh/bokeh.py +5 -5
  47. dara/components/plotting/bokeh/utils.py +1 -3
  48. dara/components/plotting/plotly/plotly.py +8 -8
  49. dara/components/plotting/plotly/themes.py +3 -3
  50. dara/components/smart/chat/config.py +1 -1
  51. dara/components/smart/chat/types.py +3 -5
  52. dara/components/smart/code_editor/code_editor.py +2 -2
  53. dara/components/smart/code_editor/util.py +4 -4
  54. dara/components/smart/data_slicer/data_slicer.py +4 -6
  55. dara/components/smart/data_slicer/data_slicer_modal.py +1 -3
  56. dara/components/smart/data_slicer/extension/data_slicer_filter.py +2 -3
  57. dara/components/smart/data_slicer/extension/filter_status_button.py +1 -3
  58. dara/components/smart/data_slicer/utils/core.py +14 -14
  59. dara/components/smart/data_slicer/utils/data_preview.py +1 -3
  60. dara/components/smart/hierarchy.py +5 -5
  61. dara/components/umd/dara.components.umd.js +116 -38
  62. {dara_components-1.21.9.dist-info → dara_components-1.21.23.dist-info}/METADATA +4 -5
  63. dara_components-1.21.23.dist-info/RECORD +87 -0
  64. dara_components-1.21.9.dist-info/RECORD +0 -87
  65. {dara_components-1.21.9.dist-info → dara_components-1.21.23.dist-info}/LICENSE +0 -0
  66. {dara_components-1.21.9.dist-info → dara_components-1.21.23.dist-info}/WHEEL +0 -0
@@ -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 typing import ClassVar, List, Optional, Union
18
+ from typing import ClassVar
19
19
 
20
20
  from pydantic import field_validator
21
21
 
@@ -24,13 +24,13 @@ from dara.core.definitions import ComponentInstance
24
24
  from dara.core.interactivity import AnyVariable, Condition, Operator
25
25
 
26
26
 
27
- def cast_list(value: Union[ComponentInstance, List[Union[ComponentInstance, None]]]) -> List[ComponentInstance]:
27
+ def cast_list(value: ComponentInstance | list[ComponentInstance | None]) -> list[ComponentInstance]:
28
28
  """
29
29
  Cast the value to a list if it is not or return original list if it is.
30
30
 
31
31
  :param value: the value to cast
32
32
  """
33
- return [v for v in value if v is not None] if isinstance(value, List) else [value]
33
+ return [v for v in value if v is not None] if isinstance(value, list) else [value]
34
34
 
35
35
 
36
36
  ConditionType = type[Condition]
@@ -66,8 +66,8 @@ class If(ModifierComponent):
66
66
  """
67
67
 
68
68
  condition: Condition
69
- true_children: List[ComponentInstance]
70
- false_children: List[ComponentInstance]
69
+ true_children: list[ComponentInstance]
70
+ false_children: list[ComponentInstance]
71
71
 
72
72
  Condition: ClassVar[ConditionType] = Condition
73
73
 
@@ -85,9 +85,9 @@ class If(ModifierComponent):
85
85
 
86
86
  def __init__(
87
87
  self,
88
- condition: Union[Condition, AnyVariable], # type: ignore
89
- true_children: Union[ComponentInstance, List[Union[ComponentInstance, None]]],
90
- false_children: Optional[Union[ComponentInstance, List[Union[ComponentInstance, None]]]] = None,
88
+ condition: Condition | AnyVariable, # type: ignore
89
+ true_children: ComponentInstance | list[ComponentInstance | None],
90
+ false_children: ComponentInstance | list[ComponentInstance | None] | None = None,
91
91
  ):
92
92
  if false_children is None:
93
93
  false_children = []
@@ -15,8 +15,6 @@ 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 FormComponent
21
19
  from dara.core.base_definitions import Action
22
20
  from dara.core.interactivity import Variable
@@ -58,8 +56,8 @@ class Input(FormComponent):
58
56
  :param id: the key to be used if this component is within a form
59
57
  """
60
58
 
61
- id: Optional[str] = None
62
- placeholder: Optional[str] = None
63
- type: Optional[str] = None
64
- onchange: Optional[Action] = None
65
- value: Optional[Variable] = None
59
+ id: str | None = None
60
+ placeholder: str | None = None
61
+ type: str | None = None
62
+ onchange: Action | None = None
63
+ value: Variable | None = None
@@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
- from typing import List, Optional, Union
19
-
20
18
  from pydantic import field_validator
21
19
 
22
20
  from dara.components.common.base_component import ContentComponent
@@ -65,13 +63,13 @@ class Label(ContentComponent):
65
63
  :param label_width: A optional string containing the width the label should take
66
64
  """
67
65
 
68
- value: Union[str, ComponentInstance]
66
+ value: str | ComponentInstance
69
67
  direction: Direction = Direction.VERTICAL
70
- label_width: Optional[str] = None
68
+ label_width: str | None = None
71
69
 
72
70
  @field_validator('children')
73
71
  @classmethod
74
- def validate_only_one_child(cls, children: List[ComponentInstance]) -> List[ComponentInstance]:
72
+ def validate_only_one_child(cls, children: list[ComponentInstance]) -> list[ComponentInstance]:
75
73
  if len(children) > 1:
76
74
  raise TypeError(
77
75
  'More than one component was passed to the Label component. Label accepts only one child component'
@@ -15,8 +15,6 @@ 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
18
  from dara.components.common.base_component import BaseDashboardComponent
21
19
  from dara.core.interactivity import ClientVariable
22
20
 
@@ -42,8 +40,8 @@ class Markdown(BaseDashboardComponent):
42
40
  if the markdown is user-provided
43
41
  """
44
42
 
45
- markdown: Union[ClientVariable, str]
43
+ markdown: ClientVariable | str
46
44
  html_raw: bool = False
47
45
 
48
- def __init__(self, markdown: Union[ClientVariable, str], html_raw: bool = False, **kwargs):
46
+ def __init__(self, markdown: ClientVariable | str, html_raw: bool = False, **kwargs):
49
47
  super().__init__(markdown=markdown, html_raw=html_raw, **kwargs)
@@ -15,8 +15,6 @@ 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 pydantic import field_validator
21
19
 
22
20
  from dara.components.common.base_component import LayoutComponent
@@ -45,7 +43,7 @@ class Overlay(LayoutComponent):
45
43
  :param position: the position of the overlay; can be top-left, top-right, bottom-left, bottom-right
46
44
  """
47
45
 
48
- show: Optional[ClientVariable] = None
46
+ show: ClientVariable | None = None
49
47
 
50
48
  @field_validator('position')
51
49
  @classmethod
@@ -15,8 +15,6 @@ 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 pydantic import field_validator
21
19
 
22
20
  from dara.components.common.base_component import ContentComponent
@@ -48,9 +46,9 @@ class ProgressBar(ContentComponent):
48
46
  :param color: Optional color property for the progress bar, this should be the hex value of the color.
49
47
  """
50
48
 
51
- progress: Union[int, ClientVariable]
49
+ progress: int | ClientVariable
52
50
  small: bool = False
53
- color: Optional[str] = None
51
+ color: str | None = None
54
52
 
55
53
  @field_validator('progress')
56
54
  @classmethod
@@ -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 typing import Any, List, Optional, Union
18
+ from typing import Any
19
19
 
20
20
  from pydantic import field_validator
21
21
  from typing_extensions import TypedDict
@@ -29,7 +29,7 @@ from dara.core.visual.components.types import Direction
29
29
 
30
30
  class RadioItem(TypedDict):
31
31
  value: Any
32
- label: Union[str, ComponentInstance]
32
+ label: str | ComponentInstance
33
33
 
34
34
 
35
35
  class RadioGroup(FormComponent):
@@ -91,16 +91,16 @@ class RadioGroup(FormComponent):
91
91
  :param id: the key to be used if this component is within a form
92
92
  """
93
93
 
94
- items: Union[List[RadioItem], List[str], ClientVariable]
95
- value: Optional[Variable[Any]] = None
96
- list_styling: Optional[bool] = False
97
- onchange: Optional[Action] = None
94
+ items: list[RadioItem] | list[str] | ClientVariable
95
+ value: Variable[Any] | None = None
96
+ list_styling: bool | None = False
97
+ onchange: Action | None = None
98
98
  direction: Direction = Direction.VERTICAL
99
- id: Optional[str] = None
99
+ id: str | None = None
100
100
 
101
101
  @field_validator('items', mode='before')
102
102
  @classmethod
103
- def validate_items(cls, items: Any) -> Union[List[RadioItem], ClientVariable]:
103
+ def validate_items(cls, items: Any) -> list[RadioItem] | ClientVariable:
104
104
  if isinstance(items, ClientVariable):
105
105
  return items
106
106
  if len(items) == 0:
@@ -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 typing import Any, List, Optional, Union
18
+ from typing import Any
19
19
 
20
20
  from pydantic import ValidationInfo, field_validator
21
21
 
@@ -36,11 +36,11 @@ class ListSection(BaseModel):
36
36
  """
37
37
 
38
38
  label: str
39
- items: List[Union[Item, str, dict]]
39
+ items: list[Item | str | dict]
40
40
 
41
41
  @field_validator('items')
42
42
  @classmethod
43
- def validate_items(cls, items: Any) -> List[Item]:
43
+ def validate_items(cls, items: Any) -> list[Item]:
44
44
  if len(items) == 0:
45
45
  raise ValueError('Items of ListSection was empty, you must provide at least one item to the component')
46
46
  return [Item.to_item(item) for item in items]
@@ -125,18 +125,18 @@ class Select(FormComponent):
125
125
  :param value: A Variable instance recording the component's state
126
126
  """
127
127
 
128
- id: Optional[str] = None
128
+ id: str | None = None
129
129
  multiselect: bool = False
130
130
  searchable: bool = False
131
- items: Union[List[Union[Item, ListSection]], ClientVariable]
131
+ items: list[Item | ListSection] | ClientVariable
132
132
  max_rows: int = 3
133
- onchange: Optional[Action] = None
134
- placeholder: Optional[str] = None
135
- value: Optional[Variable[Any]] = None
133
+ onchange: Action | None = None
134
+ placeholder: str | None = None
135
+ value: Variable[Any] | None = None
136
136
 
137
137
  @field_validator('items', mode='before')
138
138
  @classmethod
139
- def validate_items(cls, items: Any, info: ValidationInfo) -> Union[List[Union[Item, ListSection]], ClientVariable]:
139
+ def validate_items(cls, items: Any, info: ValidationInfo) -> list[Item | ListSection] | ClientVariable:
140
140
  multiselect = info.data.get('multiselect')
141
141
  searchable = info.data.get('searchable')
142
142
  if isinstance(items, ClientVariable):
@@ -156,7 +156,7 @@ class Select(FormComponent):
156
156
  return [Item.to_item(item) for item in items]
157
157
 
158
158
 
159
- def _parse_item(item: Any, return_listsection: bool = False) -> Union[Item, ListSection]:
159
+ def _parse_item(item: Any, return_listsection: bool = False) -> Item | ListSection:
160
160
  """
161
161
  Converts items to Item objects for a SectionedList. Can return a ListSection for a dictionary if
162
162
  return_listsection is set to True.
@@ -16,7 +16,7 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  from decimal import ROUND_FLOOR, Decimal
19
- from typing import Any, List, Optional, Union
19
+ from typing import Any
20
20
 
21
21
  from pydantic import Field, ValidationInfo, field_validator
22
22
 
@@ -130,21 +130,21 @@ class Slider(FormComponent):
130
130
  :param id: the key to be used if this component is within a form
131
131
  """
132
132
 
133
- domain: List[float]
134
- onchange: Optional[Action] = None
135
- step: Optional[float] = Field(None, validate_default=True)
133
+ domain: list[float]
134
+ onchange: Action | None = None
135
+ step: float | None = Field(None, validate_default=True)
136
136
  rail_from_start: bool = True
137
- rail_labels: Optional[List[str]] = None
137
+ rail_labels: list[str] | None = None
138
138
  rail_to_end: bool = False
139
- thumb_labels: Optional[List[str]] = None
140
- ticks: Optional[List[Union[float, int]]] = None
141
- value: Optional[Variable[Any]] = None
139
+ thumb_labels: list[str] | None = None
140
+ ticks: list[float | int] | None = None
141
+ value: Variable[Any] | None = None
142
142
  disable_input_alternative: bool = False
143
- id: Optional[str] = None
143
+ id: str | None = None
144
144
 
145
145
  @field_validator('domain')
146
146
  @classmethod
147
- def domain_valid(cls, v: List[float]) -> List[float]:
147
+ def domain_valid(cls, v: list[float]) -> list[float]:
148
148
  if len(v) != 2:
149
149
  raise ValueError(f'Domain must be a list of length two [min, max], found {v}')
150
150
 
@@ -155,7 +155,7 @@ class Slider(FormComponent):
155
155
 
156
156
  @field_validator('step')
157
157
  @classmethod
158
- def step_valid(cls, v: Optional[float], info: ValidationInfo) -> Optional[float]:
158
+ def step_valid(cls, v: float | None, info: ValidationInfo) -> float | None:
159
159
  # domain validation must have failed, skip
160
160
  if 'domain' not in info.data:
161
161
  return v
@@ -15,8 +15,6 @@ 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
18
  from pydantic import field_validator
21
19
 
22
20
  from dara.components.common.base_component import ContentComponent
@@ -84,8 +82,8 @@ 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
88
  @field_validator('size', 'inset')
91
89
  @classmethod
@@ -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
@@ -135,11 +134,11 @@ class Stack(LayoutComponent):
135
134
  :param scroll: Whether to scroll the content of the stack, defaults to False
136
135
  """
137
136
 
138
- collapsed: Union[Variable[bool], bool] = False
137
+ collapsed: Variable[bool] | bool = False
139
138
  direction: Direction = Direction.VERTICAL
140
- hug: Union[bool, None] = False
139
+ hug: bool | None = False
141
140
  scroll: bool = False
142
141
 
143
142
  # Dummy init that just passes through arguments to superclass, fixes Pylance complaining about types
144
- def __init__(self, *args: Union[ComponentInstance, None], **kwargs):
143
+ def __init__(self, *args: ComponentInstance | None, **kwargs):
145
144
  super().__init__(*args, **kwargs)
@@ -15,8 +15,6 @@ 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 FormComponent
21
19
  from dara.core.base_definitions import Action
22
20
  from dara.core.interactivity import Variable
@@ -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[Variable[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,8 +15,6 @@ 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
19
  from dara.core.interactivity import ClientVariable
22
20
 
@@ -63,8 +61,8 @@ class TabbedCard(LayoutComponent):
63
61
  :param selected_tab: Optional selected tab mapped to a variable so that the selected tab can be easily accessed
64
62
  """
65
63
 
66
- initial_tab: Optional[str] = None
67
- selected_tab: Optional[ClientVariable] = None
64
+ initial_tab: str | None = None
65
+ selected_tab: ClientVariable | None = None
68
66
 
69
67
 
70
68
  class Tab(LayoutComponent):
@@ -15,8 +15,9 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  """
17
17
 
18
+ from collections.abc import Sequence
18
19
  from enum import Enum
19
- from typing import Any, List, Literal, Optional, Sequence, Union
20
+ from typing import Any, ClassVar, Literal
20
21
 
21
22
  from fastapi.encoders import jsonable_encoder
22
23
  from pandas import DataFrame
@@ -47,6 +48,9 @@ class TableFormatterType(Enum):
47
48
  THRESHOLD = 'threshold'
48
49
 
49
50
 
51
+ TFormatterType = type[TableFormatterType]
52
+
53
+
50
54
  class TableFormatterCompareCondition(Enum):
51
55
  EQUAL = 'equal'
52
56
 
@@ -58,6 +62,9 @@ class TableFilter(Enum):
58
62
  DATETIME = 'datetime'
59
63
 
60
64
 
65
+ TFilterType = type[TableFilter]
66
+
67
+
61
68
  class Column(BaseModel):
62
69
  """
63
70
  Internal representation of a Table column, required for serialization to work correctly
@@ -373,27 +380,24 @@ class Column(BaseModel):
373
380
  :param type: Optional prop to specify type of column, used to determine e.g. filter type. If not specified, inferred from formatters
374
381
  """
375
382
 
376
- align: Optional[str] = None
383
+ align: str | None = None
377
384
  col_id: str
378
- unique_items: Optional[List[str]] = None
379
- filter: Optional[TableFilter] = None
380
- formatter: Optional[dict] = None
381
- label: Optional[str] = Field(default=None, validate_default=True) # mimics always=True in pydantic v1
382
- sticky: Optional[str] = None
383
- tooltip: Optional[str] = None
384
- width: Optional[Union[int, str]] = None
385
- type: Optional[
386
- Union[
387
- Literal['number'],
388
- Literal['string'],
389
- # Generic datetime, assumes datetime64[ns]
390
- Literal['datetime'],
391
- # Specific datetime64 types
392
- Literal['datetime64[ns]'],
393
- Literal['datetime64[ms]'],
394
- Literal['datetime64[s]'],
395
- ]
396
- ] = None
385
+ unique_items: list[str] | None = None
386
+ filter: TableFilter | None = None
387
+ formatter: dict | None = None
388
+ label: str | None = Field(default=None, validate_default=True) # mimics always=True in pydantic v1
389
+ sticky: str | None = None
390
+ tooltip: str | None = None
391
+ width: int | str | None = None
392
+ type: (
393
+ Literal['number']
394
+ | Literal['string']
395
+ | Literal['datetime']
396
+ | Literal['datetime64[ns]']
397
+ | Literal['datetime64[ms]']
398
+ | Literal['datetime64[s]']
399
+ | None
400
+ ) = None
397
401
 
398
402
  model_config = ConfigDict(use_enum_values=True)
399
403
 
@@ -849,21 +853,21 @@ class Table(ContentComponent):
849
853
 
850
854
  model_config = ConfigDict(ser_json_timedelta='float', use_enum_values=True, arbitrary_types_allowed=True)
851
855
 
852
- columns: Optional[Union[Sequence[Union[Column, dict, str]], ClientVariable]] = None
853
- data: Union[AnyVariable, DataFrame, list]
856
+ columns: Sequence[Column | dict | str] | ClientVariable | None = None
857
+ data: AnyVariable | DataFrame | list
854
858
  multi_select: bool = False
855
859
  show_checkboxes: bool = True
856
- onclick_row: Optional[Action] = None
857
- onselect_row: Optional[Action] = None
858
- selected_indices: Optional[Union[List[int], Variable]] = None
859
- search_columns: Optional[List[str]] = None
860
+ onclick_row: Action | None = None
861
+ onselect_row: Action | None = None
862
+ selected_indices: list[int] | Variable | None = None
863
+ search_columns: list[str] | None = None
860
864
  searchable: bool = False
861
865
  include_index: bool = True
862
- max_rows: Optional[int] = None
863
- suppress_click_events_for_selection: Optional[bool] = False
866
+ max_rows: int | None = None
867
+ suppress_click_events_for_selection: bool | None = False
864
868
 
865
- TableFormatterType = TableFormatterType
866
- TableFilter = TableFilter
869
+ TableFormatterType: ClassVar[TFormatterType] = TableFormatterType
870
+ TableFilter: ClassVar[TFilterType] = TableFilter
867
871
 
868
872
  @field_validator('data')
869
873
  @classmethod
@@ -902,7 +906,7 @@ class Table(ContentComponent):
902
906
  def validate_columns(cls, columns):
903
907
  if columns is None:
904
908
  return None
905
- if isinstance(columns, List):
909
+ if isinstance(columns, list):
906
910
  cols = []
907
911
  for col in columns:
908
912
  if isinstance(col, Column):
@@ -917,9 +921,9 @@ class Table(ContentComponent):
917
921
  else:
918
922
  raise ValueError(f'Invalid list passed to Table columns: {columns}, expected a list')
919
923
 
920
- def add_column(self, col: Union[str, dict, Column]):
924
+ def add_column(self, col: str | dict | Column):
921
925
  """Adds a new column to the data"""
922
- if not isinstance(self.columns, List):
926
+ if not isinstance(self.columns, list):
923
927
  raise ValueError('You cannot add_columns to a Variable type columns or if they are undefined')
924
928
  if isinstance(col, str):
925
929
  self.columns.append(Column(col_id=col))
@@ -15,8 +15,6 @@ 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
18
  from pydantic import field_validator
21
19
 
22
20
  from dara.components.common.base_component import ContentComponent
@@ -53,8 +51,8 @@ class Text(ContentComponent):
53
51
  :param formatted: Whether to display the text with existing formatting intact or not, default False
54
52
  """
55
53
 
56
- text: Union[str, ClientVariable]
57
- align: Union[str, None] = 'left' # type: ignore # this is actually textAlign not align-items
54
+ text: str | ClientVariable
55
+ align: str | None = 'left' # type: ignore # this is actually textAlign not align-items
58
56
  formatted: bool = False
59
57
 
60
58
  @field_validator('text')
@@ -64,5 +62,5 @@ class Text(ContentComponent):
64
62
  raise ValueError(f'Invalid text passed to Text: {value}, expected a string')
65
63
  return value
66
64
 
67
- def __init__(self, text: Union[str, ClientVariable], **kwargs):
65
+ def __init__(self, text: str | ClientVariable, **kwargs):
68
66
  super().__init__(text=text, **kwargs)
@@ -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 typing import Any, Literal, Optional
18
+ from typing import Any, Literal
19
19
 
20
20
  from dara.components.common.base_component import FormComponent
21
21
  from dara.core.base_definitions import Action
@@ -49,7 +49,7 @@ class Textarea(FormComponent):
49
49
  """
50
50
 
51
51
  autofocus: bool = False
52
- value: Optional[Variable[Any]] = None
53
- onchange: Optional[Action] = None
54
- id: Optional[str] = None
55
- resize: Optional[Literal['none', 'both', 'horizontal', 'vertical', 'block', 'inline']] = None
52
+ value: Variable[Any] | None = None
53
+ onchange: Action | None = None
54
+ id: str | None = None
55
+ resize: Literal['none', 'both', 'horizontal', 'vertical', 'block', 'inline'] | None = None
@@ -16,7 +16,6 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  import datetime
19
- from typing import Union
20
19
 
21
20
  import numpy
22
21
 
@@ -37,7 +36,7 @@ def date_to_datetime(d: datetime.date, hh=23, mm=59, ss=59) -> datetime.datetime
37
36
  return datetime.datetime(d.year, d.month, d.day, hh, mm, ss)
38
37
 
39
38
 
40
- def coerce_to_timemilli(t: Union[int, float, datetime.date, datetime.datetime]) -> float:
39
+ def coerce_to_timemilli(t: int | float | datetime.date | datetime.datetime) -> float:
41
40
  """Convert any of int/float/date/datetime into a timemilli."""
42
41
  if isinstance(t, (int, numpy.signedinteger, float, numpy.floating)):
43
42
  return float(t)
@@ -15,8 +15,6 @@ 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
18
  from dara.components.common.base_component import ModifierComponent
21
19
  from dara.components.common.stack import Stack
22
20
  from dara.core.definitions import ComponentInstance
@@ -74,14 +72,14 @@ class Tooltip(ModifierComponent):
74
72
  :param styling: Defines the style of the tooltip, can be 'default' or 'error'
75
73
  """
76
74
 
77
- content: Union[str, ComponentInstance, Variable[str], DerivedVariable[str]]
75
+ content: str | ComponentInstance | Variable[str] | DerivedVariable[str]
78
76
  placement: str = 'auto'
79
77
  styling: str = 'default'
80
78
 
81
79
  def __init__(
82
80
  self,
83
- *components: Union[ComponentInstance, None],
84
- content: Union[str, ComponentInstance, Variable[str], DerivedVariable[str]],
81
+ *components: ComponentInstance | None,
82
+ content: str | ComponentInstance | Variable[str] | DerivedVariable[str],
85
83
  placement: str = 'auto',
86
84
  styling: str = 'default',
87
85
  **kwargs,