instaui 0.2.1__py2.py3-none-any.whl → 0.3.0__py2.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 (48) hide show
  1. instaui/arco/components/select.py +2 -1
  2. instaui/components/component.py +3 -1
  3. instaui/components/container.py +32 -0
  4. instaui/components/element.py +1 -4
  5. instaui/components/heading.py +46 -0
  6. instaui/components/match.py +20 -84
  7. instaui/components/slot.py +53 -19
  8. instaui/components/vfor.py +39 -44
  9. instaui/components/vif.py +10 -22
  10. instaui/event/js_event.py +10 -8
  11. instaui/event/vue_event.py +14 -16
  12. instaui/event/web_event.py +11 -8
  13. instaui/html_tools.py +8 -2
  14. instaui/js/fn.py +13 -10
  15. instaui/runtime/__init__.py +2 -2
  16. instaui/runtime/_app.py +43 -35
  17. instaui/runtime/scope.py +117 -33
  18. instaui/spa_router/_functions.py +4 -4
  19. instaui/spa_router/_route_model.py +6 -7
  20. instaui/spa_router/_router_output.py +5 -1
  21. instaui/spa_router/_router_param_var.py +4 -9
  22. instaui/static/insta-ui.css +1 -1
  23. instaui/static/insta-ui.esm-browser.prod.js +2313 -2361
  24. instaui/static/insta-ui.js.map +1 -1
  25. instaui/ui/__init__.py +7 -2
  26. instaui/ui/__init__.pyi +7 -2
  27. instaui/ui_functions/input_slient_data.py +4 -0
  28. instaui/ui_system_var_type.py +6 -0
  29. instaui/vars/_types.py +14 -0
  30. instaui/vars/data.py +7 -4
  31. instaui/vars/element_ref.py +13 -10
  32. instaui/vars/event_context.py +7 -3
  33. instaui/vars/js_computed.py +4 -4
  34. instaui/vars/mixin_types/py_binding.py +40 -0
  35. instaui/vars/path_var.py +7 -0
  36. instaui/vars/ref.py +7 -2
  37. instaui/vars/slot_prop.py +22 -14
  38. instaui/vars/state.py +23 -12
  39. instaui/vars/vfor_item.py +170 -72
  40. instaui/vars/vue_computed.py +4 -4
  41. instaui/vars/web_computed.py +10 -6
  42. instaui/watch/js_watch.py +6 -6
  43. instaui/watch/vue_watch.py +25 -2
  44. instaui/watch/web_watch.py +15 -6
  45. {instaui-0.2.1.dist-info → instaui-0.3.0.dist-info}/METADATA +1 -1
  46. {instaui-0.2.1.dist-info → instaui-0.3.0.dist-info}/RECORD +48 -45
  47. {instaui-0.2.1.dist-info → instaui-0.3.0.dist-info}/WHEEL +0 -0
  48. {instaui-0.2.1.dist-info → instaui-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -45,7 +45,8 @@ class Select(Element):
45
45
  )
46
46
 
47
47
  with self.add_slot("default"):
48
- with ui.vfor.from_dict(options) as item: # type: ignore
48
+ with ui.vfor(options) as item:
49
+ item = ui.iter_info(item)
49
50
  Select.Option(item.dict_value).props(
50
51
  {"value": item.dict_key, "label": item.dict_value}
51
52
  )
@@ -44,6 +44,8 @@ class Component(Jsonable):
44
44
  self._slot_manager.default.__exit__(*_)
45
45
 
46
46
  def _to_json_dict(self) -> Dict:
47
- return {
47
+ data: Dict = {
48
48
  "tag": self._tag,
49
49
  }
50
+
51
+ return data
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+ from instaui.components.element import Element
3
+ from instaui.vars.types import TMaybeRef
4
+
5
+
6
+ class Container(Element):
7
+ """
8
+ Creates a layout container element with configurable width and spacing properties.
9
+
10
+ A flexible container component for structuring content layouts, providing controls for
11
+ maximum width and internal padding. The container is horizontally centered by default
12
+ through auto margins.
13
+
14
+ Args:
15
+ max_width (TMaybeRef[str], optional): Sets the maximum width of the container.
16
+ Accepts CSS width values (e.g., "800px", "100%", "75vw"). Defaults to "800px".
17
+ padding (TMaybeRef[str], optional): Controls internal spacing between container
18
+ edges and content. Accepts CSS padding values (e.g., "0.25rem", "1em", "10px").
19
+ Defaults to "0.25rem".
20
+ """
21
+
22
+ def __init__(
23
+ self,
24
+ max_width: TMaybeRef[str] = "800px",
25
+ *,
26
+ padding: TMaybeRef[str] = "0.25rem",
27
+ ):
28
+ super().__init__("div")
29
+
30
+ self.style({"max-width": max_width, "padding": padding}).style(
31
+ "margin-left:auto;margin-right:auto"
32
+ )
@@ -23,7 +23,6 @@ from typing import (
23
23
  from typing_extensions import Self
24
24
  from collections import defaultdict
25
25
  from instaui.runtime._app import get_app_slot
26
- from instaui.runtime._app import get_current_scope
27
26
  from instaui.vars.element_ref import ElementRef
28
27
  from instaui.vars.vfor_item import VForItem
29
28
  from instaui.components.directive import Directive
@@ -468,9 +467,7 @@ class Element(Component):
468
467
  )
469
468
 
470
469
  if self.__element_ref:
471
- scope = get_current_scope()
472
- data["eRef"] = self.__element_ref._to_element_config()
473
- scope.register_element_ref(self.__element_ref)
470
+ data["eRef"] = self.__element_ref._to_element_binding_config()
474
471
 
475
472
  return data
476
473
 
@@ -0,0 +1,46 @@
1
+ from __future__ import annotations
2
+ from typing import Any, Union
3
+ from instaui.components.element import Element
4
+ from instaui.vars.types import TMaybeRef
5
+ from instaui import ui_system_var_type as ui_vars_type
6
+
7
+
8
+ class Heading(Element):
9
+ def __init__(
10
+ self,
11
+ text: Union[str, TMaybeRef[Any]],
12
+ *,
13
+ size: Union[TMaybeRef[str], ui_vars_type.TSize, None] = None,
14
+ weight: Union[TMaybeRef[str], ui_vars_type.TWeight, None] = None,
15
+ align: Union[TMaybeRef[str], ui_vars_type.TAlign, None] = None,
16
+ ):
17
+ """
18
+ Creates a heading element with customizable text content and styling properties.
19
+
20
+
21
+ Args:
22
+ text (Union[str, TMaybeRef[Any]]): The text content of the heading. Can be a static
23
+ string or a reactive reference (e.g., state object).
24
+ size (Union[TMaybeRef[str], TSize, None], optional): Controls the heading size.
25
+ Accepts values from "1" to "9". Defaults to None.
26
+ weight (Union[TMaybeRef[str], TWeight, None], optional): Sets font weight.
27
+ Acceptable values: "light", "regular", "medium", "bold". Defaults to None.
28
+ align (Union[TMaybeRef[str], TAlign, None], optional): Controls text alignment.
29
+ Valid options: "left", "center", "right". Defaults to None.
30
+
31
+ Example:
32
+ .. code-block:: python
33
+ size = ui.state("6")
34
+ text = ui.state("test")
35
+ align = ui.state("left")
36
+
37
+ arco.select(["1", "2", "3", "4", "5", "6", "7", "8", "9"], size)
38
+ arco.select(["left", "center", "right"], align, allow_clear=True)
39
+
40
+ with ui.container():
41
+ arco.input(text)
42
+ ui.heading(text, size=size, align=align)
43
+ """
44
+ super().__init__("heading")
45
+
46
+ self.props({"text": text, "size": size, "weight": weight, "align": align})
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import typing
4
4
  from instaui.components.component import Component
5
- from instaui.runtime._app import new_scope
6
5
 
7
6
  from instaui.vars.mixin_types.element_binding import ElementBindingProtocol
8
7
 
@@ -11,96 +10,33 @@ class Match(Component):
11
10
  def __init__(self, on: ElementBindingProtocol):
12
11
  super().__init__("match")
13
12
  self._on = on
14
- self._default_case = None
13
+ self.cass_id_count = -1
14
+ self._case_values = []
15
15
 
16
- def _to_json_dict(self):
17
- data = super()._to_json_dict()
18
- data["props"] = {
19
- "on": self._on._to_element_binding_config(),
20
- }
21
- props: typing.Dict = data["props"]
22
-
23
- props["case"] = [
24
- item
25
- for item in self._slot_manager.default._children
26
- if isinstance(item, Case)
27
- ]
28
-
29
- if self._default_case:
30
- props["default"] = self._default_case
31
-
32
- data.pop("slots", None)
33
-
34
- return data
35
-
36
- def case(self, value: typing.Any) -> Case:
37
- with self:
38
- case = Case(value)
39
-
40
- return case
41
-
42
- def default(self) -> DefaultCase:
43
- with self:
44
- self._default_case = DefaultCase()
45
-
46
- return self._default_case
47
-
48
-
49
- class Case(Component):
50
- def __init__(self, value: typing.Any):
51
- super().__init__("case")
52
- self._value = value
53
- self.__scope_manager = new_scope()
54
- self.__scope = None
16
+ def case(self, value: typing.Any):
17
+ self.cass_id_count += 1
18
+ self._case_values.append(value)
19
+ return self._slot_manager.get_slot(str(self.cass_id_count))
55
20
 
56
- def __enter__(self):
57
- self.__scope = self.__scope_manager.__enter__()
58
- return super().__enter__()
59
-
60
- def __exit__(self, *_) -> None:
61
- self.__scope_manager.__exit__(*_)
62
- return super().__exit__(*_)
21
+ def default(self):
22
+ return self._slot_manager.get_slot(":default")
63
23
 
64
24
  def _to_json_dict(self):
65
25
  data = super()._to_json_dict()
66
- data["props"] = {
67
- "value": self._value,
68
- }
69
- props = data["props"]
70
-
71
- props["scopeId"] = self.__scope.id # type: ignore
72
-
73
- if self._slot_manager.has_slot():
74
- props["items"] = self._slot_manager
75
-
76
- data.pop("slots", None)
77
- return data
78
-
26
+ data["on"] = self._on._to_element_binding_config()
27
+ data["caseValues"] = self._case_values
79
28
 
80
- class DefaultCase(Component):
81
- def __init__(self):
82
- super().__init__("default-case")
83
-
84
- self.__scope_manager = new_scope()
85
- self.__scope = None
86
-
87
- def __enter__(self):
88
- self.__scope = self.__scope_manager.__enter__()
89
- return super().__enter__()
90
-
91
- def __exit__(self, *_) -> None:
92
- self.__scope_manager.__exit__(*_)
93
- return super().__exit__(*_)
94
-
95
- def _to_json_dict(self):
96
- data = super()._to_json_dict()
97
- data["props"] = {}
98
- props = data["props"]
29
+ data["slots"] = {
30
+ name: slot
31
+ for name, slot in self._slot_manager._slots.items()
32
+ if name != ":"
33
+ }
99
34
 
100
- props["scopeId"] = self.__scope.id # type: ignore
35
+ default_slot = self._slot_manager.get_slot(
36
+ "default"
37
+ )._to_items_container_config()
101
38
 
102
- if self._slot_manager.has_slot():
103
- props["items"] = self._slot_manager
39
+ if "sid" in default_slot:
40
+ data["sid"] = default_slot["sid"]
104
41
 
105
- data.pop("slots", None)
106
42
  return data
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Dict, List, Optional, Set
3
+ from typing import TYPE_CHECKING, Dict, List, Optional
4
4
  from instaui.common.jsonable import Jsonable
5
5
  from instaui.runtime import get_slot_stacks, pop_slot
6
- from instaui.runtime._app import get_app_slot
6
+ from instaui.runtime._app import ready_scope
7
7
  from instaui.vars.slot_prop import BindingSlotPropItem
8
8
 
9
9
  if TYPE_CHECKING:
@@ -30,13 +30,6 @@ class SlotManager(Jsonable):
30
30
  return self.get_slot(_DEFAULT_SLOT_NAME)
31
31
 
32
32
  def _to_json_dict(self):
33
- if (
34
- len(self._slots) == 1
35
- and _DEFAULT_SLOT_NAME in self._slots
36
- and (not self._slots[_DEFAULT_SLOT_NAME]._has_props_use())
37
- ):
38
- return self._slots[_DEFAULT_SLOT_NAME]._children
39
-
40
33
  return {name: slot._to_json_dict() for name, slot in self._slots.items()}
41
34
 
42
35
  def has_slot(self) -> bool:
@@ -50,23 +43,28 @@ class Slot(Jsonable):
50
43
  self._id: Optional[str] = None
51
44
  self._name = name
52
45
  self._children: List[Component] = []
53
- self._props_use_name: Set[str] = set()
54
-
55
- def _has_props_use(self):
56
- return len(self._props_use_name) > 0
46
+ self._use_slot_props: bool = False
47
+ self._scope_wrapper = ready_scope()
48
+ self._slot_prop_info = SlotPropInfo(self._scope_wrapper)
57
49
 
58
50
  def props(self, name: str):
59
- if self._id is None:
60
- self._id = get_app_slot().generate_slot_id()
51
+ self._use_slot_props = True
52
+ self._slot_prop_info.setup()
53
+
54
+ item = BindingSlotPropItem(
55
+ name, self._slot_prop_info.sid, self._slot_prop_info.var_id
56
+ )
61
57
 
62
- self._props_use_name.add(name)
63
- return BindingSlotPropItem(self._id, name)
58
+ return item[name]
64
59
 
65
60
  def __enter__(self):
66
61
  get_slot_stacks().append(self)
62
+ self._scope_wrapper.enter()
63
+
67
64
  return self
68
65
 
69
66
  def __exit__(self, *_):
67
+ self._scope_wrapper.exit()
70
68
  pop_slot()
71
69
 
72
70
  def _to_json_dict(self):
@@ -75,7 +73,43 @@ class Slot(Jsonable):
75
73
  if self._children:
76
74
  data["items"] = self._children
77
75
 
78
- if self._props_use_name:
79
- data["props"] = {"id": self._id, "use": list(self._props_use_name)}
76
+ if self._use_slot_props:
77
+ data["use_prop"] = 1
78
+
79
+ if self._scope_wrapper.used and self._scope_wrapper.scope.has_registered_task:
80
+ data["sid"] = self._scope_wrapper.scope_id
80
81
 
81
82
  return data
83
+
84
+ def _to_items_container_config(self) -> Dict:
85
+ data = self._to_json_dict()
86
+
87
+ return {k: v for k, v in data.items() if k in ("items", "sid")}
88
+
89
+
90
+ class SlotPropInfo(Jsonable):
91
+ def __init__(self, scope_wrapper: ready_scope):
92
+ pass
93
+
94
+ self._scope_wrapper = scope_wrapper
95
+ self.__register_info = None
96
+
97
+ def setup(self):
98
+ if self.__register_info is not None:
99
+ return
100
+ scope = self._scope_wrapper.scope
101
+ self.__register_info = scope.register_slot_prop_info_task(self)
102
+
103
+ @property
104
+ def sid(self) -> str:
105
+ return self.__register_info.scope_id # type: ignore
106
+
107
+ @property
108
+ def var_id(self) -> str:
109
+ return self.__register_info.var_id # type: ignore
110
+
111
+ def _to_json_dict(self):
112
+ return {
113
+ "sid": self.sid,
114
+ "id": self.var_id,
115
+ }
@@ -2,19 +2,18 @@ from __future__ import annotations
2
2
  from typing import (
3
3
  Dict,
4
4
  Literal,
5
- Mapping,
6
5
  Optional,
7
6
  Union,
8
7
  Sequence,
9
8
  Generic,
10
9
  TypeVar,
10
+ cast,
11
11
  overload,
12
12
  )
13
- import pydantic
13
+ from enum import Enum
14
14
 
15
15
  from instaui.components.component import Component
16
- from instaui.vars.vfor_item import VForItem, VForDict, VForWithIndex
17
- from instaui.runtime._app import get_app_slot, new_scope
16
+ from instaui.vars.vfor_item import VForItem
18
17
 
19
18
  from instaui.vars.mixin_types.element_binding import (
20
19
  ElementBindingMixin,
@@ -24,10 +23,16 @@ from instaui.vars.mixin_types.element_binding import (
24
23
  _T = TypeVar("_T")
25
24
 
26
25
 
26
+ class VForArrayTypeEnum(Enum):
27
+ CONST = "c"
28
+ REF = "r"
29
+ RANGE = "n"
30
+
31
+
27
32
  class VFor(Component, Generic[_T]):
28
33
  def __init__(
29
34
  self,
30
- data: Union[Sequence[_T], ElementBindingProtocol],
35
+ data: Union[Sequence[_T], ElementBindingProtocol, Dict[str, _T], _T],
31
36
  *,
32
37
  key: Union[Literal["item", "index"], str] = "index",
33
38
  ):
@@ -53,20 +58,12 @@ class VFor(Component, Generic[_T]):
53
58
  super().__init__("vfor")
54
59
  self._data = data
55
60
  self._key = key
56
- self._fid = get_app_slot().generate_vfor_id()
57
- self.__scope_manager = new_scope()
58
- self.__scope = None
59
61
  self._num = None
60
62
  self._transition_group_setting = None
61
63
 
62
64
  def __enter__(self) -> _T:
63
- self.__scope = self.__scope_manager.__enter__()
64
65
  super().__enter__()
65
- return VForItem(self).proxy # type: ignore
66
-
67
- def __exit__(self, *_) -> None:
68
- self.__scope_manager.__exit__(*_)
69
- return super().__exit__(*_)
66
+ return cast(_T, VForItem())
70
67
 
71
68
  def _set_num(self, num):
72
69
  self._num = num
@@ -75,41 +72,41 @@ class VFor(Component, Generic[_T]):
75
72
  self._transition_group_setting = {"name": name, "tag": tag}
76
73
  return self
77
74
 
78
- @property
79
- def current(self):
80
- return VForItem(self)
81
-
82
- def with_index(self):
83
- return VForWithIndex(self)
84
-
85
75
  def _to_json_dict(self):
86
76
  data = super()._to_json_dict()
87
- data["props"] = {"fid": self._fid}
88
77
 
89
- props: Dict = data["props"]
90
78
  if self._key is not None and self._key != "index":
91
- props["fkey"] = self._key
92
-
93
- if self._data is not None:
94
- if isinstance(self._data, ElementBindingMixin):
95
- props["bArray"] = self._data._to_element_binding_config()
96
- else:
97
- props["array"] = self._data
98
-
99
- if self._num is not None:
100
- props["num"] = self._num
79
+ data["fkey"] = self._key
80
+
81
+ if self._data is not None or self._num is not None:
82
+ array_type = (
83
+ VForArrayTypeEnum.REF
84
+ if isinstance(self._data, ElementBindingMixin)
85
+ else VForArrayTypeEnum.RANGE
86
+ if self._num is not None
87
+ else VForArrayTypeEnum.CONST
88
+ )
89
+
90
+ array_value = (
91
+ self._data._to_element_binding_config()
92
+ if isinstance(self._data, ElementBindingMixin)
93
+ else self._num
94
+ if self._num is not None
95
+ else self._data
96
+ )
97
+
98
+ data["array"] = {"type": array_type, "value": array_value}
101
99
 
102
100
  if self._transition_group_setting is not None:
103
- props["tsGroup"] = {
101
+ data["tsGroup"] = {
104
102
  k: v for k, v in self._transition_group_setting.items() if v is not None
105
103
  }
106
104
 
107
- props["scopeId"] = self.__scope.id # type: ignore
108
-
109
105
  if self._slot_manager.has_slot():
110
- props["items"] = self._slot_manager
111
-
112
- data.pop("slots", None)
106
+ slot_data = self._slot_manager.get_slot(
107
+ "default"
108
+ )._to_items_container_config()
109
+ data.update(slot_data)
113
110
 
114
111
  return data
115
112
 
@@ -135,8 +132,6 @@ class VFor(Component, Generic[_T]):
135
132
 
136
133
  return obj # type: ignore
137
134
 
138
- @classmethod
139
- def from_dict(
140
- cls, data: Union[Mapping, pydantic.BaseModel, ElementBindingProtocol]
141
- ):
142
- return VForDict(VFor(data)) # type: ignore
135
+
136
+ def iter_info(item: _T) -> VForItem[_T]:
137
+ return cast(VForItem[_T], item)
instaui/components/vif.py CHANGED
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
- from typing import Dict, cast
2
+ from typing import cast
3
3
  from instaui.components.component import Component
4
- from instaui.runtime._app import new_scope
5
4
  from instaui.vars.mixin_types.element_binding import ElementBindingMixin
6
5
  from instaui.vars.types import TMaybeRef
7
6
 
@@ -10,31 +9,20 @@ class VIf(Component):
10
9
  def __init__(self, on: TMaybeRef[bool]):
11
10
  super().__init__("vif")
12
11
  self._on = cast(ElementBindingMixin, on)
13
- self.__scope_manager = new_scope()
14
- self.__scope = None
15
-
16
- def __enter__(self):
17
- self.__scope = self.__scope_manager.__enter__()
18
- return super().__enter__()
19
-
20
- def __exit__(self, *_) -> None:
21
- self.__scope_manager.__exit__(*_)
22
- return super().__exit__(*_)
23
12
 
24
13
  def _to_json_dict(self):
25
14
  data = super()._to_json_dict()
26
- data["props"] = {
27
- "on": self._on
28
- if isinstance(self._on, bool)
29
- else self._on._to_element_binding_config(),
30
- }
31
- props: Dict = data["props"]
32
15
 
33
- props["scopeId"] = self.__scope.id # type: ignore
16
+ data["on"] = (
17
+ self._on
18
+ if isinstance(self._on, bool)
19
+ else self._on._to_element_binding_config()
20
+ )
34
21
 
35
22
  if self._slot_manager.has_slot():
36
- props["items"] = self._slot_manager
37
-
38
- data.pop("slots", None)
23
+ slot_data = self._slot_manager.get_slot(
24
+ "default"
25
+ )._to_items_container_config()
26
+ data.update(slot_data)
39
27
 
40
28
  return data
instaui/event/js_event.py CHANGED
@@ -1,5 +1,10 @@
1
1
  import typing
2
- from instaui.vars.mixin_types.py_binding import CanInputMixin, CanOutputMixin
2
+ from instaui.vars.mixin_types.py_binding import (
3
+ CanInputMixin,
4
+ CanOutputMixin,
5
+ inputs_to_config,
6
+ outputs_to_config,
7
+ )
3
8
  from instaui.common.jsonable import Jsonable
4
9
  from .event_mixin import EventMixin
5
10
 
@@ -16,11 +21,8 @@ class JsEvent(Jsonable, EventMixin):
16
21
  ]
17
22
  self._org_inputs = list(inputs or [])
18
23
  self._org_outputs = list(outputs or [])
19
- self._inputs = [
20
- input._to_input_config() if isinstance(input, CanInputMixin) else input
21
- for input in inputs or []
22
- ]
23
- self._outputs = [output._to_output_config() for output in outputs or []]
24
+ self._inputs = inputs or []
25
+ self._outputs = outputs or []
24
26
  self.code = code
25
27
 
26
28
  def _to_json_dict(self):
@@ -28,10 +30,10 @@ class JsEvent(Jsonable, EventMixin):
28
30
  data["type"] = self.event_type()
29
31
 
30
32
  if self._inputs:
31
- data["inputs"] = self._inputs
33
+ data["inputs"] = inputs_to_config(self._inputs)
32
34
 
33
35
  if self._outputs:
34
- data["set"] = self._outputs
36
+ data["sets"] = outputs_to_config(self._outputs)
35
37
 
36
38
  if sum(self._is_const_data) > 0:
37
39
  data["data"] = self._is_const_data
@@ -1,6 +1,7 @@
1
1
  import typing
2
2
  from instaui.common.jsonable import Jsonable
3
- from instaui.vars.mixin_types.observable import ObservableMixin
3
+ from instaui.vars.mixin_types.py_binding import CanInputMixin
4
+ from instaui.vars._types import InputBindingType
4
5
  from .event_mixin import EventMixin
5
6
 
6
7
 
@@ -36,21 +37,6 @@ class VueEvent(Jsonable, EventMixin):
36
37
  self.code = code
37
38
  self._bindings = bindings
38
39
 
39
- if bindings:
40
- bindData = [
41
- int(not isinstance(v, ObservableMixin)) for v in bindings.values()
42
- ]
43
-
44
- if sum(bindData) > 0:
45
- self.bindData = bindData
46
-
47
- self.bind = {
48
- k: typing.cast(ObservableMixin, v)._to_observable_config()
49
- if isinstance(v, ObservableMixin)
50
- else v
51
- for k, v in bindings.items()
52
- }
53
-
54
40
  def copy_with_extends(self, extends: typing.Dict):
55
41
  raise NotImplementedError("VueEvent does not support extends")
56
42
 
@@ -60,6 +46,18 @@ class VueEvent(Jsonable, EventMixin):
60
46
  def _to_json_dict(self):
61
47
  data = super()._to_json_dict()
62
48
  data["type"] = self.event_type()
49
+ if self._bindings:
50
+ data["inputs"] = {
51
+ name: {
52
+ "value": v._to_input_config()
53
+ if isinstance(v, CanInputMixin)
54
+ else v,
55
+ "type": v._to_event_input_type().value
56
+ if isinstance(v, CanInputMixin)
57
+ else InputBindingType.Data,
58
+ }
59
+ for name, v in self._bindings.items()
60
+ }
63
61
  return data
64
62
 
65
63
 
@@ -3,7 +3,13 @@ import typing
3
3
  from typing_extensions import ParamSpec
4
4
  from instaui.common.jsonable import Jsonable
5
5
  from instaui.runtime._app import get_current_scope, get_app_slot
6
- from instaui.vars.mixin_types.py_binding import CanInputMixin, CanOutputMixin
6
+ from instaui.vars.mixin_types.py_binding import (
7
+ CanInputMixin,
8
+ CanOutputMixin,
9
+ _assert_outputs_be_can_output_mixin,
10
+ inputs_to_config,
11
+ outputs_to_config,
12
+ )
7
13
  from instaui.handlers import event_handler
8
14
  from instaui import pre_setup as _pre_setup
9
15
  from .event_mixin import EventMixin
@@ -27,6 +33,8 @@ class WebEvent(Jsonable, EventMixin, typing.Generic[P, R]):
27
33
  if pre_setup:
28
34
  _pre_setup._check_args(pre_setup)
29
35
 
36
+ _assert_outputs_be_can_output_mixin(outputs)
37
+
30
38
  self._inputs = inputs
31
39
  self._outputs = outputs
32
40
  self._fn = fn
@@ -68,15 +76,10 @@ class WebEvent(Jsonable, EventMixin, typing.Generic[P, R]):
68
76
  data["sid"] = self._sid
69
77
 
70
78
  if self._inputs:
71
- data["bind"] = [
72
- binding._to_input_config()
73
- if isinstance(binding, CanInputMixin)
74
- else binding
75
- for binding in self._inputs
76
- ]
79
+ data["inputs"] = inputs_to_config(self._inputs)
77
80
 
78
81
  if self._outputs:
79
- data["set"] = [ref._to_output_config() for ref in self._outputs]
82
+ data["sets"] = outputs_to_config(self._outputs)
80
83
 
81
84
  if self._pre_setup:
82
85
  data["preSetup"] = _pre_setup.convert_config(self._pre_setup)