mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
121 lines
3.9 KiB
Dart
121 lines
3.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:syncrow_web/utils/color_manager.dart';
|
|
|
|
class CustomExpansionTile extends StatefulWidget {
|
|
final String title;
|
|
final List<Widget>? children;
|
|
final bool initiallyExpanded;
|
|
final bool? isExpanded; // External control over expansion
|
|
final ValueChanged<bool>? onExpansionChanged; // Notify when expansion changes
|
|
|
|
CustomExpansionTile({
|
|
required this.title,
|
|
this.children,
|
|
this.initiallyExpanded = false,
|
|
this.isExpanded, // Allow external control over expansion
|
|
this.onExpansionChanged, // Notify when expansion changes
|
|
});
|
|
|
|
@override
|
|
CustomExpansionTileState createState() => CustomExpansionTileState();
|
|
}
|
|
|
|
class CustomExpansionTileState extends State<CustomExpansionTile> {
|
|
bool _isExpanded = false; // Local expansion state
|
|
bool _isChecked = false; // Local checkbox state
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_isExpanded = widget.initiallyExpanded;
|
|
}
|
|
|
|
@override
|
|
void didUpdateWidget(CustomExpansionTile oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
// Sync local state with external control of expansion state
|
|
if (widget.isExpanded != null && widget.isExpanded != _isExpanded) {
|
|
setState(() {
|
|
_isExpanded = widget.isExpanded!;
|
|
});
|
|
}
|
|
}
|
|
|
|
// Utility function to capitalize the first letter of the title
|
|
String _capitalizeFirstLetter(String text) {
|
|
if (text.isEmpty) return text;
|
|
return text[0].toUpperCase() + text.substring(1);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
// The main clickable row for the expansion tile
|
|
InkWell(
|
|
onTap: () {
|
|
setState(() {
|
|
_isExpanded = !_isExpanded;
|
|
widget.onExpansionChanged?.call(_isExpanded);
|
|
});
|
|
},
|
|
child: Row(
|
|
children: [
|
|
// Checkbox with independent state management
|
|
Checkbox(
|
|
value: _isChecked,
|
|
onChanged: (bool? value) {
|
|
setState(() {
|
|
_isChecked = value ?? false;
|
|
});
|
|
},
|
|
side: MaterialStateBorderSide.resolveWith((states) {
|
|
return const BorderSide(color: ColorsManager.grayBorder);
|
|
}),
|
|
fillColor: MaterialStateProperty.resolveWith((states) {
|
|
if (states.contains(MaterialState.selected)) {
|
|
return ColorsManager.grayBorder;
|
|
} else {
|
|
return ColorsManager.checkBoxFillColor;
|
|
}
|
|
}),
|
|
checkColor: ColorsManager.whiteColors,
|
|
),
|
|
// Show the expand/collapse icon
|
|
if (widget.children != null && widget.children!.isNotEmpty)
|
|
Icon(
|
|
_isExpanded
|
|
? Icons.keyboard_arrow_down
|
|
: Icons.keyboard_arrow_right,
|
|
color: Colors.grey,
|
|
size: 16.0, // Adjusted size for better alignment
|
|
),
|
|
// The title text with dynamic styling
|
|
Expanded(
|
|
child: Text(
|
|
_capitalizeFirstLetter(widget.title),
|
|
style: TextStyle(
|
|
color:ColorsManager.lightGrayColor,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// The expanded section (children) that shows when the tile is expanded
|
|
if (_isExpanded &&
|
|
widget.children != null &&
|
|
widget.children!.isNotEmpty)
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 48.0), // Indented children
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: widget.children!,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|