/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
const focusMoved = !!wrapMoveFocus(
getFocusableElements(this.contentRef.current),
target,
shiftKey
); if (focusMoved) { // Focus was moved to the begining/end of the list, so we need to prevent the // default focus change that would happen here.
event.preventDefault();
}
event.stopPropagation();
}
/** * Makes sure that none of the focusable elements inside the list item container are * tabbable if the list item is not active. If the list item is active and focus is * outside its container, focus on the first focusable element inside.
*/
_setTabbableState() { const elms = getFocusableElements(this.contentRef.current); if (elms.length === 0) { return;
}
if (!this.props.active) {
elms.forEach(elm => elm.setAttribute("tabindex", "-1")); return;
}
if (!elms.includes(document.activeElement)) {
elms[0].focus();
}
}
class List extends Component { static get propTypes() { return { // A list of all items to be rendered using a List component.
items: PropTypes.arrayOf(
PropTypes.shape({
component: PropTypes.object,
componentProps: PropTypes.object,
className: PropTypes.string,
key: PropTypes.string.isRequired,
})
).isRequired,
// Note: the two properties below are mutually exclusive. Only one of the // label properties is necessary. // ID of an element whose textual content serves as an accessible label for // a list.
labelledBy: PropTypes.string,
// Accessibility label for a list widget.
label: PropTypes.string,
};
}
/** * Sets the passed in item to be the current item. * * @param {null|Number} index * The index of the item in to be set as current, or undefined to unset the * current item.
*/
_setCurrentItem(index = -1, options = {}) { const item = this.props.items[index]; if (item !== undefined && !options.preventAutoScroll) { const element = document.getElementById(item.key);
scrollIntoView(element, {
...options,
container: this.listRef.current,
});
}
const state = {}; if (this.state.active != undefined) {
state.active = null; if (this.listRef.current !== document.activeElement) { this.listRef.current.focus();
}
}
case"Enter": case" ": // On space or enter make current list item active. This means keyboard focus // handling is passed on to the component within the list item. if (document.activeElement === this.listRef.current) {
preventDefaultAndStopPropagation(e); if (active !== current) { this.setState({ active: current });
}
} break;
case"Escape": // If current list item is active, make it inactive and let keyboard focusing be // handled normally.
preventDefaultAndStopPropagation(e); if (active != null) { this.setState({ active: null });
}
// Only set default current to the first list item if current item is // not yet set and the focus event is not the result of a mouse // interarction. this._setCurrentItem(0);
},
onClick: () => { // Focus should always remain on the list container itself. this.listRef.current.focus();
},
onBlur: e => { if (active != null) { const { relatedTarget } = e; if (!this.listRef.current.contains(relatedTarget)) { this.setState({ active: null });
}
}
}, "aria-label": this.props.label, "aria-labelledby": this.props.labelledBy, "aria-activedescendant": current != null ? items[current].key : null,
},
items.map((item, index) => { return ListItem({
item,
current: index === current,
active: index === active, // We make a key unique depending on whether the list item is in active or // inactive state to make sure that it is actually replaced and the tabbable // state is reset.
key: `${item.key}-${index === active ? "active" : "inactive"}`, // Since the user just clicked the item, there's no need to check if it should // be scrolled into view.
onClick: () => this._setCurrentItem(index, { preventAutoScroll: true }),
});
})
);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.