3
3
// found in the LICENSE file.
4
4
5
5
import 'package:flutter/material.dart' ;
6
- import 'package:google_sign_in_web/google_sign_in_web .dart' ;
6
+ import 'package:google_sign_in_web/web_only .dart' ;
7
7
8
8
/// Type of the onChange function for `ButtonConfiguration` .
9
9
typedef OnWebConfigChangeFn = void Function (GSIButtonConfiguration newConfig);
10
10
11
- /// (Incomplete) List of the locales that can be used to configure the button.
12
- const List <String > availableLocales = < String > [
11
+ /// The type of the widget builder function for each Card in the ListView builder
12
+ typedef CardBuilder = Widget Function (
13
+ GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange);
14
+
15
+ // (Incomplete) List of the locales that can be used to configure the button.
16
+ const List <String > _availableLocales = < String > [
13
17
'en_US' ,
14
18
'es_ES' ,
15
19
'pt_BR' ,
@@ -18,123 +22,146 @@ const List<String> availableLocales = <String>[
18
22
'de_DE' ,
19
23
];
20
24
25
+ // The builder functions for the Cards that let users customize the button.
26
+ final List <CardBuilder > _cards = < CardBuilder > [
27
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
28
+ _renderLocaleCard (
29
+ value: currentConfig? .locale ?? 'en_US' ,
30
+ locales: _availableLocales,
31
+ onChanged: _onChanged <String >(currentConfig, onChange),
32
+ ),
33
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
34
+ _renderMinimumWidthCard (
35
+ value: currentConfig? .minimumWidth,
36
+ max: 500 ,
37
+ actualMax: 400 ,
38
+ onChanged: _onChanged <double >(currentConfig, onChange),
39
+ ),
40
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
41
+ _renderRadioListTileCard <GSIButtonType >(
42
+ title: 'ButtonType' ,
43
+ values: GSIButtonType .values,
44
+ selected: currentConfig? .type ?? GSIButtonType .standard,
45
+ onChanged: _onChanged <GSIButtonType >(currentConfig, onChange),
46
+ ),
47
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
48
+ _renderRadioListTileCard <GSIButtonShape >(
49
+ title: 'ButtonShape' ,
50
+ values: GSIButtonShape .values,
51
+ selected: currentConfig? .shape ?? GSIButtonShape .rectangular,
52
+ onChanged: _onChanged <GSIButtonShape >(currentConfig, onChange),
53
+ ),
54
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
55
+ _renderRadioListTileCard <GSIButtonSize >(
56
+ title: 'ButtonSize' ,
57
+ values: GSIButtonSize .values,
58
+ selected: currentConfig? .size ?? GSIButtonSize .large,
59
+ onChanged: _onChanged <GSIButtonSize >(currentConfig, onChange),
60
+ ),
61
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
62
+ _renderRadioListTileCard <GSIButtonTheme >(
63
+ title: 'ButtonTheme' ,
64
+ values: GSIButtonTheme .values,
65
+ selected: currentConfig? .theme ?? GSIButtonTheme .outline,
66
+ onChanged: _onChanged <GSIButtonTheme >(currentConfig, onChange),
67
+ ),
68
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
69
+ _renderRadioListTileCard <GSIButtonText >(
70
+ title: 'ButtonText' ,
71
+ values: GSIButtonText .values,
72
+ selected: currentConfig? .text ?? GSIButtonText .signinWith,
73
+ onChanged: _onChanged <GSIButtonText >(currentConfig, onChange),
74
+ ),
75
+ (GSIButtonConfiguration ? currentConfig, OnWebConfigChangeFn ? onChange) =>
76
+ _renderRadioListTileCard <GSIButtonLogoAlignment >(
77
+ title: 'ButtonLogoAlignment' ,
78
+ values: GSIButtonLogoAlignment .values,
79
+ selected: currentConfig? .logoAlignment ?? GSIButtonLogoAlignment .left,
80
+ onChanged: _onChanged <GSIButtonLogoAlignment >(currentConfig, onChange),
81
+ ),
82
+ ];
83
+
21
84
/// Renders a Scrollable Column widget that allows the user to see (and change) a ButtonConfiguration.
22
85
Widget renderWebButtonConfiguration (
23
86
GSIButtonConfiguration ? currentConfig, {
24
87
OnWebConfigChangeFn ? onChange,
25
88
}) {
26
89
final ScrollController scrollController = ScrollController ();
27
90
return Scrollbar (
28
- controller: scrollController,
29
- thumbVisibility: true ,
30
- interactive: true ,
31
- child: SingleChildScrollView (
32
- controller: scrollController,
33
- child: Column (
34
- crossAxisAlignment: CrossAxisAlignment .start,
35
- children: < Widget > [
36
- _renderLocaleCard (
37
- value: currentConfig? .locale,
38
- locales: availableLocales,
39
- onChanged: _onChanged <String >(currentConfig, onChange),
40
- ),
41
- _renderMinimumWidthCard (
42
- value: currentConfig? .minimumWidth,
43
- max: 500 ,
44
- actualMax: 400 ,
45
- onChanged: _onChanged <double >(currentConfig, onChange),
46
- ),
47
- _renderRadioListTileCard <GSIButtonType >(
48
- title: 'ButtonType' ,
49
- values: GSIButtonType .values,
50
- selected: currentConfig? .type,
51
- onChanged: _onChanged <GSIButtonType >(currentConfig, onChange),
52
- ),
53
- _renderRadioListTileCard <GSIButtonShape >(
54
- title: 'ButtonShape' ,
55
- values: GSIButtonShape .values,
56
- selected: currentConfig? .shape,
57
- onChanged: _onChanged <GSIButtonShape >(currentConfig, onChange),
58
- ),
59
- _renderRadioListTileCard <GSIButtonSize >(
60
- title: 'ButtonSize' ,
61
- values: GSIButtonSize .values,
62
- selected: currentConfig? .size,
63
- onChanged: _onChanged <GSIButtonSize >(currentConfig, onChange),
64
- ),
65
- _renderRadioListTileCard <GSIButtonTheme >(
66
- title: 'ButtonTheme' ,
67
- values: GSIButtonTheme .values,
68
- selected: currentConfig? .theme,
69
- onChanged: _onChanged <GSIButtonTheme >(currentConfig, onChange),
70
- ),
71
- _renderRadioListTileCard <GSIButtonText >(
72
- title: 'ButtonText' ,
73
- values: GSIButtonText .values,
74
- selected: currentConfig? .text,
75
- onChanged: _onChanged <GSIButtonText >(currentConfig, onChange),
76
- ),
77
- _renderRadioListTileCard <GSIButtonLogoAlignment >(
78
- title: 'ButtonLogoAlignment' ,
79
- values: GSIButtonLogoAlignment .values,
80
- selected: currentConfig? .logoAlignment,
81
- onChanged:
82
- _onChanged <GSIButtonLogoAlignment >(currentConfig, onChange),
83
- ),
84
- ],
85
- )));
91
+ controller: scrollController,
92
+ thumbVisibility: true ,
93
+ interactive: true ,
94
+ child: ConstrainedBox (
95
+ constraints: const BoxConstraints (maxWidth: 250 ),
96
+ child: ListView .builder (
97
+ controller: scrollController,
98
+ itemCount: _cards.length,
99
+ itemBuilder: (BuildContext _, int index) =>
100
+ _cards[index](currentConfig, onChange),
101
+ ),
102
+ ),
103
+ );
86
104
}
87
105
88
106
/// Renders a Config card with a dropdown of locales.
89
- Widget _renderLocaleCard (
90
- {String ? value,
91
- required List <String > locales,
92
- void Function (String ? )? onChanged}) {
93
- return _renderConfigCard (title: 'locale' , children: < Widget > [
94
- Padding (
95
- padding: const EdgeInsets .symmetric (horizontal: 16 ),
96
- child: DropdownButton <String >(
97
- items: locales
98
- .map ((String locale) => DropdownMenuItem <String >(
99
- value: locale,
100
- child: Text (locale),
101
- ))
102
- .toList (),
103
- value: value,
104
- onChanged: onChanged,
105
- isExpanded: true ,
106
- // padding: const EdgeInsets.symmetric(horizontal: 16), // Prefer padding here!
107
+ Widget _renderLocaleCard ({
108
+ String ? value,
109
+ required List <String > locales,
110
+ void Function (String ? )? onChanged,
111
+ }) {
112
+ return _renderConfigCard (
113
+ title: 'locale' ,
114
+ children: < Widget > [
115
+ Padding (
116
+ padding: const EdgeInsets .symmetric (horizontal: 16 ),
117
+ child: DropdownButton <String >(
118
+ items: locales
119
+ .map ((String locale) => DropdownMenuItem <String >(
120
+ value: locale,
121
+ child: Text (locale),
122
+ ))
123
+ .toList (),
124
+ value: value,
125
+ onChanged: onChanged,
126
+ isExpanded: true ,
127
+ // padding: const EdgeInsets.symmetric(horizontal: 16), // Prefer padding here!
128
+ ),
107
129
),
108
- ) ,
109
- ] );
130
+ ] ,
131
+ );
110
132
}
111
133
112
134
/// Renders a card with a slider
113
- Widget _renderMinimumWidthCard (
114
- {double ? value,
115
- double min = 0 ,
116
- double actualMax = 10 ,
117
- double max = 11 ,
118
- void Function (double )? onChanged}) {
119
- return _renderConfigCard (title: 'minimumWidth' , children: < Widget > [
120
- Slider (
121
- label: value? .toString () ?? 'null' ,
122
- value: value ?? 0 ,
123
- min: min,
124
- max: max,
125
- secondaryTrackValue: actualMax,
126
- onChanged: onChanged,
127
- divisions: 10 ,
128
- )
129
- ]);
135
+ Widget _renderMinimumWidthCard ({
136
+ double ? value,
137
+ double min = 0 ,
138
+ double actualMax = 10 ,
139
+ double max = 11 ,
140
+ void Function (double )? onChanged,
141
+ }) {
142
+ return _renderConfigCard (
143
+ title: 'minimumWidth' ,
144
+ children: < Widget > [
145
+ Slider (
146
+ label: value? .toString () ?? 'null' ,
147
+ value: value ?? 0 ,
148
+ min: min,
149
+ max: max,
150
+ secondaryTrackValue: actualMax,
151
+ onChanged: onChanged,
152
+ divisions: 10 ,
153
+ )
154
+ ],
155
+ );
130
156
}
131
157
132
158
/// Renders a Config Card with the values of an Enum as radio buttons.
133
- Widget _renderRadioListTileCard <T extends Enum >(
134
- {required String title,
135
- required List <T > values,
136
- T ? selected,
137
- void Function (T ? )? onChanged}) {
159
+ Widget _renderRadioListTileCard <T extends Enum >({
160
+ required String title,
161
+ required List <T > values,
162
+ T ? selected,
163
+ void Function (T ? )? onChanged,
164
+ }) {
138
165
return _renderConfigCard (
139
166
title: title,
140
167
children: values
@@ -150,29 +177,32 @@ Widget _renderRadioListTileCard<T extends Enum>(
150
177
}
151
178
152
179
/// Renders a Card where we render some `children` that change config.
153
- Widget _renderConfigCard (
154
- {required String title, required List <Widget > children}) {
155
- return Container (
156
- constraints: const BoxConstraints (maxWidth: 200 ),
157
- child: Card (
158
- child: Column (
159
- mainAxisSize: MainAxisSize .min,
160
- children: < Widget > [
161
- ListTile (
162
- title: Text (
163
- title,
164
- style: const TextStyle (fontWeight: FontWeight .bold),
165
- ),
166
- dense: true ,
180
+ Widget _renderConfigCard ({
181
+ required String title,
182
+ required List <Widget > children,
183
+ }) {
184
+ return Card (
185
+ child: Column (
186
+ mainAxisSize: MainAxisSize .min,
187
+ children: < Widget > [
188
+ ListTile (
189
+ title: Text (
190
+ title,
191
+ style: const TextStyle (fontWeight: FontWeight .bold),
167
192
),
168
- ...children,
169
- ],
170
- )));
193
+ dense: true ,
194
+ ),
195
+ ...children,
196
+ ],
197
+ ),
198
+ );
171
199
}
172
200
173
201
/// Sets a `value` into an `old` configuration object.
174
- GSIButtonConfiguration _copyConfigWith (
175
- GSIButtonConfiguration ? old, Object ? value) {
202
+ GSIButtonConfiguration _copyConfigWith <T >(
203
+ GSIButtonConfiguration ? old,
204
+ T ? value,
205
+ ) {
176
206
return GSIButtonConfiguration (
177
207
locale: value is String ? value : old? .locale,
178
208
minimumWidth:
@@ -188,11 +218,13 @@ GSIButtonConfiguration _copyConfigWith(
188
218
189
219
/// Returns a function that modifies the `current` configuration with a `value` , then calls `fn` with it.
190
220
void Function (T ? )? _onChanged <T >(
191
- GSIButtonConfiguration ? current, OnWebConfigChangeFn ? fn) {
221
+ GSIButtonConfiguration ? current,
222
+ OnWebConfigChangeFn ? fn,
223
+ ) {
192
224
if (fn == null ) {
193
225
return null ;
194
226
}
195
227
return (T ? value) {
196
- fn (_copyConfigWith (current, value));
228
+ fn (_copyConfigWith < T > (current, value));
197
229
};
198
230
}
0 commit comments