presentation/renderers/card.renderer.ts
presentation/renderers/card.renderer.ts is a file in Bane's Lab Site. 87 lines of code and 13 definitions.
import type { Card, CardBlock, CardFile } from "#types/block.types";
import { PERMITTED_ICON, RESTRICTED_ICON } from "#configuration/icons/card.icons";
import { PERMITTED_TITLE, RESTRICTED_TITLE } from "#configuration/strings/card.strings";
import { appendChildren, createElement } from "#core/factories/element.factory";
import { FADE_IN_UP } from "#configuration/constants/element.constants";
import { ICON_BASE_CLASS } from "#configuration/icons/element.icons";
import { animated } from "#presentation/renderers/element.renderer";
import { fillMarkup } from "#presentation/renderers/text.renderer";
const PERMITTED_CLASS = "permitted";
const RESTRICTED_CLASS = "restricted";
const renderFile = function renderFile(file: CardFile): Element {
return createElement("a", {
attributes: { download: file.name, href: file.href, title: file.title },
children: [createElement("i", { className: `${ICON_BASE_CLASS} ${file.icon}` })],
className: "block-card-file",
});
};
const renderCardHeader = function renderCardHeader(card: Card): Element {
const badges = createElement("div", {
children: [createElement("span", { className: "block-card-badge", text: card.status })],
className: "block-card-badges",
});
appendChildren(badges, (card.files ?? []).map(renderFile));
const titles = createElement("div", {
children: [createElement("h3", { className: "block-card-title", text: card.title }), badges],
className: "block-card-titles",
});
return createElement("div", {
children: [createElement("i", { className: `${card.icon} block-card-icon` }), titles],
className: "block-card-header",
});
};
const renderItem = function renderItem(item: string, icon: string): Element {
return createElement("li", {
children: [
createElement("i", { className: `${ICON_BASE_CLASS} ${icon}` }),
fillMarkup(createElement("span", {}), item),
],
});
};
const renderRules = function renderRules(items: readonly string[], title: string, tone: string, icon: string): Element {
const list = createElement("ul", { className: `block-card-rules ${tone}` });
appendChildren(
list,
items.map((item) => renderItem(item, icon)),
);
return createElement("div", {
children: [createElement("h4", { className: "block-card-rules-title", text: title }), list],
className: "block-card-group",
});
};
const renderCard = function renderCard(card: Card): Element {
const body = createElement("div", { className: "block-card-body" });
appendChildren(body, [
createElement("code", { className: "block-card-spdx", text: card.spdx }),
fillMarkup(createElement("p", { className: "block-card-description" }), card.description),
]);
if (card.permitted.length > 0) {
body.append(renderRules(card.permitted, PERMITTED_TITLE, PERMITTED_CLASS, PERMITTED_ICON));
}
if (card.restricted.length > 0) {
body.append(renderRules(card.restricted, RESTRICTED_TITLE, RESTRICTED_CLASS, RESTRICTED_ICON));
}
if (card.action !== undefined) {
body.append(
createElement("a", {
attributes: { href: card.action.href },
className: "block-card-action",
text: card.action.text,
}),
);
}
return animated(
"div",
{
attributes: { id: card.id },
children: [renderCardHeader(card), body],
className: `block-card ${card.accent}`,
},
FADE_IN_UP,
);
};
export const renderCards = function renderCards(block: CardBlock): Element {
const grid = createElement("div", { className: "block-cards" });
appendChildren(grid, block.cards.map(renderCard));
return grid;
};