Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: eliminate undesired impact of transparent components on layout #53

Merged
merged 1 commit into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/iocraft/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl InstantiatedComponent {
pub fn update(
&mut self,
context: &mut UpdateContext<'_>,
unattached_child_node_ids: Option<&mut Vec<NodeId>>,
unattached_child_node_ids: &mut Vec<NodeId>,
component_context_stack: &mut ContextStack<'_>,
props: AnyProps,
) {
Expand Down
33 changes: 33 additions & 0 deletions packages/iocraft/src/components/box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,18 @@ mod tests {
use crate::prelude::*;
use indoc::indoc;

#[derive(Default, Props)]
pub struct MyTextProps {
pub content: String,
}

#[component]
pub fn MyText<'a>(props: &MyTextProps) -> impl Into<AnyElement<'a>> {
element! {
Text(content: &props.content)
}
}

#[test]
fn test_box() {
assert_eq!(element!(Box).to_string(), "");
Expand Down Expand Up @@ -591,5 +603,26 @@ mod tests {
└──────────────────┘
"},
);

// regression test for https://github.com/ccbrown/iocraft/issues/52
assert_eq!(
element! {
Box(width: 20, border_style: BorderStyle::Single, row_gap: 1, flex_direction: FlexDirection::Column) {
Text(content: "foo")
MyText(content: "bar")
MyText(content: "baz")
}
}
.to_string(),
indoc! {"
┌──────────────────┐
│foo │
│ │
│bar │
│ │
│baz │
└──────────────────┘
"},
);
}
}
30 changes: 22 additions & 8 deletions packages/iocraft/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use futures::{
stream::{Stream, StreamExt},
};
use std::io;
use taffy::{AvailableSpace, Layout, NodeId, Point, Size, Style, TaffyTree};
use taffy::{AvailableSpace, Display, Layout, NodeId, Point, Size, Style, TaffyTree};

pub(crate) struct UpdateContext<'a> {
terminal: Option<&'a mut Terminal>,
Expand All @@ -33,7 +33,7 @@ pub struct ComponentUpdater<'a, 'b: 'a, 'c: 'a> {
node_id: NodeId,
transparent_layout: bool,
children: &'a mut Components,
unattached_child_node_ids: Option<&'a mut Vec<NodeId>>,
unattached_child_node_ids: &'a mut Vec<NodeId>,
context: &'a mut UpdateContext<'b>,
component_context_stack: &'a mut ContextStack<'c>,
}
Expand All @@ -42,7 +42,7 @@ impl<'a, 'b, 'c> ComponentUpdater<'a, 'b, 'c> {
pub(crate) fn new(
node_id: NodeId,
children: &'a mut Components,
unattached_child_node_ids: Option<&'a mut Vec<NodeId>>,
unattached_child_node_ids: &'a mut Vec<NodeId>,
context: &'a mut UpdateContext<'b>,
component_context_stack: &'a mut ContextStack<'c>,
) -> Self {
Expand Down Expand Up @@ -123,6 +123,18 @@ impl<'a, 'b, 'c> ComponentUpdater<'a, 'b, 'c> {
/// children will effectively be direct descendants of the parent of the current component for
/// layout purposes.
pub fn set_transparent_layout(&mut self, transparent_layout: bool) {
if transparent_layout && !self.transparent_layout {
self.context
.layout_engine
.set_style(
self.node_id,
Style {
display: Display::None,
..Default::default()
},
)
.expect("we should be able to set the style");
}
self.transparent_layout = transparent_layout;
}

Expand All @@ -142,9 +154,7 @@ impl<'a, 'b, 'c> ComponentUpdater<'a, 'b, 'c> {

let mut direct_child_node_ids = Vec::new();
let child_node_ids = if self.transparent_layout {
self.unattached_child_node_ids
.as_deref_mut()
.unwrap_or(&mut direct_child_node_ids)
&mut self.unattached_child_node_ids
} else {
&mut direct_child_node_ids
};
Expand Down Expand Up @@ -175,7 +185,7 @@ impl<'a, 'b, 'c> ComponentUpdater<'a, 'b, 'c> {
};
component.update(
self.context,
Some(child_node_ids),
child_node_ids,
component_context_stack,
child.props_mut(),
);
Expand Down Expand Up @@ -315,6 +325,7 @@ impl<'a> Tree<'a> {
max_width: Option<usize>,
terminal: Option<&mut Terminal>,
) -> RenderOutput {
let mut wrapper_child_node_ids = vec![self.root_component.node_id()];
let did_clear_terminal_output = {
let mut context = UpdateContext {
terminal,
Expand All @@ -324,12 +335,15 @@ impl<'a> Tree<'a> {
let mut component_context_stack = ContextStack::root(&mut self.system_context);
self.root_component.update(
&mut context,
None,
&mut wrapper_child_node_ids,
&mut component_context_stack,
self.root_component_props.borrow(),
);
context.did_clear_terminal_output
};
self.layout_engine
.set_children(self.wrapper_node_id, &wrapper_child_node_ids)
.expect("we should be able to set the children");

self.layout_engine
.compute_layout_with_measure(
Expand Down
Loading