Agent Skillsmaxrave-dev/SimpMusic › simpmusic-icons

simpmusic-icons

GitHub

SimpMusic图标管理规范,指导如何添加或修改Material Symbols ImageVector图标,避免依赖XML或外部库,提供生成、配置及在Compose中使用的具体步骤与陷阱。

.claude/skills/simpmusic-icons/SKILL.md maxrave-dev/SimpMusic

Trigger Scenarios

添加新图标 替换现有图标 解决ImageVector类型错误

Install

npx skills add maxrave-dev/SimpMusic --skill simpmusic-icons -g -y
More Options

Non-standard path

npx skills add https://github.com/maxrave-dev/SimpMusic/tree/dev/.claude/skills/simpmusic-icons -g -y

Use without installing

npx skills use maxrave-dev/SimpMusic@simpmusic-icons

指定 Agent (Claude Code)

npx skills add maxrave-dev/SimpMusic --skill simpmusic-icons -a claude-code -g -y

安装 repo 全部 skill

npx skills add maxrave-dev/SimpMusic --all -g -y

预览 repo 内 skill

npx skills add maxrave-dev/SimpMusic --list

SKILL.md

Frontmatter
{
    "name": "simpmusic-icons",
    "description": "Add or change an icon in SimpMusic. Every icon is a generated Material Symbols ImageVector under ui\/icon, addressed as SimpIcons.<Name> — there is no material-icons dependency and no XML icon drawable. Use when adding a new icon, replacing one, or hitting ImageVector\/Painter type errors."
}

SimpMusic Icons

Icons live in composeApp/src/commonMain/kotlin/com/maxrave/simpmusic/ui/icon/, one file per icon, each declaring val SimpIcons.<Name>: ImageVector.

Two things are deliberately absent and must not come back:

  • the material-icons-core / material-icons-extended dependency (Icons.Rounded.*)
  • XML icon drawables in composeResources/drawable used through painterResource(...)

Adding an icon

Google's font service generates the Compose file directly — no conversion tool needed:

curl -sfL --compressed \
  "https://fonts.gstatic.com/render/v1/Material+Symbols+Rounded/24dp/<symbol_name>.kt?var=opsz,wght,FILL,GRAD,ROND@24,400,1,0,50" \
  -o <PascalName>.kt

Keep these axes identical for every icon, or the set stops looking like one set: Rounded, opsz 24, wght 400, GRAD 0, ROND 50, FILL=1.

Use FILL=0 only for the "off" half of a state pair — FavoriteBorder, AddCircleOutline, DownloadForOfflineOutlined. At FILL=1 the off state renders identically to the on state and the distinction is lost.

Then edit the downloaded file:

  1. package com.example.testpackage com.maxrave.simpmusic.ui.icon
  2. public val <symbol_name>: ImageVectorval SimpIcons.<PascalName>: ImageVector
  3. Rename the backing field _<symbol_name>_<PascalName>, and name = "<symbol_name>""<PascalName>"
  4. If the glyph must flip in RTL, add autoMirror = true, inside ImageVector.Builder(...) (currently: ArrowForwardIos, QueueMusic, Sort, TrendingUp, VolumeOff, VolumeUp)

Using an icon

import com.maxrave.simpmusic.ui.icon.PlayArrow   // per-icon import, required
import com.maxrave.simpmusic.ui.icon.SimpIcons

Icon(SimpIcons.PlayArrow, contentDescription = null)

The project's own icon buttons take an ImageVector: RippleIconButton(imageVector = …), LiquidGlassIconButton(imageVector = …), ActionButton(icon = …).

Traps

Every icon needs its own import. val SimpIcons.X is an extension property; importing the SimpIcons object alone leaves it unresolved. This is the same mechanism that lets R8 strip unused icons, so never "simplify" the set into a map or a when — that would ship all of them.

ImageVector is not a Painter. Icon and Image have overloads for both, so those look fine. These do not, and need rememberVectorPainter(SimpIcons.X):

  • AsyncImage(placeholder = …, error = …)
  • anything drawn inside a DrawScope (with(painter) { draw(...) })
  • custom composables whose parameter is typed Painter

Do not text-replace blindly. A regex swap of Res.drawable.XSimpIcons.X produced 40 compile errors in one pass: it also hit Painter parameters, and it landed inside multi-line painterResource(\n Res.drawable.X,\n) calls, leaving the syntactically valid but wrong painterResource(SimpIcons.X).

Do not replace an icon whose colour carries meaning. These stay as resources:

File Why
baseline_downloaded.xml #FF00A0CB — the blue is the "downloaded" state
baseline_favorite_24.xml #D10000 — the red is the "liked" state
mono.xml, monochrome.xml SimpMusic logos (#0AEAF8 / black)
app_icon.png, circle_app_icon.png, holder*.png bitmaps, not icons

If a state needs that colour with a shared symbol, pass it explicitly — e.g. ActionButton's iconColor = Color(0xFF00A0CB) for the downloaded state.

Verify the symbol name exists before assuming a mapping, against google/material-design-iconsvariablefont/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].codepoints. Legacy names such as favorite_border, add_circle_outline and thumb_up_alt do still exist; person_add_alt_1 does not (use person_add).

The response is gzipped even when the request asks for identitycurl --compressed, or decompress by magic bytes (\x1f\x8b) when fetching from a script.

Version History

  • 973fbc8 Current 2026-08-04 18:59

Same Skill Collection

.claude/skills/android-accessibility/SKILL.md
.claude/skills/android-architecture/SKILL.md
.claude/skills/android-coroutines/SKILL.md
.claude/skills/android-data-layer/SKILL.md
.claude/skills/android-emulator-skill/SKILL.md
.claude/skills/android-gradle-logic/SKILL.md
.claude/skills/android-retrofit/SKILL.md
.claude/skills/android-testing/SKILL.md
.claude/skills/android-viewmodel/SKILL.md
.claude/skills/coil-compose/SKILL.md
.claude/skills/compose-navigation/SKILL.md
.claude/skills/compose-performance-audit/SKILL.md
.claude/skills/compose-ui/SKILL.md
.claude/skills/gradle-build-performance/SKILL.md
.claude/skills/jetpack-compose/SKILL.md
.claude/skills/kotlin-concurrency-expert/SKILL.md
.claude/skills/marketing-ideas/SKILL.md
.claude/skills/mobile-android-design/SKILL.md
.claude/skills/xml-to-compose-migration/SKILL.md
.claude/skills/find-skills/SKILL.md
.claude/skills/kmp/SKILL.md
.claude/skills/ui-ux-pro-max/SKILL.md

Metadata

Files
0
Version
973fbc8
Hash
c3939377
Indexed
2026-08-04 18:59

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-05 04:19
浙ICP备14020137号-1 $Гость$