content/static: update accordion controller init
Updates accordion controller to select active panel
on init. Opens doc panel on init for pages without
readme.
Change-Id: I4c0d190217bc109f322b6f5a09fff930bc7ac3a3
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/259801
Trust: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/content/static/html/helpers/_unit_outline.tmpl b/content/static/html/helpers/_unit_outline.tmpl
index 00f53ec..419b1b3 100644
--- a/content/static/html/helpers/_unit_outline.tmpl
+++ b/content/static/html/helpers/_unit_outline.tmpl
@@ -13,19 +13,19 @@
</div>
{{if .Readme.String}}
<a href="?readme=expanded#readme-top" class="UnitOutline-accordion js-accordionTrigger js-readmeExpand"
- aria-expanded="true" aria-controls="readme-panel" id="readme-accordion">
+ role="button" aria-expanded="false" aria-controls="readme-panel" id="readme-accordion">
README
</a>
<div class="UnitOutline-panel js-accordionPanel"
- id="readme-panel" role="region" aria-labelledby="readme-accordion" aria-hidden="false"></div>
+ id="readme-panel" role="region" aria-labelledby="readme-accordion" aria-hidden="true"></div>
{{end}}
{{if (or .DocOutline.String .Unit.IsPackage)}}
<a class="UnitOutline-accordion js-accordionTrigger" href="#doc-top"
- aria-expanded="false" aria-controls="outline-panel" id="outline-accordion">
+ role="button" aria-expanded="false" aria-controls="outline-panel" id="outline-accordion">
Documentation
</a>
<div class="UnitOutline-panel js-accordionPanel"
- id="outline-panel" role="region" aria-labelledby="ouline-accordion" aria-hidden="true">
+ id="outline-panel" role="region" aria-labelledby="outline-accordion" aria-hidden="true">
<div class="Documentation">
{{.DocOutline}}
</div>
@@ -33,7 +33,7 @@
{{end}}
{{if .SourceFiles}}
<a class="UnitOutline-accordion js-accordionTrigger" href="#files-top"
- aria-expanded="false" aria-controls="files-panel" id="files-accordion">
+ role="button" aria-expanded="false" aria-controls="files-panel" id="files-accordion">
Source Files
</a>
<div class="UnitOutline-panel js-accordionPanel"
@@ -41,7 +41,7 @@
{{end}}
{{if (or .Subdirectories .NestedModules)}}
<a class="UnitOutline-accordion js-accordionTrigger" href="#directories-top"
- aria-expanded="false" aria-controls="directories-panel" id="directories-accordion">
+ role="button" aria-expanded="false" aria-controls="directories-panel" id="directories-accordion">
Directories
</a>
<div class="UnitOutline-panel js-accordionPanel"
diff --git a/content/static/js/accordion.js b/content/static/js/accordion.js
index 62b640c..4cdb6c0 100644
--- a/content/static/js/accordion.js
+++ b/content/static/js/accordion.js
@@ -5,6 +5,29 @@
* license that can be found in the LICENSE file.
*/
+/**
+ * Controller for an accordion element. This class will add event
+ * listeners to close and open the panels of an accordion. When
+ * initialized it will select the active panel based on the URL
+ * hash for the requested page.
+ *
+ * Accordions must have the following structure:
+ *
+ * <div class="js-accordion">
+ * <a role="button" class="js-accordionTrigger" href="#panel-1" aria-expanded="false" aria-controls="first-panel" id="first-accordion">
+ * Title
+ * </a>
+ * <div class="js-accordionPanel" id="first-panel" role="region" aria-labelledby="first-accordion" aria-hidden="true">
+ * Panel Content
+ * </div>
+ * <a role="button" class="js-accordionTrigger" href="#panel-2" aria-expanded="false" aria-controls="second-panel" id="second-accordion">
+ * Title
+ * </a>
+ * <div class="js-accordionPanel" id="second-panel" role="region" aria-labelledby="second-accordion" aria-hidden="true">
+ * Panel Content
+ * </div>
+ * </div>
+ */
export class AccordionController {
constructor(accordion) {
this.accordion = accordion;
@@ -25,21 +48,29 @@
this.handleKeyPress(e);
}
});
+
+ const activeHash = document.querySelector(`a[href=${JSON.stringify(window.location.hash)}]`);
+ const initialTrigger =
+ this.triggers.find(
+ trigger => this.getPanel(trigger).contains(activeHash) || trigger.contains(activeHash)
+ ) || this.activeTrigger;
+
+ this.select(initialTrigger);
+ }
+
+ getPanel(trigger) {
+ return document.getElementById(trigger.getAttribute('aria-controls'));
}
select(target) {
const isExpanded = target.getAttribute('aria-expanded') === 'true';
if (!isExpanded) {
target.setAttribute('aria-expanded', 'true');
- document
- .getElementById(target.getAttribute('aria-controls'))
- .setAttribute('aria-hidden', 'false');
+ this.getPanel(target).setAttribute('aria-hidden', 'false');
}
if (this.activeTrigger !== target) {
this.activeTrigger.setAttribute('aria-expanded', 'false');
- document
- .getElementById(this.activeTrigger.getAttribute('aria-controls'))
- .setAttribute('aria-hidden', 'true');
+ this.getPanel(this.activeTrigger).setAttribute('aria-hidden', 'true');
}
this.activeTrigger = target;
}
@@ -47,6 +78,7 @@
handleKeyPress(e) {
const target = e.target;
const key = e.which;
+ const SPACE = 32;
const PAGE_UP = 33;
const PAGE_DOWN = 34;
const END = 35;
@@ -73,6 +105,8 @@
this.triggers[0].focus();
e.preventDefault();
break;
+ case SPACE:
+ this.select(target);
default:
break;
diff --git a/content/static/js/unit.js b/content/static/js/unit.js
index 9ef592a..ee068ae 100644
--- a/content/static/js/unit.js
+++ b/content/static/js/unit.js
@@ -8,18 +8,11 @@
import { AccordionController } from './accordion.js';
/**
- * Instantiates accordian controller for the left sidebar and sets
- * the panel for the current location hash as active.
+ * Instantiates accordion controller for the left sidebar.
*/
const accordion = document.querySelector('.js-accordion');
if (accordion) {
- const accordionCtlr = new AccordionController(accordion);
- const activePanel =
- window.location.hash &&
- document.querySelector(`a[href=${JSON.stringify(window.location.hash)}]`);
- if (activePanel) {
- accordionCtlr.select(activePanel);
- }
+ new AccordionController(accordion);
}
/**