flet 0.70.0.dev5774__py3-none-any.whl → 0.70.0.dev5835__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.
Potentially problematic release.
This version of flet might be problematic. Click here for more details.
- flet/__init__.py +32 -4
- flet/components/__init__.py +0 -0
- flet/components/component.py +346 -0
- flet/components/component_decorator.py +24 -0
- flet/components/component_owned.py +22 -0
- flet/components/hooks/__init__.py +0 -0
- flet/components/hooks/hook.py +12 -0
- flet/components/hooks/use_callback.py +28 -0
- flet/components/hooks/use_context.py +91 -0
- flet/components/hooks/use_effect.py +104 -0
- flet/components/hooks/use_memo.py +52 -0
- flet/components/hooks/use_state.py +58 -0
- flet/components/memo.py +34 -0
- flet/components/observable.py +269 -0
- flet/components/public_utils.py +10 -0
- flet/components/utils.py +85 -0
- flet/controls/base_control.py +34 -10
- flet/controls/base_page.py +44 -40
- flet/controls/context.py +22 -1
- flet/controls/control.py +12 -6
- flet/controls/control_event.py +19 -2
- flet/controls/core/animated_switcher.py +3 -2
- flet/controls/core/autofill_group.py +6 -2
- flet/controls/core/column.py +5 -0
- flet/controls/core/dismissible.py +12 -10
- flet/controls/core/drag_target.py +20 -10
- flet/controls/core/draggable.py +9 -9
- flet/controls/core/icon.py +16 -12
- flet/controls/core/interactive_viewer.py +24 -23
- flet/controls/core/pagelet.py +3 -2
- flet/controls/core/reorderable_draggable.py +3 -2
- flet/controls/core/row.py +5 -0
- flet/controls/core/safe_area.py +3 -2
- flet/controls/core/text_span.py +5 -3
- flet/controls/core/view.py +6 -6
- flet/controls/core/window_drag_area.py +3 -2
- flet/controls/cupertino/cupertino_action_sheet.py +10 -5
- flet/controls/cupertino/cupertino_action_sheet_action.py +3 -4
- flet/controls/cupertino/cupertino_activity_indicator.py +4 -3
- flet/controls/cupertino/cupertino_alert_dialog.py +6 -3
- flet/controls/cupertino/cupertino_button.py +6 -5
- flet/controls/cupertino/cupertino_context_menu.py +8 -4
- flet/controls/cupertino/cupertino_context_menu_action.py +3 -4
- flet/controls/cupertino/cupertino_date_picker.py +44 -28
- flet/controls/cupertino/cupertino_dialog_action.py +3 -4
- flet/controls/cupertino/cupertino_list_tile.py +3 -4
- flet/controls/cupertino/cupertino_navigation_bar.py +6 -5
- flet/controls/cupertino/cupertino_picker.py +14 -10
- flet/controls/cupertino/cupertino_segmented_button.py +6 -5
- flet/controls/cupertino/cupertino_slider.py +16 -12
- flet/controls/cupertino/cupertino_sliding_segmented_button.py +6 -5
- flet/controls/cupertino/cupertino_timer_picker.py +38 -31
- flet/controls/id_counter.py +24 -0
- flet/controls/material/alert_dialog.py +6 -5
- flet/controls/material/app_bar.py +17 -14
- flet/controls/material/banner.py +13 -11
- flet/controls/material/bottom_app_bar.py +5 -4
- flet/controls/material/bottom_sheet.py +5 -4
- flet/controls/material/button.py +12 -4
- flet/controls/material/chip.py +13 -12
- flet/controls/material/circle_avatar.py +17 -13
- flet/controls/material/datatable.py +48 -41
- flet/controls/material/divider.py +30 -14
- flet/controls/material/dropdown.py +5 -3
- flet/controls/material/expansion_tile.py +11 -22
- flet/controls/material/floating_action_button.py +32 -23
- flet/controls/material/icon_button.py +7 -3
- flet/controls/material/navigation_rail.py +14 -11
- flet/controls/material/outlined_button.py +7 -3
- flet/controls/material/progress_bar.py +18 -10
- flet/controls/material/radio_group.py +5 -1
- flet/controls/material/range_slider.py +13 -13
- flet/controls/material/segmented_button.py +21 -17
- flet/controls/material/selection_area.py +3 -2
- flet/controls/material/slider.py +16 -12
- flet/controls/material/snack_bar.py +18 -10
- flet/controls/material/switch.py +6 -5
- flet/controls/material/tabs.py +18 -14
- flet/controls/material/textfield.py +32 -15
- flet/controls/material/vertical_divider.py +20 -12
- flet/controls/object_patch.py +434 -197
- flet/controls/page.py +205 -85
- flet/controls/services/haptic_feedback.py +0 -3
- flet/controls/services/shake_detector.py +0 -3
- flet/messaging/flet_socket_server.py +13 -6
- flet/messaging/session.py +103 -10
- flet/{controls/session_storage.py → messaging/session_store.py} +2 -2
- flet/version.py +1 -1
- {flet-0.70.0.dev5774.dist-info → flet-0.70.0.dev5835.dist-info}/METADATA +5 -5
- {flet-0.70.0.dev5774.dist-info → flet-0.70.0.dev5835.dist-info}/RECORD +93 -80
- flet/controls/cache.py +0 -87
- flet/controls/control_id.py +0 -22
- flet/controls/core/state_view.py +0 -60
- {flet-0.70.0.dev5774.dist-info → flet-0.70.0.dev5835.dist-info}/WHEEL +0 -0
- {flet-0.70.0.dev5774.dist-info → flet-0.70.0.dev5835.dist-info}/entry_points.txt +0 -0
- {flet-0.70.0.dev5774.dist-info → flet-0.70.0.dev5835.dist-info}/top_level.txt +0 -0
|
@@ -27,17 +27,17 @@ class CupertinoTimerPicker(LayoutControl):
|
|
|
27
27
|
duration is bound between `0` and `23` hours `59` minutes `59` seconds.
|
|
28
28
|
|
|
29
29
|
Raises:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
ValueError: If [`value`][(c).] is negative.
|
|
31
|
+
ValueError: If [`value`][(c).] is 24 hours or more.
|
|
32
|
+
ValueError: If [`minute_interval`][(c).] is not a positive integer
|
|
33
33
|
factor of `60`.
|
|
34
|
-
|
|
34
|
+
ValueError: If [`second_interval`][(c).] is not a positive integer
|
|
35
35
|
factor of `60`.
|
|
36
|
-
|
|
36
|
+
ValueError: If [`value`][(c).] is not a multiple
|
|
37
37
|
of [`minute_interval`][(c).].
|
|
38
|
-
|
|
38
|
+
ValueError: If [`value`][(c).] is not a multiple
|
|
39
39
|
of [`second_interval`][(c).].
|
|
40
|
-
|
|
40
|
+
ValueError: If [`item_extent`][(c).] is not strictly greater than `0.0`.
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
43
|
value: DurationValue = field(default_factory=lambda: Duration())
|
|
@@ -95,32 +95,39 @@ class CupertinoTimerPicker(LayoutControl):
|
|
|
95
95
|
|
|
96
96
|
def before_update(self):
|
|
97
97
|
super().before_update()
|
|
98
|
-
# normalize for use in below
|
|
98
|
+
# normalize for use in below validation checks
|
|
99
99
|
value = (
|
|
100
100
|
self.value
|
|
101
101
|
if isinstance(self.value, Duration)
|
|
102
102
|
else Duration(seconds=self.value)
|
|
103
103
|
)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
104
|
+
if value < Duration():
|
|
105
|
+
raise ValueError("value must be a non-negative duration")
|
|
106
|
+
if value >= Duration(hours=24):
|
|
107
|
+
raise ValueError(
|
|
108
|
+
f"value must be strictly less than 24 hours, got {value.in_hours} hours"
|
|
109
|
+
)
|
|
110
|
+
if not (self.minute_interval > 0 and 60 % self.minute_interval == 0):
|
|
111
|
+
raise ValueError(
|
|
112
|
+
f"minute_interval ({self.minute_interval}) must be a positive "
|
|
113
|
+
"integer factor of 60"
|
|
114
|
+
)
|
|
115
|
+
if not (self.second_interval > 0 and 60 % self.second_interval == 0):
|
|
116
|
+
raise ValueError(
|
|
117
|
+
f"second_interval ({self.second_interval}) must be a positive "
|
|
118
|
+
"integer factor of 60"
|
|
119
|
+
)
|
|
120
|
+
if value.in_minutes % self.minute_interval != 0:
|
|
121
|
+
raise ValueError(
|
|
122
|
+
f"value ({value.in_minutes} minutes) must be a multiple "
|
|
123
|
+
f"of minute_interval ({self.minute_interval})"
|
|
124
|
+
)
|
|
125
|
+
if value.in_seconds % self.second_interval != 0:
|
|
126
|
+
raise ValueError(
|
|
127
|
+
f"value ({value.in_seconds} seconds) must be a multiple "
|
|
128
|
+
f"of second_interval ({self.second_interval})"
|
|
129
|
+
)
|
|
130
|
+
if self.item_extent <= 0:
|
|
131
|
+
raise ValueError(
|
|
132
|
+
f"item_extent must be strictly greater than 0.0, got {self.item_extent}"
|
|
133
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import threading
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from flet.utils.locks import NopeLock
|
|
6
|
+
from flet.utils.platform_utils import is_pyodide
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IdCounter:
|
|
10
|
+
def __init__(
|
|
11
|
+
self, start: int = 1, step: int = 1, lock: Optional[threading.Lock] = None
|
|
12
|
+
):
|
|
13
|
+
self._counter = itertools.count(start, step)
|
|
14
|
+
self._lock = lock or (NopeLock() if is_pyodide() else threading.Lock())
|
|
15
|
+
|
|
16
|
+
def next(self) -> int:
|
|
17
|
+
with self._lock:
|
|
18
|
+
return next(self._counter)
|
|
19
|
+
|
|
20
|
+
def __call__(self) -> int: # for dataclass default_factory
|
|
21
|
+
return self.next()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
ControlId = IdCounter(start=3)
|
|
@@ -29,7 +29,7 @@ class AlertDialog(DialogControl):
|
|
|
29
29
|
below the `content`.
|
|
30
30
|
|
|
31
31
|
Raises:
|
|
32
|
-
|
|
32
|
+
ValueError: If none of [`title`][(c).], [`content`][(c).], or
|
|
33
33
|
[`actions`][(c).] are provided, as the dialog would have nothing to display.
|
|
34
34
|
"""
|
|
35
35
|
|
|
@@ -230,7 +230,8 @@ class AlertDialog(DialogControl):
|
|
|
230
230
|
|
|
231
231
|
def before_update(self):
|
|
232
232
|
super().before_update()
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
if not (self.title or self.content or self.actions):
|
|
234
|
+
raise ValueError(
|
|
235
|
+
"AlertDialog has nothing to display. Provide at minimum one of the "
|
|
236
|
+
"following: title, content, actions"
|
|
237
|
+
)
|
|
@@ -20,9 +20,9 @@ class AppBar(AdaptiveControl):
|
|
|
20
20
|
A material design app bar.
|
|
21
21
|
|
|
22
22
|
Raises:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
ValueError: If [`elevation`][(c).] is negative.
|
|
24
|
+
ValueError: If [`elevation_on_scroll`][(c).] is negative.
|
|
25
|
+
ValueError: If [`toolbar_opacity`][(c).] is not between `0.0`
|
|
26
26
|
and `1.0` inclusive.
|
|
27
27
|
"""
|
|
28
28
|
|
|
@@ -193,14 +193,17 @@ class AppBar(AdaptiveControl):
|
|
|
193
193
|
|
|
194
194
|
def before_update(self):
|
|
195
195
|
super().before_update()
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
196
|
+
if self.elevation is not None and self.elevation < 0:
|
|
197
|
+
raise ValueError(
|
|
198
|
+
f"elevation must be greater than or equal to 0, got {self.elevation}"
|
|
199
|
+
)
|
|
200
|
+
if self.elevation_on_scroll is not None and self.elevation_on_scroll < 0:
|
|
201
|
+
raise ValueError(
|
|
202
|
+
"elevation_on_scroll must be greater than or equal to 0, "
|
|
203
|
+
f"got {self.elevation_on_scroll}"
|
|
204
|
+
)
|
|
205
|
+
if not (0 <= self.toolbar_opacity <= 1):
|
|
206
|
+
raise ValueError(
|
|
207
|
+
"toolbar_opacity must be between 0.0 and 1.0 inclusive, "
|
|
208
|
+
f"got {self.toolbar_opacity}"
|
|
209
|
+
)
|
flet/controls/material/banner.py
CHANGED
|
@@ -28,9 +28,9 @@ class Banner(DialogControl):
|
|
|
28
28
|
them at any time.
|
|
29
29
|
|
|
30
30
|
Raises:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
ValueError: if [`content`][(c).] is not visible.
|
|
32
|
+
ValueError: if [`elevation`][(c).] is negative.
|
|
33
|
+
ValueError: if [`actions`][(c).] does not contain at least one visible
|
|
34
34
|
action Control.
|
|
35
35
|
"""
|
|
36
36
|
|
|
@@ -128,11 +128,13 @@ class Banner(DialogControl):
|
|
|
128
128
|
|
|
129
129
|
def before_update(self):
|
|
130
130
|
super().before_update()
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
if self.elevation is not None and self.elevation < 0:
|
|
132
|
+
raise ValueError(
|
|
133
|
+
f"elevation must be greater than or equal to 0, got {self.elevation}"
|
|
134
|
+
)
|
|
135
|
+
if isinstance(self.content, Control) and not self.content.visible:
|
|
136
|
+
raise ValueError("content must be visible")
|
|
137
|
+
if not any(a.visible for a in self.actions):
|
|
138
|
+
raise ValueError(
|
|
139
|
+
"actions must contain at minimum one visible action Control"
|
|
140
|
+
)
|
|
@@ -20,7 +20,7 @@ class BottomAppBar(LayoutControl):
|
|
|
20
20
|
A material design bottom app bar.
|
|
21
21
|
|
|
22
22
|
Raises:
|
|
23
|
-
|
|
23
|
+
ValueError: If [`elevation`][(c).] is negative.
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
26
|
content: Optional[Control] = None
|
|
@@ -74,6 +74,7 @@ class BottomAppBar(LayoutControl):
|
|
|
74
74
|
|
|
75
75
|
def before_update(self):
|
|
76
76
|
super().before_update()
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
if self.elevation is not None and self.elevation < 0:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"elevation must be greater than or equal to 0, got {self.elevation}"
|
|
80
|
+
)
|
|
@@ -20,7 +20,7 @@ class BottomSheet(DialogControl):
|
|
|
20
20
|
from interacting with the rest of the app.
|
|
21
21
|
|
|
22
22
|
Raises:
|
|
23
|
-
|
|
23
|
+
ValueError: If [`elevation`][(c).] is negative.
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
26
|
content: Control
|
|
@@ -99,6 +99,7 @@ class BottomSheet(DialogControl):
|
|
|
99
99
|
|
|
100
100
|
def before_update(self):
|
|
101
101
|
super().before_update()
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
if self.elevation is not None and self.elevation < 0:
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"elevation must be greater than or equal to zero, got {self.elevation}"
|
|
105
|
+
)
|
flet/controls/material/button.py
CHANGED
|
@@ -22,9 +22,14 @@ __all__ = ["Button"]
|
|
|
22
22
|
@control("Button")
|
|
23
23
|
class Button(LayoutControl, AdaptiveControl):
|
|
24
24
|
"""
|
|
25
|
-
A
|
|
25
|
+
A material button.
|
|
26
26
|
|
|
27
|
-
It supports various styles, colors,
|
|
27
|
+
It supports various styles, colors, event handlers for user interaction,
|
|
28
|
+
and can be used to display text, icons, etc.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
ValueError: If neither [`icon`][(c).] nor [`content`][(c).]
|
|
32
|
+
(string or visible control) is provided.
|
|
28
33
|
"""
|
|
29
34
|
|
|
30
35
|
content: Optional[StrOrControl] = None
|
|
@@ -45,11 +50,14 @@ class Button(LayoutControl, AdaptiveControl):
|
|
|
45
50
|
|
|
46
51
|
def before_update(self):
|
|
47
52
|
super().before_update()
|
|
48
|
-
|
|
53
|
+
if not (
|
|
49
54
|
self.icon
|
|
50
55
|
or isinstance(self.content, str)
|
|
51
56
|
or (isinstance(self.content, Control) and self.content.visible)
|
|
52
|
-
)
|
|
57
|
+
):
|
|
58
|
+
raise ValueError(
|
|
59
|
+
"At least icon or content (string or visible Control) must be provided"
|
|
60
|
+
)
|
|
53
61
|
|
|
54
62
|
if (
|
|
55
63
|
self.style is not None
|
flet/controls/material/chip.py
CHANGED
|
@@ -28,9 +28,9 @@ class Chip(LayoutControl):
|
|
|
28
28
|
Chips are compact elements that represent an attribute, text, entity, or action.
|
|
29
29
|
|
|
30
30
|
Raises:
|
|
31
|
-
|
|
31
|
+
ValueError: If [`elevation`][(c).] or [`elevation_on_click`][(c).] is
|
|
32
32
|
negative.
|
|
33
|
-
|
|
33
|
+
ValueError: If callback for both [`on_click`][(c).] and [`on_select`][(c).]
|
|
34
34
|
are specified.
|
|
35
35
|
"""
|
|
36
36
|
|
|
@@ -254,13 +254,14 @@ class Chip(LayoutControl):
|
|
|
254
254
|
|
|
255
255
|
def before_update(self):
|
|
256
256
|
super().before_update()
|
|
257
|
-
|
|
258
|
-
"on_select and on_click cannot be used together"
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
257
|
+
if self.on_select is not None and self.on_click is not None:
|
|
258
|
+
raise ValueError("on_select and on_click cannot be used together")
|
|
259
|
+
if self.elevation is not None and self.elevation < 0.0:
|
|
260
|
+
raise ValueError(
|
|
261
|
+
f"elevation must be greater than or equal to 0, got {self.elevation}"
|
|
262
|
+
)
|
|
263
|
+
if self.elevation_on_click is not None and self.elevation_on_click < 0.0:
|
|
264
|
+
raise ValueError(
|
|
265
|
+
"elevation_on_click must be greater than or equal to 0, got "
|
|
266
|
+
f"{self.elevation_on_click}"
|
|
267
|
+
)
|
|
@@ -21,9 +21,9 @@ class CircleAvatar(LayoutControl):
|
|
|
21
21
|
and if this also fails, then [`bgcolor`][(c).] is used.
|
|
22
22
|
|
|
23
23
|
Raises:
|
|
24
|
-
|
|
24
|
+
ValueError: If [`radius`][(c).] or [`min_radius`][(c).]
|
|
25
25
|
or [`max_radius`][(c).] is negative.
|
|
26
|
-
|
|
26
|
+
ValueError: If [`radius`][(c).] is set and [`min_radius`][(c).]
|
|
27
27
|
or [`max_radius`][(c).] is not None.
|
|
28
28
|
"""
|
|
29
29
|
|
|
@@ -107,15 +107,19 @@ class CircleAvatar(LayoutControl):
|
|
|
107
107
|
|
|
108
108
|
def before_update(self):
|
|
109
109
|
super().before_update()
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
110
|
+
if self.radius is not None and self.radius < 0:
|
|
111
|
+
raise ValueError(
|
|
112
|
+
f"radius must be greater than or equal to 0, got {self.radius}"
|
|
113
|
+
)
|
|
114
|
+
if self.min_radius is not None and self.min_radius < 0:
|
|
115
|
+
raise ValueError(
|
|
116
|
+
f"min_radius must be greater than or equal to 0, got {self.min_radius}"
|
|
117
|
+
)
|
|
118
|
+
if self.max_radius is not None and self.max_radius < 0:
|
|
119
|
+
raise ValueError(
|
|
120
|
+
f"max_radius must be greater than or equal to 0, got {self.max_radius}"
|
|
121
|
+
)
|
|
122
|
+
if self.radius is not None and not (
|
|
120
123
|
self.min_radius is None and self.max_radius is None
|
|
121
|
-
)
|
|
124
|
+
):
|
|
125
|
+
raise ValueError("If radius is set, min_radius and max_radius must be None")
|
|
@@ -36,7 +36,7 @@ class DataColumn(Control):
|
|
|
36
36
|
Column configuration for a [`DataTable`][flet.].
|
|
37
37
|
|
|
38
38
|
Raises:
|
|
39
|
-
|
|
39
|
+
ValueError: If the [`label`][(c).] is neither a string nor
|
|
40
40
|
a visible control.
|
|
41
41
|
"""
|
|
42
42
|
|
|
@@ -82,9 +82,11 @@ class DataColumn(Control):
|
|
|
82
82
|
|
|
83
83
|
def before_update(self):
|
|
84
84
|
super().before_update()
|
|
85
|
-
|
|
86
|
-
isinstance(self.label,
|
|
87
|
-
|
|
85
|
+
if not (
|
|
86
|
+
isinstance(self.label, str)
|
|
87
|
+
or (isinstance(self.label, Control) and self.label.visible)
|
|
88
|
+
):
|
|
89
|
+
raise ValueError("label must a string or a visible control")
|
|
88
90
|
|
|
89
91
|
|
|
90
92
|
@control("DataCell")
|
|
@@ -93,7 +95,7 @@ class DataCell(Control):
|
|
|
93
95
|
The data for a cell of a [`DataTable`][flet.].
|
|
94
96
|
|
|
95
97
|
Raises:
|
|
96
|
-
|
|
98
|
+
ValueError: If the [`content`][(c).] is neither a string nor a visible
|
|
97
99
|
control.
|
|
98
100
|
"""
|
|
99
101
|
|
|
@@ -185,8 +187,8 @@ class DataCell(Control):
|
|
|
185
187
|
|
|
186
188
|
def before_update(self):
|
|
187
189
|
super().before_update()
|
|
188
|
-
if isinstance(self.content, Control):
|
|
189
|
-
|
|
190
|
+
if isinstance(self.content, Control) and not self.content.visible:
|
|
191
|
+
raise ValueError("content must be visible")
|
|
190
192
|
|
|
191
193
|
|
|
192
194
|
@control("DataRow")
|
|
@@ -197,6 +199,9 @@ class DataRow(Control):
|
|
|
197
199
|
One row configuration must be provided for each row to display in the table.
|
|
198
200
|
|
|
199
201
|
The data for this row of the table is provided in the [`cells`][(c).] property.
|
|
202
|
+
|
|
203
|
+
Raises:
|
|
204
|
+
ValueError: If [`cells`][(c).] does not contain at least one visible DataCell.
|
|
200
205
|
"""
|
|
201
206
|
|
|
202
207
|
cells: list[DataCell] = field(default_factory=list)
|
|
@@ -267,9 +272,8 @@ class DataRow(Control):
|
|
|
267
272
|
|
|
268
273
|
def before_update(self):
|
|
269
274
|
super().before_update()
|
|
270
|
-
|
|
271
|
-
"cells must contain at minimum one visible DataCell"
|
|
272
|
-
)
|
|
275
|
+
if not any(cell.visible for cell in self.cells):
|
|
276
|
+
raise ValueError("cells must contain at minimum one visible DataCell")
|
|
273
277
|
|
|
274
278
|
|
|
275
279
|
@control("DataTable")
|
|
@@ -278,13 +282,13 @@ class DataTable(LayoutControl):
|
|
|
278
282
|
A Material Design data table.
|
|
279
283
|
|
|
280
284
|
Raises:
|
|
281
|
-
|
|
282
|
-
|
|
285
|
+
ValueError: If there are no visible [`columns`][(c).].
|
|
286
|
+
ValueError: If any visible row does not contain exactly as many visible
|
|
283
287
|
[`DataRow.cells`][flet.] as there are visible [`columns`][(c).].
|
|
284
|
-
|
|
288
|
+
ValueError: If [`data_row_min_height`][(c).] is greater than
|
|
285
289
|
[`data_row_max_height`][(c).].
|
|
286
|
-
|
|
287
|
-
|
|
290
|
+
ValueError: If [`divider_thickness`][(c).] is negative.
|
|
291
|
+
ValueError: If [`sort_column_index`][(c).] is out of range.
|
|
288
292
|
"""
|
|
289
293
|
|
|
290
294
|
columns: list[DataColumn]
|
|
@@ -488,34 +492,37 @@ class DataTable(LayoutControl):
|
|
|
488
492
|
list(filter(lambda column: column.visible, self.columns))
|
|
489
493
|
)
|
|
490
494
|
visible_rows = list(filter(lambda row: row.visible, self.rows))
|
|
491
|
-
|
|
492
|
-
"columns must contain at minimum one visible DataColumn"
|
|
493
|
-
|
|
494
|
-
assert all(
|
|
495
|
+
if visible_columns_count == 0:
|
|
496
|
+
raise ValueError("columns must contain at minimum one visible DataColumn")
|
|
497
|
+
if not all(
|
|
495
498
|
[
|
|
496
499
|
len([c for c in row.cells if c.visible]) == visible_columns_count
|
|
497
500
|
for row in visible_rows
|
|
498
501
|
]
|
|
499
|
-
)
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
502
|
+
):
|
|
503
|
+
raise ValueError(
|
|
504
|
+
f"each visible DataRow must contain exactly as many visible DataCells "
|
|
505
|
+
f"as there are visible DataColumns ({visible_columns_count})"
|
|
506
|
+
)
|
|
507
|
+
if (
|
|
508
|
+
self.data_row_min_height is not None
|
|
509
|
+
and self.data_row_max_height is not None
|
|
510
|
+
and self.data_row_min_height > self.data_row_max_height
|
|
511
|
+
):
|
|
512
|
+
raise ValueError(
|
|
513
|
+
f"data_row_min_height ({self.data_row_min_height}) must be less than "
|
|
514
|
+
f"or equal to data_row_max_height ({self.data_row_max_height})"
|
|
515
|
+
)
|
|
516
|
+
if self.divider_thickness is not None and self.divider_thickness < 0:
|
|
517
|
+
raise ValueError(
|
|
518
|
+
f"divider_thickness must be greater than or equal to 0, "
|
|
519
|
+
f"got {self.divider_thickness}"
|
|
520
|
+
)
|
|
521
|
+
if self.sort_column_index is not None and not (
|
|
516
522
|
0 <= self.sort_column_index < visible_columns_count
|
|
517
|
-
)
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
523
|
+
):
|
|
524
|
+
raise ValueError(
|
|
525
|
+
f"sort_column_index ({self.sort_column_index}) must be greater than or "
|
|
526
|
+
f"equal to 0 and less than the "
|
|
527
|
+
f"number of visible columns ({visible_columns_count})"
|
|
528
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from flet.controls.base_control import control
|
|
4
|
+
from flet.controls.border_radius import BorderRadiusValue
|
|
4
5
|
from flet.controls.control import Control
|
|
5
6
|
from flet.controls.types import ColorValue, Number
|
|
6
7
|
|
|
@@ -11,6 +12,12 @@ __all__ = ["Divider"]
|
|
|
11
12
|
class Divider(Control):
|
|
12
13
|
"""
|
|
13
14
|
A thin horizontal line (divider), with padding on either side.
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
ValueError: If [`height`][(c).] is negative.
|
|
18
|
+
ValueError: If [`thickness`][(c).] is negative.
|
|
19
|
+
ValueError: If [`leading_indent`][(c).] is negative.
|
|
20
|
+
ValueError: If [`trailing_indent`][(c).] is negative.
|
|
14
21
|
"""
|
|
15
22
|
|
|
16
23
|
color: Optional[ColorValue] = None
|
|
@@ -56,19 +63,28 @@ class Divider(Control):
|
|
|
56
63
|
If that is also `None`, defaults to `0.0`.
|
|
57
64
|
"""
|
|
58
65
|
|
|
66
|
+
radius: Optional[BorderRadiusValue] = None
|
|
67
|
+
"""
|
|
68
|
+
The border radius of the divider.
|
|
69
|
+
"""
|
|
70
|
+
|
|
59
71
|
def before_update(self):
|
|
60
72
|
super().before_update()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
if self.height is not None and self.height < 0:
|
|
74
|
+
raise ValueError(
|
|
75
|
+
f"height must be greater than or equal to 0, got {self.height}"
|
|
76
|
+
)
|
|
77
|
+
if self.thickness is not None and self.thickness < 0:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"thickness must be greater than or equal to 0, got {self.thickness}"
|
|
80
|
+
)
|
|
81
|
+
if self.leading_indent is not None and self.leading_indent < 0:
|
|
82
|
+
raise ValueError(
|
|
83
|
+
f"leading_indent must be greater than or equal to 0, "
|
|
84
|
+
f"got {self.leading_indent}"
|
|
85
|
+
)
|
|
86
|
+
if self.trailing_indent is not None and self.trailing_indent < 0:
|
|
87
|
+
raise ValueError(
|
|
88
|
+
f"trailing_indent must be greater than or equal to 0, "
|
|
89
|
+
f"got {self.trailing_indent}"
|
|
90
|
+
)
|
|
@@ -30,6 +30,9 @@ class DropdownOption(Control):
|
|
|
30
30
|
"""
|
|
31
31
|
Represents an item in a dropdown. Either `key` or `text` must be specified, else an
|
|
32
32
|
`AssertionError` will be raised.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValueError: If neither [`key`][(c).] nor [`text`][(c).] are provided.
|
|
33
36
|
"""
|
|
34
37
|
|
|
35
38
|
key: Optional[str] = None
|
|
@@ -66,9 +69,8 @@ class DropdownOption(Control):
|
|
|
66
69
|
|
|
67
70
|
def before_update(self):
|
|
68
71
|
super().before_update()
|
|
69
|
-
|
|
70
|
-
"key or text must be specified"
|
|
71
|
-
)
|
|
72
|
+
if self.key is None and self.text is None:
|
|
73
|
+
raise ValueError("key or text must be specified")
|
|
72
74
|
|
|
73
75
|
|
|
74
76
|
Option = DropdownOption
|