When code exposes an identifier outward—via UI semantics (ARIA) or via string-based integration points (paths/keys/command names)—make it match the contract expected by the consuming layer.
Practical rules:
role, aria-* state, focusability) and ensure keyboard interaction corresponds to what the control “is”.trim(), case rules, path canonicalization) everywhere the identifier is produced and consumed (registration, inspection, execution). Don’t “paper over” with mismatched local formatting.Example (path normalization applied consistently):
// Shared normalization contract
function normalizeMenuPath(path: string) {
return path.trim();
}
// Use the same normalization when building UI paths and when the runner resolves them
const menuPath = normalizeMenuPath(rawMenuPath);
// ... later ...
const resolved = runnerResolve(normalizeMenuPath(menuPath));
Example (semantic naming for a UI control):
<div
role="separator"
tabIndex={0}
aria-valuemin={0}
aria-valuenow={height}
onKeyDown={(e) => {
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
// resize based on the semantic intent of the control
}
}}
/>