Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions package/lib/src/controls/create_control.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import 'animated_switcher.dart';
import 'bottom_app_bar.dart';
import 'audio.dart';
import 'badge.dart';
import 'expansion_panel.dart';
import 'selection_area.dart';
import 'banner.dart';
import 'barchart.dart';
Expand Down Expand Up @@ -325,6 +326,15 @@ Widget createWidget(Key? key, ControlViewModel controlView, Control? parent,
children: controlView.children,
parentDisabled: parentDisabled,
dispatch: controlView.dispatch);
case "expansionpanellist":
return ExpansionPanelListControl(
key: key,
parent: parent,
control: controlView.control,
children: controlView.children,
parentDisabled: parentDisabled,
dispatch: controlView.dispatch
);
case "stack":
return StackControl(
key: key,
Expand Down
124 changes: 124 additions & 0 deletions package/lib/src/controls/expansion_panel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';

import '../actions.dart';
import '../flet_app_services.dart';
import '../models/app_state.dart';
import '../models/control.dart';
import '../models/controls_view_model.dart';
import '../protocol/update_control_props_payload.dart';
import '../utils/colors.dart';
import '../utils/edge_insets.dart';
import 'create_control.dart';

class ExpansionPanelListControl extends StatefulWidget {
final Control? parent;
final Control control;
final List<Control> children;
final bool parentDisabled;
final dynamic dispatch;

const ExpansionPanelListControl(
{super.key,
this.parent,
required this.control,
required this.children,
required this.parentDisabled,
required this.dispatch});

@override
State<ExpansionPanelListControl> createState() =>
_ExpansionPanelListControlState();
}

class _ExpansionPanelListControlState extends State<ExpansionPanelListControl> {
@override
Widget build(BuildContext context) {
debugPrint("ExpansionPanelList build: ${widget.control.id}");

var panels = widget.children
.where((c) => c.name == "expansionpanel" && c.isVisible)
.toList();

void onChange(int index, bool isExpanded) {
List<Map<String, String>> props = [
{
"i": panels[index].id,
"expanded": isExpanded.toString().toLowerCase()
}
];
widget.dispatch(
UpdateControlPropsAction(UpdateControlPropsPayload(props: props)));
var server = FletAppServices.of(context).server;
server.updateControlProps(props: props);
server.sendPageEvent(
eventTarget: widget.control.id,
eventName: "change",
eventData: "$index");
}

bool disabled = widget.control.isDisabled || widget.parentDisabled;

var dividerColor = HexColor.fromString(
Theme.of(context), widget.control.attrString("dividerColor", "")!);
var expandedIconColor = HexColor.fromString(
Theme.of(context), widget.control.attrString("expandedIconColor", "")!);

var expandedHeaderPadding =
parseEdgeInsets(widget.control, "expandedHeaderPadding");

debugPrint(
"ExpansionPanelListControl StoreConnector build: ${widget.control.id}");

var panelList = StoreConnector<AppState, ControlsViewModel>(
distinct: true,
converter: (store) =>
ControlsViewModel.fromStore(store, panels.map((p) => p.id)),
builder: (content, panelViews) {
return ExpansionPanelList(
elevation: widget.control.attrDouble("elevation", 2)!,
materialGapSize: widget.control.attrDouble("spacing", 16)!,
dividerColor: dividerColor,
expandIconColor: expandedIconColor,
expandedHeaderPadding: expandedHeaderPadding ??
const EdgeInsets.symmetric(vertical: 16),
expansionCallback: !disabled
? (int index, bool isExpanded) {
onChange(index, isExpanded);
}
: null,
children: panelViews.controlViews.map((panelView) {
var headerCtrls = panelView.children
.where((c) => c.name == "header" && c.isVisible);
var bodyCtrls = panelView.children
.where((c) => c.name == "content" && c.isVisible);

var isExpanded =
panelView.control.attrBool("expanded", false)!;
var canTapHeader =
panelView.control.attrBool("canTapHeader", false)!;
var bgColor = HexColor.fromString(Theme.of(context),
panelView.control.attrString("bgColor", "")!);

return ExpansionPanel(
backgroundColor: bgColor,
isExpanded: isExpanded,
canTapOnHeader: canTapHeader,
headerBuilder: (BuildContext context, bool isExpanded) {
return headerCtrls.isNotEmpty
? createControl(
widget.control, headerCtrls.first.id, disabled)
: const ListTile(title: Text("Header Placeholder"));
},
body: bodyCtrls.isNotEmpty
? createControl(
widget.control, bodyCtrls.first.id, disabled)
: const ListTile(title: Text("Body Placeholder")),
);
}).toList());
});

return constrainedControl(
context, panelList, widget.parent, widget.control);
}
}
1 change: 1 addition & 0 deletions sdk/python/packages/flet-core/src/flet_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
from flet_core.draggable import Draggable
from flet_core.dropdown import Dropdown
from flet_core.elevated_button import ElevatedButton
from flet_core.expansion_panel import ExpansionPanel, ExpansionPanelList
from flet_core.expansion_tile import ExpansionTile, TileAffinity
from flet_core.file_picker import (
FilePicker,
Expand Down
Loading