Template
Three files gain a .hbr sibling so a storefront can be compiled with a store's own branding: app/globals.css, app/layout.tsx and components/logo.tsx. The committed files stay as they are and remain the hand-maintained default. Fourteen variables drive them: shopName, logoUrl, primaryColor, accentColor, bgColor, fontHeader and fontBody are supplied per store, while fgColor, primaryFgColor, accentFgColor, surfaceColor, mutedColor, mutedFgColor and borderColor derive from those unless pinned. Two changes were needed for the fonts to be swappable. The CSS variables next/font declares are now generic (--font-heading-family, --font-body-family, --font-mono-family) rather than named after Geist, and headings set font-family: var(--font-heading) so fontHeader has an effect when it differs from fontBody. The compiler lives outside this repo so the template carries no build script or dependency for it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013amafJZMQmXgeFEotYWfaw
59 lines
1.5 KiB
Plaintext
59 lines
1.5 KiB
Plaintext
import React from 'react';
|
|
import Link from 'next/link';
|
|
|
|
/** Baked in at compile time from the store's theme config. */
|
|
const STORE_LOGO_URL = {{json logoUrl}};
|
|
const STORE_NAME = {{json shopName}};
|
|
|
|
interface LogoProps {
|
|
/** Logo image URL. Falls back to the store name as a wordmark when absent. */
|
|
src?: string | null;
|
|
/** Wordmark text, and the image's alt text. */
|
|
storeName?: string;
|
|
/** Where the logo links to. Pass null to render it unwrapped. */
|
|
href?: string | null;
|
|
/** Sizing for the image — height only, so the aspect ratio is preserved. */
|
|
imageClassName?: string;
|
|
/** Sizing and weight for the wordmark fallback. */
|
|
textClassName?: string;
|
|
}
|
|
|
|
const Logo: React.FC<LogoProps> = ({
|
|
src,
|
|
storeName,
|
|
href = '/',
|
|
imageClassName = 'h-6',
|
|
textClassName = 'text-xl',
|
|
}) => {
|
|
// Callers pass `logoUrl=""` when they have nothing to supply, so fall back on
|
|
// any falsy value rather than only on `undefined`.
|
|
const logoSrc = src || STORE_LOGO_URL;
|
|
const name = storeName || STORE_NAME;
|
|
|
|
const mark = logoSrc ? (
|
|
<img
|
|
src={logoSrc}
|
|
alt={name}
|
|
className={`w-auto object-contain ${imageClassName}`}
|
|
/>
|
|
) : (
|
|
<span
|
|
className={`font-heading font-medium tracking-tight text-foreground ${textClassName}`}
|
|
>
|
|
{name}
|
|
</span>
|
|
);
|
|
|
|
if (href === null) {
|
|
return <span className="flex items-center">{mark}</span>;
|
|
}
|
|
|
|
return (
|
|
<Link href={href} className="flex items-center">
|
|
{mark}
|
|
</Link>
|
|
);
|
|
};
|
|
|
|
export default Logo;
|