/** * Naming Validator * * Validates BEM/BEMIT naming conventions in Eddie components: * - CSS class prefixes (ed-c-, ed-l-, ed-u-, ed-r-, ed-p-, etc.) * - BEM structure (block__element--modifier) * - Detects unclassed HTML elements in Lit component templates * * Understands Lit-specific patterns: * - Only scans inside html`...` tagged template literals * - Recognizes dynamic class bindings (class="${expr}") * - Skips JSDoc/comment blocks * - Skips .stories.ts files for unclassed element checks (slot content is fine) */ import { HealthIssue } from '../types.js'; export declare class NamingValidator { /** * Class prefix patterns */ /** * Valid class prefixes, in match order. * * The namespaced state prefixes (`ed-is-` / `ed-has-`) MUST precede the bare * ones: the extraction loop below breaks on its first match, and a bare * `/^is-/` would never match `ed-is-active` anyway — but keeping the pair * adjacent and namespaced-first documents that the `ed-` form is the * canonical one. Eddie writes the namespaced form in every one of its own * state classes (#1798: 16 distinct names, 297 occurrences, zero bare ones), * which is the correct reading of BEMIT inside a global `ed-` namespace — * every other prefix in this list carries the namespace too. The bare forms * stay valid for consumer code that predates the convention. */ private readonly validPrefixes; /** * HTML elements that can exist without a class * - SVG internals, slots, templates, scripts, style tags * - Custom elements (contain a hyphen) always skip */ private readonly unclassedAllowed; /** * Components whose slotted content is prose, where unclassed HTML is the * documented authoring pattern rather than a violation. Everything between * the open and close tag is exempt from the unclassed-element rule. */ private readonly proseContainers; /** * Validate a single component file */ validateFile(filePath: string): Promise; /** * Validate all component files in a directory */ validateDirectory(dirPath: string): Promise; /** * Validate a single CSS class name string */ validateClassName(className: string): HealthIssue | null; /** * Validate HTML elements inside Lit templates. * * Key behaviors: * - Extracts only the content inside html`...` tagged template literals * - Strips JSDoc/block comments before scanning * - Recognizes dynamic class bindings: class="${...}" counts as having a class * - Skips unclassed-element checks in .stories.ts (slot content is fine) * - Skips self-closing void elements and custom elements (contain hyphen) */ private validateTemplate; /** * Check for HTML elements without classes in template content. * * Understands: * - class="${expr}" — dynamic class, counts as having a class * - class="literal" — static class * - styleModifier="..." — Eddie's pattern for passing classes to children * - Tags with a hyphen are custom elements (always skip) */ /** * Which lines of a file sit inside an `ed-text-passage` (#1727). * * `ed-text-passage` is Eddie's sanctioned home for unclassed prose — "no * unclassed tags except in TextPassage" (CLAUDE.md) — and it ships a * light-DOM stylesheet precisely to style elements that carry no class. So a * `

`/`

  • `/`

    ` inside one is correct authoring, and telling an author * to add a BEM class there makes the code **worse**: the element opts out of * the prose styling it exists to receive. * * This is computed across the whole file instead of per template region. The * region extractor is a line-based state machine that splits on a multi-line * nested ``html`` template, and a split in the middle of a passage restarted * the depth count at zero — so the second and later entries of a mapped list * inside a passage were flagged while the first was not. * * Line-based and deliberately coarse: over-suppressing inside a passage is * the safe direction, since the alternative is advice that damages the code. */ private findProseLines; private checkUnclassedElements; /** * Check static class name values in templates for Eddie naming compliance. * Only validates literal class strings, not dynamic ${} expressions. */ private checkStaticClassNames; /** * Validate class names in SCSS file */ private validateStyleFile; /** * Validate a single class name string against Eddie's BEM/BEMIT conventions */ private classNameValidation; /** * Validate BEM structure (block__element--modifier) * Allows: block, block__element, block--modifier, block__element--modifier * Parts can contain hyphens (single) for multi-word names. Element and * modifier segments may be purely numeric (e.g. `ed-c-logo__dot--1`) — * numbered modifiers are legitimate BEM; only the block must start with * a letter. */ private validateBemStructure; /** * Suggest a corrected class name */ private suggestClassName; } //# sourceMappingURL=naming-validator.d.ts.map