pythonnative 0.15.0__py3-none-any.whl → 0.16.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.
- pythonnative/__init__.py +44 -2
- pythonnative/animated.py +38 -0
- pythonnative/components.py +734 -442
- pythonnative/hooks.py +74 -20
- pythonnative/native_views/android.py +96 -3
- pythonnative/native_views/base.py +3 -92
- pythonnative/native_views/ios.py +121 -2
- pythonnative/reconciler.py +123 -14
- pythonnative/sdk/__init__.py +1 -2
- {pythonnative-0.15.0.dist-info → pythonnative-0.16.0.dist-info}/METADATA +1 -1
- {pythonnative-0.15.0.dist-info → pythonnative-0.16.0.dist-info}/RECORD +15 -15
- {pythonnative-0.15.0.dist-info → pythonnative-0.16.0.dist-info}/WHEEL +0 -0
- {pythonnative-0.15.0.dist-info → pythonnative-0.16.0.dist-info}/entry_points.txt +0 -0
- {pythonnative-0.15.0.dist-info → pythonnative-0.16.0.dist-info}/licenses/LICENSE +0 -0
- {pythonnative-0.15.0.dist-info → pythonnative-0.16.0.dist-info}/top_level.txt +0 -0
pythonnative/components.py
CHANGED
|
@@ -1,43 +1,34 @@
|
|
|
1
|
-
"""Built-in element factories
|
|
1
|
+
"""Built-in element factories and the typed prop schemas they share.
|
|
2
2
|
|
|
3
|
-
Each
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Each ``@dataclass(frozen=True)`` class in this module — ``TextProps``,
|
|
4
|
+
``ButtonProps``, etc. — is the canonical schema for one built-in
|
|
5
|
+
component. Each factory function (``Text``, ``Button``, …) is a thin
|
|
6
|
+
ergonomic wrapper that builds an [`Element`][pythonnative.Element]
|
|
7
|
+
through the shared :func:`_make_element` helper, so style resolution,
|
|
8
|
+
``ref`` attachment, ``None``-default dropping, and forced overrides
|
|
9
|
+
(e.g. ``Column``'s fixed ``flex_direction``) live in exactly one place.
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Layout properties supported by every component:
|
|
12
|
-
|
|
13
|
-
- `width`, `height`, `flex`, `flex_grow`, `flex_shrink`, `margin`,
|
|
14
|
-
`min_width`, `max_width`, `min_height`, `max_height`, `align_self`.
|
|
15
|
-
|
|
16
|
-
Flex container properties (`View` / `Column` / `Row`):
|
|
17
|
-
|
|
18
|
-
- `flex_direction`, `justify_content`, `align_items`, `overflow`,
|
|
19
|
-
`spacing`, `padding`.
|
|
20
|
-
|
|
21
|
-
[`View`][pythonnative.View] is the universal flex container (like React
|
|
22
|
-
Native's `View`). It defaults to `flex_direction: "column"`.
|
|
23
|
-
[`Column`][pythonnative.Column] and [`Row`][pythonnative.Row] are
|
|
24
|
-
convenience wrappers that fix the direction.
|
|
11
|
+
The same Props dataclasses are used by the `pythonnative.sdk` surface
|
|
12
|
+
for third-party components, so the built-in API and the extension API
|
|
13
|
+
speak the same shape.
|
|
25
14
|
|
|
26
15
|
Example:
|
|
27
16
|
```python
|
|
28
17
|
import pythonnative as pn
|
|
29
18
|
|
|
30
19
|
pn.Column(
|
|
31
|
-
pn.Text("Hello", style=
|
|
20
|
+
pn.Text("Hello", style=pn.style(font_size=18)),
|
|
32
21
|
pn.Button("Tap", on_click=lambda: print("tapped")),
|
|
33
|
-
style=
|
|
22
|
+
style=pn.style(spacing=12, padding=16),
|
|
34
23
|
)
|
|
35
24
|
```
|
|
36
25
|
"""
|
|
37
26
|
|
|
27
|
+
from dataclasses import dataclass, field
|
|
38
28
|
from typing import Any, Callable, Dict, List, Literal, Optional
|
|
39
29
|
|
|
40
30
|
from .element import Element
|
|
31
|
+
from .sdk import Props
|
|
41
32
|
from .style import (
|
|
42
33
|
AutoCapitalize,
|
|
43
34
|
Color,
|
|
@@ -49,33 +40,265 @@ from .style import (
|
|
|
49
40
|
)
|
|
50
41
|
|
|
51
42
|
# ======================================================================
|
|
52
|
-
#
|
|
43
|
+
# Canonical element builder
|
|
53
44
|
# ======================================================================
|
|
54
45
|
|
|
55
46
|
|
|
56
|
-
def
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
def _make_element(
|
|
48
|
+
name: str,
|
|
49
|
+
*children: Element,
|
|
50
|
+
style: StyleProp = None,
|
|
51
|
+
ref: Optional[Dict[str, Any]] = None,
|
|
52
|
+
key: Optional[str] = None,
|
|
53
|
+
_defaults: Optional[Dict[str, Any]] = None,
|
|
54
|
+
_forced: Optional[Dict[str, Any]] = None,
|
|
55
|
+
**props: Any,
|
|
56
|
+
) -> Element:
|
|
57
|
+
"""Build an [`Element`][pythonnative.Element] of type ``name``.
|
|
58
|
+
|
|
59
|
+
This is the single helper every built-in factory routes through, so
|
|
60
|
+
the cross-cutting concerns that used to be duplicated per component
|
|
61
|
+
live in one place:
|
|
62
|
+
|
|
63
|
+
1. ``style`` is flattened via
|
|
64
|
+
[`resolve_style`][pythonnative.style.resolve_style] (list-of-dicts
|
|
65
|
+
and ``None`` both handled).
|
|
66
|
+
2. ``_defaults`` are filled in for keys not already present (used for
|
|
67
|
+
things like ``View``'s default ``flex_direction: "column"`` that
|
|
68
|
+
a user style may legitimately override).
|
|
69
|
+
3. ``**props`` are merged on top, with ``None`` values *dropped* so
|
|
70
|
+
optional kwargs don't pollute the prop dict.
|
|
71
|
+
4. ``ref`` is attached under the reserved ``"ref"`` key.
|
|
72
|
+
5. ``_forced`` overrides everything (used by ``Column`` / ``Row`` to
|
|
73
|
+
lock their flex direction regardless of user style).
|
|
63
74
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
Args:
|
|
76
|
+
name: Element type name (e.g. ``"Text"``).
|
|
77
|
+
*children: Child elements.
|
|
78
|
+
style: Style dict, list of dicts, or ``None``.
|
|
79
|
+
ref: Optional ``use_ref()`` dict; the reconciler populates
|
|
80
|
+
``ref["current"]`` with the underlying native view.
|
|
81
|
+
key: Stable identity for keyed reconciliation.
|
|
82
|
+
_defaults: Internal: fill-only-if-missing prop defaults.
|
|
83
|
+
_forced: Internal: prop overrides applied last.
|
|
84
|
+
**props: Per-component props. ``None`` values are dropped.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
A fresh [`Element`][pythonnative.Element].
|
|
68
88
|
"""
|
|
69
|
-
out: Dict[str, Any] =
|
|
70
|
-
if
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if
|
|
77
|
-
out["
|
|
78
|
-
|
|
89
|
+
out: Dict[str, Any] = dict(resolve_style(style))
|
|
90
|
+
if _defaults:
|
|
91
|
+
for k, v in _defaults.items():
|
|
92
|
+
out.setdefault(k, v)
|
|
93
|
+
for k, v in props.items():
|
|
94
|
+
if v is not None:
|
|
95
|
+
out[k] = v
|
|
96
|
+
if ref is not None:
|
|
97
|
+
out["ref"] = ref
|
|
98
|
+
if _forced:
|
|
99
|
+
out.update(_forced)
|
|
100
|
+
return Element(name, out, list(children), key=key)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# ======================================================================
|
|
104
|
+
# Props dataclasses
|
|
105
|
+
# ======================================================================
|
|
106
|
+
#
|
|
107
|
+
# These are the canonical schemas for every built-in component. They
|
|
108
|
+
# subclass the SDK's ``Props`` base, so the same shape works for both
|
|
109
|
+
# the built-in factory functions and the third-party
|
|
110
|
+
# [`element_factory`][pythonnative.element_factory] API.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class TextProps(Props):
|
|
115
|
+
"""Props for [`Text`][pythonnative.Text]."""
|
|
116
|
+
|
|
117
|
+
text: str = ""
|
|
118
|
+
accessibility_label: Optional[str] = None
|
|
119
|
+
accessibility_hint: Optional[str] = None
|
|
120
|
+
accessibility_role: Optional[str] = None
|
|
121
|
+
accessible: Optional[bool] = None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@dataclass(frozen=True)
|
|
125
|
+
class ButtonProps(Props):
|
|
126
|
+
"""Props for [`Button`][pythonnative.Button]."""
|
|
127
|
+
|
|
128
|
+
title: str = ""
|
|
129
|
+
on_click: Optional[Callable[[], None]] = None
|
|
130
|
+
enabled: bool = True
|
|
131
|
+
accessibility_label: Optional[str] = None
|
|
132
|
+
accessibility_hint: Optional[str] = None
|
|
133
|
+
accessibility_role: Optional[str] = None
|
|
134
|
+
accessible: Optional[bool] = None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@dataclass(frozen=True)
|
|
138
|
+
class TextInputProps(Props):
|
|
139
|
+
"""Props for [`TextInput`][pythonnative.TextInput]."""
|
|
140
|
+
|
|
141
|
+
value: str = ""
|
|
142
|
+
placeholder: Optional[str] = None
|
|
143
|
+
on_change: Optional[Callable[[str], None]] = None
|
|
144
|
+
on_submit: Optional[Callable[[str], None]] = None
|
|
145
|
+
secure: bool = False
|
|
146
|
+
multiline: bool = False
|
|
147
|
+
keyboard_type: Optional[KeyboardType] = None
|
|
148
|
+
auto_capitalize: Optional[AutoCapitalize] = None
|
|
149
|
+
auto_correct: Optional[bool] = None
|
|
150
|
+
auto_focus: bool = False
|
|
151
|
+
return_key_type: Optional[ReturnKeyType] = None
|
|
152
|
+
max_length: Optional[int] = None
|
|
153
|
+
placeholder_color: Optional[Color] = None
|
|
154
|
+
accessibility_label: Optional[str] = None
|
|
155
|
+
accessibility_hint: Optional[str] = None
|
|
156
|
+
accessible: Optional[bool] = None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass(frozen=True)
|
|
160
|
+
class ImageProps(Props):
|
|
161
|
+
"""Props for [`Image`][pythonnative.Image]."""
|
|
162
|
+
|
|
163
|
+
source: Optional[str] = None
|
|
164
|
+
scale_type: Optional[ScaleType] = None
|
|
165
|
+
tint_color: Optional[Color] = None
|
|
166
|
+
accessibility_label: Optional[str] = None
|
|
167
|
+
accessibility_role: Optional[str] = None
|
|
168
|
+
accessible: Optional[bool] = None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@dataclass(frozen=True)
|
|
172
|
+
class SwitchProps(Props):
|
|
173
|
+
"""Props for [`Switch`][pythonnative.Switch]."""
|
|
174
|
+
|
|
175
|
+
value: bool = False
|
|
176
|
+
on_change: Optional[Callable[[bool], None]] = None
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@dataclass(frozen=True)
|
|
180
|
+
class ProgressBarProps(Props):
|
|
181
|
+
"""Props for [`ProgressBar`][pythonnative.ProgressBar]."""
|
|
182
|
+
|
|
183
|
+
value: float = 0.0
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@dataclass(frozen=True)
|
|
187
|
+
class ActivityIndicatorProps(Props):
|
|
188
|
+
"""Props for [`ActivityIndicator`][pythonnative.ActivityIndicator]."""
|
|
189
|
+
|
|
190
|
+
animating: bool = True
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass(frozen=True)
|
|
194
|
+
class WebViewProps(Props):
|
|
195
|
+
"""Props for [`WebView`][pythonnative.WebView]."""
|
|
196
|
+
|
|
197
|
+
url: Optional[str] = None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@dataclass(frozen=True)
|
|
201
|
+
class SpacerProps(Props):
|
|
202
|
+
"""Props for [`Spacer`][pythonnative.Spacer]."""
|
|
203
|
+
|
|
204
|
+
size: Optional[float] = None
|
|
205
|
+
flex: Optional[float] = None
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass(frozen=True)
|
|
209
|
+
class SliderProps(Props):
|
|
210
|
+
"""Props for [`Slider`][pythonnative.Slider]."""
|
|
211
|
+
|
|
212
|
+
value: float = 0.0
|
|
213
|
+
min_value: float = 0.0
|
|
214
|
+
max_value: float = 1.0
|
|
215
|
+
on_change: Optional[Callable[[float], None]] = None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@dataclass(frozen=True)
|
|
219
|
+
class ViewProps(Props):
|
|
220
|
+
"""Props for [`View`][pythonnative.View], [`Column`][pythonnative.Column], and [`Row`][pythonnative.Row]."""
|
|
221
|
+
|
|
222
|
+
accessibility_label: Optional[str] = None
|
|
223
|
+
accessibility_hint: Optional[str] = None
|
|
224
|
+
accessibility_role: Optional[str] = None
|
|
225
|
+
accessible: Optional[bool] = None
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@dataclass(frozen=True)
|
|
229
|
+
class ScrollViewProps(Props):
|
|
230
|
+
"""Props for [`ScrollView`][pythonnative.ScrollView]."""
|
|
231
|
+
|
|
232
|
+
refresh_control: Optional[Dict[str, Any]] = None
|
|
233
|
+
scroll_axis: Optional[Literal["vertical", "horizontal"]] = None
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@dataclass(frozen=True)
|
|
237
|
+
class SafeAreaViewProps(Props):
|
|
238
|
+
"""Props for [`SafeAreaView`][pythonnative.SafeAreaView]."""
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@dataclass(frozen=True)
|
|
242
|
+
class ModalProps(Props):
|
|
243
|
+
"""Props for [`Modal`][pythonnative.Modal]."""
|
|
244
|
+
|
|
245
|
+
visible: bool = False
|
|
246
|
+
on_dismiss: Optional[Callable[[], None]] = None
|
|
247
|
+
title: Optional[str] = None
|
|
248
|
+
animation_type: Literal["slide", "fade", "none"] = "slide"
|
|
249
|
+
transparent: bool = False
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@dataclass(frozen=True)
|
|
253
|
+
class PressableProps(Props):
|
|
254
|
+
"""Props for [`Pressable`][pythonnative.Pressable]."""
|
|
255
|
+
|
|
256
|
+
on_press: Optional[Callable[[], None]] = None
|
|
257
|
+
on_long_press: Optional[Callable[[], None]] = None
|
|
258
|
+
pressed_opacity: float = 0.6
|
|
259
|
+
accessibility_label: Optional[str] = None
|
|
260
|
+
accessibility_hint: Optional[str] = None
|
|
261
|
+
accessibility_role: Optional[str] = None
|
|
262
|
+
accessible: Optional[bool] = None
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
@dataclass(frozen=True)
|
|
266
|
+
class StatusBarProps(Props):
|
|
267
|
+
"""Props for [`StatusBar`][pythonnative.StatusBar]."""
|
|
268
|
+
|
|
269
|
+
bar_style: Optional[Literal["light", "dark", "default"]] = None
|
|
270
|
+
background_color: Optional[Color] = None
|
|
271
|
+
hidden: Optional[bool] = None
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@dataclass(frozen=True)
|
|
275
|
+
class KeyboardAvoidingViewProps(Props):
|
|
276
|
+
"""Props for [`KeyboardAvoidingView`][pythonnative.KeyboardAvoidingView]."""
|
|
277
|
+
|
|
278
|
+
behavior: Literal["padding", "position"] = "padding"
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
@dataclass(frozen=True)
|
|
282
|
+
class PickerProps(Props):
|
|
283
|
+
"""Props for [`Picker`][pythonnative.Picker].
|
|
284
|
+
|
|
285
|
+
``items`` is an ordered list of ``{"value": Any, "label": str}``
|
|
286
|
+
entries. ``value`` is matched against ``items[i]["value"]`` to
|
|
287
|
+
determine the currently selected row.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
value: Any = None
|
|
291
|
+
items: List[Dict[str, Any]] = field(default_factory=list)
|
|
292
|
+
on_change: Optional[Callable[[Any], None]] = None
|
|
293
|
+
placeholder: str = "Select…"
|
|
294
|
+
accessibility_label: Optional[str] = None
|
|
295
|
+
accessibility_hint: Optional[str] = None
|
|
296
|
+
accessible: Optional[bool] = None
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
# ======================================================================
|
|
300
|
+
# Leaf factories
|
|
301
|
+
# ======================================================================
|
|
79
302
|
|
|
80
303
|
|
|
81
304
|
def Text(
|
|
@@ -91,34 +314,38 @@ def Text(
|
|
|
91
314
|
) -> Element:
|
|
92
315
|
"""Display a string of text.
|
|
93
316
|
|
|
94
|
-
Style properties:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
(
|
|
98
|
-
|
|
99
|
-
|
|
317
|
+
Style properties: ``font_size``, ``color``, ``bold``,
|
|
318
|
+
``font_weight``, ``font_family``, ``italic``, ``text_align``,
|
|
319
|
+
``background_color``, ``max_lines``, ``letter_spacing``,
|
|
320
|
+
``line_height``, ``text_decoration`` (``"underline"`` /
|
|
321
|
+
``"line_through"``), ``border_radius``, ``border_width``,
|
|
322
|
+
``border_color``, ``shadow_*``, ``opacity``, ``transform``, plus
|
|
323
|
+
the common layout props.
|
|
100
324
|
|
|
101
325
|
Args:
|
|
102
326
|
text: Text content to display.
|
|
103
|
-
style: Style dict (or list of dicts)
|
|
104
|
-
layout.
|
|
327
|
+
style: Style dict (or list of dicts).
|
|
105
328
|
accessibility_label: Spoken description for screen readers.
|
|
106
329
|
accessibility_hint: Spoken extra detail (iOS only).
|
|
107
330
|
accessibility_role: Semantic role for assistive tech.
|
|
108
331
|
accessible: Override whether the element is exposed to AT.
|
|
109
|
-
ref: Optional ``use_ref()`` dict
|
|
110
|
-
|
|
111
|
-
key: Stable identity for keyed reconciliation in lists.
|
|
332
|
+
ref: Optional ``use_ref()`` dict.
|
|
333
|
+
key: Stable identity for keyed reconciliation.
|
|
112
334
|
|
|
113
335
|
Returns:
|
|
114
|
-
An [`Element`][pythonnative.Element] of type
|
|
336
|
+
An [`Element`][pythonnative.Element] of type ``"Text"``.
|
|
115
337
|
"""
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
338
|
+
return _make_element(
|
|
339
|
+
"Text",
|
|
340
|
+
style=style,
|
|
341
|
+
ref=ref,
|
|
342
|
+
key=key,
|
|
343
|
+
text=text,
|
|
344
|
+
accessibility_label=accessibility_label,
|
|
345
|
+
accessibility_hint=accessibility_hint,
|
|
346
|
+
accessibility_role=accessibility_role,
|
|
347
|
+
accessible=accessible,
|
|
348
|
+
)
|
|
122
349
|
|
|
123
350
|
|
|
124
351
|
def Button(
|
|
@@ -129,55 +356,55 @@ def Button(
|
|
|
129
356
|
style: StyleProp = None,
|
|
130
357
|
accessibility_label: Optional[str] = None,
|
|
131
358
|
accessibility_hint: Optional[str] = None,
|
|
359
|
+
accessibility_role: Optional[str] = None,
|
|
132
360
|
accessible: Optional[bool] = None,
|
|
133
361
|
ref: Optional[Dict[str, Any]] = None,
|
|
134
362
|
key: Optional[str] = None,
|
|
135
363
|
) -> Element:
|
|
136
364
|
"""Display a tappable button.
|
|
137
365
|
|
|
138
|
-
Style properties:
|
|
139
|
-
|
|
140
|
-
|
|
366
|
+
Style properties: ``color``, ``background_color``, ``font_size``,
|
|
367
|
+
``border_radius``, ``border_width``, ``border_color``, ``shadow_*``,
|
|
368
|
+
``opacity``, ``transform``, plus the common layout props.
|
|
369
|
+
|
|
370
|
+
Buttons get ``accessibility_role="button"`` by default.
|
|
141
371
|
|
|
142
372
|
Args:
|
|
143
373
|
title: Button label.
|
|
144
374
|
on_click: Callback invoked when the user taps the button.
|
|
145
|
-
enabled: When
|
|
375
|
+
enabled: When ``False``, the button is disabled and cannot be
|
|
146
376
|
tapped.
|
|
147
377
|
style: Style dict (or list of dicts).
|
|
148
378
|
accessibility_label: Spoken description for screen readers.
|
|
149
379
|
accessibility_hint: Spoken extra detail (iOS only).
|
|
380
|
+
accessibility_role: Override the default ``"button"`` role.
|
|
150
381
|
accessible: Override whether the element is exposed to AT.
|
|
151
|
-
ref: Optional ``use_ref()`` dict
|
|
152
|
-
``ref["current"]`` with the underlying native view.
|
|
382
|
+
ref: Optional ``use_ref()`` dict.
|
|
153
383
|
key: Stable identity for keyed reconciliation.
|
|
154
384
|
|
|
155
385
|
Returns:
|
|
156
|
-
An [`Element`][pythonnative.Element] of type
|
|
386
|
+
An [`Element`][pythonnative.Element] of type ``"Button"``.
|
|
157
387
|
"""
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if ref is not None:
|
|
173
|
-
props["ref"] = ref
|
|
174
|
-
return Element("Button", props, [], key=key)
|
|
388
|
+
return _make_element(
|
|
389
|
+
"Button",
|
|
390
|
+
style=style,
|
|
391
|
+
ref=ref,
|
|
392
|
+
key=key,
|
|
393
|
+
title=title,
|
|
394
|
+
on_click=on_click,
|
|
395
|
+
enabled=enabled,
|
|
396
|
+
accessibility_label=accessibility_label,
|
|
397
|
+
accessibility_hint=accessibility_hint,
|
|
398
|
+
accessibility_role=accessibility_role,
|
|
399
|
+
accessible=accessible,
|
|
400
|
+
_defaults={"accessibility_role": "button"},
|
|
401
|
+
)
|
|
175
402
|
|
|
176
403
|
|
|
177
404
|
def TextInput(
|
|
178
405
|
*,
|
|
179
406
|
value: str = "",
|
|
180
|
-
placeholder: str =
|
|
407
|
+
placeholder: Optional[str] = None,
|
|
181
408
|
on_change: Optional[Callable[[str], None]] = None,
|
|
182
409
|
on_submit: Optional[Callable[[str], None]] = None,
|
|
183
410
|
secure: bool = False,
|
|
@@ -196,30 +423,29 @@ def TextInput(
|
|
|
196
423
|
ref: Optional[Dict[str, Any]] = None,
|
|
197
424
|
key: Optional[str] = None,
|
|
198
425
|
) -> Element:
|
|
199
|
-
"""Display a text
|
|
426
|
+
"""Display a text-entry field (single-line by default, or ``multiline``).
|
|
200
427
|
|
|
201
|
-
Style properties:
|
|
202
|
-
|
|
428
|
+
Style properties: ``font_size``, ``color``, ``background_color``,
|
|
429
|
+
``border_*``, plus the common layout props.
|
|
203
430
|
|
|
204
431
|
Args:
|
|
205
432
|
value: Current text content (controlled-input pattern).
|
|
206
|
-
placeholder: Hint shown when
|
|
433
|
+
placeholder: Hint shown when ``value`` is empty.
|
|
207
434
|
on_change: Callback invoked with the new string each keystroke.
|
|
208
435
|
on_submit: Callback invoked when the user submits (Return /
|
|
209
436
|
Done / etc.). Receives the final text.
|
|
210
|
-
secure: When
|
|
211
|
-
multiline: When
|
|
437
|
+
secure: When ``True``, characters are masked (use for passwords).
|
|
438
|
+
multiline: When ``True``, allows multiple lines of input.
|
|
212
439
|
keyboard_type: One of ``"default"``, ``"email_address"``,
|
|
213
|
-
``"number_pad"``, ``"decimal_pad"``, ``"phone_pad"``,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
``"words"``, ``"characters"``.
|
|
440
|
+
``"number_pad"``, ``"decimal_pad"``, ``"phone_pad"``, ``"url"``.
|
|
441
|
+
auto_capitalize: One of ``"none"``, ``"sentences"``, ``"words"``,
|
|
442
|
+
``"characters"``.
|
|
217
443
|
auto_correct: Enable/disable autocorrection.
|
|
218
444
|
auto_focus: Request focus on mount.
|
|
219
445
|
return_key_type: One of ``"default"``, ``"done"``, ``"go"``,
|
|
220
446
|
``"next"``, ``"send"``, ``"search"``.
|
|
221
447
|
max_length: Maximum number of characters allowed.
|
|
222
|
-
placeholder_color: Color
|
|
448
|
+
placeholder_color: Color used for the placeholder string.
|
|
223
449
|
style: Style dict (or list of dicts).
|
|
224
450
|
accessibility_label: Spoken description for screen readers.
|
|
225
451
|
accessibility_hint: Spoken extra detail (iOS only).
|
|
@@ -228,38 +454,30 @@ def TextInput(
|
|
|
228
454
|
key: Stable identity for keyed reconciliation.
|
|
229
455
|
|
|
230
456
|
Returns:
|
|
231
|
-
An [`Element`][pythonnative.Element] of type
|
|
457
|
+
An [`Element`][pythonnative.Element] of type ``"TextInput"``.
|
|
232
458
|
"""
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
props["max_length"] = max_length
|
|
256
|
-
if placeholder_color is not None:
|
|
257
|
-
props["placeholder_color"] = placeholder_color
|
|
258
|
-
props.update(resolve_style(style))
|
|
259
|
-
props.update(_accessibility_props(accessibility_label, accessibility_hint, None, accessible))
|
|
260
|
-
if ref is not None:
|
|
261
|
-
props["ref"] = ref
|
|
262
|
-
return Element("TextInput", props, [], key=key)
|
|
459
|
+
return _make_element(
|
|
460
|
+
"TextInput",
|
|
461
|
+
style=style,
|
|
462
|
+
ref=ref,
|
|
463
|
+
key=key,
|
|
464
|
+
value=value,
|
|
465
|
+
placeholder=placeholder,
|
|
466
|
+
on_change=on_change,
|
|
467
|
+
on_submit=on_submit,
|
|
468
|
+
secure=secure or None,
|
|
469
|
+
multiline=multiline or None,
|
|
470
|
+
keyboard_type=keyboard_type,
|
|
471
|
+
auto_capitalize=auto_capitalize,
|
|
472
|
+
auto_correct=auto_correct,
|
|
473
|
+
auto_focus=auto_focus or None,
|
|
474
|
+
return_key_type=return_key_type,
|
|
475
|
+
max_length=max_length,
|
|
476
|
+
placeholder_color=placeholder_color,
|
|
477
|
+
accessibility_label=accessibility_label,
|
|
478
|
+
accessibility_hint=accessibility_hint,
|
|
479
|
+
accessible=accessible,
|
|
480
|
+
)
|
|
263
481
|
|
|
264
482
|
|
|
265
483
|
def Image(
|
|
@@ -269,46 +487,50 @@ def Image(
|
|
|
269
487
|
tint_color: Optional[Color] = None,
|
|
270
488
|
style: StyleProp = None,
|
|
271
489
|
accessibility_label: Optional[str] = None,
|
|
490
|
+
accessibility_role: Optional[str] = None,
|
|
272
491
|
accessible: Optional[bool] = None,
|
|
273
492
|
ref: Optional[Dict[str, Any]] = None,
|
|
274
493
|
key: Optional[str] = None,
|
|
275
494
|
) -> Element:
|
|
276
495
|
"""Display an image from a resource path or URL.
|
|
277
496
|
|
|
278
|
-
Style properties:
|
|
279
|
-
|
|
497
|
+
Style properties: ``background_color``, ``border_*``, ``opacity``,
|
|
498
|
+
``transform``, plus the common layout props.
|
|
280
499
|
|
|
281
500
|
Network images (``http://`` / ``https://``) are loaded
|
|
282
|
-
asynchronously off the main thread on both iOS (via
|
|
283
|
-
and Android (via a worker thread
|
|
501
|
+
asynchronously off the main thread on both iOS (via
|
|
502
|
+
``NSURLSession``) and Android (via a worker thread plus
|
|
503
|
+
``BitmapFactory``).
|
|
284
504
|
|
|
285
505
|
Args:
|
|
286
506
|
source: Image resource name or URL.
|
|
287
|
-
scale_type: Fit mode:
|
|
288
|
-
|
|
507
|
+
scale_type: Fit mode: ``"cover"``, ``"contain"``, ``"stretch"``,
|
|
508
|
+
``"center"``.
|
|
289
509
|
tint_color: Color overlay applied to template images
|
|
290
510
|
(monochrome icons).
|
|
291
511
|
style: Style dict (or list of dicts).
|
|
292
512
|
accessibility_label: Spoken description for screen readers.
|
|
513
|
+
accessibility_role: Override the default ``"image"`` role.
|
|
293
514
|
accessible: Override whether the element is exposed to AT.
|
|
294
515
|
ref: Optional ``use_ref()`` dict.
|
|
295
516
|
key: Stable identity for keyed reconciliation.
|
|
296
517
|
|
|
297
518
|
Returns:
|
|
298
|
-
An [`Element`][pythonnative.Element] of type
|
|
519
|
+
An [`Element`][pythonnative.Element] of type ``"Image"``.
|
|
299
520
|
"""
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
521
|
+
return _make_element(
|
|
522
|
+
"Image",
|
|
523
|
+
style=style,
|
|
524
|
+
ref=ref,
|
|
525
|
+
key=key,
|
|
526
|
+
source=source or None,
|
|
527
|
+
scale_type=scale_type,
|
|
528
|
+
tint_color=tint_color,
|
|
529
|
+
accessibility_label=accessibility_label,
|
|
530
|
+
accessibility_role=accessibility_role,
|
|
531
|
+
accessible=accessible,
|
|
532
|
+
_defaults={"accessibility_role": "image"},
|
|
533
|
+
)
|
|
312
534
|
|
|
313
535
|
|
|
314
536
|
def Switch(
|
|
@@ -327,13 +549,15 @@ def Switch(
|
|
|
327
549
|
key: Stable identity for keyed reconciliation.
|
|
328
550
|
|
|
329
551
|
Returns:
|
|
330
|
-
An [`Element`][pythonnative.Element] of type
|
|
552
|
+
An [`Element`][pythonnative.Element] of type ``"Switch"``.
|
|
331
553
|
"""
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
554
|
+
return _make_element(
|
|
555
|
+
"Switch",
|
|
556
|
+
style=style,
|
|
557
|
+
key=key,
|
|
558
|
+
value=value,
|
|
559
|
+
on_change=on_change,
|
|
560
|
+
)
|
|
337
561
|
|
|
338
562
|
|
|
339
563
|
def ProgressBar(
|
|
@@ -342,23 +566,26 @@ def ProgressBar(
|
|
|
342
566
|
style: StyleProp = None,
|
|
343
567
|
key: Optional[str] = None,
|
|
344
568
|
) -> Element:
|
|
345
|
-
"""Show determinate progress as a value between 0.0 and 1.0
|
|
569
|
+
"""Show determinate progress as a value between ``0.0`` and ``1.0``.
|
|
346
570
|
|
|
347
571
|
For indeterminate progress, use
|
|
348
572
|
[`ActivityIndicator`][pythonnative.ActivityIndicator] instead.
|
|
349
573
|
|
|
350
574
|
Args:
|
|
351
|
-
value: Fraction complete (clamped to
|
|
575
|
+
value: Fraction complete (clamped to ``[0.0, 1.0]`` by the
|
|
352
576
|
platform handler).
|
|
353
577
|
style: Style dict (or list of dicts).
|
|
354
578
|
key: Stable identity for keyed reconciliation.
|
|
355
579
|
|
|
356
580
|
Returns:
|
|
357
|
-
An [`Element`][pythonnative.Element] of type
|
|
581
|
+
An [`Element`][pythonnative.Element] of type ``"ProgressBar"``.
|
|
358
582
|
"""
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
583
|
+
return _make_element(
|
|
584
|
+
"ProgressBar",
|
|
585
|
+
style=style,
|
|
586
|
+
key=key,
|
|
587
|
+
value=value,
|
|
588
|
+
)
|
|
362
589
|
|
|
363
590
|
|
|
364
591
|
def ActivityIndicator(
|
|
@@ -370,17 +597,20 @@ def ActivityIndicator(
|
|
|
370
597
|
"""Show an indeterminate loading spinner.
|
|
371
598
|
|
|
372
599
|
Args:
|
|
373
|
-
animating: When
|
|
600
|
+
animating: When ``False``, the spinner is hidden.
|
|
374
601
|
style: Style dict (or list of dicts).
|
|
375
602
|
key: Stable identity for keyed reconciliation.
|
|
376
603
|
|
|
377
604
|
Returns:
|
|
378
605
|
An [`Element`][pythonnative.Element] of type
|
|
379
|
-
|
|
606
|
+
``"ActivityIndicator"``.
|
|
380
607
|
"""
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
608
|
+
return _make_element(
|
|
609
|
+
"ActivityIndicator",
|
|
610
|
+
style=style,
|
|
611
|
+
key=key,
|
|
612
|
+
animating=animating,
|
|
613
|
+
)
|
|
384
614
|
|
|
385
615
|
|
|
386
616
|
def WebView(
|
|
@@ -397,13 +627,14 @@ def WebView(
|
|
|
397
627
|
key: Stable identity for keyed reconciliation.
|
|
398
628
|
|
|
399
629
|
Returns:
|
|
400
|
-
An [`Element`][pythonnative.Element] of type
|
|
630
|
+
An [`Element`][pythonnative.Element] of type ``"WebView"``.
|
|
401
631
|
"""
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
632
|
+
return _make_element(
|
|
633
|
+
"WebView",
|
|
634
|
+
style=style,
|
|
635
|
+
key=key,
|
|
636
|
+
url=url or None,
|
|
637
|
+
)
|
|
407
638
|
|
|
408
639
|
|
|
409
640
|
def Spacer(
|
|
@@ -414,32 +645,31 @@ def Spacer(
|
|
|
414
645
|
) -> Element:
|
|
415
646
|
"""Insert empty space inside a flex container.
|
|
416
647
|
|
|
417
|
-
Pass
|
|
648
|
+
Pass ``size`` for a fixed gap, or ``flex`` to expand and absorb
|
|
418
649
|
remaining space.
|
|
419
650
|
|
|
420
651
|
Args:
|
|
421
|
-
size: Fixed gap in dp/pt along the parent's main axis.
|
|
652
|
+
size: Fixed gap in dp/pt along the parent's main axis. Mirrored
|
|
653
|
+
on both axes — whichever axis the parent's
|
|
654
|
+
``flex_direction`` chooses as main becomes the actual gap.
|
|
422
655
|
flex: Flex-grow weight; useful for pushing siblings to the
|
|
423
656
|
opposite end of a [`Row`][pythonnative.Row] or
|
|
424
657
|
[`Column`][pythonnative.Column].
|
|
425
658
|
key: Stable identity for keyed reconciliation.
|
|
426
659
|
|
|
427
660
|
Returns:
|
|
428
|
-
An [`Element`][pythonnative.Element] of type
|
|
661
|
+
An [`Element`][pythonnative.Element] of type ``"Spacer"``.
|
|
429
662
|
"""
|
|
430
|
-
|
|
431
|
-
if size is not None
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if flex is not None:
|
|
441
|
-
props["flex"] = flex
|
|
442
|
-
return Element("Spacer", props, [], key=key)
|
|
663
|
+
width = size if size is not None else None
|
|
664
|
+
height = size if size is not None else None
|
|
665
|
+
return _make_element(
|
|
666
|
+
"Spacer",
|
|
667
|
+
key=key,
|
|
668
|
+
size=size,
|
|
669
|
+
width=width,
|
|
670
|
+
height=height,
|
|
671
|
+
flex=flex,
|
|
672
|
+
)
|
|
443
673
|
|
|
444
674
|
|
|
445
675
|
def Slider(
|
|
@@ -451,7 +681,7 @@ def Slider(
|
|
|
451
681
|
style: StyleProp = None,
|
|
452
682
|
key: Optional[str] = None,
|
|
453
683
|
) -> Element:
|
|
454
|
-
"""Continuous-value slider between
|
|
684
|
+
"""Continuous-value slider between ``min_value`` and ``max_value``.
|
|
455
685
|
|
|
456
686
|
Args:
|
|
457
687
|
value: Current slider value.
|
|
@@ -463,21 +693,21 @@ def Slider(
|
|
|
463
693
|
key: Stable identity for keyed reconciliation.
|
|
464
694
|
|
|
465
695
|
Returns:
|
|
466
|
-
An [`Element`][pythonnative.Element] of type
|
|
696
|
+
An [`Element`][pythonnative.Element] of type ``"Slider"``.
|
|
467
697
|
"""
|
|
468
|
-
|
|
469
|
-
"
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
698
|
+
return _make_element(
|
|
699
|
+
"Slider",
|
|
700
|
+
style=style,
|
|
701
|
+
key=key,
|
|
702
|
+
value=value,
|
|
703
|
+
min_value=min_value,
|
|
704
|
+
max_value=max_value,
|
|
705
|
+
on_change=on_change,
|
|
706
|
+
)
|
|
477
707
|
|
|
478
708
|
|
|
479
709
|
# ======================================================================
|
|
480
|
-
# Container
|
|
710
|
+
# Container factories
|
|
481
711
|
# ======================================================================
|
|
482
712
|
|
|
483
713
|
|
|
@@ -491,28 +721,24 @@ def View(
|
|
|
491
721
|
ref: Optional[Dict[str, Any]] = None,
|
|
492
722
|
key: Optional[str] = None,
|
|
493
723
|
) -> Element:
|
|
494
|
-
"""Universal flex container (like React Native's
|
|
724
|
+
"""Universal flex container (like React Native's ``View``).
|
|
495
725
|
|
|
496
|
-
Defaults to
|
|
726
|
+
Defaults to ``flex_direction: "column"`` (override via ``style``).
|
|
497
727
|
|
|
498
|
-
|
|
499
|
-
pn.View(child_a, child_b, style={"flex_direction": "row"})
|
|
500
|
-
```
|
|
728
|
+
Flex container properties (passed via ``style``):
|
|
501
729
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
`shadow_opacity`, `shadow_radius`, `elevation`, `opacity`,
|
|
515
|
-
`transform`.
|
|
730
|
+
- ``flex_direction``: ``"column"`` (default), ``"row"``,
|
|
731
|
+
``"column_reverse"``, ``"row_reverse"``.
|
|
732
|
+
- ``justify_content``: main-axis distribution. Accepts
|
|
733
|
+
``"flex_start"`` (default), ``"center"``, ``"flex_end"``,
|
|
734
|
+
``"space_between"``, ``"space_around"``, ``"space_evenly"``.
|
|
735
|
+
- ``align_items``: cross-axis alignment. Accepts ``"stretch"``
|
|
736
|
+
(default), ``"flex_start"``, ``"center"``, ``"flex_end"``.
|
|
737
|
+
- ``overflow``: ``"visible"`` (default) or ``"hidden"``.
|
|
738
|
+
- ``spacing``, ``padding``, ``background_color``, ``border_radius``,
|
|
739
|
+
``border_width``, ``border_color``, ``shadow_color``,
|
|
740
|
+
``shadow_offset``, ``shadow_opacity``, ``shadow_radius``,
|
|
741
|
+
``elevation``, ``opacity``, ``transform``.
|
|
516
742
|
|
|
517
743
|
Args:
|
|
518
744
|
*children: Child elements rendered inside the container.
|
|
@@ -521,19 +747,24 @@ def View(
|
|
|
521
747
|
accessibility_hint: Spoken extra detail (iOS only).
|
|
522
748
|
accessibility_role: Semantic role for assistive tech.
|
|
523
749
|
accessible: Override whether the element is exposed to AT.
|
|
524
|
-
ref: Optional ``use_ref()`` dict
|
|
525
|
-
``ref["current"]`` with the underlying native view.
|
|
750
|
+
ref: Optional ``use_ref()`` dict.
|
|
526
751
|
key: Stable identity for keyed reconciliation.
|
|
527
752
|
|
|
528
753
|
Returns:
|
|
529
|
-
An [`Element`][pythonnative.Element] of type
|
|
754
|
+
An [`Element`][pythonnative.Element] of type ``"View"``.
|
|
530
755
|
"""
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
756
|
+
return _make_element(
|
|
757
|
+
"View",
|
|
758
|
+
*children,
|
|
759
|
+
style=style,
|
|
760
|
+
ref=ref,
|
|
761
|
+
key=key,
|
|
762
|
+
accessibility_label=accessibility_label,
|
|
763
|
+
accessibility_hint=accessibility_hint,
|
|
764
|
+
accessibility_role=accessibility_role,
|
|
765
|
+
accessible=accessible,
|
|
766
|
+
_defaults={"flex_direction": "column"},
|
|
767
|
+
)
|
|
537
768
|
|
|
538
769
|
|
|
539
770
|
def Column(
|
|
@@ -545,20 +776,8 @@ def Column(
|
|
|
545
776
|
"""Arrange children vertically.
|
|
546
777
|
|
|
547
778
|
Convenience wrapper around [`View`][pythonnative.View] with
|
|
548
|
-
|
|
549
|
-
need to switch between row and column at runtime.
|
|
550
|
-
|
|
551
|
-
Style properties: `spacing`, `padding`, `align_items`,
|
|
552
|
-
`justify_content`, `background_color`, `overflow`, plus the common
|
|
553
|
-
layout props.
|
|
554
|
-
|
|
555
|
-
`align_items` controls cross-axis (horizontal) alignment:
|
|
556
|
-
`"stretch"` (default), `"flex_start"` / `"leading"`, `"center"`, or
|
|
557
|
-
`"flex_end"` / `"trailing"`.
|
|
558
|
-
|
|
559
|
-
`justify_content` controls main-axis (vertical) distribution:
|
|
560
|
-
`"flex_start"` (default), `"center"`, `"flex_end"`,
|
|
561
|
-
`"space_between"`, `"space_around"`, `"space_evenly"`.
|
|
779
|
+
``flex_direction`` locked to ``"column"``. Use ``View`` directly if
|
|
780
|
+
you need to switch between row and column at runtime.
|
|
562
781
|
|
|
563
782
|
Args:
|
|
564
783
|
*children: Child elements stacked top to bottom.
|
|
@@ -567,14 +786,16 @@ def Column(
|
|
|
567
786
|
key: Stable identity for keyed reconciliation.
|
|
568
787
|
|
|
569
788
|
Returns:
|
|
570
|
-
An [`Element`][pythonnative.Element] of type
|
|
789
|
+
An [`Element`][pythonnative.Element] of type ``"Column"``.
|
|
571
790
|
"""
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
791
|
+
return _make_element(
|
|
792
|
+
"Column",
|
|
793
|
+
*children,
|
|
794
|
+
style=style,
|
|
795
|
+
ref=ref,
|
|
796
|
+
key=key,
|
|
797
|
+
_forced={"flex_direction": "column"},
|
|
798
|
+
)
|
|
578
799
|
|
|
579
800
|
|
|
580
801
|
def Row(
|
|
@@ -586,20 +807,8 @@ def Row(
|
|
|
586
807
|
"""Arrange children horizontally.
|
|
587
808
|
|
|
588
809
|
Convenience wrapper around [`View`][pythonnative.View] with
|
|
589
|
-
|
|
590
|
-
to switch between row and column at runtime.
|
|
591
|
-
|
|
592
|
-
Style properties: `spacing`, `padding`, `align_items`,
|
|
593
|
-
`justify_content`, `background_color`, `overflow`, plus the common
|
|
594
|
-
layout props.
|
|
595
|
-
|
|
596
|
-
`align_items` controls cross-axis (vertical) alignment:
|
|
597
|
-
`"stretch"` (default), `"flex_start"` / `"top"`, `"center"`, or
|
|
598
|
-
`"flex_end"` / `"bottom"`.
|
|
599
|
-
|
|
600
|
-
`justify_content` controls main-axis (horizontal) distribution:
|
|
601
|
-
`"flex_start"` (default), `"center"`, `"flex_end"`,
|
|
602
|
-
`"space_between"`, `"space_around"`, `"space_evenly"`.
|
|
810
|
+
``flex_direction`` locked to ``"row"``. Use ``View`` directly if you
|
|
811
|
+
need to switch between row and column at runtime.
|
|
603
812
|
|
|
604
813
|
Args:
|
|
605
814
|
*children: Child elements arranged left to right.
|
|
@@ -608,49 +817,57 @@ def Row(
|
|
|
608
817
|
key: Stable identity for keyed reconciliation.
|
|
609
818
|
|
|
610
819
|
Returns:
|
|
611
|
-
An [`Element`][pythonnative.Element] of type
|
|
820
|
+
An [`Element`][pythonnative.Element] of type ``"Row"``.
|
|
612
821
|
"""
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
822
|
+
return _make_element(
|
|
823
|
+
"Row",
|
|
824
|
+
*children,
|
|
825
|
+
style=style,
|
|
826
|
+
ref=ref,
|
|
827
|
+
key=key,
|
|
828
|
+
_forced={"flex_direction": "row"},
|
|
829
|
+
)
|
|
619
830
|
|
|
620
831
|
|
|
621
832
|
def ScrollView(
|
|
622
|
-
|
|
623
|
-
*,
|
|
833
|
+
*children: Element,
|
|
624
834
|
refresh_control: Optional[Dict[str, Any]] = None,
|
|
835
|
+
scroll_axis: Optional[Literal["vertical", "horizontal"]] = None,
|
|
625
836
|
style: StyleProp = None,
|
|
626
837
|
ref: Optional[Dict[str, Any]] = None,
|
|
627
838
|
key: Optional[str] = None,
|
|
628
839
|
) -> Element:
|
|
629
|
-
"""Wrap
|
|
840
|
+
"""Wrap children in a scrollable container.
|
|
841
|
+
|
|
842
|
+
``ScrollView`` typically takes a single child (a ``Column`` or
|
|
843
|
+
``Row`` aggregating the scrollable content). It accepts ``*children``
|
|
844
|
+
for ergonomic call sites; the underlying native scroll view stacks
|
|
845
|
+
them on its content axis.
|
|
630
846
|
|
|
631
847
|
Args:
|
|
632
|
-
|
|
633
|
-
[`Column`][pythonnative.Column] or
|
|
634
|
-
[`Row`][pythonnative.Row] first.
|
|
848
|
+
*children: Child elements to scroll.
|
|
635
849
|
refresh_control: Optional pull-to-refresh spec, typically
|
|
636
850
|
constructed via
|
|
637
851
|
[`RefreshControl`][pythonnative.RefreshControl]. The dict
|
|
638
|
-
must have ``refreshing`` (bool) and ``on_refresh``
|
|
852
|
+
must have ``refreshing`` (bool) and ``on_refresh``
|
|
853
|
+
(callable).
|
|
854
|
+
scroll_axis: ``"vertical"`` (default) or ``"horizontal"``.
|
|
639
855
|
style: Style dict (or list of dicts).
|
|
640
856
|
ref: Optional ``use_ref()`` dict.
|
|
641
857
|
key: Stable identity for keyed reconciliation.
|
|
642
858
|
|
|
643
859
|
Returns:
|
|
644
|
-
An [`Element`][pythonnative.Element] of type
|
|
860
|
+
An [`Element`][pythonnative.Element] of type ``"ScrollView"``.
|
|
645
861
|
"""
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
862
|
+
return _make_element(
|
|
863
|
+
"ScrollView",
|
|
864
|
+
*children,
|
|
865
|
+
style=style,
|
|
866
|
+
ref=ref,
|
|
867
|
+
key=key,
|
|
868
|
+
refresh_control=refresh_control,
|
|
869
|
+
scroll_axis=scroll_axis,
|
|
870
|
+
)
|
|
654
871
|
|
|
655
872
|
|
|
656
873
|
def SafeAreaView(
|
|
@@ -666,11 +883,14 @@ def SafeAreaView(
|
|
|
666
883
|
key: Stable identity for keyed reconciliation.
|
|
667
884
|
|
|
668
885
|
Returns:
|
|
669
|
-
An [`Element`][pythonnative.Element] of type
|
|
886
|
+
An [`Element`][pythonnative.Element] of type ``"SafeAreaView"``.
|
|
670
887
|
"""
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
888
|
+
return _make_element(
|
|
889
|
+
"SafeAreaView",
|
|
890
|
+
*children,
|
|
891
|
+
style=style,
|
|
892
|
+
key=key,
|
|
893
|
+
)
|
|
674
894
|
|
|
675
895
|
|
|
676
896
|
def Modal(
|
|
@@ -685,21 +905,21 @@ def Modal(
|
|
|
685
905
|
) -> Element:
|
|
686
906
|
"""Overlay modal dialog backed by a real native presentation.
|
|
687
907
|
|
|
688
|
-
The modal is shown when
|
|
689
|
-
Drive
|
|
908
|
+
The modal is shown when ``visible=True`` and hidden when ``False``.
|
|
909
|
+
Drive ``visible`` from a hook so the parent component can dismiss
|
|
690
910
|
the modal in response to user actions. On iOS this presents a
|
|
691
|
-
|
|
911
|
+
``UIViewController``; on Android it shows an ``android.app.Dialog``.
|
|
692
912
|
|
|
693
913
|
Children are mounted as the modal's content view, not into the
|
|
694
|
-
on-tree placeholder, so they appear above all other native
|
|
695
|
-
|
|
914
|
+
on-tree placeholder, so they appear above all other native content
|
|
915
|
+
and don't influence the underlying layout.
|
|
696
916
|
|
|
697
917
|
Args:
|
|
698
918
|
*children: Modal content.
|
|
699
919
|
visible: Controls whether the modal is presented.
|
|
700
920
|
on_dismiss: Callback invoked when the user dismisses the modal
|
|
701
|
-
via system gesture
|
|
702
|
-
title: Optional title
|
|
921
|
+
via system gesture.
|
|
922
|
+
title: Optional title-bar text.
|
|
703
923
|
animation_type: ``"slide"`` (default), ``"fade"``, or ``"none"``.
|
|
704
924
|
transparent: When ``True``, the underlying view is dimmed
|
|
705
925
|
instead of fully covered.
|
|
@@ -707,91 +927,152 @@ def Modal(
|
|
|
707
927
|
key: Stable identity for keyed reconciliation.
|
|
708
928
|
|
|
709
929
|
Returns:
|
|
710
|
-
An [`Element`][pythonnative.Element] of type
|
|
930
|
+
An [`Element`][pythonnative.Element] of type ``"Modal"``.
|
|
711
931
|
"""
|
|
712
|
-
|
|
713
|
-
"
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
932
|
+
return _make_element(
|
|
933
|
+
"Modal",
|
|
934
|
+
*children,
|
|
935
|
+
style=style,
|
|
936
|
+
key=key,
|
|
937
|
+
visible=visible,
|
|
938
|
+
animation_type=animation_type,
|
|
939
|
+
transparent=transparent,
|
|
940
|
+
on_dismiss=on_dismiss,
|
|
941
|
+
title=title,
|
|
942
|
+
)
|
|
723
943
|
|
|
724
944
|
|
|
725
945
|
def Pressable(
|
|
726
|
-
|
|
727
|
-
*,
|
|
946
|
+
*children: Element,
|
|
728
947
|
on_press: Optional[Callable[[], None]] = None,
|
|
729
948
|
on_long_press: Optional[Callable[[], None]] = None,
|
|
730
949
|
pressed_opacity: float = 0.6,
|
|
731
950
|
style: StyleProp = None,
|
|
732
951
|
accessibility_label: Optional[str] = None,
|
|
733
952
|
accessibility_hint: Optional[str] = None,
|
|
953
|
+
accessibility_role: Optional[str] = None,
|
|
734
954
|
accessible: Optional[bool] = None,
|
|
735
955
|
key: Optional[str] = None,
|
|
736
956
|
) -> Element:
|
|
737
|
-
"""Wrap
|
|
957
|
+
"""Wrap children with tap and long-press handlers.
|
|
738
958
|
|
|
739
959
|
Useful for making non-button elements (text, images, custom views)
|
|
740
960
|
respond to user taps. The wrapper view fades to ``pressed_opacity``
|
|
741
|
-
on touch-down and back to full opacity on touch-up
|
|
742
|
-
|
|
961
|
+
on touch-down and back to full opacity on touch-up.
|
|
962
|
+
|
|
963
|
+
Pressable gets ``accessibility_role="button"`` by default.
|
|
743
964
|
|
|
744
965
|
Args:
|
|
745
|
-
|
|
966
|
+
*children: Elements to make pressable.
|
|
746
967
|
on_press: Callback invoked on a normal tap.
|
|
747
968
|
on_long_press: Callback invoked on a sustained press.
|
|
748
|
-
pressed_opacity: Opacity (0
|
|
749
|
-
|
|
750
|
-
feedback.
|
|
969
|
+
pressed_opacity: Opacity (0–1) applied while the user's finger
|
|
970
|
+
is down. Set to ``1.0`` for no visual feedback.
|
|
751
971
|
style: Style dict applied to the wrapper.
|
|
752
972
|
accessibility_label: Spoken description for screen readers.
|
|
753
973
|
accessibility_hint: Spoken extra detail (iOS only).
|
|
974
|
+
accessibility_role: Override the default ``"button"`` role.
|
|
754
975
|
accessible: Override whether the element is exposed to AT.
|
|
755
976
|
key: Stable identity for keyed reconciliation.
|
|
756
977
|
|
|
757
978
|
Returns:
|
|
758
|
-
An [`Element`][pythonnative.Element] of type
|
|
979
|
+
An [`Element`][pythonnative.Element] of type ``"Pressable"``.
|
|
759
980
|
"""
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
981
|
+
return _make_element(
|
|
982
|
+
"Pressable",
|
|
983
|
+
*children,
|
|
984
|
+
style=style,
|
|
985
|
+
key=key,
|
|
986
|
+
on_press=on_press,
|
|
987
|
+
on_long_press=on_long_press,
|
|
988
|
+
pressed_opacity=pressed_opacity,
|
|
989
|
+
accessibility_label=accessibility_label,
|
|
990
|
+
accessibility_hint=accessibility_hint,
|
|
991
|
+
accessibility_role=accessibility_role,
|
|
992
|
+
accessible=accessible,
|
|
993
|
+
_defaults={"accessibility_role": "button"},
|
|
994
|
+
)
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
# ======================================================================
|
|
998
|
+
# Fragment
|
|
999
|
+
# ======================================================================
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
def Fragment(*children: Optional[Element], key: Optional[str] = None) -> Element:
|
|
1003
|
+
"""Group children without adding a wrapping native view.
|
|
1004
|
+
|
|
1005
|
+
Like React's ``<></>``: returns multiple elements from a component
|
|
1006
|
+
without introducing an extra container. The reconciler flattens
|
|
1007
|
+
Fragment elements at the children-list level, so each child appears
|
|
1008
|
+
as a direct sibling of the Fragment's parent in the native tree.
|
|
1009
|
+
|
|
1010
|
+
Useful inside [`Provider`][pythonnative.Provider] /
|
|
1011
|
+
[`memo`][pythonnative.memo] / conditional logic when grouping
|
|
1012
|
+
siblings inside another component's child list:
|
|
1013
|
+
|
|
1014
|
+
```python
|
|
1015
|
+
pn.Column(
|
|
1016
|
+
pn.Text("Top"),
|
|
1017
|
+
pn.Fragment(
|
|
1018
|
+
pn.Text("Middle A"),
|
|
1019
|
+
pn.Text("Middle B"),
|
|
1020
|
+
),
|
|
1021
|
+
pn.Text("Bottom"),
|
|
1022
|
+
)
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
Args:
|
|
1026
|
+
*children: Child elements to expose at the parent level. ``None``
|
|
1027
|
+
children are dropped, which makes conditional rendering with
|
|
1028
|
+
``cond and pn.Text(...)`` ergonomic.
|
|
1029
|
+
key: Optional key for the Fragment itself (rarely useful since
|
|
1030
|
+
Fragment doesn't appear in the native tree).
|
|
1031
|
+
|
|
1032
|
+
Returns:
|
|
1033
|
+
An [`Element`][pythonnative.Element] of type ``"__Fragment__"``.
|
|
1034
|
+
|
|
1035
|
+
Note:
|
|
1036
|
+
Today, returning a Fragment from a ``@pn.component`` function
|
|
1037
|
+
only mounts its first child as the component's root. To return
|
|
1038
|
+
multiple top-level elements from a function component, use a
|
|
1039
|
+
container such as [`Column`][pythonnative.Column] or
|
|
1040
|
+
[`Row`][pythonnative.Row] instead.
|
|
1041
|
+
"""
|
|
1042
|
+
filtered = [c for c in children if c is not None]
|
|
1043
|
+
return Element("__Fragment__", {}, filtered, key=key)
|
|
1044
|
+
|
|
1045
|
+
|
|
1046
|
+
# ======================================================================
|
|
1047
|
+
# Error boundary
|
|
1048
|
+
# ======================================================================
|
|
773
1049
|
|
|
774
1050
|
|
|
775
1051
|
def ErrorBoundary(
|
|
776
|
-
|
|
777
|
-
*,
|
|
1052
|
+
*children: Element,
|
|
778
1053
|
fallback: Optional[Any] = None,
|
|
779
1054
|
key: Optional[str] = None,
|
|
780
1055
|
) -> Element:
|
|
781
|
-
"""Catch render errors in
|
|
1056
|
+
"""Catch render errors in the wrapped subtree and display ``fallback`` instead.
|
|
1057
|
+
|
|
1058
|
+
``fallback`` may be an [`Element`][pythonnative.Element] or a
|
|
1059
|
+
callable that receives the exception and returns an ``Element``.
|
|
1060
|
+
Useful for isolating risky subtrees so a single failure doesn't
|
|
1061
|
+
crash the page.
|
|
782
1062
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1063
|
+
When multiple children are passed they're grouped under a
|
|
1064
|
+
[`Fragment`][pythonnative.Fragment] so the boundary still wraps a
|
|
1065
|
+
single logical subtree.
|
|
786
1066
|
|
|
787
1067
|
Args:
|
|
788
|
-
|
|
789
|
-
fallback: Element
|
|
790
|
-
or a callable
|
|
1068
|
+
*children: Subtree to wrap.
|
|
1069
|
+
fallback: Element rendered when the subtree raises during
|
|
1070
|
+
render, or a callable ``fallback(err) -> Element``.
|
|
791
1071
|
key: Stable identity for keyed reconciliation.
|
|
792
1072
|
|
|
793
1073
|
Returns:
|
|
794
|
-
An [`Element`][pythonnative.Element] of type
|
|
1074
|
+
An [`Element`][pythonnative.Element] of type
|
|
1075
|
+
``"__ErrorBoundary__"``.
|
|
795
1076
|
|
|
796
1077
|
Example:
|
|
797
1078
|
```python
|
|
@@ -806,8 +1087,16 @@ def ErrorBoundary(
|
|
|
806
1087
|
props: Dict[str, Any] = {}
|
|
807
1088
|
if fallback is not None:
|
|
808
1089
|
props["__fallback__"] = fallback
|
|
809
|
-
|
|
810
|
-
|
|
1090
|
+
if len(children) <= 1:
|
|
1091
|
+
kids = list(children)
|
|
1092
|
+
else:
|
|
1093
|
+
kids = [Fragment(*children)]
|
|
1094
|
+
return Element("__ErrorBoundary__", props, kids, key=key)
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
# ======================================================================
|
|
1098
|
+
# Lists
|
|
1099
|
+
# ======================================================================
|
|
811
1100
|
|
|
812
1101
|
|
|
813
1102
|
def FlatList(
|
|
@@ -822,17 +1111,18 @@ def FlatList(
|
|
|
822
1111
|
style: StyleProp = None,
|
|
823
1112
|
key: Optional[str] = None,
|
|
824
1113
|
) -> Element:
|
|
825
|
-
"""Virtualized scrollable list that renders items from
|
|
1114
|
+
"""Virtualized scrollable list that renders items from ``data`` lazily.
|
|
826
1115
|
|
|
827
|
-
Backed by
|
|
828
|
-
|
|
829
|
-
|
|
1116
|
+
Backed by ``UITableView`` on iOS and ``RecyclerView`` on Android via
|
|
1117
|
+
the ``VirtualList`` element. Each visible row is mounted on demand
|
|
1118
|
+
by a nested
|
|
1119
|
+
[`Reconciler`][pythonnative.reconciler.Reconciler] when
|
|
830
1120
|
``item_height`` is specified.
|
|
831
1121
|
|
|
832
1122
|
When ``item_height`` is omitted the implementation falls back to an
|
|
833
1123
|
eager (non-virtualized) ``ScrollView`` of every row — keep the data
|
|
834
|
-
set small in that mode (the fallback is convenient for short
|
|
835
|
-
|
|
1124
|
+
set small in that mode (the fallback is convenient for short lists
|
|
1125
|
+
where virtualization overhead would dominate).
|
|
836
1126
|
|
|
837
1127
|
Args:
|
|
838
1128
|
data: Iterable of arbitrary item values.
|
|
@@ -852,11 +1142,12 @@ def FlatList(
|
|
|
852
1142
|
on_item_press: Callback invoked with the row index when the
|
|
853
1143
|
user taps a row (virtualized backend only).
|
|
854
1144
|
style: Style dict (or list of dicts).
|
|
855
|
-
key: Stable identity for keyed reconciliation of the list
|
|
1145
|
+
key: Stable identity for keyed reconciliation of the list
|
|
1146
|
+
itself.
|
|
856
1147
|
|
|
857
1148
|
Returns:
|
|
858
|
-
An [`Element`][pythonnative.Element] of type
|
|
859
|
-
(virtualized) or
|
|
1149
|
+
An [`Element`][pythonnative.Element] of type ``"VirtualList"``
|
|
1150
|
+
(virtualized) or ``"ScrollView"`` (eager fallback).
|
|
860
1151
|
|
|
861
1152
|
Example:
|
|
862
1153
|
```python
|
|
@@ -883,11 +1174,7 @@ def FlatList(
|
|
|
883
1174
|
el = Element(el.type, el.props, el.children, key=key_extractor(item, i))
|
|
884
1175
|
items_eager.append(el)
|
|
885
1176
|
inner = Column(*items_eager, style={"spacing": separator_height} if separator_height else None)
|
|
886
|
-
|
|
887
|
-
if refresh_control is not None:
|
|
888
|
-
sv_props["refresh_control"] = refresh_control
|
|
889
|
-
sv_props.update(resolve_style(style))
|
|
890
|
-
return Element("ScrollView", sv_props, [inner], key=key)
|
|
1177
|
+
return ScrollView(inner, refresh_control=refresh_control, style=style, key=key)
|
|
891
1178
|
|
|
892
1179
|
# Virtualized path: render_item is invoked lazily by the native
|
|
893
1180
|
# cell mount callback when each row scrolls into view.
|
|
@@ -928,17 +1215,16 @@ def FlatList(
|
|
|
928
1215
|
|
|
929
1216
|
backend.add_child(content_view, native_root, "View")
|
|
930
1217
|
|
|
931
|
-
|
|
932
|
-
"
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
return Element("VirtualList", list_props, [], key=key)
|
|
1218
|
+
return _make_element(
|
|
1219
|
+
"VirtualList",
|
|
1220
|
+
style=style,
|
|
1221
|
+
key=key,
|
|
1222
|
+
count=len(items_list),
|
|
1223
|
+
row_height=row_h,
|
|
1224
|
+
mount_row=_mount_row,
|
|
1225
|
+
on_row_press=on_item_press,
|
|
1226
|
+
refresh_control=refresh_control,
|
|
1227
|
+
)
|
|
942
1228
|
|
|
943
1229
|
|
|
944
1230
|
def SectionList(
|
|
@@ -961,8 +1247,10 @@ def SectionList(
|
|
|
961
1247
|
|
|
962
1248
|
Args:
|
|
963
1249
|
sections: Each section is ``{"title": ..., "data": [...]}``.
|
|
964
|
-
render_item: ``render_item(item, item_index, section_index) ->
|
|
965
|
-
|
|
1250
|
+
render_item: ``render_item(item, item_index, section_index) ->
|
|
1251
|
+
Element``.
|
|
1252
|
+
render_section_header: ``render_section_header(section,
|
|
1253
|
+
section_index) -> Element``.
|
|
966
1254
|
item_height: Fixed row height for items, in layout units.
|
|
967
1255
|
section_header_height: Fixed header height in layout units.
|
|
968
1256
|
separator_height: Gap appended below each item, in layout units.
|
|
@@ -970,9 +1258,9 @@ def SectionList(
|
|
|
970
1258
|
key: Stable identity for keyed reconciliation.
|
|
971
1259
|
|
|
972
1260
|
Returns:
|
|
973
|
-
An [`Element`][pythonnative.Element] of type
|
|
974
|
-
(virtualized). When ``item_height`` is omitted the layout
|
|
975
|
-
|
|
1261
|
+
An [`Element`][pythonnative.Element] of type ``"VirtualList"``
|
|
1262
|
+
(virtualized). When ``item_height`` is omitted the layout falls
|
|
1263
|
+
back to an eager column.
|
|
976
1264
|
"""
|
|
977
1265
|
sections_list = list(sections or [])
|
|
978
1266
|
|
|
@@ -997,9 +1285,7 @@ def SectionList(
|
|
|
997
1285
|
else:
|
|
998
1286
|
children.append(Text(str(entry["item"])))
|
|
999
1287
|
inner = Column(*children, style={"spacing": separator_height} if separator_height else None)
|
|
1000
|
-
|
|
1001
|
-
sv_props.update(resolve_style(style))
|
|
1002
|
-
return Element("ScrollView", sv_props, [inner], key=key)
|
|
1288
|
+
return ScrollView(inner, style=style, key=key)
|
|
1003
1289
|
|
|
1004
1290
|
# Virtualized: mixed row heights aren't supported in v1, so we
|
|
1005
1291
|
# use the larger of section_header_height and item_height + sep.
|
|
@@ -1032,23 +1318,24 @@ def SectionList(
|
|
|
1032
1318
|
except Exception:
|
|
1033
1319
|
pass
|
|
1034
1320
|
|
|
1035
|
-
|
|
1036
|
-
"
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1321
|
+
return _make_element(
|
|
1322
|
+
"VirtualList",
|
|
1323
|
+
style=style,
|
|
1324
|
+
key=key,
|
|
1325
|
+
count=len(flat),
|
|
1326
|
+
row_height=row_h,
|
|
1327
|
+
mount_row=_mount_row,
|
|
1328
|
+
)
|
|
1042
1329
|
|
|
1043
1330
|
|
|
1044
1331
|
# ======================================================================
|
|
1045
|
-
#
|
|
1332
|
+
# StatusBar / KeyboardAvoidingView / RefreshControl / Picker
|
|
1046
1333
|
# ======================================================================
|
|
1047
1334
|
|
|
1048
1335
|
|
|
1049
1336
|
def StatusBar(
|
|
1050
1337
|
*,
|
|
1051
|
-
|
|
1338
|
+
bar_style: Optional[Literal["light", "dark", "default"]] = None,
|
|
1052
1339
|
background_color: Optional[Color] = None,
|
|
1053
1340
|
hidden: Optional[bool] = None,
|
|
1054
1341
|
key: Optional[str] = None,
|
|
@@ -1059,8 +1346,13 @@ def StatusBar(
|
|
|
1059
1346
|
content but applies its props to the host platform's status bar.
|
|
1060
1347
|
Mount one near the top of your tree.
|
|
1061
1348
|
|
|
1349
|
+
The ``bar_style`` parameter is named separately from the universal
|
|
1350
|
+
``style`` kwarg (which is unused here) to avoid the conflict that
|
|
1351
|
+
``style="light"`` would create with the visual-style dict used
|
|
1352
|
+
elsewhere.
|
|
1353
|
+
|
|
1062
1354
|
Args:
|
|
1063
|
-
|
|
1355
|
+
bar_style: ``"light"`` (light icons over dark backgrounds),
|
|
1064
1356
|
``"dark"`` (dark icons over light backgrounds), or
|
|
1065
1357
|
``"default"`` (system default).
|
|
1066
1358
|
background_color: Color of the status-bar background (Android
|
|
@@ -1069,11 +1361,11 @@ def StatusBar(
|
|
|
1069
1361
|
key: Stable identity for keyed reconciliation.
|
|
1070
1362
|
|
|
1071
1363
|
Returns:
|
|
1072
|
-
An [`Element`][pythonnative.Element] of type
|
|
1364
|
+
An [`Element`][pythonnative.Element] of type ``"StatusBar"``.
|
|
1073
1365
|
"""
|
|
1074
1366
|
props: Dict[str, Any] = {}
|
|
1075
|
-
if
|
|
1076
|
-
props["
|
|
1367
|
+
if bar_style is not None:
|
|
1368
|
+
props["bar_style"] = bar_style
|
|
1077
1369
|
if background_color is not None:
|
|
1078
1370
|
props["background_color"] = background_color
|
|
1079
1371
|
if hidden is not None:
|
|
@@ -1091,8 +1383,8 @@ def KeyboardAvoidingView(
|
|
|
1091
1383
|
|
|
1092
1384
|
Subscribes to the platform-reported keyboard height (via
|
|
1093
1385
|
[`use_keyboard_height`][pythonnative.use_keyboard_height]
|
|
1094
|
-
internally) and applies it as bottom padding so the focused
|
|
1095
|
-
|
|
1386
|
+
internally) and applies it as bottom padding so the focused text
|
|
1387
|
+
input stays visible.
|
|
1096
1388
|
|
|
1097
1389
|
Args:
|
|
1098
1390
|
*children: Children rendered inside the avoiding container.
|
|
@@ -1103,11 +1395,15 @@ def KeyboardAvoidingView(
|
|
|
1103
1395
|
|
|
1104
1396
|
Returns:
|
|
1105
1397
|
An [`Element`][pythonnative.Element] of type
|
|
1106
|
-
|
|
1398
|
+
``"KeyboardAvoidingView"``.
|
|
1107
1399
|
"""
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1400
|
+
return _make_element(
|
|
1401
|
+
"KeyboardAvoidingView",
|
|
1402
|
+
*children,
|
|
1403
|
+
style=style,
|
|
1404
|
+
key=key,
|
|
1405
|
+
behavior=behavior,
|
|
1406
|
+
)
|
|
1111
1407
|
|
|
1112
1408
|
|
|
1113
1409
|
def RefreshControl(
|
|
@@ -1119,16 +1415,16 @@ def RefreshControl(
|
|
|
1119
1415
|
"""Pull-to-refresh spec for [`ScrollView`][pythonnative.ScrollView] / [`FlatList`][pythonnative.FlatList].
|
|
1120
1416
|
|
|
1121
1417
|
Returns a plain dict that should be passed as the
|
|
1122
|
-
``refresh_control=`` prop. Modeled as a dict (not an
|
|
1123
|
-
the host scroll container can
|
|
1124
|
-
child node.
|
|
1418
|
+
``refresh_control=`` prop. Modeled as a dict (not an
|
|
1419
|
+
[`Element`][pythonnative.Element]) so the host scroll container can
|
|
1420
|
+
hold one without it appearing as a child node.
|
|
1125
1421
|
|
|
1126
1422
|
Args:
|
|
1127
1423
|
refreshing: Drive the spinner's visibility from a use_state
|
|
1128
1424
|
value.
|
|
1129
|
-
on_refresh: Callback invoked when the user pulls down past
|
|
1130
|
-
|
|
1131
|
-
|
|
1425
|
+
on_refresh: Callback invoked when the user pulls down past the
|
|
1426
|
+
threshold. Set ``refreshing`` to ``True`` for the duration
|
|
1427
|
+
of the work, then back to ``False`` on completion.
|
|
1132
1428
|
tint_color: Color of the spinner.
|
|
1133
1429
|
|
|
1134
1430
|
Returns:
|
|
@@ -1171,53 +1467,49 @@ def Picker(
|
|
|
1171
1467
|
on_change: Optional[Callable[[Any], None]] = None,
|
|
1172
1468
|
placeholder: str = "Select…",
|
|
1173
1469
|
style: StyleProp = None,
|
|
1470
|
+
accessibility_label: Optional[str] = None,
|
|
1471
|
+
accessibility_hint: Optional[str] = None,
|
|
1472
|
+
accessible: Optional[bool] = None,
|
|
1473
|
+
ref: Optional[Dict[str, Any]] = None,
|
|
1174
1474
|
key: Optional[str] = None,
|
|
1175
1475
|
) -> Element:
|
|
1176
|
-
"""A
|
|
1476
|
+
"""A real native dropdown / select widget.
|
|
1477
|
+
|
|
1478
|
+
Renders a tappable trigger labelled with the selected item; the
|
|
1479
|
+
iOS handler attaches a ``UIMenu`` (system dropdown) and the Android
|
|
1480
|
+
handler uses a native ``Spinner``. Selecting an item fires
|
|
1481
|
+
``on_change(value)``.
|
|
1177
1482
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
[`Alert`][pythonnative.Alert]-style action sheet listing the
|
|
1181
|
-
options. Selecting an option fires ``on_change(value)``.
|
|
1483
|
+
``items`` is an ordered list of ``{"value": Any, "label": str}``
|
|
1484
|
+
entries (``label`` defaults to ``str(value)`` when omitted).
|
|
1182
1485
|
|
|
1183
1486
|
Args:
|
|
1184
1487
|
value: Currently selected value (matched against
|
|
1185
1488
|
``items[i]["value"]``).
|
|
1186
|
-
items:
|
|
1187
|
-
on_change: Callback invoked with the
|
|
1188
|
-
placeholder: Label shown when
|
|
1189
|
-
style: Style dict applied to the trigger
|
|
1489
|
+
items: Selectable options.
|
|
1490
|
+
on_change: Callback invoked with the new value.
|
|
1491
|
+
placeholder: Label shown when no item matches ``value``.
|
|
1492
|
+
style: Style dict applied to the trigger.
|
|
1493
|
+
accessibility_label: Spoken description for screen readers.
|
|
1494
|
+
accessibility_hint: Spoken extra detail (iOS only).
|
|
1495
|
+
accessible: Override whether the element is exposed to AT.
|
|
1496
|
+
ref: Optional ``use_ref()`` dict.
|
|
1190
1497
|
key: Stable identity for keyed reconciliation.
|
|
1191
1498
|
|
|
1192
1499
|
Returns:
|
|
1193
|
-
An [`Element`][pythonnative.Element] of type
|
|
1500
|
+
An [`Element`][pythonnative.Element] of type ``"Picker"``.
|
|
1194
1501
|
"""
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
def _press() -> None:
|
|
1210
|
-
if on_change is not None:
|
|
1211
|
-
try:
|
|
1212
|
-
on_change(item.get("value"))
|
|
1213
|
-
except Exception:
|
|
1214
|
-
pass
|
|
1215
|
-
|
|
1216
|
-
return {"label": str(item.get("label", item.get("value"))), "on_press": _press}
|
|
1217
|
-
|
|
1218
|
-
buttons = [_make_btn(it) for it in items_list]
|
|
1219
|
-
buttons.append({"label": "Cancel", "style": "cancel"})
|
|
1220
|
-
Alert.show(title=placeholder, buttons=buttons, style="action_sheet")
|
|
1221
|
-
|
|
1222
|
-
label_text = Text(selected_label)
|
|
1223
|
-
return Pressable(label_text, on_press=_open, style=style, key=key)
|
|
1502
|
+
return _make_element(
|
|
1503
|
+
"Picker",
|
|
1504
|
+
style=style,
|
|
1505
|
+
ref=ref,
|
|
1506
|
+
key=key,
|
|
1507
|
+
value=value,
|
|
1508
|
+
items=list(items) if items is not None else [],
|
|
1509
|
+
on_change=on_change,
|
|
1510
|
+
placeholder=placeholder,
|
|
1511
|
+
accessibility_label=accessibility_label,
|
|
1512
|
+
accessibility_hint=accessibility_hint,
|
|
1513
|
+
accessible=accessible,
|
|
1514
|
+
_defaults={"accessibility_role": "button"},
|
|
1515
|
+
)
|