FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
pythonnative/src/pythonnative/components/_base.py at v0.43.1 · pythonnative/pythonnative · GitHub
pythonnative
pythonnative
Repository navigation
Code
Issues
11
(11)
Pull requests
4
(4)
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
pythonnative
/
src
/
pythonnative
/
components
/
_base.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
166 lines (141 loc) · 6 KB
Breadcrumbs
pythonnative
/
src
/
pythonnative
/
components
/
_base.py
Copy path
File metadata and controls
166 lines (141 loc) · 6 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""Shared private helpers behind the built-in element factories.
Every factory in this package routes through :func:`_make_element`, so
style resolution, ``ref`` attachment, ``None``-default dropping, and
forced overrides live in exactly one place. The rich-text span
flattening used by ``Text`` also lives here so it can be shared.
"""
from
typing
import
Any
,
Dict
,
List
,
Optional
,
Tuple
from
..
element
import
Element
from
..
hooks
import
Ref
from
..
style
import
StyleProp
,
resolve_style
,
validate_style_keys
# ======================================================================
# Canonical element builder
# ======================================================================
def
_make_element
(
name
:
str
,
*
children
:
Element
,
style
:
StyleProp
=
None
,
ref
:
Optional
[
Ref
]
=
None
,
key
:
Optional
[
str
]
=
None
,
_defaults
:
Optional
[
Dict
[
str
,
Any
]]
=
None
,
_forced
:
Optional
[
Dict
[
str
,
Any
]]
=
None
,
**
props
:
Any
,
)
->
Element
:
"""Build an [`Element`][pythonnative.Element] of type ``name``.
This is the single helper every built-in factory routes through, so
the cross-cutting concerns that used to be duplicated per component
live in one place:
1. ``style`` is flattened via
[`resolve_style`][pythonnative.style.resolve_style] (list-of-dicts
and ``None`` both handled).
2. ``_defaults`` are filled in for keys not already present (used for
things like ``View``'s default ``flex_direction: "column"`` that
a user style may legitimately override).
3. ``**props`` are merged on top, with ``None`` values *dropped* so
optional kwargs don't pollute the prop dict.
4. ``ref`` is attached under the reserved ``"ref"`` key.
5. ``_forced`` overrides everything (used by ``Column`` / ``Row`` to
lock their flex direction regardless of user style).
Args:
name: Element type name (e.g. ``"Text"``).
*children: Child elements.
style: Style dict, list of dicts, or ``None``.
ref: Optional [`Ref`][pythonnative.Ref] from ``use_ref()``; the
reconciler populates ``ref.current`` with the underlying
native view.
key: Stable identity for keyed reconciliation.
_defaults: Internal: fill-only-if-missing prop defaults.
_forced: Internal: prop overrides applied last.
**props: Per-component props. ``None`` values are dropped.
Returns:
A fresh [`Element`][pythonnative.Element].
"""
from
..
sdk
.
builtins
import
validate_props
validate_props
(
name
,
props
)
out
:
Dict
[
str
,
Any
]
=
dict
(
resolve_style
(
style
))
if
out
:
validate_style_keys
(
out
,
owner
=
name
)
if
_defaults
:
for
k
,
v
in
_defaults
.
items
():
out
.
setdefault
(
k
,
v
)
for
k
,
v
in
props
.
items
():
if
v
is
not
None
:
out
[
k
]
=
v
if
ref
is
not
None
:
out
[
"ref"
]
=
ref
if
_forced
:
out
.
update
(
_forced
)
return
Element
(
name
,
out
,
list
(
children
),
key
=
key
)
# ======================================================================
# RefreshControl attachment
# ======================================================================
REFRESH_CONTROL_TYPE
=
"RefreshControl"
"""Element type produced by [`RefreshControl`][pythonnative.RefreshControl]."""
def
_refresh_control_props
(
control
:
Optional
[
Element
],
*
,
owner
:
str
)
->
Optional
[
Dict
[
str
,
Any
]]:
"""Turn a ``RefreshControl`` element into the ``refresh_control`` wire prop.
Scroll containers hold their refresh control as a prop rather than
a child (the native side attaches a ``UIRefreshControl`` /
``SwipeRefreshLayout`` to the scroll view itself), so the element
is unwrapped here into the flat dict the bridge and the event
extractor expect. Keeping it an element on the Python side means
users build it like every other piece of UI and get a clear error
if they pass the wrong thing.
Raises:
TypeError: If ``control`` is not a ``RefreshControl`` element.
"""
if
control
is
None
:
return
None
if
not
isinstance
(
control
,
Element
)
or
control
.
type
!=
REFRESH_CONTROL_TYPE
:
raise
TypeError
(
f"
{
owner
}
(refresh_control=...) expects pn.RefreshControl(...), got
{
type
(
control
).
__name__
}
:
{
control
!r
}
"
)
return
dict
(
control
.
props
)
# ======================================================================
# Rich text spans
# ======================================================================
# Style keys that can vary per span inside a rich-text run. Layout
# keys are excluded: spans are inline fragments of one paragraph and
# have no boxes of their own.
_SPAN_STYLE_KEYS
=
(
"color"
,
"background_color"
,
"font_size"
,
"font_family"
,
"font_weight"
,
"bold"
,
"italic"
,
"text_decoration"
,
"letter_spacing"
,
)
def
_flatten_text_spans
(
parts
:
Tuple
[
Any
, ...],
inherited
:
Dict
[
str
,
Any
],
)
->
List
[
Dict
[
str
,
Any
]]:
"""Flatten nested ``Text`` parts into a flat list of styled spans.
Strings become spans carrying only the inherited style overrides;
nested ``Text`` elements contribute their own span-style keys
(merged over what they inherit) and recurse into their parts.
"""
spans
:
List
[
Dict
[
str
,
Any
]]
=
[]
for
part
in
parts
:
if
part
is
None
:
continue
if
isinstance
(
part
,
Element
):
props
=
part
.
props
or
{}
child_style
=
dict
(
inherited
)
for
k
in
_SPAN_STYLE_KEYS
:
if
props
.
get
(
k
)
is
not
None
:
child_style
[
k
]
=
props
[
k
]
nested
=
props
.
get
(
"spans"
)
if
nested
:
for
span
in
nested
:
merged
=
dict
(
child_style
)
for
k
in
_SPAN_STYLE_KEYS
:
if
span
.
get
(
k
)
is
not
None
:
merged
[
k
]
=
span
[
k
]
spans
.
append
({
"text"
:
span
.
get
(
"text"
,
""
),
**
merged
})
else
:
spans
.
append
({
"text"
:
str
(
props
.
get
(
"text"
,
""
)),
**
child_style
})
else
:
spans
.
append
({
"text"
:
str
(
part
),
**
inherited
})
return
spans
Back
|
FazBrowse Home
|
New Git URL