Closed thedigitalman closed 3 years ago
I wasn't able to publish a branch for this feature. But, here's the working code I'm using.
const cheerio = require('cheerio')
const ParseOptions = require('./ParseOptions')
const NestHeadings = require('./NestHeadings')
const BuildList = require('./BuildList')
const defaults = {
tags: ['h2', 'h3', 'h4'],
wrapper: 'nav',
wrapperClass: 'toc',
wrapperLabel: 'Table of contents',
wrapperHeading: 'h2',
wrapperHeadingClass: 'toc-heading',
ul: false,
flat: false,
}
const BuildTOC = (text, opts) => {
const {tags, wrapper, wrapperClass, wrapperLabel, wrapperHeading, wrapperHeadingClass, ul, flat} = ParseOptions(opts, defaults)
const $ = cheerio.load(text)
const headings = NestHeadings(tags, $)
if (wrapper !== 'nav') {
return headings.length > 0
? `<${wrapper} class="${wrapperClass}" role="navigation" aria-labelledby="toc-label">
<${wrapperHeading} class="${wrapperHeadingClass}" id="toc-label">${wrapperLabel}</${wrapperHeading}>
${BuildList(headings, ul, flat)}</${wrapper}>`
: undefined
} else {
return headings.length > 0
? `<${wrapper} class="${wrapperClass}" aria-label="${wrapperLabel}">
${BuildList(headings, ul, flat)}</${wrapper}>`
: undefined
}
}
module.exports = BuildTOC
<nav>
wrapper as a navigation landmark.
Thanks for writing this plugin! I'm currently working on a design system using 11ty and this has been very useful.
I have two accessibility related suggestions.
aria-label
andaria-labelledby
to help identify the navigation landmark.role="navigation"
for any wrapper other than "nav".4.3.6 Navigation | WAI-ARIA Authoring Practices 1.1
aria-label
The
aria-label
attribute could be included by default with a value of "Table of contents". A new option ofwrapperLabel
could be added to replace the default value.aria-labelledby
If the author wants visible text to describe the table of contents, they could set a
wrapperLabelHeading
option to "true".That would add
aria-labelledby="toc-label"
to the<nav>
element, and a<h2>
with anid
of "toc-label" with thewrapperLabel
option providing the text.role="navigation"
If the wrapper is anything other then
<nav>
, addrole="navigation"
.Navigation Landmark: ARIA Landmark Example