61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { ComponentConfig } from "@reacteditor/core";
|
|
import { Megaphone } from "lucide-react";
|
|
import { cn } from "~/editor/lib/utils";
|
|
|
|
export type BannerProps = {
|
|
text: string;
|
|
ctaLabel: string;
|
|
ctaHref: string;
|
|
tone: "default" | "inverse" | "muted";
|
|
};
|
|
|
|
function Banner({ text, ctaLabel, ctaHref, tone }: BannerProps) {
|
|
const toneClass: Record<BannerProps["tone"], string> = {
|
|
default: "bg-foreground text-background",
|
|
inverse: "bg-background text-foreground border-y border-border",
|
|
muted: "bg-muted text-foreground border-y border-border",
|
|
};
|
|
return (
|
|
<div className={cn("w-full py-2 text-center text-xs tracking-[0.18em] uppercase", toneClass[tone])}>
|
|
<div className="container mx-auto flex flex-col items-center justify-center gap-2 px-6 sm:flex-row">
|
|
<span>{text}</span>
|
|
{ctaLabel ? (
|
|
<a
|
|
href={ctaHref || "#"}
|
|
className="underline-offset-4 hover:underline"
|
|
>
|
|
{ctaLabel} →
|
|
</a>
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export const bannerEditor: ComponentConfig<BannerProps> = {
|
|
label: "Announcement bar",
|
|
icon: <Megaphone size={16} />,
|
|
category: "hero",
|
|
defaultProps: {
|
|
text: "Free shipping on orders over $150",
|
|
ctaLabel: "Shop new",
|
|
ctaHref: "/collections/new",
|
|
tone: "default",
|
|
},
|
|
fields: {
|
|
text: { label: "Text", type: "text", contentEditable: true },
|
|
ctaLabel: { label: "CTA label", type: "text", contentEditable: true },
|
|
ctaHref: { label: "CTA link", type: "text" },
|
|
tone: {
|
|
label: "Tone",
|
|
type: "select",
|
|
options: [
|
|
{ label: "Default (dark)", value: "default" },
|
|
{ label: "Inverse (light)", value: "inverse" },
|
|
{ label: "Muted", value: "muted" },
|
|
],
|
|
},
|
|
},
|
|
render: (props) => <Banner {...props} />,
|
|
};
|