Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
0.7.1 - 2026-10-13
Fixed
- #51
StyleandTaffyTreecan be used and dropped from any thread. Garbage collecting either one on a thread other than the one that created it no longer reportsRuntimeError: ... is unsendable, but is being dropped on another thread.
0.7.0 - 2026-10-10
Changed
- #50
TaffyTree.absolute_layouts(root)leaves out nodes withdisplay=Display.Niland their whole subtrees, instead of reporting them as zero-sized boxes at their parent's origin. It returns an empty list whenrootor one of its ancestors is hidden. This is a breaking change for callers that expect an entry for every node in the subtree.
0.6.0 - 2026-10-10
Added
- #49 Support for Python 3.15, with release wheels built for it.
- #49
Styleexposes the layout features added in taffy 0.10 through 0.14:direction(Direction.Ltr/Rtl),floatandclear(Float,Clear),contain(Contain),flex_line_count, anditem_is_table/item_is_replaced. - #49
Display.FlowRootandFlexWrap.Balance/BalanceReverse. - #49
Safe alignment and self-relative alignment:
AlignItems.SelfStart/SelfEnd, andSafe*members ofAlignItemsandAlignContent. - #49
size_*andflex_basisaccept the CSS sizing keywordsMIN_CONTENT,MAX_CONTENT,FitContent(limit),FIT_CONTENT(FitContentKeyword), andSTRETCH(Stretch);flex_basisalso acceptsCONTENT(Content). - #49
Grid
repeat()viaRepeat(count, tracks, line_names), withcountanint,AUTO_FILL, orAUTO_FIT. - #49
Named grid lines via
grid_template_row_names/grid_template_column_names, placed withNamedGridLineandNamedGridSpan. - #49
Grid template areas via
grid_template_areas, built withGridTemplateArea/GridTemplateAreasor parsed from CSS strings withGridTemplateAreas.from_strings. - #49
TaffyTree.detailed_layout_info()returns aDetailedGridInfofor grid containers: track positions, line names, item placements, and resolvedgrid-template-*strings, plusresolve_absolute_grid_area()for placing absolutely positioned children. - #49
InvalidFlexLineCount,InvalidRepeat,InvalidGridTemplateArea, andInvalidGridTemplateAreas, raised for values that taffy would otherwise panic on during layout. - #49
Layout.content_box_size(),content_box_x(),content_box_y(),scroll_width(), andscroll_height(). - #49
TaffyTree.remove_children_range(). - #49
Style.fields_set, the names of the explicitly set fields. - #49
TaffyTree.absolute_layouts(root)returns every node in a subtree, in pre-order, with its absolute position and itsLayout. With rounding enabled, each position is the sum of the unrounded locations rounded once, which matches taffy's rounded sizes. Summing roundedlocations yourself can leave 1px gaps or overlaps between siblings, because taffy 0.14 roundslocationrelative to the parent but size in absolute coordinates (taffy#834, fixed upstream in taffy#1189 but not yet released). - #49
TaffyTree.format_tree(root)returns an indented dump of a subtree (each node's id, location, size, and non-default style fields) as a string, unlikeprint_tree, which writes to stdout. - #49 A performance guide for callers that lay out a tree every frame.
- #49
The API reference documents every property, including those of the geometry and
value types, and the module constants (
AUTO,STRETCH,AUTO_FILL, ...).
Changed
- #49 Upgraded taffy from 0.9 to 0.14, which fixes many layout bugs across block, flexbox, and grid and so can change computed layouts. See taffy's changelog.
- #49
Layout.content_sizeis replaced byLayout.scrollable_overflow_rect, aRectwhoseright/bottomare the old width/height. - #49
DimensionValueincludes the new sizing keywords, somargin_*,inset_*,min_size_*, andmax_size_*, which don't accept them, are typedLengthPercentageAutoValueinstead. - #49
Styleequality and hashing take into account which fields were explicitly set, so two styles are equal only if they also merge identically. Styles can no longer be compared by layout alone:Style() == Style(display=Display.Flex)isFalse, thoughFlexis the default.TaffyTree.style(node)marks every field set, so it equals the style passed toset_styleonly if that style set every field. - #49
Style(...)raisesTypeErrorfor an unknown keyword argument instead of ignoring it. - #49
A value of the wrong type for a value union
(in
Style,AvailableSize,Minmax,Repeat,GridPlacement, ...) raises a one-lineTypeErrornaming the accepted types, e.g.expected Length | Percent | Auto, got int. - #49
repr(Style(...))lists the explicitly set fields, as constructor syntax (Style(flex_grow=1.0, border_top=Length(1))). - #49
TaffyTree.set_styledoes nothing when the new style's values equal the node's current style, so the node keeps its cached layout. Usemark_dirtyto force a relayout. - #49
compute_layoutcalls themeasurecallback at most once per node for each distinct(known_size, available_size)input within one call, reusing the earlier result for repeats. This assumes the callback returns the same size for the same inputs within one layout. - #49
Styleconstruction and hashing are faster, every call from Python into waxy has less fixed overhead, andcompute_layoutspends less time around each call to themeasurecallback. Release wheels are built with link-time optimization.
Fixed
- #49
After the
measurecallback raised, the nextcompute_layoutreused the zero sizes from the failed call instead of measuring the affected leaves again. - #49
repr(Layout)shows its location and size asPoint(...)andSize(...)instead of Rust debug output.
Removed
- #49
Rectgeometry methods, since taffy'sRectholds one value per side (like margin, padding and border) rather than a box:width,height,size,contains,top_left,top_right,bottom_left,bottom_right,corners,top_edge,bottom_edge,left_edge,right_edge,points,rows,columns,intersection, iteration, andlen(). - #49
Line.length,Line.contains, iteration, andlen().Lineremains as a start/end pair, as inDetailedGridTracksInfo.positions.
0.5.0 - 2026-04-03
Added
- #45
Rect.intersection(other)returns the intersection rectangle (including edge-touching degenerate intersections), orNoneif the two rectangles do not intersect.
0.4.0 - 2026-03-01
Added
- #36
Pointis now hashable, enabling use in sets and as dictionary keys. - #38
Stylenow supports value equality via==and is hashable. - #39
Rect,Size,Line,GridPlacement, andLayoutare now hashable, enabling use in sets and as dictionary keys. - #39
GridPlacementandLayoutnow support value equality via==.
Changed
- #35 Clarified
Layoutcoordinate system in API docs:locationis relative to the parent's border box origin,sizeis the border box dimensions, and documented allLayoutfields.
Fixed
- #36
Point,KnownSize, andAvailableSize__hash__now correctly normalize-0.0to0.0so that equal objects always hash identically.
0.3.0 - 2026-02-24
Added
- #22 Custom measure functions via an optional
measurekwarg oncompute_layout, enabling proper sizing of leaf nodes based on their content. - #22 Generic node context support:
new_leaf_with_context,set_node_context, andget_node_contextmethods onTaffyTree. - #29 Ergonomic value types (
Length,Percent,Auto,MinContent,MaxContent,Definite,Fraction,FitContent,Minmax,GridLine,GridSpan) as standalone frozen pyclasses with union-based style fields, replacing the previous 1:1 taffy enum representations. - #33
Rect.points(),Rect.rows(), andRect.columns()methods for iterating over integer pixel locations within a rectangle.
Changed
- #30 Slotmap panics from accessing removed nodes are now raised as
InvalidNodeId(TaffyException, KeyError)instead of weird internalpyo3exceptions.
0.2.0 - 2026-02-16
Added
- #19
Stylemerging via__or__—a | bproduces a new style where the right-hand side takes precedence. - #19 Helper methods on geometry objects (
Size,Rect,Point,Line). - #9 Documentation site using mkdocs-material and mkdocstrings.
Changed
- #19 All types except
TaffyTreeare now immutable (#[pyclass(frozen)]).
0.1.0 - 2026-02-14
Initial release — proof-of-concept Python wrapper around taffy.
Added
TaffyTreecore API for building and computing layouts.Stylestruct with all-kwargs constructor.Layoutresult struct.NodeIdwrapper.- Geometry types:
Size,Rect,Point,Line. - Layout enums:
Display,Position,FlexDirection,FlexWrap,AlignItems,AlignContent,GridAutoFlow,Overflow,BoxSizing. - CI with GitHub Actions, release workflow with maturin.