supabase-community / flutter-auth-ui

Supabase Auth UI library for Flutter
https://supabase.com
MIT License
114 stars 58 forks source link

feat: Add BooleanMetaDataField to support checkbox inputs on sign-up form #115

Closed bcorman closed 1 month ago

bcorman commented 1 month ago

What kind of change does this PR introduce?

This commit adds a new BooleanMetaDataField class to support checkbox inputs in the SupaEmailAuth component for boolean metadata. This enhancement allows for more versatile form creation, particularly useful for consent checkboxes or boolean preferences.

Resolves #96

Key changes:

  1. New BooleanMetaDataField class:

    • Extends MetaDataField to maintain compatibility
    • Supports both simple text labels and rich text labels with interactive elements
    • Supports semantic labeling for accessibility
    • 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:

    • Ensured checkbox styling matches other form elements in both light and dark mode
    • 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.

Additional context

There's quite a lot here, so while I've supplied screenshots, I recommend viewing the change in the example app to get a sense of its behavior. Don't hesitate to push back or question any decisions I made.

There are two specific issues that I would like feedback on before this PR gets approved, since any future changes to BooleanMetaDataField could be breaking:

  1. I'm a bit ambivalent on how interactive text is passed in. At first I had a richLabel property that took a single RichText widget, but that won't match the styling of the other components on the form unless users of this library match it themselves. It felt too customizable, when all that the class really needs is a list of text widgets so it can arrange them like: "".

So I modified it to instead take a List<InlineSpan>, and keep the RichText widget internal and give it a default style that matches the other fields in the form. If needed, the style can be overridden in the widgets that are passed in (for example, making a link blue).

  1. Accessibility support: I wanted this to work out of the box with screen readers, which it mostly does. I built the example app in Windows and used the Windows screen reader tool. The BooleanMetaDataField will focus like any other field in the form, and when selected, the label or semanticsLabel will be read aloud appropriately.

The only issue I had was getting the screen reader to select and read aloud any links or interactive text within the richLabelSpan. The ideal (and expected) behavior would be:

  1. [Focus on "I agree to the terms and conditions" and read semantic label]
  2. Press tab to focus on next focusNode
  3. [Focus on "terms and conditions" and read semantic label, like "Link to terms and conditions"]
  4. Press tab to activate link

I wanted this to work out of the box, but it was a bit more difficult than I anticipated. Only step one works. Pressing tab again will focus on the next form component or the submit button.

I eventually got the subtext focusable, but I was never able to get the screen reader to read it aloud. The further I got into making that work, the more complex this change got, and after a certain point it just seemed out of scope. I have a lengthy change stashed on my fork that almost works, but for now I think users of this library will have to handle accessibility themselves for whatever widgets are passed in to richLabelSpan. If I figure out a clean and easily-maintainable way to handle it, I'll submit another PR.

Screenshots

Desktop: Screenshot 2024-10-03 143305 Screenshot 2024-10-03 143313 Screenshot 2024-10-03 143326 Screenshot 2024-10-03 143336

Mobile: Screenshot_1727990090 Screenshot_1727990121 Screenshot_1727990129