105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
import { brandLogoBox, type BrandLogoFit, type BrandLogoSize, type BrandMark } from "@/lib/brand";
|
|
|
|
/** 页眉品牌锁:图加文字 / 纯图 / 纯文字。图槽按画幅占位,铺法决定图怎么填进框。 */
|
|
export default function BrandLockup({
|
|
mode,
|
|
size = "sq",
|
|
fit = "contain",
|
|
name,
|
|
wordmark = "",
|
|
slogan = "",
|
|
logoLight = "",
|
|
logoDark = "",
|
|
frame = false,
|
|
}: {
|
|
mode: BrandMark;
|
|
size?: BrandLogoSize;
|
|
fit?: BrandLogoFit;
|
|
name: string;
|
|
wordmark?: string;
|
|
slogan?: string;
|
|
logoLight?: string;
|
|
logoDark?: string;
|
|
/** 后台预览画出画幅框,方便看非正方形占位 */
|
|
frame?: boolean;
|
|
}) {
|
|
const label = wordmark.trim() || name;
|
|
const line = slogan.trim();
|
|
const showImage = mode !== "text";
|
|
const showText = mode !== "image";
|
|
const box = brandLogoBox(size);
|
|
const src = logoLight || logoDark;
|
|
const both = !!(logoLight && logoDark && logoLight !== logoDark);
|
|
const useBox = showImage && (!!src || frame);
|
|
|
|
return (
|
|
<span className="j13-brand-lockup inline-flex items-center gap-2.5 min-w-0">
|
|
{showImage ? (
|
|
useBox ? (
|
|
<span
|
|
className="j13-brand-slot"
|
|
data-frame={frame ? "1" : undefined}
|
|
data-fit={src ? fit : undefined}
|
|
style={{ width: box.w, height: box.h }}
|
|
>
|
|
{src ? (
|
|
both ? (
|
|
<>
|
|
<Logo src={logoLight} fit={fit} extra="j13-brand-logo-light" />
|
|
<Logo src={logoDark} fit={fit} extra="j13-brand-logo-dark" />
|
|
</>
|
|
) : (
|
|
<Logo src={src} fit={fit} />
|
|
)
|
|
) : (
|
|
<Bubble h={box.h} />
|
|
)}
|
|
</span>
|
|
) : (
|
|
<Bubble h={36} />
|
|
)
|
|
) : null}
|
|
{showText ? (
|
|
<span className="leading-none min-w-0">
|
|
<span className="block font-extrabold text-[17px] tracking-tight truncate" style={{ color: "var(--ink)" }}>
|
|
{label}
|
|
</span>
|
|
{line ? (
|
|
<span className="block text-[10.5px] mt-0.5 truncate" style={{ color: "var(--ink-3)" }}>
|
|
{line}
|
|
</span>
|
|
) : null}
|
|
</span>
|
|
) : null}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
function Logo({ src, fit, extra = "" }: { src: string; fit: BrandLogoFit; extra?: string }) {
|
|
if (fit === "repeat") {
|
|
return (
|
|
<span
|
|
className={`j13-brand-logo j13-brand-logo-tile ${extra}`}
|
|
style={{ backgroundImage: `url("${src.replace(/["\\\n\r]/g, "")}")` }}
|
|
/>
|
|
);
|
|
}
|
|
return (
|
|
/* eslint-disable-next-line @next/next/no-img-element */
|
|
<img src={src} alt="" className={`j13-brand-logo ${extra}`} />
|
|
);
|
|
}
|
|
|
|
function Bubble({ h }: { h: number }) {
|
|
return (
|
|
<span
|
|
className="j13-brand-bubble rounded-2xl flex items-center justify-center shrink-0 transition-transform duration-300 group-hover:rotate-[-6deg]"
|
|
style={{ width: h, height: h, background: "var(--accent)", color: "var(--accent-on)" }}
|
|
>
|
|
<svg width="50%" height="50%" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
|
|
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
|
|
</svg>
|
|
</span>
|
|
);
|
|
}
|