JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2484
  • Score
    100M100P100Q115439F
  • License MIT

Accessibility linter for Templatical email templates

Package Exports

  • @templatical/quality

Readme

@templatical/quality

Accessibility linter for Templatical email templates. Runs in the browser or on Node.

npm version License

Deterministic accessibility checks against the JSON TemplateContent block tree — missing alt text, low-contrast text and buttons, vague link / CTA copy, heading-skip, undersized touch targets, and more. Same package validates inside the editor (live sidebar tab + canvas badges) and in headless / CI checks.

MIT-licensed, JSON-only, no Vue, no DOM. Optional peer of @templatical/editor.

Install

npm install @templatical/quality

Usage

Headless

import { lintAccessibility } from "@templatical/quality";
import type { TemplateContent } from "@templatical/types";

const content: TemplateContent = JSON.parse(stored);
const issues = lintAccessibility(content);

for (const issue of issues) {
  console.log(`[${issue.severity}] ${issue.ruleId}: ${issue.message}`);
}

lintAccessibility(content, options?) is synchronous and pure — no DOM, no network, no fetch.

Editor

@templatical/editor lazy-imports this package on demand. Pass accessibility to init() / initCloud():

import { init } from "@templatical/editor";

init({
  container: "#editor",
  locale: "en",
  accessibility: {
    rules: {
      "img-missing-alt": "warning",
      "text-all-caps": "off",
    },
    thresholds: { minFontSize: 16 },
  },
});

The sidebar tab and inline canvas badges appear automatically once this peer is resolved.

Custom rules

Compose your own walkers using the same primitives the package ships:

import { walkBlocks, getContrastRatio } from "@templatical/quality";

walkBlocks(content, (block, ctx) => {
  if (block.type === "title" && block.color) {
    const ratio = getContrastRatio(block.color, ctx.resolvedBackgroundColor);
    if (ratio < 4.5) {
      console.warn(`Heading ${block.id} contrast ${ratio.toFixed(2)}:1`);
    }
  }
});

Docs