Skip to content

Commit f45b216

Browse files
authored
Update taffy to 0.9 and fix Grid errors #21240 (#21672)
# Objective - #21240 - Update taffy to 0.9.1 and grid placement with start and ends works again. ## Solution I had to make some rather un-ergonomic changes I would like advice on, so I've left comments below. ## Testing - Pending... --- ## Showcase <img width="912" height="740" alt="Screenshot 2025-10-27 at 8 18 50 PM" src="https://github.com/user-attachments/assets/50ec2de2-288f-4f8a-9e20-216bd9d1474d" /> Fixes issue with grid start and ends...
1 parent 95d15f9 commit f45b216

File tree

5 files changed

+161
-116
lines changed

5 files changed

+161
-116
lines changed

crates/bevy_ui/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev", default-fea
3434
] }
3535

3636
# other
37-
taffy = { version = "0.7" }
37+
taffy = { version = "0.9", default-features = false, features = [
38+
"std",
39+
"block_layout",
40+
"flexbox",
41+
"grid",
42+
"content_size",
43+
"taffy_tree",
44+
] }
3845
serde = { version = "1", features = ["derive"], optional = true }
3946
uuid = { version = "1.1", features = ["v4"], optional = true }
4047
thiserror = { version = "2", default-features = false }

crates/bevy_ui/src/layout/convert.rs

Lines changed: 100 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,33 @@ impl Val {
1515
context: &LayoutContext,
1616
) -> taffy::style::LengthPercentageAuto {
1717
match self {
18-
Val::Auto => taffy::style::LengthPercentageAuto::Auto,
19-
Val::Percent(value) => taffy::style::LengthPercentageAuto::Percent(value / 100.),
20-
Val::Px(value) => {
21-
taffy::style::LengthPercentageAuto::Length(context.scale_factor * value)
18+
Val::Auto => style_helpers::auto(),
19+
Val::Percent(value) => style_helpers::percent(value / 100.),
20+
Val::Px(value) => style_helpers::length(context.scale_factor * value),
21+
Val::VMin(value) => {
22+
style_helpers::length(context.physical_size.min_element() * value / 100.)
2223
}
23-
Val::VMin(value) => taffy::style::LengthPercentageAuto::Length(
24-
context.physical_size.min_element() * value / 100.,
25-
),
26-
Val::VMax(value) => taffy::style::LengthPercentageAuto::Length(
27-
context.physical_size.max_element() * value / 100.,
28-
),
29-
Val::Vw(value) => {
30-
taffy::style::LengthPercentageAuto::Length(context.physical_size.x * value / 100.)
31-
}
32-
Val::Vh(value) => {
33-
taffy::style::LengthPercentageAuto::Length(context.physical_size.y * value / 100.)
24+
Val::VMax(value) => {
25+
style_helpers::length(context.physical_size.max_element() * value / 100.)
3426
}
27+
Val::Vw(value) => style_helpers::length(context.physical_size.x * value / 100.),
28+
Val::Vh(value) => style_helpers::length(context.physical_size.y * value / 100.),
3529
}
3630
}
3731

3832
fn into_length_percentage(self, context: &LayoutContext) -> taffy::style::LengthPercentage {
39-
match self.into_length_percentage_auto(context) {
40-
taffy::style::LengthPercentageAuto::Auto => taffy::style::LengthPercentage::Length(0.0),
41-
taffy::style::LengthPercentageAuto::Percent(value) => {
42-
taffy::style::LengthPercentage::Percent(value)
33+
match self {
34+
Val::Auto => style_helpers::length(0.),
35+
Val::Percent(value) => style_helpers::percent(value / 100.),
36+
Val::Px(value) => style_helpers::length(context.scale_factor * value),
37+
Val::VMin(value) => {
38+
style_helpers::length(context.physical_size.min_element() * value / 100.)
4339
}
44-
taffy::style::LengthPercentageAuto::Length(value) => {
45-
taffy::style::LengthPercentage::Length(value)
40+
Val::VMax(value) => {
41+
style_helpers::length(context.physical_size.max_element() * value / 100.)
4642
}
43+
Val::Vw(value) => style_helpers::length(context.physical_size.x * value / 100.),
44+
Val::Vh(value) => style_helpers::length(context.physical_size.y * value / 100.),
4745
}
4846
}
4947

@@ -146,6 +144,7 @@ pub fn from_node(node: &Node, context: &LayoutContext, ignore_border: bool) -> t
146144
.collect::<Vec<_>>(),
147145
grid_row: node.grid_row.into(),
148146
grid_column: node.grid_column.into(),
147+
..Default::default()
149148
}
150149
}
151150

@@ -311,7 +310,7 @@ impl From<GridAutoFlow> for taffy::style::GridAutoFlow {
311310
}
312311
}
313312

314-
impl From<GridPlacement> for taffy::geometry::Line<taffy::style::GridPlacement> {
313+
impl From<GridPlacement> for taffy::geometry::Line<taffy::style::GridPlacement<String>> {
315314
fn from(value: GridPlacement) -> Self {
316315
let span = value.get_span().unwrap_or(1);
317316
match (value.get_start(), value.get_end()) {
@@ -335,77 +334,76 @@ impl From<GridPlacement> for taffy::geometry::Line<taffy::style::GridPlacement>
335334
impl MinTrackSizingFunction {
336335
fn into_taffy(self, context: &LayoutContext) -> taffy::style::MinTrackSizingFunction {
337336
match self {
338-
MinTrackSizingFunction::Px(val) => taffy::style::MinTrackSizingFunction::Fixed(
339-
Val::Px(val).into_length_percentage(context),
340-
),
341-
MinTrackSizingFunction::Percent(val) => taffy::style::MinTrackSizingFunction::Fixed(
342-
Val::Percent(val).into_length_percentage(context),
343-
),
344-
MinTrackSizingFunction::Auto => taffy::style::MinTrackSizingFunction::Auto,
345-
MinTrackSizingFunction::MinContent => taffy::style::MinTrackSizingFunction::MinContent,
346-
MinTrackSizingFunction::MaxContent => taffy::style::MinTrackSizingFunction::MaxContent,
347-
MinTrackSizingFunction::VMin(val) => taffy::style::MinTrackSizingFunction::Fixed(
348-
Val::VMin(val).into_length_percentage(context),
349-
),
350-
MinTrackSizingFunction::VMax(val) => taffy::style::MinTrackSizingFunction::Fixed(
351-
Val::VMax(val).into_length_percentage(context),
352-
),
353-
MinTrackSizingFunction::Vh(val) => taffy::style::MinTrackSizingFunction::Fixed(
354-
Val::Vh(val).into_length_percentage(context),
355-
),
356-
MinTrackSizingFunction::Vw(val) => taffy::style::MinTrackSizingFunction::Fixed(
357-
Val::Vw(val).into_length_percentage(context),
358-
),
337+
MinTrackSizingFunction::Px(val) => Val::Px(val).into_length_percentage(context).into(),
338+
MinTrackSizingFunction::Percent(val) => {
339+
Val::Percent(val).into_length_percentage(context).into()
340+
}
341+
MinTrackSizingFunction::Auto => taffy::style::MinTrackSizingFunction::auto(),
342+
MinTrackSizingFunction::MinContent => {
343+
taffy::style::MinTrackSizingFunction::min_content()
344+
}
345+
MinTrackSizingFunction::MaxContent => {
346+
taffy::style::MinTrackSizingFunction::max_content()
347+
}
348+
MinTrackSizingFunction::VMin(val) => {
349+
Val::VMin(val).into_length_percentage(context).into()
350+
}
351+
MinTrackSizingFunction::VMax(val) => {
352+
Val::VMax(val).into_length_percentage(context).into()
353+
}
354+
MinTrackSizingFunction::Vh(val) => Val::Vh(val).into_length_percentage(context).into(),
355+
MinTrackSizingFunction::Vw(val) => Val::Vw(val).into_length_percentage(context).into(),
359356
}
360357
}
361358
}
362359

363360
impl MaxTrackSizingFunction {
364361
fn into_taffy(self, context: &LayoutContext) -> taffy::style::MaxTrackSizingFunction {
365362
match self {
366-
MaxTrackSizingFunction::Px(val) => taffy::style::MaxTrackSizingFunction::Fixed(
367-
Val::Px(val).into_length_percentage(context),
368-
),
369-
MaxTrackSizingFunction::Percent(val) => taffy::style::MaxTrackSizingFunction::Fixed(
370-
Val::Percent(val).into_length_percentage(context),
371-
),
372-
MaxTrackSizingFunction::Auto => taffy::style::MaxTrackSizingFunction::Auto,
373-
MaxTrackSizingFunction::MinContent => taffy::style::MaxTrackSizingFunction::MinContent,
374-
MaxTrackSizingFunction::MaxContent => taffy::style::MaxTrackSizingFunction::MaxContent,
363+
MaxTrackSizingFunction::Px(val) => Val::Px(val).into_length_percentage(context).into(),
364+
MaxTrackSizingFunction::Percent(val) => {
365+
Val::Percent(val).into_length_percentage(context).into()
366+
}
367+
MaxTrackSizingFunction::Auto => taffy::style::MaxTrackSizingFunction::auto(),
368+
MaxTrackSizingFunction::MinContent => {
369+
taffy::style::MaxTrackSizingFunction::min_content()
370+
}
371+
MaxTrackSizingFunction::MaxContent => {
372+
taffy::style::MaxTrackSizingFunction::max_content()
373+
}
375374
MaxTrackSizingFunction::FitContentPx(val) => {
376-
taffy::style::MaxTrackSizingFunction::FitContent(
377-
Val::Px(val).into_length_percentage(context),
375+
taffy::style::MaxTrackSizingFunction::fit_content_px(
376+
Val::Px(val)
377+
.into_length_percentage(context)
378+
.into_raw()
379+
.value(),
378380
)
379381
}
380382
MaxTrackSizingFunction::FitContentPercent(val) => {
381-
taffy::style::MaxTrackSizingFunction::FitContent(
382-
Val::Percent(val).into_length_percentage(context),
383+
taffy::style::MaxTrackSizingFunction::fit_content_percent(
384+
Val::Percent(val)
385+
.into_length_percentage(context)
386+
.into_raw()
387+
.value(),
383388
)
384389
}
385390
MaxTrackSizingFunction::Fraction(fraction) => {
386-
taffy::style::MaxTrackSizingFunction::Fraction(fraction)
391+
taffy::style::MaxTrackSizingFunction::fr(fraction)
392+
}
393+
MaxTrackSizingFunction::VMin(val) => {
394+
Val::VMin(val).into_length_percentage(context).into()
387395
}
388-
MaxTrackSizingFunction::VMin(val) => taffy::style::MaxTrackSizingFunction::Fixed(
389-
Val::VMin(val).into_length_percentage(context),
390-
),
391-
MaxTrackSizingFunction::VMax(val) => taffy::style::MaxTrackSizingFunction::Fixed(
392-
Val::VMax(val).into_length_percentage(context),
393-
),
394-
MaxTrackSizingFunction::Vh(val) => taffy::style::MaxTrackSizingFunction::Fixed(
395-
Val::Vh(val).into_length_percentage(context),
396-
),
397-
MaxTrackSizingFunction::Vw(val) => taffy::style::MaxTrackSizingFunction::Fixed(
398-
Val::Vw(val).into_length_percentage(context),
399-
),
396+
MaxTrackSizingFunction::VMax(val) => {
397+
Val::VMax(val).into_length_percentage(context).into()
398+
}
399+
MaxTrackSizingFunction::Vh(val) => Val::Vh(val).into_length_percentage(context).into(),
400+
MaxTrackSizingFunction::Vw(val) => Val::Vw(val).into_length_percentage(context).into(),
400401
}
401402
}
402403
}
403404

404405
impl GridTrack {
405-
fn into_taffy_track(
406-
self,
407-
context: &LayoutContext,
408-
) -> taffy::style::NonRepeatedTrackSizingFunction {
406+
fn into_taffy_track(self, context: &LayoutContext) -> taffy::style::TrackSizingFunction {
409407
let min = self.min_sizing_function.into_taffy(context);
410408
let max = self.max_sizing_function.into_taffy(context);
411409
style_helpers::minmax(min, max)
@@ -416,12 +414,12 @@ impl RepeatedGridTrack {
416414
fn clone_into_repeated_taffy_track(
417415
&self,
418416
context: &LayoutContext,
419-
) -> taffy::style::TrackSizingFunction {
417+
) -> taffy::style::GridTemplateComponent<String> {
420418
if self.tracks.len() == 1 && self.repetition == GridTrackRepetition::Count(1) {
421419
let min = self.tracks[0].min_sizing_function.into_taffy(context);
422420
let max = self.tracks[0].max_sizing_function.into_taffy(context);
423421
let taffy_track = style_helpers::minmax(min, max);
424-
taffy::style::TrackSizingFunction::Single(taffy_track)
422+
taffy::GridTemplateComponent::Single(taffy_track)
425423
} else {
426424
let taffy_tracks: Vec<_> = self
427425
.tracks
@@ -436,10 +434,10 @@ impl RepeatedGridTrack {
436434
match self.repetition {
437435
GridTrackRepetition::Count(count) => style_helpers::repeat(count, taffy_tracks),
438436
GridTrackRepetition::AutoFit => {
439-
style_helpers::repeat(taffy::style::GridTrackRepetition::AutoFit, taffy_tracks)
437+
style_helpers::repeat(taffy::style::RepetitionCount::AutoFit, taffy_tracks)
440438
}
441439
GridTrackRepetition::AutoFill => {
442-
style_helpers::repeat(taffy::style::GridTrackRepetition::AutoFill, taffy_tracks)
440+
style_helpers::repeat(taffy::style::RepetitionCount::AutoFill, taffy_tracks)
443441
}
444442
}
445443
}
@@ -537,15 +535,15 @@ mod tests {
537535
);
538536
assert_eq!(
539537
taffy_style.inset.right,
540-
taffy::style::LengthPercentageAuto::Percent(0.5)
538+
taffy::style::LengthPercentageAuto::percent(0.5)
541539
);
542540
assert_eq!(
543541
taffy_style.inset.top,
544-
taffy::style::LengthPercentageAuto::Length(12.)
542+
taffy::style::LengthPercentageAuto::length(12.)
545543
);
546544
assert_eq!(
547545
taffy_style.inset.bottom,
548-
taffy::style::LengthPercentageAuto::Auto
546+
taffy::style::LengthPercentageAuto::auto()
549547
);
550548
assert_eq!(
551549
taffy_style.flex_direction,
@@ -576,23 +574,23 @@ mod tests {
576574
);
577575
assert_eq!(
578576
taffy_style.margin.right,
579-
taffy::style::LengthPercentageAuto::Length(10.)
577+
taffy::style::LengthPercentageAuto::length(10.)
580578
);
581579
assert_eq!(
582580
taffy_style.margin.top,
583-
taffy::style::LengthPercentageAuto::Percent(0.15)
581+
taffy::style::LengthPercentageAuto::percent(0.15)
584582
);
585583
assert_eq!(
586584
taffy_style.margin.bottom,
587-
taffy::style::LengthPercentageAuto::Auto
585+
taffy::style::LengthPercentageAuto::auto()
588586
);
589587
assert_eq!(
590588
taffy_style.padding.left,
591-
taffy::style::LengthPercentage::Percent(0.13)
589+
taffy::style::LengthPercentage::percent(0.13)
592590
);
593591
assert_eq!(
594592
taffy_style.padding.right,
595-
taffy::style::LengthPercentage::Length(21.)
593+
taffy::style::LengthPercentage::length(21.)
596594
);
597595
assert_eq!(
598596
taffy_style.padding.top,
@@ -604,7 +602,7 @@ mod tests {
604602
);
605603
assert_eq!(
606604
taffy_style.border.left,
607-
taffy::style::LengthPercentage::Length(14.)
605+
taffy::style::LengthPercentage::length(14.)
608606
);
609607
assert_eq!(
610608
taffy_style.border.right,
@@ -613,16 +611,16 @@ mod tests {
613611
assert_eq!(taffy_style.border.top, taffy::style::LengthPercentage::ZERO);
614612
assert_eq!(
615613
taffy_style.border.bottom,
616-
taffy::style::LengthPercentage::Percent(0.31)
614+
taffy::style::LengthPercentage::percent(0.31)
617615
);
618616
assert_eq!(taffy_style.flex_grow, 1.);
619617
assert_eq!(taffy_style.flex_shrink, 0.);
620618
assert_eq!(taffy_style.flex_basis, taffy::style::Dimension::ZERO);
621619
assert_eq!(taffy_style.size.width, taffy::style::Dimension::ZERO);
622-
assert_eq!(taffy_style.size.height, taffy::style::Dimension::Auto);
620+
assert_eq!(taffy_style.size.height, taffy::style::Dimension::auto());
623621
assert_eq!(taffy_style.min_size.width, taffy::style::Dimension::ZERO);
624622
assert_eq!(taffy_style.min_size.height, taffy::style::Dimension::ZERO);
625-
assert_eq!(taffy_style.max_size.width, taffy::style::Dimension::Auto);
623+
assert_eq!(taffy_style.max_size.width, taffy::style::Dimension::auto());
626624
assert_eq!(taffy_style.max_size.height, taffy::style::Dimension::ZERO);
627625
assert_eq!(taffy_style.aspect_ratio, None);
628626
assert_eq!(taffy_style.scrollbar_width, 7.);
@@ -643,8 +641,8 @@ mod tests {
643641
assert_eq!(
644642
taffy_style.grid_auto_rows,
645643
vec![
646-
sh::fit_content(taffy::style::LengthPercentage::Length(10.0)),
647-
sh::fit_content(taffy::style::LengthPercentage::Percent(0.25)),
644+
sh::fit_content(taffy::style::LengthPercentage::length(10.0)),
645+
sh::fit_content(taffy::style::LengthPercentage::percent(0.25)),
648646
sh::minmax(sh::length(0.0), sh::fr(2.0)),
649647
]
650648
);
@@ -667,20 +665,19 @@ mod tests {
667665
use taffy::style::LengthPercentage;
668666
let context = LayoutContext::new(2.0, Vec2::new(800., 600.));
669667
let cases = [
670-
(Val::Auto, LengthPercentage::Length(0.)),
671-
(Val::Percent(1.), LengthPercentage::Percent(0.01)),
672-
(Val::Px(1.), LengthPercentage::Length(2.)),
673-
(Val::Vw(1.), LengthPercentage::Length(8.)),
674-
(Val::Vh(1.), LengthPercentage::Length(6.)),
675-
(Val::VMin(2.), LengthPercentage::Length(12.)),
676-
(Val::VMax(2.), LengthPercentage::Length(16.)),
668+
(Val::Auto, LengthPercentage::length(0.)),
669+
(Val::Percent(1.), LengthPercentage::percent(0.01)),
670+
(Val::Px(1.), LengthPercentage::length(2.)),
671+
(Val::Vw(1.), LengthPercentage::length(8.)),
672+
(Val::Vh(1.), LengthPercentage::length(6.)),
673+
(Val::VMin(2.), LengthPercentage::length(12.)),
674+
(Val::VMax(2.), LengthPercentage::length(16.)),
677675
];
678676
for (val, length) in cases {
679-
assert!(match (val.into_length_percentage(&context), length) {
680-
(LengthPercentage::Length(a), LengthPercentage::Length(b))
681-
| (LengthPercentage::Percent(a), LengthPercentage::Percent(b)) =>
682-
(a - b).abs() < 0.0001,
683-
_ => false,
677+
assert!({
678+
let lhs = val.into_length_percentage(&context).into_raw().value();
679+
let rhs = length.into_raw().value();
680+
(lhs - rhs).abs() < 0.0001
684681
});
685682
}
686683
}

crates/bevy_ui/src/layout/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub enum LayoutError {
6666
#[error("Invalid hierarchy")]
6767
InvalidHierarchy,
6868
#[error("Taffy error: {0}")]
69-
TaffyError(taffy::TaffyError),
69+
TaffyError(taffy::tree::TaffyError),
7070
}
7171

7272
/// Updates the UI's layout tree, computes the new layout geometry and then updates the sizes and transforms of all the UI nodes.

0 commit comments

Comments
 (0)