|
@@ -2,6 +2,7 @@ import React, { useState, useEffect, createRef, useRef } from 'react'
|
|
|
import PropTypes from 'prop-types'
|
|
import PropTypes from 'prop-types'
|
|
|
import scrollIntoViewIfNeeded from 'scroll-into-view-if-needed'
|
|
import scrollIntoViewIfNeeded from 'scroll-into-view-if-needed'
|
|
|
import classNames from 'classnames'
|
|
import classNames from 'classnames'
|
|
|
|
|
+import { useTranslation } from 'react-i18next'
|
|
|
import OutlineList from './outline-list'
|
|
import OutlineList from './outline-list'
|
|
|
|
|
|
|
|
function getChildrenLines(children) {
|
|
function getChildrenLines(children) {
|
|
@@ -13,6 +14,8 @@ function getChildrenLines(children) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) {
|
|
function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) {
|
|
|
|
|
+ const { t } = useTranslation()
|
|
|
|
|
+
|
|
|
const [expanded, setExpanded] = useState(true)
|
|
const [expanded, setExpanded] = useState(true)
|
|
|
const titleElementRef = createRef()
|
|
const titleElementRef = createRef()
|
|
|
const isHighlightedRef = useRef(false)
|
|
const isHighlightedRef = useRef(false)
|
|
@@ -30,9 +33,11 @@ function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) {
|
|
|
!expanded &&
|
|
!expanded &&
|
|
|
getChildrenLines(outlineItem.children).includes(highlightedLine)
|
|
getChildrenLines(outlineItem.children).includes(highlightedLine)
|
|
|
|
|
|
|
|
|
|
+ const isHighlighted =
|
|
|
|
|
+ highlightedLine === outlineItem.line || hasHighlightedChild
|
|
|
|
|
+
|
|
|
const itemLinkClasses = classNames('outline-item-link', {
|
|
const itemLinkClasses = classNames('outline-item-link', {
|
|
|
- 'outline-item-link-highlight':
|
|
|
|
|
- highlightedLine === outlineItem.line || hasHighlightedChild
|
|
|
|
|
|
|
+ 'outline-item-link-highlight': isHighlighted
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
function handleExpandCollapseClick() {
|
|
function handleExpandCollapseClick() {
|
|
@@ -64,13 +69,23 @@ function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) {
|
|
|
[highlightedLine, titleElementRef, isHighlightedRef]
|
|
[highlightedLine, titleElementRef, isHighlightedRef]
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ // don't set the aria-expanded attribute when there are no children
|
|
|
|
|
+ const ariaExpandedValue = outlineItem.children ? expanded : undefined
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
- <li className={mainItemClasses}>
|
|
|
|
|
|
|
+ <li
|
|
|
|
|
+ className={mainItemClasses}
|
|
|
|
|
+ aria-expanded={ariaExpandedValue}
|
|
|
|
|
+ role="treeitem"
|
|
|
|
|
+ aria-current={isHighlighted}
|
|
|
|
|
+ aria-label={outlineItem.title}
|
|
|
|
|
+ >
|
|
|
<div className="outline-item-row">
|
|
<div className="outline-item-row">
|
|
|
{outlineItem.children ? (
|
|
{outlineItem.children ? (
|
|
|
<button
|
|
<button
|
|
|
className="outline-item-expand-collapse-btn"
|
|
className="outline-item-expand-collapse-btn"
|
|
|
onClick={handleExpandCollapseClick}
|
|
onClick={handleExpandCollapseClick}
|
|
|
|
|
+ aria-label={expanded ? t('collapse') : t('expand')}
|
|
|
>
|
|
>
|
|
|
<i className={expandCollapseIconClasses} />
|
|
<i className={expandCollapseIconClasses} />
|
|
|
</button>
|
|
</button>
|
|
@@ -100,7 +115,7 @@ OutlineItem.propTypes = {
|
|
|
outlineItem: PropTypes.exact({
|
|
outlineItem: PropTypes.exact({
|
|
|
line: PropTypes.number.isRequired,
|
|
line: PropTypes.number.isRequired,
|
|
|
title: PropTypes.string.isRequired,
|
|
title: PropTypes.string.isRequired,
|
|
|
- level: PropTypes.number.isRequired,
|
|
|
|
|
|
|
+ level: PropTypes.number,
|
|
|
children: PropTypes.array
|
|
children: PropTypes.array
|
|
|
}).isRequired,
|
|
}).isRequired,
|
|
|
jumpToLine: PropTypes.func.isRequired,
|
|
jumpToLine: PropTypes.func.isRequired,
|