Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New form builder #204

Merged
merged 30 commits into from
Apr 1, 2021
Merged

New form builder #204

merged 30 commits into from
Apr 1, 2021

Conversation

hartsick
Copy link
Contributor

@hartsick hartsick commented Sep 2, 2020

Molly, Symonne, and I created a new FormBuilder on CMR because we found the previous Honeycrisp version difficult to work with, especially when styling differently than GCF (CMR was using in a new 'compact form' context).

In creating this, CMR looked into existing Form Builders (Rails, Formtastic, GCF, Honeycrisp V1) to chart our course. The rough notes from that research are here. We also looked to past conversations about the future fo the Honeycrisp FormBuilder, which can be found here. here, and here.

For this reason, we decided to undertake building a new FormBuilder for Honeycrisp. Here are some goals we articulated for it:

  • Flexible Styling: ability to pass classes to a method and have them applied to the html components
  • Consistent interface: all methods take similar arguments in the same order to the extent possible, to aid in usability and understandability
  • Extensibility: provide building blocks that are discrete enough to be used in many different contexts, but comprehensive enough to make generating "good" forms "fool-proof"
  • Accessibility: Generate best-practice accessible HTML
  • Test coverage: Test in a way that makes it easy to understand what the intention behind the HTML output is, instead of just testing the full HTML presented

Additionally, after talking with Ben S, I added the following goal:

  • Adhering as closely to the method options and signatures in the Rails FormBuilder as possible, to aid in extensibility and understandability (we wouldn't be charting our own path)

Current roadmap / TODOs:

  • Finish cfa_radiogroup
  • Implement cfa_radio
  • Implement cfa_button
  • Make sure 'required' input is consistent / how we want across our methods
  • Figure out how we want to support "required" and "errors" for fieldset vs individual radio buttons
  • Remove style hooks
  • Implement cfa_check_box [Currently a WIP - need to get to pass accessibility checks and make sure it works as we intend to use it (with a collection of values, potentially in a fieldset), including with errors]
  • Implement cfa_collection_check_boxes
  • Implement cfa_collection_radio_buttons
  • Review HTML of all inputs and make sure we are happy with it

Before merging to trunk:

  • Change cfa_text_input -> cfa_text_field
  • Fix tests
  • Proof of concept that current HTML structure supports needed styling, then making any updates needed to HTML [Ben is working on a spike on this New form builder style #256]
  • Make sure visual diffs for new form builder are covered by Percy

Possible work after merging to trunk:

  • Get into workable style state, with own stylesheet/classes
  • Implement cfa_collection_select
  • Implement cfa_textarea
  • Consider adding: cfa_grouped_collection_select (all based on Rails FormBuilder)
  • Implement cfa_date_input (can this wait? we need to extract more than just form builder method for it to be usable)
  • Make sure 'help_text' input is consistent / how we want across our methods.
  • Look at Gov.UK and USWDS for guidance on help text and error accessibility
  • Manual accessibility check (especially for validation errors)
  • Add documentation for usage for each method that isn't just example usage
  • Consider adding help_text for fieldset
  • Add documentation for setting h1 as label or associating help text to fieldset
  • Add documentation about fallback to Rails FormBuilder

Outstanding questions:

  • Should we wrap individual checkboxes within collection checkboxes in cfa_check_box class? What about error classes (vs only showing them + message on fieldset)? [update: decided to not assign error classes on individual checkboxes or radios, but do have wrapping class]
  • We currently show error messages on each cfa_check_box, which would make them a bit wonky if used inside a fieldset. Same for cfa_radio. Should we only show errors when used with a fieldset? I believe this is Rails Formbuilder behavior, but we should check. What about error classes? What is the best visual + screenreader experience? [update: ditto above. label right now for fieldset is required, which makes validation on an individual checkbox a bit wonky but you can hide it (visually and for screen readers) with CSS, so seemed ok]
  • Why isn't HTML preview showing the form-group--error on wrapping classes when the rendered HTML does?
  • Do we want to accept blocks (eg for help_text)
  • Do we need to always provide a method name for cfa_fieldset? Seems okay, since we could just use regular HTML for fieldset

@hartsick hartsick temporarily deployed to honeycrisp-new-form-bui-hp8lc0 September 2, 2020 00:20 Inactive
@hartsick hartsick temporarily deployed to honeycrisp-new-form-bui-hp8lc0 September 2, 2020 00:29 Inactive
Copy link
Contributor

@bensheldon bensheldon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a review with Wave on the Review app. I ran into a little bit of trouble because the inputs all have the same name (with Wave really didn't like), so apologies if I interpreted it wrong.

  • Generally it looks like it performs a lot like v1. Which is great!

  • The label's "optional" text is outside the label. I'm not sure if that's intended, but the HTML was unexpected:

    <label for="form_example_method_name">Example input with options</label> <div class="form-question--optional"></div>
    <span class="sr-only">(Optional)</span>
  • I'm most curious about the behavior of the "aria-describedby" and the interaction between errors and help_text. I dunno if I'm too in the weeds but I suspect there is some conflict between them.

  • As a breaking v2, I would like to give some input on the method signature of cfa_text_input because I think some significant changes would be really beneficial. Specifically:

    • Comparing the arguments to the comparable built-in Rails form_helper and trying to create as much symmetry as possible.
    • having consistent options. For example, having input_options, label_options, (label_wrapper_options ?)group_options
    • (technical/implementation) I am curious how constructing HTML with capture/concat and Rails html helper methods (e.g. content_tag), instead of using HTML heredocs, might potentially influence the method signatures. There are some tradeoffs, but I look at wrapper_classes as being so unlike a Rails helper method that it makes me curious.

@hartsick hartsick temporarily deployed to honeycrisp-new-form-bui-hp8lc0 September 15, 2020 22:07 Inactive
@hartsick hartsick force-pushed the new-form-builder branch 3 times, most recently from b542997 to d79f57c Compare October 29, 2020 22:38
@hartsick hartsick force-pushed the new-form-builder branch 2 times, most recently from 459053c to 445ba91 Compare November 13, 2020 23:28
@hartsick hartsick force-pushed the new-form-builder branch 5 times, most recently from 8a8e384 to 113428f Compare March 1, 2021 19:50
@bensheldon
Copy link
Contributor

This is very high level observational feedback, non-blocking: in thinking about the goals that we set out "adhering as closely to the method options and signatures in the Rails FormBuilder as possible", I noticed that I think the form elements have a very similar interface to simple_form. The main similarity I've noticed is injecting *_options kwargs down to sub-elements, in simple_form they are *_html kwargs. If there are any sticking points in the interface, you might also consider checking if simple_form addresses it.

As it is, I am very happy with the new form builder 🎉

@hartsick hartsick changed the base branch from master to main March 13, 2021 00:50
@hartsick
Copy link
Contributor Author

hartsick commented Mar 19, 2021

Ben Golder did a styling spike to see if we could style the form builder without adding style hook classes that exist in our CSS (see form-elements & form-molecules SCSS files). After trying this out, we felt it was better to add the style hook classes since it would get us closer to current styles faster (and otherwise we'd just be copying a lot of existing styles), and would also allow us still to override (eg by swapping out the SCSS files or by selectively targeting CSS).

Here are the hook classes that I think we need to add, based on referencing from the styleguide documentation, form elements and form-molecules SCSS, and GetCalFresh:

form elements:

form molecules

  • form-group
  • form-group--error
  • text--error
  • input-group [not sure where this goes in each input, and should be possible to pass down through options where needed]

@hartsick hartsick marked this pull request as ready for review March 19, 2021 17:40
@hartsick hartsick force-pushed the new-form-builder branch 2 times, most recently from a517811 to 08d7221 Compare March 19, 2021 18:43
Anule Ndukwu and others added 7 commits March 24, 2021 09:24
Includes Form Builder and specs from
https://github.com/codeforamerica/illinois_petition_service/blob/master/app/helpers/cmr_v2_form_builder.rb.

Still to go:
- Decide if we want to require label and legend text in method signatures
- Add missing methods for Honeycrisp v1 FormBuilder (possibly:
checkbox_set, checkbox_set_with_none, range_field, textarea,
single_tap_button)
- Bring over dense form styles
- Bring over supporting files for new date input (validations, multipart
form file)

Co-authored-by: Christa Hartsock <[email protected]>
Adds text input

Still needs:
- Remaining implemented fields
- Styles for form builder methods

Co-authored-by: Ben Sheldon <[email protected]>
This allows us to use any method name prefixed with example_method as a
method for a form, which will generate unique IDs. Unique IDs are
necessary for doing realistic accessibility testing with Wave.

[#175500754]

Co-authored-by: Ben Sheldon <[email protected]>
- Move 'optional' tag into the label, so that it is picked up by
screenreaders as being associated with the input
- When an input is errored, add a text prefix to the label announcing
that it's errored, so that the screenreader notifies the user without
them having to listen to all assocaited descriptions.

[#175500754]

Co-authored-by: Ben Sheldon <[email protected]>
Also makes implementation more consistent with other form methods,
including adding an external div with identifying class and then
accepting wrapper classes.

In future, may want to accept a block instead of label text, so that we
can pass in things like icons.

[#175500754]
This is a blueprint for changing the method signatures of all v2 form
builder methods.

Co-authored-by: Christa Hartsock <[email protected]>
bensheldon and others added 20 commits March 24, 2021 09:24
And validate it.

Also updates method names in the text-input partial so that IDs are
unique on the documentation page.

Co-authored-by: Christa Hartsock <[email protected]>
Can be used for radios, checkboxes, etc.

Also removes CSS helping classes like form-question in favor of reducing HTML and writing
our own CSS classes.
Doesn't show its own errors, since it's unclear what that would look
like. Expectation is that it would only be used within a cfa_fieldset,
which would render errors.
Does include error state, since checkboxes can exist without fieldset
(eg for consent / confirmations)

Required/disabled are handled by input options -- may need some styling
hook for future, since it's hard to target a descendant CSS state
(checked input) for a wrapping class.
We get this for free because we collect all input options as keyword
args, and each of the inputs have a supported HTML attribute of
'required'. This means we also don't need to set "aria-required" since
we can just use the HTML attribute.

Also:
- Adds in validation errors to examples
Naming convention more closely matches Rails FormBuilder
To match Rails FormBuilder naming convention.
Needs much more work to bundle with Honeycrisp gem. Intend to add after
launch.
Should help us use existing styles, and build ones more easily in
future.

The included styles are based off of our form-elements and, selectively,
some base form molecules (just .form-group, so that .form-group--error
can style appropriately).
Javascript was only looking at the parent, but when there is an error on
a checkbox Rails inserts a div between the errored input and where we
are assigning the checkbox class. This brings the click handler in line
with what we are doing on initial state setting.
Should more easily support Honeycrisp compact checkbox styles
Should more easily support Honeycrisp compact checkbox styles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants