tempest-core 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 (48) hide show
  1. tempest_core/__init__.py +86 -0
  2. tempest_core/animation.py +425 -0
  3. tempest_core/components/__init__.py +119 -0
  4. tempest_core/components/bars.py +266 -0
  5. tempest_core/components/base.py +54 -0
  6. tempest_core/components/brforms.py +461 -0
  7. tempest_core/components/cards.py +200 -0
  8. tempest_core/components/dates.py +221 -0
  9. tempest_core/components/disclosure.py +83 -0
  10. tempest_core/components/feedback.py +194 -0
  11. tempest_core/components/fields.py +204 -0
  12. tempest_core/components/layout.py +179 -0
  13. tempest_core/components/mediainputs.py +254 -0
  14. tempest_core/components/menu.py +111 -0
  15. tempest_core/components/navigation.py +215 -0
  16. tempest_core/components/selection.py +269 -0
  17. tempest_core/components/table.py +235 -0
  18. tempest_core/core/__init__.py +45 -0
  19. tempest_core/core/introspection.py +271 -0
  20. tempest_core/core/ir.py +159 -0
  21. tempest_core/core/reconciler.py +302 -0
  22. tempest_core/core/state.py +656 -0
  23. tempest_core/devices.py +144 -0
  24. tempest_core/i18n.py +90 -0
  25. tempest_core/icons.py +394 -0
  26. tempest_core/navigation.py +114 -0
  27. tempest_core/py.typed +0 -0
  28. tempest_core/style.py +722 -0
  29. tempest_core/theme.py +126 -0
  30. tempest_core/validators.py +168 -0
  31. tempest_core/widgets/__init__.py +352 -0
  32. tempest_core/widgets/animated.py +283 -0
  33. tempest_core/widgets/base.py +386 -0
  34. tempest_core/widgets/button.py +31 -0
  35. tempest_core/widgets/events.py +760 -0
  36. tempest_core/widgets/forms.py +241 -0
  37. tempest_core/widgets/gestures.py +426 -0
  38. tempest_core/widgets/indicators.py +53 -0
  39. tempest_core/widgets/inputs.py +553 -0
  40. tempest_core/widgets/layout.py +370 -0
  41. tempest_core/widgets/lists.py +518 -0
  42. tempest_core/widgets/media.py +613 -0
  43. tempest_core/widgets/navigation_widgets.py +182 -0
  44. tempest_core/widgets/overlays.py +270 -0
  45. tempest_core/widgets/text.py +19 -0
  46. tempest_core-0.1.0.dist-info/METADATA +66 -0
  47. tempest_core-0.1.0.dist-info/RECORD +48 -0
  48. tempest_core-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,86 @@
1
+ """tempest-core — the renderer-agnostic core shared across the tempest stack.
2
+
3
+ The engine behind both tempestroid (native renderers) and tempestweb (DOM): the
4
+ IR, reconciler, state model, style model, widgets, components and the
5
+ cross-cutting helpers (animation, i18n, navigation, theme, validators). It carries
6
+ no platform-coupled code (no Qt, no JNI, no Android, no DOM) so it imports cleanly
7
+ under CPython, Pyodide and a headless server.
8
+
9
+ This is the single source of truth — consumers depend on the published package and
10
+ import from here (``from tempest_core import App, Column, build, diff``) rather than
11
+ vendoring a copy.
12
+ """
13
+
14
+ from tempest_core.animation import AnimationController
15
+ from tempest_core.core import (
16
+ App,
17
+ Insert,
18
+ Node,
19
+ OverlayEntry,
20
+ Patch,
21
+ Path,
22
+ Remove,
23
+ Reorder,
24
+ Replace,
25
+ Scene,
26
+ Update,
27
+ build,
28
+ build_scene,
29
+ diff,
30
+ diff_scene,
31
+ event_catalog,
32
+ introspect,
33
+ widget_catalog,
34
+ )
35
+ from tempest_core.i18n import Locale, t, translate
36
+ from tempest_core.navigation import NavStack, Route, routes_from_path
37
+ from tempest_core.style import Style
38
+ from tempest_core.theme import MediaQueryData, Theme, ThemeMode
39
+ from tempest_core.widgets import (
40
+ Button,
41
+ Column,
42
+ Component,
43
+ Container,
44
+ Row,
45
+ Text,
46
+ Widget,
47
+ )
48
+
49
+ __all__ = [
50
+ "AnimationController",
51
+ "App",
52
+ "Button",
53
+ "Column",
54
+ "Component",
55
+ "Container",
56
+ "Insert",
57
+ "Locale",
58
+ "MediaQueryData",
59
+ "NavStack",
60
+ "Node",
61
+ "OverlayEntry",
62
+ "Patch",
63
+ "Path",
64
+ "Remove",
65
+ "Reorder",
66
+ "Replace",
67
+ "Route",
68
+ "Row",
69
+ "Scene",
70
+ "Style",
71
+ "Text",
72
+ "Theme",
73
+ "ThemeMode",
74
+ "Update",
75
+ "Widget",
76
+ "build",
77
+ "build_scene",
78
+ "diff",
79
+ "diff_scene",
80
+ "event_catalog",
81
+ "introspect",
82
+ "routes_from_path",
83
+ "t",
84
+ "translate",
85
+ "widget_catalog",
86
+ ]
@@ -0,0 +1,425 @@
1
+ """Explicit, core-driven animation framework.
2
+
3
+ This module holds the *driver* half of tempestroid's animation system, which
4
+ lives entirely in the renderer-agnostic core so the reconciler stays pure: an
5
+ :class:`AnimationController` advances a normalized ``value`` (0.0..1.0) on the
6
+ app's frame clock, a :class:`Tween` interpolates a typed value (``float``,
7
+ :class:`~tempestroid.style.Color`, :class:`~tempestroid.style.Edge` or a numeric
8
+ ``tuple``) from that ``value``, and the user's ``view`` reads the interpolated
9
+ result to build a tree whose styles are already at their per-frame target.
10
+
11
+ Because the interpolation happens here — not in either leaf renderer — both the
12
+ Qt and Compose backends only ever see *final* props for the current frame, so
13
+ the divergence between "interpolate in the core" (Qt) and "drive the native
14
+ animation engine" (Compose) is confined to the leaf renderers (documented in the
15
+ conformance suite).
16
+
17
+ The :class:`AnimationController` is wired to an :class:`~tempestroid.core.state.App`
18
+ lazily — :meth:`AnimationController.forward`/:meth:`AnimationController.reverse`
19
+ bind the controller to whatever app registered it — so this module never imports
20
+ ``App`` and there is no import cycle (the binding is duck-typed through a small
21
+ :class:`_AppClock` protocol).
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import math
27
+ from collections.abc import Callable
28
+ from typing import Generic, Protocol, TypeVar, cast, runtime_checkable
29
+
30
+ from pydantic import BaseModel, ConfigDict, Field
31
+
32
+ from tempest_core.style import Color, Curve, Edge
33
+
34
+ __all__ = ["Spring", "AnimationController", "Tween"]
35
+
36
+ T = TypeVar("T")
37
+
38
+
39
+ @runtime_checkable
40
+ class _AppClock(Protocol):
41
+ """The slice of :class:`~tempestroid.core.state.App` an animation drives.
42
+
43
+ Declared structurally so :class:`AnimationController` binds to an app via
44
+ duck typing, keeping ``animation.py`` free of any ``App`` import (no cycle).
45
+ """
46
+
47
+ def register_animation(self, ctrl: AnimationController) -> None:
48
+ """Register an active controller on the app's frame clock."""
49
+ ...
50
+
51
+ def unregister_animation(self, ctrl: AnimationController) -> None:
52
+ """Remove a finished/stopped controller from the app's frame clock."""
53
+ ...
54
+
55
+
56
+ class Spring(BaseModel):
57
+ """A spring's physical parameters, used instead of a fixed duration.
58
+
59
+ When a :class:`AnimationController` is given a :class:`Spring`, it advances
60
+ its ``value`` by integrating a damped harmonic oscillator toward the target
61
+ (1.0 on ``forward``, 0.0 on ``reverse``) rather than easing over a fixed
62
+ ``duration_s``. Frozen so it can be compared/diffed by value.
63
+
64
+ Attributes:
65
+ stiffness: The spring constant ``k`` (higher snaps faster).
66
+ damping: The damping coefficient ``c`` (higher settles with less bounce).
67
+ mass: The attached mass ``m`` (higher is more sluggish).
68
+ """
69
+
70
+ model_config = ConfigDict(frozen=True)
71
+
72
+ stiffness: float = Field(default=300.0, gt=0.0)
73
+ damping: float = Field(default=30.0, ge=0.0)
74
+ mass: float = Field(default=1.0, gt=0.0)
75
+
76
+
77
+ def _apply_curve(curve: Curve, t: float) -> float:
78
+ """Map a linear progress ``t`` (0..1) through an easing curve.
79
+
80
+ These are pure, dependency-free approximations of the named curves so the
81
+ core can interpolate without a renderer. The leaf renderers may apply their
82
+ own native curve to the *same* ``Curve`` value; the core's job is only to
83
+ produce a smooth per-frame value for the simulator/test clock.
84
+
85
+ Args:
86
+ curve: The easing curve to apply.
87
+ t: Linear progress, clamped to ``[0.0, 1.0]``.
88
+
89
+ Returns:
90
+ The eased progress, in ``[0.0, 1.0]`` for the monotone curves and
91
+ possibly slightly outside for the overshoot curves (``ELASTIC``).
92
+ """
93
+ t = 0.0 if t < 0.0 else 1.0 if t > 1.0 else t
94
+ if curve is Curve.LINEAR:
95
+ return t
96
+ if curve is Curve.EASE_IN:
97
+ return t * t
98
+ if curve is Curve.EASE_OUT:
99
+ return 1.0 - (1.0 - t) * (1.0 - t)
100
+ if curve in (Curve.EASE_IN_OUT, Curve.EASE):
101
+ # Smooth cubic ease-in-out (matches CSS ``ease``/``ease-in-out`` closely).
102
+ if t < 0.5:
103
+ return 4.0 * t * t * t
104
+ f = 2.0 * t - 2.0
105
+ return 1.0 + f * f * f / 2.0
106
+ if curve is Curve.BOUNCE:
107
+ return _bounce_out(t)
108
+ if curve is Curve.ELASTIC:
109
+ if t in (0.0, 1.0):
110
+ return t
111
+ c4 = (2.0 * math.pi) / 3.0
112
+ return float(-(2.0 ** (10.0 * t - 10.0)) * math.sin((t * 10.0 - 10.75) * c4))
113
+ return t
114
+
115
+
116
+ def _bounce_out(t: float) -> float:
117
+ """Compute the ``ease-out`` bounce curve (decelerating with rebounds).
118
+
119
+ Args:
120
+ t: Linear progress, in ``[0.0, 1.0]``.
121
+
122
+ Returns:
123
+ The bounced progress, in ``[0.0, 1.0]``.
124
+ """
125
+ n1 = 7.5625
126
+ d1 = 2.75
127
+ if t < 1.0 / d1:
128
+ return n1 * t * t
129
+ if t < 2.0 / d1:
130
+ t -= 1.5 / d1
131
+ return n1 * t * t + 0.75
132
+ if t < 2.5 / d1:
133
+ t -= 2.25 / d1
134
+ return n1 * t * t + 0.9375
135
+ t -= 2.625 / d1
136
+ return n1 * t * t + 0.984375
137
+
138
+
139
+ class AnimationController:
140
+ """Drives a normalized ``value`` on the app's frame clock.
141
+
142
+ A controller is renderer-agnostic: it owns only its progress (``value``,
143
+ 0.0..1.0), the direction it is moving (``forward`` toward 1.0, ``reverse``
144
+ toward 0.0), and how to advance — either an eased ramp over ``duration_s`` or
145
+ a :class:`Spring` integration. The app's clock calls :meth:`_advance` once
146
+ per frame with the elapsed ``dt`` and removes the controller when it reports
147
+ completion.
148
+
149
+ The controller binds to an app lazily: it stores no ``App`` reference until
150
+ :meth:`forward`/:meth:`reverse` is called *after* the app has registered it
151
+ (via :meth:`bind`), so a controller can be constructed in a ``view`` without
152
+ a circular import.
153
+
154
+ Attributes:
155
+ value: The current progress, 0.0..1.0 — read by the ``view``.
156
+
157
+ Methods:
158
+ bind: Attach the controller to an app's frame clock.
159
+ forward: Animate ``value`` toward 1.0 and (re)register on the app clock.
160
+ reverse: Animate ``value`` toward 0.0 and (re)register on the app clock.
161
+ stop: Halt the animation and unregister from the app clock.
162
+ """
163
+
164
+ def __init__(
165
+ self,
166
+ duration_s: float,
167
+ curve: Curve = Curve.EASE_IN_OUT,
168
+ spring: Spring | None = None,
169
+ *,
170
+ time_source: Callable[[], float] | None = None,
171
+ ) -> None:
172
+ """Initialize the controller.
173
+
174
+ Args:
175
+ duration_s: The ramp duration in seconds (ignored when ``spring`` is
176
+ given). Must be positive for a fixed-duration ramp.
177
+ curve: The easing curve applied to the linear ramp.
178
+ spring: Optional spring parameters; when set, the controller
179
+ integrates a damped oscillator instead of easing over a fixed
180
+ duration.
181
+ time_source: Optional injectable monotonic clock (seconds). Tests
182
+ pass a deterministic source; in production the app supplies its
183
+ own loop clock, so this is normally left unset.
184
+ """
185
+ self.duration_s: float = duration_s
186
+ self.curve: Curve = curve
187
+ self.spring: Spring | None = spring
188
+ self.value: float = 0.0
189
+ self._time_source: Callable[[], float] | None = time_source
190
+ self._dir: int = 0
191
+ self._elapsed: float = 0.0
192
+ # Spring integration state (velocity), only used when ``spring`` is set.
193
+ self._velocity: float = 0.0
194
+ self._app: _AppClock | None = None
195
+
196
+ def bind(self, app: _AppClock) -> None:
197
+ """Attach the controller to an app's frame clock.
198
+
199
+ Called by :meth:`~tempestroid.core.state.App.register_animation` so a
200
+ later :meth:`stop` can unregister, and so :meth:`forward`/:meth:`reverse`
201
+ can (re)register even if invoked after construction.
202
+
203
+ Args:
204
+ app: The app driving this controller's frames.
205
+ """
206
+ self._app = app
207
+
208
+ def forward(self) -> None:
209
+ """Animate ``value`` toward 1.0 and (re)register on the app clock."""
210
+ self._dir = 1
211
+ if self._app is not None:
212
+ self._app.register_animation(self)
213
+
214
+ def reverse(self) -> None:
215
+ """Animate ``value`` toward 0.0 and (re)register on the app clock."""
216
+ self._dir = -1
217
+ if self._app is not None:
218
+ self._app.register_animation(self)
219
+
220
+ def stop(self) -> None:
221
+ """Halt the animation and unregister from the app clock."""
222
+ self._dir = 0
223
+ self._velocity = 0.0
224
+ if self._app is not None:
225
+ self._app.unregister_animation(self)
226
+
227
+ def _advance(self, dt: float) -> bool:
228
+ """Advance the controller by ``dt`` seconds toward its target.
229
+
230
+ Args:
231
+ dt: Elapsed wall-clock time since the previous frame, in seconds.
232
+
233
+ Returns:
234
+ ``True`` when the controller has reached its target (0.0 on reverse,
235
+ 1.0 on forward) and should be unregistered; ``False`` otherwise.
236
+ """
237
+ if self._dir == 0:
238
+ return True
239
+ if dt < 0.0:
240
+ dt = 0.0
241
+ if self.spring is not None:
242
+ return self._advance_spring(dt)
243
+ return self._advance_ramp(dt)
244
+
245
+ def _advance_ramp(self, dt: float) -> bool:
246
+ """Advance an eased fixed-duration ramp.
247
+
248
+ Args:
249
+ dt: Elapsed time since the previous frame, in seconds.
250
+
251
+ Returns:
252
+ ``True`` when the ramp has reached its target end, else ``False``.
253
+ """
254
+ target = 1.0 if self._dir > 0 else 0.0
255
+ if self.duration_s <= 0.0:
256
+ self.value = target
257
+ self._dir = 0
258
+ return True
259
+ self._elapsed += dt
260
+ progress = self._elapsed / self.duration_s
261
+ if progress >= 1.0:
262
+ self.value = target
263
+ self._elapsed = 0.0
264
+ self._dir = 0
265
+ return True
266
+ eased = _apply_curve(self.curve, progress)
267
+ # On reverse, walk the eased curve back from 1.0 toward 0.0.
268
+ self.value = eased if self._dir > 0 else 1.0 - eased
269
+ return False
270
+
271
+ def _advance_spring(self, dt: float) -> bool:
272
+ """Integrate the damped harmonic oscillator one frame toward the target.
273
+
274
+ Args:
275
+ dt: Elapsed time since the previous frame, in seconds.
276
+
277
+ Returns:
278
+ ``True`` when the spring has settled at its target, else ``False``.
279
+ """
280
+ spring = self.spring
281
+ assert spring is not None # narrowed by the caller
282
+ target = 1.0 if self._dir > 0 else 0.0
283
+ displacement = self.value - target
284
+ force = -spring.stiffness * displacement - spring.damping * self._velocity
285
+ acceleration = force / spring.mass
286
+ self._velocity += acceleration * dt
287
+ self.value += self._velocity * dt
288
+ # Settle once both the displacement and the velocity are negligible.
289
+ if abs(self.value - target) < 0.001 and abs(self._velocity) < 0.001:
290
+ self.value = target
291
+ self._velocity = 0.0
292
+ self._dir = 0
293
+ return True
294
+ return False
295
+
296
+
297
+ class Tween(BaseModel, Generic[T]):
298
+ """A linear interpolator between two typed endpoints.
299
+
300
+ Supports ``float``, :class:`~tempestroid.style.Color` (per-channel),
301
+ :class:`~tempestroid.style.Edge` (per-side) and numeric ``tuple`` endpoints.
302
+ The ``view`` reads :meth:`at` with an :class:`AnimationController`'s ``value``
303
+ to get the per-frame interpolated value, which it then feeds into a
304
+ :class:`~tempestroid.style.Style` — so the interpolation stays in the core.
305
+
306
+ Type Args:
307
+ T: The endpoint type being interpolated.
308
+
309
+ Attributes:
310
+ begin: The value at ``t == 0.0``.
311
+ end: The value at ``t == 1.0``.
312
+
313
+ Methods:
314
+ at: Interpolate between ``begin`` and ``end`` at fraction ``t``.
315
+ """
316
+
317
+ model_config = ConfigDict(frozen=True)
318
+
319
+ begin: T
320
+ end: T
321
+
322
+ def at(self, t: float) -> T:
323
+ """Interpolate between :attr:`begin` and :attr:`end` at fraction ``t``.
324
+
325
+ Args:
326
+ t: The interpolation fraction, typically an
327
+ :class:`AnimationController`'s ``value`` (0.0..1.0). Values
328
+ outside ``[0, 1]`` extrapolate linearly.
329
+
330
+ Returns:
331
+ The interpolated value, of the same type as the endpoints.
332
+
333
+ Raises:
334
+ TypeError: If the endpoint type is not a supported interpolatable
335
+ type.
336
+ """
337
+ begin: object = self.begin
338
+ end: object = self.end
339
+ if isinstance(begin, bool) or isinstance(end, bool):
340
+ raise TypeError("Tween does not interpolate bool endpoints")
341
+ if isinstance(begin, (int, float)) and isinstance(end, (int, float)):
342
+ return _lerp_float(float(begin), float(end), t) # type: ignore[return-value]
343
+ if isinstance(begin, Color) and isinstance(end, Color):
344
+ return _lerp_color(begin, end, t) # type: ignore[return-value]
345
+ if isinstance(begin, Edge) and isinstance(end, Edge):
346
+ return _lerp_edge(begin, end, t) # type: ignore[return-value]
347
+ if isinstance(begin, tuple) and isinstance(end, tuple):
348
+ a = cast("tuple[float, ...]", begin)
349
+ b = cast("tuple[float, ...]", end)
350
+ return _lerp_tuple(a, b, t) # type: ignore[return-value]
351
+ type_name: str = type(begin).__name__
352
+ raise TypeError(f"Tween cannot interpolate endpoints of type {type_name}")
353
+
354
+
355
+ def _lerp_float(a: float, b: float, t: float) -> float:
356
+ """Linearly interpolate two floats.
357
+
358
+ Args:
359
+ a: The value at ``t == 0.0``.
360
+ b: The value at ``t == 1.0``.
361
+ t: The interpolation fraction.
362
+
363
+ Returns:
364
+ ``a + (b - a) * t``.
365
+ """
366
+ return a + (b - a) * t
367
+
368
+
369
+ def _lerp_color(a: Color, b: Color, t: float) -> Color:
370
+ """Interpolate two colors per channel (r, g, b rounded; alpha as float).
371
+
372
+ Args:
373
+ a: The color at ``t == 0.0``.
374
+ b: The color at ``t == 1.0``.
375
+ t: The interpolation fraction.
376
+
377
+ Returns:
378
+ The interpolated color.
379
+ """
380
+ return Color(
381
+ r=round(_lerp_float(a.r, b.r, t)),
382
+ g=round(_lerp_float(a.g, b.g, t)),
383
+ b=round(_lerp_float(a.b, b.b, t)),
384
+ a=_lerp_float(a.a, b.a, t),
385
+ )
386
+
387
+
388
+ def _lerp_edge(a: Edge, b: Edge, t: float) -> Edge:
389
+ """Interpolate two edges per side.
390
+
391
+ Args:
392
+ a: The edge at ``t == 0.0``.
393
+ b: The edge at ``t == 1.0``.
394
+ t: The interpolation fraction.
395
+
396
+ Returns:
397
+ The interpolated edge.
398
+ """
399
+ return Edge(
400
+ top=_lerp_float(a.top, b.top, t),
401
+ right=_lerp_float(a.right, b.right, t),
402
+ bottom=_lerp_float(a.bottom, b.bottom, t),
403
+ left=_lerp_float(a.left, b.left, t),
404
+ )
405
+
406
+
407
+ def _lerp_tuple(
408
+ a: tuple[float, ...], b: tuple[float, ...], t: float
409
+ ) -> tuple[float, ...]:
410
+ """Interpolate two equal-length numeric tuples element-wise.
411
+
412
+ Args:
413
+ a: The tuple at ``t == 0.0``.
414
+ b: The tuple at ``t == 1.0``.
415
+ t: The interpolation fraction.
416
+
417
+ Returns:
418
+ The interpolated tuple.
419
+
420
+ Raises:
421
+ ValueError: If the tuples differ in length.
422
+ """
423
+ if len(a) != len(b):
424
+ raise ValueError("Tween tuple endpoints must have the same length")
425
+ return tuple(_lerp_float(x, y, t) for x, y in zip(a, b, strict=True))
@@ -0,0 +1,119 @@
1
+ """Composite, higher-level UI components built from primitive widgets.
2
+
3
+ Each component is a :class:`tempestroid.widgets.Component` that lowers to a
4
+ primitive ``Text`` / ``Row`` / ``Column`` / ``Container`` tree via its ``render``
5
+ method, so it works in both renderers (Qt and Compose) with no renderer changes
6
+ and is fully device-ready. The package collects reusable page-structure and
7
+ navigation building blocks:
8
+
9
+ * :class:`AppBar` — top bar with leading widget, title and trailing actions.
10
+ * :class:`Header` / :class:`Footer` — page header band and bottom bar.
11
+ * :class:`Sidebar` — fixed-width lateral column.
12
+ * :class:`Scaffold` — page frame stacking app bar, body and bottom bar.
13
+ * :class:`NavBar` — selectable navigation/tab bar with an active index.
14
+ * Brazilian form inputs — :class:`EmailInput`, :class:`PasswordInput`,
15
+ :class:`PhoneInput`, :class:`CPFInput`, :class:`CNPJInput` and the grouped
16
+ :class:`AddressInput` (pair them with :mod:`tempestroid.validators`).
17
+ * Media pickers — :class:`ImagePicker`, :class:`DocumentPicker` and the circular
18
+ :class:`ImagePicture` profile-photo picker.
19
+
20
+ The default theme tokens and :func:`merge_style` (used to overlay a caller's
21
+ ``style`` onto a component default) are re-exported for building custom
22
+ components in the same idiom.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ from tempest_core.components.bars import (
28
+ AppBar,
29
+ CollapsingAppBar,
30
+ Footer,
31
+ Header,
32
+ )
33
+ from tempest_core.components.base import (
34
+ ACCENT,
35
+ BACKGROUND,
36
+ MUTED,
37
+ ON_MUTED,
38
+ ON_SURFACE,
39
+ SURFACE,
40
+ merge_style,
41
+ )
42
+ from tempest_core.components.brforms import (
43
+ AddressInput,
44
+ CNPJInput,
45
+ CPFInput,
46
+ EmailInput,
47
+ PasswordInput,
48
+ PhoneInput,
49
+ )
50
+ from tempest_core.components.cards import Avatar, Card, Divider, ListTile
51
+ from tempest_core.components.dates import Calendar, Clock
52
+ from tempest_core.components.disclosure import Accordion
53
+ from tempest_core.components.feedback import Badge, Banner, EmptyState
54
+ from tempest_core.components.fields import SearchBar, Stepper
55
+ from tempest_core.components.layout import Grid, Scaffold, Sidebar
56
+ from tempest_core.components.mediainputs import (
57
+ DocumentPicker,
58
+ ImagePicker,
59
+ ImagePicture,
60
+ )
61
+ from tempest_core.components.menu import Burger, Drawer
62
+ from tempest_core.components.navigation import Breadcrumb, NavBar
63
+ from tempest_core.components.selection import (
64
+ Chip,
65
+ RadioGroup,
66
+ Rating,
67
+ SegmentedControl,
68
+ )
69
+ from tempest_core.components.table import DataTable, Table, TableCell, TableRow
70
+
71
+ __all__ = [
72
+ "AppBar",
73
+ "CollapsingAppBar",
74
+ "Header",
75
+ "Footer",
76
+ "Sidebar",
77
+ "Scaffold",
78
+ "Grid",
79
+ "NavBar",
80
+ "Breadcrumb",
81
+ "Burger",
82
+ "Drawer",
83
+ "Calendar",
84
+ "Clock",
85
+ "Card",
86
+ "ListTile",
87
+ "Avatar",
88
+ "Divider",
89
+ "SegmentedControl",
90
+ "RadioGroup",
91
+ "Chip",
92
+ "Rating",
93
+ "Stepper",
94
+ "SearchBar",
95
+ "EmailInput",
96
+ "PasswordInput",
97
+ "PhoneInput",
98
+ "CPFInput",
99
+ "CNPJInput",
100
+ "AddressInput",
101
+ "ImagePicker",
102
+ "DocumentPicker",
103
+ "ImagePicture",
104
+ "Accordion",
105
+ "Banner",
106
+ "EmptyState",
107
+ "Badge",
108
+ "Table",
109
+ "DataTable",
110
+ "TableCell",
111
+ "TableRow",
112
+ "merge_style",
113
+ "BACKGROUND",
114
+ "SURFACE",
115
+ "ACCENT",
116
+ "MUTED",
117
+ "ON_SURFACE",
118
+ "ON_MUTED",
119
+ ]