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,312 @@
|
|
|
1
|
+
"""Carousel family (native + compat sibling types)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from nicegui.element import Element
|
|
9
|
+
|
|
10
|
+
from .._base import BootstrapElement, make_surface_classes, normalize_style, style_to_css
|
|
11
|
+
from .._host import set_element_text
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"Carousel",
|
|
15
|
+
"DbcCarousel",
|
|
16
|
+
"carousel",
|
|
17
|
+
"carousel_structural_classes",
|
|
18
|
+
"clamp_carousel_index",
|
|
19
|
+
"normalize_carousel_item",
|
|
20
|
+
"resolve_carousel_interval",
|
|
21
|
+
"wrap_carousel_index",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
_KNOWN_ITEM_KEYS: tuple[str, ...] = (
|
|
25
|
+
"src",
|
|
26
|
+
"alt",
|
|
27
|
+
"header",
|
|
28
|
+
"caption",
|
|
29
|
+
"img_style",
|
|
30
|
+
"img_class_name",
|
|
31
|
+
"caption_class_name",
|
|
32
|
+
"href",
|
|
33
|
+
"target",
|
|
34
|
+
"external_link",
|
|
35
|
+
)
|
|
36
|
+
_DEFAULT_IMG_CLASS_NAME = "d-block w-100"
|
|
37
|
+
_PERSIST_MODES: tuple[str, ...] = ("off", "local", "session")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def carousel_structural_classes(
|
|
41
|
+
*,
|
|
42
|
+
slide: bool = True,
|
|
43
|
+
variant: str | None = None,
|
|
44
|
+
) -> list[str]:
|
|
45
|
+
"""Return Bootstrap ``carousel`` classes. Unknown variants raise ``ValueError``."""
|
|
46
|
+
if variant is not None and variant != "dark":
|
|
47
|
+
raise ValueError(f"variant must be None or 'dark', got {variant!r}")
|
|
48
|
+
classes = ["carousel"]
|
|
49
|
+
if slide:
|
|
50
|
+
classes.append("slide")
|
|
51
|
+
if variant == "dark":
|
|
52
|
+
classes.append("carousel-dark")
|
|
53
|
+
return classes
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def normalize_carousel_item(item: dict[str, Any]) -> dict[str, Any]:
|
|
57
|
+
"""Return a copy with known keys only and default ``img_class_name``."""
|
|
58
|
+
normalized: dict[str, Any] = {key: item[key] for key in _KNOWN_ITEM_KEYS if key in item}
|
|
59
|
+
normalized.setdefault("img_class_name", _DEFAULT_IMG_CLASS_NAME)
|
|
60
|
+
return normalized
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def wrap_carousel_index(index: int, length: int) -> int:
|
|
64
|
+
"""Wrap ``index`` into ``[0, length)``. Empty length yields ``0``."""
|
|
65
|
+
if length <= 0:
|
|
66
|
+
return 0
|
|
67
|
+
return index % length
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def clamp_carousel_index(index: int, length: int) -> int:
|
|
71
|
+
"""Return ``index`` if in range, otherwise ``0``. Empty length yields ``0``."""
|
|
72
|
+
if length <= 0 or index < 0 or index >= length:
|
|
73
|
+
return 0
|
|
74
|
+
return index
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def resolve_carousel_interval(interval: int | bool | None) -> int | None:
|
|
78
|
+
"""Return autoplay milliseconds, or ``None`` when autoplay is disabled."""
|
|
79
|
+
if interval is False or interval is None:
|
|
80
|
+
return None
|
|
81
|
+
return int(interval)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _validate_persist(persist: str, public_id: str | None) -> None:
|
|
85
|
+
if persist not in _PERSIST_MODES:
|
|
86
|
+
raise ValueError(f"persist must be 'off', 'local', or 'session', got {persist!r}")
|
|
87
|
+
if persist != "off" and not public_id:
|
|
88
|
+
raise ValueError("persist requires a public id when not 'off'")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class _CarouselImpl(BootstrapElement):
|
|
92
|
+
"""Private Carousel implementation driven by an ``items`` dict list."""
|
|
93
|
+
|
|
94
|
+
component_name = "Carousel"
|
|
95
|
+
children_kind = "grouping"
|
|
96
|
+
reserved_classes = ("carousel",)
|
|
97
|
+
|
|
98
|
+
def __init__(
|
|
99
|
+
self,
|
|
100
|
+
children: object = None,
|
|
101
|
+
*,
|
|
102
|
+
_surface: str,
|
|
103
|
+
items: list[dict[str, Any]] | None = None,
|
|
104
|
+
active_index: int = 0,
|
|
105
|
+
controls: bool = True,
|
|
106
|
+
indicators: bool = True,
|
|
107
|
+
interval: int | bool | None = None,
|
|
108
|
+
slide: bool | None = True,
|
|
109
|
+
variant: str | None = None,
|
|
110
|
+
persist: str = "off",
|
|
111
|
+
on_change: Callable[..., Any] | None = None,
|
|
112
|
+
**kwargs: Any,
|
|
113
|
+
) -> None:
|
|
114
|
+
if "ride" in kwargs:
|
|
115
|
+
raise TypeError("Carousel.__init__() got an unexpected keyword argument 'ride'")
|
|
116
|
+
if not isinstance(items, list):
|
|
117
|
+
raise TypeError("items must be a list of dicts")
|
|
118
|
+
for item in items:
|
|
119
|
+
if not isinstance(item, dict):
|
|
120
|
+
raise TypeError("each carousel item must be a dict")
|
|
121
|
+
|
|
122
|
+
self._surface = _surface
|
|
123
|
+
raw_id: Any = kwargs.get("id")
|
|
124
|
+
public_id = raw_id if isinstance(raw_id, str) else None
|
|
125
|
+
_validate_persist(persist, public_id)
|
|
126
|
+
|
|
127
|
+
slide_enabled = True if slide is None else bool(slide)
|
|
128
|
+
self._structural_classes = tuple(
|
|
129
|
+
carousel_structural_classes(slide=slide_enabled, variant=variant)
|
|
130
|
+
)
|
|
131
|
+
self._items = [normalize_carousel_item(item) for item in items]
|
|
132
|
+
self._active_index = clamp_carousel_index(active_index, len(self._items))
|
|
133
|
+
self._show_controls = bool(controls)
|
|
134
|
+
self._show_indicators = bool(indicators)
|
|
135
|
+
self._on_change = on_change
|
|
136
|
+
self._persist = persist
|
|
137
|
+
self._interval = resolve_carousel_interval(interval)
|
|
138
|
+
self._public_id = public_id
|
|
139
|
+
self._item_elements: list[Element] = []
|
|
140
|
+
self._indicator_elements: list[Element] = []
|
|
141
|
+
|
|
142
|
+
super().__init__(None, tag="div", **kwargs)
|
|
143
|
+
|
|
144
|
+
if self._interval is None:
|
|
145
|
+
self._props["data-bs-interval"] = "false"
|
|
146
|
+
else:
|
|
147
|
+
self._props["data-bs-interval"] = str(self._interval)
|
|
148
|
+
self._props["data-bs-ride"] = "carousel"
|
|
149
|
+
|
|
150
|
+
self._build()
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def active_index(self) -> int:
|
|
154
|
+
"""Zero-based index of the visible slide."""
|
|
155
|
+
return self._active_index
|
|
156
|
+
|
|
157
|
+
def _target_selector(self) -> str:
|
|
158
|
+
return f"#{self._public_id}" if self._public_id else ""
|
|
159
|
+
|
|
160
|
+
def _build(self) -> None:
|
|
161
|
+
with self:
|
|
162
|
+
self._build_indicators()
|
|
163
|
+
self._build_inner()
|
|
164
|
+
self._build_controls()
|
|
165
|
+
|
|
166
|
+
def _build_indicators(self) -> None:
|
|
167
|
+
if not self._show_indicators or not self._items:
|
|
168
|
+
return
|
|
169
|
+
indicators = Element("div")
|
|
170
|
+
indicators.classes("carousel-indicators")
|
|
171
|
+
with indicators:
|
|
172
|
+
for index, _item in enumerate(self._items):
|
|
173
|
+
button = Element("button")
|
|
174
|
+
button._props["type"] = "button"
|
|
175
|
+
button._props["data-bs-target"] = self._target_selector()
|
|
176
|
+
button._props["data-bs-slide-to"] = str(index)
|
|
177
|
+
button._props["aria-label"] = f"Slide {index + 1}"
|
|
178
|
+
if index == self._active_index:
|
|
179
|
+
button.classes(add="active")
|
|
180
|
+
button._props["aria-current"] = "true"
|
|
181
|
+
button.on("click", self._make_index_handler(index))
|
|
182
|
+
self._indicator_elements.append(button)
|
|
183
|
+
|
|
184
|
+
def _build_inner(self) -> None:
|
|
185
|
+
inner = Element("div")
|
|
186
|
+
inner.classes("carousel-inner")
|
|
187
|
+
with inner:
|
|
188
|
+
for index, item in enumerate(self._items):
|
|
189
|
+
self._build_item(item, is_active=index == self._active_index)
|
|
190
|
+
|
|
191
|
+
def _build_item(self, item: dict[str, Any], *, is_active: bool) -> None:
|
|
192
|
+
item_el = Element("div")
|
|
193
|
+
item_el.classes("carousel-item")
|
|
194
|
+
if is_active:
|
|
195
|
+
item_el.classes(add="active")
|
|
196
|
+
with item_el:
|
|
197
|
+
href = item.get("href")
|
|
198
|
+
if href:
|
|
199
|
+
link = Element("a")
|
|
200
|
+
self._apply_link_props(link, item)
|
|
201
|
+
with link:
|
|
202
|
+
self._add_image(item)
|
|
203
|
+
self._add_caption(item)
|
|
204
|
+
else:
|
|
205
|
+
self._add_image(item)
|
|
206
|
+
self._add_caption(item)
|
|
207
|
+
self._item_elements.append(item_el)
|
|
208
|
+
|
|
209
|
+
def _apply_link_props(self, link: Element, item: dict[str, Any]) -> None:
|
|
210
|
+
link._props["href"] = str(item["href"])
|
|
211
|
+
target = item.get("target")
|
|
212
|
+
if item.get("external_link"):
|
|
213
|
+
link._props["target"] = str(target) if target else "_blank"
|
|
214
|
+
link._props["rel"] = "noopener noreferrer"
|
|
215
|
+
elif target:
|
|
216
|
+
link._props["target"] = str(target)
|
|
217
|
+
|
|
218
|
+
def _add_image(self, item: dict[str, Any]) -> None:
|
|
219
|
+
image = Element("img")
|
|
220
|
+
image.classes(str(item.get("img_class_name") or _DEFAULT_IMG_CLASS_NAME))
|
|
221
|
+
src = item.get("src")
|
|
222
|
+
if src is not None:
|
|
223
|
+
image._props["src"] = str(src)
|
|
224
|
+
alt = item.get("alt")
|
|
225
|
+
image._props["alt"] = "" if alt is None else str(alt)
|
|
226
|
+
raw_style = item.get("img_style")
|
|
227
|
+
if raw_style is not None:
|
|
228
|
+
if isinstance(raw_style, dict):
|
|
229
|
+
image.style(style_to_css(normalize_style(raw_style)))
|
|
230
|
+
else:
|
|
231
|
+
image.style(str(raw_style))
|
|
232
|
+
|
|
233
|
+
def _add_caption(self, item: dict[str, Any]) -> None:
|
|
234
|
+
header = item.get("header")
|
|
235
|
+
caption = item.get("caption")
|
|
236
|
+
if not header and not caption:
|
|
237
|
+
return
|
|
238
|
+
caption_el = Element("div")
|
|
239
|
+
caption_el.classes("carousel-caption")
|
|
240
|
+
extra = item.get("caption_class_name")
|
|
241
|
+
if extra:
|
|
242
|
+
caption_el.classes(str(extra))
|
|
243
|
+
with caption_el:
|
|
244
|
+
if header:
|
|
245
|
+
heading = Element("h5")
|
|
246
|
+
set_element_text(heading, str(header))
|
|
247
|
+
if caption:
|
|
248
|
+
paragraph = Element("p")
|
|
249
|
+
set_element_text(paragraph, str(caption))
|
|
250
|
+
|
|
251
|
+
def _build_controls(self) -> None:
|
|
252
|
+
if not self._show_controls:
|
|
253
|
+
return
|
|
254
|
+
self._build_control("prev")
|
|
255
|
+
self._build_control("next")
|
|
256
|
+
|
|
257
|
+
def _build_control(self, direction: str) -> None:
|
|
258
|
+
button = Element("button")
|
|
259
|
+
button.classes(f"carousel-control-{direction}")
|
|
260
|
+
button._props["type"] = "button"
|
|
261
|
+
button._props["data-bs-target"] = self._target_selector()
|
|
262
|
+
button._props["data-bs-slide"] = direction
|
|
263
|
+
with button:
|
|
264
|
+
icon = Element("span")
|
|
265
|
+
icon.classes(f"carousel-control-{direction}-icon")
|
|
266
|
+
icon._props["aria-hidden"] = "true"
|
|
267
|
+
label = Element("span")
|
|
268
|
+
label.classes("visually-hidden")
|
|
269
|
+
set_element_text(label, "Previous" if direction == "prev" else "Next")
|
|
270
|
+
if direction == "prev":
|
|
271
|
+
button.on("click", self._handle_prev)
|
|
272
|
+
else:
|
|
273
|
+
button.on("click", self._handle_next)
|
|
274
|
+
|
|
275
|
+
def _make_index_handler(self, index: int) -> Callable[..., None]:
|
|
276
|
+
def _handler(*_args: Any, **_kwargs: Any) -> None:
|
|
277
|
+
self._go_to(index, notify=True)
|
|
278
|
+
|
|
279
|
+
return _handler
|
|
280
|
+
|
|
281
|
+
def _handle_prev(self, *_args: Any, **_kwargs: Any) -> None:
|
|
282
|
+
self._go_to(wrap_carousel_index(self._active_index - 1, len(self._items)), notify=True)
|
|
283
|
+
|
|
284
|
+
def _handle_next(self, *_args: Any, **_kwargs: Any) -> None:
|
|
285
|
+
self._go_to(wrap_carousel_index(self._active_index + 1, len(self._items)), notify=True)
|
|
286
|
+
|
|
287
|
+
def _go_to(self, index: int, *, notify: bool) -> None:
|
|
288
|
+
length = len(self._item_elements)
|
|
289
|
+
if length == 0:
|
|
290
|
+
self._active_index = 0
|
|
291
|
+
return
|
|
292
|
+
new_index = wrap_carousel_index(index, length)
|
|
293
|
+
changed = new_index != self._active_index
|
|
294
|
+
self._active_index = new_index
|
|
295
|
+
for i, item_el in enumerate(self._item_elements):
|
|
296
|
+
if i == new_index:
|
|
297
|
+
item_el.classes(add="active")
|
|
298
|
+
else:
|
|
299
|
+
item_el.classes(remove="active")
|
|
300
|
+
for i, indicator_el in enumerate(self._indicator_elements):
|
|
301
|
+
if i == new_index:
|
|
302
|
+
indicator_el.classes(add="active")
|
|
303
|
+
indicator_el._props["aria-current"] = "true"
|
|
304
|
+
else:
|
|
305
|
+
indicator_el.classes(remove="active")
|
|
306
|
+
indicator_el._props["aria-current"] = "false"
|
|
307
|
+
if notify and changed and self._on_change is not None:
|
|
308
|
+
self._on_change()
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
Carousel, DbcCarousel = make_surface_classes("Carousel", globals())
|
|
312
|
+
carousel = Carousel
|