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

118 lines 6.34 kB
// 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