后台站点设计UIUX优化
This commit is contained in:
104
frontend/components/BrandLockup.tsx
Normal file
104
frontend/components/BrandLockup.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user