Skip to content

feat: add global icon color override - #457

Open
CoffeePatch wants to merge 5 commits into
ujiro99:mainfrom
CoffeePatch:feature/global-icon-color-override
Open

feat: add global icon color override#457
CoffeePatch wants to merge 5 commits into
ujiro99:mainfrom
CoffeePatch:feature/global-icon-color-override

Conversation

@CoffeePatch

Copy link
Copy Markdown

Summary

  • Add a global Icon Color setting for the popup
  • Allow individual icons to override the global color
  • Recolor supported SVG and PNG UI icons
  • Automatically preserve recognized website/brand favicons
  • Add tests for icon recoloring and favicon detection

Verification

  • Tests: 1116 passed
  • ESLint: passed
  • Extension build: passed
  • Manually tested in Brave

Copilot AI lite review requested due to automatic review settings September 13, 2026 12:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved moderate findings affect favicon classification and accessibility.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a global icon color override, per-icon overrides, SVG/PNG recoloring, favicon detection, tests, and localization updates.

Changes:

  • Added global and per-icon color settings.
  • Implemented icon recoloring with favicon preservation.
  • Updated schemas, popup/menu UI, styles, tests, and locales.
File summaries
File Summary
packages/shared/src/types/command.ts Extends command icon configuration types.
packages/extension/src/types/schema.ts Updates command and folder validation.
packages/extension/src/types/schema.test.ts Tests the new schema fields.
packages/extension/src/types/index.ts Updates extension-side types.
packages/extension/src/services/option/userStyles.ts Adds icon color style attributes.
packages/extension/src/lib/favicon.ts Adds favicon detection. Moderate (2 votes): suffix-only host comparison can misclassify unrelated sites.
packages/extension/src/lib/favicon.test.ts Tests favicon detection.
packages/extension/src/hooks/usePopupContext.tsx Provides icon color state through popup context.
packages/extension/src/const.ts Adds icon color constants.
packages/extension/src/components/Popup.tsx Applies global icon color.
packages/extension/src/components/option/field/IconField.tsx Adds the per-icon override switch. Moderate (2 votes): the switch lacks an accessible name.
packages/extension/src/components/option/editor/UserStyleList.tsx Adds icon color to the settings list.
packages/extension/src/components/option/editor/FolderEditDialog.tsx Adds folder icon-color defaults.
packages/extension/src/components/option/editor/CommandEditDialog.tsx Adds command icon-color defaults.
packages/extension/src/components/menu/MenuItem.tsx Handles icon recoloring and favicon status.
packages/extension/src/components/menu/MenuImage.tsx Implements SVG/PNG recoloring. Moderate (2 votes): empty-alt decorative images retain an empty role="img"/ARIA label.
packages/extension/src/components/menu/MenuImage.test.tsx Tests recolored icon rendering.
packages/extension/src/components/menu/MenuFolder.tsx Applies folder icon settings. Moderate (1 vote): forcing isFavicon={false} recolors recognized folder favicons.
packages/extension/src/components/menu/Menu.tsx Shares original icon URLs through context.
packages/extension/src/components/menu/Menu.module.css Adds mask display styles.
packages/extension/public/_locales/zh_CN/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Chinese.
packages/extension/public/_locales/ru/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Russian.
packages/extension/public/_locales/pt_PT/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Portuguese.
packages/extension/public/_locales/pt_BR/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Portuguese.
packages/extension/public/_locales/ms/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Malay.
packages/extension/public/_locales/ko/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Korean.
packages/extension/public/_locales/ja/messages.json Adds Japanese messages.
packages/extension/public/_locales/it/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Italian.
packages/extension/public/_locales/id/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Indonesian.
packages/extension/public/_locales/hi/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Hindi.
packages/extension/public/_locales/fr/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into French.
packages/extension/public/_locales/es/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into Spanish.
packages/extension/public/_locales/en/messages.json Adds English messages.
packages/extension/public/_locales/de/messages.json Adds messages; three remain in English. Nit (1 vote): translate them into German.
Review details

Suppressed comments (13)

packages/extension/public/_locales/de/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはドイツ語化されているため、この設定だけ英語表示になります。3キーをドイツ語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/es/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはスペイン語化されているため、この設定だけ英語表示になります。3キーをスペイン語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/fr/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはフランス語化されているため、この設定だけ英語表示になります。3キーをフランス語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/hi/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはヒンディー語化されているため、この設定だけ英語表示になります。3キーをヒンディー語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/id/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはインドネシア語化されているため、この設定だけ英語表示になります。3キーをインドネシア語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/it/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはイタリア語化されているため、この設定だけ英語表示になります。3キーをイタリア語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/ko/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージは韓国語化されているため、この設定だけ英語表示になります。3キーを韓国語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/ms/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはマレー語化されているため、この設定だけ英語表示になります。3キーをマレー語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/pt_BR/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはポルトガル語化されているため、この設定だけ英語表示になります。3キーをポルトガル語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/pt_PT/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはポルトガル語化されているため、この設定だけ英語表示になります。3キーをポルトガル語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/ru/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージはロシア語化されているため、この設定だけ英語表示になります。3キーをロシア語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/public/_locales/zh_CN/messages.json:726

  • このロケールで追加されたアイコン色設定の3メッセージが英語のままです。周辺の既存メッセージは中国語化されているため、この設定だけ英語表示になります。3キーを中国語に翻訳してください。
  "Option_userStyles_option_icon_color": {
    "message": "Icon Color"
  },
  "Option_userStyles_desc_icon_color": {
    "message": "Specify icon color. Default: #0F172A"

packages/extension/src/components/menu/MenuFolder.tsx:147

  • ここで isFavicon={false} を固定すると、フォルダに favicon.ico などの認識可能なブランドアイコンを設定しても常に UI アイコン扱いになり、グローバル色でマスクされます。フォルダについてもキャッシュ前の URL を保持して isFaviconIcon で判定するか、この値を自動判定に委ねてください。
            isFavicon={false}
  • Files reviewed: 34/34 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/extension/src/components/menu/MenuImage.tsx Outdated
Comment thread packages/extension/src/components/option/field/IconField.tsx
Comment thread packages/extension/src/lib/favicon.ts Outdated
@ujiro99

ujiro99 commented Sep 14, 2026

Copy link
Copy Markdown
Owner

@CoffeePatch
Thank you for the implementation!

I especially like the technique of applying a custom color to monochrome PNG icons using CSS masks.
I think it's a great approach.

There are a few points regarding the specification and detection logic that I'd like you to review and,
if possible, update:

  • In packages/extension/src/lib/favicon.ts, regarding the isIconLibrary check in isFaviconIcon around line 107: I'd prefer checks for specific URLs or services to be handled explicitly in Steps 1–3 above, rather than through the isIconLibrary logic. I think this would make the intent of each rule clearer and keep the domain-based detection more generic.

  • For getRegistrableDomain, maintaining our own domain-parsing logic could become difficult over time, especially with the variety of public suffixes. Could you use tldts instead?
    https://www.npmjs.com/package/tldts

  • Regarding the setting name overrideGlobalIconColor, based on its actual behavior, I wonder if exclude would be more appropriate than override. As I understand it, this option excludes an individual icon from the global icon color rather than overriding the global color with another value. Something like excludeFromGlobalIconColor might make the behavior clearer.

Thanks again for working on this!

… icon library check

- Replace custom registrable domain parsing with tldts
- Keep isIconLibrary generic and keep service-specific asset checks explicit
- Determine favicon classification based on actual icon URL instead of command openMode
- Update favicon detection tests
…me setting

- Rename overrideGlobalIconColor to excludeFromGlobalIconColor across types, schemas, and locales
- Automatically preserve original colors for genuine favicons without persisting manual settings
- Enable recoloring for custom icons when manual exclusion is off
- Keep manual exclusion toggle functional for custom icons
…icon protection

- Add tests for MenuItem and MenuImage rendering paths with custom icons and genuine favicons
- Add tests for dynamic URL changes and state preservation in IconField
- Verify recoloring for AI Prompt command with custom Flaticon/Iconfinder PNGs
@CoffeePatch

Copy link
Copy Markdown
Author

@ujiro99

Thank you for the suggestions! I have addressed all three points:

  • Kept isIconLibrary generic and moved service-specific checks into the explicit detection steps.
  • Replaced the custom registrable-domain parsing logic with tldts.
  • Renamed overrideGlobalIconColor to excludeFromGlobalIconColor.

I also added tests and verified the changes with lint, TypeScript checks, the extension build, and manual browser testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants