An accordion component that manages expansion state of content panels with min/max constraints.
Interactive preview
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
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.',
),
),
],
),
);
}
RemixAccordionStyler get itemStyle {
return RemixAccordionStyler()
.content(.padding(.horizontal(16).top(8)))
.wrap(.clipRRect(borderRadius: .circular(8)))
.paddingX(16)
.paddingY(14)
.borderRounded(8)
.onHovered(.color(Colors.grey.shade100))
.decoration(
BoxDecorationMix.color(Colors.white)
.border(
.color(Colors.grey.shade300)
.width(1),
)
.borderRadius(.circular(8)),
)
.trigger(
.direction(.horizontal)
.mainAxisAlignment(.spaceBetween)
.spacing(12),
)
.leadingIcon(.color(Colors.grey.shade700).size(20))
.title(
.color(Colors.grey.shade900)
.fontWeight(.w500)
.fontSize(14),
)
.trailingIcon(.color(Colors.grey.shade700).size(20));
}
}Fortal widgets
Remix includes a generated Fortal-themed widget for this component:
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: [
FortalAccordion.surface(
value: 'item1',
title: 'First Item',
size: FortalAccordionSize.size2,
child: Text('First content'),
),
FortalAccordion.soft(
value: 'item2',
title: 'Second Item',
size: FortalAccordionSize.size3,
child: Text('Second content'),
),
],
),
);
}
}See the fortalAccordionStyler source code for all available options.
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,
Widget Function(Widget, Animation<double>) transitionBuilder = defaultAccordionTransitionBuilder,
RemixAccordionStyler style = const RemixAccordionStyler.create(),
RemixAccordionSpec? styleSpec,
})Properties
Widget Properties
key → Key?
Optional. Controls how one widget replaces another widget in the tree.
value → T
Required. Unique identifier tracked by the controller.
child → Widget
Required. Content rendered while expanded.
title → String?
Optional. Title text for the trigger.
leadingIcon → IconData?
Optional. Optional leading icon for the trigger.
trailingIcon → IconData?
Optional. Optional trailing icon for the trigger.
builder → NakedAccordionTriggerBuilder<T>?
Optional. Custom builder for the trigger.
enabled → bool
Optional. Whether the accordion item is interactive.
mouseCursor → MouseCursor
Optional. Mouse cursor to use when interactive.
enableFeedback → bool
Optional. Whether to provide platform feedback on interactions.
autofocus → bool
Optional. Whether the header should autofocus.
focusNode → FocusNode?
Optional. Focus node associated with the header.
onFocusChange → ValueChanged<bool>?
Optional. Called when the header’s focus state changes.
onHoverChange → ValueChanged<bool>?
Optional. Called when the header’s hover state changes.
onPressChange → ValueChanged<bool>?
Optional. Called when the header’s pressed state changes.
semanticLabel → String?
Optional. Semantic label announced for the header.
style → RemixAccordionStyler
Optional. The style configuration for the accordion item.
styleSpec → RemixAccordionSpec?
Optional. A raw resolved style spec that bypasses fluent style resolution.
transitionBuilder → Widget Function(Widget, Animation<double>)
Optional. The transition builder for the accordion item.
Style Methods
trigger(FlexBoxStyler value)
Configures the trigger row style.
leadingIcon(IconStyler value)
Configures the leading icon style.
title(TextStyler value)
Configures the title text style.
trailingIcon(IconStyler value)
Configures the trailing icon style.
content(BoxStyler value)
Configures the expanded content container style.
backgroundColor(Color value) / color(Color value)
Sets the trigger background color.
padding(EdgeInsetsGeometryMix value)
Sets trigger padding.
margin(EdgeInsetsGeometryMix value)
Sets trigger margin.
spacing(double value)
Sets spacing between trigger children.
alignment(Alignment value)
Sets trigger alignment.
size(double width, double height)
Sets fixed trigger width and height constraints.
constraints(BoxConstraintsMix value)
Sets trigger constraints.
decoration(DecorationMix value)
Sets trigger decoration.
borderRadius(BorderRadiusGeometryMix radius)
Sets trigger border radius.
foregroundDecoration(DecorationMix value)
Sets trigger foreground decoration.
transform(Matrix4 value, {AlignmentGeometry alignment = .center})
Applies a matrix transform to the trigger.
flex(FlexStyler value)
Configures trigger flex behavior.
titleColor(Color value)
Sets title color.
titleFontSize(double value)
Sets title font size.
titleFontWeight(FontWeight value)
Sets title font weight.
titleStyle(TextStyleMix value)
Sets title style using a TextStyleMix.
leadingIconColor(Color value)
Sets leading icon color.
leadingIconSize(double value)
Sets leading icon size.
trailingIconColor(Color value)
Sets trailing icon color.
trailingIconSize(double value)
Sets trailing icon size.
contentColor(Color value)
Sets expanded content background color.
contentPadding(EdgeInsetsGeometryMix value)
Sets expanded content padding.
contentDecoration(DecorationMix value)
Sets expanded content decoration.
onExpanded<T>(RemixAccordionStyler value)
Applies a style while the item is expanded.
onCollapsed<T>(RemixAccordionStyler value)
Applies a style while the item is collapsed.
onCanCollapse(RemixAccordionStyler value)
Applies a style while the item can be collapsed.
onCanExpand<T>(RemixAccordionStyler value)
Applies a style while the item can be expanded.
animate(AnimationConfig value)
Configures implicit animation for style transitions.
variants(List<VariantStyle<RemixAccordionSpec>> value)
Sets custom style variants.
wrap(WidgetModifierConfig value)
Applies widget modifiers such as clipping, opacity, or scaling.