presentation/renderers/glossary.block.renderer.ts

presentation/renderers/glossary.block.renderer.ts is a file in Bane's Lab Site. 37 lines of code and 7 definitions.

import type { GlossaryBlock, GlossaryEntry } from "#types/block.types";
import { appendChildren, createElement } from "#core/factories/element.factory";
import { ICON_BASE_CLASS } from "#configuration/icons/element.icons";
import { NO_CLASS } from "#configuration/constants/element.constants";
import { createLink } from "#presentation/components/link.component";
import { fillMarkup } from "#presentation/renderers/text.renderer";

const renderEntry = function renderEntry(entry: GlossaryEntry): readonly Element[] {
    const term =
        entry.href === undefined
            ? createElement("dt", { text: entry.term })
            : createElement("dt", { children: [createLink(entry.href, NO_CLASS, [entry.term])] });
    return [term, fillMarkup(createElement("dd", {}), entry.description)];
};

const renderIconEntry = function renderIconEntry(entry: GlossaryEntry, icon: string): Element {
    return createElement("div", {
        children: [
            createElement("i", { className: `${ICON_BASE_CLASS} ${icon} block-icon` }),
            createElement("span", { className: "block-icon-label", text: entry.term }),
            fillMarkup(createElement("span", { className: "block-icon-description" }), entry.description),
        ],
        className: "block-icon-item",
    });
};

export const renderGlossary = function renderGlossary(block: GlossaryBlock): Element {
    const iconic = block.entries.every((entry) => entry.icon !== undefined);
    if (iconic) {
        const grid = createElement("div", { className: "block-icons" });
        appendChildren(
            grid,
            block.entries.map((entry) => renderIconEntry(entry, entry.icon ?? "")),
        );
        return grid;
    }
    const list = createElement("dl", { className: "block-glossary" });
    appendChildren(list, block.entries.flatMap(renderEntry));
    return list;
};