nicegui-bootstrap-components 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.
- nicegui_bootstrap_components/__init__.py +7 -0
- nicegui_bootstrap_components/_base.py +590 -0
- nicegui_bootstrap_components/_host.py +259 -0
- nicegui_bootstrap_components/assets.py +371 -0
- nicegui_bootstrap_components/bs/__init__.py +267 -0
- nicegui_bootstrap_components/bs/_actions.py +232 -0
- nicegui_bootstrap_components/bs/_alert_spinner.py +423 -0
- nicegui_bootstrap_components/bs/_carousel.py +312 -0
- nicegui_bootstrap_components/bs/_choices.py +779 -0
- nicegui_bootstrap_components/bs/_content.py +1343 -0
- nicegui_bootstrap_components/bs/_forms.py +378 -0
- nicegui_bootstrap_components/bs/_inputs.py +560 -0
- nicegui_bootstrap_components/bs/_layout.py +341 -0
- nicegui_bootstrap_components/bs/_nav.py +650 -0
- nicegui_bootstrap_components/bs/_navbar.py +445 -0
- nicegui_bootstrap_components/bs/_overlay_root.py +73 -0
- nicegui_bootstrap_components/bs/_overlays.py +2633 -0
- nicegui_bootstrap_components/bs/_scope.py +28 -0
- nicegui_bootstrap_components/bs/_tabs.py +605 -0
- nicegui_bootstrap_components/bs/_toast.py +137 -0
- nicegui_bootstrap_components/bs/_tooltip_popover.py +537 -0
- nicegui_bootstrap_components/contracts/dbc-2.0.4.json +16811 -0
- nicegui_bootstrap_components/dbc/__init__.py +108 -0
- nicegui_bootstrap_components/icons.py +29 -0
- nicegui_bootstrap_components/persist.py +201 -0
- nicegui_bootstrap_components/py.typed +0 -0
- nicegui_bootstrap_components/static/dist/fonts/bootstrap-icons.woff +0 -0
- nicegui_bootstrap_components/static/dist/fonts/bootstrap-icons.woff2 +0 -0
- nicegui_bootstrap_components/static/dist/ngbs-bootstrap-unscoped.css +12047 -0
- nicegui_bootstrap_components/static/dist/ngbs-bootstrap.css +12057 -0
- nicegui_bootstrap_components/static/dist/ngbs-cerulean-unscoped.css +12338 -0
- nicegui_bootstrap_components/static/dist/ngbs-cerulean.css +12348 -0
- nicegui_bootstrap_components/static/dist/ngbs-compat-unscoped.css +12 -0
- nicegui_bootstrap_components/static/dist/ngbs-compat.css +12 -0
- nicegui_bootstrap_components/static/dist/ngbs-cosmo-unscoped.css +11825 -0
- nicegui_bootstrap_components/static/dist/ngbs-cosmo.css +11835 -0
- nicegui_bootstrap_components/static/dist/ngbs-cyborg-unscoped.css +12213 -0
- nicegui_bootstrap_components/static/dist/ngbs-cyborg.css +12223 -0
- nicegui_bootstrap_components/static/dist/ngbs-darkly-unscoped.css +12143 -0
- nicegui_bootstrap_components/static/dist/ngbs-darkly.css +12153 -0
- nicegui_bootstrap_components/static/dist/ngbs-flatly-unscoped.css +12129 -0
- nicegui_bootstrap_components/static/dist/ngbs-flatly.css +12139 -0
- nicegui_bootstrap_components/static/dist/ngbs-grid-unscoped.css +4084 -0
- nicegui_bootstrap_components/static/dist/ngbs-grid.css +4094 -0
- nicegui_bootstrap_components/static/dist/ngbs-host-unscoped.css +9 -0
- nicegui_bootstrap_components/static/dist/ngbs-host.css +9 -0
- nicegui_bootstrap_components/static/dist/ngbs-icons-bootstrap.css +5 -0
- nicegui_bootstrap_components/static/dist/ngbs-icons-fontawesome.css +9 -0
- nicegui_bootstrap_components/static/dist/ngbs-journal-unscoped.css +12112 -0
- nicegui_bootstrap_components/static/dist/ngbs-journal.css +12122 -0
- nicegui_bootstrap_components/static/dist/ngbs-litera-unscoped.css +12214 -0
- nicegui_bootstrap_components/static/dist/ngbs-litera.css +12224 -0
- nicegui_bootstrap_components/static/dist/ngbs-lumen-unscoped.css +12377 -0
- nicegui_bootstrap_components/static/dist/ngbs-lumen.css +12387 -0
- nicegui_bootstrap_components/static/dist/ngbs-lux-unscoped.css +12048 -0
- nicegui_bootstrap_components/static/dist/ngbs-lux.css +12058 -0
- nicegui_bootstrap_components/static/dist/ngbs-materia-unscoped.css +13197 -0
- nicegui_bootstrap_components/static/dist/ngbs-materia.css +13207 -0
- nicegui_bootstrap_components/static/dist/ngbs-minty-unscoped.css +12184 -0
- nicegui_bootstrap_components/static/dist/ngbs-minty.css +12194 -0
- nicegui_bootstrap_components/static/dist/ngbs-morph-unscoped.css +12829 -0
- nicegui_bootstrap_components/static/dist/ngbs-morph.css +12839 -0
- nicegui_bootstrap_components/static/dist/ngbs-pulse-unscoped.css +11901 -0
- nicegui_bootstrap_components/static/dist/ngbs-pulse.css +11911 -0
- nicegui_bootstrap_components/static/dist/ngbs-quartz-unscoped.css +12625 -0
- nicegui_bootstrap_components/static/dist/ngbs-quartz.css +12635 -0
- nicegui_bootstrap_components/static/dist/ngbs-sandstone-unscoped.css +12214 -0
- nicegui_bootstrap_components/static/dist/ngbs-sandstone.css +12224 -0
- nicegui_bootstrap_components/static/dist/ngbs-simplex-unscoped.css +12199 -0
- nicegui_bootstrap_components/static/dist/ngbs-simplex.css +12209 -0
- nicegui_bootstrap_components/static/dist/ngbs-sketchy-unscoped.css +12518 -0
- nicegui_bootstrap_components/static/dist/ngbs-sketchy.css +12528 -0
- nicegui_bootstrap_components/static/dist/ngbs-slate-unscoped.css +12527 -0
- nicegui_bootstrap_components/static/dist/ngbs-slate.css +12537 -0
- nicegui_bootstrap_components/static/dist/ngbs-solar-unscoped.css +12152 -0
- nicegui_bootstrap_components/static/dist/ngbs-solar.css +12162 -0
- nicegui_bootstrap_components/static/dist/ngbs-spacelab-unscoped.css +12279 -0
- nicegui_bootstrap_components/static/dist/ngbs-spacelab.css +12289 -0
- nicegui_bootstrap_components/static/dist/ngbs-superhero-unscoped.css +12223 -0
- nicegui_bootstrap_components/static/dist/ngbs-superhero.css +12233 -0
- nicegui_bootstrap_components/static/dist/ngbs-united-unscoped.css +12090 -0
- nicegui_bootstrap_components/static/dist/ngbs-united.css +12100 -0
- nicegui_bootstrap_components/static/dist/ngbs-vapor-unscoped.css +12556 -0
- nicegui_bootstrap_components/static/dist/ngbs-vapor.css +12566 -0
- nicegui_bootstrap_components/static/dist/ngbs-yeti-unscoped.css +12333 -0
- nicegui_bootstrap_components/static/dist/ngbs-yeti.css +12343 -0
- nicegui_bootstrap_components/static/dist/ngbs-zephyr-unscoped.css +12296 -0
- nicegui_bootstrap_components/static/dist/ngbs-zephyr.css +12306 -0
- nicegui_bootstrap_components/static/prototype-ngbs.css +541 -0
- nicegui_bootstrap_components/static/webfonts/fa-brands-400.ttf +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-brands-400.woff2 +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-regular-400.ttf +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-regular-400.woff2 +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-solid-900.ttf +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-solid-900.woff2 +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-v4compatibility.ttf +0 -0
- nicegui_bootstrap_components/static/webfonts/fa-v4compatibility.woff2 +0 -0
- nicegui_bootstrap_components/theme.py +238 -0
- nicegui_bootstrap_components/themes.py +131 -0
- nicegui_bootstrap_components-0.1.0.dist-info/METADATA +234 -0
- nicegui_bootstrap_components-0.1.0.dist-info/RECORD +103 -0
- nicegui_bootstrap_components-0.1.0.dist-info/WHEEL +4 -0
- nicegui_bootstrap_components-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Dash Bootstrap Components compatibility surface (PascalCase sibling types)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from .._base import make_surface_classes
|
|
9
|
+
from ..bs._actions import DbcButton as Button
|
|
10
|
+
from ..bs._actions import DbcButtonGroup as ButtonGroup
|
|
11
|
+
from ..bs._layout import DbcCol as Col
|
|
12
|
+
from ..bs._layout import DbcContainer as Container
|
|
13
|
+
from ..bs._layout import DbcRow as Row
|
|
14
|
+
from ..bs._layout import DbcStack as Stack
|
|
15
|
+
|
|
16
|
+
__all__ = ["Button", "ButtonGroup", "Col", "Container", "Row", "Stack"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _compat_class(module_name: str, name: str) -> type[Any]:
|
|
20
|
+
module = importlib.import_module(module_name)
|
|
21
|
+
dname = f"Dbc{name}"
|
|
22
|
+
existing = getattr(module, dname, None)
|
|
23
|
+
if existing is not None:
|
|
24
|
+
return existing
|
|
25
|
+
impl = getattr(module, f"_{name}Impl", None)
|
|
26
|
+
if impl is not None:
|
|
27
|
+
_native, compat = make_surface_classes(impl)
|
|
28
|
+
return compat
|
|
29
|
+
raise AttributeError(
|
|
30
|
+
f"{module_name} must export {dname} or _{name}Impl so dbc.{name} is a sibling type"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _try_compat(module_name: str, name: str) -> type[Any] | None:
|
|
35
|
+
try:
|
|
36
|
+
return _compat_class(module_name, name)
|
|
37
|
+
except (ImportError, AttributeError):
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
for _mod, _name in (
|
|
42
|
+
("nicegui_bootstrap_components.bs._overlays", "Accordion"),
|
|
43
|
+
("nicegui_bootstrap_components.bs._overlays", "AccordionItem"),
|
|
44
|
+
("nicegui_bootstrap_components.bs._overlays", "Collapse"),
|
|
45
|
+
("nicegui_bootstrap_components.bs._overlays", "DropdownMenu"),
|
|
46
|
+
("nicegui_bootstrap_components.bs._overlays", "DropdownMenuItem"),
|
|
47
|
+
("nicegui_bootstrap_components.bs._overlays", "Fade"),
|
|
48
|
+
("nicegui_bootstrap_components.bs._overlays", "Modal"),
|
|
49
|
+
("nicegui_bootstrap_components.bs._overlays", "ModalBody"),
|
|
50
|
+
("nicegui_bootstrap_components.bs._overlays", "ModalFooter"),
|
|
51
|
+
("nicegui_bootstrap_components.bs._overlays", "ModalHeader"),
|
|
52
|
+
("nicegui_bootstrap_components.bs._overlays", "ModalTitle"),
|
|
53
|
+
("nicegui_bootstrap_components.bs._overlays", "Offcanvas"),
|
|
54
|
+
("nicegui_bootstrap_components.bs._alert_spinner", "Alert"),
|
|
55
|
+
("nicegui_bootstrap_components.bs._alert_spinner", "Spinner"),
|
|
56
|
+
("nicegui_bootstrap_components.bs._content", "Badge"),
|
|
57
|
+
("nicegui_bootstrap_components.bs._content", "Card"),
|
|
58
|
+
("nicegui_bootstrap_components.bs._content", "CardBody"),
|
|
59
|
+
("nicegui_bootstrap_components.bs._content", "CardFooter"),
|
|
60
|
+
("nicegui_bootstrap_components.bs._content", "CardGroup"),
|
|
61
|
+
("nicegui_bootstrap_components.bs._content", "CardHeader"),
|
|
62
|
+
("nicegui_bootstrap_components.bs._content", "CardImg"),
|
|
63
|
+
("nicegui_bootstrap_components.bs._content", "CardImgOverlay"),
|
|
64
|
+
("nicegui_bootstrap_components.bs._content", "CardLink"),
|
|
65
|
+
("nicegui_bootstrap_components.bs._content", "ListGroup"),
|
|
66
|
+
("nicegui_bootstrap_components.bs._content", "ListGroupItem"),
|
|
67
|
+
("nicegui_bootstrap_components.bs._content", "Placeholder"),
|
|
68
|
+
("nicegui_bootstrap_components.bs._content", "Progress"),
|
|
69
|
+
("nicegui_bootstrap_components.bs._content", "Table"),
|
|
70
|
+
("nicegui_bootstrap_components.bs._nav", "Breadcrumb"),
|
|
71
|
+
("nicegui_bootstrap_components.bs._nav", "Nav"),
|
|
72
|
+
("nicegui_bootstrap_components.bs._nav", "NavItem"),
|
|
73
|
+
("nicegui_bootstrap_components.bs._nav", "NavLink"),
|
|
74
|
+
("nicegui_bootstrap_components.bs._nav", "Pagination"),
|
|
75
|
+
("nicegui_bootstrap_components.bs._navbar", "Navbar"),
|
|
76
|
+
("nicegui_bootstrap_components.bs._navbar", "NavbarBrand"),
|
|
77
|
+
("nicegui_bootstrap_components.bs._navbar", "NavbarSimple"),
|
|
78
|
+
("nicegui_bootstrap_components.bs._navbar", "NavbarToggler"),
|
|
79
|
+
("nicegui_bootstrap_components.bs._carousel", "Carousel"),
|
|
80
|
+
("nicegui_bootstrap_components.bs._choices", "Checkbox"),
|
|
81
|
+
("nicegui_bootstrap_components.bs._choices", "Checklist"),
|
|
82
|
+
("nicegui_bootstrap_components.bs._choices", "RadioButton"),
|
|
83
|
+
("nicegui_bootstrap_components.bs._choices", "RadioItems"),
|
|
84
|
+
("nicegui_bootstrap_components.bs._choices", "Select"),
|
|
85
|
+
("nicegui_bootstrap_components.bs._choices", "Switch"),
|
|
86
|
+
("nicegui_bootstrap_components.bs._forms", "Form"),
|
|
87
|
+
("nicegui_bootstrap_components.bs._forms", "FormFeedback"),
|
|
88
|
+
("nicegui_bootstrap_components.bs._forms", "FormFloating"),
|
|
89
|
+
("nicegui_bootstrap_components.bs._forms", "FormText"),
|
|
90
|
+
("nicegui_bootstrap_components.bs._forms", "InputGroup"),
|
|
91
|
+
("nicegui_bootstrap_components.bs._forms", "InputGroupText"),
|
|
92
|
+
("nicegui_bootstrap_components.bs._forms", "Label"),
|
|
93
|
+
("nicegui_bootstrap_components.bs._inputs", "Input"),
|
|
94
|
+
("nicegui_bootstrap_components.bs._inputs", "Textarea"),
|
|
95
|
+
("nicegui_bootstrap_components.bs._tabs", "Tab"),
|
|
96
|
+
("nicegui_bootstrap_components.bs._tabs", "Tabs"),
|
|
97
|
+
("nicegui_bootstrap_components.bs._toast", "Toast"),
|
|
98
|
+
("nicegui_bootstrap_components.bs._tooltip_popover", "Popover"),
|
|
99
|
+
("nicegui_bootstrap_components.bs._tooltip_popover", "PopoverBody"),
|
|
100
|
+
("nicegui_bootstrap_components.bs._tooltip_popover", "PopoverHeader"),
|
|
101
|
+
("nicegui_bootstrap_components.bs._tooltip_popover", "Tooltip"),
|
|
102
|
+
):
|
|
103
|
+
_cls = _try_compat(_mod, _name)
|
|
104
|
+
if _cls is not None:
|
|
105
|
+
globals()[_name] = _cls
|
|
106
|
+
__all__.append(_name)
|
|
107
|
+
|
|
108
|
+
__all__.sort()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Pinned icon stylesheet constants.
|
|
2
|
+
|
|
3
|
+
The bundled stylesheets include the font files referenced by the pinned CSS.
|
|
4
|
+
Bundled files are used by default. When permitted CDN mode is selected, icon
|
|
5
|
+
imports use their pinned jsDelivr URLs because icon selectors are
|
|
6
|
+
mode-independent; this does not relax the Mode B CDN guard for themes.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from .themes import Theme
|
|
12
|
+
|
|
13
|
+
__all__ = ["BOOTSTRAP", "FONT_AWESOME", "IconTheme"]
|
|
14
|
+
|
|
15
|
+
IconTheme = Theme
|
|
16
|
+
|
|
17
|
+
_CDN_ROOT = "https://cdn.jsdelivr.net/npm"
|
|
18
|
+
|
|
19
|
+
BOOTSTRAP = IconTheme(
|
|
20
|
+
name="bootstrap",
|
|
21
|
+
cdn=f"{_CDN_ROOT}/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css",
|
|
22
|
+
bundled="ngbs-icons-bootstrap",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
FONT_AWESOME = IconTheme(
|
|
26
|
+
name="fontawesome",
|
|
27
|
+
cdn=(f"{_CDN_ROOT}/@fortawesome/fontawesome-free@6.7.2/css/all.min.css"),
|
|
28
|
+
bundled="ngbs-icons-fontawesome",
|
|
29
|
+
)
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""Adapted persistence helpers and navigation policy."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import logging
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from . import _host
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"persist_key",
|
|
14
|
+
"validate_persist",
|
|
15
|
+
"storage_name",
|
|
16
|
+
"read_persisted",
|
|
17
|
+
"write_persisted",
|
|
18
|
+
"restore_value",
|
|
19
|
+
"navigation_kind",
|
|
20
|
+
"apply_navigation",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
_LOG = logging.getLogger(__name__)
|
|
24
|
+
_ALLOWED_PERSIST = frozenset({"off", "local", "session"})
|
|
25
|
+
_LOGGED_INVALID_KEYS: set[str] = set()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def persist_key(element_id: str, prop: str) -> str:
|
|
29
|
+
"""Return the storage key ``ngbs:{id}:{prop}``."""
|
|
30
|
+
return f"ngbs:{element_id}:{prop}"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def validate_persist(persist: str, *, element_id: str | None, prop: str) -> None:
|
|
34
|
+
"""Raise ``ValueError`` when ``persist`` or ``element_id`` is not valid."""
|
|
35
|
+
if persist not in _ALLOWED_PERSIST:
|
|
36
|
+
raise ValueError(f"persist must be 'off', 'local', or 'session', got {persist!r}")
|
|
37
|
+
if persist != "off" and not element_id:
|
|
38
|
+
raise ValueError(f"persist={persist!r} requires a public id for prop {prop!r}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def storage_name(persist: str) -> str | None:
|
|
42
|
+
"""Return the Web Storage object name for ``persist``, or ``None`` when off."""
|
|
43
|
+
if persist == "local":
|
|
44
|
+
return "localStorage"
|
|
45
|
+
if persist == "session":
|
|
46
|
+
return "sessionStorage"
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _log_invalid(key: str, reason: str) -> None:
|
|
51
|
+
if key in _LOGGED_INVALID_KEYS:
|
|
52
|
+
return
|
|
53
|
+
_LOGGED_INVALID_KEYS.add(key)
|
|
54
|
+
_LOG.debug("Ignoring invalid persisted value for %s (%s)", key, reason)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _type_matches(value: Any, default: Any) -> bool:
|
|
58
|
+
if default is None:
|
|
59
|
+
return True
|
|
60
|
+
return type(value) is type(default)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _decode_stored(raw: Any, default: Any, key: str) -> Any:
|
|
64
|
+
if raw is None:
|
|
65
|
+
return default
|
|
66
|
+
if isinstance(raw, str):
|
|
67
|
+
try:
|
|
68
|
+
value: Any = json.loads(raw)
|
|
69
|
+
except json.JSONDecodeError:
|
|
70
|
+
_log_invalid(key, "invalid JSON")
|
|
71
|
+
return default
|
|
72
|
+
else:
|
|
73
|
+
value = raw
|
|
74
|
+
if not _type_matches(value, default):
|
|
75
|
+
_log_invalid(key, "wrong type")
|
|
76
|
+
return default
|
|
77
|
+
return value
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _execute_javascript(code: str, client: Any) -> Any:
|
|
81
|
+
run_javascript: Any = _host.run_javascript
|
|
82
|
+
return run_javascript(code, client=client)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def read_persisted(
|
|
86
|
+
persist: str,
|
|
87
|
+
element_id: str,
|
|
88
|
+
prop: str,
|
|
89
|
+
default: Any,
|
|
90
|
+
*,
|
|
91
|
+
client: Any | None = None,
|
|
92
|
+
) -> Any:
|
|
93
|
+
"""Read a persisted value from Web Storage.
|
|
94
|
+
|
|
95
|
+
When ``persist`` is ``off`` or ``client`` is ``None``, return ``default``
|
|
96
|
+
without touching storage. Invalid JSON or a value whose type does not match
|
|
97
|
+
``default`` yields ``default`` and a single debug log per key.
|
|
98
|
+
"""
|
|
99
|
+
validate_persist(persist, element_id=element_id, prop=prop)
|
|
100
|
+
name = storage_name(persist)
|
|
101
|
+
if name is None or client is None:
|
|
102
|
+
return default
|
|
103
|
+
key = persist_key(element_id, prop)
|
|
104
|
+
code = f"window.{name}.getItem({json.dumps(key)})"
|
|
105
|
+
raw = _execute_javascript(code, client)
|
|
106
|
+
return _decode_stored(raw, default, key)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def write_persisted(
|
|
110
|
+
persist: str,
|
|
111
|
+
element_id: str,
|
|
112
|
+
prop: str,
|
|
113
|
+
value: Any,
|
|
114
|
+
*,
|
|
115
|
+
client: Any | None = None,
|
|
116
|
+
) -> None:
|
|
117
|
+
"""Write ``value`` to Web Storage.
|
|
118
|
+
|
|
119
|
+
No-op when ``persist`` is ``off`` or ``client`` is ``None``.
|
|
120
|
+
"""
|
|
121
|
+
validate_persist(persist, element_id=element_id, prop=prop)
|
|
122
|
+
name = storage_name(persist)
|
|
123
|
+
if name is None or client is None:
|
|
124
|
+
return
|
|
125
|
+
key = persist_key(element_id, prop)
|
|
126
|
+
code = f"window.{name}.setItem({json.dumps(key)}, JSON.stringify({json.dumps(value)}))"
|
|
127
|
+
_execute_javascript(code, client)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def restore_value(
|
|
131
|
+
persist: str,
|
|
132
|
+
element_id: str,
|
|
133
|
+
prop: str,
|
|
134
|
+
default: Any,
|
|
135
|
+
*,
|
|
136
|
+
client: Any | None = None,
|
|
137
|
+
) -> Any:
|
|
138
|
+
"""Return the stored value or ``default`` without writing back.
|
|
139
|
+
|
|
140
|
+
Callers must apply the result silently: do not fire ``on_change`` and do not
|
|
141
|
+
persist the restored value (that would create a restore/write loop).
|
|
142
|
+
"""
|
|
143
|
+
return read_persisted(persist, element_id, prop, default, client=client)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def navigation_kind(href: str | None, external_link: bool | None) -> str:
|
|
147
|
+
"""Return ``external``, ``internal``, or ``none`` for an href policy."""
|
|
148
|
+
if not href:
|
|
149
|
+
return "none"
|
|
150
|
+
if external_link is True:
|
|
151
|
+
return "external"
|
|
152
|
+
if href.startswith(("http://", "https://", "//")):
|
|
153
|
+
return "external"
|
|
154
|
+
return "internal"
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _click_handler(
|
|
158
|
+
on_click: Callable[..., Any] | None,
|
|
159
|
+
navigate_to: str | None,
|
|
160
|
+
) -> Callable[..., None]:
|
|
161
|
+
def _handler(*_args: Any, **_kwargs: Any) -> None:
|
|
162
|
+
if on_click is not None:
|
|
163
|
+
on_click()
|
|
164
|
+
if navigate_to is not None:
|
|
165
|
+
from nicegui import ui
|
|
166
|
+
|
|
167
|
+
ui.navigate.to(navigate_to)
|
|
168
|
+
|
|
169
|
+
return _handler
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def apply_navigation(
|
|
173
|
+
element: Any,
|
|
174
|
+
href: str | None,
|
|
175
|
+
external_link: bool | None,
|
|
176
|
+
on_click: Callable[..., Any] | None,
|
|
177
|
+
) -> None:
|
|
178
|
+
"""Wire ``href``, ``target``, click handling, and in-app navigation.
|
|
179
|
+
|
|
180
|
+
Buttons never receive ``href``, ``target``, or ``external_link``. External
|
|
181
|
+
links keep a real ``href``/``target`` and do not call ``ui.navigate``.
|
|
182
|
+
Internal links set ``href`` and navigate after ``on_click``.
|
|
183
|
+
"""
|
|
184
|
+
kind = navigation_kind(href, external_link)
|
|
185
|
+
tag = getattr(element, "tag", None)
|
|
186
|
+
if isinstance(tag, str) and tag.lower() == "button":
|
|
187
|
+
if on_click is not None:
|
|
188
|
+
element.on("click", _click_handler(on_click, None))
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
if kind != "none" and href is not None:
|
|
192
|
+
element._props["href"] = href
|
|
193
|
+
if kind == "external":
|
|
194
|
+
element._props["target"] = "_blank"
|
|
195
|
+
|
|
196
|
+
if kind == "internal" and href:
|
|
197
|
+
element.on("click", _click_handler(on_click, href))
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
if on_click is not None:
|
|
201
|
+
element.on("click", _click_handler(on_click, None))
|
|
File without changes
|
|
Binary file
|
|
Binary file
|