bezel-icons
The Lucide set — 1834 glyphs, ported from a pinned release into typed
constants for gpui. Part of bezel, and reached as bezel::icons from it.
[]
= { = "bezel-icons", = "0.1", = ["navigation"] }
use ;
theme.icon // ladder step, palette tone
theme.icon // the filled variant
icon.size.text_color
icon returns a gpui Svg, so it colors with text_color and sizes like any
element — but gpui reads an svg's tone from that element's own style and never
inherits one, so an icon with neither set paints nothing. bezel-ui's
theme.icon(..) is this same builder with both supplied, which is what app code
should reach for; a component that has its own metric sets it on top.
What a component takes
Icon is the value, and it erases where the drawing came from:
theme.row_icon // a glyph compiled in
theme.row_icon // the app's own AssetSource
theme.row_icon // a file on disk
Components take impl Into<Icon>, so a constant passes as itself and neither
the signature nor the component learns which it got. SwiftUI's Image erases
its sources the same way.
An Icon carries no size and no color. Those belong to the environment, which
here is the component: a menu row's glyph is the row's metric, not the caller's.
Icon::solid is the one thing it does carry — SwiftUI's .symbolVariant(.fill)
— and it fills the outline where icon draws it, so a control swapping
between them does not jump.
Paying for what you paint
A constant is the SVG itself, not a path into an asset source — nothing
registers with with_assets, and the linker drops a glyph the app never names.
Features are Lucide's 42 categories under Lucide's own names, and full is all
of them. Nothing is on by default. Cargo unions features across a graph, so a
category a dependency turns on is the floor for everyone below it.
CATEGORIES is every enabled category and its icons, for an icon browser.
Naming it pins the enabled set, so an app that only paints icons never mentions
it and keeps the dead-code pass.
Names
Modules are Lucide's categories and constants are Lucide's names, both generated
from the release: a name copied off lucide.dev compiles
here. A glyph Lucide files under two categories is one constant re-exported
twice, so glyph holds each exactly once.
Upgrading
LUCIDE in build.rs is the pinned release. Bumping it invalidates the index
beside the assets and the next build re-ports, so the diff shows which glyphs
upstream redrew. The port runs only in a fresh checkout — the published crate
carries the glyphs, which is what keeps it offline, vendorable and buildable on
docs.rs.
Icons are Lucide, under the ISC license.