panel splitters get keyboard parity and Semantics (T-111)

Drag handles for sidebar / context / editor split were pure
pointer-Listeners — no Tab focus, no arrow-key adjust, no Semantics.
Each now wraps in a FocusableActionDetector with arrow shortcuts (10
px fine / 50 px coarse for the column handles, 2% / 10% for the
editor split) and a slider Semantics node that announces the current
size. The CLI verb half is split out as T-119 and waits on T-99.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-05-18 09:43:56 +02:00
co-authored by Claude
parent f113cb5efd
commit 5d1237501c
6 changed files with 207 additions and 40 deletions
@@ -4,6 +4,7 @@ library;
import 'package:clide/extension/extension.dart';
import 'package:clide/kernel/kernel.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -83,6 +84,40 @@ void main() {
expect(arr.sizeOf(Slots.contextPanel), 150);
});
testWidgets('exposes a slider Semantics node with the current size', (tester) async {
final arr = LayoutArrangement();
arr.applyPreset(const LayoutPresetContribution(
id: 'test-preset',
displayName: 'Test',
slots: [
LayoutSlot(slot: Slots.sidebar, position: SlotPosition.left, defaultSize: 240),
],
));
final semHandle = tester.ensureSemantics();
await tester.pumpWidget(harness(
f,
Center(
child: SizedBox(
width: 40,
height: 200,
child: DragResizeHandle(
arrangement: arr,
slot: Slots.sidebar,
axis: Axis.horizontal,
),
),
),
));
await tester.pumpAndSettle();
final data = tester.getSemantics(find.byType(DragResizeHandle));
expect(data.label, 'Sidebar width');
expect(data.value, '240 pixels');
final actions = data.getSemanticsData().actions;
expect(actions & SemanticsAction.increase.index, isNot(0));
expect(actions & SemanticsAction.decrease.index, isNot(0));
semHandle.dispose();
});
testWidgets('hovered state flips the line colour without throwing', (tester) async {
final arr = LayoutArrangement();
arr.applyPreset(const LayoutPresetContribution(