diff --git a/RELEASES.md b/RELEASES.md
index 6426ca647..7c9f62e99 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -31,6 +31,7 @@ Example usage change:
### Added
- Support for [CSS Block layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow#elements_participating_in_a_block_formatting_context) has been added. This can be used via the new `Display::Block` variant of the `Display` enum. Note that inline, inline-block and float have *not* been implemented. The use case supported is block container nodes which contain block-level children.
+- Added `insert_child_at_index()` method to the `Taffy` tree. This can be used to insert a child node at any position instead of just the end.
### Removed
diff --git a/src/tree/taffy_tree/tree.rs b/src/tree/taffy_tree/tree.rs
index 40fd70317..060bb3519 100644
--- a/src/tree/taffy_tree/tree.rs
+++ b/src/tree/taffy_tree/tree.rs
@@ -263,6 +263,22 @@ impl Taffy {
Ok(())
}
+ /// Inserts a `child` node at the given `child_index` under the supplied `parent`, shifting all children after it to the right.
+ pub fn insert_child_at_index(&mut self, parent: NodeId, child_index: usize, child: NodeId) -> TaffyResult<()> {
+ let parent_key = parent.into();
+
+ let child_count = self.children[parent_key].len();
+ if child_index > child_count {
+ return Err(TaffyError::ChildIndexOutOfBounds { parent, child_index, child_count });
+ }
+
+ self.parents[child.into()] = Some(parent);
+ self.children[parent_key].insert(child_index, child);
+ self.mark_dirty(parent)?;
+
+ Ok(())
+ }
+
/// Directly sets the `children` of the supplied `parent`
pub fn set_children(&mut self, parent: NodeId, children: &[NodeId]) -> TaffyResult<()> {
let parent_key = parent.into();
@@ -561,6 +577,33 @@ mod tests {
assert_eq!(taffy.child_count(node).unwrap(), 2);
}
+ #[test]
+ fn insert_child_at_index() {
+ let mut taffy = Taffy::new();
+
+ let child0 = taffy.new_leaf(Style::default()).unwrap();
+ let child1 = taffy.new_leaf(Style::default()).unwrap();
+ let child2 = taffy.new_leaf(Style::default()).unwrap();
+
+ let node = taffy.new_leaf(Style::default()).unwrap();
+ assert_eq!(taffy.child_count(node).unwrap(), 0);
+
+ taffy.insert_child_at_index(node, 0, child0).unwrap();
+ assert_eq!(taffy.child_count(node).unwrap(), 1);
+ assert_eq!(taffy.children(node).unwrap()[0], child0);
+
+ taffy.insert_child_at_index(node, 0, child1).unwrap();
+ assert_eq!(taffy.child_count(node).unwrap(), 2);
+ assert_eq!(taffy.children(node).unwrap()[0], child1);
+ assert_eq!(taffy.children(node).unwrap()[1], child0);
+
+ taffy.insert_child_at_index(node, 1, child2).unwrap();
+ assert_eq!(taffy.child_count(node).unwrap(), 3);
+ assert_eq!(taffy.children(node).unwrap()[0], child1);
+ assert_eq!(taffy.children(node).unwrap()[1], child2);
+ assert_eq!(taffy.children(node).unwrap()[2], child0);
+ }
+
#[test]
fn set_children() {
let mut taffy = Taffy::new();