-
Notifications
You must be signed in to change notification settings - Fork 334
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
Accordion component #958
Accordion component #958
Conversation
Hello. I've not used your recommended unit test framework, Jest, before, but it looks straightforward, so I'm not too worried about that. That said, I'm not sure how much of the Do you have a standardised way of doing integration testing at all, eg setting up an HTML page, adding the javascript, and then clicking the various elements and asserting what should happen? Selenium? |
Just realised that Jest does do full integration testing, so ignore that question... |
Do you have any thoughts on how the javascript should be structured. Currently, both This feels a bit messy. An alternative pattern might be something like this: function Accordion(element) {
this.sections = [new Section()]
function Section(sectionElement) {
this.expanded = false
}
Section.prototype.setExpanded = function(expanded) {
this.expanded = expanded
};
}
Accordion.prototype.setExpandAll = function(expandAll) {
for (section of this.sections) {
section.setExpanded(expandAll)
}
} Which would only expose an var accordion = new Accordion(document.querySelector('.govuk-accordion'))
accordion.sections.length
=> 2
accordion.sections[0].setExpanded(true)
accordion.sections[0].expanded
=> true
accordion.setExpandAll(true)
accordion.sections[1].expanded
=> true (it'd be nice to be able to avoid having a separate setter function, but I'm not sure how easy that is with javascript right now). Any thoughts? |
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.
Looking good 👍 I've left some comments but haven't had a chance to review most of it yet, will continue to review later. I'm also going to take a look at your above question about structuring JS.
Hi @frankieroberto, as discussed I've pushed some changes to the JS, these address the structure of the JS questions. We can keep discussing this obviously. @joelanman Do you have any thoughts around using "+ or -" or arrow up/down as we use with details component? Another question: should we consider an enhancement of storing the open/closed state of sections? |
d136952
to
911e9c6
Compare
This bug means that it's not possible to expand |
On the open/close control:
I would say from this that we have some evidence that arrows are clearer than plus/minus. The Step by step approach is probably less ambiguous, with words rather than images, and it has an accessibility advantage with the controls on the left. However it is not as widely used as the other accordion design and so I don't know if we can recommend it for all services. |
DfE had an issue with the use of the Back button and the existing accordion, their fix for which is summarised here: DFE-Digital/search-and-compare-ui#156 This makes me think we should do some research into whether/how different browsers restore state when using the back button – we've definitely observed some differences between browsers for this. |
We'd also want to ensure that the accordions don't all flash open whilst the javascript is loading |
@dankmitchell do the existing ones do that at all? |
@frankieroberto some context #1000 |
I've updated the component now to incorporate this fix from DfE, which makes sure that that the button says "Close all" if the component is initialised with all the sections open: DFE-Digital/search-and-compare-ui@4f129b8 (thanks @tvararu!) I've also updated the nunjucks macro so that you can now pass in an optional |
@hannalaakso any thoughts on how we should "inline" (via base64 encoding) the SVG image? I think it makes sense to keep the SVG file in the repo, but have the inlining be part of the sass compilation step? In which case we'd need to pick an npm package like https://www.npmjs.com/package/sass-inline-image to add a sass function? |
Work-in-progress on the documentation is here: alphagov/govuk-design-system#579 |
Decisions from catch up with @frankieroberto and @joelanman:
|
Addition to the minutes from last week: We discussed storing of state and decided that since this is something Service Manual accordions use (example here), we should try to get it in if we can (but it shouldn't delay the initial release of the component if it comes to it). We’ll look into using session storage for this. We can either advise in guidance that service teams will need to make sure each accordion item has a unique ID or we can look into generating a unique ID based on a combination of page url and indexed ID for the accordion item. |
Just a note to say that I've done some testing with Jaws and NVDA and have added some accessibility to-do's to the PR description. |
@hannalaakso I've made the accessibility changes you suggestion, except for a couple of differences, which I think are worth discussing:
Other comments:
|
We initially went with "panel" for the content area as this reflects the lexicon of W3C but in fact "content" is more self-explanatory.
This will make the class names slightly more verbose but the advantage is that the hierarchy of classes will be clearer (more BEM-my) this way.
Thanks @36degrees Plus some minor SCSS fixes
- Fix bug where clicking on OpenAll doesn't store state of accordions (as clicking on "Open all" wasn't calling `storeState()` - it now does) - Consistently use `checkIfAllSectionsOpen()` to check for state of allExpanded - Rename `onToggleExpanded` to `onSectionToggle` to better explain what it does, and `openOrCloseAllSections` to `onOpenCloseButtonClick` to show it's event bound - Move `updateOpenAllButton` further down in code to make it clearer that it relates to `openAllSections()` - Move `setOpenAllButtonAttributes()` further up to make it clearer it sets the button - Add some more comments
- Rename function to indicate if they init, get or set states and stuff - Move init functions to top for readability
We might want to change the styling of the headings in the future so removing hardcoded `govuk-heading-m` from template. This is similar to what was done in https://github.com/alphagov/govuk-frontend/blob/e43f778e54c30f778aed2c812246bd592f133788/components/fieldset/_fieldset.scss#L43-L46
Copy over all attributes and their values from `<span>`. We currently don’t set any attributes on `span` but might do so in the future
As we don't have evidence at the moment that it's needed.
For IE8 css pseudo elements, we needed to force a repaint to toggle the icons. This is done by using CSS content property. https://stackoverflow.com/questions/8703799/forcing-ie8-to-rerender-repaint-before-after-pseudo-elements
1. init method had a lot of code in it and so I moved most of it out into separate methods. So now its easy to see that it initialises the section headers & creates the controls. As part of this refactoring, I changed how "readState" method worked. When init method was running it would iterate through the headers twice, once to setup the markup for the sections headers and then again to read the previous state and set them. Instead this would be better to do it in one transaction so it only loops through the headings once. 2. refactor checkIfAllSectionsOpen method There is no need to loop through all the sections to work out if they are expanded. We can find the length of sections that are expanded against the total number of sections and if they are equal then it means all sections are open. 3. refactors storeState to stop iterating through all sections Everytime a user clicked on a section header storeState would be called against each section in the accordion and set state for each section. Its not a issue when we only have a few sections but the more sections there are the more unnecessary work the browser needs to do. Now we only call storeState on the section that was clicked. 5. Refactors SessionStorage support We should cache the result of SessionStorage support instead of constantly looking it up and setting/removing session data. We should proberly move the SessionStorage helper method out to its own file as it might be useful for other components.
Instead of defining them in the methods. This makes them easier to update.
bfb58c0
to
c3957c6
Compare
A lot has changed since my initial review
// Update "Open all" button | ||
Accordion.prototype.updateOpenAllButton = function (expanded) { | ||
var newButtonText = expanded ? 'Close all' : 'Open all' | ||
newButtonText += '<span class="govuk-visually-hidden"> sections</span>' |
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.
Non-blocking suggestion,
These two lines and line 60 look like they could do with a function that returns the mark up.
Also if we wanted to add translation support to the component we could use the macro to determine the text and set a html data attribute which this js could pickup and use.
This is looking good, well done everyone who's contributed so far! |
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.
😍👏
🎊 |
Note for reviewers:
Please leave any comments pertaining to the guidance/documentation or the content used for the accordion on alphagov/govuk-design-system#635.
Please leave any comments for the accordion component itself (design, code) on this PR.
Preview here: https://deploy-preview-635--govuk-design-system-preview.netlify.com/components/accordion/
This is work-in-progress on adding an Accordion component to the Design System.
(Opening this Pull Request mainly as a place to collaborate and discuss the component implementation)
So far I've just done the most minimal lift-and-shift from https://github.com/frankieroberto/accordion to get it working, which has meant:
this.element
tothis.$module
(following the convention of existing components)new Accordion()
) to an explicit function call (new Accordion().init()
), following the convention of existing components.To-do (prior to Working Group review):
<details>
element instead of divs, and the.open
DOM API.params
here<button>
that is inside a<h3>
id
that is used byaria-labelledby
of relevant panelaria-controls
that refers toid
of relevant panelaria-expanded
that is toggledfalse
/true
based on stateid
to panel that corresponds toaria-controls
of relevant headeraria-labelledby
to panel that refers toid
of relevant headerTo-do (can be done after Working Group review)
govuk-frontend/src/components/panel/template.njk
Line 5 in 3e7f8f1
govuk-accordion__section-header-button
to leave the text hard aligned to the left edge@include govuk-responsive-margin(6, "bottom");
to.govuk-accordion
as all components / wrappers on this "outer" layer have the same bottom margin applied..govuk-accordion__section
currently use magic numbers for the spacing. Ideally we should use padding values from the spacing scale (spacing scale 3, 15px) and override with current magic values in a separate section at the bottom of the scss file. This is down to where New Transport sits on the baseline compared to the default sans-serif, we have a new version of this the font that fixes this so it would be great to quickly remove the "magic numbers" block of CSS when this version of the font is released..govuk-accordion__section-panel
description
(orsummary
as we now call it that in the Design System?) option for adding the summary line (at the moment we pass in markup to do this)Post working group review / pre-publish work
Nice to have
References:
W3C Authoring Practises - Accordion
W3C Accordion example