Skip to content

ui: replace emojis with icons#80

Merged
keraliss merged 1 commit into
citadel-tech:mainfrom
hulxv:ui/replace-emojis
Mar 29, 2026
Merged

ui: replace emojis with icons#80
keraliss merged 1 commit into
citadel-tech:mainfrom
hulxv:ui/replace-emojis

Conversation

@hulxv
Copy link
Copy Markdown
Collaborator

@hulxv hulxv commented Mar 27, 2026

Replace emojis with icons to avoid font issues

Summary by CodeRabbit

  • Style
    • Replaced emoji icons with professional SVG icons throughout the application interface for improved visual consistency and polish. Updates affect all major screens including connection status indicators, transaction logs, market data displays, address management, swap operations, and user settings panels.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

This PR introduces an icon system using the lucide library. A new src/js/icons.js module exports icon-rendering helpers that convert lucide components to SVG strings. Multiple UI components are updated to replace hardcoded emoji characters with these rendered icon calls throughout the application.

Changes

Cohort / File(s) Summary
Icon System Foundation
package.json, src/js/icons.js
Added lucide dependency at ^1.7.0. New module exports 35+ icon-rendering functions that convert lucide icon components to inline SVG strings with configurable size and CSS classes.
Connection & Logging Components
src/components/connection/ConnectionStatus.js, src/components/log/Log.js
Replaced static emoji symbols with icon renders: warning glyph, lightbulb, refresh button, and folder icons for UI labels and status indicators.
Market & Trading Components
src/components/market/Market.js, src/components/swap/Coinswap.js, src/components/swap/Swap.js, src/components/swap/SwapHistory.js, src/components/swap/SwapReport.js
Replaced protocol badges (⚡, 🔒), status indicators (✓, ❌, 🔄), and transaction symbols with corresponding icon renders. Updated sync spinners, progress indicators, and transaction list status displays.
Wallet & Address Components
src/components/receive/Receive.js, src/components/receive/AddressList.js, src/components/wallet/TransactionsList.js
Replaced clipboard, inbox, error, and transaction-type emoji with icon renders. Updated button feedback (copy confirmation) and empty-state indicators to use SVG icons.
Settings & Initialization Components
src/components/settings/Settings.js, src/components/settings/FirstTimeSetup.js, src/components/send/Send.js, src/components/taker/TakerInitialization.js
Replaced emoji in setup wizards, connection status displays, validation errors, and success/failure alerts with icon renders. Updated button labels and result indicators.
Styling Updates
src/styles/output.css
Added .mr-1 and .align-middle utility classes for icon spacing and alignment. Removed .text-6xl utility class.

Possibly related PRs

  • App updates #72: Modifies overlapping UI components (Market, Receive/AddressList, Settings/FirstTimeSetup, Swap components, Log, TransactionsList) with related markup and rendering logic changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A carrot-load of icons, sprites so bright,
Lucide brings vector magic to the sight,
No more emoji scattered, plain and flat,
SVG renders where the emojis sat,
The UI hops with style and polish true! 🎨✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'ui: replace emojis with icons' accurately summarizes the main change across all modified files—a systematic replacement of emoji characters with SVG icon renderings throughout the UI components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/components/settings/FirstTimeSetup.js (1)

1076-1078: ⚠️ Potential issue | 🟡 Minor

Tor test button loses its icon after first test cycle.

On Line 1076, originalText is captured via textContent, and Line 1121 restores with textContent; this strips the SVG icon from the original label.

Also applies to: 1121-1122

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/FirstTimeSetup.js` around lines 1076 - 1078, The code
captures and restores the button label using textContent, which strips the SVG
icon; change the capture and restore to use innerHTML so the original HTML
(including the SVG) is preserved — replace uses of originalText =
btn.textContent and btn.textContent = ... restoration with innerHTML equivalents
(keep the temporary "Testing..." state and disabled toggles on btn unchanged) so
the SVG icon is retained when restoring the label for the Tor test button
(references: btn and originalText in FirstTimeSetup.js).
src/components/send/Send.js (1)

649-652: ⚠️ Potential issue | 🟡 Minor

Sign/Broadcast buttons lose their icons after first action.

On Line 649 and Line 691, textContent is cached from iconized buttons; restoring with textContent (Line 679/Line 762) removes SVG markup permanently for that button state.

♻️ Proposed fix
-    const originalText = signBtn.textContent;
+    const originalHtml = signBtn.innerHTML;
@@
-      signBtn.textContent = originalText;
+      signBtn.innerHTML = originalHtml;
-    const originalText = broadcastBtn.textContent;
+    const originalHtml = broadcastBtn.innerHTML;
@@
-      broadcastBtn.textContent = originalText;
+      broadcastBtn.innerHTML = originalHtml;

Also applies to: 679-680, 691-694, 762-763

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/send/Send.js` around lines 649 - 652, The code caches and
restores button text using signBtn.textContent (and similarly
broadcastBtn.textContent), which strips SVG/icon markup; change the
caching/restoring to use signBtn.innerHTML (and broadcastBtn.innerHTML) so the
original HTML (including SVG icons) is preserved when disabling/enabling and
when setting "Signing..."/"Broadcasting..." states; update all spots that assign
or restore the cached value (where originalText/originalBroadcastText are set
and later restored) to use innerHTML instead of textContent.
src/components/market/Market.js (1)

17-37: 🧹 Nitpick | 🔵 Trivial

Replace the remaining Unified glyph with an icon helper for consistency.

Line 27 still uses a raw glyph ('◈') while the other protocol badges use SVG helpers. This keeps one font-dependent path in the same UI area.

♻️ Proposed refactor
       case 'Unified':
         return {
           label: 'Unified',
-          icon: '◈',
+          icon: icons.link(14),
           classes: 'bg-emerald-500/20 text-emerald-400',
         };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/market/Market.js` around lines 17 - 37, The Unified case in
the protocol switch returns a raw glyph ('◈') instead of using the SVG icon
helpers used by Taproot and Legacy; update the Unified branch inside the switch
(case 'Unified') to use the icons helper (e.g., icons.diamond(14) or the
appropriate existing icon helper) and keep the same label and classes, ensuring
the import/usage matches how icons.zap and icons.lock are used so the Unified
badge is rendered via the SVG helper rather than a font glyph.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/settings/FirstTimeSetup.js`:
- Around line 811-814: The code currently injects raw error text into the DOM
via errorDiv.innerHTML (using icons.xCircle(...) and ${message}) which can
render untrusted markup; locate the error rendering in FirstTimeSetup.js where
errorDiv.innerHTML is used and replace it with DOM-safe construction: create the
container element, insert the icon in a safe way (e.g., create an icon
element/node or sanitize/parse only the known SVG string from icons.xCircle into
a DOM node), then create a separate span/div for the message and set its
textContent to message (do not interpolate message into innerHTML). Apply the
same change to the other occurrence around lines 1059–1062 so all user-facing
errors use textContent for the message and only insert trusted markup for icons
via DOM nodes.

In `@src/components/settings/Settings.js`:
- Around line 645-649: The copy-feedback code currently saves btn.textContent
which strips the SVG icon; change it to cache and restore the button's innerHTML
instead (e.g., replace originalText = btn.textContent with originalHTML =
btn.innerHTML and restore btn.innerHTML = originalHTML inside the setTimeout) in
the copy handler where icons.check(14, 'mr-1') + ' Copied!' is used; make the
same innerHTML-based change for the second occurrence of this pattern (the block
around the btn/textContent restore at the later spot).

In `@src/components/swap/Coinswap.js`:
- Around line 185-186: updateHopStatus currently writes SVG markup to an element
using textContent, so SVG strings passed from callers like icons.check(...)
render as raw text; change updateHopStatus to assign the markup to
element.innerHTML (or otherwise insert the SVG markup as HTML) instead of
textContent so the icons render correctly, and verify callers that pass SVG
strings (e.g., the places invoking icons.check(...)) keep passing their markup
unchanged.

In `@src/js/icons.js`:
- Around line 63-70: The toSvg function returns inline SVGs that should be
hidden from assistive tech by default; modify toSvg(iconData, size, cls) so the
generated <svg> includes accessibility defaults for decorative icons by adding
aria-hidden="true" and focusable="false" to the returned SVG string (keep
existing class handling and other attributes intact) so assistive technologies
won't announce these paired-with-text icons.
- Around line 14-51: The import of Lucide icons currently uses a fragile
relative path ("../../node_modules/lucide/dist/esm/lucide.js"); update the
module specifier to import from the package entrypoint (e.g., "lucide") instead.
Locate the import statement that brings in Check, CheckCircle, XCircle,
AlertTriangle, RefreshCw, Loader, ArrowDownCircle, ArrowUpCircle, Package, Save,
ExternalLink, Zap, Copy, Search, Lock, Key, KeyRound, ClipboardCopy, Info,
Timer, Link, Handshake, Receipt, FileText, CircleDollarSign, ShieldCheck,
Recycle, Globe, Inbox, Radio, Hourglass, FolderOpen, Folder, Lightbulb,
PlusCircle, PauseCircle and replace the relative node_modules path with the
package specifier so bundlers and dependency layouts resolve the public API
correctly.

---

Outside diff comments:
In `@src/components/market/Market.js`:
- Around line 17-37: The Unified case in the protocol switch returns a raw glyph
('◈') instead of using the SVG icon helpers used by Taproot and Legacy; update
the Unified branch inside the switch (case 'Unified') to use the icons helper
(e.g., icons.diamond(14) or the appropriate existing icon helper) and keep the
same label and classes, ensuring the import/usage matches how icons.zap and
icons.lock are used so the Unified badge is rendered via the SVG helper rather
than a font glyph.

In `@src/components/send/Send.js`:
- Around line 649-652: The code caches and restores button text using
signBtn.textContent (and similarly broadcastBtn.textContent), which strips
SVG/icon markup; change the caching/restoring to use signBtn.innerHTML (and
broadcastBtn.innerHTML) so the original HTML (including SVG icons) is preserved
when disabling/enabling and when setting "Signing..."/"Broadcasting..." states;
update all spots that assign or restore the cached value (where
originalText/originalBroadcastText are set and later restored) to use innerHTML
instead of textContent.

In `@src/components/settings/FirstTimeSetup.js`:
- Around line 1076-1078: The code captures and restores the button label using
textContent, which strips the SVG icon; change the capture and restore to use
innerHTML so the original HTML (including the SVG) is preserved — replace uses
of originalText = btn.textContent and btn.textContent = ... restoration with
innerHTML equivalents (keep the temporary "Testing..." state and disabled
toggles on btn unchanged) so the SVG icon is retained when restoring the label
for the Tor test button (references: btn and originalText in FirstTimeSetup.js).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6a0edc0d-a599-499e-a96f-e1f706097da9

📥 Commits

Reviewing files that changed from the base of the PR and between 0b3709a and 0e0797e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (17)
  • package.json
  • src/components/connection/ConnectionStatus.js
  • src/components/log/Log.js
  • src/components/market/Market.js
  • src/components/receive/AddressList.js
  • src/components/receive/Receive.js
  • src/components/send/Send.js
  • src/components/settings/FirstTimeSetup.js
  • src/components/settings/Settings.js
  • src/components/swap/Coinswap.js
  • src/components/swap/Swap.js
  • src/components/swap/SwapHistory.js
  • src/components/swap/SwapReport.js
  • src/components/taker/TakerInitialization.js
  • src/components/wallet/TransactionsList.js
  • src/js/icons.js
  • src/styles/output.css

Comment on lines 811 to 814
errorDiv.innerHTML = `
<div class="flex items-center">
<span class="text-sm text-red-400"> ${message}</span>
<span class="text-sm text-red-400">${icons.xCircle(14, 'mr-1')} ${message}</span>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Do not inject raw error messages via innerHTML.

At Line 813 and Line 1061, runtime error text is directly interpolated into HTML. If an error string contains markup, it will be rendered. Render the message with textContent on a dedicated element instead.

🛡️ Proposed fix pattern
-        errorDiv.innerHTML = `
-          <div class="flex items-center">
-            <span class="text-sm text-red-400">${icons.xCircle(14, 'mr-1')} ${message}</span>
-          </div>
-        `;
+        errorDiv.innerHTML = `
+          <div class="flex items-center">
+            ${icons.xCircle(14, 'mr-1')}
+            <span id="setup-error-text" class="text-sm text-red-400"></span>
+          </div>
+        `;
+        errorDiv.querySelector('#setup-error-text').textContent = message;

As per coding guidelines "Validate all user inputs".

Also applies to: 1059-1062

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/FirstTimeSetup.js` around lines 811 - 814, The code
currently injects raw error text into the DOM via errorDiv.innerHTML (using
icons.xCircle(...) and ${message}) which can render untrusted markup; locate the
error rendering in FirstTimeSetup.js where errorDiv.innerHTML is used and
replace it with DOM-safe construction: create the container element, insert the
icon in a safe way (e.g., create an icon element/node or sanitize/parse only the
known SVG string from icons.xCircle into a DOM node), then create a separate
span/div for the message and set its textContent to message (do not interpolate
message into innerHTML). Apply the same change to the other occurrence around
lines 1059–1062 so all user-facing errors use textContent for the message and
only insert trusted markup for icons via DOM nodes.

Comment on lines 645 to 649
const originalText = btn.textContent;
btn.textContent = '✓ Copied!';
btn.innerHTML = icons.check(14, 'mr-1') + ' Copied!';
setTimeout(() => {
btn.textContent = originalText;
}, 2000);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Restore button HTML, not plain text, after copy feedback.

originalText = btn.textContent (Line 645 / Line 707) drops the SVG icon, so after timeout the button no longer shows the icon label. Cache/restore innerHTML instead.

♻️ Proposed fix
-        const originalText = btn.textContent;
+        const originalHtml = btn.innerHTML;
         btn.innerHTML = icons.check(14, 'mr-1') + ' Copied!';
         setTimeout(() => {
-          btn.textContent = originalText;
+          btn.innerHTML = originalHtml;
         }, 2000);
-        const originalText = btn.textContent;
+        const originalHtml = btn.innerHTML;
         btn.innerHTML = icons.check(14, 'mr-1') + ' Copied!';
         setTimeout(() => {
-          btn.textContent = originalText;
+          btn.innerHTML = originalHtml;
         }, 2000);

Also applies to: 707-711

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/Settings.js` around lines 645 - 649, The
copy-feedback code currently saves btn.textContent which strips the SVG icon;
change it to cache and restore the button's innerHTML instead (e.g., replace
originalText = btn.textContent with originalHTML = btn.innerHTML and restore
btn.innerHTML = originalHTML inside the setTimeout) in the copy handler where
icons.check(14, 'mr-1') + ' Copied!' is used; make the same innerHTML-based
change for the second occurrence of this pattern (the block around the
btn/textContent restore at the later spot).

Comment on lines +185 to 186
updateHopStatus(i, `${icons.check(14, 'mr-1')} Complete`, 'green');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Hop status icons won’t render with the current sink.

These callsites now pass SVG markup into updateHopStatus(...), but updateHopStatus writes to textContent (Line 150). Result: raw SVG text appears instead of icons.

♻️ Proposed fix
-      hopStatus.textContent = statusText;
+      hopStatus.innerHTML = statusText;

Also applies to: 321-322, 346-347

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/swap/Coinswap.js` around lines 185 - 186, updateHopStatus
currently writes SVG markup to an element using textContent, so SVG strings
passed from callers like icons.check(...) render as raw text; change
updateHopStatus to assign the markup to element.innerHTML (or otherwise insert
the SVG markup as HTML) instead of textContent so the icons render correctly,
and verify callers that pass SVG strings (e.g., the places invoking
icons.check(...)) keep passing their markup unchanged.

Comment thread src/js/icons.js
Comment on lines +14 to +51
import {
Check,
CheckCircle,
XCircle,
AlertTriangle,
RefreshCw,
Loader,
ArrowDownCircle,
ArrowUpCircle,
Package,
Save,
ExternalLink,
Zap,
Copy,
Search,
Lock,
Key,
KeyRound,
ClipboardCopy,
Info,
Timer,
Link,
Handshake,
Receipt,
FileText,
CircleDollarSign,
ShieldCheck,
Recycle,
Globe,
Inbox,
Radio,
Hourglass,
FolderOpen,
Folder,
Lightbulb,
PlusCircle,
PauseCircle,
} from '../../node_modules/lucide/dist/esm/lucide.js';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

What is the officially supported ES module import path for the lucidenpm package, and is importing fromnode_modules/lucide/dist/esm/lucide.js considered a stable/public API?

💡 Result:

The officially supported ES module import path for the lucide npm package is import { createIcons, Menu } from 'lucide';. Icons and functions are imported directly from the package specifier 'lucide', which resolves to the ESM build via standard Node.js module resolution (likely configured in package.json "module" or "exports" fields). Official documentation consistently shows this usage for Vanilla JS/ESM environments, emphasizing tree-shaking by importing specific icons. Importing from node_modules/lucide/dist/esm/lucide.js is not considered a stable/public API. This is an internal dist path exposed due to the package structure (confirmed by npm files listing dist/esm/), but docs never recommend direct dist imports. Similar paths like dist/esm/lucide-react.js appear in issues as internal resolutions, and direct dist usage (e.g., dynamicIconImports.js) leads to errors or requires workarounds, indicating it's unsupported for public consumption. Use the package specifier for stability.

Citations:


Replace the relative node_modules import path with the package specifier.

Line 14-51 imports lucide via a relative filesystem path (../../node_modules/lucide/dist/esm/lucide.js) instead of the official package entrypoint. This is fragile and unsupported—the dist/ directory is an internal implementation detail, not a public API. Direct dist imports can break across bundler configurations and when dependency layouts change.

🔧 Proposed fix
-} from '../../node_modules/lucide/dist/esm/lucide.js';
+} from 'lucide';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {
Check,
CheckCircle,
XCircle,
AlertTriangle,
RefreshCw,
Loader,
ArrowDownCircle,
ArrowUpCircle,
Package,
Save,
ExternalLink,
Zap,
Copy,
Search,
Lock,
Key,
KeyRound,
ClipboardCopy,
Info,
Timer,
Link,
Handshake,
Receipt,
FileText,
CircleDollarSign,
ShieldCheck,
Recycle,
Globe,
Inbox,
Radio,
Hourglass,
FolderOpen,
Folder,
Lightbulb,
PlusCircle,
PauseCircle,
} from '../../node_modules/lucide/dist/esm/lucide.js';
import {
Check,
CheckCircle,
XCircle,
AlertTriangle,
RefreshCw,
Loader,
ArrowDownCircle,
ArrowUpCircle,
Package,
Save,
ExternalLink,
Zap,
Copy,
Search,
Lock,
Key,
KeyRound,
ClipboardCopy,
Info,
Timer,
Link,
Handshake,
Receipt,
FileText,
CircleDollarSign,
ShieldCheck,
Recycle,
Globe,
Inbox,
Radio,
Hourglass,
FolderOpen,
Folder,
Lightbulb,
PlusCircle,
PauseCircle,
} from 'lucide';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/js/icons.js` around lines 14 - 51, The import of Lucide icons currently
uses a fragile relative path ("../../node_modules/lucide/dist/esm/lucide.js");
update the module specifier to import from the package entrypoint (e.g.,
"lucide") instead. Locate the import statement that brings in Check,
CheckCircle, XCircle, AlertTriangle, RefreshCw, Loader, ArrowDownCircle,
ArrowUpCircle, Package, Save, ExternalLink, Zap, Copy, Search, Lock, Key,
KeyRound, ClipboardCopy, Info, Timer, Link, Handshake, Receipt, FileText,
CircleDollarSign, ShieldCheck, Recycle, Globe, Inbox, Radio, Hourglass,
FolderOpen, Folder, Lightbulb, PlusCircle, PauseCircle and replace the relative
node_modules path with the package specifier so bundlers and dependency layouts
resolve the public API correctly.

Comment thread src/js/icons.js
Comment on lines +63 to +70
function toSvg(iconData, size, cls) {
const children = iconData.map(nodeToString).join('');
const baseClass = 'inline-block align-middle flex-shrink-0';
const classAttr = cls
? `class="${baseClass} ${cls}"`
: `class="${baseClass}"`;
return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ${classAttr}>${children}</svg>`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add decorative-icon accessibility defaults to generated SVG.

Since these icons are primarily paired with visible text labels, defaulting them to hidden for assistive tech avoids unnecessary screen-reader noise.

♿ Proposed refactor
-  return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ${classAttr}>${children}</svg>`;
+  return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" ${classAttr}>${children}</svg>`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function toSvg(iconData, size, cls) {
const children = iconData.map(nodeToString).join('');
const baseClass = 'inline-block align-middle flex-shrink-0';
const classAttr = cls
? `class="${baseClass} ${cls}"`
: `class="${baseClass}"`;
return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ${classAttr}>${children}</svg>`;
}
function toSvg(iconData, size, cls) {
const children = iconData.map(nodeToString).join('');
const baseClass = 'inline-block align-middle flex-shrink-0';
const classAttr = cls
? `class="${baseClass} ${cls}"`
: `class="${baseClass}"`;
return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" ${classAttr}>${children}</svg>`;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/js/icons.js` around lines 63 - 70, The toSvg function returns inline SVGs
that should be hidden from assistive tech by default; modify toSvg(iconData,
size, cls) so the generated <svg> includes accessibility defaults for decorative
icons by adding aria-hidden="true" and focusable="false" to the returned SVG
string (keep existing class handling and other attributes intact) so assistive
technologies won't announce these paired-with-text icons.

@keraliss keraliss merged commit c44f4c8 into citadel-tech:main Mar 29, 2026
1 check passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 3, 2026
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.

2 participants