UNPKG

@awsui/components-react

Version:

AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A

85 lines (84 loc) 5.01 kB
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'; import clsx from 'clsx'; import FocusLock from 'react-focus-lock'; import { ResizableBox } from 'react-resizable'; import { KeyCode } from '../internal/keycode'; import Button from '../button'; import handler from './resize-handler'; import styles from './styles.css.js'; var ANNOTATION_ITEM_HEIGHT = 31; var PANE_ANNOTATIONS_PADDING = 12; var MIN_HEIGHT = 3 * ANNOTATION_ITEM_HEIGHT + 2 * PANE_ANNOTATIONS_PADDING; export var Pane = forwardRef(function (_a, ref) { var id = _a.id, visible = _a.visible, annotations = _a.annotations, highlighted = _a.highlighted, onWhitelist = _a.onWhitelist, onClose = _a.onClose, onAnnotationClick = _a.onAnnotationClick, onAnnotationClear = _a.onAnnotationClear, cursorPositionLabel = _a.cursorPositionLabel, closeButtonAriaLabel = _a.closeButtonAriaLabel; var listRef = useRef(null); var _b = useState(false), isFocusTrapActive = _b[0], setFocusTrapActive = _b[1]; useEffect(function () { var _a; if (!highlighted) { return; } var row = highlighted.row, column = highlighted.column; var highlightedAnnotationIndex = annotations.indexOf(annotations.filter(function (a) { return a.row === row && a.column === column; })[0]); if (highlightedAnnotationIndex > -1) { var errorItem = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.children[highlightedAnnotationIndex]; if (errorItem) { errorItem.scrollIntoView(true); } } }, [highlighted, annotations]); var onItemFocus = useCallback(function () { setFocusTrapActive(true); onAnnotationClear(); }, [onAnnotationClear]); var onItemClick = useCallback(function (annotation) { setFocusTrapActive(false); onAnnotationClick(annotation); }, [onAnnotationClick]); var onItemKeyDown = useCallback(function (annotation, e) { if (e.keyCode === KeyCode.enter || e.keyCode === KeyCode.space) { e.preventDefault(); setFocusTrapActive(false); onAnnotationClick(annotation); } }, [onAnnotationClick]); var onEscKeyDown = useCallback(function (e) { if (e.keyCode === KeyCode.escape) { e.preventDefault(); setFocusTrapActive(false); onClose(); } }, [onClose]); useImperativeHandle(ref, function () { return ({ focusFirstElement: function () { var _a; onAnnotationClear(); var errorItem = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.firstChild; if (errorItem) { errorItem.scrollIntoView(true); errorItem.focus(); } } }); }); if (!visible) { return null; } return (React.createElement("div", { id: id, className: styles.pane, onKeyDown: onEscKeyDown, role: "tabpanel" }, React.createElement(ResizableBox, { className: styles['resizable-box'], width: Infinity, height: MIN_HEIGHT, minConstraints: [Infinity, MIN_HEIGHT], axis: "y", handle: handler }, React.createElement(FocusLock, { disabled: !isFocusTrapActive, className: styles['focus-lock'], autoFocus: false, returnFocus: false, whiteList: onWhitelist }, React.createElement("div", { className: styles.pane__list, tabIndex: -1 }, React.createElement("table", { className: styles.pane__table, role: "presentation" }, React.createElement("colgroup", null, React.createElement("col", { style: { width: 1 } }), React.createElement("col", { style: { width: 'auto' } })), React.createElement("tbody", { ref: listRef }, annotations.map(function (annotation, i) { var _a; return (React.createElement("tr", { key: i, className: clsx(styles.pane__item, (_a = {}, _a[styles['pane__item--highlighted']] = annotation === highlighted, _a)), onFocus: onItemFocus, onMouseOver: onAnnotationClear, onClick: onItemClick.bind(null, annotation), onKeyDown: onItemKeyDown.bind(null, annotation), tabIndex: 0, role: "link" }, React.createElement("td", { className: styles.pane__location, tabIndex: -1 }, cursorPositionLabel((annotation.row || 0) + 1, (annotation.column || 0) + 1)), React.createElement("td", { className: styles.pane__description, tabIndex: -1 }, annotation.text))); })))), React.createElement("div", { className: styles['pane__close-container'] }, React.createElement(Button, { formAction: "none", variant: "icon", iconName: "close", onClick: onClose, ariaLabel: closeButtonAriaLabel })))))); });