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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

USWDS - Banner: Add accordion dependency #5242

Merged
merged 4 commits into from
May 25, 2023
Merged

USWDS - Banner: Add accordion dependency #5242

merged 4 commits into from
May 25, 2023

Conversation

mejiaj
Copy link
Contributor

@mejiaj mejiaj commented Apr 17, 2023

Summary

Banner initializes without external dependencies. USA banner module now initializes on it's own without the user having to separately initialize accordion.

Note
Because accordion classes are used within banner we have to initialize accordion from within banner. This means that a user could initialize accordion and expect their banners to work and vice versa.

We don't see this issue when projects import uswds.js because it includes accordion already. Now you should be able to import banner and only banner and have it work as expected.

Breaking change

This is not a breaking change.

Related issue

Closes #5179.

Related pull requests

  1. Need to create changelog entry in banner in uswds-site.
  2. Also need to update interactive components spreadsheet 馃敀

Preview link

Preview link: Banner init test

Problem statement

  1. Banner should initialize without user having to import and init accordion.
  2. Banner should work independently, meaning one shouldn't trigger another
  3. Banner shouldn't initialize or have any effect on USA Accordion

Solution

  1. Banner JS now imports accordion [4550a41].
  2. Created a setting (hasInit - boolean) in accordion to check if accordion.init() has run.
  3. Call accordion.init() in banner if it hasn't. Allows us to import Banner modularly without user having to import and initialize accordion.
  4. Removed accordion import dependency in unit test [41144b0].
  5. Banner only initializes accordion on individual banners.

Alternatives

  1. Remove usa-accordion dependency and use toggle.js utility to recreate functionality.

  2. Update banner guidance to note accordion dependency.

  3. Run accordion.on() on banner init. This will also init accordions on the page, which will cause issues for users.

  4. Import toggle and selectors from accordion. We'd be recreating accordion functionality. More code reuse, but no real performance benefit.

Major changes

Banner script now imports accordion. Meaning users can follow Guidance to import banner via

import banner from "@uswds/uswds/js/usa-banner"

Initialize it with banner.on() and have component work properly. There are some new changes behind the scenes to check if accordion has initialized.

Testing and review

Traditional site

  1. Check out testing branch jm-banner-init-test
  2. Start StorybookJS npm start
  3. Visit Banner init test page
  4. Accordion & banner should work without any issues
  5. Accordion should only initialize once
  6. Locally, visit uswds-core/src/js/start.js
  7. Init Banner only, everything should work
  8. Init Accordion only, everything should work
  9. Init all components, components should work without conflicts
  10. Run npm run test:unit; banner & accordion should only contain their respective scripts & run without errors
Frameworks

  1. Visit uswds/uswds-sandbox at jm-test-uswds-5179
  2. Run npm install
  3. Run npm start
  4. Accordion and banner should work without conflicts.
  5. Import only banner; component should initialize accordion.
  6. Import both banner and accordion. Both components should work without conflicts.

Additional information

  • Additional instructions in start.js 21-27
  • Created branch in uswds-sandbox [jm-test-uswds-5179] for additional testing
Previous testing instructions

Keeping for historical record.

  1. Visit preview link for Banner init test
  2. Each banner should work
  3. One banner should have no effect on another
  4. Accordion component should not work. If so, it would mean that banner is unexpectedly initializing accordions. In projects this would cause unintended side effects.
  5. npm run test:unit should run without errors.

Compiled package size

Dependency name Previous version New version
uswds.js 798KB 801KB
uswds.min.js 87KB 87KB

When imported as a single package, the banner won't work properly because of the missing dependency of accordion JS.

- Only initialize accordion on banner buttons. Prevents side effects on accordions.
- Add JSDoc comment to toggleBanner
Banners should initialize on their own.
@mejiaj mejiaj marked this pull request as ready for review April 17, 2023 21:12
mahoneycm
mahoneycm previously approved these changes Apr 18, 2023
Copy link
Contributor

@mahoneycm mahoneycm left a comment

Choose a reason for hiding this comment

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

Working as described and doesn't initiate the accordion! Thanks for making the test page 馃憤

bannerButtons.forEach((button) => {
const parentBanner = button.closest(accordion.ACCORDION);

accordion.on(parentBanner);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this risk being double-initialized if the accordion script is also initialized? Imagining if there might be side-effects or at least redundant event handlers.

Copy link
Contributor Author

@mejiaj mejiaj Apr 18, 2023

Choose a reason for hiding this comment

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

Hey @aduth, the initial solution just called accordion.on() on init and it was initializing accordions as well. That's been changed.

Right now it only initializes accordions in banners.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, misunderstood. Yes, it gets initialized again when accordion is imported.

I've moved this PR to draft to rethink this approach.

@mejiaj
Copy link
Contributor Author

mejiaj commented Apr 19, 2023

Wanted to share, the test template was created with other pre-existing components and data.

If you'd like to do the same in the future you can see how I did that here:

<h2>Banner init test</h2>

<h3>Default banner</h3>
{% include "@components/usa-banner/src/usa-banner.twig" with DefaultContent %}

<h3>Default Spanish banner</h3>
{% include "@components/usa-banner/src/usa-banner.twig" with DefaultContentLangEs %}

<h3>Accordion</h3>
{% include "@components/usa-accordion/src/usa-accordion.twig" with accordionContent %}

https://github.com/uswds/uswds/blob/36d31a1b6b846aa682b7ee938b9d4ca0cfaf8636/packages/usa-banner/src/test/test-patterns/test-usa-banner-init.twig


In the future I'd like to improve the shorthand for twig components, but not a major priority right now.

amyleadem
amyleadem previously approved these changes Apr 19, 2023
Copy link
Contributor

@amyleadem amyleadem left a comment

Choose a reason for hiding this comment

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

Looks good to me. I successfully performed the test described in the PR description.
I really appreciate the well thought-out test page and guidance in this PR. It helped me better understand the problem you were solving. Thanks for the extra work there, @mejiaj!

@mejiaj mejiaj marked this pull request as draft April 20, 2023 14:55
const toggleBanner = function toggleEl(event) {
event.preventDefault();
this.closest(HEADER).classList.toggle(EXPANDED_CLASS);
event.target.closest(HEADER).classList.toggle(EXPANDED_CLASS);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using event.target instead of this to avoid potential scoping issues.

@mejiaj mejiaj marked this pull request as ready for review April 21, 2023 18:26
@mejiaj
Copy link
Contributor Author

mejiaj commented Apr 21, 2023

Re-requesting review. Unfortunately couldn't separate banner & accordion (see PR notes). But now they can be imported individually without conflicts.

@mejiaj mejiaj dismissed stale reviews from amyleadem and mahoneycm April 25, 2023 15:54

There's a new solution for JS conflicts

Copy link
Contributor

@mahoneycm mahoneycm left a comment

Choose a reason for hiding this comment

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

Everything is working great! Tested by:

  • Switching order of component initialization,
  • Initializing only banner/accordion
  • Running test

Everything worked as expected!

Should we consider making hasInit a pattern for dynamic components? In #5208 I run a conditional check to usa-modal for a class that is created during initialization, but if we wanted to be consistent I could use hasInit instead!

toggleButton(button, expanded);
});
// Check if Banner has previously initialized accordion.
if (!this.hasInit) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this something which could make sense to implement as common in the behavior function initialization for all components?

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'm conflicted on this and would prefer to limit this feature for now. Mainly to test and be able to have the ability to quickly change if needed.

That said, I'm also looking forward to the teams feedback. If it's something we should move forward with on all components, that's totally possible too.

Copy link
Member

Choose a reason for hiding this comment

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

I'm comfortable with leaving this scoped to these specific components for now. But I agree it could make sense to move into behavior as we identify the need.

@mejiaj
Copy link
Contributor Author

mejiaj commented Apr 28, 2023

Everything is working great! Tested by:

  • Switching order of component initialization,
  • Initializing only banner/accordion
  • Running test

Everything worked as expected!

Should we consider making hasInit a pattern for dynamic components? In #5242 I run a conditional check to usa-modal for a class that is created during initialization, but if we wanted to be consistent I could use hasInit instead!

Hey @mahoneycm, thanks for the feedback. What's the issue/PR number for modal check? Yes, if components require it this could be a pattern moving forward, but open to ideas too.

@mahoneycm
Copy link
Contributor

@mejiaj Apologies! Linked the wrong PR. It's #5208

@mejiaj
Copy link
Contributor Author

mejiaj commented May 2, 2023

@mahoneycm this could help resolve that problem, but I'd like to understand first why the modal component is initializing multiple times. For example, with two modals it initializing four times instead of the expected two.

I hesitate to introduce this as a fix for what might be a framework specific issue in implementation.

Copy link
Contributor

@amyleadem amyleadem left a comment

Choose a reason for hiding this comment

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

I was able to successfully perform the tests outlined in the PR description. Everything is working as expected.

@thisisdano thisisdano merged commit 10ef49f into develop May 25, 2023
3 checks passed
@thisisdano thisisdano deleted the jm-banner-init branch May 25, 2023 21:53
@thisisdano thisisdano mentioned this pull request Jun 6, 2023
mejiaj added a commit that referenced this pull request Jun 7, 2023
thisisdano added a commit that referenced this pull request Jun 7, 2023
Revert "Merge pull request #5242 from uswds/jm-banner-init"
@amyleadem
Copy link
Contributor

According to Slack, this PR was reverted because of some JS issues when bundled.

Seems to be our bundler browserify is changing this to void(0) for some reason.

@mejiaj Does it make sense to re-open this effort?

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.

USWDS - Bug: Banner has issues with accordion initialization
5 participants