dev
dart 113 lines 3.88 KB
Raw
1 import 'package:flutter/material.dart';
2
3 class ExpandableBridgeDetailRow extends StatefulWidget {
4 const ExpandableBridgeDetailRow({
5 required this.label,
6 required this.title,
7 this.address,
8 this.showChevron = false,
9 });
10
11 final String label;
12 final String title;
13 final String? address;
14 final bool showChevron;
15
16 @override
17 State<ExpandableBridgeDetailRow> createState() => ExpandableBridgeDetailRowState();
18 }
19
20 class ExpandableBridgeDetailRowState extends State<ExpandableBridgeDetailRow> {
21 bool _expanded = false;
22
23 @override
24 Widget build(BuildContext context) {
25 final scheme = Theme.of(context).colorScheme;
26 final showChevron = widget.showChevron;
27
28 return Column(
29 crossAxisAlignment: CrossAxisAlignment.stretch,
30 children: [
31 InkWell(
32 onTap: showChevron ? () => setState(() => _expanded = !_expanded) : null,
33 child: Padding(
34 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
35 child: Row(
36 crossAxisAlignment: CrossAxisAlignment.start,
37 children: [
38 Text(
39 widget.label,
40 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
41 color: scheme.onSurface,
42 fontWeight: FontWeight.w400,
43 fontSize: 14,
44 letterSpacing: -0.07,
45 ),
46 ),
47 const SizedBox(width: 12),
48 Expanded(
49 child: Row(
50 mainAxisAlignment: MainAxisAlignment.end,
51 crossAxisAlignment: CrossAxisAlignment.start,
52 children: [
53 Flexible(
54 child: Text(
55 widget.title,
56 textAlign: TextAlign.end,
57 maxLines: 2,
58 overflow: TextOverflow.ellipsis,
59 style: Theme.of(context).textTheme.bodyMedium?.copyWith(
60 fontWeight: FontWeight.w400,
61 fontSize: 14,
62 letterSpacing: -0.07,
63 color: scheme.onSurfaceVariant,
64 ),
65 ),
66 ),
67 if (showChevron) ...[
68 const SizedBox(width: 2),
69 AnimatedRotation(
70 turns: _expanded ? 0.5 : 0,
71 duration: const Duration(milliseconds: 200),
72 curve: Curves.easeOutCubic,
73 child: Icon(
74 Icons.keyboard_arrow_down,
75 size: 22,
76 color: scheme.onSurfaceVariant,
77 ),
78 ),
79 ],
80 ],
81 ),
82 ),
83 ],
84 ),
85 ),
86 ),
87 AnimatedSize(
88 duration: const Duration(milliseconds: 200),
89 curve: Curves.easeOutCubic,
90 alignment: Alignment.topCenter,
91 child: showChevron && _expanded
92 ? Padding(
93 padding: const EdgeInsets.fromLTRB(16, 0, 16, 14),
94 child: Align(
95 alignment: Alignment.centerRight,
96 child: SelectableText(
97 widget.address ?? '',
98 textAlign: TextAlign.end,
99 style: TextStyle(
100 fontSize: 13,
101 height: 1.35,
102 color: scheme.onSurfaceVariant,
103 fontWeight: FontWeight.w400,
104 ),
105 ),
106 ),
107 )
108 : const SizedBox.shrink(),
109 ),
110 ],
111 );
112 }
113 }