docs/guide/icons
핵심 개념 · Lucide 아이콘 2,026개

Icon Gallery

zenit 공개 아이콘을 검색·미리 보기·복사하고, 정적 상수, 동적 registry, 시맨틱 레이어가 어떻게 역할을 나누는지 알아봅니다.

8분 분량 · 검색 가능한 전체 목록

두 가지 진입점

공개 빌드에는 Lucide(lucide-static v1.31.0)가 포함됩니다. 전체 provider 카탈로그는 ui.icons이며 이름이 2,026개입니다. 업스트림 SVG 2,025개에 호환 별칭 hand-pointing(업스트림 pointer.svg와 바이트 단위로 동일)을 더한 것입니다. ui.system_icons는 provider와 무관한 시맨틱 역할 45개를 제공합니다. zenit 자체 컴포넌트는 이것에만 의존하므로 벤더 이름이 공개 컴포넌트 계약에 새어 들어가지 않습니다.

진입점용도
ui.system_icons안정적인 시맨틱 역할 45개(close, search, alert, pointer…); 어떤 provider로도 컴파일되어야 하는 재사용 가능한 프레임워크 / 패키지 코드용
ui.iconsLucide 이름 2,026개; 제품 UI와 동적 구성용
ui.assets.common레거시 호환 아이콘 17개; 새 코드에는 권장하지 않음
ICON PATH
시맨틱 역할 → provider 매핑 → Asset → 아이콘 렌더 경로. provider를 바꾸면 매핑 모듈만 교체됩니다.
실제 zenit Storybook의 시맨틱 아이콘 story: 가상 커서가 역할, 크기, tint를 훑습니다. 전체 provider 카탈로그는 아래 웹 목록에 있습니다. /components/icons

아이콘 2,026개 전체

이름을 입력하면 즉시 필터링됩니다. 아이콘은 180개씩 불러오므로 페이지가 DOM 노드 2천여 개를 한 번에 만들지 않습니다. 아이콘을 클릭하면 바로 붙여 넣을 수 있는 ui.iconTint 호출이 나옵니다. 이스케이프가 필요한 이름(예: ui.icons.@"type")은 생성기 규칙을 따릅니다.

180 / 2,026

렌더링과 색조

빌드 시 gen-icons가 각 아이콘을 평탄화된 지오메트리로 바꿉니다(모든 Asset은 icon_id와 크기별 reps를 가집니다). 런타임에는 ui.iconTint가 논리 크기에 가장 가까운 rep을 골라 노드에 씁니다. 창 안에서 SVG 엔진은 돌지 않으며, 미리 평탄화된 지오메트리가 없는 Asset만 svgTint 래스터화로 폴백합니다. 너비 / 높이가 고정 픽셀이 아니면 Asset의 기본 크기(Lucide는 24)가 적용됩니다.

ui.iconTint는 테마를 따르는 색상에 가장 적합하며, 하나의 Asset을 어떤 크기와 색으로도 재사용할 수 있습니다. ui.icon은 tint를 받지 않고 흰색으로 그리므로 밝은 배경에서는 iconTint를 사용하세요. 불투명도 같은 BoxStyle 필드가 필요하면 ui.iconTintStyled를 사용합니다. 마운트된 아이콘의 색을 바꾸려면(hover, 선택 상태) node.setTint(color)를 호출하세요. icon 테이블 저장소와 svgTint 폴백의 image 저장소를 모두 처리하며, 노드에 둘 다 없으면 false를 반환합니다.

icons.zig
// Follow the theme: tint with a token color.
const settings = try ui.iconTint(
    cx,
    ui.icons.settings,
    cx.tokens.color.fg_secondary,
    .{ .width = .fixed(20), .height = .fixed(20) },
);

// Dynamic lookup by kebab-case source name (config files, user data).
const configured = ui.icons.get("circle-alert") orelse
    return error.UnknownIcon;
const warning = try ui.iconTint(cx, configured, cx.tokens.color.warning, .{
    .width = .fixed(24),
    .height = .fixed(24),
});

// Enumerate the whole registry.
for (ui.icons.all) |entry| {
    std.log.debug("{s}", .{entry.name});
}

시맨틱 아이콘 계약

컴포넌트 코드는 특정 벤더 이름에 묶이지 말고 ui.system_icons.close라고 써야 합니다. Lucide 프로필은 src/ui/system_icons_lucide.zig에서 역할 45개 모두를 구체적인 Asset에 매핑합니다. -Dicon-set으로 provider를 바꿔도 컴포넌트 API는 그대로입니다.

activity
alert
audio
check
close
search
heart
star
home
settings
notification
calendar
user
mail
trash
download
upload
edit
copy
lock
chevron_down
chevron_up
chevron_left
chevron_right
minus
plus
more_horizontal
cursor_default
cursor_click
pointer
move
not_allowed
grab
resize_horizontal
resize_vertical
resize_diagonal
wait
progress
help
warning
info
chevrons_up
pause
sun
moon

Lucide 이름이 다른 역할:

ui.system_iconsLucide 소스 이름
alertcircle-alert
audioheadphones
closex
homehouse
notificationbell
trashtrash-2
editpencil
more_horizontalellipsis
cursor_defaultmouse-pointer-2
cursor_clickmouse-pointer-click
pointerhand-pointing
not_allowedban
grabhand
resize_horizontalchevrons-left-right
resize_verticalchevrons-up-down
resize_diagonalexpand
waithourglass
progressloader-circle
helpcircle-help
warningtriangle-alert
semantic.zig
// Reusable code: depend on the role, not the provider's name.
const close = try ui.iconTint(cx, ui.system_icons.close, cx.tokens.color.fg_secondary, .{
    .width = .fixed(16),
    .height = .fixed(16),
});

// Icon-only button: no visible label, so set the accessible name explicitly.
const remove = try ui.widgets.Button(.{
    .icon_only = true,
    .icon_asset = ui.system_icons.trash,
    .variant = .ghost,
}).mount(scope, cx);
remove.behavior.interaction.a11y.label = "Delete";

이름, 업데이트, 라이선스

  • ✓

    두 가지 표기. Registry 조회는 Lucide의 kebab-case 소스 이름(ui.icons.get("circle-alert"))을 쓰고, Zig 상수는 하이픈을 밑줄로 바꿉니다(ui.icons.circle_alert).

  • ✓

    자동 이스케이프. Zig 키워드나 기본 타입 이름(iN / uN 포함)과 겹치거나 숫자로 시작하는 상수는 생성기가 이스케이프합니다. 예: ui.icons.@"type". 동적 get은 영향을 받지 않습니다.

  • ✓

    열거 가능. ui.icons.all은 이름순으로 정렬된 { name, asset } 배열이며, get은 이를 이진 탐색합니다.

  • ✓

    업스트림과 동일. SVG 파일은 업스트림과 바이트 단위로 같아 업데이트와 라이선스 감사가 깔끔합니다. 이름이 바뀐 아이콘이 남지 않도록 복사하기 전에 기존 파일을 삭제하세요.

  • ✓

    별도 라이선스. Lucide는 ISC License(src/ui/icons_oss/LICENSE)를 따르며 zenit 루트의 GPL-3.0-only 라이선스 적용 대상이 아닙니다.

update & verify
# Verify the Lucide profile (test-headless + storybook build); the worktree is not modified
bash scripts/switch_icon_set.sh lucide

# Regenerate the committed provider module after the SVG set changes
zig build gen-icons-lucide
zig build test-ui
zenit · 이중 라이선스오픈 소스 프로젝트는 GPL-3.0-only로 무료 사용할 수 있으며, 비공개 소스나 상용 제품에는 상용 라이선스가 필요합니다.작성자 연락처: zongyi.xzy#gmail.com (#을 @로 바꾸세요)zenit 5f9add5+wip 2026-09-30