MODAL
This commit is contained in:
parent
1e6a0f1c7b
commit
acab2f9003
9 changed files with 207 additions and 65 deletions
|
@ -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<Self>;
|
||||
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
dbg!("rendering GoToLine");
|
||||
div().bg(red()).w(px(100.0)).h(px(100.0))
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
modal(cx).child(div().bg(red()).w(px(100.0)).h(px(100.0)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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::*;
|
||||
|
|
28
crates/ui2/src/components/elevated_surface.rs
Normal file
28
crates/ui2/src/components/elevated_surface.rs
Normal file
|
@ -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<V: 'static>(level: ElevationIndex, cx: &mut ViewContext<V>) -> Div<V> {
|
||||
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<V>(cx: &mut ViewContext<V>) -> Div<V> {
|
||||
elevated_surface(ElevationIndex::ModalSurfaces, cx)
|
||||
}
|
|
@ -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)]
|
||||
|
|
|
@ -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<Workspace>) -> Div<Workspace> {
|
||||
let mut div = div();
|
||||
|
||||
// div, c workspace.toggle_modal()div.on_action()) {
|
||||
//
|
||||
// }
|
||||
|
||||
// for (type_id, action) in cx.global::<ModalRegistry>().registered_modals.iter() {
|
||||
// div = div.useful_on_action(*type_id, action)
|
||||
// }
|
||||
let mut parent = div().relative();
|
||||
|
||||
for (_, action) in cx.global::<ModalRegistry>().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())))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ export default function assistant(): any {
|
|||
const theme = useTheme()
|
||||
|
||||
const interactive_role = (
|
||||
color: StyleSets
|
||||
color: StyleSets,
|
||||
): Interactive<RoleCycleButton> => {
|
||||
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"),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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)),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue