v3.2.0

Textualize/textualv3.2.0May 2, 2025by willmcgugan

AI Summary

Introduced compact widgets, breakpoint support, toggle_class reactives, and CSS pseudo-classes, with a breaking change to RadioSet sizing.

Key Highlights

  • Added compact parameter and reactive to Button, Input, etc.
  • Added toggle_class parameter to reactives
  • Added :first-child and :last-child pseudo classes
  • Added breakpoint support as a first-class feature

Breaking Changes

  • RadioSet now has a default width of 1fr

New Features

  • Added HORIZONTAL_BREAKPOINTS and VERTICAL_BREAKPOINTS to App and Screen

Full Release Notes

There are a few interesting features in this release.

Many widgets have grown a `compact` reactive. If you set this to `True` then the widget will have a compact (borderless) style.

Reactives have a new `toggle_class` attribute, that toggles a TCSS classname according to the truthyness of its value. If that sounds complicated, it really isn't in practice. Let's see it in action:

```python
class MyWidget(Widget):
    compact = reactive(False, toggle_class="-textual-compact")
```

This adds a boolean attribute to the widget. If you set `compact=True` then it will add the class "-textual-compact". If you set `compact=False` it will remove the class. Simples.

We also have breakpoint support, so you can build UIs that adjust to the dimensions of the screen. This was always possible, but it was a pattern before. Now it is a first class feature. See the [breakpoints.py](https://github.com/Textualize/textual/blob/main/examples/breakpoints.py) example.

We also have two new pseudo classes: `:first-child` and `:last-child`, which have the same meaning as browser CSS. Contributed by @sponsfreixes

There is one potential breaking change. `RadioSet` now has a default width of 1fr, meaning they will take up the full available space. This makes RadioSet size like other widgets. If you want the original behavior, then set the width to "auto"

## [3.2.0] - 2025-05-02

### Fixed

- Fixed `OptionList` causing excessive redrawing https://github.com/Textualize/textual/pull/5766
- Log messages could be written to stdout when there was no app, which could happen when using run_async or threads. Now they will be suppressed, unless the env var `TEXTUAL_DEBUG` is set https://github.com/Textualize/textual/pull/5782

### Added

- Added `:first-child` and `:last-child` pseudo classes https://github.com/Textualize/textual/pull/5776
- Added `toggle_class` parameter to reactives https://github.com/Textualize/textual/pull/5778
- Added `compact` parameter and reactive to `Button`, `Input`, `ToggleButton`, `RadioSet`, `OptionList`, `TextArea` https://github.com/Textualize/textual/pull/5778
- Added `HORIZONTAL_BREAKPOINTS` and `VERTICAL_BREAKPOINTS` to `App` and `Screen` https://github.com/Textualize/textual/pull/5779

### Changed

- `RadioSet` now has a default width of `1fr` https://github.com/Textualize/textual/pull/5778