Skip to main content

gpui_kit_assets/
lib.rs

1//! Bundled Lucide icons shared by GPUI Kit presentation and behavior layers.
2//!
3//! [`IconName`] and [`IconNamed`] do not depend on GPUI Component. Register
4//! [`Assets`] for the default component bundle, or [`AllAssets`] for the full
5//! catalog. Applications can provide their own source for additional icons.
6
7#[cfg(feature = "gpui-fast")]
8extern crate gpui_fast as gpui;
9#[cfg(all(feature = "gpui-fast", test))]
10extern crate gpui_fast_platform as gpui_platform;
11
12mod icon;
13pub use icon::{IconName, IconNamed};
14
15/// Embed application assets for GPUI Component.
16///
17/// This assets provides icons svg files for [IconName].
18///
19/// ## Usage
20///
21/// ```rust,no_run
22/// use gpui_kit_assets::Assets;
23///
24/// let app = gpui_platform::application().with_assets(Assets);
25/// ```
26///
27/// ## Platform Differences
28///
29/// - **Native (Desktop)**: Icons are embedded in the binary using RustEmbed
30/// - **WASM (Web)**: Icons are downloaded from CDN using web_sys::Request
31///   - This significantly reduces WASM bundle size
32///   - Icons are downloaded on-demand when first used
33///   - Downloaded icons are cached in memory
34#[cfg(not(target_family = "wasm"))]
35mod native_assets;
36
37#[cfg(target_family = "wasm")]
38mod wasm_assets;
39
40#[cfg(not(target_family = "wasm"))]
41pub use native_assets::{AllAssets, Assets};
42
43#[cfg(target_family = "wasm")]
44pub use wasm_assets::Assets;
45
46/// On WASM, the complete catalog uses the same on-demand CDN source.
47#[cfg(target_family = "wasm")]
48pub use wasm_assets::Assets as AllAssets;
49
50// Public only so exported macros can resolve dependencies in downstream crates,
51// including applications that depend solely on the gpui-kit umbrella crate.
52#[doc(hidden)]
53pub mod __private {
54    pub use crate::icon::embedded::*;
55    pub use gpui::{AssetSource, Result, SharedString};
56}
57
58/// Embed only the selected icons in a native or WebAssembly application.
59///
60/// ```ignore
61/// use gpui_kit::assets::{icon_assets, IconName};
62/// icon_assets!(AppAssets, [Search, Check]);
63/// // gpui_kit::application().with_assets(AppAssets)
64/// ```
65///
66/// Unlisted paths return `Ok(None)`. The selected SVG bytes are borrowed from
67/// static storage; loading them does not copy them or build a runtime cache.
68/// This source contains only the selected icons. Applications using components
69/// can compose it with `Assets` to retain their default icons.
70#[macro_export]
71macro_rules! icon_assets {
72    ($vis:vis $name:ident, [$($icon:ident),* $(,)?]) => {
73        #[derive(Clone, Copy, Debug, Default)]
74        $vis struct $name;
75
76        impl $crate::__private::AssetSource for $name {
77            fn load(&self, path: &str) -> $crate::__private::Result<Option<::std::borrow::Cow<'static, [u8]>>> {
78                $(if path == $crate::__private::$icon.0 {
79                    return Ok(Some(::std::borrow::Cow::Borrowed($crate::__private::$icon.1)));
80                })*
81                let _ = path;
82                Ok(None)
83            }
84
85            fn list(&self, path: &str) -> $crate::__private::Result<::std::vec::Vec<$crate::__private::SharedString>> {
86                let paths: &[&str] = &[$($crate::__private::$icon.0),*];
87                Ok(paths.iter().copied().filter(|name| name.starts_with(path)).map(Into::into).collect())
88            }
89        }
90    };
91}