refactor(web): use Primer Octicons mark for local Github icon

Swap the local lucide v0 outline mark for a verbatim copy of Primer
Octicons `mark-github-{16,24}` — the icon set GitHub itself ships on
github.com (MIT, Copyright (c) GitHub Inc.).

Why this source over the alternatives is documented at the top of
`gitnexus-web/src/lib/lucide-icons.tsx`, including:

  * the lucide v1 brand-icon removal context and migration link,
  * the trademark vs. license distinction (MIT covers our right to
    copy the SVG; trademark rules govern *use*, and we only use the
    mark in permitted ways per GitHub's brand toolkit),
  * why we didn't add `@primer/octicons-react`, `react-icons`, or
    `simple-icons` (zero-dep policy for one icon),
  * source URLs for both SVG variants.

The component still implements `LucideProps` and is drop-in compatible
with the existing import sites in Header, RepoAnalyzer and
AnalyzeOnboarding. The mark is now filled (matching github.com) rather
than stroke-outlined; lucide-only stroke props are accepted for type
parity but ignored. Both 16 and 24 variants are shipped so the mark
stays crisp at small sizes when consumers pass an explicit `size`.

Made-with: Cursor
This commit is contained in:
Gergo Magyar 2026-04-24 15:44:01 +01:00
parent 09ef484225
commit 387660c65b

View file

@ -6,10 +6,37 @@
* which icons are used and allows future optimization (e.g., tree-shaking
* configuration, icon subset bundling) without touching every component.
*
* Note on `Github`: brand icons were removed in lucide-react v1
* (https://lucide.dev/guide/react/migration). We provide a local
* SVG component below that mirrors the lucide v0 mark and the lucide
* component API, so consumers can keep importing it from this module.
* --- Why a local `Github` icon? ---
*
* Lucide removed all brand icons in v1
* (https://lucide.dev/guide/react/migration,
* https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md),
* so `import { Github } from 'lucide-react'` no longer compiles.
*
* We replace it with the official mark from Primer Octicons — the icon set
* GitHub itself uses on github.com — copied verbatim. This was preferred over
* the alternatives because it:
*
* 1. Is the canonical GitHub-maintained source for the mark, kept in sync
* with what users see on github.com.
* 2. Is MIT-licensed (Copyright (c) GitHub Inc.,
* https://github.com/primer/octicons/blob/main/LICENSE), so embedding the
* path data is permitted.
* 3. Adds zero new npm dependencies (vs. `@primer/octicons-react`,
* `react-icons`, or `simple-icons`), keeping the web bundle lean.
* 4. Ships per-size hand-tuned glyphs (16 + 24) — the same approach Primer
* uses — so the mark stays crisp at the small `h-4 w-4` sites in the
* header and onboarding screens as well as at full size.
*
* Trademark note: the GitHub mark is a registered trademark of GitHub, Inc.
* (https://brand.github.com/foundations/logo). The MIT license covers our
* right to copy the SVG; trademark rules still govern *use*. We use the mark
* here only to link to GitHub and to indicate GitHub source-repo integration,
* which are explicitly permitted by GitHub's brand toolkit.
*
* SVG sources (copied verbatim, MIT, Copyright (c) GitHub Inc.):
* - https://github.com/primer/octicons/blob/main/icons/mark-github-16.svg
* - https://github.com/primer/octicons/blob/main/icons/mark-github-24.svg
*/
import { forwardRef } from 'react';
import type { LucideProps } from 'lucide-react';
@ -83,13 +110,50 @@ export {
ZoomOut,
} from 'lucide-react';
/**
* GitHub mark — local copy of Primer Octicons `mark-github-{16,24}`.
*
* Why this exists, why Primer Octicons, and the trademark caveat are documented
* at the top of this file. Please read that header before changing the SVG
* paths or swapping the source.
*
* API-compatible with `lucide-react` icons (`LucideProps`). The Octicons mark
* is a *filled* glyph, so the lucide-only stroke props (`strokeWidth`,
* `absoluteStrokeWidth`) are accepted for type parity but ignored. Color
* defaults to `currentColor`, so Tailwind `text-*` utilities work the same as
* with any other icon in this module.
*/
export const Github = forwardRef<SVGSVGElement, LucideProps>(function Github(
{ size = 24, color = 'currentColor', strokeWidth = 2, absoluteStrokeWidth, className, ...rest },
{
size = 24,
color = 'currentColor',
className,
strokeWidth: _strokeWidth,
absoluteStrokeWidth: _absoluteStrokeWidth,
...rest
},
ref,
) {
const resolvedStrokeWidth = absoluteStrokeWidth
? (Number(strokeWidth) * 24) / Number(size)
: strokeWidth;
const numericSize = typeof size === 'string' ? Number.parseFloat(size) : size;
const useSmallVariant = Number.isFinite(numericSize) && (numericSize as number) <= 16;
if (useSmallVariant) {
return (
<svg
ref={ref}
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 16 16"
fill={color}
className={className}
{...rest}
>
<path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656" />
</svg>
);
}
return (
<svg
ref={ref}
@ -97,16 +161,11 @@ export const Github = forwardRef<SVGSVGElement, LucideProps>(function Github(
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke={color}
strokeWidth={resolvedStrokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
fill={color}
className={className}
{...rest}
>
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
<path d="M9 18c-4.51 2-5-2-7-2" />
<path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943" />
</svg>
);
});