Skip to content

Modifiers

Functional-style modifiers to apply styling, layout, and event handling to widgets.

focusable(enabled=True, on_focus_change=None, on_key=None)

Mark the widget as focusable.

Parameters:

Name Type Description Default
enabled bool

Whether the widget is focusable.

True
on_focus_change Optional[Callable[[bool], None]]

Callback invoked when focus state changes.

None
on_key Optional[Callable[[str, int], bool]]

Callback invoked when a key event occurs while focused. Return True to stop propagation (bubbling).

None
Source code in src/nuiitivet/modifiers/focus.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def focusable(
    enabled: bool = True,
    on_focus_change: Optional[Callable[[bool], None]] = None,
    on_key: Optional[Callable[[str, int], bool]] = None,
) -> FocusableModifier:
    """
    Mark the widget as focusable.

    Args:
        enabled: Whether the widget is focusable.
        on_focus_change: Callback invoked when focus state changes.
        on_key: Callback invoked when a key event occurs while focused.
                Return True to stop propagation (bubbling).
    """
    return FocusableModifier(enabled, on_focus_change, on_key)

modeless(content, *, is_open=None, alignment='bottom-left', anchor='top-left', offset=(0.0, 0.0), transition_spec=None)

Return a modeless overlay modifier anchored to the modified widget.

The overlay is rendered above the widget tree via :meth:Overlay.show_modeless, so it avoids clipping and sits at the top of the Z-order.

Parameters:

Name Type Description Default
content Widget

Widget to display as the popup overlay.

required
is_open Optional['Observable[bool]']

Observable[bool] to control open/close state. When None, an internal observable is created and exposed via :attr:PopupBox.is_open. Callers are responsible for toggling it.

None
alignment AlignmentLike

Reference point on the anchor widget (default "bottom-left").

'bottom-left'
anchor AlignmentLike

Reference point on the content widget to align to (default "top-left").

'top-left'
offset Tuple[float, float]

Additional (dx, dy) offset in screen pixels.

(0.0, 0.0)
transition_spec Optional['TransitionSpec']

Passed directly to :meth:Overlay.show_modeless for enter/exit animation.

None

Returns:

Name Type Description
A PopupModifier

class:PopupModifier suitable for :meth:Widget.modifier.

Example::

# External state control (recommended)
is_open: Observable[bool] = Observable(False)
icon_button.modifier(modeless(Menu(...), is_open=is_open))

# Explicit positioning with animation
icon_button.modifier(
    modeless(
        Menu(...),
        alignment="bottom-left",
        anchor="top-left",
        offset=(0.0, 4.0),
        transition_spec=MaterialTransitions.menu(),
    )
)
Source code in src/nuiitivet/modifiers/popup.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
def modeless(
    content: Widget,
    *,
    is_open: Optional["Observable[bool]"] = None,
    alignment: AlignmentLike = "bottom-left",
    anchor: AlignmentLike = "top-left",
    offset: Tuple[float, float] = (0.0, 0.0),
    transition_spec: Optional["TransitionSpec"] = None,
) -> PopupModifier:
    """Return a modeless overlay modifier anchored to the modified widget.

    The overlay is rendered above the widget tree via :meth:`Overlay.show_modeless`, so
    it avoids clipping and sits at the top of the Z-order.

    Args:
        content: Widget to display as the popup overlay.
        is_open: ``Observable[bool]`` to control open/close state.
            When ``None``, an internal observable is created and exposed via
            :attr:`PopupBox.is_open`. Callers are responsible for toggling it.
        alignment: Reference point on the **anchor widget** (default
            ``"bottom-left"``).
        anchor: Reference point on the **content widget** to align to (default
            ``"top-left"``).
        offset: Additional ``(dx, dy)`` offset in screen pixels.
        transition_spec: Passed directly to :meth:`Overlay.show_modeless` for
            enter/exit animation.

    Returns:
        A :class:`PopupModifier` suitable for :meth:`Widget.modifier`.

    Example::

        # External state control (recommended)
        is_open: Observable[bool] = Observable(False)
        icon_button.modifier(modeless(Menu(...), is_open=is_open))

        # Explicit positioning with animation
        icon_button.modifier(
            modeless(
                Menu(...),
                alignment="bottom-left",
                anchor="top-left",
                offset=(0.0, 4.0),
                transition_spec=MaterialTransitions.menu(),
            )
        )
    """
    return PopupModifier(
        content=content,
        is_open=is_open,
        alignment=alignment,
        anchor=anchor,
        offset=offset,
        transition_spec=transition_spec,
    )

light_dismiss(content, *, is_open=None, alignment='bottom-left', anchor='top-left', offset=(0.0, 0.0), transition_spec=None)

Return a light-dismiss overlay modifier anchored to the modified widget.

Source code in src/nuiitivet/modifiers/popup.py
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
def light_dismiss(
    content: Widget,
    *,
    is_open: Optional["Observable[bool]"] = None,
    alignment: AlignmentLike = "bottom-left",
    anchor: AlignmentLike = "top-left",
    offset: Tuple[float, float] = (0.0, 0.0),
    transition_spec: Optional["TransitionSpec"] = None,
) -> PopupModifier:
    """Return a light-dismiss overlay modifier anchored to the modified widget."""
    return PopupModifier(
        content=content,
        is_open=is_open,
        alignment=alignment,
        anchor=anchor,
        offset=offset,
        transition_spec=transition_spec,
        light_dismiss=True,
    )

opacity(value)

Return a modifier that applies opacity to a widget during paint.

Parameters:

Name Type Description Default
value OpacityLike

Opacity value between 0.0 (transparent) and 1.0 (opaque), or an observable providing opacity.

required
Note

Opacity is paint-only. Layout and hit-testing remain unchanged.

Source code in src/nuiitivet/modifiers/transform.py
379
380
381
382
383
384
385
386
387
388
389
def opacity(value: OpacityLike) -> TransformModifier:
    """Return a modifier that applies opacity to a widget during paint.

    Args:
        value: Opacity value between 0.0 (transparent) and 1.0 (opaque),
            or an observable providing opacity.

    Note:
        Opacity is paint-only. Layout and hit-testing remain unchanged.
    """
    return TransformModifier(opacity=value)

rotate(angle, origin='center')

Return a modifier that rotates a widget during paint.

Parameters:

Name Type Description Default
angle AngleLike

Rotation angle in degrees, or an observable providing degrees.

required
origin OriginLike

Rotation origin. Supported: "center", "top_left", "top_right", "bottom_left", "bottom_right", or a (x, y) tuple in local coords.

'center'
Note

Rotation is paint-only. Layout and hit-testing remain untransformed.

Source code in src/nuiitivet/modifiers/transform.py
339
340
341
342
343
344
345
346
347
348
349
350
def rotate(angle: AngleLike, origin: OriginLike = "center") -> TransformModifier:
    """Return a modifier that rotates a widget during paint.

    Args:
        angle: Rotation angle in degrees, or an observable providing degrees.
        origin: Rotation origin. Supported: "center", "top_left", "top_right",
            "bottom_left", "bottom_right", or a (x, y) tuple in local coords.

    Note:
        Rotation is paint-only. Layout and hit-testing remain untransformed.
    """
    return TransformModifier(rotation=angle, transform_origin=origin)

scale(factor, origin='center')

Return a modifier that scales a widget during paint.

Parameters:

Name Type Description Default
factor ScaleLike

Scale factor (uniform) or (sx, sy) tuple, or an observable.

required
origin OriginLike

Scale origin. Supported: "center", "top_left", "top_right", "bottom_left", "bottom_right", or a (x, y) tuple in local coords.

'center'
Note

Scale is paint-only. Layout and hit-testing remain untransformed.

Source code in src/nuiitivet/modifiers/transform.py
353
354
355
356
357
358
359
360
361
362
363
364
def scale(factor: ScaleLike, origin: OriginLike = "center") -> TransformModifier:
    """Return a modifier that scales a widget during paint.

    Args:
        factor: Scale factor (uniform) or (sx, sy) tuple, or an observable.
        origin: Scale origin. Supported: "center", "top_left", "top_right",
            "bottom_left", "bottom_right", or a (x, y) tuple in local coords.

    Note:
        Scale is paint-only. Layout and hit-testing remain untransformed.
    """
    return TransformModifier(scale=factor, transform_origin=origin)

translate(offset)

Return a modifier that translates a widget during paint.

Parameters:

Name Type Description Default
offset TranslateLike

Translation offset as (dx, dy) tuple, or an observable.

required
Note

Translation is paint-only. Layout and hit-testing remain untransformed.

Source code in src/nuiitivet/modifiers/transform.py
367
368
369
370
371
372
373
374
375
376
def translate(offset: TranslateLike) -> TransformModifier:
    """Return a modifier that translates a widget during paint.

    Args:
        offset: Translation offset as (dx, dy) tuple, or an observable.

    Note:
        Translation is paint-only. Layout and hit-testing remain untransformed.
    """
    return TransformModifier(translation=offset)