-
Notifications
You must be signed in to change notification settings - Fork 921
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
Conversation
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.
There was a problem hiding this 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 馃憤
packages/usa-banner/src/index.js
Outdated
bannerButtons.forEach((button) => { | ||
const parentBanner = button.closest(accordion.ACCORDION); | ||
|
||
accordion.on(parentBanner); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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 %} In the future I'd like to improve the shorthand for twig components, but not a major priority right now. |
There was a problem hiding this 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!
const toggleBanner = function toggleEl(event) { | ||
event.preventDefault(); | ||
this.closest(HEADER).classList.toggle(EXPANDED_CLASS); | ||
event.target.closest(HEADER).classList.toggle(EXPANDED_CLASS); |
There was a problem hiding this comment.
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.
Re-requesting review. Unfortunately couldn't separate banner & accordion (see PR notes). But now they can be imported individually without conflicts. |
There's a new solution for JS conflicts
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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 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. |
There was a problem hiding this 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.
Revert "Merge pull request #5242 from uswds/jm-banner-init"
Summary
Banner initializes without external dependencies. USA banner module now initializes on it's own without the user having to separately initialize accordion.
Breaking change
This is not a breaking change.
Related issue
Closes #5179.
Related pull requests
uswds-site
.Preview link
Preview link: Banner init test
Problem statement
Solution
hasInit - boolean
) in accordion to check ifaccordion.init()
has run.accordion.init()
in banner if it hasn't. Allows us to import Banner modularly without user having to import and initialize accordion.Banner only initializes accordion on individual banners.Alternatives
Remove
usa-accordion
dependency and usetoggle.js
utility to recreate functionality.Update banner guidance to note accordion dependency.
Runaccordion.on()
on banner init. This will also init accordions on the page, which will cause issues for users.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
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
jm-banner-init-test
npm start
uswds-core/src/js/start.js
npm run test:unit
; banner & accordion should only contain their respective scripts & run without errorsFrameworks
npm install
npm start
Additional information
jm-test-uswds-5179
] for additional testingPrevious testing instructions
Keeping for historical record.
npm run test:unit
should run without errors.Compiled package size