diff --git a/AGENTS.md b/AGENTS.md index d281d30..1855b6f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -153,7 +153,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - A row that holds text beside fixed parts lets the text give way: the text takes `flex_1().min_w_0()` and an `Ellipsis`; counts, icons, dates and chevrons take `flex_none`. A label that must stay whole wraps in that block instead, as `forms::Checkbox`'s does. - A mark over a text field reads the field at paint time, from a canvas laid over it (`collab::RemoteCursor`): by then `TextInput::bounds_for` holds this frame's layout, and a still page never renders again to catch up. - A callback field holds a named `type` alias; clippy's type_complexity rejects `Option>`. A chapter shares one alias per shape. -- A component that fills its container takes no width on its root: a block or a flex column stretches it. Percents fill badly in taffy 0.9. `w_full` in a flex column that a block measures by content keeps its content's width: taffy lays the column out once at unknown width and keeps that layout when the width comes out the same. `min_w_full` resolves against a block's outer width, padding and all (`forms::FormField`). In a flex row the host gives it `flex_1`; as a window's root it sits in a `size_full` box. A root centered under a cap keeps `w_full`, since `mx_auto` needs a width to fill (`layout::Container`). A row that hands a text field a `flex_1` share keeps `w_full` too: stretched without a width, taffy 0.9 can keep a pass that laid the share at no width, and the field draws nothing (`forms::Input`, `InputGroup`, `TagInput`). +- A component that fills its container takes no width on its root: a block or a flex column stretches it. Percents fill badly in taffy 0.9. `w_full` in a flex column that a block measures by content keeps its content's width: taffy lays the column out once at unknown width and keeps that layout when the width comes out the same. `min_w_full` resolves against a block's outer width, padding and all (`forms::FormField`). In a flex row the host gives it `flex_1`; as a window's root it sits in a `size_full` box. A root centered under a cap keeps `w_full`, since `mx_auto` needs a width to fill (`layout::Container`); so does one that keeps a ratio, since taffy 0.9 follows a ratio from a set width, not a stretch (`layout::AspectRatio`). A row that hands a text field a `flex_1` share keeps `w_full` too: stretched without a width, taffy 0.9 can keep a pass that laid the share at no width, and the field draws nothing (`forms::Input`, `InputGroup`, `TagInput`). - A field's `Highlight` sets color, wash, weight, slant and strike per span; measuring and painting share one set of runs, so wrapped heights match. - A block editor keeps one undo for the document: text and structure together, as snapshots through `forms::History`; it takes Undo and Redo before its fields do. - gpui calls focus listeners only while the window is active. A test that needs focus events activates its window with `window.activate_window()`. diff --git a/TASKS.md b/TASKS.md index 5f29fff..9ec4b8f 100644 --- a/TASKS.md +++ b/TASKS.md @@ -472,3 +472,4 @@ Per-component lines live in `tasks/`. Tags there: | T43b | 2 | PASS | | | T43c | 1 | FAIL | the audit left fg_subtle on active and every syntax color unread, both under 4.5:1; the viewer left out avatar and container sizes while claiming every token | | T43c | 2 | PASS | the AGENTS.md decision narrowed to the pairs the audit holds, in the pass commit | +| T44a | 1 | FAIL | twelve roots in nine components still said w_full: a root held in a variable, a match arm or an animation passed the sweep | diff --git a/examples/gallery/pages/buttons/actions.rs b/examples/gallery/pages/buttons/actions.rs index 2dedeb9..8cf8487 100644 --- a/examples/gallery/pages/buttons/actions.rs +++ b/examples/gallery/pages/buttons/actions.rs @@ -171,6 +171,7 @@ pub fn action_bar(cx: &App) -> impl IntoElement + use<> { ) .child( ActionBar::new() + .w_full() .child(Button::new("bar-cancel", "Cancel").variant(ButtonVariant::Ghost)) .child(Button::new("bar-save", "Save changes").primary()), ), diff --git a/src/buttons/bars.rs b/src/buttons/bars.rs index 8045120..b6164fb 100644 --- a/src/buttons/bars.rs +++ b/src/buttons/bars.rs @@ -69,8 +69,7 @@ impl RenderOnce for ActionBar { .border_color(colors.border) .shadow(theme.elevation(Elevation::Floating)) } else { - bar.w_full() - .justify_end() + bar.justify_end() .px_4() .py_3() .bg(colors.surface) diff --git a/src/chat/composer.rs b/src/chat/composer.rs index 5d0b05b..23f4c2b 100644 --- a/src/chat/composer.rs +++ b/src/chat/composer.rs @@ -364,7 +364,6 @@ impl RenderOnce for PromptInput { let body = div() .id(self.id.clone()) .relative() - .w_full() .flex() .flex_col() .gap_2() diff --git a/src/chat/message.rs b/src/chat/message.rs index 68d12ad..d539eca 100644 --- a/src/chat/message.rs +++ b/src/chat/message.rs @@ -238,7 +238,6 @@ impl RenderOnce for MessageBubble { .children(self.body); match self.role { Role::System => div() - .w_full() .flex() .justify_center() .py_1() @@ -247,7 +246,6 @@ impl RenderOnce for MessageBubble { .child(body.text_size(theme.text_size(TextSize::Xs))) .into_any_element(), Role::User => div() - .w_full() .flex() .gap_3() .child( @@ -282,7 +280,6 @@ impl RenderOnce for MessageBubble { .children(self.avatar) .into_any_element(), Role::Assistant | Role::Error => div() - .w_full() .flex() .gap_3() .children(self.avatar) diff --git a/src/forms/files.rs b/src/forms/files.rs index 53f7732..6dae1c7 100644 --- a/src/forms/files.rs +++ b/src/forms/files.rs @@ -298,7 +298,6 @@ impl RenderOnce for DropZone { .flex_col() .items_center() .gap_2() - .w_full() .px_6() .py_8() .rounded(theme.radius(Radius::Lg)) diff --git a/src/media/listen.rs b/src/media/listen.rs index 305a226..3baf317 100644 --- a/src/media/listen.rs +++ b/src/media/listen.rs @@ -115,7 +115,7 @@ impl RenderOnce for Playlist { let theme = cx.theme(); let (muted, lead) = (theme.colors.fg_muted, theme.icon_size(IconSize::Lg)); let small = theme.text_size(TextSize::Sm); - let mut list = SelectableList::new(self.id.clone()).w_full(); + let mut list = SelectableList::new(self.id.clone()); for (ix, track) in self.tracks.into_iter().enumerate() { let now = self.current.as_ref() == Some(&track.key); let mark = if now { diff --git a/src/navigation/tabs.rs b/src/navigation/tabs.rs index a0136a3..35c9580 100644 --- a/src/navigation/tabs.rs +++ b/src/navigation/tabs.rs @@ -237,7 +237,7 @@ impl RenderOnce for Tabs { move |panel, t| if turn == 0 { panel } else { panel.opacity(t) }, ) }); - let frame = div().id(self.id).flex().gap_4().w_full(); + let frame = div().id(self.id).flex().gap_4(); match placement { TabPlacement::Top => frame.flex_col().child(strip).children(panel), TabPlacement::Bottom => frame.flex_col().children(panel).child(strip), diff --git a/src/primitives/divider.rs b/src/primitives/divider.rs index 077786c..ea554cb 100644 --- a/src/primitives/divider.rs +++ b/src/primitives/divider.rs @@ -39,12 +39,11 @@ impl RenderOnce for Divider { return line().h_full().border_l_1(); } match self.label { - None => line().w_full().border_t_1(), + None => line().border_t_1(), Some(label) => div() .flex() .items_center() .gap_3() - .w_full() .child(line().flex_1().border_t_1()) .child( div() diff --git a/src/shell/chrome.rs b/src/shell/chrome.rs index 392f570..7bba17f 100644 --- a/src/shell/chrome.rs +++ b/src/shell/chrome.rs @@ -376,7 +376,6 @@ impl RenderOnce for TitleBar { .flex_none() .items_center() .gap_2() - .w_full() .h(theme.titlebar_height()) .bg(theme.colors.bg) .border_b_1()