feat(polaris): 更新导航链接并修复图标加载
调整链接数据、图标映射和相关测试,新增 go-zero 本地图标。 修复图片在事件绑定前已加载或失败时的显示问题。
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
/* eslint-disable @next/next/no-img-element -- favicon 来源由数据动态决定,静态 Image 配置无法预枚举域名。 */
|
||||
import { useState } from "react"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
|
||||
import {
|
||||
getIconCandidates,
|
||||
@@ -29,6 +29,7 @@ function SiteIconContent({
|
||||
}: SiteIconContentProps) {
|
||||
const [candidateIndex, setCandidateIndex] = useState(0)
|
||||
const [loadedImageSrc, setLoadedImageSrc] = useState<string | null>(null)
|
||||
const imageRef = useRef<HTMLImageElement | null>(null)
|
||||
const candidate = candidates[candidateIndex]
|
||||
const initialCandidate = candidates.at(-1)
|
||||
const initialValue =
|
||||
@@ -36,6 +37,21 @@ function SiteIconContent({
|
||||
const wrapperClassName = cn("site-icon", className)
|
||||
const style = { width: size, height: size }
|
||||
|
||||
// 缓存命中的图片可能在 React 附加 onLoad/onError(如水合)之前就完成或失败,
|
||||
// 之后不再派发任何事件;挂载后按 complete/naturalWidth 补偿判定,
|
||||
// 避免透明图片永久停留在首字母占位,也避免坏图卡住候选链。
|
||||
// 候选推进有末位钳制,末位为首字母分支,不会形成无限循环。
|
||||
useEffect(() => {
|
||||
if (candidate.kind !== "image") return
|
||||
const image = imageRef.current
|
||||
if (!image?.complete) return
|
||||
if (image.naturalWidth > 0) {
|
||||
setLoadedImageSrc(candidate.src)
|
||||
} else {
|
||||
setCandidateIndex((index) => Math.min(index + 1, candidates.length - 1))
|
||||
}
|
||||
}, [candidate, candidates.length])
|
||||
|
||||
if (candidate.kind === "simple") {
|
||||
const icon = SIMPLE_ICON_MAP[candidate.slug]
|
||||
return (
|
||||
@@ -72,6 +88,7 @@ function SiteIconContent({
|
||||
alt={`${link.title} 图标`}
|
||||
width={size}
|
||||
height={size}
|
||||
ref={imageRef}
|
||||
onLoad={() => setLoadedImageSrc(candidate.src)}
|
||||
onError={() =>
|
||||
setCandidateIndex((index) =>
|
||||
|
||||
Reference in New Issue
Block a user