@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
118 lines • 6.34 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import clsx from 'clsx';
import { getAnalyticsMetadataAttribute } from '@awsui/component-toolkit/internal/analytics-metadata';
import Icon from '../../../../icon/internal';
import Tooltip from '../../../../internal/components/tooltip';
import testutilStyles from '../../../test-classes/styles.css.js';
import styles from './styles.css.js';
function TriggerButton({ ariaLabel, className, iconName, iconSvg, customSvg, ariaExpanded, ariaControls, onClick, testId, disabled = false, badge, selected = false, hasTooltip = false, tooltipText, hasOpenDrawer = false, isMobile = false, isForPreviousActiveDrawer = false, isForSplitPanel = false, variant = 'circle', }, ref) {
const containerRef = useRef(null);
const tooltipValue = tooltipText ? tooltipText : ariaLabel ? ariaLabel : '';
const [showTooltip, setShowTooltip] = useState(false);
const [suppressTooltip, setSupressTooltip] = useState(false);
const handleTriggerClick = (event) => {
event.stopPropagation(); // Stop the event from propagating to the badge icon
setShowTooltip(false);
setSupressTooltip(true);
onClick(event);
};
const handleBlur = (keepSupressed = false) => {
setSupressTooltip(keepSupressed);
setShowTooltip(false);
};
const handlePointerEnter = () => {
setSupressTooltip(false);
setShowTooltip(true);
};
/**
* Takes the drawer being closed and the data-shift-focus value from a close button on that drawer that persists
* on the event relatedTarget to determine not to show the tooltip
* @param event
*/
const handleOnFocus = useCallback((event) => {
var _a;
let shouldShowTooltip = false;
const eventWithRelatedTarget = event;
const relatedTarget = eventWithRelatedTarget === null || eventWithRelatedTarget === void 0 ? void 0 : eventWithRelatedTarget.relatedTarget;
const isFromAnotherTrigger = ((_a = relatedTarget === null || relatedTarget === void 0 ? void 0 : relatedTarget.dataset) === null || _a === void 0 ? void 0 : _a.shiftFocus) === 'awsui-layout-drawer-trigger';
if ((isForSplitPanel && !!relatedTarget) || // relatedTarget is null when split panel is closed
(!isForSplitPanel &&
(isFromAnotherTrigger || // for key navigation from another trigger button
!isForPreviousActiveDrawer)) // for when the drawer was not opened recently
) {
shouldShowTooltip = true;
}
setSupressTooltip(!shouldShowTooltip);
setShowTooltip(true);
}, [
// To assert reference equality check
isForPreviousActiveDrawer,
isForSplitPanel,
]);
const tooltipVisible = useMemo(() => {
return (hasTooltip &&
showTooltip &&
!suppressTooltip &&
!!(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) &&
tooltipValue &&
!(isMobile && hasOpenDrawer));
}, [hasTooltip, showTooltip, containerRef, tooltipValue, isMobile, hasOpenDrawer, suppressTooltip]);
useEffect(() => {
if (hasTooltip && tooltipValue) {
const close = () => {
setShowTooltip(false);
setSupressTooltip(false);
};
const shouldCloseTooltip = (event) => {
var _a;
if (event.target && containerRef && ((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
return false;
}
return true;
};
const handlePointerDownEvent = (event) => {
if (shouldCloseTooltip(event)) {
close();
}
};
const handleKeyDownEvent = (event) => {
if (event.key === 'Escape') {
close();
}
};
const wrapperDiv = containerRef.current;
if (wrapperDiv) {
const controller = new AbortController();
wrapperDiv.addEventListener('pointerdown', handlePointerDownEvent, { signal: controller.signal });
wrapperDiv.addEventListener('keydown', handleKeyDownEvent, { signal: controller.signal });
return () => {
controller.abort();
};
}
}
}, [containerRef, hasTooltip, tooltipValue]);
const triggerEventMetadata = {
action: selected ? 'close' : 'open',
detail: { label: { root: 'self' } },
};
return (React.createElement("div", { ref: containerRef, ...(hasTooltip && {
onPointerEnter: () => handlePointerEnter(),
onPointerLeave: () => handleBlur(true),
onFocus: e => handleOnFocus(e),
onBlur: () => handleBlur(true),
}), className: styles['trigger-wrapper'] },
React.createElement("button", { "aria-expanded": ariaExpanded, "aria-controls": ariaControls, "aria-haspopup": true, "aria-label": ariaLabel, "aria-disabled": disabled, disabled: disabled, className: clsx(styles.trigger, styles[variant], {
[styles.selected]: selected,
[styles['trigger-with-badge']]: badge,
[testutilStyles['drawers-trigger-with-badge']]: badge,
}, className), onClick: handleTriggerClick, ref: ref, type: "button", "data-testid": testId, "data-shift-focus": "awsui-layout-drawer-trigger", ...getAnalyticsMetadataAttribute(triggerEventMetadata) }, customSvg !== null && customSvg !== void 0 ? customSvg : ((iconName || iconSvg) && React.createElement(Icon, { name: iconName, svg: iconSvg }))),
badge && React.createElement("div", { className: styles.dot }),
tooltipVisible && (React.createElement(Tooltip, { trackRef: containerRef, value: tooltipValue, className: testutilStyles['trigger-tooltip'], onDismiss: () => {
setShowTooltip(false);
setSupressTooltip(false);
} }))));
}
export default React.forwardRef(TriggerButton);
//# sourceMappingURL=index.js.map