9227ddf696
* test: add text ANSI sanitization parity tests from Ink (+15) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: add use-animation parity tests from Ink (+43) Port 43 new tests from Ink's use-animation test suite covering: - Multiple animations in sync, different rates, sibling unmount - Timer cleanup/recreation on unmount and remount - Inactive animations, timer leak prevention - Edge intervals (NaN, Infinity, -Infinity, oversized, zero, negative) - isActive toggle resets, pause/resume cycles - Frame catch-up, time/delta tracking, reset() behavior - Newly mounted/activated animations don't inherit elapsed time - Wall clock monotonicity, getter function isActive support Uses selective fake timers (setInterval + performance only) so that render()'s internal setImmediate still works on real clocks. Fake timer tests read refs directly to avoid Vue scheduler flush timing issues. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: add use-box-metrics/measure parity tests from Ink (+16) Port 16 missing tests from Ink's use-box-metrics, measure-element, and measure-text test suites. Fix useBoxMetrics to reset metrics to zeros when the tracked ref detaches (element unmounts or ref switches to null). 3 tests are skipped because vue-tui's useBoxMetrics uses watchPostEffect (re-runs only when ref.value changes) rather than Ink's layout-commit listener pattern, so sibling-content and resize-driven re-measurement is not yet supported. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: add screen-reader parity tests from Ink (+11) Add 11 screen-reader integration tests covering aria-label substitution on Text/Box, ANSI styling omission, multiple/nested components, null component, aria-state variants (busy, disabled, expanded), multi-line roles, and multiselectable listbox. Also fix component prop bug: Vue normalizes kebab-case prop names to camelCase at runtime, so props["aria-label"] was always undefined. Switch Box/Text prop declarations and access to camelCase (ariaLabel, ariaHidden, ariaRole, ariaState). Add isScreenReaderEnabled option to renderToString() so tests can exercise screen-reader output through the component pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: add render-to-string parity tests from Ink (+18) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: add cursor composable parity tests from Ink (+7) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: add 6 missing screen-reader Ink parity tests Add tests for aria-hidden, select input (list with roles/states/labels), aria-state.multiline, aria-state.readonly, aria-state.required, and nested multi-line text rendering in screen-reader mode. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: fix render-to-string missing Ink parity tests (+10) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: fix cursor composable missing Ink parity tests (+6) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: fix use-box-metrics missing Ink parity tests (+4) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: add layout listener so useBoxMetrics updates on resize and sibling changes Adds a layout listener mechanism to TuiRoot matching Ink's architecture: - TuiRoot.layoutListeners Set with addLayoutListener/emitLayoutListeners - emitLayoutListeners called after every yoga.calculateLayout in commit() - useBoxMetrics subscribes to layout listeners, diffs values before updating Enables 4 previously-skipped tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>