Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat (icons): Icons API end points for retrieving icons.#209

Open
dlabaj wants to merge 7 commits intomainfrom
icons-api
Open

feat (icons): Icons API end points for retrieving icons.#209
dlabaj wants to merge 7 commits intomainfrom
icons-api

Conversation

@dlabaj
Copy link
Contributor

@dlabaj dlabaj commented Feb 4, 2026

Closes issue #173 by adding support for PF Icons.

Summary by CodeRabbit

  • New Features

    • New API endpoints to list icons (with metadata and optional filter) and to return individual icon SVGs; includes prebuilt/prerendered icon index and SVG assets for reliability and performance.
    • Utilities to enumerate, filter, parse, and render icons to SVG.
  • Documentation

    • OpenAPI/spec updated to document the new icon endpoints.
  • Tests

    • Comprehensive tests covering listing, filtering, SVG retrieval, and error cases.
  • Chores

    • Added react-icons dependency.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 4, 2026

Deploying patternfly-doc-core with  Cloudflare Pages  Cloudflare Pages

Latest commit: 76d907d
Status: ✅  Deploy successful!
Preview URL: https://a3cf76b6.patternfly-doc-core.pages.dev
Branch Preview URL: https://icons-api.patternfly-doc-core.pages.dev

View logs

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

Walkthrough

Adds react-icons integration and new icon APIs: endpoints to list/filter icons and serve per-icon SVGs, pre-rendered icons index and per-set SVGs, utilities to load/filter/render icons, OpenAPI and API index updates, SVG response helper, and comprehensive tests.

Changes

Cohort / File(s) Summary
Dependencies
package.json
Added react-icons dependency.
API Routes — runtime
src/pages/api/[version]/icons/index.ts, src/pages/api/[version]/icons/[iconName].ts, src/pages/api/index.ts
New GET handlers (export prerender = false, GET) for listing icons (optional filter) and returning SVG by set_icon id; API index updated to advertise endpoints; validate version and return 400/404/500 as appropriate.
OpenAPI / Spec
src/pages/api/openapi.json.ts
Added OpenAPI paths for GET /{version}/icons and GET /{version}/icons/{icon-name} with parameters, response schemas, and operationIds.
Icons Utilities (runtime & build)
src/utils/icons/reactIcons.ts, src/utils/icons/fetch.ts
New react-icons integration: IconMetadata type, dynamic imports of icon sets, getAllIcons, filterIcons, getIconSvg, getIconSvgsForSet, parseIconId; fetch helpers fetchIconsIndex and fetchIconSvgs for pre-rendered assets.
API Helpers
src/utils/apiHelpers.ts
Expanded getHeaders to include image/svg+xml and added createSvgResponse(content, status) for SVG responses.
Pre-rendered Index / SVG assets
src/pages/iconsIndex.json.ts, src/pages/iconsSvgs/[setId].json.ts
Added pre-rendered icons index (prerender = true, GET) and per-set SVG JSON routes with getStaticPaths and GET to serve prebuilt SVG maps.
Tests
src/__tests__/pages/api/__tests__/[version]/icons/index.test.ts, src/__tests__/pages/api/__tests__/[version]/icons/[iconName].test.ts
New test suites covering listing, filtering (case-insensitive), empty results, SVG retrieval, and error cases (400/404/500); mocks for react-icons utilities and index fetch.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant API as Icons API Route
    participant Index as Icons Index (iconsIndex.json / fetchApiIndex)
    participant Utils as ReactIcons Utils
    participant RN as node_modules/react-icons

    Client->>API: GET /api/{version}/icons[?filter] or /api/{version}/icons/{set_icon}
    API->>Index: fetchIconsIndex(origin)
    Index-->>API: icons index (list)
    alt version exists
        API->>Utils: filterIcons / getIconSvg
        Utils->>RN: dynamic import icon set
        RN-->>Utils: icon components / metadata
        Utils-->>API: icons list or SVG markup
        API-->>Client: 200 JSON or image/svg+xml
    else version missing
        API-->>Client: 400 or 404 error
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • Add API support for icons #173 — Implements matching icon listing and per-icon SVG endpoints plus react-icons utilities; likely the same feature area.

Possibly related PRs

Suggested reviewers

  • wise-king-sullyman
  • kmcfaul
  • thatblindgeye
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 'feat (icons): Icons API end points for retrieving icons' directly describes the main change—adding API endpoints for icon retrieval. It clearly summarizes the primary purpose of the PR.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch icons-api

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
Contributor

@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: 1

🤖 Fix all issues with AI agents
In `@src/__tests__/pages/api/__tests__/`[version]/icons/index.test.ts:
- Line 100: The test's assertion calls expect(body.icons.every((i: { name:
string }) => i.name.includes('circle'))) but never asserts a value, so it always
passes; update the assertion to actually check the boolean (e.g., call
.toBe(true) or .toBeTruthy()) on the expression using body.icons and the
existing predicate to ensure the test fails when no icon names include "circle".
🧹 Nitpick comments (9)
src/utils/icons/reactIcons.ts (3)

50-54: Static analysis ReDoS warning is a false positive in this context.

The regex at line 51 is constructed from setId values that originate from IconsManifest (react-icons library internal data), not from user input. The pattern ^${setPrefix} is a simple anchored prefix match without problematic quantifiers, making ReDoS practically impossible here.

However, if you want to be extra defensive, you could sanitize the input or use a literal string match instead:

♻️ Optional: Use string operations instead of regex
   } else {
     const setPrefix = setId.charAt(0).toUpperCase() + setId.slice(1)
-    const prefix = new RegExp(`^${setPrefix}`, 'i')
-    base = base.replace(prefix, '')
+    if (base.toLowerCase().startsWith(setPrefix.toLowerCase())) {
+      base = base.slice(setPrefix.length)
+    }
   }

82-84: Consider logging failed icon set loads for debugging.

Silent failures make troubleshooting difficult. While graceful degradation is appropriate, logging would help identify issues during development or when icon sets are unexpectedly unavailable.

♻️ Optional: Add debug logging
-    } catch {
-      // Skip sets that fail to load
+    } catch (error) {
+      // Skip sets that fail to load, but log for debugging
+      console.debug(`Failed to load icon set '${setId}':`, error)
     }

62-88: Consider caching getAllIcons() result to avoid repeated dynamic imports.

getAllIcons() performs dynamic imports for every icon set on each call. For a production API, this could be expensive if called frequently. Consider memoizing the result since icon sets don't change at runtime.

♻️ Proposed caching implementation
+let cachedIcons: IconMetadata[] | null = null
+
 export async function getAllIcons(): Promise<IconMetadata[]> {
+  if (cachedIcons) {
+    return cachedIcons
+  }
+
   const icons: IconMetadata[] = []

   for (const setId of ICON_SET_IDS) {
     // ... existing code ...
   }

+  cachedIcons = icons
   return icons
 }
src/__tests__/pages/api/__tests__/[version]/icons/[iconName].test.ts (1)

17-24: Mock duplicates production logic - consider importing the real function.

The parseIconId mock reimplements the actual logic, which could lead to test/implementation drift. Consider using Jest's requireActual to import the real function while mocking only what's necessary.

♻️ Proposed: Use real parseIconId implementation
 jest.mock('../../../../../../utils/icons/reactIcons', () => ({
   getIconSvg: jest.fn((setId: string, iconName: string) => {
     if (setId === 'fa' && iconName === 'FaCircle') return Promise.resolve(mockSvg)
     return Promise.resolve(null)
   }),
-  parseIconId: jest.fn((iconId: string) => {
-    const underscoreIndex = iconId.indexOf('_')
-    if (underscoreIndex <= 0) return null
-    const setId = iconId.slice(0, underscoreIndex)
-    const iconName = iconId.slice(underscoreIndex + 1)
-    if (!setId || !iconName) return null
-    return { setId, iconName }
-  }),
+  parseIconId: jest.requireActual('../../../../../../utils/icons/reactIcons').parseIconId,
 }))
src/pages/api/openapi.json.ts (2)

107-163: Consider adding 404 response for version not found.

The /{version}/icons endpoint returns 404 when the version doesn't exist (per the implementation in src/pages/api/[version]/icons/index.ts), but this isn't documented in the OpenAPI spec.

📝 Add 404 response documentation
             '200': {
               description: 'List of icons with metadata',
               // ... existing schema ...
             },
+            '404': {
+              description: 'Version not found',
+            },
           },

164-201: Consider adding 400 response for invalid icon name format.

The /{version}/icons/{icon-name} endpoint returns 400 for invalid icon name formats, but only 404 is documented. This could cause confusion for API consumers.

📝 Add 400 response documentation
           responses: {
             '200': {
               description: 'SVG markup for the icon',
               content: {
                 'image/svg+xml': {
                   schema: { type: 'string' },
                 },
               },
             },
+            '400': {
+              description: 'Invalid icon name format. Expected: {set}_{iconName}',
+            },
             '404': {
               description: 'Icon not found',
             },
           },
src/pages/api/[version]/icons/[iconName].ts (1)

17-17: Minor: Variable aliasing may cause confusion.

The destructuring { version, iconName: iconId } creates an alias, but iconName is reused later (line 53) as a different variable from parseIconId. While not a bug, this could be clearer.

♻️ Suggested clarification

Consider renaming for clarity:

-  const { version, iconName: iconId } = params
+  const { version, iconName: rawIconId } = params

And update references to iconIdrawIconId accordingly.

src/__tests__/pages/api/__tests__/[version]/icons/index.test.ts (1)

50-51: Consider using describe block and afterEach for cleaner test organization.

Tests would benefit from wrapping in a describe block and moving the repeated jest.restoreAllMocks() calls to an afterEach hook.

♻️ Suggested structure
+describe('GET /api/{version}/icons', () => {
+  afterEach(() => {
+    jest.restoreAllMocks()
+  })
+
 it('returns all icons with metadata', async () => {
   global.fetch = jest.fn(() =>
     ...
   expect(body.icons[0]).toHaveProperty('unicode')
-
-  jest.restoreAllMocks()
 })
 // ... other tests without individual restoreAllMocks calls
+})

Also applies to: 79-80

src/pages/api/[version]/icons/index.ts (1)

32-33: Consider pagination for large icon sets.

react-icons contains thousands of icons across all sets. Returning all icons in a single response could impact performance and client-side rendering. Consider adding pagination (limit/offset or cursor-based) for production use.

@dlabaj dlabaj changed the title WIP Feat (icons): Icons API end points for retrieving icons. feat (icons): Icons API end points for retrieving icons. Feb 6, 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.

1 participant