Skip to content

Commit 785387f

Browse files
authored
feat: Add BooleanMetaDataField to support checkbox inputs on sign-up form (#115)
* Add BooleanMetaDataField for checkbox inputs in SupaEmailAuth This commit introduces a new BooleanMetaDataField class to support checkbox inputs in the SupaEmailAuth component. This enhancement allows for more versatile form creation, particularly useful for consent checkboxes or boolean preferences. Key changes: 1. New BooleanMetaDataField class: - Extends MetaDataField to maintain compatibility - Supports both simple text labels and rich text labels with interactive elements (allowing links to be inserted within the text) - Supports semantic labeling for accessability - Allows customization of checkbox position (leading or trailing) - Includes a 'required' option for mandatory fields 2. Updates to SupaEmailAuth: - Modified to handle both MetaDataField and BooleanMetaDataField - Implemented rendering logic for checkbox fields - Added support for rich text labels in checkboxes - Implemented validation for required checkbox fields 3. Styling improvements: - Ensured checkbox styling matches other form elements - Added support for dark mode theming - Implemented error message display for invalid checkbox fields - Error message added to localization class 4. Documentation: - Added comprehensive documentation for BooleanMetaDataField - Updated existing documentation to reflect new capabilities 5. Example updates: - Modified example code to demonstrate usage of BooleanMetaDataField - Included examples of both simple and rich text labels 6. Backward compatibility: - Maintained support for existing MetaDataField usage - No breaking changes to public API This enhancement provides developers with more flexibility in creating sign-up forms, particularly for scenarios requiring user consent or boolean preferences, while maintaining the existing functionality of the SupaEmailAuth component. * Add documentation to README and minor code cleanup
1 parent a5c75b8 commit 785387f

File tree

4 files changed

+332
-44
lines changed

4 files changed

+332
-44
lines changed

README.md

+34-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ SupaEmailAuth(
2727
// do something, for example: navigate("wait_for_email");
2828
},
2929
metadataFields: [
30+
// Creates an additional TextField for string metadata, for example:
31+
// {'username': 'exampleUsername'}
3032
MetaDataField(
3133
prefixIcon: const Icon(Icons.person),
3234
label: 'Username',
@@ -38,8 +40,38 @@ SupaEmailAuth(
3840
return null;
3941
},
4042
),
41-
],
42-
),
43+
44+
// Creates a CheckboxListTile for boolean metadata, for example:
45+
// {'marketing_consent': true}
46+
BooleanMetaDataField(
47+
label: 'I wish to receive marketing emails',
48+
key: 'marketing_consent',
49+
checkboxPosition: ListTileControlAffinity.leading,
50+
),
51+
// Supports interactive text. Fields can be marked as required, blocking form
52+
// submission unless the checkbox is checked.
53+
BooleanMetaDataField(
54+
key: 'terms_agreement',
55+
isRequired: true,
56+
checkboxPosition: ListTileControlAffinity.leading,
57+
richLabelSpans: [
58+
const TextSpan(
59+
text: 'I have read and agree to the '),
60+
TextSpan(
61+
text: 'Terms and Conditions',
62+
style: const TextStyle(
63+
color: Colors.blue,
64+
),
65+
recognizer: TapGestureRecognizer()
66+
..onTap = () {
67+
// do something, for example: navigate("terms_and_conditions");
68+
},
69+
),
70+
// Or use some other custom widget.
71+
WidgetSpan()
72+
],
73+
),
74+
]),
4375
```
4476

4577
## Magic Link Auth

example/lib/sign_in.dart

+80-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:flutter/foundation.dart';
2+
import 'package:flutter/gestures.dart';
23
import 'package:flutter/material.dart';
34
import 'package:supabase_auth_ui/supabase_auth_ui.dart';
45

@@ -26,12 +27,16 @@ class SignUp extends StatelessWidget {
2627
borderRadius: BorderRadius.circular(8),
2728
borderSide: BorderSide.none,
2829
),
29-
labelStyle: const TextStyle(color: Color.fromARGB(179, 255, 255, 255)), // text labeling text entry
30+
labelStyle: const TextStyle(
31+
color:
32+
Color.fromARGB(179, 255, 255, 255)), // text labeling text entry
3033
),
3134
elevatedButtonTheme: ElevatedButtonThemeData(
3235
style: ElevatedButton.styleFrom(
33-
backgroundColor: const Color.fromARGB(255, 22, 135, 188), // main button
34-
foregroundColor: const Color.fromARGB(255, 255, 255, 255), // main button text
36+
backgroundColor:
37+
const Color.fromARGB(255, 22, 135, 188), // main button
38+
foregroundColor:
39+
const Color.fromARGB(255, 255, 255, 255), // main button text
3540
shape: RoundedRectangleBorder(
3641
borderRadius: BorderRadius.circular(8),
3742
),
@@ -60,6 +65,29 @@ class SignUp extends StatelessWidget {
6065
return null;
6166
},
6267
),
68+
BooleanMetaDataField(
69+
label: 'Keep me up to date with the latest news and updates.',
70+
key: 'marketing_consent',
71+
checkboxPosition: ListTileControlAffinity.leading,
72+
),
73+
BooleanMetaDataField(
74+
key: 'terms_agreement',
75+
isRequired: true,
76+
checkboxPosition: ListTileControlAffinity.leading,
77+
richLabelSpans: [
78+
const TextSpan(text: 'I have read and agree to the '),
79+
TextSpan(
80+
text: 'Terms and Conditions',
81+
style: const TextStyle(
82+
color: Colors.blue,
83+
),
84+
recognizer: TapGestureRecognizer()
85+
..onTap = () {
86+
// Handle tap on Terms and Conditions
87+
},
88+
),
89+
],
90+
),
6391
],
6492
),
6593

@@ -76,17 +104,55 @@ class SignUp extends StatelessWidget {
76104
child: Theme(
77105
data: darkModeThemeData,
78106
child: SupaEmailAuth(
79-
redirectTo: kIsWeb ? null : 'io.supabase.flutter://',
80-
onSignInComplete: navigateHome,
81-
onSignUpComplete: navigateHome,
82-
prefixIconEmail: null,
83-
prefixIconPassword: null,
84-
localization: const SupaEmailAuthLocalization(
85-
enterEmail: "email",
86-
enterPassword: "password",
87-
dontHaveAccount: "sign up",
88-
forgotPassword: "forgot password"),
89-
),
107+
redirectTo: kIsWeb ? null : 'io.supabase.flutter://',
108+
onSignInComplete: navigateHome,
109+
onSignUpComplete: navigateHome,
110+
prefixIconEmail: null,
111+
prefixIconPassword: null,
112+
localization: const SupaEmailAuthLocalization(
113+
enterEmail: "email",
114+
enterPassword: "password",
115+
dontHaveAccount: "sign up",
116+
forgotPassword: "forgot password"),
117+
metadataFields: [
118+
MetaDataField(
119+
prefixIcon: const Icon(Icons.person),
120+
label: 'Username',
121+
key: 'username',
122+
validator: (val) {
123+
if (val == null || val.isEmpty) {
124+
return 'Please enter something';
125+
}
126+
return null;
127+
},
128+
),
129+
BooleanMetaDataField(
130+
label:
131+
'Keep me up to date with the latest news and updates.',
132+
key: 'marketing_consent',
133+
checkboxPosition: ListTileControlAffinity.leading,
134+
),
135+
BooleanMetaDataField(
136+
key: 'terms_agreement',
137+
isRequired: true,
138+
checkboxPosition: ListTileControlAffinity.leading,
139+
richLabelSpans: [
140+
const TextSpan(
141+
text: 'I have read and agree to the '),
142+
TextSpan(
143+
text: 'Terms and Conditions.',
144+
style: const TextStyle(
145+
color: Colors.blue,
146+
),
147+
recognizer: TapGestureRecognizer()
148+
..onTap = () {
149+
//ignore: avoid_print
150+
print('Terms and Conditions');
151+
},
152+
),
153+
],
154+
),
155+
]),
90156
),
91157
)),
92158

0 commit comments

Comments
 (0)