Expandable
The Expandable widget is a versatile UI component that allows you to show or hide content dynamically. It consists of a header that remains always visible and collapsible content that can be revealed or hidden with a tap. This widget is particularly useful for creating accordions, FAQ sections, collapsible forms, and any interface where space conservation is important while still providing access to detailed information on demand.
Expandable widgets help reduce visual clutter by allowing users to access information only when they need it, creating cleaner, more organized interfaces especially on mobile devices or complex forms.
Use Cases
Expandable is ideal for:
FAQ Sections: Display questions as headers with answers that expand on tap.
Accordion Menus: Create collapsible navigation or category lists.
Settings Panels: Hide advanced options until users need them.
Product Details: Show basic info by default, expand for specifications.
Forms with Sections: Organize long forms into collapsible sections.
Filter Panels: Show/hide filter options in e-commerce or search interfaces.
Reading Lists: Display article titles with expandable summaries.
Terms & Conditions: Show abbreviated text with full text expansion.
Educational Content: Display lesson titles with expandable content.
User Profiles: Collapse sections like "About", "Skills", "Experience".
User Experience Tip: Always provide clear visual indicators (like icons or arrows) that show whether content is expanded or collapsed. This helps users understand the widget's interactive nature.
Core Concepts
1. Three Required Children Slots
The Expandable widget requires three separate child widgets to function properly:
header: The always-visible part that users tap to toggle expansion.collapsedView: The content shown when the widget is in its collapsed state.expandedView: The content shown when the widget is in its expanded state.
All three children are required. The widget automatically handles the transition between collapsed and expanded views based on user interaction.
2. State Management: Collapsed vs. Expanded
The Expandable widget maintains an internal state that determines which view is currently visible:
Collapsed State: Shows the header and collapsedView content.
Expanded State: Shows the header and expandedView content.
You can control the initial state using the Initially Expanded property, and users can toggle between states by tapping (depending on your tap behavior configuration). You can also bind Initially Expanded to expressions or variables to dynamically control the expansion state based on app logic.
3. Tap Behavior Flexibility
Unlike simple toggles, Expandable provides granular control over tap interactions:
Tap Header to Toggle: Most common pattern—tapping the header switches states.
Tap Body to Expand: Tapping the collapsed content can expand it.
Tap Body to Collapse: Tapping the expanded content can collapse it.
These options can be enabled independently, giving you complete control over the interaction model.
4. Visual Feedback with Icons & Animations
Expandable provides built-in support for:
Expand/Collapse Icons: Automatically swap icons based on state.
Icon Rotation: Smoothly rotate icons during transitions (e.g., chevron pointing down → up).
Animation Duration: Control how fast the expand/collapse animation plays.
InkWell Effect: Add Material Design ripple effects to interactions.
Children Slots
The Expandable widget has three required children slots:
header
Required. The always-visible part of the widget, typically containing a title or label. This is what users see and tap to toggle expansion.
collapsedView
Required. The content displayed when the widget is in its collapsed state. Often contains a brief summary, preview, or placeholder.
expandedView
Required. The content displayed when the widget is in its expanded state. Contains the full detailed information or interactive elements.
Properties
Active View Property
Active View
Dashboard Preview Only. Controls whether the widget appears in the Collapsed or Expanded state in the builder dashboard. This is purely for design preview purposes and does not affect the runtime behavior of the widget.
Initially Expanded
If true, the widget will be in the expanded state by default when the page first loads in the actual app. Default is false (collapsed). This is the property that controls the real initial state.
Tap Behavior Properties
These properties control how users can interact with the widget:
Tap Header to Toggle
If true, tapping anywhere on the header will toggle between collapsed and expanded states. This is the most common interaction pattern.
Tap Body to Expand
If true, tapping on the collapsed content will expand the widget. Useful when you want the collapsed content to be interactive.
Tap Body to Collapse
If true, tapping on the expanded content will collapse the widget. Useful for "dismiss" behavior.
Alignment Properties
Control how content is positioned within each slot:
Alignment
The alignment of the entire expandable widget within its parent container (e.g., left, center, right).
Header Alignment
The alignment of content within the header slot. Controls how child widgets are positioned inside the header.
Body Alignment
The alignment of content within the collapsed and expanded view slots.
Icon Properties
The Expandable widget has built-in support for state-indicating icons:
Has Icon
If true, an icon will be displayed in the header to indicate the expand/collapse state.
Icon Placement
Where to position the icon within the header: Left or Right.
Collapsed Icon
The icon to display when the widget is in the collapsed state (e.g., chevron_down, add, arrow_forward).
Expanded Icon
The icon to display when the widget is in the expanded state (e.g., chevron_up, remove, arrow_drop_down).
Icon Size
The size of the icon in pixels. Default is typically 24px.
Icon Color
The color of the icon. Can be set from your design system colors or as a custom hex value.
Icon Padding
The padding around the icon to create spacing between the icon and other header content.
Icon Rotation Angle
The angle (in degrees) to rotate the icon when transitioning to the expanded state. Creates smooth rotation animations (e.g., 180° to flip a chevron).
Icon Best Practice: Use consistent icon pairs across your app:
chevron_right/expand_morefor horizontal/vertical expansionadd/removefor accordion-style interfacesarrow_forward/arrow_drop_downfor dropdown-like behavior
Style & Animation Properties
Animation Duration
The duration of the expand and collapse animation in milliseconds. Default is typically 300ms. Lower values create snappier transitions, higher values create smoother, more deliberate animations.
Use InkWell Effect
If true, a Material Design ripple effect will be shown when the user taps the widget. Provides tactile feedback.
InkWell Border Radius
The corner radius for the ripple effect when InkWell is enabled. Should typically match your container's border radius for visual consistency.
Building an Expandable Widget
Example 1: Simple FAQ Item
Create a basic FAQ item with a question header and answer content:
Setup:
Add an Expandable widget to your page
Set
Initially ExpandedtofalseEnable
Tap Header to ToggleEnable
Has Iconand set icon placement toRight
Header Slot:
Row
├─ Text: "What is Digia Studio?" (flex: 1)
└─ (Icon handled automatically by Expandable properties)CollapsedView Slot:
SizedBox (height: 0) // Empty collapsed stateExpandedView Slot:
Padding (all: 16)
└─ Text: "Digia Studio is a server-driven UI platform..."
└─ Style: bodyMedium, grey colorProperties Configuration:
Collapsed Icon:
chevron_rightExpanded Icon:
expand_moreIcon Rotation Angle:
90Animation Duration:
300
Example 2: Product Details with Preview
Show product summary when collapsed, full details when expanded:
Setup:
Add Expandable widget
Set
Initially ExpandedtofalseEnable
Tap Header to ToggleandTap Body to Expand
Header Slot:
Row (mainAxisAlignment: spaceBetween)
├─ Column (crossAxisAlignment: start)
│ ├─ Text: "Premium Wireless Headphones"
│ └─ Text: "$299.99" (style: bold, primaryColor)
└─ (Icon managed by widget)CollapsedView Slot:
Padding (left: 16, right: 16, bottom: 8)
└─ Text: "High-quality audio with noise cancellation..."
└─ maxLines: 2
└─ overflow: ellipsis
└─ color: greyExpandedView Slot:
Column
├─ Image (product photo)
├─ Padding
│ └─ Column
│ ├─ Text: "Product Description"
│ ├─ Text: "Full product description here..."
│ ├─ SizedBox (height: 16)
│ ├─ Text: "Features"
│ ├─ Column
│ │ ├─ Row: "• 40-hour battery life"
│ │ ├─ Row: "• Active noise cancellation"
│ │ └─ Row: "• Wireless charging"
│ └─ Button: "Add to Cart"Properties:
Collapsed Icon:
add_circle_outlineExpanded Icon:
remove_circle_outlineIcon Color:
primaryColorUse InkWell Effect:
true
Example 3: Form Section with Conditional Expansion
Advanced settings that expand based on user selection:
Header Slot:
Container (backgroundColor: lightGrey, padding: 12)
└─ Row
├─ Icon: settings
├─ SizedBox (width: 8)
└─ Text: "Advanced Settings"CollapsedView Slot:
Container (padding: 16)
└─ Text: "Click to configure advanced options"
└─ style: italic, greyExpandedView Slot:
Container (padding: 16, backgroundColor: white)
└─ Column
├─ TextFormField (label: "API Timeout")
├─ SizedBox (height: 12)
├─ Row
│ ├─ Text: "Enable Debug Mode"
│ └─ Switch
├─ SizedBox (height: 12)
├─ TextFormField (label: "Log Level")
└─ Button: "Save Settings"Properties:
Initially Expanded:
${appState.isAdvancedUser}Tap Header to Toggle:
trueAnimation Duration:
400
Event Handling
While Expandable doesn't have explicit event handlers like onExpanded, you can respond to state changes in several ways:
1. Binding to Initially Expanded
You can bind the Initially Expanded property to a state variable to dynamically control expansion:
Initially Expanded: ${expandState.isExpanded}Then use this state variable to control the expansion state from other parts of your app or based on conditions.
2. Using Wrapper Events
Add tap handlers by wrapping the Expandable widget:
Widget with onClick
├─ onClick: Set State (track expansion analytics)
└─ ExpandableYou can wrap the Expandable in any widget that supports onClick or other event handlers to track when users interact with it.
Guides
For comprehensive examples and real-world implementations, see:
https://github.com/Digia-Technology-Private-Limited/digiaDocs/blob/main/docs/guides/expandable-accordion-patterns.mdThis guide includes:
FAQ Section - Build interactive question-and-answer interfaces with accordion behavior
Product Details Accordion - Create e-commerce product pages with expandable specifications
Settings Panel - Organize complex settings with nested expandable sections
Advanced patterns including nested expandables, loading states, and state management
Best Practices
Design Guidelines
Visual Consistency:
Use consistent header styling across all expandable widgets in your app
Maintain the same icon style (filled vs outlined) throughout
Keep animation durations uniform for predictable UX
Content Organization:
Place most important information in the header
Use collapsedView for teasers or summaries
Reserve expandedView for detailed content or actions
Accessibility:
Ensure sufficient tap target size for headers (minimum 44x44 points)
Use clear, descriptive header text
Provide adequate color contrast for text and icons
Performance Considerations
Lazy Loading:
For heavy content in expandedView, consider lazy loading images or data
Don't load all expanded content upfront if you have many expandables
Animation Optimization:
Keep animation durations under 500ms for responsive feel
Avoid animating heavy widgets; use lightweight containers
List Performance:
When using multiple Expandables in a ListView, ensure only one is expanded at a time
Use state management to track which item is expanded
Common Patterns
Accordion (One-at-a-Time): Create a system where only one expandable is open at a time:
Store current expanded index in state
When expandable is tapped:
- Close previously expanded item
- Open current item
- Update state with new indexProgressive Disclosure: Use expandables in multi-step forms to reveal sections as users progress:
Step 1 Header: "Personal Information" - Initially Expanded: true
Step 2 Header: "Address Details" - Initially Expanded: false
Step 3 Header: "Payment Information" - Initially Expanded: falseSearch & Expand: Combine search functionality with expandables:
Search results → Each result is an Expandable
- Header shows title and summary
- CollapsedView shows brief preview
- ExpandedView shows full contentDefault Properties
The Expandable widget supports all Default Properties.
Last updated