import type { TileView } from "./types.ts"; import { durationTag, escapeHtml, STATUS_DOT } from "./tile-render-values.ts"; /** * The markup under a view's headline: its `extra`, with the span its * `duration` gives drawn in the chart's corner. A duration labels the chart in * `extra`, so without chart markup there is no positioned box for the label. */ export function chartBody(v: TileView): string { return v.duration && v.extra ? `
${v.extra}${ durationTag(v.duration) }
` : (v.extra ?? ""); } /** What a link to `href` adds to open it in a new tab when it leaves the page. */ export function newTab(href: string): string { return /^https?:/.test(href) ? ` target="_blank" rel="noopener"` : ""; } /** * A box carrying `attributes` that holds the texture layer, then `head`, then * `chart`, all of it a link to `link.href` when there is a `link`, with its * `hint` as the link's tooltip and description. The box is that link, unless * `chart` holds links of its own: an anchor cannot hold another, so the link * then wraps the texture and `head`, and `chart` follows it. The texture * covers the box, so all of the box but `chart` is still the link. */ export function linkedBox( attributes: string, head: string, chart: string, link?: { href: string; hint?: string }, ): string { const texture = `
`; if (link === undefined) { return `
${texture}${head}${chart}
`; } const target = `href="${escapeHtml(link.href)}"${newTab(link.href)}${ link.hint ? ` aria-description="${escapeHtml(link.hint)}" title="${escapeHtml(link.hint)}"` : "" }`; return /]/i.test(chart) ? `
${texture}${head}${chart}
` : `${texture}${head}${chart}`; } export function renderTile(label: string, v: TileView, wide = false): string { const cls = `tile ${v.status}${v.href ? " link" : ""}${wide ? " wide" : ""}${ v.alignChartBottom ? " bottom-chart" : "" }`; const attributes = `class="${cls}" data-tile-label="${escapeHtml(label)}"`; const dot = ``; const hint = v.hint ? `` : ""; const header = `

${dot} ${ escapeHtml(label) }${v.aside ?? ""}${hint}

`; const big = v.value !== undefined ? `

${v.value}

` : ""; const sub = v.sub ? `

${escapeHtml(v.sub)}

` : ""; return linkedBox( attributes, `${header}${big}${sub}`, chartBody(v), v.href ? { href: v.href, hint: v.hint } : undefined, ); }