Implement Export Format Selector Widget
epic-bufdir-reporting-export-ui-task-003 — Build the BufdirExportFormatSelector Flutter widget presenting Excel, CSV, and PDF options as selectable cards. Each card must display the format name, file-type icon, and a short Bufdir compatibility note. Selection state is managed internally and exposed via callback. Meets WCAG 2.2 AA contrast and focus-order requirements.
Acceptance Criteria
Technical Requirements
Implementation Notes
Model formats as a BufdirExportFormat enum with a metadata extension: displayName, fileExtension, bufdirNote, iconData. This keeps the card widget free of business logic. Use a simple selectedFormat state variable inside a StatefulWidget — no BLoC needed for this isolated widget. The active card border should use a design token like AppColors.primary with AppBorderRadius.md.
Use IndexedSemantics or explicit Semantics(selected: isSelected) on each card so screen readers announce selection changes. Pre-select Excel by default as it is the Bufdir-standard import format per project documentation. Export the enum and widget from a single barrel file.
Testing Requirements
Write flutter_test widget tests: (1) all three cards render with correct labels, (2) tapping Excel fires onFormatSelected(BufdirExportFormat.excel), (3) tapping CSV after Excel deselects Excel and selects CSV — callback fires once with CSV, (4) initialFormat pre-selects the correct card without firing callback, (5) Semantics labels reflect selected/unselected state accurately, (6) no overflow at text scale 1.5×. Snapshot test the three-card layout at 375 px width (iPhone SE) and 414 px width (iPhone Pro).
For large exports that run for 10–30 seconds, a static loading spinner will feel broken to users on slow mobile connections. If the UI cannot display meaningful progress during the export pipeline, coordinators may abandon the flow or trigger duplicate exports by pressing the button multiple times.
Mitigation & Contingency
Mitigation: Implement streaming progress events from the orchestrator BLoC through named pipeline stages (querying, mapping, generating, uploading). Display each stage label with a progress indicator on the trigger screen. Disable the generate button immediately on first tap to prevent duplicates.
Contingency: If streaming pipeline progress is not feasible in the first release, implement a deterministic stage-based progress animation (10% querying, 50% generating, 90% uploading) that gives users feedback without requiring real server events.
Custom date range pickers are among the most common accessibility failures in mobile apps. Blindeforbundet users rely on VoiceOver, and NHF users include people with cognitive impairments. A non-accessible period picker could make the entire export workflow unusable for a significant portion of the intended user base.
Mitigation & Contingency
Mitigation: Build the period picker using Flutter's native date picker semantics as the foundation, with preset shortcuts as primary navigation (reducing the need to interact with the custom range picker at all). Test with VoiceOver on iOS and TalkBack on Android before UI epic sign-off. Engage Blindeforbundet's test contact for accessibility validation.
Contingency: If the custom date range picker cannot be made fully accessible before release, ship only the preset period shortcuts (covering the majority of use cases) and add the custom range picker in a follow-up sprint after dedicated accessibility remediation.