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

This commit is contained in:
Jason Lee 2025-11-14 15:03:26 +08:00 committed by GitHub
parent 724ccd64a7
commit 37d1678b6f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
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

View file

@ -1,5 +1,6 @@
use gpui::*;
use gpui_component::{button::*, menu::ContextMenuExt, *};
use gpui_component_assets::Assets;
actions!(class_menu, [Open, Delete, Export, Info]);
@ -78,7 +79,7 @@ impl Render for HelloWorld {
}
fn main() {
let app = Application::new();
let app = Application::new().with_assets(Assets);
app.run(move |cx| {
gpui_component::init(cx);

View file

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

View file

@ -3,6 +3,7 @@ use gpui_component::{
input::{Input, InputEvent, InputState},
*,
};
use gpui_component_assets::Assets;
pub struct Example {
input_state: Entity<InputState>,
@ -53,7 +54,7 @@ impl Render for Example {
}
fn main() {
let app = Application::new();
let app = Application::new().with_assets(Assets);
app.run(move |cx| {
// This must be called before using any GPUI Component features.

View file

@ -8,8 +8,8 @@ version = "0.4.0-preview2"
[dependencies]
anyhow.workspace = true
gpui.workspace = true
gpui-component = { workspace = true }
rust-embed = { version = "8", features = ["interpolate-folder-path"] }
gpui-component.workspace = true
gpui-component-assets.workspace = true
[lints]
workspace = true

View file

@ -1,9 +0,0 @@
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-120.000000, 0.000000)" fill="#000000" fill-rule="nonzero">
<g id="close" transform="translate(120.000000, 0.000000)">
<path d="M19.203125,20 C19.3125,20 19.4166667,19.9791667 19.515625,19.9375 C19.6145833,19.8958333 19.6992188,19.8385417 19.7695312,19.765625 C19.8398438,19.6927083 19.8958333,19.6067708 19.9375,19.5078125 C19.9791667,19.4088542 20,19.3046875 20,19.1953125 C20,18.9765625 19.921875,18.7890625 19.765625,18.6328125 L19.765625,18.6328125 L13.1328125,12 L19.765625,5.3671875 C19.921875,5.2109375 20,5.02083333 20,4.796875 C20,4.6875 19.9791667,4.58463542 19.9375,4.48828125 C19.8958333,4.39192708 19.8385417,4.30729167 19.765625,4.234375 C19.6927083,4.16145833 19.6080729,4.10416667 19.5117188,4.0625 C19.4153646,4.02083333 19.3125,4 19.203125,4 C18.9791667,4 18.7890625,4.078125 18.6328125,4.234375 L18.6328125,4.234375 L12,10.8671875 L5.3671875,4.234375 C5.2109375,4.078125 5.0234375,4 4.8046875,4 C4.6953125,4 4.59114583,4.02083333 4.4921875,4.0625 C4.39322917,4.10416667 4.30729167,4.16015625 4.234375,4.23046875 C4.16145833,4.30078125 4.10416667,4.38541667 4.0625,4.484375 C4.02083333,4.58333333 4,4.6875 4,4.796875 C4,5.02083333 4.078125,5.2109375 4.234375,5.3671875 L4.234375,5.3671875 L10.8671875,12 L4.234375,18.6328125 C4.078125,18.7890625 4,18.9765625 4,19.1953125 C4,19.4244792 4.07682292,19.6158854 4.23046875,19.7695312 C4.38411458,19.9231771 4.57552083,20 4.8046875,20 C5.0234375,20 5.2109375,19.921875 5.3671875,19.765625 L5.3671875,19.765625 L12,13.1328125 L18.6328125,19.765625 C18.7890625,19.921875 18.9791667,20 19.203125,20 Z"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,9 +0,0 @@
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-80.000000, 0.000000)" fill="#000000" fill-rule="nonzero">
<g id="maximize" transform="translate(80.000000, 0.000000)">
<path d="M17.640625,20 C17.953125,20 18.2526042,19.9361979 18.5390625,19.8085938 C18.8255208,19.6809896 19.0768229,19.5091146 19.2929688,19.2929688 C19.5091146,19.0768229 19.6809896,18.8255208 19.8085938,18.5390625 C19.9361979,18.2526042 20,17.953125 20,17.640625 L20,17.640625 L20,6.359375 C20,6.046875 19.9361979,5.74739583 19.8085938,5.4609375 C19.6809896,5.17447917 19.5091146,4.92317708 19.2929688,4.70703125 C19.0768229,4.49088542 18.8255208,4.31901042 18.5390625,4.19140625 C18.2526042,4.06380208 17.953125,4 17.640625,4 L17.640625,4 L6.359375,4 C6.046875,4 5.74739583,4.06380208 5.4609375,4.19140625 C5.17447917,4.31901042 4.92317708,4.49088542 4.70703125,4.70703125 C4.49088542,4.92317708 4.31901042,5.17447917 4.19140625,5.4609375 C4.06380208,5.74739583 4,6.046875 4,6.359375 L4,6.359375 L4,17.640625 C4,17.953125 4.06380208,18.2526042 4.19140625,18.5390625 C4.31901042,18.8255208 4.49088542,19.0768229 4.70703125,19.2929688 C4.92317708,19.5091146 5.17447917,19.6809896 5.4609375,19.8085938 C5.74739583,19.9361979 6.046875,20 6.359375,20 L6.359375,20 L17.640625,20 Z M17.6015625,18.3984375 L6.3984375,18.3984375 C6.2890625,18.3984375 6.18619792,18.3776042 6.08984375,18.3359375 C5.99348958,18.2942708 5.90885417,18.2369792 5.8359375,18.1640625 C5.76302083,18.0911458 5.70572917,18.0065104 5.6640625,17.9101562 C5.62239583,17.8138021 5.6015625,17.7109375 5.6015625,17.6015625 L5.6015625,17.6015625 L5.6015625,6.3984375 C5.6015625,6.2890625 5.62239583,6.18619792 5.6640625,6.08984375 C5.70572917,5.99348958 5.76302083,5.90885417 5.8359375,5.8359375 C5.90885417,5.76302083 5.99348958,5.70572917 6.08984375,5.6640625 C6.18619792,5.62239583 6.2890625,5.6015625 6.3984375,5.6015625 L6.3984375,5.6015625 L17.6015625,5.6015625 C17.7109375,5.6015625 17.8138021,5.62239583 17.9101562,5.6640625 C18.0065104,5.70572917 18.0911458,5.76302083 18.1640625,5.8359375 C18.2369792,5.90885417 18.2942708,5.99348958 18.3359375,6.08984375 C18.3776042,6.18619792 18.3984375,6.2890625 18.3984375,6.3984375 L18.3984375,6.3984375 L18.3984375,17.6015625 C18.3984375,17.7109375 18.3776042,17.8138021 18.3359375,17.9101562 C18.2942708,18.0065104 18.2369792,18.0911458 18.1640625,18.1640625 C18.0911458,18.2369792 18.0065104,18.2942708 17.9101562,18.3359375 C17.8138021,18.3776042 17.7109375,18.3984375 17.6015625,18.3984375 L17.6015625,18.3984375 Z"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -1,9 +0,0 @@
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-40.000000, 0.000000)" fill="#000000" fill-rule="nonzero">
<g id="minimize" transform="translate(40.000000, 0.000000)">
<path d="M19.203125,12 C19.3125,12 19.4153646,11.9791667 19.5117188,11.9375 C19.6080729,11.8958333 19.6927083,11.8385417 19.765625,11.765625 C19.8385417,11.6927083 19.8958333,11.6080729 19.9375,11.5117188 C19.9791667,11.4153646 20,11.3125 20,11.203125 C20,11.09375 19.9791667,10.9908854 19.9375,10.8945312 C19.8958333,10.7981771 19.8385417,10.7122396 19.765625,10.6367188 C19.6927083,10.5611979 19.6080729,10.5026042 19.5117188,10.4609375 C19.4153646,10.4192708 19.3125,10.3984375 19.203125,10.3984375 L19.203125,10.3984375 L4.796875,10.3984375 C4.6875,10.3984375 4.58463542,10.4192708 4.48828125,10.4609375 C4.39192708,10.5026042 4.30729167,10.5611979 4.234375,10.6367188 C4.16145833,10.7122396 4.10416667,10.7981771 4.0625,10.8945312 C4.02083333,10.9908854 4,11.09375 4,11.203125 C4,11.3125 4.02083333,11.4153646 4.0625,11.5117188 C4.10416667,11.6080729 4.16145833,11.6927083 4.234375,11.765625 C4.30729167,11.8385417 4.39192708,11.8958333 4.48828125,11.9375 C4.58463542,11.9791667 4.6875,12 4.796875,12 L4.796875,12 L19.203125,12 Z"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="#000000" fill-rule="nonzero">
<g id="restore">
<path d="M18.3984375,16.6640625 C18.6380208,16.5807292 18.8567708,16.4635417 19.0546875,16.3125 C19.2526042,16.1614583 19.421875,15.9869792 19.5625,15.7890625 C19.703125,15.5911458 19.8111979,15.3736979 19.8867188,15.1367188 C19.9622396,14.8997396 20,14.6536458 20,14.3984375 L20,14.3984375 L20,8.796875 C20,8.13541667 19.8736979,7.51302083 19.6210938,6.9296875 C19.3684896,6.34635417 19.0247396,5.83854167 18.5898438,5.40625 C18.1549479,4.97395833 17.6458333,4.63151042 17.0625,4.37890625 C16.4791667,4.12630208 15.8567708,4 15.1953125,4 L15.1953125,4 L9.6015625,4 C9.34635417,4 9.10026042,4.03776042 8.86328125,4.11328125 C8.62630208,4.18880208 8.40885417,4.296875 8.2109375,4.4375 C8.01302083,4.578125 7.83854167,4.74739583 7.6875,4.9453125 C7.53645833,5.14322917 7.41927083,5.36197917 7.3359375,5.6015625 L7.3359375,5.6015625 L15.1953125,5.6015625 C15.6223958,5.6015625 16.0299479,5.68359375 16.4179688,5.84765625 C16.8059896,6.01171875 17.1471354,6.23567708 17.4414062,6.51953125 C17.7356771,6.80338542 17.96875,7.13671875 18.140625,7.51953125 C18.3125,7.90234375 18.3984375,8.30989583 18.3984375,8.7421875 L18.3984375,8.7421875 L18.3984375,16.6640625 Z M14.4375,20 C14.7552083,20 15.0559896,19.9361979 15.3398438,19.8085938 C15.6236979,19.6809896 15.8736979,19.5091146 16.0898438,19.2929688 C16.3059896,19.0768229 16.4778646,18.8268229 16.6054688,18.5429688 C16.7330729,18.2591146 16.796875,17.9583333 16.796875,17.640625 L16.796875,17.640625 L16.796875,9.5625 C16.796875,9.24479167 16.7330729,8.94270833 16.6054688,8.65625 C16.4778646,8.36979167 16.3072917,8.11979167 16.09375,7.90625 C15.8802083,7.69270833 15.6302083,7.52213542 15.34375,7.39453125 C15.0572917,7.26692708 14.7552083,7.203125 14.4375,7.203125 L14.4375,7.203125 L6.359375,7.203125 C6.04166667,7.203125 5.74088542,7.26692708 5.45703125,7.39453125 C5.17317708,7.52213542 4.92317708,7.69401042 4.70703125,7.91015625 C4.49088542,8.12630208 4.31901042,8.37630208 4.19140625,8.66015625 C4.06380208,8.94401042 4,9.24479167 4,9.5625 L4,9.5625 L4,17.640625 C4,17.953125 4.06380208,18.2526042 4.19140625,18.5390625 C4.31901042,18.8255208 4.49088542,19.0768229 4.70703125,19.2929688 C4.92317708,19.5091146 5.17447917,19.6809896 5.4609375,19.8085938 C5.74739583,19.9361979 6.046875,20 6.359375,20 L6.359375,20 L14.4375,20 Z M14.3984375,18.3984375 L6.3984375,18.3984375 C6.2890625,18.3984375 6.18619792,18.3776042 6.08984375,18.3359375 C5.99348958,18.2942708 5.90885417,18.2369792 5.8359375,18.1640625 C5.76302083,18.0911458 5.70572917,18.0065104 5.6640625,17.9101562 C5.62239583,17.8138021 5.6015625,17.7109375 5.6015625,17.6015625 L5.6015625,17.6015625 L5.6015625,9.6015625 C5.6015625,9.4921875 5.62239583,9.38932292 5.6640625,9.29296875 C5.70572917,9.19661458 5.76302083,9.11067708 5.8359375,9.03515625 C5.90885417,8.95963542 5.99348958,8.90104167 6.08984375,8.859375 C6.18619792,8.81770833 6.2890625,8.796875 6.3984375,8.796875 L6.3984375,8.796875 L14.3984375,8.796875 C14.5078125,8.796875 14.6119792,8.81770833 14.7109375,8.859375 C14.8098958,8.90104167 14.8958333,8.95833333 14.96875,9.03125 C15.0416667,9.10416667 15.0989583,9.19010417 15.140625,9.2890625 C15.1822917,9.38802083 15.203125,9.4921875 15.203125,9.6015625 L15.203125,9.6015625 L15.203125,17.6015625 C15.203125,17.7109375 15.1822917,17.8138021 15.140625,17.9101562 C15.0989583,18.0065104 15.0403646,18.0911458 14.9648438,18.1640625 C14.8893229,18.2369792 14.8033854,18.2942708 14.7070312,18.3359375 C14.6106771,18.3776042 14.5078125,18.3984375 14.3984375,18.3984375 L14.3984375,18.3984375 Z"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -1,34 +1,8 @@
use anyhow::anyhow;
use gpui::*;
use gpui_component::{
button::{Button, ButtonVariants},
h_flex, v_flex, Root, TitleBar,
};
use rust_embed::Embed;
use std::borrow::Cow;
#[derive(Embed)]
#[folder = "./assets"]
#[include = "icons/**/*.svg"]
pub struct Assets;
impl AssetSource for Assets {
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
if path.is_empty() {
return Ok(None);
}
Self::get(path)
.map(|f| Some(f.data))
.ok_or_else(|| anyhow!("could not find asset at path \"{path}\""))
}
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
Ok(Self::iter()
.filter_map(|p| p.starts_with(path).then(|| p.into()))
.collect())
}
}
pub struct Example;
impl Render for Example {
@ -65,7 +39,7 @@ impl Render for Example {
}
fn main() {
let app = Application::new().with_assets(Assets);
let app = Application::new().with_assets(gpui_component_assets::Assets);
app.run(move |cx| {
gpui_component::init(cx);