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.
Files changed (103) hide show
  1. nicegui_bootstrap_components/__init__.py +7 -0
  2. nicegui_bootstrap_components/_base.py +590 -0
  3. nicegui_bootstrap_components/_host.py +259 -0
  4. nicegui_bootstrap_components/assets.py +371 -0
  5. nicegui_bootstrap_components/bs/__init__.py +267 -0
  6. nicegui_bootstrap_components/bs/_actions.py +232 -0
  7. nicegui_bootstrap_components/bs/_alert_spinner.py +423 -0
  8. nicegui_bootstrap_components/bs/_carousel.py +312 -0
  9. nicegui_bootstrap_components/bs/_choices.py +779 -0
  10. nicegui_bootstrap_components/bs/_content.py +1343 -0
  11. nicegui_bootstrap_components/bs/_forms.py +378 -0
  12. nicegui_bootstrap_components/bs/_inputs.py +560 -0
  13. nicegui_bootstrap_components/bs/_layout.py +341 -0
  14. nicegui_bootstrap_components/bs/_nav.py +650 -0
  15. nicegui_bootstrap_components/bs/_navbar.py +445 -0
  16. nicegui_bootstrap_components/bs/_overlay_root.py +73 -0
  17. nicegui_bootstrap_components/bs/_overlays.py +2633 -0
  18. nicegui_bootstrap_components/bs/_scope.py +28 -0
  19. nicegui_bootstrap_components/bs/_tabs.py +605 -0
  20. nicegui_bootstrap_components/bs/_toast.py +137 -0
  21. nicegui_bootstrap_components/bs/_tooltip_popover.py +537 -0
  22. nicegui_bootstrap_components/contracts/dbc-2.0.4.json +16811 -0
  23. nicegui_bootstrap_components/dbc/__init__.py +108 -0
  24. nicegui_bootstrap_components/icons.py +29 -0
  25. nicegui_bootstrap_components/persist.py +201 -0
  26. nicegui_bootstrap_components/py.typed +0 -0
  27. nicegui_bootstrap_components/static/dist/fonts/bootstrap-icons.woff +0 -0
  28. nicegui_bootstrap_components/static/dist/fonts/bootstrap-icons.woff2 +0 -0
  29. nicegui_bootstrap_components/static/dist/ngbs-bootstrap-unscoped.css +12047 -0
  30. nicegui_bootstrap_components/static/dist/ngbs-bootstrap.css +12057 -0
  31. nicegui_bootstrap_components/static/dist/ngbs-cerulean-unscoped.css +12338 -0
  32. nicegui_bootstrap_components/static/dist/ngbs-cerulean.css +12348 -0
  33. nicegui_bootstrap_components/static/dist/ngbs-compat-unscoped.css +12 -0
  34. nicegui_bootstrap_components/static/dist/ngbs-compat.css +12 -0
  35. nicegui_bootstrap_components/static/dist/ngbs-cosmo-unscoped.css +11825 -0
  36. nicegui_bootstrap_components/static/dist/ngbs-cosmo.css +11835 -0
  37. nicegui_bootstrap_components/static/dist/ngbs-cyborg-unscoped.css +12213 -0
  38. nicegui_bootstrap_components/static/dist/ngbs-cyborg.css +12223 -0
  39. nicegui_bootstrap_components/static/dist/ngbs-darkly-unscoped.css +12143 -0
  40. nicegui_bootstrap_components/static/dist/ngbs-darkly.css +12153 -0
  41. nicegui_bootstrap_components/static/dist/ngbs-flatly-unscoped.css +12129 -0
  42. nicegui_bootstrap_components/static/dist/ngbs-flatly.css +12139 -0
  43. nicegui_bootstrap_components/static/dist/ngbs-grid-unscoped.css +4084 -0
  44. nicegui_bootstrap_components/static/dist/ngbs-grid.css +4094 -0
  45. nicegui_bootstrap_components/static/dist/ngbs-host-unscoped.css +9 -0
  46. nicegui_bootstrap_components/static/dist/ngbs-host.css +9 -0
  47. nicegui_bootstrap_components/static/dist/ngbs-icons-bootstrap.css +5 -0
  48. nicegui_bootstrap_components/static/dist/ngbs-icons-fontawesome.css +9 -0
  49. nicegui_bootstrap_components/static/dist/ngbs-journal-unscoped.css +12112 -0
  50. nicegui_bootstrap_components/static/dist/ngbs-journal.css +12122 -0
  51. nicegui_bootstrap_components/static/dist/ngbs-litera-unscoped.css +12214 -0
  52. nicegui_bootstrap_components/static/dist/ngbs-litera.css +12224 -0
  53. nicegui_bootstrap_components/static/dist/ngbs-lumen-unscoped.css +12377 -0
  54. nicegui_bootstrap_components/static/dist/ngbs-lumen.css +12387 -0
  55. nicegui_bootstrap_components/static/dist/ngbs-lux-unscoped.css +12048 -0
  56. nicegui_bootstrap_components/static/dist/ngbs-lux.css +12058 -0
  57. nicegui_bootstrap_components/static/dist/ngbs-materia-unscoped.css +13197 -0
  58. nicegui_bootstrap_components/static/dist/ngbs-materia.css +13207 -0
  59. nicegui_bootstrap_components/static/dist/ngbs-minty-unscoped.css +12184 -0
  60. nicegui_bootstrap_components/static/dist/ngbs-minty.css +12194 -0
  61. nicegui_bootstrap_components/static/dist/ngbs-morph-unscoped.css +12829 -0
  62. nicegui_bootstrap_components/static/dist/ngbs-morph.css +12839 -0
  63. nicegui_bootstrap_components/static/dist/ngbs-pulse-unscoped.css +11901 -0
  64. nicegui_bootstrap_components/static/dist/ngbs-pulse.css +11911 -0
  65. nicegui_bootstrap_components/static/dist/ngbs-quartz-unscoped.css +12625 -0
  66. nicegui_bootstrap_components/static/dist/ngbs-quartz.css +12635 -0
  67. nicegui_bootstrap_components/static/dist/ngbs-sandstone-unscoped.css +12214 -0
  68. nicegui_bootstrap_components/static/dist/ngbs-sandstone.css +12224 -0
  69. nicegui_bootstrap_components/static/dist/ngbs-simplex-unscoped.css +12199 -0
  70. nicegui_bootstrap_components/static/dist/ngbs-simplex.css +12209 -0
  71. nicegui_bootstrap_components/static/dist/ngbs-sketchy-unscoped.css +12518 -0
  72. nicegui_bootstrap_components/static/dist/ngbs-sketchy.css +12528 -0
  73. nicegui_bootstrap_components/static/dist/ngbs-slate-unscoped.css +12527 -0
  74. nicegui_bootstrap_components/static/dist/ngbs-slate.css +12537 -0
  75. nicegui_bootstrap_components/static/dist/ngbs-solar-unscoped.css +12152 -0
  76. nicegui_bootstrap_components/static/dist/ngbs-solar.css +12162 -0
  77. nicegui_bootstrap_components/static/dist/ngbs-spacelab-unscoped.css +12279 -0
  78. nicegui_bootstrap_components/static/dist/ngbs-spacelab.css +12289 -0
  79. nicegui_bootstrap_components/static/dist/ngbs-superhero-unscoped.css +12223 -0
  80. nicegui_bootstrap_components/static/dist/ngbs-superhero.css +12233 -0
  81. nicegui_bootstrap_components/static/dist/ngbs-united-unscoped.css +12090 -0
  82. nicegui_bootstrap_components/static/dist/ngbs-united.css +12100 -0
  83. nicegui_bootstrap_components/static/dist/ngbs-vapor-unscoped.css +12556 -0
  84. nicegui_bootstrap_components/static/dist/ngbs-vapor.css +12566 -0
  85. nicegui_bootstrap_components/static/dist/ngbs-yeti-unscoped.css +12333 -0
  86. nicegui_bootstrap_components/static/dist/ngbs-yeti.css +12343 -0
  87. nicegui_bootstrap_components/static/dist/ngbs-zephyr-unscoped.css +12296 -0
  88. nicegui_bootstrap_components/static/dist/ngbs-zephyr.css +12306 -0
  89. nicegui_bootstrap_components/static/prototype-ngbs.css +541 -0
  90. nicegui_bootstrap_components/static/webfonts/fa-brands-400.ttf +0 -0
  91. nicegui_bootstrap_components/static/webfonts/fa-brands-400.woff2 +0 -0
  92. nicegui_bootstrap_components/static/webfonts/fa-regular-400.ttf +0 -0
  93. nicegui_bootstrap_components/static/webfonts/fa-regular-400.woff2 +0 -0
  94. nicegui_bootstrap_components/static/webfonts/fa-solid-900.ttf +0 -0
  95. nicegui_bootstrap_components/static/webfonts/fa-solid-900.woff2 +0 -0
  96. nicegui_bootstrap_components/static/webfonts/fa-v4compatibility.ttf +0 -0
  97. nicegui_bootstrap_components/static/webfonts/fa-v4compatibility.woff2 +0 -0
  98. nicegui_bootstrap_components/theme.py +238 -0
  99. nicegui_bootstrap_components/themes.py +131 -0
  100. nicegui_bootstrap_components-0.1.0.dist-info/METADATA +234 -0
  101. nicegui_bootstrap_components-0.1.0.dist-info/RECORD +103 -0
  102. nicegui_bootstrap_components-0.1.0.dist-info/WHEEL +4 -0
  103. nicegui_bootstrap_components-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,378 @@
1
+ """Forms family: Form, Label, FormText, FormFeedback, FormFloating, InputGroup, InputGroupText."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import contextlib
6
+ from collections.abc import Callable
7
+ from typing import Any
8
+
9
+ from .._base import BootstrapElement, UnsupportedPropError, make_surface_classes
10
+ from ._layout import col_breakpoint_classes
11
+
12
+ __all__ = [
13
+ "DbcForm",
14
+ "DbcFormFeedback",
15
+ "DbcFormFloating",
16
+ "DbcFormText",
17
+ "DbcInputGroup",
18
+ "DbcInputGroupText",
19
+ "DbcLabel",
20
+ "Form",
21
+ "FormFeedback",
22
+ "FormFloating",
23
+ "FormText",
24
+ "InputGroup",
25
+ "InputGroupText",
26
+ "Label",
27
+ "form",
28
+ "form_feedback",
29
+ "form_feedback_classes",
30
+ "form_floating",
31
+ "form_method",
32
+ "form_text",
33
+ "form_text_classes",
34
+ "input_group",
35
+ "input_group_classes",
36
+ "input_group_text",
37
+ "label",
38
+ "label_classes",
39
+ ]
40
+
41
+ _FORM_METHODS = frozenset({"GET", "POST"})
42
+ _FEEDBACK_TYPES = frozenset({"valid", "invalid"})
43
+ _SIZES = frozenset({"sm", "md", "lg"})
44
+ _COMPACT_SIZES = frozenset({"sm", "lg"})
45
+ _LABEL_ALIGN = frozenset({"start", "center", "end"})
46
+
47
+ _JS_SUBMIT = """(...args) => {
48
+ const e = args[0];
49
+ if (e && typeof e.preventDefault === 'function') {
50
+ e.preventDefault();
51
+ }
52
+ emit(true);
53
+ }"""
54
+
55
+ _JS_SUBMIT_ALLOW = """(...args) => {
56
+ emit(true);
57
+ }"""
58
+
59
+
60
+ def form_method(method: str | None) -> str | None:
61
+ """Validate Form ``method`` (``GET`` or ``POST``) and return it."""
62
+ if method is None:
63
+ return None
64
+ if method not in _FORM_METHODS:
65
+ raise ValueError(f"Invalid Form method: {method!r}")
66
+ return method
67
+
68
+
69
+ def label_classes(
70
+ *,
71
+ size: str | None = None,
72
+ hidden: bool = False,
73
+ check: bool = False,
74
+ color: str | None = None,
75
+ ) -> list[str]:
76
+ """Return Bootstrap ``form-label`` classes."""
77
+ classes = ["form-label"]
78
+ if hidden:
79
+ classes.append("visually-hidden")
80
+ if size in _COMPACT_SIZES:
81
+ classes.append("col-form-label")
82
+ classes.append(f"col-form-label-{size}")
83
+ elif size not in (None, "md"):
84
+ raise ValueError(f"Invalid Label size: {size!r}")
85
+ if check:
86
+ classes.append("form-check-label")
87
+ if color is not None:
88
+ classes.append(f"text-{color}")
89
+ return classes
90
+
91
+
92
+ def _label_grid_classes(
93
+ *,
94
+ width: object = None,
95
+ xs: object = None,
96
+ sm: object = None,
97
+ md: object = None,
98
+ lg: object = None,
99
+ xl: object = None,
100
+ xxl: object = None,
101
+ align: str | None = None,
102
+ ) -> list[str]:
103
+ if all(value is None for value in (width, xs, sm, md, lg, xl, xxl)):
104
+ return []
105
+ classes = col_breakpoint_classes(
106
+ width=width,
107
+ xs=xs,
108
+ sm=sm,
109
+ md=md,
110
+ lg=lg,
111
+ xl=xl,
112
+ xxl=xxl,
113
+ )
114
+ if align is not None:
115
+ if align not in _LABEL_ALIGN:
116
+ raise ValueError(f"Invalid Label align: {align!r}")
117
+ classes.append(f"align-self-{align}")
118
+ return classes
119
+
120
+
121
+ def form_text_classes(*, color: str | None = None) -> list[str]:
122
+ """Return Bootstrap ``form-text`` classes."""
123
+ classes = ["form-text"]
124
+ if color is not None:
125
+ classes.append(f"text-{color}")
126
+ return classes
127
+
128
+
129
+ def form_feedback_classes(
130
+ *,
131
+ type: str | None = None,
132
+ tooltip: bool = False,
133
+ ) -> list[str]:
134
+ """Return Bootstrap valid/invalid feedback or tooltip classes."""
135
+ if type is None:
136
+ return []
137
+ if type not in _FEEDBACK_TYPES:
138
+ raise ValueError(f"Invalid FormFeedback type: {type!r}")
139
+ kind = "tooltip" if tooltip else "feedback"
140
+ return [f"{type}-{kind}"]
141
+
142
+
143
+ def input_group_classes(*, size: str | None = None) -> list[str]:
144
+ """Return Bootstrap ``input-group`` classes."""
145
+ classes = ["input-group"]
146
+ if size in _COMPACT_SIZES:
147
+ classes.append(f"input-group-{size}")
148
+ elif size not in (None, "md"):
149
+ raise ValueError(f"Invalid InputGroup size: {size!r}")
150
+ return classes
151
+
152
+
153
+ def _apply_html_for_to_first_label(host: Any, html_for: str) -> None:
154
+ """Set ``for`` on the first adopted child whose tag is ``label``."""
155
+ slot = getattr(host, "default_slot", None)
156
+ adopted: Any = getattr(slot, "children", None) if slot is not None else None
157
+ if adopted is None:
158
+ adopted = getattr(host, "elements", None)
159
+ if not adopted:
160
+ return
161
+ for child in adopted:
162
+ if getattr(child, "tag", None) == "label":
163
+ props = getattr(child, "_props", None)
164
+ if props is not None:
165
+ props["for"] = html_for
166
+ break
167
+
168
+
169
+ class _FormImpl(BootstrapElement):
170
+ """Private Form implementation. Submit listener is registered in ``__init__`` only."""
171
+
172
+ component_name = "Form"
173
+ children_kind = "auto"
174
+
175
+ def __init__(
176
+ self,
177
+ children: object = None,
178
+ *,
179
+ _surface: str,
180
+ action: str | None = None,
181
+ method: str | None = None,
182
+ prevent_default_on_submit: bool = True,
183
+ n_submit: int = 0,
184
+ novalidate: bool = False,
185
+ on_submit: Callable[..., Any] | None = None,
186
+ **kwargs: Any,
187
+ ) -> None:
188
+ self._surface = _surface
189
+ method = form_method(method)
190
+ if self._surface == "compat" and novalidate:
191
+ raise UnsupportedPropError("novalidate")
192
+ self._structural_classes = ()
193
+ self._n_submit = int(n_submit)
194
+ self._on_submit = on_submit
195
+ super().__init__(children, tag="form", **kwargs)
196
+ if action is not None:
197
+ self._props["action"] = action
198
+ if method is not None:
199
+ self._props["method"] = method
200
+ if novalidate:
201
+ self._props["novalidate"] = True
202
+ self._props["data-ngbs-prevent-default"] = "true" if prevent_default_on_submit else "false"
203
+ js_handler = _JS_SUBMIT if prevent_default_on_submit else _JS_SUBMIT_ALLOW
204
+ self.on("submit", self._handle_submit, js_handler=js_handler)
205
+
206
+ @property
207
+ def n_submit(self) -> int:
208
+ """Number of times the form was submitted."""
209
+ return self._n_submit
210
+
211
+ def _handle_submit(self, *_args: Any, **_kwargs: Any) -> None:
212
+ self._n_submit += 1
213
+ if self._on_submit is not None:
214
+ self._on_submit()
215
+
216
+
217
+ class _LabelImpl(BootstrapElement):
218
+ """Private Label implementation."""
219
+
220
+ component_name = "Label"
221
+ children_kind = "auto"
222
+ reserved_classes = ("form-label",)
223
+
224
+ def __init__(
225
+ self,
226
+ children: object = None,
227
+ *,
228
+ _surface: str,
229
+ size: str | None = None,
230
+ html_for: str | None = None,
231
+ hidden: bool = False,
232
+ check: bool = False,
233
+ align: str | None = None,
234
+ color: str | None = None,
235
+ width: object = None,
236
+ xs: object = None,
237
+ sm: object = None,
238
+ md: object = None,
239
+ lg: object = None,
240
+ xl: object = None,
241
+ xxl: object = None,
242
+ **kwargs: Any,
243
+ ) -> None:
244
+ self._surface = _surface
245
+ self._structural_classes = tuple(
246
+ label_classes(size=size, hidden=hidden, check=check, color=color)
247
+ + _label_grid_classes(
248
+ width=width,
249
+ xs=xs,
250
+ sm=sm,
251
+ md=md,
252
+ lg=lg,
253
+ xl=xl,
254
+ xxl=xxl,
255
+ align=align,
256
+ )
257
+ )
258
+ super().__init__(children, tag="label", **kwargs)
259
+ if html_for is not None:
260
+ self._props["for"] = html_for
261
+
262
+
263
+ class _FormTextImpl(BootstrapElement):
264
+ """Private FormText implementation."""
265
+
266
+ component_name = "FormText"
267
+ children_kind = "auto"
268
+ reserved_classes = ("form-text",)
269
+
270
+ def __init__(
271
+ self,
272
+ children: object = None,
273
+ *,
274
+ _surface: str,
275
+ color: str | None = None,
276
+ **kwargs: Any,
277
+ ) -> None:
278
+ self._surface = _surface
279
+ self._structural_classes = tuple(form_text_classes(color=color))
280
+ super().__init__(children, tag="small", **kwargs)
281
+
282
+
283
+ class _FormFeedbackImpl(BootstrapElement):
284
+ """Private FormFeedback implementation."""
285
+
286
+ component_name = "FormFeedback"
287
+ children_kind = "auto"
288
+
289
+ def __init__(
290
+ self,
291
+ children: object = None,
292
+ *,
293
+ _surface: str,
294
+ type: str | None = None,
295
+ tooltip: bool = False,
296
+ **kwargs: Any,
297
+ ) -> None:
298
+ self._surface = _surface
299
+ self._structural_classes = tuple(form_feedback_classes(type=type, tooltip=tooltip))
300
+ super().__init__(children, tag="div", **kwargs)
301
+
302
+
303
+ class _FormFloatingImpl(BootstrapElement):
304
+ """Private FormFloating. Control-then-label child order is required; not reordered."""
305
+
306
+ component_name = "FormFloating"
307
+ children_kind = "auto"
308
+ reserved_classes = ("form-floating",)
309
+
310
+ def __init__(
311
+ self,
312
+ children: object = None,
313
+ *,
314
+ _surface: str,
315
+ html_for: str | None = None,
316
+ **kwargs: Any,
317
+ ) -> None:
318
+ self._surface = _surface
319
+ self._structural_classes = ("form-floating",)
320
+ super().__init__(children, tag="div", **kwargs)
321
+ if html_for is not None:
322
+ with contextlib.suppress(Exception):
323
+ _apply_html_for_to_first_label(self, html_for)
324
+
325
+
326
+ class _InputGroupImpl(BootstrapElement):
327
+ """Private InputGroup implementation."""
328
+
329
+ component_name = "InputGroup"
330
+ children_kind = "grouping"
331
+ reserved_classes = ("input-group",)
332
+
333
+ def __init__(
334
+ self,
335
+ children: object = None,
336
+ *,
337
+ _surface: str,
338
+ size: str | None = None,
339
+ **kwargs: Any,
340
+ ) -> None:
341
+ self._surface = _surface
342
+ self._structural_classes = tuple(input_group_classes(size=size))
343
+ super().__init__(children, tag="div", **kwargs)
344
+
345
+
346
+ class _InputGroupTextImpl(BootstrapElement):
347
+ """Private InputGroupText implementation."""
348
+
349
+ component_name = "InputGroupText"
350
+ children_kind = "auto"
351
+ reserved_classes = ("input-group-text",)
352
+
353
+ def __init__(
354
+ self,
355
+ children: object = None,
356
+ *,
357
+ _surface: str,
358
+ **kwargs: Any,
359
+ ) -> None:
360
+ self._surface = _surface
361
+ self._structural_classes = ("input-group-text",)
362
+ super().__init__(children, tag="span", **kwargs)
363
+
364
+
365
+ Form, DbcForm = make_surface_classes("Form", globals())
366
+ form = Form
367
+ Label, DbcLabel = make_surface_classes("Label", globals())
368
+ label = Label
369
+ FormText, DbcFormText = make_surface_classes("FormText", globals())
370
+ form_text = FormText
371
+ FormFeedback, DbcFormFeedback = make_surface_classes("FormFeedback", globals())
372
+ form_feedback = FormFeedback
373
+ FormFloating, DbcFormFloating = make_surface_classes("FormFloating", globals())
374
+ form_floating = FormFloating
375
+ InputGroup, DbcInputGroup = make_surface_classes("InputGroup", globals())
376
+ input_group = InputGroup
377
+ InputGroupText, DbcInputGroupText = make_surface_classes("InputGroupText", globals())
378
+ input_group_text = InputGroupText