PasswordField#
Masked text input for password entry with an optional visibility toggle.
Usage#
Read or set the secret through field.value — always the unmasked string — or
bind it with textsignal=. Users can briefly reveal the input by holding the
eye toggle, and you can drive masking from code with reveal() / hide().
Validation runs against the typed value, exactly like a plain
text field.
Basic#
bs.PasswordField(placeholder="Enter password…")
Label and message#
Use label= for a field title and message= for helper text below.
bs.PasswordField(
label="Password",
placeholder="Enter password…",
message="Must be at least 8 characters.",
)
Required#
Set required=True to mark the field visually and prevent empty submission.
bs.PasswordField(label="Password", required=True)
Visibility toggle#
The eye-icon button is shown by default and reveals the password while held.
Disable it with show_visibility_toggle=False.
bs.PasswordField(label="With toggle", value="secret123")
bs.PasswordField(label="No toggle", value="secret123", show_visibility_toggle=False)
The toggle stays usable on a read-only field — revealing only unmasks the
text, it never changes the value (handy for a generated secret shown for the user
to peek at and copy). A fully disabled field dims it along with everything else.
Programmatic reveal / hide#
Call reveal() and hide() to control masking in code — useful for a
“show password” checkbox pattern.
field = bs.PasswordField(label="Password", show_visibility_toggle=False)
def _toggle_reveal(e):
if checkbox.value:
field.reveal()
else:
field.hide()
checkbox = bs.Checkbox("Show password", on_change=_toggle_reveal)
Custom mask character#
The default mask is '•'. Supply any single character via mask=.
bs.PasswordField(mask="*")
States#
bs.PasswordField(value="secret123", label="Normal")
bs.PasswordField(value="secret123", label="Read only", read_only=True)
bs.PasswordField(value="secret123", label="Disabled", disabled=True)
Reactive binding#
Bind a Signal[str] with textsignal=. The field and signal stay in
sync automatically — typing updates the signal, setting the signal updates
the field.
password = bs.Signal("")
bs.PasswordField(label="Password", textsignal=password)
password.subscribe(lambda v: validate_strength(v))
Submit on Enter#
field = bs.PasswordField(placeholder="Password…")
field.on_submit(lambda e: attempt_login(field.value))
Validation#
Attach rules with add_validation_rule(). Rules run on the configured
trigger ('blur', 'key', or 'manual').
field = bs.PasswordField(label="Password")
field.add_validation_rule(
"stringLength",
message="Password must be at least 8 characters.",
min=8,
trigger="blur",
)
# Explicit validation check
is_valid = field.validate()
Validity is reactive state. field.valid is a Signal[bool] and
field.error a Signal[str] (the current message, "" when valid) — bind
the error to a label and it keeps itself in sync, or gate the submit button off
field.valid:
bs.Label(textsignal=field.error, accent="danger") # shows and clears itself
Note
The full rule taxonomy (stringLength, pattern, custom, …) and
aggregating a whole form’s validity live in the
Validation guide.
Widget sizing#
All widgets accept self-placement kwargs via **kwargs. The parent
container determines which options apply — Column / Row parents use
the layout kwargs below, grid-based parents use grid kwargs.
Column (vertical layout)
Used inside a Column, App, or any other container with a column layout.
Children are arranged top-to-bottom, so horizontal aligns each child across
the width and grow shares the vertical space. (vertical does not apply —
the order of the children sets their top-to-bottom position.)
|
Cross-axis placement of the widget: |
|
Claim and fill a share of the leftover vertical space (the layout
direction). |
|
External spacing in pixels. Accepts an integer (equal on all
sides), a 2-tuple |
|
Horizontal external spacing (left and right). Accepts an integer
or a 2-tuple |
|
Vertical external spacing (top and bottom). Accepts an integer
or a 2-tuple |
Row (horizontal layout)
Used inside a Row or any other container with a row layout. Children are
arranged left-to-right, so vertical aligns each child across the height and
grow shares the horizontal space. (horizontal does not apply — the order
of the children sets their left-to-right position.)
|
Cross-axis placement of the widget: |
|
Claim and fill a share of the leftover horizontal space (the layout
direction). |
|
External spacing in pixels. Accepts an integer (equal on all
sides), a 2-tuple |
|
Horizontal external spacing (left and right). Accepts an integer
or a 2-tuple |
|
Vertical external spacing (top and bottom). Accepts an integer
or a 2-tuple |
Grid
Used inside a Grid container.
|
Zero-based row and column indices. |
|
Number of rows or columns to span. |
|
Horizontal placement within the grid cell: |
|
Vertical placement within the grid cell: |
|
External spacing in pixels. Accepts an integer, a 2-tuple
|
|
Horizontal external spacing. Accepts an integer or |
|
Vertical external spacing. Accepts an integer or |
See also#
TextField — plain text input
NumberField — numeric input with optional range constraints
Validation — the full rule set and form-level validity
Customizing Fields — add buttons or icons inside a field, and reusable field types
Signals — the reactive binding behind
textsignal=
API#
The complete reference for PasswordField lives on the
Widgets API page. At a glance:
A masked text field for password input with an optional visibility toggle. |
Full Example#
1
2with bs.App(title="PasswordField Demo", padding=20, gap=16) as app:
3
4 # Basic
5 bs.Label("Basic", font="heading-sm")
6 bs.PasswordField(placeholder="Enter password…", horizontal="stretch")
7
8 # Label, message, required
9 bs.Label("Label, Message, Required", font="heading-sm")
10 bs.PasswordField(
11 label="Password",
12 placeholder="Enter password…",
13 message="Must be at least 8 characters.",
14 required=True,
15 horizontal="stretch",
16 )
17
18 # Visibility toggle
19 bs.Label("Visibility Toggle", font="heading-sm")
20 with bs.Row(gap=8, horizontal="stretch", grow_items=True):
21 bs.PasswordField(label="With toggle", value="secret123")
22 bs.PasswordField(label="No toggle", value="secret123", show_visibility_toggle=False)
23
24 # Custom mask character
25 bs.Label("Custom Mask Character", font="heading-sm")
26 with bs.Row(gap=8, horizontal="stretch", grow_items=True):
27 bs.PasswordField(value="secret", label="Default (•)")
28 bs.PasswordField(value="secret", label="Asterisk (*)", mask="*")
29
30 # States
31 bs.Label("States", font="heading-sm")
32 with bs.Row(gap=8, horizontal="stretch", grow_items=True):
33 bs.PasswordField(value="secret123", label="Normal")
34 bs.PasswordField(value="secret123", label="Read only", read_only=True)
35 bs.PasswordField(value="secret123", label="Disabled", disabled=True)
36
37app.run()