diff --git a/src/components/editorAccessibility.ts b/src/components/editorAccessibility.ts index f2cc1779..376a9a0b 100644 --- a/src/components/editorAccessibility.ts +++ b/src/components/editorAccessibility.ts @@ -37,6 +37,20 @@ function normalizedAccessibilityValue( return normalized ? normalized : undefined; } +/** Reject runtime direction values outside Inkspan's public finite contract. */ +function validateEditorTextDirection( + value: EditorTextDirection | undefined, +): void { + if ( + value !== undefined && + value !== 'ltr' && + value !== 'rtl' && + value !== 'auto' + ) { + throw new RangeError('Editor text direction must be ltr, rtl, or auto.'); + } +} + /** * Normalize the shared visual and semantic empty-editor guidance. * @@ -61,6 +75,7 @@ export function normalizeEditorPlaceholder( export function buildEditorAccessibilityAttributes( options: EditorAccessibilityOptions, ): Record { + validateEditorTextDirection(options.textDirection); const placeholder = normalizeEditorPlaceholder(options.placeholder); const languageTag = normalizedAccessibilityValue(options.languageTag); const labelledBy = normalizedAccessibilityValue(options.ariaLabelledBy); diff --git a/src/components/editorAccessibilityRuntime.test.ts b/src/components/editorAccessibilityRuntime.test.ts new file mode 100644 index 00000000..04ce1ea4 --- /dev/null +++ b/src/components/editorAccessibilityRuntime.test.ts @@ -0,0 +1,29 @@ +import { describe, expect, it } from 'vitest'; +import { buildEditorAccessibilityAttributes } from './editorAccessibility.js'; + +describe('editor accessibility runtime contracts', () => { + it.each(['ltr', 'rtl', 'auto'] as const)( + 'preserves the valid %s text direction', + (textDirection) => { + expect( + buildEditorAccessibilityAttributes({ + defaultLabel: 'Editor', + editable: true, + textDirection, + }).dir, + ).toBe(textDirection); + }, + ); + + it('rejects a runtime text direction outside the public enumerated states', () => { + expect(() => + buildEditorAccessibilityAttributes({ + defaultLabel: 'Editor', + editable: true, + textDirection: 'sideways' as never, + }), + ).toThrowError( + new RangeError('Editor text direction must be ltr, rtl, or auto.'), + ); + }); +});