GPUI Box GitHub

Scenes

browser-panel

Builds BrowserPanel

browser-panel in the dark theme
studio-dark
browser-panel in the light theme
studio-light

The code that drew it

A still frame holds a repeating animation at its first frame and a one-shot at its last, because a still of a moving thing is not reproducible. Run the gallery to review motion.

fn browser_panel(_window: &mut Window, cx: &mut App) -> AnyElement {
    let theme = cx.theme().clone();
    stack(&theme)
        .child(
            row(&theme)
                .items_start()
                .child(
                    div().w(px(232.0)).h(px(190.0)).child(
                        BrowserPanel::new("scene.browser.loading")
                            .url("https://docs.example.com/a/long/path/that-must-stay-inside-the-address-well")
                            .state(ViewportState::Loading)
                            .on_reload(|_, _| {}),
                    ),
                )
                .child(
                    div().w(px(232.0)).h(px(190.0)).child(
                        BrowserPanel::new("scene.browser.empty")
                            .url("https://docs.example.com/empty")
                            .state(ViewportState::Empty)
                            .on_back(|_, _| {})
                            .on_reload(|_, _| {}),
                    ),
                )
                .child(
                    div().w(px(232.0)).h(px(190.0)).child(
                        BrowserPanel::new("scene.browser.unavailable")
                            .url("https://internal.example.com/admin")
                            .state(ViewportState::Unavailable(
                                "The workspace policy does not allow this host.".into(),
                            ))
                            .on_reload(|_, _| {}),
                    ),
                ),
        )
        .child(
            row(&theme)
                .items_start()
                .child(
                    div().w(px(352.0)).h(px(210.0)).child(
                        BrowserPanel::new("scene.browser.error")
                            .url("https://status.example.com/incidents/current")
                            .state(ViewportState::Error(
                                "The host could not resolve this address.".into(),
                            ))
                            .on_back(|_, _| {})
                            .on_reload(|_, _| {}),
                    ),
                )
                .child(
                    div().w(px(352.0)).h(px(210.0)).child(
                        BrowserPanel::new("scene.browser.ready")
                            .url("https://docs.example.com/ready")
                            .state(ViewportState::Ready)
                            .viewport(
                                div()
                                    .size_full()
                                    .p_token(&theme, Space::Md)
                                    .child(crate::foundation::text(
                                        &theme,
                                        TypeScale::Subtitle,
                                        "Host-owned page surface",
                                    ))
                                    .child(
                                        div()
                                            .mt_token(&theme, Space::Sm)
                                            .child(crate::foundation::text(&theme, TypeScale::Body, "Long page content remains clipped by the BrowserPanel viewport even when it cannot wrap naturally.").text_tone(&theme, TextTone::Muted)),
                                    ),
                            )
                            .on_back(|_, _| {})
                            .on_forward(|_, _| {})
                            .on_reload(|_, _| {}),
                    ),
                ),
        )
        .into_any_element()
}