dara-core 1.21.23__py3-none-any.whl → 1.21.24__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.
@@ -454,6 +454,29 @@ class RouterPath(BaseModel):
454
454
  A URL hash string, beginning with '#'.
455
455
  """
456
456
 
457
+ params: dict[str, ClientVariable | Any] | None = None # type: ignore # noqa: F821
458
+ """
459
+ Optional mapping of dynamic path params to their values.
460
+
461
+ ```python
462
+ from dara.core import RouterPath, Variable
463
+
464
+ foo_var = Variable('foo_value')
465
+
466
+ # Will resolve to '/foo_value/bar'
467
+ path = RouterPath(pathname='/:foo/:bar', params={'foo': foo_var, 'bar': 'bar'})
468
+
469
+ Link('Link to path', to=path)
470
+ ```
471
+ """
472
+
473
+ def __init__(self, **data):
474
+ # Resolve the circular dependency to use ClientVariable as the type of the params
475
+ from dara.core.interactivity.client_variable import ClientVariable # noqa: F401
476
+
477
+ self.model_rebuild()
478
+ super().__init__(**data)
479
+
457
480
 
458
481
  class NavigateOptions(BaseModel):
459
482
  """
dara/core/defaults.py CHANGED
@@ -44,6 +44,8 @@ from dara.core.visual.components import (
44
44
  Fallback,
45
45
  For,
46
46
  ForDef,
47
+ Match,
48
+ MatchDef,
47
49
  Menu,
48
50
  MenuDef,
49
51
  PoweredByCausalens,
@@ -89,6 +91,7 @@ CORE_COMPONENTS: dict[str, ComponentTypeAnnotation] = {
89
91
  cast(str, Fallback.Default.py_component): DefaultFallbackDef,
90
92
  cast(str, Fallback.Row.py_component): RowFallbackDef,
91
93
  cast(str, Fallback.Custom.py_component): CustomFallbackDef,
94
+ Match.__name__: MatchDef,
92
95
  For.__name__: ForDef,
93
96
  Link.__name__: LinkDef,
94
97
  Outlet.__name__: OutletDef,
@@ -44,6 +44,7 @@ from dara.core.interactivity.condition import Condition, Operator
44
44
  from dara.core.interactivity.data_variable import DataVariable
45
45
  from dara.core.interactivity.derived_data_variable import DerivedDataVariable
46
46
  from dara.core.interactivity.derived_variable import DerivedVariable
47
+ from dara.core.interactivity.loop_variable import LoopVariable
47
48
  from dara.core.interactivity.non_data_variable import NonDataVariable
48
49
  from dara.core.interactivity.plain_variable import Variable
49
50
  from dara.core.interactivity.server_variable import ServerVariable
@@ -69,6 +70,7 @@ __all__ = [
69
70
  'DownloadVariable',
70
71
  'DownloadContent',
71
72
  'DownloadContentImpl',
73
+ 'LoopVariable',
72
74
  'NavigateTo',
73
75
  'NavigateToImpl',
74
76
  'Notify',
@@ -2,6 +2,10 @@ from pydantic import Field, SerializerFunctionWrapHandler, model_serializer
2
2
 
3
3
  from .client_variable import ClientVariable
4
4
 
5
+ _INDEX = '__index'
6
+ _IS_LAST = '__is_last'
7
+ _IS_FIRST = '__is_first'
8
+
5
9
 
6
10
  class LoopVariable(ClientVariable):
7
11
  """
@@ -76,6 +80,27 @@ class LoopVariable(ClientVariable):
76
80
  def __getitem__(self, key: str):
77
81
  return self.get(key)
78
82
 
83
+ @property
84
+ def index(self):
85
+ """
86
+ Value of the index of the current item in the list.
87
+ """
88
+ return self.model_copy(update={'nested': [_INDEX]}, deep=True)
89
+
90
+ @property
91
+ def is_last(self):
92
+ """
93
+ Whether the current item is the last item in the list.
94
+ """
95
+ return self.model_copy(update={'nested': [_IS_LAST]}, deep=True)
96
+
97
+ @property
98
+ def is_first(self):
99
+ """
100
+ Whether the current item is the first item in the list.
101
+ """
102
+ return self.model_copy(update={'nested': [_IS_FIRST]}, deep=True)
103
+
79
104
  @property
80
105
  def list_item(self):
81
106
  raise RuntimeError('LoopVariable does not support list_item')
@@ -81,6 +81,44 @@ class _PathParamStore(PersistenceStore):
81
81
  pass
82
82
 
83
83
 
84
+ class _RouteMatchStore(PersistenceStore):
85
+ """
86
+ Internal store for route matches.
87
+ Should not be used directly, Dara will use this internally to keep a variable
88
+ in sync with the current route matches.
89
+ """
90
+
91
+ async def init(self, variable: 'Variable'):
92
+ # noop
93
+ pass
94
+
95
+
96
+ class RouteMatch(BaseModel):
97
+ """
98
+ Data structure representing a route match in the router
99
+ """
100
+
101
+ id: str
102
+ """
103
+ Route ID, as set when defining the route
104
+ """
105
+
106
+ pathname: str
107
+ """
108
+ Full pathname of the route
109
+ """
110
+
111
+ params: dict[str, Any]
112
+ """
113
+ Mapping of dynamic path params to their values
114
+ """
115
+
116
+ definition: 'BaseRoute'
117
+ """
118
+ Definition of the route
119
+ """
120
+
121
+
84
122
  class RouteData(BaseModel):
85
123
  """
86
124
  Data structure representing a route in the router
@@ -709,6 +747,12 @@ class Router(HasChildRoutes):
709
747
  building routes step by step, while the object API is more declarative and compact.
710
748
  """
711
749
 
750
+ route_matches: Variable[list[RouteMatch]] = Field(default_factory=lambda: Variable([], store=_RouteMatchStore()))
751
+ """
752
+ Variable containing current list of route matches.
753
+ Note that this will be updated by Dara automatically, so you should not modify it directly.
754
+ """
755
+
712
756
  def __init__(self, *children: BaseRoute, **kwargs):
713
757
  routes = list(children)
714
758
  if 'children' not in kwargs: