162 lines
3.9 KiB
TypeScript
162 lines
3.9 KiB
TypeScript
/* eslint-disable @next/next/no-img-element -- Pure image-renderer templates never mount in the webpage. */
|
|
import type { ComponentProps, CSSProperties, ReactNode } from "react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ImageProps = Omit<ComponentProps<"img">, "width" | "height"> & {
|
|
width?: number;
|
|
height?: number;
|
|
fill?: boolean;
|
|
sizes?: string;
|
|
unoptimized?: boolean;
|
|
priority?: boolean;
|
|
quality?: number;
|
|
};
|
|
// The renderer receives original image sources, not Next.js optimized image URLs.
|
|
export function Image({
|
|
src,
|
|
alt = "",
|
|
width,
|
|
height,
|
|
fill,
|
|
className,
|
|
style,
|
|
}: ImageProps) {
|
|
return (
|
|
<img
|
|
src={src}
|
|
alt={alt}
|
|
width={width}
|
|
height={height}
|
|
className={className}
|
|
style={{
|
|
...(fill
|
|
? ({
|
|
position: "absolute",
|
|
inset: 0,
|
|
width: "100%",
|
|
height: "100%",
|
|
} as CSSProperties)
|
|
: {}),
|
|
...style,
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
export function getImageProps({ src }: ImageProps) {
|
|
return { props: { src } };
|
|
}
|
|
export function Link({
|
|
children,
|
|
className,
|
|
}: {
|
|
children: ReactNode;
|
|
className?: string;
|
|
[key: string]: unknown;
|
|
}) {
|
|
return <div className={className}>{children}</div>;
|
|
}
|
|
export function Kbd({
|
|
children,
|
|
className,
|
|
}: {
|
|
children: ReactNode;
|
|
className?: string;
|
|
}) {
|
|
return <span className={className}>{children}</span>;
|
|
}
|
|
export function ArrowUpRightIcon() {
|
|
return <span>↗</span>;
|
|
}
|
|
export function ImageIcon({
|
|
className,
|
|
}: {
|
|
className?: string;
|
|
[key: string]: unknown;
|
|
}) {
|
|
return <span className={className}>◇</span>;
|
|
}
|
|
export function ConditionSwitcher({
|
|
children,
|
|
}: {
|
|
children: ReactNode;
|
|
label: string;
|
|
labels: string[];
|
|
}) {
|
|
return <>{children}</>;
|
|
}
|
|
export function Separator() {
|
|
return <div className="h-px w-full bg-border" />;
|
|
}
|
|
export function Badge({ children }: { children: ReactNode; variant?: string }) {
|
|
return (
|
|
<span className="inline-flex h-5 items-center justify-center rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground">
|
|
{children}
|
|
</span>
|
|
);
|
|
}
|
|
type BoxProps = ComponentProps<"div">;
|
|
export function Card({ className, children, ...props }: BoxProps) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
className={cn(
|
|
"flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10",
|
|
className,
|
|
)}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
export function CardHeader({ className, ...props }: BoxProps) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
className={cn(
|
|
"grid auto-rows-min items-start gap-1 rounded-t-xl px-4",
|
|
className,
|
|
)}
|
|
/>
|
|
);
|
|
}
|
|
export function CardTitle({ className, ...props }: BoxProps) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
className={cn(
|
|
"font-heading text-base leading-snug font-medium",
|
|
className,
|
|
)}
|
|
/>
|
|
);
|
|
}
|
|
export function CardContent({ className, ...props }: BoxProps) {
|
|
return <div {...props} className={cn("px-4", className)} />;
|
|
}
|
|
export function GuideExportBranding({
|
|
backgroundUrl,
|
|
variant = "standard",
|
|
}: {
|
|
backgroundUrl: string;
|
|
variant?: "standard" | "constellation";
|
|
}) {
|
|
const constellation = variant === "constellation";
|
|
return (
|
|
<>
|
|
<Image alt="" src={backgroundUrl} fill className="object-cover" />
|
|
<div className="absolute inset-0 bg-[#050817]/65" />
|
|
<Image
|
|
alt=""
|
|
src="/icon/Watermark.png"
|
|
width={constellation ? 280 : 180}
|
|
height={constellation ? 158 : 101}
|
|
className={
|
|
constellation
|
|
? "guide-export-watermark absolute right-4 bottom-0 z-30 h-auto w-[280px] object-contain drop-shadow-[0_4px_3px_rgba(0,0,0,0.8)]"
|
|
: "guide-export-watermark absolute top-4 right-4 z-30 h-auto w-[180px] object-contain drop-shadow-[0_4px_3px_rgba(0,0,0,0.8)]"
|
|
}
|
|
/>
|
|
</>
|
|
);
|
|
}
|