Skip to Content
DocsRemixComponentsAccordion

An accordion component that manages expansion state of content panels with min/max constraints.

When to use this

  • FAQ sections: Display frequently asked questions with expandable answers
  • Content organization: Organize large amounts of content in a compact, scannable format
  • Settings panels: Group related settings that can be shown/hidden
  • Navigation menus: Create collapsible menu structures with nested content

Basic implementation

Basic implementation
import 'package:flutter/material.dart'; import 'package:remix/remix.dart'; class AccordionExample extends StatefulWidget { const AccordionExample({super.key}); @override State<AccordionExample> createState() => _AccordionExampleState(); } class _AccordionExampleState extends State<AccordionExample> { final controller = RemixAccordionController<String>(min: 0, max: 1); @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return RemixAccordionGroup( controller: controller, child: ColumnBox( style: FlexBoxStyler().spacing(16), children: [ RemixAccordion( value: 'accordion1', title: 'How do I update my account information?', leadingIcon: Icons.help_outline, style: itemStyle, child: const Text( 'Insert the accordion description here. It would look better as two lines of text.', ), ), RemixAccordion( value: 'accordion2', title: 'What payment methods are accepted?', leadingIcon: Icons.help_outline, style: itemStyle, child: const Text( 'Major credit and debit cards like Visa, MasterCard, and American Express, as well as digital payment options like PayPal and Apple Pay.'), ), RemixAccordion( value: 'accordion3', title: 'How can I track my order?', leadingIcon: Icons.help_outline, style: itemStyle, child: const Text( 'You can track your order status in the "My Orders" section of your account.'), ), ], ), ); } RemixAccordionStyle<String> get itemStyle { return RemixAccordionStyle<String>() .content(BoxStyler().paddingX(16).paddingTop(8)) .wrapClipRRect(borderRadius: BorderRadius.circular(8)) .paddingX(16) .paddingY(14) .borderRounded(8) .onHovered(RemixAccordionStyle<String>().color(Colors.grey.shade100)) .decoration( BoxDecorationMix( color: Colors.white, border: BoxBorderMix.all( BorderSideMix().color(Colors.grey.shade300).width(1), ), borderRadius: BorderRadiusMix.circular(8), ), ) .trigger( FlexBoxStyler() .direction(Axis.horizontal) .mainAxisAlignment(MainAxisAlignment.spaceBetween) .spacing(12), ) .leadingIcon(IconStyler().color(Colors.grey.shade700).size(20)) .title( TextStyler() .color(Colors.grey.shade900) .fontWeight(FontWeight.w500) .fontSize(14), ) .trailingIcon(IconStyler().color(Colors.grey.shade700).size(20)); } }

Interactive preview

Resolving preview metadata...

Fortal styles

Remix includes Fortal-themed style helpers for this component:

Fortal base style
import 'package:flutter/material.dart'; import 'package:remix/remix.dart'; class FortalAccordionExample extends StatefulWidget { const FortalAccordionExample({super.key}); @override State<FortalAccordionExample> createState() => _FortalAccordionExampleState(); } class _FortalAccordionExampleState extends State<FortalAccordionExample> { final controller = RemixAccordionController<String>(); @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return RemixAccordionGroup( controller: controller, child: Column( children: [ RemixAccordion( value: 'item1', title: 'First Item', style: FortalAccordionStyle.base(), child: Text('First content'), ), RemixAccordion( value: 'item2', title: 'Second Item', style: FortalAccordionStyle.base(), child: Text('Second content'), ), ], ), ); } }

See the FortalAccordionStyle source code  for all available options.

Constructor

Constructor
// Accordion Group const RemixAccordionGroup({ Key? key, required Widget child, required RemixAccordionController<T> controller, List<T> initialExpandedValues = const [], }) // Accordion Item const RemixAccordion({ Key? key, required T value, required Widget child, String? title, IconData? leadingIcon, IconData? trailingIcon, NakedAccordionTriggerBuilder<T>? builder, bool enabled = true, MouseCursor mouseCursor = SystemMouseCursors.click, bool enableFeedback = true, bool autofocus = false, FocusNode? focusNode, ValueChanged<bool>? onFocusChange, ValueChanged<bool>? onHoverChange, ValueChanged<bool>? onPressChange, String? semanticLabel, RemixAccordionStyle style = const RemixAccordionStyle.create(), Widget Function(Widget, Animation<double>) transitionBuilder = defaultAccordionTransitionBuilder, })

Properties

Widget Properties

PropTypeRequired / Default Value
keyKey?Optional. Controls how one widget replaces another widget in the tree.
valueTRequired. Unique identifier tracked by the controller.
childWidgetRequired. Content rendered while expanded.
titleString?Optional. Title text for the trigger.
leadingIconIconData?Optional. Optional leading icon for the trigger.
trailingIconIconData?Optional. Optional trailing icon for the trigger.
builderNakedAccordionTriggerBuilder<T>?Optional. Custom builder for the trigger.
enabledboolOptional. Whether the accordion item is interactive.
mouseCursorMouseCursorOptional. Mouse cursor to use when interactive.
enableFeedbackboolOptional. Whether to provide platform feedback on interactions.
autofocusboolOptional. Whether the header should autofocus.
focusNodeFocusNode?Optional. Focus node associated with the header.
onFocusChangeValueChanged<bool>?Optional. Called when the header’s focus state changes.
onHoverChangeValueChanged<bool>?Optional. Called when the header’s hover state changes.
onPressChangeValueChanged<bool>?Optional. Called when the header’s pressed state changes.
semanticLabelString?Optional. Semantic label announced for the header.
styleRemixAccordionStyle<T>Optional. The style configuration for the accordion item.
transitionBuilderWidget Function(Widget, Animation<double>)Optional. The transition builder for the accordion item.
Last updated on

This package is currently in development — see GitHub for details.