From 0b0b50f2a8d87f61535aa0b91eb6bc83e96b7952 Mon Sep 17 00:00:00 2001 From: Ben Corman Date: Thu, 3 Oct 2024 14:24:55 -0700 Subject: [PATCH] Add documentation to README and minor code cleanup --- README.md | 36 +++++++++++++++++++++++-- example/lib/sign_in.dart | 20 +++++++------- lib/src/components/supa_email_auth.dart | 18 ++++++++----- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index b589ccc..6772c15 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ SupaEmailAuth( // do something, for example: navigate("wait_for_email"); }, metadataFields: [ + // Creates an additional TextField for string metadata, for example: + // {'username': 'exampleUsername'} MetaDataField( prefixIcon: const Icon(Icons.person), label: 'Username', @@ -38,8 +40,38 @@ SupaEmailAuth( return null; }, ), - ], -), + + // Creates a CheckboxListTile for boolean metadata, for example: + // {'marketing_consent': true} + BooleanMetaDataField( + label: 'I wish to receive marketing emails', + key: 'marketing_consent', + checkboxPosition: ListTileControlAffinity.leading, + ), + // Supports interactive text. Fields can be marked as required, blocking form + // submission unless the checkbox is checked. + BooleanMetaDataField( + key: 'terms_agreement', + isRequired: true, + checkboxPosition: ListTileControlAffinity.leading, + richLabelSpans: [ + const TextSpan( + text: 'I have read and agree to the '), + TextSpan( + text: 'Terms and Conditions', + style: const TextStyle( + color: Colors.blue, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + // do something, for example: navigate("terms_and_conditions"); + }, + ), + // Or use some other custom widget. + WidgetSpan() + ], + ), + ]), ``` ## Magic Link Auth diff --git a/example/lib/sign_in.dart b/example/lib/sign_in.dart index f4bcafd..6492132 100644 --- a/example/lib/sign_in.dart +++ b/example/lib/sign_in.dart @@ -65,16 +65,14 @@ class SignUp extends StatelessWidget { return null; }, ), - // Checkbox on the right BooleanMetaDataField( - label: 'I agree to a checkbox on the right', - key: 'right_checkbox', + label: 'Keep me up to date with the latest news and updates.', + key: 'marketing_consent', + checkboxPosition: ListTileControlAffinity.leading, ), - - // Checkbox on the left BooleanMetaDataField( key: 'terms_agreement', - required: true, + isRequired: true, checkboxPosition: ListTileControlAffinity.leading, richLabelSpans: [ const TextSpan(text: 'I have read and agree to the '), @@ -85,8 +83,7 @@ class SignUp extends StatelessWidget { ), recognizer: TapGestureRecognizer() ..onTap = () { - //ignore: avoid_print - print('Terms and Conditions'); + // Handle tap on Terms and Conditions }, ), ], @@ -130,19 +127,20 @@ class SignUp extends StatelessWidget { }, ), BooleanMetaDataField( - label: 'I wish to receive marketing emails', + label: + 'Keep me up to date with the latest news and updates.', key: 'marketing_consent', checkboxPosition: ListTileControlAffinity.leading, ), BooleanMetaDataField( key: 'terms_agreement', - required: true, + isRequired: true, checkboxPosition: ListTileControlAffinity.leading, richLabelSpans: [ const TextSpan( text: 'I have read and agree to the '), TextSpan( - text: 'Terms and Conditions', + text: 'Terms and Conditions.', style: const TextStyle( color: Colors.blue, ), diff --git a/lib/src/components/supa_email_auth.dart b/lib/src/components/supa_email_auth.dart index 98b41f7..11f782f 100644 --- a/lib/src/components/supa_email_auth.dart +++ b/lib/src/components/supa_email_auth.dart @@ -102,7 +102,7 @@ class BooleanMetaDataField extends MetaDataField { /// Whether the field is required. /// /// If true, the user must check the checkbox in order for the form to submit. - final bool required; + final bool isRequired; /// Semantic label for the checkbox. final String? checkboxSemanticLabel; @@ -112,7 +112,7 @@ class BooleanMetaDataField extends MetaDataField { String? label, this.richLabelSpans, this.checkboxSemanticLabel, - this.required = false, + this.isRequired = false, this.checkboxPosition = ListTileControlAffinity.platform, required super.key, }) : assert(label != null || richLabelSpans != null, @@ -120,9 +120,9 @@ class BooleanMetaDataField extends MetaDataField { super(label: label ?? ''); Widget getLabelWidget(BuildContext context) { - // It's important that this matches the default style of [TextField], which - // is used for the other fields in the form. TextField's default style - // uses bodyLarge for Material 3, or otherwise titleMedium. + // This matches the default style of [TextField], to match the other fields + // in the form. TextField's default style uses `bodyLarge` for Material 3, + // or otherwise `titleMedium`. final defaultStyle = Theme.of(context).useMaterial3 ? Theme.of(context).textTheme.bodyLarge : Theme.of(context).textTheme.titleMedium; @@ -333,10 +333,11 @@ class _SupaEmailAuthState extends State { ...widget.metadataFields! .map((metadataField) => [ // Render a Checkbox that displays an error message - // beneath it if the field is required and the user hasn't checked it when submitting. + // beneath it if the field is required and the user + // hasn't checked it when submitting the form. if (metadataField is BooleanMetaDataField) FormField( - validator: metadataField.required + validator: metadataField.isRequired ? (bool? value) { if (value != true) { return localization.requiredFieldError; @@ -368,6 +369,9 @@ class _SupaEmailAuthState extends State { metadataField.checkboxSemanticLabel, controlAffinity: metadataField.checkboxPosition, + contentPadding: + const EdgeInsets.symmetric( + horizontal: 4.0), activeColor: theme.colorScheme.primary, checkColor: theme.colorScheme.onPrimary, tileColor: isDark