@terrazzo/parser
Version:
Parser/validator for the Design Tokens Community Group (DTCG) standard.
65 lines (55 loc) • 1.84 kB
text/typescript
import { isTokenMatch } from '@terrazzo/token-tools';
import type { LintRule } from '../../../types.js';
import { docsLink } from '../lib/docs.js';
export const A11Y_MIN_FONT_SIZE = 'a11y/min-font-size';
export interface RuleA11yMinFontSizeOptions {
/** Minimum font size (pixels) */
minSizePx?: number;
/** Minimum font size (rems) */
minSizeRem?: number;
/** Token IDs to ignore. Accepts globs. */
ignore?: string[];
}
export const ERROR_TOO_SMALL = 'TOO_SMALL';
const rule: LintRule<typeof ERROR_TOO_SMALL, RuleA11yMinFontSizeOptions> = {
meta: {
messages: {
[ERROR_TOO_SMALL]: '{{ id }} font size too small. Expected minimum of {{ min }}',
},
docs: {
description: 'Enforce font sizes are no smaller than the given value.',
url: docsLink(A11Y_MIN_FONT_SIZE),
},
},
defaultOptions: {},
create({ tokens, options, report }) {
if (!options.minSizePx && !options.minSizeRem) {
throw new Error('Must specify at least one of minSizePx or minSizeRem');
}
for (const t of Object.values(tokens)) {
if (options.ignore && isTokenMatch(t.id, options.ignore)) {
continue;
}
// skip aliases
if (t.aliasOf) {
continue;
}
if (t.$type === 'typography' && 'fontSize' in t.$value) {
const fontSize = t.$value.fontSize!;
if (
(fontSize.unit === 'px' && options.minSizePx && fontSize.value < options.minSizePx) ||
(fontSize.unit === 'rem' && options.minSizeRem && fontSize.value < options.minSizeRem)
) {
report({
messageId: ERROR_TOO_SMALL,
data: {
id: t.id,
min: options.minSizePx ? `${options.minSizePx}px` : `${options.minSizeRem}rem`,
},
});
}
}
}
},
};
export default rule;