Menu
Public repository / 439f0dcabf5cdf2b120c7724be895cf1df30507f
AkurAI-Framework / site/frontend/ai/components/content/x_post.js
Latest change 67a966d4abf972b300e8c6c214a30a0279103337 - feat(ai): Artifacts content components + geo map + item carousel (AB3-C) by Ólafur Búi Ólafsson
/**
* X Post — Artifacts / content component.
* Payload: { handle: string, name: string, avatar?: string, text: string, stats?: { likes?: number, reposts?: number, replies?: number } }
* Renders an X/Twitter-style post card.
*/
function esc(str) {
return String(str ?? "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
}
function fmt(n) {
if (n == null) return "0";
if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + "M";
if (n >= 1_000) return (n / 1_000).toFixed(1) + "K";
return String(n);
}
function avatarEl(avatar, name) {
if (avatar) {
return `<img class="tc-content-xpost__avatar" src="${esc(avatar)}" alt="${esc(name)}" width="40" height="40" loading="lazy">`;
}
const initials = esc((name || "?").slice(0, 2).toUpperCase());
return `<div class="tc-content-xpost__avatar tc-content-xpost__avatar--placeholder" aria-label="${esc(name)}">${initials}</div>`;
}
export const def = {
name: "x_post",
category: "Artifacts",
title: "X Post",
match(payload) {
return (
payload !== null &&
typeof payload === "object" &&
typeof payload.handle === "string" &&
typeof payload.text === "string"
);
},
render(payload) {
const { handle, name = handle, avatar, text, stats = {} } = payload;
const { likes = 0, reposts = 0, replies = 0 } = stats;
const card = document.createElement("div");
card.className = "tc-content-xpost";
card.setAttribute("role", "article");
card.setAttribute("aria-label", `Post by ${name}`);
card.innerHTML = `
<div class="tc-content-xpost__header">
${avatarEl(avatar, name)}
<div class="tc-content-xpost__meta">
<span class="tc-content-xpost__name">${esc(name)}</span>
<span class="tc-content-xpost__handle">@${esc(handle)}</span>
</div>
<svg class="tc-content-xpost__logo" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="18" height="18">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.746l7.73-8.835L1.254 2.25H8.08l4.253 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117L17.083 19.77z"/>
</svg>
</div>
<div class="tc-content-xpost__text">${esc(text)}</div>
<div class="tc-content-xpost__stats">
<span class="tc-content-xpost__stat">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" width="16" height="16" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
${fmt(replies)}
</span>
<span class="tc-content-xpost__stat">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" width="16" height="16" aria-hidden="true"><path d="M17 1l4 4-4 4M3 11V9a4 4 0 0 1 4-4h14M7 23l-4-4 4-4M21 13v2a4 4 0 0 1-4 4H3"/></svg>
${fmt(reposts)}
</span>
<span class="tc-content-xpost__stat tc-content-xpost__stat--likes">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" width="16" height="16" aria-hidden="true"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
${fmt(likes)}
</span>
</div>
`;
return card;
},
example: {
handle: "olibuijr",
name: "Ólafur Búi",
text: "Just shipped the AI component library for AkurAI Framework — native ESM, zero deps, streaming generative UI. No React, no bundler. 🚀",
stats: { likes: 142, reposts: 38, replies: 17 },
},
};