Refactor icon rendering and head element injection
This commit is contained in:
parent
49a8471628
commit
df23b62962
|
|
@ -42,6 +42,12 @@ const renderHtml = async (req: Request, route: Bun.MatchedRoute) => {
|
|||
|
||||
// Remove any < characters from the loader data to prevent XSS attacks
|
||||
const escapedLoaderData = JSON.stringify(loaderData).replace(/</g, "\\u003c")
|
||||
const headLinks = component.head?.links?.map(
|
||||
(link: any) => `<link rel="${link.rel}" href="${link.href}" ${link.attributes || ""}>`
|
||||
)
|
||||
const headScripts = component.head?.scripts?.map(
|
||||
(script: any) => `<script src="${script.src}" ${script.type ? `type="${script.type}"` : ""}></script>`
|
||||
)
|
||||
return new Response(
|
||||
`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
|
@ -50,20 +56,8 @@ const renderHtml = async (req: Request, route: Bun.MatchedRoute) => {
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="${routeName + ".css"}" />
|
||||
<title>${component.head?.title ?? "Untitled"}</title>
|
||||
${
|
||||
component.head?.links
|
||||
?.map((link: any) => `<link rel="${link.rel}" href="${link.href}" ${link.attributes || ""}>`)
|
||||
.join("\n") || ""
|
||||
}
|
||||
${
|
||||
component.head?.scripts
|
||||
?.map(
|
||||
(script: any) =>
|
||||
`<script src="${script.src}" ${script.type ? `type="${script.type}"` : ""}></script>`
|
||||
)
|
||||
.join("\n") || ""
|
||||
}
|
||||
|
||||
${headLinks?.join("\n") ?? ""}
|
||||
${headScripts?.join("\n") ?? ""}
|
||||
<script id="__LOADER_DATA__" type="application/json">${escapedLoaderData}</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -24,25 +24,19 @@ export const Icon: FC<IconProps> = (props) => {
|
|||
throw new Error(`Icon "${name}" not found in Lucide icons`)
|
||||
}
|
||||
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
width={size}
|
||||
height={size}
|
||||
class={className}
|
||||
style={{
|
||||
display: "block",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
dangerouslySetInnerHTML={{ __html: getIconContent(iconSvg) }}
|
||||
/>
|
||||
)
|
||||
// Modify the SVG string to include our custom attributes
|
||||
const modifiedSvg = iconSvg
|
||||
.replace(/width="[^"]*"/, `width="${size}"`)
|
||||
.replace(/height="[^"]*"/, `height="${size}"`)
|
||||
.replace(/class="[^"]*"/, className ? `class="${className}"` : "")
|
||||
.replace(
|
||||
/<svg([^>]*)>/,
|
||||
`<svg$1 style="display: block; flex-shrink: 0;"${
|
||||
className && !iconSvg.includes("class=") ? ` class="${className}"` : ""
|
||||
}>`
|
||||
)
|
||||
|
||||
return <div dangerouslySetInnerHTML={{ __html: modifiedSvg }} />
|
||||
}
|
||||
|
||||
export const IconLink: FC<IconLinkProps> = (props) => {
|
||||
|
|
@ -82,23 +76,23 @@ export const Test = () => {
|
|||
<h2 class="text-xl font-bold mb-4">Styling with CSS Classes</h2>
|
||||
<div class="grid grid-cols-5 gap-6">
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Star" size={8} />
|
||||
<Icon name="Star" size={24} />
|
||||
<p class="text-sm">Default</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Star" size={8} class="text-blue-500" />
|
||||
<Icon name="Star" size={24} class="text-blue-500" />
|
||||
<p class="text-sm">Blue Color</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Star" size={8} class="stroke-1" />
|
||||
<Icon name="Star" size={24} class="stroke-1" />
|
||||
<p class="text-sm">Thin Stroke</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Star" size={8} class="text-yellow-400 stroke-0 fill-current" />
|
||||
<Icon name="Star" size={24} class="text-yellow-400 stroke-0 fill-current" />
|
||||
<p class="text-sm">Filled</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Star" size={8} class="text-purple-500 hover:text-purple-700 transition-colors" />
|
||||
<Icon name="Star" size={24} class="text-purple-500 hover:text-purple-700 transition-colors" />
|
||||
<p class="text-sm">Hover Effect</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -109,19 +103,19 @@ export const Test = () => {
|
|||
<h2 class="text-xl font-bold mb-4">Advanced Styling</h2>
|
||||
<div class="grid grid-cols-4 gap-6">
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Heart" size={10} class="text-red-500 stroke-0 fill-current" />
|
||||
<Icon name="Heart" size={24} class="text-red-500 stroke-0 fill-current" />
|
||||
<p class="text-sm">Filled Heart</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Shield" size={10} class="text-green-600 stroke-2" />
|
||||
<Icon name="Shield" size={24} class="text-green-600 stroke-2" />
|
||||
<p class="text-sm">Thick Stroke</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Sun" size={10} class="text-yellow-500 animate-spin" />
|
||||
<Icon name="Sun" size={24} class="text-yellow-500 animate-spin" />
|
||||
<p class="text-sm">Animated</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center space-y-2">
|
||||
<Icon name="Zap" size={10} class="text-blue-400 drop-shadow-lg" />
|
||||
<Icon name="Zap" size={24} class="text-blue-400 drop-shadow-lg" />
|
||||
<p class="text-sm">Drop Shadow</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user