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
@@ -14,6 +14,7 @@ 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.common.accordion import Accordion, AccordionItem
19
20
  from dara.components.common.anchor import Anchor
@@ -33,8 +34,12 @@ from dara.components.common.card import Card
33
34
  from dara.components.common.carousel import Carousel
34
35
  from dara.components.common.checkbox_group import CheckboxGroup
35
36
  from dara.components.common.code import Code
36
- from dara.components.common.component_select_list import ComponentSelectList
37
+ from dara.components.common.component_select_list import (
38
+ ComponentItem,
39
+ ComponentSelectList,
40
+ )
37
41
  from dara.components.common.datepicker import Datepicker
42
+ from dara.components.common.dropdown_menu import DropdownMenu, MenuItem
38
43
  from dara.components.common.dropzone import UploadDropzone
39
44
  from dara.components.common.form import Form
40
45
  from dara.components.common.form_page import FormPage
@@ -51,7 +56,7 @@ from dara.components.common.modal import Modal
51
56
  from dara.components.common.overlay import Overlay
52
57
  from dara.components.common.paragraph import Paragraph
53
58
  from dara.components.common.progress_bar import ProgressBar
54
- from dara.components.common.radio_group import RadioGroup
59
+ from dara.components.common.radio_group import RadioGroup, RadioItem
55
60
  from dara.components.common.select import ListSection, Select
56
61
  from dara.components.common.slider import Slider
57
62
  from dara.components.common.spacer import Spacer
@@ -80,8 +85,10 @@ __all__ = [
80
85
  'CheckboxGroup',
81
86
  'Code',
82
87
  'ComponentSelectList',
88
+ 'ComponentItem',
83
89
  'Datepicker',
84
90
  'Direction',
91
+ 'DropdownMenu',
85
92
  'Form',
86
93
  'FormPage',
87
94
  'Grid',
@@ -95,6 +102,7 @@ __all__ = [
95
102
  'ItemBadge',
96
103
  'Label',
97
104
  'ListSection',
105
+ 'MenuItem',
98
106
  'Markdown',
99
107
  'Modal',
100
108
  'Overlay',
@@ -106,6 +114,7 @@ __all__ = [
106
114
  'Stack',
107
115
  'Switch',
108
116
  'RadioGroup',
117
+ 'RadioItem',
109
118
  'Text',
110
119
  'Textarea',
111
120
  'Tab',
@@ -15,15 +15,16 @@ 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
- from pydantic import BaseModel, validator
20
+ from pydantic import field_validator
21
21
 
22
22
  from dara.components.common.base_component import LayoutComponent
23
23
  from dara.components.common.utils import ItemBadge
24
24
  from dara.core.base_definitions import Action
25
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
25
26
  from dara.core.definitions import ComponentInstance
26
- from dara.core.interactivity import UrlVariable, Variable
27
+ from dara.core.interactivity import Variable
27
28
  from dara.core.logging import dev_logger
28
29
 
29
30
 
@@ -78,9 +79,9 @@ class AccordionItem(BaseModel):
78
79
  :param content: Optional content to render
79
80
  """
80
81
 
81
- badge: Optional[ItemBadge]
82
- label: Union[str, ComponentInstance]
83
- content: Optional[ComponentInstance]
82
+ badge: ItemBadge | None = None
83
+ label: str | ComponentInstance
84
+ content: ComponentInstance | None = None
84
85
 
85
86
 
86
87
  class Accordion(LayoutComponent):
@@ -163,7 +164,7 @@ class Accordion(LayoutComponent):
163
164
  For these components you can set a height, for example:
164
165
 
165
166
  ```python
166
- from dara.core import get_icon, ConfigurationBuilder, DataVariable
167
+ from dara.core import get_icon, ConfigurationBuilder, ServerVariable
167
168
  from dara.components.common import ComponentInstance, Table, Accordion, AccordionItem
168
169
  from dara.components.graphs import CausalGraphViewer
169
170
  from dara.components.graphs.graph_layout import PlanarLayout
@@ -184,7 +185,7 @@ class Accordion(LayoutComponent):
184
185
 
185
186
 
186
187
  # creates Table data
187
- table_data = DataVariable(
188
+ table_data = ServerVariable(
188
189
  DataFrame(
189
190
  [
190
191
  {
@@ -232,7 +233,7 @@ class Accordion(LayoutComponent):
232
233
 
233
234
 
234
235
  config = ConfigurationBuilder()
235
- config.add_page(name='Accordion Page', content=accordion(), icon=get_icon('chart-line'))
236
+ config.router.add_page(path='accordion', content=accordion)
236
237
  ```
237
238
 
238
239
  For more examples check the AccordionItem documentation.
@@ -244,29 +245,22 @@ class Accordion(LayoutComponent):
244
245
  :param onchange: An action to triggered when the component's state changes
245
246
  """
246
247
 
247
- initial: Optional[Union[int, List[int]]] = 0
248
- value: Optional[
249
- Union[
250
- Variable[Union[int, List[int]]],
251
- UrlVariable[Union[int, List[int]]],
252
- int,
253
- List[int],
254
- ]
255
- ] = 0
256
- onchange: Optional[Action] = None
257
- items: List[AccordionItem]
258
- multi: Optional[bool] = True
259
-
260
- @validator('initial', pre=True)
248
+ initial: int | list[int] | None = 0
249
+ value: Variable[int | list[int]] | int | list[int] | None = 0
250
+ onchange: Action | None = None
251
+ items: list[AccordionItem]
252
+ multi: bool | None = True
253
+
254
+ @field_validator('initial', mode='before')
261
255
  @classmethod
262
- def validate_initial(cls, initial: Any) -> Union[int, List[int]]:
256
+ def validate_initial(cls, initial: Any) -> int | list[int]:
263
257
  if initial is not None:
264
258
  dev_logger.warning("Accordion's initial prop is now deprecated, please use value instead.")
265
259
  return initial
266
260
 
267
- @validator('items', pre=True)
261
+ @field_validator('items', mode='before')
268
262
  @classmethod
269
- def validate_items(cls, items: Any) -> List[AccordionItem]:
263
+ def validate_items(cls, items: Any) -> list[AccordionItem]:
270
264
  if not isinstance(items, list):
271
265
  raise ValueError('AccordionItems must be passed as a list to the Accordion component')
272
266
  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 List, Optional, Union
18
+ from typing_extensions import deprecated
19
19
 
20
20
  from dara.components.common.base_component import (
21
21
  ContentComponent,
@@ -23,10 +23,11 @@ from dara.components.common.base_component import (
23
23
  ModifierComponent,
24
24
  )
25
25
  from dara.components.common.text import Text
26
- from dara.core.definitions import TemplateMarker, discover
26
+ from dara.core.definitions import discover
27
27
  from dara.core.interactivity import AnyVariable, DerivedVariable, Variable
28
28
 
29
29
 
30
+ @deprecated('Use `dara.core.Link` instead')
30
31
  @discover
31
32
  class Anchor(ModifierComponent):
32
33
  """
@@ -60,19 +61,17 @@ class Anchor(ModifierComponent):
60
61
  :param new_tab: whether to open the link in a new tab
61
62
  """
62
63
 
63
- href: Optional[str] = None
64
- name: Optional[str] = None
64
+ href: str | None = None
65
+ name: str | None = None
65
66
  clean: bool = False
66
67
  new_tab: bool = False
67
68
 
68
- def __init__(
69
- self, child: Union[ContentComponent, str, Variable[str], DerivedVariable[str], TemplateMarker], **kwargs
70
- ):
71
- if isinstance(child, (ContentComponent, Variable, DerivedVariable, TemplateMarker, str)) is False:
69
+ def __init__(self, child: ContentComponent | str | Variable[str] | DerivedVariable[str], **kwargs):
70
+ if isinstance(child, (ContentComponent, Variable, DerivedVariable, str)) is False:
72
71
  raise LayoutError(f'Only a single ContentComponent may be passed as an Anchors child, passed : {child}')
73
72
 
74
73
  # Handle a string or Variable being passed directly to an anchor
75
- if isinstance(child, (str, AnyVariable, TemplateMarker)):
74
+ if isinstance(child, (str, AnyVariable)):
76
75
  child = Text(child)
77
- parsed_args: List[ContentComponent] = [child]
76
+ parsed_args: list[ContentComponent] = [child]
78
77
  super().__init__(*parsed_args, **kwargs)
@@ -15,7 +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 Literal, Optional
18
+ from typing import Literal
19
+
20
+ from pydantic import ConfigDict
19
21
 
20
22
  from dara.core.definitions import ComponentInstance, StyledComponentInstance
21
23
 
@@ -40,25 +42,6 @@ JustifyContent = Literal[
40
42
  None,
41
43
  ]
42
44
 
43
- AlignItems = Literal[
44
- '-moz-initial',
45
- 'baseline',
46
- 'center',
47
- 'end',
48
- 'flex-end',
49
- 'flex-start',
50
- 'inherit',
51
- 'initial',
52
- 'normal',
53
- 'revert',
54
- 'self-end',
55
- 'self-start',
56
- 'start',
57
- 'stretch',
58
- 'unset',
59
- None,
60
- ]
61
-
62
45
 
63
46
  class LayoutError(Exception):
64
47
  """An Error type for when the layout is invalid"""
@@ -69,16 +52,20 @@ class BaseDashboardComponent(StyledComponentInstance):
69
52
  The base Component class for all other dashboarding components to extend from.
70
53
  """
71
54
 
55
+ model_config = ConfigDict(extra='forbid', use_enum_values=True)
56
+
72
57
  # Define JS module on the base component so we don't have to repeat that on each component
73
58
  js_module = '@darajs/components'
74
59
 
75
- class Config:
76
- smart_union = True
77
- extra = 'forbid'
78
- use_enum_values = True
60
+ def __init__(self, *args: ComponentInstance | None, **kwargs):
61
+ if len(args) > 0 and len(kwargs.get('children') or []) == 0:
62
+ kwargs['children'] = list(arg for arg in args if arg is not None)
79
63
 
80
- def __init__(self, *args: ComponentInstance, **kwargs):
81
- super().__init__(children=list(args), **kwargs)
64
+ # Fallback
65
+ if 'children' not in kwargs:
66
+ kwargs['children'] = []
67
+
68
+ super().__init__(**kwargs)
82
69
 
83
70
 
84
71
  class LayoutComponent(BaseDashboardComponent):
@@ -91,9 +78,9 @@ class LayoutComponent(BaseDashboardComponent):
91
78
  :param align: the align-items value to be passed to the component
92
79
  """
93
80
 
94
- position: str = 'relative'
95
- justify: Optional[JustifyContent] = None
96
- align: Optional[AlignItems] = None
81
+ position: str | None = 'relative'
82
+
83
+ justify: JustifyContent | None = None
97
84
 
98
85
  def append(self, component: ComponentInstance):
99
86
  """
@@ -102,18 +89,18 @@ class LayoutComponent(BaseDashboardComponent):
102
89
 
103
90
  :param component: the component to add, can be any type of BaseComponent
104
91
  """
105
- if isinstance(component, ComponentInstance) is False:
92
+ if ComponentInstance.isinstance(component) is False:
106
93
  name = self.__class__.__name__
107
94
  raise TypeError(f'You may only append other components to a {name} component. Not: {component}')
108
- self.children.append(component) # type: ignore
95
+ self.children.append(component) # type: ignore
109
96
 
110
97
  def pop(self):
111
98
  """
112
99
  Pops the last child from the list of children and returns it. Raises an IndexError if the parent is empty
113
100
  """
114
- if len(self.children) == 0: # type: ignore
101
+ if len(self.children) == 0: # type: ignore
115
102
  raise IndexError(f'{self.__class__.__name__} is empty')
116
- return self.children.pop() # type: ignore
103
+ return self.children.pop() # type: ignore
117
104
 
118
105
 
119
106
  class ContentComponent(BaseDashboardComponent):
@@ -127,8 +114,8 @@ class ContentComponent(BaseDashboardComponent):
127
114
  super().__init__(*args, **kwargs)
128
115
 
129
116
  cmp_name = self.__class__.__name__
130
- if len(self.children) != 0: # type: ignore
131
- for child in self.children: # type: ignore # pylint: disable=not-an-iterable
117
+ if len(self.children) != 0: # type: ignore
118
+ for child in self.children: # type: ignore
132
119
  if isinstance(child, LayoutComponent):
133
120
  raise LayoutError(f'A {child.__class__.__name__} component cannot be nested inside a {cmp_name}')
134
121
 
@@ -151,4 +138,4 @@ class FormComponent(InteractiveComponent):
151
138
  A subset of InteractiveComponents which must subscribe to the Form context.
152
139
  """
153
140
 
154
- id: Optional[str] = None
141
+ 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 List, Union
19
-
20
18
  from dara.components.common.base_component import ContentComponent
21
19
  from dara.core.interactivity import DerivedVariable, Variable
22
20
 
@@ -42,5 +40,5 @@ class BulletList(ContentComponent):
42
40
  :param numbered: Boolean, if True then number the bullets
43
41
  """
44
42
 
45
- items: Union[List[str], Variable, DerivedVariable]
43
+ items: list[str] | Variable | DerivedVariable
46
44
  numbered: bool = False
@@ -16,14 +16,14 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  from enum import Enum
19
- from typing import Optional, Union
19
+ from typing import cast
20
20
 
21
21
  from dara.components.common.base_component import LayoutComponent
22
22
  from dara.components.common.text import Text
23
23
  from dara.core import ComponentInstance
24
24
  from dara.core.base_definitions import Action
25
- from dara.core.definitions import TemplateMarker, discover
26
- from dara.core.interactivity import Condition, NonDataVariable
25
+ from dara.core.definitions import discover
26
+ from dara.core.interactivity import ClientVariable, Condition
27
27
 
28
28
 
29
29
  class ButtonStyle(str, Enum):
@@ -48,18 +48,20 @@ class Button(LayoutComponent):
48
48
  A button component with an icon and styling:
49
49
 
50
50
  ```python
51
-
52
- from dara.core import NavigateTo
51
+ from dara.core import action
53
52
  from dara.components import Button, ButtonStyle
54
53
 
54
+ @action
55
+ async def navigate_to(ctx: action.Ctx, url: str):
56
+ await ctx.navigate(url)
57
+
55
58
  Button(
56
59
  'Click',
57
- onclick=NavigateTo('/test'),
60
+ onclick=navigate_to('/test'),
58
61
  icon='Pen',
59
62
  styling=ButtonStyle.SECONDARY,
60
63
  outline=True,
61
64
  )
62
-
63
65
  ```
64
66
 
65
67
  The different button styles supported are: 'error', 'ghost', 'plain', 'primary' and 'secondary'. Other styling option
@@ -69,17 +71,20 @@ class Button(LayoutComponent):
69
71
 
70
72
  ```python
71
73
 
72
- from dara.core import Variable, NavigateTo
74
+ from dara.core import Variable, action
73
75
  from dara.components import Button
74
76
 
75
77
  disabled = Variable(True)
76
78
 
79
+ @action
80
+ async def navigate_to(ctx: action.Ctx, url: str):
81
+ await ctx.navigate(url)
82
+
77
83
  Button(
78
84
  'Click',
79
85
  disabled=disabled,
80
- onclick=NavigateTo('/test),
86
+ onclick=navigate_to('/test'),
81
87
  )
82
-
83
88
  ```
84
89
 
85
90
  A button component can also take any component inside of it to make it into some clickable component.
@@ -87,49 +92,53 @@ class Button(LayoutComponent):
87
92
 
88
93
  ```python
89
94
 
90
- from dara.core import NavigateTo
95
+ from dara.core import action
91
96
  from dara.components import Button, Stack, Text
92
97
 
98
+ @action
99
+ async def navigate_to(ctx: action.Ctx, url: str):
100
+ await ctx.navigate(url)
101
+
93
102
  Button(
94
103
  Stack(
95
104
  Text(
96
105
  'Stack passed to button, when clicked I navigate to test page',
97
106
  ),
98
107
  ),
99
- onclick=NavigateTo('/test'),
108
+ onclick=navigate_to('/test'),
100
109
  )
101
-
102
110
  ```
103
111
 
104
112
  :param disabled: A variable, condition, or bool to disabled the button when true
113
+ :param loading: A variable, condition, or bool to set the button to a loading state, showing a spinner.
114
+ By default, the button will automatically be set to loading=True while the onclick action is running,
115
+ equivalent to `Button(..., onclick=my_action, loading=my_action.loading)`. You can opt out of this behaviour by
116
+ simply setting `loading=False`.
105
117
  :param onclick: An Action that is triggered by clicking the button
106
118
  :param icon: An optional icon to display, see dara.core.css.get_icon for details
107
119
  :param styling: A style of the button, can be 'primary', 'secondary', 'error', 'plain' or 'ghost'
108
120
  :param outline: This allows to pick between two styles, if False the button is filled with a solid background color,
109
121
  if True it shows a transparent background with an outlined colored border. Filled buttons are more prominent and
110
122
  often used as primary actions, while outline buttons are more subtle and commonly used as secondary actions.
123
+ :param stop_click_propagation: Whether to stop the click event from propagating to the parent element, defaults to true
111
124
  """
112
125
 
113
- disabled: Optional[Union[Condition, NonDataVariable, bool]] = None
114
- onclick: Optional[Action] = None
115
- icon: Optional[str] = None
116
- styling: Optional[ButtonStyle] = None
126
+ disabled: Condition | ClientVariable | bool | None = None
127
+ loading: Condition | ClientVariable | bool | None = None
128
+ onclick: Action | None = None
129
+ icon: str | None = None
130
+ styling: ButtonStyle | None = None
117
131
  outline: bool = False
118
-
119
- class Config:
120
- smart_union = True
132
+ stop_click_propagation: bool = True
121
133
 
122
134
  def __init__(
123
- self,
124
- children: Union[str, ComponentInstance, NonDataVariable, TemplateMarker],
125
- styling: Optional[ButtonStyle] = None,
126
- **kwargs
135
+ self, children: str | ComponentInstance | ClientVariable, styling: ButtonStyle | None = None, **kwargs
127
136
  ):
128
137
  child = children
129
138
  style = styling if styling is not None else ButtonStyle.PRIMARY
130
- if isinstance(children, (str, NonDataVariable, TemplateMarker)):
139
+ if isinstance(children, (str, ClientVariable)):
131
140
  child = Text(text=children)
132
141
  if not styling and isinstance(children, ComponentInstance) and not isinstance(children, Text):
133
142
  style = ButtonStyle.PLAIN
134
143
 
135
- super().__init__(child, styling=style, **kwargs)
144
+ super().__init__(cast(ComponentInstance, child), styling=style, **kwargs)
@@ -16,14 +16,14 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  from enum import Enum
19
- from typing import Any, List, Optional, Union
19
+ from typing import Any
20
20
 
21
- from pydantic import validator
21
+ from pydantic import field_validator
22
22
 
23
23
  from dara.components.common.base_component import FormComponent
24
24
  from dara.components.common.utils import Item
25
25
  from dara.core.base_definitions import Action
26
- from dara.core.interactivity import UrlVariable, Variable
26
+ from dara.core.interactivity import Variable
27
27
 
28
28
 
29
29
  class ButtonBarStyle(str, Enum):
@@ -41,57 +41,62 @@ class ButtonBar(FormComponent):
41
41
  A simple button bar component:
42
42
 
43
43
  ```python
44
-
45
44
  from dara.core import Variable
46
45
  from dara.components.common import ButtonBar, Item
47
46
 
47
+ bar_var = Variable('val2')
48
+
48
49
  ButtonBar(
49
50
  items=[
50
51
  Item(label='Value 1', value='val1'),
51
52
  Item(label='Value 2', value='val2'),
52
53
  Item(label='Value 3', value='val3'),
53
54
  ],
54
- value=Variable('val2')
55
+ value=bar_var,
55
56
  )
56
-
57
57
  ```
58
58
 
59
59
  A ButtonBar component with onchange:
60
60
 
61
61
  ```python
62
-
63
- from dara.core import Variable, Notify
62
+ from dara.core import Variable, action
64
63
  from dara.components.common import ButtonBar, Item
65
64
 
65
+ bar_var = Variable('val2')
66
+
67
+ @action
68
+ async def notify_change(ctx: action.Ctx):
69
+ bar = ctx.input
70
+ await ctx.notify(title='Alert', message=f'ButtonBar value changed to {bar}', status='SUCCESS')
71
+
66
72
  ButtonBar(
67
73
  items=[
68
74
  Item(label='Value 1', value='val1'),
69
75
  Item(label='Value 2', value='val2'),
70
76
  Item(label='Value 3', value='val3'),
71
77
  ],
72
- value=Variable('val2')
73
- onchange=Notify(message='ButtonBar value changed'),
78
+ value=bar_var,
79
+ onchange=notify_change(),
74
80
  )
75
-
76
81
  ```
77
82
 
78
83
  A button bar component with styling:
79
84
 
80
85
  ```python
81
-
82
86
  from dara.core import Variable
83
87
  from dara.components.common import ButtonBar, ButtonBarStyle, Item
84
88
 
89
+ bar_var = Variable('val2')
90
+
85
91
  ButtonBar(
86
92
  items=[
87
93
  Item(label='Value 1', value='val1'),
88
94
  Item(label='Value 2', value='val2'),
89
95
  Item(label='Value 3', value='val3'),
90
96
  ],
91
- value=Variable('val2'),
97
+ value=bar_var,
92
98
  styling=ButtonBarStyle.SECONDARY
93
99
  )
94
-
95
100
  ```
96
101
 
97
102
  :param items: An Item list that defines the button labels
@@ -101,15 +106,15 @@ class ButtonBar(FormComponent):
101
106
  :param styling: A style of the ButtonBar, can be 'primary' or 'secondary'
102
107
  """
103
108
 
104
- items: List[Item]
105
- value: Optional[Union[Variable, UrlVariable]] = None
106
- onchange: Optional[Action] = None
107
- id: Optional[str] = None
109
+ items: list[Item]
110
+ value: Variable | None = None
111
+ onchange: Action | None = None
112
+ id: str | None = None
108
113
  styling: ButtonBarStyle = ButtonBarStyle.PRIMARY
109
114
 
110
- @validator('items', pre=True)
115
+ @field_validator('items', mode='before')
111
116
  @classmethod
112
- def validate_items(cls, items: Any) -> List[Item]:
117
+ def validate_items(cls, items: Any) -> list[Item]:
113
118
  if not isinstance(items, list):
114
119
  raise ValueError('Items must be passed as a list to the button bar component')
115
120
  if len(items) == 0:
@@ -15,9 +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
19
+ from dara.core import ClientVariable
21
20
  from dara.core.definitions import ComponentInstance
22
21
 
23
22
 
@@ -52,9 +51,9 @@ class Card(LayoutComponent):
52
51
  :param align: How to align the content of the card, accepts any flexbox alignments
53
52
  """
54
53
 
55
- subtitle: Optional[str] = None
56
- title: Optional[str] = None
54
+ subtitle: str | ClientVariable | None = None
55
+ title: str | ClientVariable | None = None
57
56
  accent: bool = False
58
57
 
59
- def __init__(self, *args: ComponentInstance, **kwargs):
58
+ def __init__(self, *args: ComponentInstance | None, **kwargs):
60
59
  super().__init__(*args, **kwargs)
@@ -15,14 +15,14 @@ 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
- from pydantic import validator
20
+ from pydantic import field_validator
21
21
 
22
22
  from dara.components.common.base_component import ContentComponent
23
23
  from dara.components.common.utils import CarouselItem
24
24
  from dara.core.base_definitions import Action
25
- from dara.core.interactivity import NonDataVariable, UrlVariable, Variable
25
+ from dara.core.interactivity import ClientVariable, Variable
26
26
 
27
27
 
28
28
  class Carousel(ContentComponent):
@@ -118,14 +118,14 @@ class Carousel(ContentComponent):
118
118
  :param onchange: Action triggered when the component changes states
119
119
  """
120
120
 
121
- items: Union[List[CarouselItem], NonDataVariable]
122
- value: Optional[Union[Variable[int], UrlVariable[int]]] = None
123
- onchange: Optional[Action] = None
121
+ items: list[CarouselItem] | ClientVariable
122
+ value: Variable[int] | None = None
123
+ onchange: Action | None = None
124
124
 
125
- @validator('items', pre=True)
125
+ @field_validator('items', mode='before')
126
126
  @classmethod
127
- def validate_items(cls, items: Any) -> Union[List[CarouselItem], NonDataVariable]:
128
- if isinstance(items, NonDataVariable):
127
+ def validate_items(cls, items: Any) -> list[CarouselItem] | ClientVariable:
128
+ if isinstance(items, ClientVariable):
129
129
  return items
130
130
  if not isinstance(items, list):
131
131
  raise ValueError('CarouselItem must be passed as a list to the Carousel component')