Popover content supports setting the maximum width (#180)

Before:

![image](https://github.com/user-attachments/assets/cde8dc35-f59d-474c-8386-b6f666e83249)

After:

![image](https://github.com/user-attachments/assets/d5db1bed-5c2d-4efd-81e4-a0d13e48b035)
This commit is contained in:
ihavecoke 2024-08-27 22:08:50 +08:00 committed by GitHub
parent 7b5efd19bb
commit a5217df13e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 51 deletions

View file

@ -185,10 +185,36 @@ impl Render for PopupStory {
Popover::new("info-top-left")
.trigger(Button::new("info-top-left", cx).label("Top Left"))
.content(|cx| {
cx.new_view(|cx| {
PopoverContent::new(cx, |cx| {
v_flex()
.gap_4()
.child("Hello, this is a Popover.")
.w(px(400.))
.child(Divider::horizontal())
.child(
Button::new("info1", cx)
.label("Yes")
.w(px(80.))
.small(),
)
.into_any()
}).max_w(px(600.))
})
})
),
)
.child(
Popover::new("info-top-right")
.anchor(AnchorCorner::TopRight)
.trigger(Button::new("info-top-right", cx).label("Top Right"))
.content(|cx| {
cx.new_view(|cx|
PopoverContent::new(cx, |cx| {
v_flex()
.gap_4()
.child("Hello, this is a Popover.")
.w_96()
.child("Hello, this is a Popover on the Top Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", cx)
@ -197,29 +223,7 @@ impl Render for PopupStory {
.small(),
)
.into_any()
})
}),
),
)
.child(
Popover::new("info-top-right")
.anchor(AnchorCorner::TopRight)
.trigger(Button::new("info-top-right", cx).label("Top Right"))
.content(|cx| {
PopoverContent::new(cx, |cx| {
v_flex()
.gap_4()
.w_96()
.child("Hello, this is a Popover on the Top Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", cx)
.label("Yes")
.w(px(80.))
.small(),
)
.into_any()
})
}))
}),
),
)
@ -280,19 +284,20 @@ impl Render for PopupStory {
.w(px(300.)),
)
.content(|cx| {
PopoverContent::new(cx, |cx| {
v_flex()
.gap_4()
.child("Hello, this is a Popover on the Bottom Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", cx)
.label("Yes")
.w(px(80.))
.small(),
)
.into_any()
})
cx.new_view(|cx|
PopoverContent::new(cx, |cx| {
v_flex()
.gap_4()
.child("Hello, this is a Popover on the Bottom Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", cx)
.label("Yes")
.w(px(80.))
.small(),
)
.into_any()
}))
}),
),
),

View file

@ -102,7 +102,7 @@ impl Modal {
}
/// Set the maximum width of the modal, defaults to `None`.
pub fn max_width(mut self, max_width: Pixels) -> Self {
pub fn max_w(mut self, max_width: Pixels) -> Self {
self.max_width = Some(max_width);
self
}

View file

@ -16,21 +16,26 @@ pub fn init(_cx: &mut AppContext) {}
pub struct PopoverContent {
focus_handle: FocusHandle,
content: Rc<dyn Fn(&mut WindowContext) -> AnyElement>,
max_width: Option<Pixels>,
}
impl PopoverContent {
pub fn new<B>(cx: &mut WindowContext, content: B) -> View<Self>
pub fn new<B>(cx: &mut WindowContext, content: B) -> Self
where
B: Fn(&mut WindowContext) -> AnyElement + 'static,
{
cx.new_view(|cx| {
let focus_handle = cx.focus_handle();
let focus_handle = cx.focus_handle();
Self {
focus_handle,
content: Rc::new(content),
}
})
Self {
focus_handle,
content: Rc::new(content),
max_width: None,
}
}
pub fn max_w(mut self, max_width: Pixels) -> Self {
self.max_width = Some(max_width);
self
}
}
impl EventEmitter<DismissEvent> for PopoverContent {}
@ -43,7 +48,7 @@ impl FocusableView for PopoverContent {
impl Render for PopoverContent {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
div().p_4().max_w_128().child(self.content.clone()(cx))
div().p_4().when_some(self.max_width, |this, v| this.max_w(v)).child(self.content.clone()(cx))
}
}
@ -309,8 +314,8 @@ impl<M: ManagedView> Element for Popover<M> {
fn paint(
&mut self,
id: Option<&gpui::GlobalElementId>,
_bounds: gpui::Bounds<gpui::Pixels>,
id: Option<&GlobalElementId>,
_bounds: Bounds<Pixels>,
request_layout: &mut Self::RequestLayoutState,
prepaint: &mut Self::PrepaintState,
cx: &mut WindowContext,

View file

@ -113,8 +113,8 @@ impl PopupMenu {
}
/// Set max width of the popup menu, default is 500px
pub fn max_w(mut self, height: impl Into<Pixels>) -> Self {
self.max_width = height.into();
pub fn max_w(mut self, width: impl Into<Pixels>) -> Self {
self.max_width = width.into();
self
}