Menu
Public repository / 439f0dcabf5cdf2b120c7724be895cf1df30507f
AkurAI-Framework / site/frontend/ai/components/media/image.js
Latest change 36f53e8d189d0609aaabc65e705cf9db9d497d14 - Port Media components as vanilla ES modules by Ólafur Búi Ólafsson
// Image component — renders a responsive image card with optional caption.
export const def = {
name: "image",
category: "Media",
title: "Image",
match(payload) {
return typeof payload?.src === "string";
},
render(payload, ctx) {
const { src, alt = "", caption = "" } = payload;
// XSS safety: only set src/alt from payload, never innerHTML
const img = document.createElement("img");
img.src = src;
img.alt = alt;
img.loading = "lazy";
img.style.width = "100%";
img.style.height = "auto";
img.style.borderRadius = "10px";
img.style.display = "block";
if (!caption) {
// No caption — just the image in a card
const card = document.createElement("div");
card.className = "card";
card.style.padding = "0";
card.style.overflow = "hidden";
card.appendChild(img);
return card;
}
// With caption
const card = document.createElement("div");
card.className = "card";
const imgWrapper = document.createElement("div");
imgWrapper.style.marginBottom = "12px";
imgWrapper.style.overflow = "hidden";
imgWrapper.style.borderRadius = "8px";
imgWrapper.appendChild(img);
const captionEl = document.createElement("p");
captionEl.style.margin = "0";
captionEl.style.fontSize = "13px";
captionEl.style.color = "var(--muted)";
captionEl.style.lineHeight = "1.5";
captionEl.textContent = caption;
card.appendChild(imgWrapper);
card.appendChild(captionEl);
return card;
},
example: {
src: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop",
alt: "Mountain landscape",
caption: "A serene mountain landscape at sunset"
}
};