mattrguerra/meridian-ops-boardmainPrivate on GitHub, published here in full

html.ts

Language TypeScript1.0 KB22 lines

apps/dashboard/src/html.ts

  1. /** Tiny HTML helpers. Everything user-visible goes through `esc`. */
  2. export const esc = (s: unknown): string =>
  3. String(s ?? '').replace(
  4. /[&<>"']/g,
  5. (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c]!,
  6. )
  7. /** Join, dropping empties, so an absent optional block leaves no blank markup. */
  8. export const join = (parts: (string | false | null | undefined)[]): string =>
  9. parts.filter(Boolean).join('')
  10. // `readonly T[]` so a frozen config list (CHECKIN_QUESTIONS) maps without a
  11. // cast. Widening the parameter takes nothing away from callers passing arrays.
  12. export const map = <T>(xs: readonly T[], f: (x: T, i: number) => string): string =>
  13. xs.map(f).join('')
  14. /** A number that might not exist. Renders the absence, never a zero. */
  15. export const orUntracked = (n: number | null): string =>
  16. n === null ? '<span class="untracked">not tracked</span>' : `<span class="num">${n}</span>`
  17. export const plural = (n: number, one: string, many = `${one}s`): string => (n === 1 ? one : many)