149 lines
4.6 KiB
TypeScript
149 lines
4.6 KiB
TypeScript
'use client'
|
|
|
|
import React, { useEffect, useRef } from 'react'
|
|
import type { FDCodeEmbedBlock as FDCodeEmbedBlockProps } from '@/payload-types'
|
|
|
|
const maxWidthClasses: Record<string, string> = {
|
|
default: 'max-w-[1200px]',
|
|
narrow: 'max-w-[800px]',
|
|
wide: 'max-w-[1400px]',
|
|
full: 'max-w-full',
|
|
}
|
|
|
|
// Navy stays dark. White/gray adapt to OS dark mode.
|
|
const bgClasses: Record<string, string> = {
|
|
white: 'bg-white dark:bg-fd-navy',
|
|
navy: 'bg-fd-navy',
|
|
gray: 'bg-fd-surface-alt dark:bg-fd-navy',
|
|
yellow: 'bg-fd-yellow',
|
|
transparent: 'bg-transparent',
|
|
}
|
|
|
|
/* Priority #5: Responsive radius for embed card wrappers */
|
|
const cardRadius = 'rounded-[32px] md:rounded-[50px] lg:rounded-[70px]'
|
|
|
|
export const FDCodeEmbedBlockComponent: React.FC<FDCodeEmbedBlockProps> = ({
|
|
heading,
|
|
description,
|
|
embedType = 'iframe',
|
|
iframeSrc,
|
|
iframeTitle = 'Inbäddat formulär',
|
|
iframeHeight = '600px',
|
|
iframeAllow,
|
|
customCode,
|
|
sandboxed = true,
|
|
maxWidth = 'default',
|
|
sectionBackground = 'white',
|
|
textColor = 'auto',
|
|
embedBackground = 'none',
|
|
anchorId,
|
|
}) => {
|
|
const customCodeRef = useRef<HTMLDivElement>(null)
|
|
|
|
const isDark = sectionBackground === 'navy'
|
|
|
|
const headingColor =
|
|
textColor === 'white' ? 'text-white'
|
|
: textColor === 'navy' ? 'text-fd-navy'
|
|
: isDark
|
|
? 'text-fd-yellow'
|
|
: 'text-fd-navy dark:text-fd-yellow'
|
|
|
|
const bodyColor =
|
|
textColor === 'white' ? 'text-white'
|
|
: textColor === 'navy' ? 'text-fd-navy'
|
|
: isDark
|
|
? 'text-white'
|
|
: 'text-fd-navy dark:text-white'
|
|
|
|
const bgClass = bgClasses[sectionBackground ?? 'white'] || 'bg-white dark:bg-fd-navy'
|
|
const containerClass = maxWidthClasses[maxWidth ?? 'default'] || 'max-w-[1200px]'
|
|
|
|
const embedWrapperClass =
|
|
embedBackground === 'card'
|
|
? `bg-white dark:bg-white/10 ${cardRadius} shadow-lg p-6 md:p-10 overflow-hidden`
|
|
: embedBackground === 'navy-card'
|
|
? `bg-fd-navy ${cardRadius} shadow-lg p-6 md:p-10 overflow-hidden`
|
|
: ''
|
|
|
|
useEffect(() => {
|
|
if (embedType === 'custom' && !sandboxed && customCode && customCodeRef.current) {
|
|
const container = customCodeRef.current
|
|
container.innerHTML = customCode
|
|
const scripts = container.querySelectorAll('script')
|
|
scripts.forEach((oldScript) => {
|
|
const newScript = document.createElement('script')
|
|
Array.from(oldScript.attributes).forEach((attr) => {
|
|
newScript.setAttribute(attr.name, attr.value)
|
|
})
|
|
newScript.textContent = oldScript.textContent
|
|
oldScript.parentNode?.replaceChild(newScript, oldScript)
|
|
})
|
|
}
|
|
}, [embedType, sandboxed, customCode])
|
|
|
|
const sandboxedSrcDoc = customCode
|
|
? `<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<style>
|
|
body { margin: 0; padding: 0; font-family: system-ui, -apple-system, sans-serif; }
|
|
</style>
|
|
</head>
|
|
<body>${customCode}</body>
|
|
</html>`
|
|
: ''
|
|
|
|
return (
|
|
<section id={anchorId || undefined} className={`relative w-full py-16 md:py-20 lg:py-[99px] ${bgClass} overflow-hidden`}>
|
|
<div className={`relative ${containerClass} mx-auto px-6 md:px-8`}>
|
|
{(heading || description) && (
|
|
<div className="mb-8 md:mb-12 text-center">
|
|
{heading && (
|
|
<h2 className={`font-joey-heavy text-fd-h1 mb-4 ${headingColor}`}>
|
|
{heading}
|
|
</h2>
|
|
)}
|
|
{description && (
|
|
<p className={`font-joey text-fd-body-lg max-w-[800px] mx-auto ${bodyColor}`}>
|
|
{description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
<div className={embedWrapperClass}>
|
|
{embedType === 'iframe' && iframeSrc && (
|
|
<iframe
|
|
src={iframeSrc}
|
|
title={iframeTitle || 'Inbäddat formulär'}
|
|
width="100%"
|
|
height={iframeHeight || '600px'}
|
|
style={{ border: 'none', minHeight: '200px' }}
|
|
allow={iframeAllow || undefined}
|
|
loading="lazy"
|
|
/>
|
|
)}
|
|
|
|
{embedType === 'custom' && sandboxed && customCode && (
|
|
<iframe
|
|
srcDoc={sandboxedSrcDoc}
|
|
title="Anpassad inbäddning"
|
|
width="100%"
|
|
style={{ border: 'none', minHeight: '200px', height: iframeHeight || '400px' }}
|
|
sandbox="allow-scripts allow-forms allow-same-origin allow-popups"
|
|
loading="lazy"
|
|
/>
|
|
)}
|
|
|
|
{embedType === 'custom' && !sandboxed && (
|
|
<div ref={customCodeRef} className="w-full" />
|
|
)}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|