gpui_kit/lib.rs
1//! GPUI Kit: one dependency for building desktop applications with GPUI.
2//!
3//! GPUI itself is published as a family of `gpui-pre-*` crates that move
4//! together. This crate depends on the matching set for you, so an
5//! application lists `gpui-kit` alone. `use gpui_kit::*;` is GPUI, and each
6//! layer is reachable by name:
7//!
8//! | Path | Crate | Feature |
9//! | --------------- | ----------------- | ---------------- |
10//! | `gpui_kit::*` | `gpui` | always |
11//! | `platform` | `gpui_platform` | desktop / web |
12//! | [`base`] | `gpui-base` | always |
13//! | [`component`] | `gpui-component` | `component` (on) |
14//! | [`assets`] | `gpui-kit-assets` | `assets` (on) |
15//!
16//! On desktop and web, `application` opens the platform. Mobile applications
17//! supply their backend to `Application::with_platform`. [`init`] initializes the enabled
18//! layers:
19//!
20//! ```no_run
21//! use gpui_kit::*;
22//!
23//! actions!(hello, [Quit]);
24//!
25//! struct Hello;
26//!
27//! impl Render for Hello {
28//! fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
29//! div().child("Hello, World!")
30//! }
31//! }
32//!
33//! fn main() {
34//! gpui_kit::application().run(|cx| {
35//! gpui_kit::init(cx);
36//! cx.spawn(async move |cx| {
37//! cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| Hello))
38//! .expect("failed to open window");
39//! })
40//! .detach();
41//! });
42//! }
43//! ```
44//!
45//! See [`component`] for the same program with the styled component library.
46
47/// Defines unit actions without requiring consumers to depend on GPUI under the
48/// crate name `gpui`.
49///
50/// GPUI's original macro spells its derive as `gpui::Action`, which does not
51/// resolve when GPUI is consumed solely through this facade.
52#[macro_export]
53macro_rules! actions {
54 ($namespace:path, [ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
55 $(
56 #[derive(
57 ::std::clone::Clone,
58 ::std::cmp::PartialEq,
59 ::std::default::Default,
60 ::std::fmt::Debug,
61 $crate::Action
62 )]
63 #[action(namespace = $namespace)]
64 $(#[$attr])*
65 pub struct $name;
66 )*
67 };
68 ([ $( $(#[$attr:meta])* $name:ident),* $(,)? ]) => {
69 $(
70 #[derive(
71 ::std::clone::Clone,
72 ::std::cmp::PartialEq,
73 ::std::default::Default,
74 ::std::fmt::Debug,
75 $crate::Action
76 )]
77 $(#[$attr])*
78 pub struct $name;
79 )*
80 };
81}
82
83// Public facade decision — 2026-09-08:
84// GPUI Kit is the application-facing entry point. Users should depend on and
85// import gpui-kit without needing to know which GPUI crates implement it.
86// Keep GPUI APIs available through the Kit root and preserve the published
87// #[gpui_kit::test] macro. Do not replace it with Rust's built-in #[test].
88// A future switch to official GPUI crates is an internal dependency migration,
89// not a reason to steer Kit users toward gpui:: paths or require import changes.
90// Keep the existing gpui namespace re-export hidden for source compatibility;
91// it is not the recommended application API.
92//
93// With test-support, the glob below includes GPUI's test macro. Test modules
94// should import their Kit types explicitly to avoid shadowing Rust's #[test].
95pub use ::gpui::*;
96
97#[doc(hidden)]
98pub use ::gpui;
99
100/// UI integration testing: render real components in headless windows, dispatch
101/// pointer and keyboard events, and assert state, focus, layout and callbacks.
102/// Run tests with `#[gpui_kit::test]`; use this module to interact with their UI.
103#[cfg(feature = "test-support")]
104pub mod test;
105
106pub use ::gpui_base as base;
107#[cfg(not(any(target_os = "ios", target_os = "android")))]
108pub use ::gpui_platform as platform;
109#[cfg(target_family = "wasm")]
110pub use ::gpui_web as web;
111pub use gpui_base::is_mobile;
112
113/// The styled component library.
114///
115/// ```no_run
116/// use gpui_kit::component::button::*;
117/// use gpui_kit::component::Root;
118/// use gpui_kit::*;
119///
120/// struct Hello;
121///
122/// impl Render for Hello {
123/// fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
124/// div().child(Button::new("ok").primary().label("Let's Go!"))
125/// }
126/// }
127///
128/// fn main() {
129/// gpui_kit::application().run(|cx| {
130/// gpui_kit::init(cx);
131/// cx.spawn(async move |cx| {
132/// cx.open_window(WindowOptions::default(), |window, cx| {
133/// let view = cx.new(|_| Hello);
134/// cx.new(|cx| Root::new(view, window, cx))
135/// })
136/// .expect("failed to open window");
137/// })
138/// .detach();
139/// });
140/// }
141/// ```
142#[cfg(feature = "component")]
143pub use ::gpui_component as component;
144#[cfg(feature = "assets")]
145pub use ::gpui_kit_assets as assets;
146
147// Mobile applications provide their platform with `Application::with_platform`.
148#[cfg(not(any(target_os = "ios", target_os = "android")))]
149pub use ::gpui_platform::application;
150
151/// Initializes every enabled layer. Call it once, before using anything else.
152///
153/// With the `component` feature (on by default) this is
154/// `gpui_component::init`, which also initializes `gpui-base`; otherwise it
155/// is `gpui_base::init`.
156pub fn init(cx: &mut App) {
157 #[cfg(feature = "component")]
158 gpui_component::init(cx);
159 #[cfg(not(feature = "component"))]
160 gpui_base::init(cx);
161}
162
163/// Fluent UI test observation, inert unless `test-support` is enabled.
164pub use gpui_base::TestSupportExt;