Files
zed/crates/gpui/examples/shadow.rs
T
Lukas Wirth ab1c37a4ef gpui_web: Let applications provide fonts (#63493)
`gpui_web` currently embeds IBM Plex Sans and Lilex into every browser
application during platform construction. Applications such as Delta
already provide their own fonts, so those binaries contain overlapping
font bundles and register the same faces twice.

This change starts the web platform with an empty font database,
matching the ownership boundary used by native applications: the
application selects and registers its fonts before opening a window.
Delta already follows that sequence. GPUI's browser-capable examples now
load the former eight-face bundle explicitly through shared example
support, while the standalone `hello_web` example demonstrates
registering a minimal application font directly.

Testing performed:

- `cargo check -p gpui --examples --target wasm32-unknown-unknown`
- `cargo check -p gpui --examples`
- `cargo check -p gpui_web --target wasm32-unknown-unknown`
- `cargo check --manifest-path
crates/gpui_web/examples/hello_web/Cargo.toml --target
wasm32-unknown-unknown`
- `./script/clippy -p gpui_web --target wasm32-unknown-unknown`
- `cargo fmt -p gpui -p gpui_web --check`

Release Notes:

- N/A
2026-08-31 13:07:22 +00:00

623 lines
27 KiB
Rust

#![cfg_attr(target_family = "wasm", no_main)]
#[path = "example_support/fonts.rs"]
mod example_support;
use gpui::{
App, Bounds, BoxShadow, Context, Div, SharedString, Window, WindowBounds, WindowOptions, div,
hsla, prelude::*, px, relative, rgb, size,
};
use gpui_platform::application;
struct Shadow {}
impl Shadow {
fn base() -> Div {
div()
.size_16()
.bg(rgb(0xffffff))
.rounded_full()
.border_1()
.border_color(hsla(0.0, 0.0, 0.0, 0.1))
}
fn square() -> Div {
div()
.size_16()
.bg(rgb(0xffffff))
.border_1()
.border_color(hsla(0.0, 0.0, 0.0, 0.1))
}
fn rounded_small() -> Div {
div()
.size_16()
.bg(rgb(0xffffff))
.rounded(px(4.))
.border_1()
.border_color(hsla(0.0, 0.0, 0.0, 0.1))
}
fn rounded_medium() -> Div {
div()
.size_16()
.bg(rgb(0xffffff))
.rounded(px(8.))
.border_1()
.border_color(hsla(0.0, 0.0, 0.0, 0.1))
}
fn rounded_large() -> Div {
div()
.size_16()
.bg(rgb(0xffffff))
.rounded(px(12.))
.border_1()
.border_color(hsla(0.0, 0.0, 0.0, 0.1))
}
}
fn example(label: impl Into<SharedString>, example: impl IntoElement) -> impl IntoElement {
let label = label.into();
div()
.flex()
.flex_col()
.justify_center()
.items_center()
.w(relative(1. / 6.))
.border_r_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.child(
div()
.flex()
.items_center()
.justify_center()
.flex_1()
.py_12()
.child(example),
)
.child(
div()
.w_full()
.border_t_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.p_1()
.flex()
.items_center()
.child(label),
)
}
impl Render for Shadow {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.id("shadow-example")
.overflow_y_scroll()
.bg(rgb(0xffffff))
.size_full()
.text_xs()
.child(div().flex().flex_col().w_full().children(vec![
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.flex_row()
.children(vec![
example(
"Square",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded 4",
Shadow::rounded_small().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded 8",
Shadow::rounded_medium().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded 16",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Circle",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
]),
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.w_full()
.children(vec![
example("None", Shadow::base()),
// 2Xsmall shadow
example("2X Small", Shadow::base().shadow_2xs()),
// Xsmall shadow
example("Extra Small", Shadow::base().shadow_xs()),
// Small shadow
example("Small", Shadow::base().shadow_sm()),
// Medium shadow
example("Medium", Shadow::base().shadow_md()),
// Large shadow
example("Large", Shadow::base().shadow_lg()),
example("Extra Large", Shadow::base().shadow_xl()),
example("2X Large", Shadow::base().shadow_2xl()),
]),
// Horizontal list of increasing blur radii
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Blur 0",
Shadow::base().shadow(vec![BoxShadow::new(
px(0.),
px(8.),
hsla(0.0, 0.0, 0.0, 0.3),
)]),
),
example(
"Blur 2",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(2.)),
]),
),
example(
"Blur 4",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(4.)),
]),
),
example(
"Blur 8",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Blur 16",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(16.)),
]),
),
]),
// Horizontal list of increasing spread radii
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Spread 0",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Spread 2",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(2.)),
]),
),
example(
"Spread 4",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(4.)),
]),
),
example(
"Spread 8",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(8.)),
]),
),
example(
"Spread 16",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(16.)),
]),
),
]),
// Square spread examples
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Square Spread 0",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Square Spread 8",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(8.)),
]),
),
example(
"Square Spread 16",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(16.)),
]),
),
]),
// Rounded large spread examples
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Rounded Large Spread 0",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded Large Spread 8",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(8.)),
]),
),
example(
"Rounded Large Spread 16",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.3))
.blur_radius(px(8.))
.spread_radius(px(16.)),
]),
),
]),
// Directional shadows
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Left",
Shadow::base().shadow(vec![
BoxShadow::new(px(-8.), px(0.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Right",
Shadow::base().shadow(vec![
BoxShadow::new(px(8.), px(0.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Top",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(-8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Bottom",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
]),
// Square directional shadows
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Square Left",
Shadow::square().shadow(vec![
BoxShadow::new(px(-8.), px(0.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Square Right",
Shadow::square().shadow(vec![
BoxShadow::new(px(8.), px(0.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Square Top",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(-8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Square Bottom",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
]),
// Rounded large directional shadows
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Rounded Large Left",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(-8.), px(0.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded Large Right",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(8.), px(0.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded Large Top",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(-8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
example(
"Rounded Large Bottom",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.5, 0.5, 0.3))
.blur_radius(px(8.)),
]),
),
]),
// Multiple shadows for different shapes
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.children(vec![
example(
"Circle Multiple",
Shadow::base().shadow(vec![
BoxShadow::new(
px(0.),
px(-12.),
hsla(0.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(12.),
px(0.),
hsla(60.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(0.),
px(12.),
hsla(120.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(-12.),
px(0.),
hsla(240.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
]),
),
example(
"Square Multiple",
Shadow::square().shadow(vec![
BoxShadow::new(
px(0.),
px(-12.),
hsla(0.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(12.),
px(0.),
hsla(60.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(0.),
px(12.),
hsla(120.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(-12.),
px(0.),
hsla(240.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
]),
),
example(
"Rounded Large Multiple",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(
px(0.),
px(-12.),
hsla(0.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(12.),
px(0.),
hsla(60.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(0.),
px(12.),
hsla(120.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
BoxShadow::new(
px(-12.),
px(0.),
hsla(240.0 / 360., 1.0, 0.5, 0.3),
)
.blur_radius(px(8.))
.spread_radius(px(2.)),
]),
),
]),
// Inset shadows (CSS `box-shadow: inset ...`).
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.w_full()
.children(vec![
example(
"Inset basic",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(0.), hsla(0.0, 0.0, 0.0, 0.5))
.blur_radius(px(12.))
.inset(),
]),
),
example(
"Inset offset",
Shadow::base().shadow(vec![
BoxShadow::new(px(6.), px(6.), hsla(0.0, 0.0, 0.0, 0.5))
.blur_radius(px(8.))
.inset(),
]),
),
example(
"Inset spread",
Shadow::base().shadow(vec![
BoxShadow::new(px(0.), px(0.), hsla(0.0, 0.0, 0.0, 0.5))
.blur_radius(px(4.))
.spread_radius(px(8.))
.inset(),
]),
),
example(
"Inset rounded",
Shadow::rounded_large().shadow(vec![
BoxShadow::new(px(0.), px(4.), hsla(0.0, 0.0, 0.0, 0.5))
.blur_radius(px(10.))
.spread_radius(px(2.))
.inset(),
]),
),
example(
"Inset sharp",
Shadow::square().shadow(vec![
BoxShadow::new(px(0.), px(0.), hsla(0.0, 0.0, 0.0, 0.6))
.spread_radius(px(6.))
.inset(),
]),
),
]),
// Combined: drop + inset shadows on the same element.
div()
.border_b_1()
.border_color(hsla(0.0, 0.0, 0.0, 1.0))
.flex()
.w_full()
.children(vec![example(
"Drop + Inset",
Shadow::rounded_medium().shadow(vec![
BoxShadow::new(px(0.), px(8.), hsla(0.0, 0.0, 0.0, 0.25))
.blur_radius(px(12.)),
BoxShadow::new(px(0.), px(2.), hsla(0.0, 0.0, 0.0, 0.4))
.blur_radius(px(4.))
.inset(),
]),
)]),
]))
}
}
fn run_example() {
application().run(|cx: &mut App| {
if !example_support::load_fonts(cx) {
return;
}
let bounds = Bounds::centered(None, size(px(1000.0), px(800.0)), cx);
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
..Default::default()
},
|_, cx| cx.new(|_| Shadow {}),
)
.unwrap();
cx.activate(true);
});
}
#[cfg(not(target_family = "wasm"))]
fn main() {
run_example();
}
#[cfg(target_family = "wasm")]
#[wasm_bindgen::prelude::wasm_bindgen(start)]
pub fn start() {
gpui_platform::web_init();
run_example();
}