Jason Lee 2024-06-29 23:49:59 +08:00 committed by GitHub
parent 709ee29fe0
commit 93779164f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 348 additions and 248 deletions

View file

@ -60,7 +60,6 @@ There have a part of UI components from [Zed](https://github.com/zed-industries/
- title_bar - title_bar
- picker - picker
- popover (based on popup_menu)
> I think we can discuss them with Zed team to change the license to MIT or Apache License for share to community. > I think we can discuss them with Zed team to change the license to MIT or Apache License for share to community.

View file

@ -1,73 +1,147 @@
use gpui::{div, px, Element, IntoElement, ParentElement as _, Render, Styled as _, ViewContext}; use gpui::{
div, px, AnchorCorner, AppContext, DismissEvent, Element, EventEmitter, FocusHandle,
FocusableView, IntoElement, MouseButton, ParentElement as _, Render, Styled as _, View,
ViewContext, VisualContext, WindowContext,
};
use ui::{ use ui::{
button::{Button, ButtonSize}, button::{Button, ButtonSize},
divider::Divider, divider::Divider,
h_flex, h_flex,
input::TextInput,
popover::{Popover, PopoverContent}, popover::{Popover, PopoverContent},
v_flex, v_flex, Clickable,
}; };
use crate::story_case; use crate::story_case;
pub struct PopoverStory {} struct Form {
input1: View<TextInput>,
}
impl Form {
fn new(cx: &mut WindowContext) -> View<Self> {
cx.new_view(|cx| Self {
input1: cx.new_view(|cx| TextInput::new(cx)),
})
}
}
impl FocusableView for Form {
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
self.input1.focus_handle(cx)
}
}
impl EventEmitter<DismissEvent> for Form {}
impl Render for Form {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
v_flex()
.gap_4()
.size_full()
.child("This is a form container.")
.child(self.input1.clone())
.child(
Button::primary("submit", "Submit")
.on_click(cx.listener(|_, _, cx| cx.emit(DismissEvent))),
)
}
}
pub struct PopoverStory {
form: View<Form>,
}
impl PopoverStory { impl PopoverStory {
pub fn new(_: &mut ViewContext<Self>) -> Self { pub fn new(cx: &mut ViewContext<Self>) -> Self {
Self {} let form = Form::new(cx);
Self { form }
} }
} }
impl Render for PopoverStory { impl Render for PopoverStory {
fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement { fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
let form = self.form.clone();
story_case( story_case(
"Popover", "Popover",
"Displays rich content in a portal, triggered by a button.", "Displays rich content in a portal, triggered by a button.",
) )
.child( .child(
h_flex().items_center().justify_between().child( h_flex()
v_flex().gap_4().child( .items_center()
Popover::new("info-top-left") .justify_between()
.trigger(Button::new("info", "Top Left").width(px(300.))) .child(
.content(|cx| { v_flex().gap_4().child(
PopoverContent::new(|_| { Popover::new("info-top-left")
v_flex().gap_4().child("Hello, this is a Popover.") .trigger(Button::new("info-top-left", "Top Left"))
.content(|cx| {
PopoverContent::new(cx, |_| {
v_flex()
.gap_4()
.child("Hello, this is a Popover.")
.child(Divider::horizontal())
.child(
Button::new("info1", "Yes")
.width(px(80.))
.size(ButtonSize::Small),
)
.into_any()
})
}),
),
)
.child(
Popover::new("info-top-right")
.anchor(AnchorCorner::TopRight)
.trigger(Button::new("info-top-right", "Top Right"))
.content(|cx| {
PopoverContent::new(cx, |_| {
v_flex()
.gap_4()
.child("Hello, this is a Popover on the Top Right.")
.child(Divider::horizontal()) .child(Divider::horizontal())
.child( .child(
Button::new("info1", "Yes") Button::new("info1", "Yes")
.width(px(80.)) .width(px(80.))
.size(ButtonSize::Small) .size(ButtonSize::Small),
).into_any() )
}, .into_any()
cx, })
) }),
}) ),
).child("This is background text, should be covered by Popover.")
).child(
Popover::new("info-top-right")
.trigger(Button::new("info", "Top Right").width(px(300.)))
.content(|cx| {
PopoverContent::new(|_|
"Hello, this is a Popover.\nYou can click outside to dissmis.".into_any(),
cx,
)
}),
)
) )
.child( .child(
div().absolute().bottom_4().left_0().w_full().h_10().child( div().absolute().bottom_4().left_0().w_full().h_10().child(
h_flex().items_center().justify_between().child( h_flex()
Popover::new("info-bottom-left") .items_center()
.trigger(Button::new("pop", "Bottom Left").width(px(300.))) .justify_between()
.content(|cx| { .child(
PopoverContent::new(|_| "这是另外一个 Popover。\n你可以点击外部来关闭。\nThis popover has position bottom_4().left_0().w_full().h_10().".into_any(), cx) Popover::new("info-bottom-left")
})).child( .anchor(AnchorCorner::BottomLeft)
Popover::new("info-bottom-right") .trigger(Button::new("pop", "Popup with Form").width(px(300.)))
.trigger(Button::new("pop", "Bottom Right").width(px(300.))) .content(move |_| form.clone()),
.content(|cx| { )
PopoverContent::new(|_| "这是另外一个 Popover。\n你可以点击外部来关闭。\nThis popover has position bottom_4().left_0().w_full().h_10().".into_any(), cx) .child(
})) Popover::new("info-bottom-right")
.anchor(AnchorCorner::BottomRight)
.mouse_button(MouseButton::Right)
.trigger(Button::new("pop", "Mouse Right Click").width(px(300.)))
.content(|cx| {
PopoverContent::new(cx, |_| {
v_flex()
.gap_4()
.child("Hello, this is a Popover on the Bottom Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", "Yes")
.width(px(80.))
.size(ButtonSize::Small),
)
.into_any()
})
}),
),
), ),
) )
} }

View file

@ -65,6 +65,18 @@ impl Button {
} }
} }
pub fn primary(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
Self::new(id, label).style(ButtonStyle::Primary)
}
pub fn danger(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
Self::new(id, label).style(ButtonStyle::Danger)
}
pub fn small(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
Self::new(id, label).size(ButtonSize::Small)
}
pub fn width(mut self, width: impl Into<DefiniteLength>) -> Self { pub fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
self.width = Some(width.into()); self.width = Some(width.into());
self self

View file

@ -1,21 +1,17 @@
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use crate::theme::ActiveTheme; use crate::{theme::ActiveTheme, Selectable, StyledExt as _};
use crate::{Clickable, Selectable, StyledExt};
use gpui::{ use gpui::{
actions, anchored, deferred, div, prelude::FluentBuilder as _, AnchorCorner, AnyElement, actions, anchored, deferred, div, prelude::FluentBuilder, AnchorCorner, AnyElement, AppContext,
AppContext, Bounds, DismissEvent, Element, ElementId, EventEmitter, FocusHandle, FocusableView, Bounds, DismissEvent, DispatchPhase, Element, ElementId, EventEmitter, FocusHandle,
HitboxId, InteractiveElement, IntoElement, LayoutId, ManagedView, ParentElement, Pixels, FocusableView, GlobalElementId, Hitbox, InteractiveElement, IntoElement, LayoutId, ManagedView,
Render, Style, Styled, View, ViewContext, VisualContext, WindowContext, MouseButton, MouseDownEvent, ParentElement as _, Pixels, Point, Render, Style, Styled as _,
View, ViewContext, VisualContext, WindowContext,
}; };
use gpui::{point, px, DispatchPhase, MouseDownEvent, Point};
actions!(popover, [Dismiss]); actions!(popover, [Open, Dismiss]);
pub trait Triggerable: IntoElement + Clickable + Selectable + 'static {} pub fn init(_cx: &AppContext) {}
impl<T: IntoElement + Clickable + Selectable + 'static> Triggerable for T {}
pub fn init(_cx: &mut AppContext) {}
pub struct PopoverContent { pub struct PopoverContent {
focus_handle: FocusHandle, focus_handle: FocusHandle,
@ -23,7 +19,7 @@ pub struct PopoverContent {
} }
impl PopoverContent { impl PopoverContent {
pub fn new<B>(content: B, cx: &mut WindowContext) -> View<Self> pub fn new<B>(cx: &mut WindowContext, content: B) -> View<Self>
where where
B: Fn(&mut WindowContext) -> AnyElement + 'static, B: Fn(&mut WindowContext) -> AnyElement + 'static,
{ {
@ -47,102 +43,72 @@ impl FocusableView for PopoverContent {
impl Render for PopoverContent { impl Render for PopoverContent {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
div() div().child(self.content.clone()(cx))
.id("test")
// .on_action(cx.listener(Self::dissmiss))
.absolute()
.mt_2()
.elevation_2(cx)
.bg(cx.theme().popover)
.border_1()
.border_color(cx.theme().border)
.p_4()
.max_w_128()
.w_80()
.occlude()
.child(self.content.clone()(cx))
.on_mouse_down_out(cx.listener(|_, _, cx| cx.emit(DismissEvent)))
} }
} }
pub struct Popover<M: ManagedView> { pub struct Popover<M: ManagedView> {
id: ElementId, id: ElementId,
anchor: AnchorCorner, anchor: AnchorCorner,
trigger_builder: Option< trigger: Option<Box<dyn FnOnce(&WindowContext) -> AnyElement + 'static>>,
Box< content: Option<Rc<dyn Fn(&mut WindowContext) -> View<M> + 'static>>,
dyn FnOnce( mouse_button: MouseButton,
Rc<RefCell<Option<View<M>>>>,
Option<Rc<dyn Fn(&mut WindowContext) -> View<M> + 'static>>,
) -> AnyElement
+ 'static,
>,
>,
content_builder: Option<Rc<dyn Fn(&mut WindowContext) -> View<M> + 'static>>,
} }
impl<M: ManagedView> Popover<M> { impl<M> Popover<M>
where
M: ManagedView,
{
pub fn new(id: impl Into<ElementId>) -> Self { pub fn new(id: impl Into<ElementId>) -> Self {
Self { Self {
id: id.into(), id: id.into(),
trigger_builder: None,
content_builder: None,
anchor: AnchorCorner::TopLeft, anchor: AnchorCorner::TopLeft,
trigger: None,
content: None,
mouse_button: MouseButton::Left,
} }
} }
pub fn trigger<T: Triggerable>(mut self, trigger: T) -> Self {
self.trigger_builder = Some(Box::new(|popover, builder| {
let open = popover.borrow_mut().is_some();
trigger
.selected(open)
.when_some(builder, |this, builder| {
this.on_click(move |_, cx| Self::show_popover(&builder, &popover, cx))
})
.into_any_element()
}));
self
}
pub fn content(
mut self,
content_builder: impl Fn(&mut WindowContext) -> View<M> + 'static,
) -> Self {
self.content_builder = Some(Rc::new(content_builder));
self
}
/// anchor defines which corner of the menu to anchor to the attachment point
/// (by default the cursor position, but see attach)
pub fn anchor(mut self, anchor: AnchorCorner) -> Self { pub fn anchor(mut self, anchor: AnchorCorner) -> Self {
self.anchor = anchor; self.anchor = anchor;
self self
} }
fn show_popover( /// Set the mouse button to trigger the popover, default is `MouseButton::Left`.
builder: &Rc<dyn Fn(&mut WindowContext) -> View<M> + 'static>, pub fn mouse_button(mut self, mouse_button: MouseButton) -> Self {
popover: &Rc<RefCell<Option<View<M>>>>, self.mouse_button = mouse_button;
cx: &mut WindowContext, self
) { }
let new_popover = (builder)(cx);
let popover_cloned = popover.clone(); pub fn trigger<T>(mut self, trigger: T) -> Self
let prev_focus_handle = cx.focused(); where
T: Selectable + IntoElement + 'static,
{
self.trigger = Some(Box::new(|_| trigger.into_any_element()));
self
}
cx.subscribe(&new_popover, move |modal, _: &DismissEvent, cx| { /// Set the content of the popover.
if modal.focus_handle(cx).contains_focused(cx) { ///
if let Some(prev_focus_handle) = prev_focus_handle.as_ref() { /// The `content` is a closure that returns an `AnyElement`.
cx.focus(prev_focus_handle); pub fn content<C>(mut self, content: C) -> Self
} where
} C: Fn(&mut WindowContext) -> View<M> + 'static,
*popover_cloned.borrow_mut() = None; {
cx.refresh(); self.content = Some(Rc::new(content));
}) self
.detach(); }
cx.focus_view(&new_popover); fn render_trigger(&mut self, cx: &mut WindowContext) -> impl IntoElement {
*popover.borrow_mut() = Some(new_popover); let base = div().id("popover-trigger");
cx.refresh();
if self.trigger.is_none() {
return base;
}
let trigger = self.trigger.take().unwrap();
base.child((trigger)(cx)).into_element()
} }
fn resolved_corner(&self, bounds: Bounds<Pixels>) -> Point<Pixels> { fn resolved_corner(&self, bounds: Bounds<Pixels>) -> Point<Pixels> {
@ -155,45 +121,27 @@ impl<M: ManagedView> Popover<M> {
.corner(bounds) .corner(bounds)
} }
fn resolved_offset(&self, _cx: &WindowContext) -> Point<Pixels> { fn with_element_state<R>(
let offset = px(0.); &mut self,
match self.anchor { id: &GlobalElementId,
AnchorCorner::TopRight | AnchorCorner::BottomRight => point(offset, px(0.)), cx: &mut WindowContext,
AnchorCorner::TopLeft | AnchorCorner::BottomLeft => point(-offset, px(0.)), f: impl FnOnce(&mut Self, &mut PopoverElementState<M>, &mut WindowContext) -> R,
} ) -> R {
cx.with_optional_element_state::<PopoverElementState<M>, _>(
Some(id),
|element_state, cx| {
let mut element_state = element_state.unwrap().unwrap_or_default();
let result = f(self, &mut element_state, cx);
(result, Some(element_state))
},
)
} }
} }
pub struct PopoverElementState<M> { impl<M> IntoElement for Popover<M>
trigger_bounds: Option<Bounds<Pixels>>, where
popover: Rc<RefCell<Option<View<M>>>>, M: ManagedView,
} {
impl<M> Clone for PopoverElementState<M> {
fn clone(&self) -> Self {
Self {
popover: Rc::clone(&self.popover),
trigger_bounds: self.trigger_bounds,
}
}
}
impl<M> Default for PopoverElementState<M> {
fn default() -> Self {
Self {
popover: Rc::default(),
trigger_bounds: None,
}
}
}
pub struct PopoverFrameState {
trigger_layout_id: Option<LayoutId>,
trigger_element: Option<AnyElement>,
popover_element: Option<AnyElement>,
}
impl<M: ManagedView> IntoElement for Popover<M> {
type Element = Self; type Element = Self;
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Element {
@ -201,9 +149,37 @@ impl<M: ManagedView> IntoElement for Popover<M> {
} }
} }
pub struct PopoverElementState<M> {
trigger_layout_id: Option<LayoutId>,
popover_element: Option<AnyElement>,
trigger_element: Option<AnyElement>,
content_view: Rc<RefCell<Option<View<M>>>>,
/// Trigger bounds for positioning the popover.
trigger_bounds: Option<Bounds<Pixels>>,
}
impl<M> Default for PopoverElementState<M> {
fn default() -> Self {
Self {
trigger_layout_id: None,
popover_element: None,
trigger_element: None,
content_view: Rc::new(RefCell::new(None)),
trigger_bounds: None,
}
}
}
pub struct PrepaintState {
hitbox: Hitbox,
/// Trigger bounds for limit a rect to handle mouse click.
trigger_bounds: Option<Bounds<Pixels>>,
}
impl<M: ManagedView> Element for Popover<M> { impl<M: ManagedView> Element for Popover<M> {
type RequestLayoutState = PopoverFrameState; type RequestLayoutState = PopoverElementState<M>;
type PrepaintState = Option<HitboxId>;
type PrepaintState = PrepaintState;
fn id(&self) -> Option<ElementId> { fn id(&self) -> Option<ElementId> {
Some(self.id.clone()) Some(self.id.clone())
@ -211,109 +187,150 @@ impl<M: ManagedView> Element for Popover<M> {
fn request_layout( fn request_layout(
&mut self, &mut self,
global_id: Option<&gpui::GlobalElementId>, id: Option<&gpui::GlobalElementId>,
cx: &mut WindowContext, cx: &mut WindowContext,
) -> (gpui::LayoutId, Self::RequestLayoutState) { ) -> (gpui::LayoutId, Self::RequestLayoutState) {
cx.with_element_state( self.with_element_state(id.unwrap(), cx, |this, element_state, cx| {
global_id.unwrap(), let mut trigger_element = this.render_trigger(cx).into_any_element();
|element_state: Option<PopoverElementState<M>>, cx| { let trigger_layout_id = trigger_element.request_layout(cx);
let element_state = element_state.unwrap_or_default();
let mut popover_layout_id = None; let mut popover_layout_id = None;
let popover_element = element_state.popover.borrow_mut().as_mut().map(|popover| { let mut popover_element = None;
let mut anchored = anchored().snap_to_window().anchor(self.anchor);
if let Some(trigger_bounds) = element_state.trigger_bounds {
anchored = anchored.position(
self.resolved_corner(trigger_bounds) + self.resolved_offset(cx),
);
}
let mut element = deferred(anchored.child(popover.clone()))
.with_priority(1)
.into_any();
popover_layout_id = Some(element.request_layout(cx)); if let Some(content_view) = element_state.content_view.borrow_mut().as_mut() {
element let content_view_mut = element_state.content_view.clone();
});
let mut trigger_element = self.trigger_builder.take().map(|builder| { let mut anchored = anchored().snap_to_window().anchor(this.anchor);
builder(element_state.popover.clone(), self.content_builder.clone()) if let Some(trigger_bounds) = element_state.trigger_bounds {
}); anchored = anchored.position(this.resolved_corner(trigger_bounds));
}
let trigger_layout_id = trigger_element let mut element = deferred(
.as_mut() anchored.child(
.map(|trigger_element| trigger_element.request_layout(cx)); div()
.occlude()
let layout_id = cx.request_layout( .map(|d| match this.anchor {
Style::default(), AnchorCorner::TopLeft | AnchorCorner::TopRight => d.mt_2(),
popover_layout_id.into_iter().chain(trigger_layout_id), AnchorCorner::BottomLeft | AnchorCorner::BottomRight => d.mb_2(),
); })
.elevation_2(cx)
( .bg(cx.theme().popover)
( .border_1()
layout_id, .border_color(cx.theme().border)
PopoverFrameState { .p_4()
trigger_layout_id, .max_w_128()
trigger_element, .occlude()
popover_element, .on_mouse_down_out(move |_, cx| {
}, // Update the element_state.content_view to `None`,
// so that the `paint`` method will not paint it.
*content_view_mut.borrow_mut() = None;
cx.refresh();
})
.child(content_view.clone()),
), ),
element_state,
) )
}, .with_priority(1)
) .into_any();
popover_layout_id = Some(element.request_layout(cx));
popover_element = Some(element);
}
let layout_id = cx.request_layout(
Style::default(),
popover_layout_id.into_iter().chain(Some(trigger_layout_id)),
);
(
layout_id,
PopoverElementState {
trigger_layout_id: Some(trigger_layout_id),
popover_element: popover_element,
trigger_element: Some(trigger_element),
..Default::default()
},
)
})
} }
fn prepaint( fn prepaint(
&mut self, &mut self,
global_id: Option<&gpui::GlobalElementId>, _id: Option<&gpui::GlobalElementId>,
_: gpui::Bounds<gpui::Pixels>, _bounds: gpui::Bounds<gpui::Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
cx: &mut WindowContext, cx: &mut WindowContext,
) -> Self::PrepaintState { ) -> Self::PrepaintState {
if let Some(element) = &mut request_layout.trigger_element { if let Some(element) = &mut request_layout.trigger_element {
element.prepaint(cx); element.prepaint(cx);
} }
if let Some(element) = &mut request_layout.popover_element { if let Some(element) = &mut request_layout.popover_element {
element.prepaint(cx); element.prepaint(cx);
} }
request_layout.trigger_layout_id.map(|layout_id| { let trigger_bounds = request_layout
let bounds = cx.layout_bounds(layout_id); .trigger_layout_id
cx.with_element_state(global_id.unwrap(), |element_state, _cx| { .map(|id| cx.layout_bounds(id));
let mut element_state: PopoverElementState<M> = element_state.unwrap(); let hitbox = cx.insert_hitbox(trigger_bounds.unwrap_or_default(), false);
element_state.trigger_bounds = Some(bounds);
((), element_state)
});
cx.insert_hitbox(bounds, false).id PrepaintState {
}) trigger_bounds,
hitbox,
}
} }
fn paint( fn paint(
&mut self, &mut self,
_: Option<&gpui::GlobalElementId>, id: Option<&gpui::GlobalElementId>,
_: gpui::Bounds<gpui::Pixels>, _bounds: gpui::Bounds<gpui::Pixels>,
request_layout: &mut Self::RequestLayoutState, request_layout: &mut Self::RequestLayoutState,
trigger_hitbox: &mut Option<HitboxId>, prepaint: &mut Self::PrepaintState,
cx: &mut WindowContext, cx: &mut WindowContext,
) { ) {
if let Some(element) = &mut request_layout.trigger_element { self.with_element_state(id.unwrap(), cx, |this, element_state, cx| {
element.paint(cx); element_state.trigger_bounds = prepaint.trigger_bounds;
}
if let Some(element) = &mut request_layout.popover_element { if let Some(mut element) = request_layout.trigger_element.take() {
element.paint(cx); element.paint(cx);
if let Some(hitbox) = *trigger_hitbox {
// Mouse-downing outside the menu dismisses it, so we don't
// want a click on the toggle to re-open it.
cx.on_mouse_event(move |_: &MouseDownEvent, phase, cx| {
if phase == DispatchPhase::Bubble && hitbox.is_hovered(cx) {
cx.stop_propagation()
}
})
} }
}
if let Some(mut element) = request_layout.popover_element.take() {
element.paint(cx);
return;
}
let Some(content_build) = this.content.take() else {
return;
};
let old_content_view = element_state.content_view.clone();
let hitbox_id = prepaint.hitbox.id;
let mouse_button = this.mouse_button;
// When mouse click down in the trigger bounds, open the popover.
cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
if phase == DispatchPhase::Bubble
&& event.button == mouse_button
&& hitbox_id.is_hovered(cx)
{
let new_content_view = (content_build)(cx);
let old_content_view1 = old_content_view.clone();
let previous_focus_handle = cx.focused();
cx.subscribe(&new_content_view, move |modal, _: &DismissEvent, cx| {
if modal.focus_handle(cx).contains_focused(cx) {
if let Some(previous_focus_handle) = previous_focus_handle.as_ref() {
cx.focus(previous_focus_handle);
}
}
*old_content_view1.borrow_mut() = None;
cx.refresh();
})
.detach();
cx.focus_view(&new_content_view);
*old_content_view.borrow_mut() = Some(new_content_view);
cx.refresh();
}
});
});
} }
} }

View file

@ -38,13 +38,11 @@ impl ElevationIndex {
} }
} }
fn elevated<E: Styled>(this: E, cx: &mut WindowContext, index: ElevationIndex) -> E { fn elevated<E: Styled>(this: E, cx: &WindowContext, index: ElevationIndex) -> E {
let theme = cx.theme(); this.bg(cx.theme().popover)
this.bg(theme.popover)
.rounded(px(8.)) .rounded(px(8.))
.border_1() .border_1()
.border_color(theme.border) .border_color(cx.theme().border)
.shadow(index.shadow()) .shadow(index.shadow())
} }
@ -65,17 +63,17 @@ pub trait StyledExt: Styled + Sized {
} }
/// Located above the app background /// Located above the app background
fn elevation_1(self, cx: &mut WindowContext) -> Self { fn elevation_1(self, cx: &WindowContext) -> Self {
elevated(self, cx, ElevationIndex::Surface) elevated(self, cx, ElevationIndex::Surface)
} }
/// Appear above most UI elements /// Appear above most UI elements
fn elevation_2(self, cx: &mut WindowContext) -> Self { fn elevation_2(self, cx: &WindowContext) -> Self {
elevated(self, cx, ElevationIndex::PopoverSurface) elevated(self, cx, ElevationIndex::PopoverSurface)
} }
// Above all other UI elements and are located above the wash layer // Above all other UI elements and are located above the wash layer
fn elevation_3(self, cx: &mut WindowContext) -> Self { fn elevation_3(self, cx: &WindowContext) -> Self {
elevated(self, cx, ElevationIndex::ModalSurface) elevated(self, cx, ElevationIndex::ModalSurface)
} }
} }