instaui 0.1.0__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.
- instaui/__init__.py +9 -0
- instaui/_helper/observable_helper.py +35 -0
- instaui/boot_info.py +43 -0
- instaui/common/jsonable.py +37 -0
- instaui/components/__init__.py +0 -0
- instaui/components/column.py +18 -0
- instaui/components/component.py +47 -0
- instaui/components/content.py +34 -0
- instaui/components/directive.py +55 -0
- instaui/components/element.py +462 -0
- instaui/components/grid.py +80 -0
- instaui/components/html/__init__.py +36 -0
- instaui/components/html/_mixins.py +34 -0
- instaui/components/html/button.py +38 -0
- instaui/components/html/checkbox.py +42 -0
- instaui/components/html/date.py +28 -0
- instaui/components/html/div.py +7 -0
- instaui/components/html/form.py +7 -0
- instaui/components/html/input.py +28 -0
- instaui/components/html/label.py +21 -0
- instaui/components/html/li.py +17 -0
- instaui/components/html/link.py +31 -0
- instaui/components/html/number.py +34 -0
- instaui/components/html/paragraph.py +19 -0
- instaui/components/html/range.py +45 -0
- instaui/components/html/select.py +93 -0
- instaui/components/html/span.py +19 -0
- instaui/components/html/ul.py +20 -0
- instaui/components/match.py +106 -0
- instaui/components/row.py +19 -0
- instaui/components/slot.py +82 -0
- instaui/components/transition_group.py +9 -0
- instaui/components/value_element.py +48 -0
- instaui/components/vfor.py +140 -0
- instaui/components/vif.py +38 -0
- instaui/consts.py +18 -0
- instaui/dependencies/__init__.py +15 -0
- instaui/dependencies/component_registrar.py +82 -0
- instaui/dependencies/installer.py +5 -0
- instaui/event/event_mixin.py +12 -0
- instaui/event/js_event.py +57 -0
- instaui/event/web_event.py +108 -0
- instaui/experimental/__init__.py +4 -0
- instaui/experimental/debug.py +48 -0
- instaui/fastapi_server/_utils.py +42 -0
- instaui/fastapi_server/_uvicorn.py +37 -0
- instaui/fastapi_server/config_router.py +60 -0
- instaui/fastapi_server/debug_mode_router.py +61 -0
- instaui/fastapi_server/event_router.py +58 -0
- instaui/fastapi_server/middlewares.py +19 -0
- instaui/fastapi_server/request_context.py +19 -0
- instaui/fastapi_server/server.py +246 -0
- instaui/fastapi_server/watch_router.py +53 -0
- instaui/handlers/_utils.py +66 -0
- instaui/handlers/computed_handler.py +42 -0
- instaui/handlers/config_handler.py +13 -0
- instaui/handlers/event_handler.py +58 -0
- instaui/handlers/watch_handler.py +57 -0
- instaui/html_tools.py +139 -0
- instaui/inject.py +33 -0
- instaui/js/__init__.py +4 -0
- instaui/js/js_output.py +15 -0
- instaui/js/lambda_func.py +35 -0
- instaui/launch_collector.py +52 -0
- instaui/page_info.py +23 -0
- instaui/runtime/__init__.py +29 -0
- instaui/runtime/_app.py +206 -0
- instaui/runtime/_inner_helper.py +9 -0
- instaui/runtime/context.py +47 -0
- instaui/runtime/dataclass.py +30 -0
- instaui/runtime/resource.py +87 -0
- instaui/runtime/scope.py +107 -0
- instaui/runtime/ui_state_scope.py +15 -0
- instaui/settings/__init__.py +4 -0
- instaui/settings/__settings.py +13 -0
- instaui/skip.py +12 -0
- instaui/spa_router/__init__.py +26 -0
- instaui/spa_router/_components.py +35 -0
- instaui/spa_router/_file_base_utils.py +264 -0
- instaui/spa_router/_functions.py +122 -0
- instaui/spa_router/_install.py +11 -0
- instaui/spa_router/_route_model.py +139 -0
- instaui/spa_router/_router_box.py +40 -0
- instaui/spa_router/_router_output.py +22 -0
- instaui/spa_router/_router_param_var.py +51 -0
- instaui/spa_router/_types.py +4 -0
- instaui/spa_router/templates/page_routes +59 -0
- instaui/static/insta-ui.css +1 -0
- instaui/static/insta-ui.esm-browser.prod.js +3663 -0
- instaui/static/insta-ui.iife.js +29 -0
- instaui/static/insta-ui.iife.js.map +1 -0
- instaui/static/insta-ui.js.map +1 -0
- instaui/static/tailwindcss.min.js +62 -0
- instaui/static/templates/debug/sse.html +117 -0
- instaui/static/templates/web.html +118 -0
- instaui/static/templates/zero.html +55 -0
- instaui/static/vue.esm-browser.prod.js +9 -0
- instaui/static/vue.global.prod.js +9 -0
- instaui/static/vue.runtime.esm-browser.prod.js +5 -0
- instaui/systems/file_system.py +17 -0
- instaui/systems/func_system.py +104 -0
- instaui/systems/js_system.py +22 -0
- instaui/systems/pydantic_system.py +27 -0
- instaui/systems/string_system.py +10 -0
- instaui/template/__init__.py +4 -0
- instaui/template/env.py +7 -0
- instaui/template/web_template.py +55 -0
- instaui/template/zero_template.py +24 -0
- instaui/ui/__init__.py +121 -0
- instaui/ui/events.py +25 -0
- instaui/ui_functions/input_slient_data.py +16 -0
- instaui/ui_functions/server.py +13 -0
- instaui/ui_functions/str_format.py +36 -0
- instaui/ui_functions/ui_page.py +31 -0
- instaui/ui_functions/ui_types.py +13 -0
- instaui/ui_functions/url_location.py +33 -0
- instaui/vars/__init__.py +13 -0
- instaui/vars/_types.py +8 -0
- instaui/vars/_utils.py +12 -0
- instaui/vars/data.py +68 -0
- instaui/vars/element_ref.py +42 -0
- instaui/vars/event_context.py +45 -0
- instaui/vars/event_extend.py +0 -0
- instaui/vars/js_computed.py +95 -0
- instaui/vars/mixin_types/common_type.py +5 -0
- instaui/vars/mixin_types/element_binding.py +10 -0
- instaui/vars/mixin_types/observable.py +7 -0
- instaui/vars/mixin_types/pathable.py +14 -0
- instaui/vars/mixin_types/py_binding.py +13 -0
- instaui/vars/mixin_types/str_format_binding.py +8 -0
- instaui/vars/mixin_types/var_type.py +5 -0
- instaui/vars/path_var.py +89 -0
- instaui/vars/ref.py +103 -0
- instaui/vars/slot_prop.py +46 -0
- instaui/vars/state.py +82 -0
- instaui/vars/types.py +24 -0
- instaui/vars/vfor_item.py +204 -0
- instaui/vars/vue_computed.py +82 -0
- instaui/vars/web_computed.py +157 -0
- instaui/vars/web_view_computed.py +1 -0
- instaui/version.py +3 -0
- instaui/watch/_types.py +4 -0
- instaui/watch/_utils.py +3 -0
- instaui/watch/js_watch.py +74 -0
- instaui/watch/vue_watch.py +61 -0
- instaui/watch/web_watch.py +123 -0
- instaui/zero/__init__.py +3 -0
- instaui/zero/scope.py +9 -0
- instaui-0.1.0.dist-info/LICENSE +21 -0
- instaui-0.1.0.dist-info/METADATA +154 -0
- instaui-0.1.0.dist-info/RECORD +152 -0
- instaui-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Union
|
3
|
+
|
4
|
+
from instaui.components.value_element import ValueElement
|
5
|
+
from ._mixins import InputEventMixin
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from instaui.vars.types import TMaybeRef
|
9
|
+
from instaui.components.element import Element
|
10
|
+
|
11
|
+
_T_value = str
|
12
|
+
|
13
|
+
|
14
|
+
class Date(InputEventMixin, ValueElement[_T_value]):
|
15
|
+
def __init__(
|
16
|
+
self,
|
17
|
+
value: Union[_T_value, TMaybeRef[_T_value], None] = None,
|
18
|
+
*,
|
19
|
+
model_value: Union[_T_value, TMaybeRef[_T_value], None] = None,
|
20
|
+
):
|
21
|
+
super().__init__("input", value, is_html_component=True)
|
22
|
+
self.props({"type": "date"})
|
23
|
+
|
24
|
+
if model_value is not None:
|
25
|
+
self.props({"value": model_value})
|
26
|
+
|
27
|
+
def _input_event_mixin_element(self) -> Element:
|
28
|
+
return self
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Optional, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
from instaui.components.value_element import ValueElement
|
5
|
+
|
6
|
+
from ._mixins import InputEventMixin
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
import instaui.vars as ui_vars
|
10
|
+
|
11
|
+
|
12
|
+
class Input(InputEventMixin, ValueElement[str]):
|
13
|
+
def __init__(
|
14
|
+
self,
|
15
|
+
value: Union[str, ui_vars.TMaybeRef[str], None] = None,
|
16
|
+
*,
|
17
|
+
model_value: Union[str, ui_vars.TMaybeRef[str], None] = None,
|
18
|
+
disabled: Optional[ui_vars.TMaybeRef[bool]] = None,
|
19
|
+
):
|
20
|
+
super().__init__("input", value, is_html_component=True)
|
21
|
+
|
22
|
+
if disabled is not None:
|
23
|
+
self.props({"disabled": disabled})
|
24
|
+
if model_value is not None:
|
25
|
+
self.props({"value": model_value})
|
26
|
+
|
27
|
+
def _input_event_mixin_element(self) -> Element:
|
28
|
+
return self
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Any, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
import instaui.vars as ui_vars
|
7
|
+
|
8
|
+
|
9
|
+
class Label(Element):
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
text: Union[Any, ui_vars.TMaybeRef[Any], None] = None,
|
13
|
+
):
|
14
|
+
super().__init__("label")
|
15
|
+
|
16
|
+
if text is not None:
|
17
|
+
self.props(
|
18
|
+
{
|
19
|
+
"innerText": text,
|
20
|
+
}
|
21
|
+
)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Any, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from instaui.vars import TMaybeRef
|
7
|
+
|
8
|
+
|
9
|
+
class Li(Element):
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
text: Union[Any, TMaybeRef[Any], None] = None,
|
13
|
+
):
|
14
|
+
super().__init__("li")
|
15
|
+
|
16
|
+
if text:
|
17
|
+
self.props({"innerText": text})
|
@@ -0,0 +1,31 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import (
|
3
|
+
Optional,
|
4
|
+
)
|
5
|
+
from instaui.components.element import Element
|
6
|
+
|
7
|
+
from instaui.vars.types import TMaybeRef
|
8
|
+
|
9
|
+
|
10
|
+
class Link(Element):
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
href: Optional[TMaybeRef[str]] = None,
|
14
|
+
*,
|
15
|
+
text: Optional[TMaybeRef[str]] = None,
|
16
|
+
):
|
17
|
+
super().__init__("a")
|
18
|
+
|
19
|
+
if text is not None:
|
20
|
+
self.props(
|
21
|
+
{
|
22
|
+
"innerText": text,
|
23
|
+
}
|
24
|
+
)
|
25
|
+
|
26
|
+
if href is not None:
|
27
|
+
self.props(
|
28
|
+
{
|
29
|
+
"href": href,
|
30
|
+
}
|
31
|
+
)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Optional, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
from instaui.components.value_element import ValueElement
|
5
|
+
from ._mixins import InputEventMixin
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
import instaui.vars as ui_vars
|
9
|
+
|
10
|
+
|
11
|
+
_T_value = Union[int, float]
|
12
|
+
|
13
|
+
|
14
|
+
class Number(InputEventMixin, ValueElement[_T_value]):
|
15
|
+
def __init__(
|
16
|
+
self,
|
17
|
+
value: Optional[ui_vars.TMaybeRef[_T_value]] = None,
|
18
|
+
*,
|
19
|
+
model_value: Optional[ui_vars.TMaybeRef[_T_value]] = None,
|
20
|
+
min: Optional[ui_vars.TMaybeRef[_T_value]] = None,
|
21
|
+
max: Optional[ui_vars.TMaybeRef[_T_value]] = None,
|
22
|
+
):
|
23
|
+
super().__init__("input", value, is_html_component=True)
|
24
|
+
self.props({"type": "number"})
|
25
|
+
|
26
|
+
if min is not None:
|
27
|
+
self.props({"min": min})
|
28
|
+
if max is not None:
|
29
|
+
self.props({"max": max})
|
30
|
+
if model_value is not None:
|
31
|
+
self.props({"value": model_value})
|
32
|
+
|
33
|
+
def _input_event_mixin_element(self) -> Element:
|
34
|
+
return self
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Any, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
import instaui.vars as ui_vars
|
7
|
+
|
8
|
+
|
9
|
+
class Paragraph(Element):
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
text: Union[str, ui_vars.TMaybeRef[Any]],
|
13
|
+
):
|
14
|
+
super().__init__("p")
|
15
|
+
self.props(
|
16
|
+
{
|
17
|
+
"innerText": text,
|
18
|
+
}
|
19
|
+
)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import List, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
from instaui.components.value_element import ValueElement
|
5
|
+
from instaui import consts
|
6
|
+
from instaui.vars.types import TMaybeRef
|
7
|
+
from instaui.vars.mixin_types.element_binding import ElementBindingMixin
|
8
|
+
from ._mixins import InputEventMixin
|
9
|
+
|
10
|
+
_T_value = Union[int, float]
|
11
|
+
|
12
|
+
|
13
|
+
class Range(InputEventMixin, ValueElement[_T_value]):
|
14
|
+
def __init__(
|
15
|
+
self,
|
16
|
+
value: Union[_T_value, TMaybeRef[_T_value], None] = None,
|
17
|
+
*,
|
18
|
+
min: Union[_T_value, TMaybeRef[_T_value], None] = None,
|
19
|
+
max: Union[_T_value, TMaybeRef[_T_value], None] = None,
|
20
|
+
):
|
21
|
+
super().__init__("input", value, is_html_component=True)
|
22
|
+
self.props({"type": "range"})
|
23
|
+
|
24
|
+
if min is not None:
|
25
|
+
self.props({"min": min})
|
26
|
+
if max is not None:
|
27
|
+
self.props({"max": max})
|
28
|
+
|
29
|
+
def vmodel(
|
30
|
+
self,
|
31
|
+
value: ElementBindingMixin,
|
32
|
+
modifiers: Union[consts.TModifier, List[consts.TModifier], None] = None,
|
33
|
+
*,
|
34
|
+
prop_name: str = "value",
|
35
|
+
):
|
36
|
+
modifiers = modifiers or []
|
37
|
+
if isinstance(modifiers, str):
|
38
|
+
modifiers = [modifiers]
|
39
|
+
|
40
|
+
modifiers_with_number = list(set([*modifiers, "number"]))
|
41
|
+
|
42
|
+
return super().vmodel(value, modifiers_with_number, prop_name=prop_name) # type: ignore
|
43
|
+
|
44
|
+
def _input_event_mixin_element(self) -> Element:
|
45
|
+
return self
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import (
|
3
|
+
TYPE_CHECKING,
|
4
|
+
Any,
|
5
|
+
Callable,
|
6
|
+
Dict,
|
7
|
+
List,
|
8
|
+
Literal,
|
9
|
+
Optional,
|
10
|
+
Self,
|
11
|
+
Union,
|
12
|
+
overload,
|
13
|
+
)
|
14
|
+
|
15
|
+
from instaui.vars import Ref
|
16
|
+
from instaui.components.value_element import ValueElement
|
17
|
+
from instaui.components.element import Element
|
18
|
+
from instaui.vars.types import TMaybeRef
|
19
|
+
from instaui.components.vfor import VFor
|
20
|
+
|
21
|
+
if TYPE_CHECKING:
|
22
|
+
import instaui.vars as ui_vars
|
23
|
+
|
24
|
+
|
25
|
+
_T_Select_Value = Union[List[str], str]
|
26
|
+
|
27
|
+
|
28
|
+
class Select(ValueElement[Union[List[str], str]]):
|
29
|
+
def __init__(
|
30
|
+
self,
|
31
|
+
value: Union[_T_Select_Value, ui_vars.TMaybeRef[_T_Select_Value], None] = None,
|
32
|
+
):
|
33
|
+
super().__init__("select", value, is_html_component=True)
|
34
|
+
|
35
|
+
def vmodel(
|
36
|
+
self,
|
37
|
+
value: Ref[Any],
|
38
|
+
*modifiers: Literal["lazy"],
|
39
|
+
):
|
40
|
+
return super().vmodel(value, *modifiers) # type: ignore
|
41
|
+
|
42
|
+
@overload
|
43
|
+
def on_change(self, handler: Callable, *, key: Optional[str] = None) -> Self: ...
|
44
|
+
|
45
|
+
@overload
|
46
|
+
def on_change(
|
47
|
+
self,
|
48
|
+
handler: str,
|
49
|
+
*,
|
50
|
+
bindings: Optional[Dict] = None,
|
51
|
+
key: Optional[str] = None,
|
52
|
+
) -> Self: ...
|
53
|
+
|
54
|
+
def on_change(
|
55
|
+
self,
|
56
|
+
handler: Union[Callable, str],
|
57
|
+
*,
|
58
|
+
bindings: Optional[Dict] = None,
|
59
|
+
key: Optional[str] = None,
|
60
|
+
):
|
61
|
+
self.on("change", handler, bindings=bindings, key=key) # type: ignore
|
62
|
+
return self
|
63
|
+
|
64
|
+
@classmethod
|
65
|
+
def from_list(
|
66
|
+
cls,
|
67
|
+
options: TMaybeRef[List],
|
68
|
+
) -> Select:
|
69
|
+
with cls() as select:
|
70
|
+
with VFor(options) as item:
|
71
|
+
Select.Option(item) # type: ignore
|
72
|
+
|
73
|
+
return select
|
74
|
+
|
75
|
+
class Option(Element):
|
76
|
+
def __init__(
|
77
|
+
self,
|
78
|
+
text: Optional[ui_vars.TMaybeRef[str]] = None,
|
79
|
+
value: Optional[ui_vars.TMaybeRef[str]] = None,
|
80
|
+
disabled: Optional[ui_vars.TMaybeRef[bool]] = None,
|
81
|
+
):
|
82
|
+
props = {
|
83
|
+
key: value
|
84
|
+
for key, value in {
|
85
|
+
"text": text,
|
86
|
+
"value": value,
|
87
|
+
"disabled": disabled,
|
88
|
+
}.items()
|
89
|
+
if value is not None
|
90
|
+
}
|
91
|
+
super().__init__("option")
|
92
|
+
|
93
|
+
self._props.update(props)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Any, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
import instaui.vars as ui_vars
|
7
|
+
|
8
|
+
|
9
|
+
class Span(Element):
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
text: Union[str, ui_vars.TMaybeRef[Any]],
|
13
|
+
):
|
14
|
+
super().__init__("span")
|
15
|
+
self.props(
|
16
|
+
{
|
17
|
+
"innerText": text,
|
18
|
+
}
|
19
|
+
)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import List, Union
|
3
|
+
from instaui.components.element import Element
|
4
|
+
from .li import Li
|
5
|
+
from instaui.components.vfor import VFor
|
6
|
+
|
7
|
+
from instaui.vars.mixin_types.element_binding import ElementBindingMixin
|
8
|
+
|
9
|
+
|
10
|
+
class Ul(Element):
|
11
|
+
def __init__(self):
|
12
|
+
super().__init__("ul")
|
13
|
+
|
14
|
+
@classmethod
|
15
|
+
def from_list(cls, data: Union[List, ElementBindingMixin[List]]) -> Ul:
|
16
|
+
with Ul() as ul:
|
17
|
+
with VFor(data) as items:
|
18
|
+
Li(items)
|
19
|
+
|
20
|
+
return ul
|
@@ -0,0 +1,106 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import typing
|
4
|
+
from instaui.components.component import Component
|
5
|
+
from instaui.runtime._app import new_scope
|
6
|
+
|
7
|
+
from instaui.vars.mixin_types.element_binding import ElementBindingMixin
|
8
|
+
|
9
|
+
|
10
|
+
class Match(Component):
|
11
|
+
def __init__(self, on: ElementBindingMixin):
|
12
|
+
super().__init__("match")
|
13
|
+
self._on = on
|
14
|
+
self._default_case = None
|
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(append_to_app=False)
|
54
|
+
self.__scope = None
|
55
|
+
|
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__(*_)
|
63
|
+
|
64
|
+
def _to_json_dict(self):
|
65
|
+
data = super()._to_json_dict()
|
66
|
+
data["props"] = {
|
67
|
+
"value": self._value,
|
68
|
+
}
|
69
|
+
props = data["props"]
|
70
|
+
|
71
|
+
props["scope"] = self.__scope
|
72
|
+
|
73
|
+
if self._slot_manager.has_slot():
|
74
|
+
props["items"] = self._slot_manager
|
75
|
+
|
76
|
+
data.pop("slots", None)
|
77
|
+
return data
|
78
|
+
|
79
|
+
|
80
|
+
class DefaultCase(Component):
|
81
|
+
def __init__(self):
|
82
|
+
super().__init__("default-case")
|
83
|
+
|
84
|
+
self.__scope_manager = new_scope(append_to_app=False)
|
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"]
|
99
|
+
|
100
|
+
props["scope"] = self.__scope
|
101
|
+
|
102
|
+
if self._slot_manager.has_slot():
|
103
|
+
props["items"] = self._slot_manager
|
104
|
+
|
105
|
+
data.pop("slots", None)
|
106
|
+
return data
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import (
|
3
|
+
TypeVar,
|
4
|
+
)
|
5
|
+
from instaui.components.element import Element
|
6
|
+
|
7
|
+
_T = TypeVar("_T")
|
8
|
+
|
9
|
+
|
10
|
+
class Row(Element):
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
):
|
14
|
+
super().__init__("div")
|
15
|
+
self.style("display: flex; flex-direction: row;")
|
16
|
+
|
17
|
+
|
18
|
+
def gap(self, value: str) -> Row:
|
19
|
+
return self.style({"gap": value})
|
@@ -0,0 +1,82 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union
|
4
|
+
from instaui.common.jsonable import Jsonable
|
5
|
+
from instaui.runtime import get_slot_stacks, pop_slot
|
6
|
+
from instaui.runtime._app import get_app_slot
|
7
|
+
from instaui.vars.slot_prop import BindingSlotPropItem
|
8
|
+
|
9
|
+
if TYPE_CHECKING:
|
10
|
+
from instaui.components.component import Component
|
11
|
+
from instaui.components.vfor import VFor
|
12
|
+
|
13
|
+
_DEFAULT_SLOT_NAME = ":"
|
14
|
+
|
15
|
+
|
16
|
+
class SlotManager(Jsonable):
|
17
|
+
def __init__(self) -> None:
|
18
|
+
super().__init__()
|
19
|
+
self._slots: Dict[str, Slot] = {}
|
20
|
+
|
21
|
+
def get_slot(self, name: str) -> Slot:
|
22
|
+
name = _DEFAULT_SLOT_NAME if name == "default" else name
|
23
|
+
|
24
|
+
if name not in self._slots:
|
25
|
+
self._slots[name] = Slot(name)
|
26
|
+
|
27
|
+
return self._slots[name]
|
28
|
+
|
29
|
+
@property
|
30
|
+
def default(self):
|
31
|
+
return self.get_slot(_DEFAULT_SLOT_NAME)
|
32
|
+
|
33
|
+
def _to_json_dict(self):
|
34
|
+
if (
|
35
|
+
len(self._slots) == 1
|
36
|
+
and _DEFAULT_SLOT_NAME in self._slots
|
37
|
+
and (not self._slots[_DEFAULT_SLOT_NAME]._has_props_use())
|
38
|
+
):
|
39
|
+
return self._slots[_DEFAULT_SLOT_NAME]._children
|
40
|
+
|
41
|
+
return {name: slot._to_json_dict() for name, slot in self._slots.items()}
|
42
|
+
|
43
|
+
def has_slot(self) -> bool:
|
44
|
+
return len(self._slots) > 0
|
45
|
+
|
46
|
+
|
47
|
+
class Slot(Jsonable):
|
48
|
+
def __init__(self, name: str) -> None:
|
49
|
+
super().__init__()
|
50
|
+
|
51
|
+
self._id: Optional[str] = None
|
52
|
+
self._name = name
|
53
|
+
self._children: List[Union[Component, VFor]] = []
|
54
|
+
self._props_use_name: Set[str] = set()
|
55
|
+
|
56
|
+
def _has_props_use(self):
|
57
|
+
return len(self._props_use_name) > 0
|
58
|
+
|
59
|
+
def props(self, name: str):
|
60
|
+
if self._id is None:
|
61
|
+
self._id = get_app_slot().generate_slot_id()
|
62
|
+
|
63
|
+
self._props_use_name.add(name)
|
64
|
+
return BindingSlotPropItem(self._id, name)
|
65
|
+
|
66
|
+
def __enter__(self):
|
67
|
+
get_slot_stacks().append(self)
|
68
|
+
return self
|
69
|
+
|
70
|
+
def __exit__(self, *_):
|
71
|
+
pop_slot()
|
72
|
+
|
73
|
+
def _to_json_dict(self):
|
74
|
+
data = super()._to_json_dict()
|
75
|
+
|
76
|
+
if self._children:
|
77
|
+
data["items"] = self._children
|
78
|
+
|
79
|
+
if self._props_use_name:
|
80
|
+
data["props"] = {"id": self._id, "use": list(self._props_use_name)}
|
81
|
+
|
82
|
+
return data
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import (
|
3
|
+
Generic,
|
4
|
+
List,
|
5
|
+
Optional,
|
6
|
+
Union,
|
7
|
+
TypeVar,
|
8
|
+
)
|
9
|
+
from instaui.components.element import Element
|
10
|
+
from instaui import consts
|
11
|
+
|
12
|
+
from instaui.vars.types import TMaybeRef
|
13
|
+
from instaui.vars.web_computed import WebComputed
|
14
|
+
|
15
|
+
|
16
|
+
_T = TypeVar("_T")
|
17
|
+
|
18
|
+
|
19
|
+
class ValueElement(Element, Generic[_T]):
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
tag: Optional[str] = None,
|
23
|
+
value: Union[_T, TMaybeRef[_T], None] = None,
|
24
|
+
is_html_component: bool = False,
|
25
|
+
value_name: str = "value",
|
26
|
+
):
|
27
|
+
super().__init__(tag)
|
28
|
+
self.__is_html_component = is_html_component
|
29
|
+
|
30
|
+
if value is not None:
|
31
|
+
if isinstance(value, WebComputed):
|
32
|
+
self.props({value_name:value})
|
33
|
+
else:
|
34
|
+
self.vmodel(value, prop_name=value_name)
|
35
|
+
|
36
|
+
def vmodel(
|
37
|
+
self,
|
38
|
+
value,
|
39
|
+
modifiers: Union[consts.TModifier, List[consts.TModifier], None] = None,
|
40
|
+
*,
|
41
|
+
prop_name: str = "value",
|
42
|
+
):
|
43
|
+
return super().vmodel(
|
44
|
+
value,
|
45
|
+
modifiers,
|
46
|
+
prop_name=prop_name,
|
47
|
+
is_html_component=self.__is_html_component,
|
48
|
+
)
|