+ Hello from WebKit
+ HTML the owner hands in, drawn by a native web view.
+"#;
+
+pub fn render(cx: &App) -> impl IntoElement + use<> {
+ div()
+ .child(
+ section(
+ "WebView / HTMLPreview",
+ "A native web view laid over its box: an address, or HTML the owner hands in, which makes it an HTML preview. It draws above everything gpui paints and follows the box each frame.",
+ cx,
+ )
+ .child(
+ div()
+ .w(px(480.0))
+ .h(px(200.0))
+ .child(WebView::new("web", WebSource::Html(PAGE.into()))),
+ ),
+ )
+ .child(
+ section(
+ "IframeEmbed / EmbedCard",
+ "A page from another address in a frame of its own, with Open in browser. EmbedCard is chat::LinkPreviewCard, shown on the AI Chat page.",
+ cx,
+ )
+ .child(div().w(px(480.0)).child(IframeEmbed::new(
+ "iframe",
+ "https://example.com",
+ 16.0 / 9.0,
+ ))),
+ )
+ .child(
+ section(
+ "PrintButton · ShareSheet",
+ "ShareSheet is buttons::ShareButton, shown on the Buttons & Actions page.",
+ cx,
+ )
+ .child(blocked(
+ "PrintButton: gpui 0.2.2 has no print API.",
+ cx,
+ )),
+ )
+}
diff --git a/src/misc/mod.rs b/src/misc/mod.rs
index 9da54f2..044b919 100644
--- a/src/misc/mod.rs
+++ b/src/misc/mod.rs
@@ -13,6 +13,7 @@ mod survey;
#[cfg(all(test, feature = "test-support"))]
mod tests;
mod units;
+mod web;
pub use calculator::Calculator;
pub use captcha::{Captcha, CaptchaState};
@@ -27,3 +28,4 @@ pub use scanner::QrCodeScanner;
pub use stopwatch::Stopwatch;
pub use survey::{Answer, Question, Survey};
pub use units::UnitConverter;
+pub use web::{IframeEmbed, WebSource, WebView};
diff --git a/src/misc/web.rs b/src/misc/web.rs
new file mode 100644
index 0000000..f6f82f7
--- /dev/null
+++ b/src/misc/web.rs
@@ -0,0 +1,226 @@
+use gpui::{
+ AnyElement, App, Bounds, ElementId, IntoElement, ParentElement, Pixels, RenderOnce,
+ SharedString, Styled, Window, div,
+};
+
+use crate::{
+ buttons::IconButton,
+ primitives::{Icon, IconName, checked_ratio, framed},
+ theme::{ActiveTheme, IconSize, Radius, TextSize},
+ typography::{Ellipsis, literal},
+};
+
+/// What a web view shows: a page at an address, or the owner's HTML.
+#[derive(Clone, Debug, PartialEq)]
+pub enum WebSource {
+ Url(SharedString),
+ Html(SharedString),
+}
+
+/// Whether a box lies, at least in part, inside what the window shows of its region.
+pub(crate) fn in_view(bounds: Bounds