Skip to content

FRD-061: Export Menu Widget

FieldValue
OwnerDavid Holmes
StatusDraft
Last Updated2026-05-26
Target Releasev2.0.0 (P2)
T-Shirt SizeS
TypeWidget

Document Summary

A dropdown-based export menu widget that lets users choose an export format, optionally select which fields to include, and trigger a download. Designed for data tables, reports, and dashboard exports across SaaS products.


Introduction

Overview

Data export is a recurring need in SaaS applications. Users expect to download table data, reports, or filtered views in formats like CSV, JSON, XLSX, or PDF. This widget provides a standardized export dropdown with format selection, optional field picking, and a download CTA.

Goals

  • Dropdown menu triggered by an export button.
  • Format picker supporting configurable format options (CSV, JSON, XLSX, PDF, etc.).
  • Optional field-selection checklist for choosing which columns/fields to export.
  • Download CTA that invokes a consumer callback with selected format and fields.
  • Ship Storybook stories covering format-only, with-field-selection, and loading states.

Non-Goals

  • Actual file generation (consumer produces the file blob or URL).
  • Server-side export orchestration.
  • Scheduled or recurring exports.
  • Email delivery of export files.

Scope

In Scope

ItemDescription
ExportMenu componentDropdown with format picker, field selector, and download CTA
Format optionsConfigurable list of export formats
Field selectionOptional checklist of fields/columns to include
Download actionCalls onExport({ format, fields }) callback
Storybook storiesFormatsOnly, WithFieldSelection, Loading, Disabled

Out of Scope

ItemRationale
File generationConsumer handles blob/URL creation
Background export jobsRequires backend queuing infrastructure
Export historySeparate widget concern

Users and Pain Points

UserPain Point
Data analystsInconsistent export options across different tables and views
Product teamsRebuilding export menus per feature with varying format support
End usersNot knowing which formats are available or what data will be included

Definitions

TermDefinition
Export formatThe file type for the download (e.g., CSV, JSON, XLSX, PDF)
Field selectionA subset of available data columns the user chooses to include
Download CTAThe button that initiates the export/download action

Current State

No export menu widget exists. Products use ad-hoc dropdown menus or inline buttons for exports. The DropdownMenu primitive is available and can serve as the foundation.


Proposed Solution

Create an ExportMenu widget at src/components/widgets/export-menu.tsx that:

  1. Renders a trigger button (configurable label, defaults to “Export”).
  2. Opens a dropdown menu with format options as selectable items.
  3. Optionally shows a field-selection checklist when fields prop is provided.
  4. Includes a “Download” or “Export” CTA at the bottom of the dropdown.
  5. Calls onExport with the selected format and fields.
  6. Supports a loading state that shows a spinner on the CTA and disables interaction.

Requirements

The widget is a controlled dropdown that delegates all file generation to the consumer via callbacks. It must not trigger file downloads directly.


Functional Requirements

IDRequirementPriority
FR-01Render a trigger button that opens the export dropdownMust
FR-02Display a list of format options with icons and labelsMust
FR-03Allow single-select of a format (radio behavior)Must
FR-04Optionally display a field checklist with select-all/deselect-allShould
FR-05Render a download CTA button inside the dropdownMust
FR-06Call onExport({ format, fields }) when CTA is clickedMust
FR-07Support a loading prop that disables CTA and shows spinnerMust
FR-08Support a disabled prop on the trigger buttonMust
FR-09Close the dropdown after successful export callbackShould
FR-10Pre-select a default format via defaultFormat propShould

Non-Functional Requirements

IDRequirement
NFR-01Bundle size under 2 KB gzipped (excluding shared primitives)
NFR-02Dropdown opens within one animation frame
NFR-03Full light/dark theme support

API / Interface Requirements

interface ExportFormat {
id: string;
label: string;
icon?: ReactNode;
description?: string;
}
interface ExportField {
id: string;
label: string;
defaultSelected?: boolean;
}
interface ExportMenuProps {
formats: ExportFormat[];
fields?: ExportField[];
defaultFormat?: string;
triggerLabel?: string; // default "Export"
downloadLabel?: string; // default "Download"
loading?: boolean;
disabled?: boolean;
onExport: (payload: { format: string; fields?: string[] }) => void | Promise<void>;
className?: string;
}

Accessibility Requirements

IDRequirement
A11Y-01Dropdown follows WAI-ARIA menu pattern with keyboard navigation
A11Y-02Format options use role="menuitemradio" with aria-checked
A11Y-03Field checkboxes use role="menuitemcheckbox" with aria-checked
A11Y-04Trigger button has aria-haspopup="menu" and aria-expanded
A11Y-05Loading state conveys status via aria-busy on the CTA

Content and Documentation Requirements

  • Storybook doc page with props, usage examples, and integration guidance.
  • Stories: FormatsOnly, WithFieldSelection, Loading, Disabled, PreselectedFormat.
  • JSDoc on all exported types and the main component.

Dependencies

DependencyTypeNotes
DropdownMenuInternalMenu container and item primitives
ButtonInternalTrigger and download CTA
CheckboxInternalField selection items
SpinnerInternalLoading state

Risks and Tradeoffs

RiskImpactMitigation
Long field lists overflow the dropdownPoor UXCap visible fields at 10 with scroll; add search filter in follow-up
Format icons inconsistencyVisual clutterProvide default icons for common formats (CSV, JSON, PDF, XLSX)
Async export takes too longUser re-clicksDisable CTA during loading; show progress if export is slow

Open Questions

  1. Should the dropdown remain open during async export, or close immediately?
  2. Do we need a “Select columns” sub-menu or inline checklist?
  3. Should there be a “Remember my preferences” option using localStorage?

Acceptance Criteria

  • Trigger button opens a dropdown with format options.
  • Selecting a format and clicking download calls onExport with correct payload.
  • Field selection checklist works with select-all/deselect-all.
  • Loading state disables the CTA and shows a spinner.
  • All Storybook stories render without errors.
  • Passes axe accessibility audit with zero violations.
  • Unit tests cover format selection, field selection, and export callback.

LLM Handoff Instructions

When implementing this FRD:

  1. Create src/components/widgets/export-menu.tsx.
  2. Use DropdownMenu from @/components/ui/dropdown-menu as the foundation.
  3. Create src/components/widgets/export-menu.stories.tsx with all listed stories.
  4. Create src/components/widgets/export-menu.test.tsx.
  5. Provide default icons for CSV (FileText), JSON (Code2), PDF (FileText), XLSX (Table) from the icon pack.
  6. Follow existing widget patterns for prop naming and callback conventions.

Decision Log

DateDecisionRationale
2026-05-26Widget does not generate filesKeeps the widget portable; file generation varies by data source
2026-05-26Field selection is optionalMany exports don’t need field picking; keeps the simple case simple

Document History

DateVersionAuthorChanges
2026-05-260.1David HolmesInitial draft