@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
JavaScript
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 }))))));
});