@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
45 lines • 3.31 kB
JavaScript
import { __rest } from "tslib";
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useEffect, useRef } from 'react';
import clsx from 'clsx';
import { findUpUntil } from '@awsui/component-toolkit/dom';
import { useStableCallback } from '@awsui/component-toolkit/internal';
import { getBaseProps } from '../../base-component';
import { fireKeyboardEvent, fireNonCancelableEvent, } from '../../events';
import { useMergeRefs } from '../../hooks/use-merge-refs';
import styles from './styles.css.js';
const BOTTOM_TRIGGER_OFFSET = 80;
const getItemIndex = (containerRef, event) => {
const target = findUpUntil(event.target, element => element === containerRef.current || !!element.dataset.mouseTarget);
const mouseTarget = target === null || target === void 0 ? void 0 : target.dataset.mouseTarget;
return mouseTarget ? parseInt(mouseTarget) : -1;
};
const OptionsList = (_a, ref) => {
var { open, statusType, children, nativeAttributes = {}, onKeyDown, onBlur, onFocus, onLoadMore, onMouseUp, onMouseMove, position = 'relative', role = 'listbox', decreaseBlockMargin = false, ariaLabel, ariaLabelledby, ariaDescribedby, embedded } = _a, restProps = __rest(_a, ["open", "statusType", "children", "nativeAttributes", "onKeyDown", "onBlur", "onFocus", "onLoadMore", "onMouseUp", "onMouseMove", "position", "role", "decreaseBlockMargin", "ariaLabel", "ariaLabelledby", "ariaDescribedby", "embedded"]);
const baseProps = getBaseProps(restProps);
const menuRef = useRef(null);
const handleScroll = useStableCallback(() => {
const scrollContainer = menuRef === null || menuRef === void 0 ? void 0 : menuRef.current;
if (scrollContainer) {
const bottomEdgePosition = scrollContainer.scrollTop + scrollContainer.clientHeight;
const remainingScrollHeight = scrollContainer.scrollHeight - bottomEdgePosition;
if (remainingScrollHeight < BOTTOM_TRIGGER_OFFSET) {
fireNonCancelableEvent(onLoadMore);
}
}
});
useEffect(() => {
if (open && statusType === 'pending') {
handleScroll();
}
}, [open, statusType, handleScroll]);
const className = clsx(styles['options-list'], {
[styles['decrease-block-margin']]: decreaseBlockMargin,
[styles['options-list-embedded']]: embedded,
});
const mergedRef = useMergeRefs(ref, menuRef);
return (React.createElement("ul", Object.assign({}, baseProps, nativeAttributes, { className: className, ref: mergedRef, style: { position }, role: role, onScroll: handleScroll, onKeyDown: event => fireKeyboardEvent(onKeyDown, event), onMouseMove: event => onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(getItemIndex(menuRef, event)), onMouseUp: event => onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(getItemIndex(menuRef, event)), onBlur: event => fireNonCancelableEvent(onBlur, { relatedTarget: event.relatedTarget }), onFocus: () => fireNonCancelableEvent(onFocus), tabIndex: embedded ? 0 : -1, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby }), open && children));
};
export default React.forwardRef(OptionsList);
//# sourceMappingURL=index.js.map