From c86e96a68df94478abd987c1bb1dd7efcb4d5069 Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Thu, 19 Sep 2019 18:45:38 +0100 Subject: [PATCH 1/2] Add accordion example demonstrating anchor link issue --- .../accordion-with-anchor-link/index.njk | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 app/views/examples/accordion-with-anchor-link/index.njk diff --git a/app/views/examples/accordion-with-anchor-link/index.njk b/app/views/examples/accordion-with-anchor-link/index.njk new file mode 100644 index 0000000000..d3740dcdfe --- /dev/null +++ b/app/views/examples/accordion-with-anchor-link/index.njk @@ -0,0 +1,60 @@ +{% from "back-link/macro.njk" import govukBackLink %} +{% from "accordion/macro.njk" import govukAccordion %} + +{% extends "layout.njk" %} + +{% block beforeContent %} + {{ govukBackLink({ + "href": "/" + }) }} +{% endblock %} + +{% block content %} +
+
+ +

+ Accordion with an anchor link in side a section example +

+ +

+ This example allows us to test that links within sections can be focused properly. +

+ +

+ + Link to anchor within a section + +

+ + {% set sectionHTML %} +

+ This is the content with a anchor link inside. +

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum justo dui, imperdiet nec mollis quis, luctus a dolor. Cras consectetur tincidunt tristique. Donec eget vulputate turpis. Nullam sem urna, pulvinar in euismod ac, aliquam hendrerit ex. Donec vehicula velit ut felis dictum pharetra. Aliquam dapibus quam ut consequat aliquet. Aenean vestibulum felis sit amet tortor congue semper. Ut lacus nisl, rutrum in bibendum eu, molestie eget nulla.

+

+ Anchor +

+

Aenean fringilla vel metus nec tincidunt. Nam venenatis metus tempor finibus efficitur. Aenean ex elit, convallis vitae nisi et, mattis vestibulum dolor. Aenean et purus nec arcu pulvinar tincidunt ac nec lacus. Curabitur malesuada pellentesque dui a sollicitudin. Morbi ac dignissim risus. Cras consequat, ex ut ultricies volutpat, libero velit vestibulum nisl, eu iaculis nibh ligula sed tellus.

+ {% endset %} + + {{ govukAccordion({ + id: "accordion-with-anchor-link", + items: [ + { + heading: { + text: "Section with a anchor link inside" + }, + content: { + html: sectionHTML + } + } + ] + }) }} + +

Vestibulum pretium viverra mi. Nulla finibus tempus nulla malesuada auctor. Suspendisse a aliquam turpis. Aenean ut malesuada tortor. Donec vel mi dolor. Nam in gravida est. Aliquam eu nibh eu metus porta volutpat. Donec placerat orci et urna euismod volutpat. Integer blandit urna vitae eleifend maximus. Quisque fringilla iaculis venenatis. Etiam in porta ex. Nullam vitae sapien mollis, pharetra felis in, gravida elit. Nulla ultrices urna ac mi molestie maximus. In tincidunt tellus dolor, eget tincidunt diam vestibulum in. Maecenas sed sapien non nisi malesuada ornare. Proin nec rhoncus libero.

+

Donec ante diam, imperdiet vitae pretium at, facilisis in nulla. Vestibulum ultrices, orci eget consequat mattis, eros purus rutrum nibh, nec commodo neque justo id nulla. Praesent at enim facilisis sem iaculis consequat. Sed dictum dui et justo blandit venenatis. Etiam tempor, nibh ut sollicitudin blandit, neque diam ullamcorper neque, in viverra neque neque et arcu. Curabitur non dui dolor. Proin eget dictum ante. Aliquam egestas eget augue eget cursus. Nam consectetur ut neque quis interdum.

+

Sed nec volutpat neque. Sed finibus, nisl id ullamcorper interdum, nibh augue sagittis nisl, vel venenatis justo risus eu nulla. Sed sodales est vel cursus vehicula. Curabitur ut facilisis quam. Vestibulum consequat vel arcu ut fringilla. Curabitur posuere leo ut magna consequat sollicitudin. Proin id metus in ex scelerisque placerat. Vestibulum ut mauris velit. Donec id tortor metus. In id laoreet enim. Praesent egestas, dui non hendrerit ultricies, arcu felis aliquet nunc, vitae sollicitudin nisl arcu a quam. Cras ultricies nunc metus, ac bibendum libero finibus in. Mauris tristique finibus massa id posuere. Vestibulum neque ligula, laoreet eu nisi in, pulvinar pretium lacus. Nullam porta, urna nec aliquam euismod, neque est viverra quam, vel scelerisque metus tellus vitae massa. Ut sed neque quis lacus lobortis lobortis.

+
+
+{% endblock %} From fc89c84be3ebb76fe97634acfd30ea1b9235967a Mon Sep 17 00:00:00 2001 From: Nick Colley Date: Thu, 19 Sep 2019 18:45:53 +0100 Subject: [PATCH 2/2] [wip] handle anchor links in accordion sections --- src/govuk/components/accordion/accordion.js | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/govuk/components/accordion/accordion.js b/src/govuk/components/accordion/accordion.js index 6dde305885..e2de390170 100644 --- a/src/govuk/components/accordion/accordion.js +++ b/src/govuk/components/accordion/accordion.js @@ -50,6 +50,16 @@ Accordion.prototype.init = function () { // See if "Open all" button text should be updated var areAllSectionsOpen = this.checkIfAllSectionsOpen() this.updateOpenAllButton(areAllSectionsOpen) + + // Is it only anchor links that have the behaviour of scrolling to a section? + // Should we handle hashchange too, I'm not sure what real usecase people would be setting programmatic focus to something + // instead of using an anchor link, so maybe we should intentionally avoid that til we find a real user need... + document.addEventListener('click', function (event) { + this.onAnchorLinksPressed(event.target.hash, false) + }.bind(this)) + window.addEventListener('load', function () { + this.onAnchorLinksPressed(window.location.hash, true) + }.bind(this)) } // Initialise controls and set attributes @@ -163,6 +173,34 @@ Accordion.prototype.onOpenOrCloseAllToggle = function () { $module.updateOpenAllButton(nowExpanded) } +Accordion.prototype.onAnchorLinksPressed = function (hash, shouldScrollIntoView) { + if (!hash) { + return + } + // Check if there is an element to anchor to. + var $idTarget = document.getElementById(hash.substr(1)) + if (!$idTarget) { + return + } + // If that element is inside of a section then we can expanded that section. + // TODO: Polyfill #closest + var $parentSection = $idTarget.closest('.govuk-accordion__section') + if (!$parentSection || this.isExpanded($parentSection)) { + return + } + + this.setExpanded(true, $parentSection) + + // If the hash is set on page load then we'll need to scroll to the right element ourselves. + if (!shouldScrollIntoView) { + return + } + // Wait for the page to re-layout so that the element we want to move to is visible. + window.setTimeout(function () { + $idTarget.scrollIntoView() + }) +} + // Set section attributes when opened/closed Accordion.prototype.setExpanded = function (expanded, $section) { var $button = $section.querySelector('.' + this.sectionButtonClass)