assets: Add gpui-component-assets crate. (#1601)

This commit is contained in:
Jason Lee
2025-11-14 15:03:26 +08:00
parent c24f245a8b
commit fc39dee024
29 changed files with 151 additions and 91 deletions

15
Cargo.lock generated
View File

@@ -1610,6 +1610,7 @@ dependencies = [
"anyhow",
"gpui",
"gpui-component",
"gpui-component-assets",
]
[[package]]
@@ -2893,6 +2894,15 @@ dependencies = [
"zed-sum-tree",
]
[[package]]
name = "gpui-component-assets"
version = "0.4.0-preview2"
dependencies = [
"anyhow",
"gpui",
"rust-embed",
]
[[package]]
name = "gpui-component-macros"
version = "0.4.0-preview2"
@@ -2913,6 +2923,7 @@ dependencies = [
"fake",
"gpui",
"gpui-component",
"gpui-component-assets",
"gtk",
"itertools 0.14.0",
"lsp-types 0.97.0",
@@ -2920,7 +2931,6 @@ dependencies = [
"raw-window-handle",
"regex",
"reqwest_client",
"rust-embed",
"serde",
"serde_json",
"smol",
@@ -3677,6 +3687,7 @@ dependencies = [
"anyhow",
"gpui",
"gpui-component",
"gpui-component-assets",
]
[[package]]
@@ -8813,7 +8824,7 @@ dependencies = [
"anyhow",
"gpui",
"gpui-component",
"rust-embed",
"gpui-component-assets",
]
[[package]]

View File

@@ -1,12 +1,14 @@
[workspace]
default-members = [
"crates/ui",
"crates/story"
"crates/story",
"crates/assets"
]
members = [
"crates/macros",
"crates/story",
"crates/ui",
"crates/assets",
"examples/app_assets",
"examples/hello_world",
"examples/input",
@@ -16,8 +18,9 @@ members = [
resolver = "2"
[workspace.dependencies]
gpui-component = { path = "crates/ui" }
gpui-component = { path = "crates/ui", version = "0.4.0-preview2" }
gpui-component-macros = { path = "crates/macros", version = "0.4.0-preview2" }
gpui-component-assets = { path = "crates/assets", version = "0.4.0-preview2" }
story = { path = "crates/story" }
gpui = "0.2.2"

20
crates/assets/Cargo.toml Normal file
View File

@@ -0,0 +1,20 @@
[package]
name = "gpui-component-assets"
description = "Default bundled assets for GPUI Component."
edition = "2021"
keywords = ["desktop", "gpui", "shadcn", "ui", "uikit"]
license = "Apache-2.0"
documentation = "https://docs.rs/gpui-component"
homepage = "https://longbridge.github.io/gpui-component"
repository = "https://github.com/longbridge/gpui-component"
publish = true
readme = "README.md"
version = "0.4.0-preview2"
[lib]
doctest = false
[dependencies]
anyhow.workspace = true
gpui.workspace = true
rust-embed = { version = "8.7.2", features = ["interpolate-folder-path"] }

7
crates/assets/README.md Normal file
View File

@@ -0,0 +1,7 @@
# GPUI Component Assets
The default assets bundle for [GPUI Component](https://github.com/longbridge/gpui-component).
## License
Apache-2.0

View File

@@ -3,6 +3,16 @@ use gpui::{AssetSource, Result, SharedString};
use rust_embed::RustEmbed;
use std::borrow::Cow;
/// Embed application assets for GPUI Component.
///
/// This assets provides icons svg files for [IconName](https://docs.rs/gpui-component/latest/gpui_component/enum.IconName.html).
///
/// ```
/// use gpui::*;
/// use gpui_component_assets::Assets;
///
/// let app = Application::new().with_assets(Assets);
/// ```
#[derive(RustEmbed)]
#[folder = "$CARGO_MANIFEST_DIR/../../assets"]
#[include = "icons/**/*.svg"]

View File

@@ -14,6 +14,7 @@ gpui-component = { workspace = true, features = [
"tree-sitter-languages",
"webview",
] }
gpui-component-assets.workspace = true
reqwest_client = { path = "../reqwest_client" }
autocorrect = "2.14.2"
@@ -25,7 +26,6 @@ lsp-types.workspace = true
rand = "0.8"
raw-window-handle = { version = "0.6", features = ["std"] }
regex = "1"
rust-embed = { version = "8.7.2", features = ["interpolate-folder-path"] }
serde = "1"
serde_json = "1"
smol.workspace = true

View File

@@ -10,7 +10,7 @@ use gpui_component::{
slider::{Slider, SliderState},
v_flex,
};
use gpui_component_story::Assets;
use gpui_component_assets::Assets;
pub struct BrushStory {
focus_handle: gpui::FocusHandle,

View File

@@ -7,9 +7,10 @@ use gpui_component::{
menu::DropdownMenu,
};
use gpui_component_assets::Assets;
use gpui_component_story::{
AccordionStory, AppState, AppTitleBar, Assets, ButtonStory, CalendarStory, DialogStory,
FormStory, IconStory, ImageStory, InputStory, LabelStory, ListStory, NotificationStory, Open,
AccordionStory, AppState, AppTitleBar, ButtonStory, CalendarStory, DialogStory, FormStory,
IconStory, ImageStory, InputStory, LabelStory, ListStory, NotificationStory, Open,
PopoverStory, ProgressStory, ResizableStory, ScrollableStory, SelectStory, SidebarStory,
StoryContainer, SwitchStory, TableStory, TooltipStory, WebViewStory,
};

View File

@@ -23,7 +23,8 @@ use gpui_component::{
tree::{TreeItem, TreeState, tree},
v_flex,
};
use gpui_component_story::{Assets, Open};
use gpui_component_assets::Assets;
use gpui_component_story::Open;
use lsp_types::{
CodeAction, CodeActionKind, CompletionContext, CompletionItem, CompletionResponse,
CompletionTextEdit, InsertReplaceEdit, TextEdit, WorkspaceEdit,

View File

@@ -5,7 +5,7 @@ use gpui_component::{
resizable::h_resizable,
text::TextView,
};
use gpui_component_story::Assets;
use gpui_component_assets::Assets;
pub struct Example {
input_state: Entity<InputState>,

View File

@@ -6,7 +6,7 @@ use gpui_component::{
input::{self, Input, InputEvent, InputState, TabSize},
v_flex,
};
use gpui_component_story::Assets;
use gpui_component_assets::Assets;
pub struct Example {
editor: Entity<InputState>,

View File

@@ -5,7 +5,8 @@ use gpui_component::{
resizable::{h_resizable, resizable_panel},
text::TextView,
};
use gpui_component_story::{Assets, Open};
use gpui_component_assets::Assets;
use gpui_component_story::Open;
pub struct Example {
input_state: Entity<InputState>,

View File

@@ -9,7 +9,8 @@ use gpui_component::{
input::{Input, InputState},
scroll::ScrollbarShow,
};
use gpui_component_story::{Assets, ButtonStory, IconStory, StoryContainer};
use gpui_component_assets::Assets;
use gpui_component_story::{ButtonStory, IconStory, StoryContainer};
use serde::{Deserialize, Serialize};
use std::{sync::Arc, time::Duration};

View File

@@ -1,5 +1,6 @@
use gpui::*;
use gpui_component_story::{Assets, WebViewStory};
use gpui_component_assets::Assets;
use gpui_component_story::WebViewStory;
pub struct Example {
root: Entity<WebViewStory>,

View File

@@ -1,7 +1,6 @@
mod accordion_story;
mod alert_story;
mod app_menus;
mod assets;
mod avatar_story;
mod badge_story;
mod button_story;
@@ -51,7 +50,6 @@ mod virtual_list_story;
mod webview_story;
mod welcome_story;
pub use assets::Assets;
use gpui::{
Action, AnyElement, AnyView, App, AppContext, Bounds, Context, Div, Entity, EventEmitter,
Focusable, Global, Hsla, InteractiveElement, IntoElement, KeyBinding, ParentElement, Pixels,

View File

@@ -6,6 +6,7 @@ use gpui_component::{
sidebar::{Sidebar, SidebarGroup, SidebarHeader, SidebarMenu, SidebarMenuItem},
v_flex,
};
use gpui_component_assets::Assets;
use gpui_component_story::*;
pub struct Gallery {

View File

@@ -7,14 +7,45 @@ order: -4
The [IconName] and [Icon] in GPUI Component provide a comprehensive set of icons and assets that can be easily integrated into your GPUI applications.
But for minimal size applications, **we have not embedded any icon assets by default**. You can choose to include only the icons you need.
But for minimal size applications, **we have not embedded any icon assets by default** in `gpui-component` crate.
We split the icon assets into a separate crate [gpui-component-assets] to allow developers to choose whether to include the icon assets in their applications or if you don't need the icons at all, you can build your own assets.
## Use default bundled assets
The [gpui-component-assets] crate provides a default bundled assets implementation that includes all the icon files in the `assets/icons` folder.
To use the default bundled assets, you need to add the `gpui-component-assets` crate as a dependency in your `Cargo.toml`:
```toml
[dependencies]
gpui-component = "*"
gpui-component-assets = "*"
```
Then we need call the `with_assets` method when creating the GPUI application to register the asset source:
```rs
use gpui::*;
use gpui_component_assets::Assets;
let app = Application::new().with_assets(Assets);
```
Now, we can use `IconName` and `Icon` in our application as usual, the all icon assets are loaded from the default bundled assets.
Continue [Use the icons](#use-the-icons) section to see how to use the icons in your application.
## Build you own assets
You may have a specific set of icons that you want to use in your application, or you may want to reduce the size of your application binary by including only the icons you need.
In this case, you can build your own assets by following these steps.
The [assets](https://github.com/longbridge/gpui-component/tree/main/assets) folder in source code contains all the available icons in SVG format, every file is that GPUI Component support, it matched with the [IconName] enum.
You can download the SVG files you need from the [assets] folder, or you can use your own SVG files by following the [IconName] naming convention.
## Usage
In GPUI application, we can use the [rust-embed] crate to embed the SVG files into the application binary.
And GPUI Application providers an `AssetSource` trait to load the assets.
@@ -76,6 +107,8 @@ fn main() {
}
```
## Use the icons
Now we can use the icons in our application:
```rs
@@ -97,9 +130,10 @@ impl Render for Example {
## Resources
- [Lucide Icons](https://lucide.dev/) - The icon set used in GPUI Component is based on the open-source [Lucide Icons](https://lucide.dev/) library, which provides a wide range of customizable SVG icons.
- [Lucide Icons](https://lucide.dev/) - The icon set used in GPUI Component is based on the open-source Lucide Icons library, which provides a wide range of customizable SVG icons.
[rust-embed]: https://docs.rs/rust-embed/latest/rust_embed/
[IconName]: https://docs.rs/gpui_component/latest/gpui_component/icon/enum.IconName.html
[Icon]: https://docs.rs/gpui_component/latest/gpui_component/icon/struct.Icon.html
[assets]: https://github.com/longbridge/gpui-component/tree/main/assets
[gpui-component-assets]: https://crates.io/crates/gpui-component-assets

View File

@@ -14,8 +14,18 @@ Add dependencies to your `Cargo.toml`:
[dependencies]
gpui = "0.2"
gpui-component = "0.4.0-preview2"
# Optional, for default bundled assets
gpui-component-assets = "0.4.0-preview2"
```
:::tip
The `gpui-component-assets` crate is optional.
It provides a default set of icon assets. If you want to manage your own assets, you can skip adding this dependency.
See [Icons & Assets](./assets.md) for more details.
:::
## Quick Start
Here's a simple example to get you started:
@@ -45,7 +55,7 @@ impl Render for HelloWorld {
}
fn main() {
let app = Application::new();
let app = Application::new().with_assets(gpui_component_assets::Assets);
app.run(move |cx| {
// This must be called before using any GPUI Component features.

View File

@@ -60,3 +60,23 @@ fn main() {
// ...
}
```
## Use default bundled assets.
The `gpui-component-assets` crate provide a default bundled assets implementation that include all the icon files in the `assets/icons` folder.
If you don't want to manage your own icon files, you can just use the default bundled assets.
Just add `gpui-component-assets` as a dependency in your `Cargo.toml`:
```toml
[dependencies]
gpui-component = "*"
gpui-component-assets = "*"
```
And then use it in your application:
```rs
let app = Application::new().with_assets(gpui_component_assets::Assets);
```

View File

@@ -8,7 +8,8 @@ version = "0.4.0-preview2"
[dependencies]
anyhow.workspace = true
gpui.workspace = true
gpui-component = { workspace = true }
gpui-component.workspace = true
gpui-component-assets.workspace = true
[lints]
workspace = true

Some files were not shown because too many files have changed in this diff Show More