UNPKG

@awsui/components-react

Version:

On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en

95 lines 5.06 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { memo, useRef } from 'react'; import clsx from 'clsx'; import InternalBox from '../../../box/internal'; import { useInternalI18n } from '../../../i18n/context'; import { KeyCode } from '../../keycode'; import handleKey from '../../utils/handle-key'; import SeriesMarker from '../chart-series-marker'; import styles from './styles.css.js'; export default memo(ChartLegend); function ChartLegend({ series, onHighlightChange, highlightedSeries, legendTitle, ariaLabel, plotContainerRef, }) { const i18n = useInternalI18n('[charts]'); const containerRef = useRef(null); const segmentsRef = useRef([]); const highlightedSeriesIndex = findSeriesIndex(series, highlightedSeries); const highlightInlineStart = () => { var _a; const currentIndex = highlightedSeriesIndex !== null && highlightedSeriesIndex !== void 0 ? highlightedSeriesIndex : 0; const nextIndex = currentIndex - 1 >= 0 ? currentIndex - 1 : series.length - 1; (_a = segmentsRef.current[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus(); }; const highlightInlineEnd = () => { var _a; const currentIndex = highlightedSeriesIndex !== null && highlightedSeriesIndex !== void 0 ? highlightedSeriesIndex : 0; const nextIndex = currentIndex + 1 < series.length ? currentIndex + 1 : 0; (_a = segmentsRef.current[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus(); }; const handleKeyPress = (event) => { if (event.keyCode === KeyCode.right || event.keyCode === KeyCode.left) { // Preventing default fixes an issue in Safari+VO when VO additionally interprets arrow keys as its commands. event.preventDefault(); handleKey(event, { onInlineStart: () => highlightInlineStart(), onInlineEnd: () => highlightInlineEnd(), }); } }; const handleSelection = (index) => { if (series[index].datum !== highlightedSeries) { onHighlightChange(series[index].datum); } }; const handleBlur = (event) => { var _a; // We need to check if the next element to be focused inside the plot container or not // so we don't clear the selected legend in case we are still focusing elements ( legend elements ) // inside the plot container if (event.relatedTarget === null || (containerRef.current && !containerRef.current.contains(event.relatedTarget) && !((_a = plotContainerRef === null || plotContainerRef === void 0 ? void 0 : plotContainerRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget)))) { onHighlightChange(null); } }; const handleMouseOver = (s) => { if (s !== highlightedSeries) { onHighlightChange(s); } }; const handleMouseLeave = () => { onHighlightChange(null); }; return (React.createElement(React.Fragment, null, React.createElement("div", { ref: containerRef, role: "toolbar", "aria-label": legendTitle || i18n('i18nStrings.legendAriaLabel', ariaLabel), className: styles.root, onKeyDown: handleKeyPress, onBlur: handleBlur }, legendTitle && (React.createElement(InternalBox, { fontWeight: "bold", className: styles.title }, legendTitle)), React.createElement("div", { className: styles.list }, series.map((s, index) => { const someHighlighted = highlightedSeries !== null; const isHighlighted = highlightedSeries === s.datum; const isDimmed = someHighlighted && !isHighlighted; return (React.createElement("div", { role: "button", key: index, "aria-pressed": isHighlighted, className: clsx(styles.marker, { [styles['marker--dimmed']]: isDimmed, [styles['marker--highlighted']]: isHighlighted, }), ref: elem => { if (elem) { segmentsRef.current[index] = elem; } else { delete segmentsRef.current[index]; } }, tabIndex: index === highlightedSeriesIndex || (highlightedSeriesIndex === undefined && index === 0) ? 0 : -1, onFocus: () => handleSelection(index), onClick: () => handleSelection(index), onMouseOver: () => handleMouseOver(s.datum), onMouseLeave: handleMouseLeave }, React.createElement(SeriesMarker, { color: s.color, type: s.type }), " ", s.label)); }))))); } function findSeriesIndex(series, targetSeries) { for (let index = 0; index < series.length; index++) { if (series[index].datum === targetSeries) { return index; } } return undefined; } //# sourceMappingURL=index.js.map