refactor(web): extract citation TYPE_ICONS into a shared module

`citation.tsx` and `citation-list.tsx` each defined the same
`TYPE_ICONS: Record<CitationType, LucideIcon>` map with byte-identical
contents. Extract it into `./type-icons.ts` and import from both call
sites so the mapping has a single source of truth.

While here, drop the Lucide icon imports (`Code2`, `Database`, `File`,
`FileText`, `Newspaper`) and the now-unused `LucideIcon` / `CitationType`
type imports from the two call sites, keeping only the icons still used
directly (`Globe` for the fallback, `ExternalLink` for the hover
affordance).

Fixes #1190.
This commit is contained in:
Tim Ren 2026-04-15 20:07:47 +08:00
parent 656e061f84
commit 13f0d5c952
3 changed files with 18 additions and 24 deletions

View file

@ -1,22 +1,13 @@
"use client";
import type { LucideIcon } from "lucide-react";
import { Code2, Database, ExternalLink, File, FileText, Globe, Newspaper } from "lucide-react";
import { ExternalLink, Globe } from "lucide-react";
import NextImage from "next/image";
import * as React from "react";
import { openSafeNavigationHref, resolveSafeNavigationHref } from "../shared/media";
import { cn, Popover, PopoverContent, PopoverTrigger } from "./_adapter";
import { Citation } from "./citation";
import type { CitationType, CitationVariant, SerializableCitation } from "./schema";
const TYPE_ICONS: Record<CitationType, LucideIcon> = {
webpage: Globe,
document: FileText,
article: Newspaper,
api: Database,
code: Code2,
other: File,
};
import type { CitationVariant, SerializableCitation } from "./schema";
import { TYPE_ICONS } from "./type-icons";
function useHoverPopover(delay = 100) {
const [open, setOpen] = React.useState(false);

View file

@ -1,24 +1,15 @@
"use client";
import type { LucideIcon } from "lucide-react";
import { Code2, Database, ExternalLink, File, FileText, Globe, Newspaper } from "lucide-react";
import { ExternalLink, Globe } from "lucide-react";
import NextImage from "next/image";
import * as React from "react";
import { openSafeNavigationHref, sanitizeHref } from "../shared/media";
import { cn, Popover, PopoverContent, PopoverTrigger } from "./_adapter";
import type { CitationType, CitationVariant, SerializableCitation } from "./schema";
import type { CitationVariant, SerializableCitation } from "./schema";
import { TYPE_ICONS } from "./type-icons";
const FALLBACK_LOCALE = "en-US";
const TYPE_ICONS: Record<CitationType, LucideIcon> = {
webpage: Globe,
document: FileText,
article: Newspaper,
api: Database,
code: Code2,
other: File,
};
function extractDomain(url: string): string | undefined {
try {
const urlObj = new URL(url);

View file

@ -0,0 +1,12 @@
import type { LucideIcon } from "lucide-react";
import { Code2, Database, File, FileText, Globe, Newspaper } from "lucide-react";
import type { CitationType } from "./schema";
export const TYPE_ICONS: Record<CitationType, LucideIcon> = {
webpage: Globe,
document: FileText,
article: Newspaper,
api: Database,
code: Code2,
other: File,
};