Skip to content

Changelog

0.1.0

Added

  • #318 Added three text wrapping modes for Text elements: text_wrap_stable (greedy), text_wrap_balance (equalizes line lengths), and text_wrap_pretty (Knuth–Plass DP, minimizes ragged lines). The default remains text_wrap_none (no wrapping). Words longer than the available width are broken with a hyphen.

  • #315 Added canvas(width, height, cells, default) to counterweight.utils for rendering half-block pixel art in a terminal canvas using characters.

  • #315 Documented style merging semantics: styles are additive-only, meaning a field equal to its default value is treated as "not set" and does not override a value from the other style.

  • #305 Added clamp(min_, val, max_) to counterweight.utils for clamping numeric values to a range.

  • #305 Added a PrintPaint autopilot control that prints the current rendered frame as a text grid, useful for debugging layout and rendering output.

  • #305 New functional style utilities: pad(n), pad_x(n), pad_y(n), pad_top(n), etc.; margin(n), margin_x(n), margin_y(n), margin_top(n), etc.; gap(n), gap_width(n), gap_height(n); size(w, h), grow(n); inset_top(n), inset_bottom(n), inset_left(n), inset_right(n); full, full_width, full_height.
  • #305 New style utilities position_absolute and position_relative replace the old absolute(x, y), relative(x, y), and fixed(x, y) helpers. Offsets are now expressed with inset_left(n) / inset_top(n) (and friends) instead of x/y arguments.
  • #305 Color style utilities (e.g. text("slate", 500), border_bg("blue", 300), content_color("green", 500), margin_color("red", 600)) now use functional helpers instead of per-shade constants, greatly reducing the size of the generated utilities module.
  • #123 Add styling for content area background color.

Changed

  • #318 Breaking: Key.Space now has the string value " " instead of "space". Code that matched on the string value (e.g. event.key == "space") must be updated; matching on the enum member (Key.Space) is unaffected.

  • #315 Core types (Style, CellStyle, Div, Text, Chunk, hook types) have been converted from Pydantic models to frozen dataclass instances, removing the runtime Pydantic dependency.

  • #305 The layout engine has been replaced with waxy, a Python binding for the taffy flexbox/grid layout engine. This brings standard CSS flexbox semantics, improved correctness for complex layouts, and eliminates the hand-rolled layout engine.

  • #305 use_rects now returns waxy.Rect objects instead of the removed counterweight.geometry.Rect.

Fixed

  • #125 Mouse wheel scroll events are now captured correctly (they were previously reported as mouse presses). The check-input CLI subcommand is also fixed (was broken by #86).

Removed

  • #305 The following style types have been removed; layout is now configured directly via waxy.Style on the Style.layout field or through the new utility helpers: Border, BorderEdge, Margin, Padding, Content, Span, Typography, Relative, Absolute, Fixed, Flex, Inset. The Style model is now flat: border, margin, padding, typography, and positioning properties are top-level fields rather than nested sub-models.
  • #305 counterweight.geometry.Rect and counterweight.geometry.Edge have been removed; use waxy.Rect instead.
  • #165 Dropped support for Python 3.11 and 3.12. Python 3.13 or later is now required.

0.0.9

Released 2024-02-27

Fixed

  • #121 A change in effect reconciliation introduced in 0.0.8 caused a regression in the behavior of use_effect, where if the setup function returned (i.e., stopped itself), Counterweight would crash when trying to cancel the effect. This now works again.

0.0.8

Released 2024-02-17

Changed

  • #110 Calling a use_state setter with a value equal to the current value of the state no longer emits a SetState event, to avoid triggering unnecessary render cycles.
  • #111 Border healing is now more efficient, especially when there are many non-border characters in the UI.
  • #112 Major, backwards-incompatible changes to how Counterweight handles mouse interactions. The on_mouse_down and on_mouse_up event handlers have been removed; use the new combined on_mouse event handler instead, which receives all mouse events (MouseMoved, MouseDown, and MouseUp). The on_hover style attribute on elements has been removed; use the new use_mouse, use_rects, and use_hovered hooks instead, and calculate the desired style in your component. The goal of these changes is to provide more flexibility and control over mouse interactions to application authors while minimizing the work that Counterweight needs to do while rendering, at the cost of more complex application code for simple cases like detecting hover state.

0.0.7

Released 2024-02-02

Changed

  • #105 Screenshot and Suspend handlers can now be async functions.

0.0.6

Released 2024-01-28

Added

  • #92 Added an inset attribute to Absolute that chooses which corner of the parent's context box to use as the origin for the absolute positioning.
  • #98 Added a z attribute to Flex that controls the stacking order of elements.

Changed

  • #101 The initial_value of use_ref may now be a Callable[[], T] instead of just a T.

Removed

  • #96 Chunks can no longer be created with CellPaints directly.

0.0.5

Released 2024-01-06

Added

  • #86 Added a Suspend control which suspends the Counterweight application while a user-supplied callback function runs. Counterweight will stop controlling the terminal while the callback runs, and will resume when the callback returns. This can be used to run a subprocess that also wants control of the terminal (e.g., a text editor).
  • #88 #90 Implemented Absolute and Fixed positioning, which allow for precise placement of elements outside the normal layout flow.

0.0.4

Released 2023-12-31

Fixed

  • #83 Fixed virtual terminal escape code parsing for mouse tracking when the moues coordinates are large (>94 or so). Mouse tracking should now work for any terminal size. Various Key members that aren't currently parseable have been removed to avoid confusion.

0.0.3

Released 2023-12-30

Changed

  • #71 Controls are now a union over different @dataclasses (instead of an Enum) to allow for more flexibility. The Screenshot control now takes a callback function which will be called with the SVG screenshot as an XML tree.
  • #81 The minimum Python version has been raised to 3.11.2 due to a bug in CPython 3.11.1

0.0.2

Released 2023-12-26

Added

  • #65 Added ability to take an SVG "screenshot" by returning Control.Screenshot from an event handler. The screenshot will be saved to the current working directory as screenshot.svg; more options will be added in the future.
  • #66 Added "border healing": when border elements for certain border types are adjacent to each other and appear as if they should "join up", but don't because they belong to different elements, they will now be joined up.

Changed

  • Various namespaces moved around to make more sense (especially in documentation) and separate concerns better as part of #68.

0.0.1

Released 2023-12-19