Files
Ely-GPUI-Components/frontend/src/docs/icons.md
T
ZacharyZhang-NY 49ed1f8405
CI / crate (push) Failing after 2s
CI / site (push) Successful in 30s
CI / platforms (ubuntu-24.04) (push) Failing after 1m48s
CI / platforms (macos-15-intel) (push) Canceled after 0s
CI / platforms (ubuntu-24.04-arm) (push) Canceled after 0s
CI / platforms (windows-11-arm) (push) Canceled after 0s
CI / platforms (windows-latest) (push) Failing after 15s
Site and gallery: the repo and the showcase catalog live on Gitea at git.zacharyzhang.com
Links, the header's Gitea mark, the catalog's archive download and the showcase pin
workflow (Gitea's API and commit status) move off GitHub; pinned at 6973834, which
restores TokenLedger.
2026-10-09 16:20:32 -04:00

3.6 KiB

Icons, fonts and assets

Assets embeds Ely's icons and fonts in the binary. Pass it to with_assets, or Assets::before(other) to serve Ely's files first and every other path from another source; init checks that each of Ely's files loads through the app's source, then registers the fonts.

Icons

Ely bundles 306 Lucide 1.48.0 icons, each an IconName variant: IconName::Check is icons/check.svg, and name() returns the Lucide name, check. IconName::ALL lists them all.

Call Does
Icon::new(name) Draws the icon at IconSize::Md in the theme's fg.
Icon::from_path(path) Draws an SVG from the application's asset source with the same defaults.
.size(IconSize::Xl) Xs to Xxl, from the theme's icon sizes.
.color(color) Any color; components pass theme colors.
.rotate(Radians(..)) Turns the glyph inside its box.
.scale(factor) Draws the glyph larger or smaller in the same box.

GPUI's svg() paints with its own text color alone, so Icon always sets one.

Adding an icon

From a clone of the repository:

  1. scripts/icons.sh <lucide-name>... fetches Lucide 1.48.0 with npm and copies each SVG into assets/icons/.
  2. Add a line to the icons! list in src/primitives/icon.rs, such as Rocket => "rocket",.

File icons

FileIcon::file(name) shows the icon a file's name suggests, and FileIcon::folder(open) a folder's. Ely maps extensions to icons: rs and ts to FileCode, toml to FileCog, json to FileJson, images, audio, video, archives and more. An app lays its own rules over that map:

Call Does
IconTheme::default().name("Cargo.toml", IconName::Package) A file of that exact name, in any case.
.extension("md", IconName::BookOpen) Files with that extension, given without its dot.
.apply(cx) Serves every window from then on, and repaints.

A name rule beats an extension rule, and both beat Ely's map.

Fonts

init registers seven fonts from Assets: Inter Regular, Medium, SemiBold and Italic; JetBrains Mono Regular and Medium; IBM Plex Sans Regular. The theme draws text in Inter and code in JetBrains Mono, set by its font_family and mono_family fields. On the web, GPUI answers the system UI font with IBM Plex Sans, and text inside SVGs falls back to it.

An app's own assets

GPUI takes one asset source. An app with files of its own, or another library's, passes Assets::before(theirs): Ely's paths load from Ely, every other path from theirs, whose errors pass through. init returns an error naming the first of Ely's files the source cannot load.

Use Icon::from_path("app-icons/mark.svg") to draw one of those SVG assets with Ely's themed sizing and color. It also accepts an owned String or SharedString. Paths are asset keys resolved by AssetSource; a path it lacks logs an error on first draw and shows a red broken-picture icon. SVGs render as single-color masks; IconName and IconPicker continue to list the bundled icons.

Compatible single-color SVGs can come from Lucide, Hugeicons, Phosphor, Remix Icon, or Tabler. The app supplies its chosen files and preserves their licenses; Ely does not download or register those catalogs.

The example below includes its asset source. Copy examples/assets/mark.svg with it, or supply your own SVG.

A window of icons