Files
jiang13-bbs/frontend/app/admin/appearance/BgModePicker.tsx

108 lines
3.4 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.
"use client";
import { BG_MODE_OPTIONS, type BgMode } from "@/lib/bg";
/** 铺放示意:16:9 小窗里用色块表达裁切 / 完整 / 平铺 / 拉伸。 */
function ModeGlyph({ mode }: { mode: BgMode }) {
const photo = "var(--accent-soft)";
const ink = "var(--accent)";
return (
<span
className="relative block w-16 aspect-video overflow-hidden rounded-[3px] shrink-0"
style={{ background: "var(--bg)", border: "1px solid var(--line-2)" }}
aria-hidden
>
{mode === "cover" && (
<span
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
style={{ width: "72%", height: "140%", background: photo }}
>
<span
className="absolute left-1/2 top-[18%] -translate-x-1/2 w-[30%] aspect-square rounded-full"
style={{ background: ink, opacity: 0.45 }}
/>
</span>
)}
{mode === "contain" && (
<span
className="absolute inset-y-0 left-1/2 -translate-x-1/2"
style={{ width: "58%", background: photo }}
>
<span
className="absolute left-1/2 top-[18%] -translate-x-1/2 w-[36%] aspect-square rounded-full"
style={{ background: ink, opacity: 0.45 }}
/>
</span>
)}
{mode === "repeat" && (
<span className="absolute inset-[2px] grid grid-cols-3 grid-rows-2 gap-[2px]">
{Array.from({ length: 6 }, (_, i) => (
<span key={i} style={{ background: photo }} />
))}
</span>
)}
{mode === "stretch" && (
<span className="absolute inset-0" style={{ background: photo }}>
<span
className="absolute left-1/2 top-[22%] -translate-x-1/2 h-[38%]"
style={{
width: "70%",
borderRadius: "50%",
background: ink,
opacity: 0.45,
}}
/>
</span>
)}
</span>
);
}
export default function BgModePicker({
value,
onChange,
disabled,
ariaLabel,
}: {
value: BgMode;
onChange: (mode: BgMode) => void;
disabled?: boolean;
ariaLabel: string;
}) {
return (
<div className="grid grid-cols-2 gap-2" role="group" aria-label={ariaLabel}>
{BG_MODE_OPTIONS.map((o) => {
const active = value === o.key;
return (
<button
key={o.key}
type="button"
disabled={disabled}
aria-pressed={active}
onClick={() => {
if (!active) onChange(o.key);
}}
className="flex items-center gap-2.5 min-w-0 px-2.5 py-2 rounded-[var(--r-sm)] border text-left transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
style={{
borderColor: active ? "var(--accent)" : "var(--line)",
background: active ? "var(--accent-soft)" : "var(--panel)",
cursor: disabled ? "not-allowed" : "pointer",
}}
>
<ModeGlyph mode={o.key} />
<span className="min-w-0">
<span
className="block text-[13px] font-medium leading-tight"
style={{ color: active ? "var(--accent)" : "var(--ink)" }}
>
{o.label}
</span>
<span className="block meta text-[11.5px] mt-0.5 leading-snug">{o.hint}</span>
</span>
</button>
);
})}
</div>
);
}