thread-master/apps/web/src/components/ui/AppIcons.tsx

130 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { ReactNode, SVGProps } from "react";
import type { NavKey } from "../../lib/nav";
export type AppIconName = NavKey | "more" | "spark";
type Props = {
name: AppIconName;
size?: number;
className?: string;
} & Omit<SVGProps<SVGSVGElement>, "name">;
/**
* 精緻線稿 icon圓潤端點、雙層深度、細微星芒魔法感但不吵
* 可隨 currentColor 換色,適配 light / dark。
*/
export function AppIcon({ name, size = 22, className = "", ...rest }: Props) {
return (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
className={`hb-app-icon ${className}`.trim()}
aria-hidden
{...rest}
>
{glyphs[name]}
</svg>
);
}
const stroke = {
stroke: "currentColor",
strokeWidth: 1.5,
strokeLinecap: "round" as const,
strokeLinejoin: "round" as const,
};
/** 小星芒 */
function Spark({ x = 18, y = 5, s = 1 }: { x?: number; y?: number; s?: number }) {
return (
<g opacity={0.85} transform={`translate(${x} ${y}) scale(${s})`}>
<path d="M0-2.2V2.2M-2.2 0H2.2" {...stroke} strokeWidth={1.35} />
</g>
);
}
const glyphs: Record<AppIconName, ReactNode> = {
// 今日:圓角日曆 + 星
today: (
<>
<rect x="3.5" y="5" width="17" height="15" rx="3.5" {...stroke} />
<path d="M8 3.75v3.1M16 3.75v3.1M3.5 10.25h17" {...stroke} />
<circle cx="9.2" cy="14.6" r="1.05" fill="currentColor" opacity={0.9} />
<Spark x={16.2} y={14.4} s={0.72} />
</>
),
// 帳號:雙圓 + 柔弧(島民)
crew: (
<>
<circle cx="9" cy="8.6" r="3" {...stroke} />
<path d="M4 18.2c.55-2.9 2.7-4.35 5-4.35 2.3 0 4.45 1.45 5 4.35" {...stroke} />
<circle cx="16.6" cy="9.4" r="2.35" {...stroke} opacity={0.85} />
<path d="M14.2 18.2c.35-1.85 1.55-2.85 3.15-2.85 1.35 0 2.45.7 3.05 1.9" {...stroke} opacity={0.85} />
<Spark x={18.8} y={5.2} s={0.55} />
</>
),
// 創作:羽毛筆 + 星
studio: (
<>
<path
d="M5.2 19.2 14.6 5.4a1.7 1.7 0 0 1 2.45-.15l1.9 1.9a1.7 1.7 0 0 1-.15 2.45L9.3 19.2H5.2z"
{...stroke}
/>
<path d="M12.7 7.9 16.1 11.3" {...stroke} />
<path d="M5.2 19.2 8.1 18.3" {...stroke} opacity={0.7} />
<Spark x={18.5} y={5.5} s={0.7} />
</>
),
// 海巡:水晶球 / 羅盤弧 + 十字光
scout: (
<>
<circle cx="11.2" cy="11.2" r="6.4" {...stroke} />
<circle cx="11.2" cy="11.2" r="2.15" {...stroke} opacity={0.55} />
<path d="M11.2 6.4v9.6M6.4 11.2h9.6" {...stroke} opacity={0.55} />
<path d="M15.8 15.8 20.2 20.2" {...stroke} />
<Spark x={18.2} y={6.2} s={0.62} />
</>
),
// 發送:紙飛機 + 軌跡星
outbox: (
<>
<path d="M4.2 11.1 19.6 4.6 12.2 19.8l-1.7-6.3z" {...stroke} />
<path d="M10.5 13.5 19.6 4.6" {...stroke} opacity={0.65} />
<Spark x={7.2} y={7.5} s={0.5} />
</>
),
// 任務:魔法卷軸/手提袋簡化
jobs: (
<>
<rect x="4.2" y="7.2" width="15.6" height="12.2" rx="2.6" {...stroke} />
<path d="M9 7.2V5.9a2.1 2.1 0 0 1 2.1-2.1h1.8A2.1 2.1 0 0 1 15 5.9v1.3" {...stroke} />
<path d="M4.2 12.1h15.6" {...stroke} opacity={0.55} />
<Spark x={17.5} y={15.8} s={0.55} />
</>
),
// 品牌:旗幟堡壘簡化 + 星
brands: (
<>
<path d="M6.2 20V9.1L12 5.2 17.8 9.1V20" {...stroke} />
<path d="M10.2 20v-4.6h3.6V20" {...stroke} />
<path d="M12 9.6v2.4" {...stroke} opacity={0.55} />
<Spark x={17.8} y={6.4} s={0.58} />
</>
),
more: (
<>
<circle cx="6.5" cy="12" r="1.45" fill="currentColor" />
<circle cx="12" cy="12" r="1.45" fill="currentColor" />
<circle cx="17.5" cy="12" r="1.45" fill="currentColor" />
</>
),
spark: (
<>
<Spark x={12} y={12} s={1.35} />
<circle cx="12" cy="12" r="1.1" fill="currentColor" opacity={0.35} />
</>
),
};