diff --git a/crates/go_to_line2/src/go_to_line.rs b/crates/go_to_line2/src/go_to_line.rs index 13d283ecff..6ae58124d8 100644 --- a/crates/go_to_line2/src/go_to_line.rs +++ b/crates/go_to_line2/src/go_to_line.rs @@ -1,4 +1,8 @@ -use gpui::{actions, div, px, red, AppContext, Div, Render, Styled, ViewContext, VisualContext}; +use gpui::{ + actions, div, px, red, AppContext, Div, ParentElement, Render, Styled, ViewContext, + VisualContext, +}; +use ui::modal; use workspace::ModalRegistry; actions!(Toggle); @@ -27,9 +31,8 @@ pub struct GoToLine; impl Render for GoToLine { type Element = Div; - fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { - dbg!("rendering GoToLine"); - div().bg(red()).w(px(100.0)).h(px(100.0)) + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + modal(cx).child(div().bg(red()).w(px(100.0)).h(px(100.0))) } } diff --git a/crates/gpui2/src/styled.rs b/crates/gpui2/src/styled.rs index 06be0368c0..2bf3006d41 100644 --- a/crates/gpui2/src/styled.rs +++ b/crates/gpui2/src/styled.rs @@ -4,7 +4,7 @@ use crate::{ SharedString, StyleRefinement, Visibility, }; use crate::{BoxShadow, TextStyleRefinement}; -use smallvec::smallvec; +use smallvec::{smallvec, SmallVec}; pub trait Styled { fn style(&mut self) -> &mut StyleRefinement; @@ -290,24 +290,11 @@ pub trait Styled { /// Sets the box shadow of the element. /// [Docs](https://tailwindcss.com/docs/box-shadow) - fn shadow(mut self) -> Self + fn shadow(mut self, shadows: SmallVec<[BoxShadow; 2]>) -> Self where Self: Sized, { - self.style().box_shadow = Some(smallvec![ - BoxShadow { - color: hsla(0., 0., 0., 0.1), - offset: point(px(0.), px(1.)), - blur_radius: px(3.), - spread_radius: px(0.), - }, - BoxShadow { - color: hsla(0., 0., 0., 0.1), - offset: point(px(0.), px(1.)), - blur_radius: px(2.), - spread_radius: px(-1.), - } - ]); + self.style().box_shadow = Some(shadows); self } diff --git a/crates/ui2/src/components.rs b/crates/ui2/src/components.rs index 857d0f1042..706918c080 100644 --- a/crates/ui2/src/components.rs +++ b/crates/ui2/src/components.rs @@ -3,6 +3,7 @@ mod button; mod checkbox; mod context_menu; mod details; +mod elevated_surface; mod facepile; mod icon; mod icon_button; @@ -30,6 +31,7 @@ pub use button::*; pub use checkbox::*; pub use context_menu::*; pub use details::*; +pub use elevated_surface::*; pub use facepile::*; pub use icon::*; pub use icon_button::*; diff --git a/crates/ui2/src/components/elevated_surface.rs b/crates/ui2/src/components/elevated_surface.rs new file mode 100644 index 0000000000..9070ac4428 --- /dev/null +++ b/crates/ui2/src/components/elevated_surface.rs @@ -0,0 +1,28 @@ +use gpui::{div, hsla, point, px, BoxShadow, Div}; + +use crate::{prelude::*, v_stack}; + +/// Create an elevated surface. +/// +/// Must be used inside of a relative parent element +pub fn elevated_surface(level: ElevationIndex, cx: &mut ViewContext) -> Div { + let colors = cx.theme().colors(); + + // let shadow = BoxShadow { + // color: hsla(0., 0., 0., 0.1), + // offset: point(px(0.), px(1.)), + // blur_radius: px(3.), + // spread_radius: px(0.), + // }; + + v_stack() + .rounded_lg() + .bg(colors.elevated_surface_background) + .border() + .border_color(colors.border) + .shadow(level.shadow()) +} + +pub fn modal(cx: &mut ViewContext) -> Div { + elevated_surface(ElevationIndex::ModalSurfaces, cx) +} diff --git a/crates/ui2/src/elevation.rs b/crates/ui2/src/elevation.rs index 3218f3f5f1..0dd51e3314 100644 --- a/crates/ui2/src/elevation.rs +++ b/crates/ui2/src/elevation.rs @@ -1,3 +1,6 @@ +use gpui::{hsla, point, px, BoxShadow}; +use smallvec::{smallvec, SmallVec}; + #[doc = include_str!("elevation.md")] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Elevation { @@ -17,8 +20,8 @@ pub enum ElevationIndex { } impl ElevationIndex { - pub fn usize(&self) -> usize { - match *self { + pub fn z_index(self) -> u32 { + match self { ElevationIndex::AppBackground => 0, ElevationIndex::UISurface => 100, ElevationIndex::ElevatedSurface => 200, @@ -27,6 +30,26 @@ impl ElevationIndex { ElevationIndex::DraggedElement => 900, } } + + pub fn shadow(self) -> SmallVec<[BoxShadow; 2]> { + match self { + ElevationIndex::AppBackground => smallvec![], + + ElevationIndex::UISurface => smallvec![BoxShadow { + color: hsla(0., 0., 0., 0.12), + offset: point(px(0.), px(1.)), + blur_radius: px(3.), + spread_radius: px(0.), + }], + + _ => smallvec![BoxShadow { + color: hsla(0., 0., 0., 0.32), + offset: point(px(1.), px(3.)), + blur_radius: px(12.), + spread_radius: px(0.), + }], + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/crates/workspace2/src/modal_layer.rs b/crates/workspace2/src/modal_layer.rs index 01f940273a..5f8b9b0345 100644 --- a/crates/workspace2/src/modal_layer.rs +++ b/crates/workspace2/src/modal_layer.rs @@ -1,8 +1,8 @@ use std::{any::TypeId, sync::Arc}; use gpui::{ - div, AnyView, AppContext, DispatchPhase, Div, ParentElement, Render, StatelessInteractive, - View, ViewContext, + div, AnyView, AppContext, Component, DispatchPhase, Div, ParentElement, Render, + StatelessInteractive, Styled, View, ViewContext, }; use crate::Workspace; @@ -69,22 +69,47 @@ impl ModalLayer { Self { open_modal: None } } + // Workspace + // - ModalLayer parent + // - - container + // - - - modal + // - - - content of the modal + // - - content of the workspace + + // app + // workspace + // container some layer that contains all modals and is 100% wide and high + // modal (this has a shadow, some witdht) + // whatever + pub fn render(&self, workspace: &Workspace, cx: &ViewContext) -> Div { - let mut div = div(); - - // div, c workspace.toggle_modal()div.on_action()) { - // - // } - - // for (type_id, action) in cx.global::().registered_modals.iter() { - // div = div.useful_on_action(*type_id, action) - // } + let mut parent = div().relative(); for (_, action) in cx.global::().registered_modals.iter() { - div = (action)(div); + parent = (action)(parent); } - div.children(self.open_modal.clone()) + parent.when_some(self.open_modal.as_ref(), |parent, open_modal| { + let container1 = div() + .absolute() + .size_full() + .top_0() + .left_0() + .right_0() + .bottom_0(); + + // transparent layer + let container2 = div() + .flex() + .h_96() + .justify_center() + .size_full() + .relative() + .top_20() + .z_index(400); + + parent.child(container1.child(container2.child(open_modal.clone()))) + }) } } diff --git a/styles/src/style_tree/assistant.ts b/styles/src/style_tree/assistant.ts index 08297731bb..d261a23bcd 100644 --- a/styles/src/style_tree/assistant.ts +++ b/styles/src/style_tree/assistant.ts @@ -23,7 +23,7 @@ export default function assistant(): any { const theme = useTheme() const interactive_role = ( - color: StyleSets + color: StyleSets, ): Interactive => { return interactive({ base: { @@ -94,7 +94,7 @@ export default function assistant(): any { margin: { left: 8, right: 18 }, color: foreground(theme.highest, "positive"), width: 12, - } + }, }, retrieve_context: toggleable({ base: interactive({ @@ -106,7 +106,8 @@ export default function assistant(): any { background: background(theme.highest, "on"), corner_radius: 2, border: { - width: 1., color: background(theme.highest, "on") + width: 1, + color: background(theme.highest, "on"), }, margin: { left: 2 }, padding: { @@ -118,17 +119,45 @@ export default function assistant(): any { }, state: { hovered: { - ...text(theme.highest, "mono", "variant", "hovered"), - background: background(theme.highest, "on", "hovered"), + ...text( + theme.highest, + "mono", + "variant", + "hovered", + ), + background: background( + theme.highest, + "on", + "hovered", + ), border: { - width: 1., color: background(theme.highest, "on", "hovered") + width: 1, + color: background( + theme.highest, + "on", + "hovered", + ), }, }, clicked: { - ...text(theme.highest, "mono", "variant", "pressed"), - background: background(theme.highest, "on", "pressed"), + ...text( + theme.highest, + "mono", + "variant", + "pressed", + ), + background: background( + theme.highest, + "on", + "pressed", + ), border: { - width: 1., color: background(theme.highest, "on", "pressed") + width: 1, + color: background( + theme.highest, + "on", + "pressed", + ), }, }, }, @@ -143,11 +172,19 @@ export default function assistant(): any { border: border(theme.highest, "accent"), }, hovered: { - background: background(theme.highest, "accent", "hovered"), + background: background( + theme.highest, + "accent", + "hovered", + ), border: border(theme.highest, "accent", "hovered"), }, clicked: { - background: background(theme.highest, "accent", "pressed"), + background: background( + theme.highest, + "accent", + "pressed", + ), border: border(theme.highest, "accent", "pressed"), }, }, @@ -163,7 +200,8 @@ export default function assistant(): any { background: background(theme.highest, "on"), corner_radius: 2, border: { - width: 1., color: background(theme.highest, "on") + width: 1, + color: background(theme.highest, "on"), }, padding: { left: 4, @@ -174,17 +212,45 @@ export default function assistant(): any { }, state: { hovered: { - ...text(theme.highest, "mono", "variant", "hovered"), - background: background(theme.highest, "on", "hovered"), + ...text( + theme.highest, + "mono", + "variant", + "hovered", + ), + background: background( + theme.highest, + "on", + "hovered", + ), border: { - width: 1., color: background(theme.highest, "on", "hovered") + width: 1, + color: background( + theme.highest, + "on", + "hovered", + ), }, }, clicked: { - ...text(theme.highest, "mono", "variant", "pressed"), - background: background(theme.highest, "on", "pressed"), + ...text( + theme.highest, + "mono", + "variant", + "pressed", + ), + background: background( + theme.highest, + "on", + "pressed", + ), border: { - width: 1., color: background(theme.highest, "on", "pressed") + width: 1, + color: background( + theme.highest, + "on", + "pressed", + ), }, }, }, @@ -199,11 +265,19 @@ export default function assistant(): any { border: border(theme.highest, "accent"), }, hovered: { - background: background(theme.highest, "accent", "hovered"), + background: background( + theme.highest, + "accent", + "hovered", + ), border: border(theme.highest, "accent", "hovered"), }, clicked: { - background: background(theme.highest, "accent", "pressed"), + background: background( + theme.highest, + "accent", + "pressed", + ), border: border(theme.highest, "accent", "pressed"), }, }, diff --git a/styles/src/style_tree/status_bar.ts b/styles/src/style_tree/status_bar.ts index b279bbac14..5ced6b0d7b 100644 --- a/styles/src/style_tree/status_bar.ts +++ b/styles/src/style_tree/status_bar.ts @@ -78,33 +78,33 @@ export default function status_bar(): any { padding: { top: 2, bottom: 2, left: 6, right: 6 }, }, container_warning: diagnostic_status_container, - container_error: diagnostic_status_container + container_error: diagnostic_status_container, }, state: { hovered: { icon_color_ok: foreground(layer, "on"), container_ok: { - background: background(layer, "hovered") + background: background(layer, "hovered"), }, container_warning: { - background: background(layer, "hovered") + background: background(layer, "hovered"), }, container_error: { - background: background(layer, "hovered") + background: background(layer, "hovered"), }, }, clicked: { icon_color_ok: foreground(layer, "on"), container_ok: { - background: background(layer, "pressed") + background: background(layer, "pressed"), }, container_warning: { - background: background(layer, "pressed") + background: background(layer, "pressed"), }, container_error: { - background: background(layer, "pressed") - } - } + background: background(layer, "pressed"), + }, + }, }, }), panel_buttons: { diff --git a/styles/src/themes/rose-pine/rose-pine-dawn.ts b/styles/src/themes/rose-pine/rose-pine-dawn.ts index c78f1132dd..9642107bdb 100644 --- a/styles/src/themes/rose-pine/rose-pine-dawn.ts +++ b/styles/src/themes/rose-pine/rose-pine-dawn.ts @@ -31,7 +31,7 @@ export const theme: ThemeConfig = { color.muted, color.subtle, color.text, - ].reverse() + ].reverse(), ) .domain([0, 0.35, 0.45, 0.65, 0.7, 0.8, 0.9, 1]), red: color_ramp(chroma(color.love)),