From 173c1c8b6165ccffd4d46abdf005e6aa7fe64cf9 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 11 Aug 2026 19:38:12 +0900 Subject: [PATCH 1/3] test: prove editor direction fails closed at runtime --- .../editorAccessibilityRuntime.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/components/editorAccessibilityRuntime.test.ts diff --git a/src/components/editorAccessibilityRuntime.test.ts b/src/components/editorAccessibilityRuntime.test.ts new file mode 100644 index 00000000..1f42c9df --- /dev/null +++ b/src/components/editorAccessibilityRuntime.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from 'vitest'; +import { buildEditorAccessibilityAttributes } from './editorAccessibility.js'; + +describe('editor accessibility runtime contracts', () => { + 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.'), + ); + }); +}); From 579e803ff2497936f304d3c63dbcca443fb13d05 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 11 Aug 2026 19:44:24 +0900 Subject: [PATCH 2/3] test: cover every supported editor direction --- src/components/editorAccessibilityRuntime.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/editorAccessibilityRuntime.test.ts b/src/components/editorAccessibilityRuntime.test.ts index 1f42c9df..04ce1ea4 100644 --- a/src/components/editorAccessibilityRuntime.test.ts +++ b/src/components/editorAccessibilityRuntime.test.ts @@ -2,6 +2,19 @@ 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({ From 16d6a12f87bcf487102329b7ebbc5ca2b8652a56 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 11 Aug 2026 19:45:14 +0900 Subject: [PATCH 3/3] fix: reject invalid runtime editor direction --- src/components/editorAccessibility.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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);