Skip to content

Use design system icons for icon buttons#5904

Merged
aduth merged 19 commits intomainfrom
aduth-icon-button
Feb 3, 2022
Merged

Use design system icons for icon buttons#5904
aduth merged 19 commits intomainfrom
aduth-icon-button

Conversation

@aduth
Copy link
Contributor

@aduth aduth commented Feb 2, 2022

Why: So that we use a consistent icon set conforming to the design system rather than ad-hoc icons, and can make use of the IconComponent convenience abstraction.

Device Before After
Desktop localhost_3000_backup_code_setup (1) localhost_3000_backup_code_setup
Mobile localhost_3000_backup_code_setup(iPhone XR) (1) localhost_3000_backup_code_setup(iPhone XR)

aduth added 4 commits February 2, 2022 14:08
Anticipate simpler style defaults
**Why**: So that we use a consistent icon set conforming to the design system rather than ad-hoc icons, and can make use of the IconComponent convenience abstraction.
Comment on lines +42 to +43
<%= render IconComponent.new(icon: :loop) -%>
<% concat(t('links.two_factor_authentication.get_another_code')) %>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So this was an interesting predicament: The icon and accompanying text here are sensitive to whitespace. This isn't the case with the upstream proposal in uswds/uswds#4493, since it uses float. We can't use float here, because full-width buttons (a Login.gov-specific button feature) would cause the icon to appear at the far left of the button.

The combination of -%> on line 42 and <% concat on line 43 avoid whitespace. There are some other ways to do this, though:

  • Have them be on the same line
  • Use something like <%= safe_join([ ... ]) %>

Ultimately I'm also trying to optimize for: What's easiest for future developers to copy/paste as reference and not get wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another option could be to have something like an IconButtonComponent, which wouldn't be a far stretch from what we have already with ButtonComponent, and could absorb this implementation detail. The problem is that I'm not totally sure how well that'd work with the many variations we'd need to support: button_to, button_tag, f.button, link_to, and perhaps others.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should also clarify there's a desire to not include additional class names or child elements to make this work. It could be easily solved if we could e.g. wrap the text in a <span>, or change the wrapper to a display: flex.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like the idea of an IconButtonComponent, or maybe update the button component to have an optional icon: param?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like the idea of an IconButtonComponent, or maybe update the button component to have an optional icon: param?

It's a bit hastily put together as I approach the end of my day so there may be some mistakes, but how do you feel about the recent round of revisions? The "factory" business feels a bit wonky to me, but otherwise it's got all the upsides that I'd expect from componentizing this behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

Left some comments here since it felt easier to comment on the impl: https://github.com/18F/identity-idp/pull/5904/files#r798056283

Copy link
Contributor

@anniehirshman-gsa anniehirshman-gsa left a comment

Choose a reason for hiding this comment

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

LGTM!

For future reference, by default, icons will now be pulled from usa-icons? It looks like they used to be Font Awesome and are moving to these, but I'm not totally clear on how USWDS icons work, so want to check. CC: @nickttng

@aduth
Copy link
Contributor Author

aduth commented Feb 2, 2022

For future reference, by default, icons will now be pulled from usa-icons? It looks like they used to be Font Awesome and are moving to these, but I'm not totally clear on how USWDS icons work, so want to check. CC: @nickttng

I think it should be the default source, yes. And I believe those in turn are (at least in part) sourced from the Material icon set.

Also worth clarifying that we still use a few different icons in the IdP even after these changes. This covers only the icon+button case.

@nickttng
Copy link
Contributor

nickttng commented Feb 2, 2022

For future reference, by default, icons will now be pulled from usa-icons?

Yep, USWDS icons by default. It does seem to be heavily sourced from Material icon set, which is mentioned in the USWDS license. Also mentioned is Font Awesome (FA). With that in mind, we can consider Material (first preference) and FA (second preference) when an USWDS icon isn't available or suitable.

@anniehirshman-gsa
Copy link
Contributor

With that in mind, we can consider Material (first preference) and FA (second preference) when an USWDS icon isn't available or suitable.

That's a helpful way to think about it, thank you! 👍

Comment on lines +39 to +46
<%= render ButtonComponent.new(
idv_resend_otp_path,
method: :post,
factory: :button_to,
outline: true,
icon: :loop,
class: 'margin-bottom-4',
).with_content(t('links.two_factor_authentication.get_another_code')) %>
Copy link
Contributor

@zachmargolis zachmargolis Feb 2, 2022

Choose a reason for hiding this comment

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

Noodling on the factory bit here, I feel like that name doesn't quite cover what's going on, and factory_args only makes sense when looking at examples.

Here's an idea that uses procs?

Suggested change
<%= render ButtonComponent.new(
idv_resend_otp_path,
method: :post,
factory: :button_to,
outline: true,
icon: :loop,
class: 'margin-bottom-4',
).with_content(t('links.two_factor_authentication.get_another_code')) %>
<%= render ButtonComponent.new(
idv_resend_otp_path,
action: proc do |body, url, options|
button_to(body, url, method: :post, **options)
end,
outline: true,
icon: :loop,
class: 'margin-bottom-4',
).with_content(t('links.two_factor_authentication.get_another_code')) %>

We could have a default value for the proc that serves as an example:

class ButtonComponent
  def initialize(url, action: proc { |body, url, options| link_to(body, url, options) },  **options)
  # ... etc
   end
end

Copy link
Contributor

Choose a reason for hiding this comment

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

or honestly, we just call it link_or_button: :link because realistically there are only those two factories we are choosing from?

Then all the stuff into link_or_button_options and public_send(link_or_button, content, url_link_or_button_options)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or honestly, we just call it link_or_button: :link because realistically there are only those two factories we are choosing from?

Then all the stuff into link_or_button_options and public_send(link_or_button, content, url_link_or_button_options)

We've got button_to and button_tag within these changes already, and I expect we'd probably also want to support SimpleForm f.button and f.submit as well... though it's doubtful those could be supported with the implementation as it stands.

I like the proc idea. It's a bit more verbose, but with a reasonable default I think it can also be clearer to understand how to customize, and also more flexible to support the SimpleForm cases as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Took a pass at it in 2c1e7aa. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

I like it! I didn't even think about SimpleForm, let's ship the proc 🚢

aduth added 2 commits February 3, 2022 11:13
**Why**: Avoids button kwargs being treated as attributes in button output
@aduth aduth merged commit 5a70437 into main Feb 3, 2022
@aduth aduth deleted the aduth-icon-button branch February 3, 2022 17:51
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.

4 participants