UNPKG

@kubit-ui-web/react-components

Version:

Kubit React Components is a customizable, accessible library of React web components, designed to enhance your application's user experience

83 lines 4.08 kB
import { jsx as _jsx } from "react/jsx-runtime"; import React from 'react'; import { useEscPressedV2 } from '../../hooks/useEscPressedV2/useEscPressedV2'; import { useMediaDevice } from '../../hooks/useMediaDevice/useMediaDevice'; import { useStyles } from '../../hooks/useStyles/useStyles'; import { useSwipeDown } from '../../hooks/useSwipeDown/useSwipeDown'; import { ErrorBoundary } from '../../provider/errorBoundary/errorBoundary'; import { FallbackComponent } from '../../provider/errorBoundary/fallbackComponent'; import { DeviceBreakpointsType } from '../../types/breakpoints/breakpoints'; import { OliveMenuStandAlone } from './oliveMenuStandAlone'; const OLIVE_MENU_STYLES = 'OLIVE_MENU_STYLES'; const OliveMenuComponent = React.forwardRef(({ variant, ctv, trigger, actionBottomSheetStructure, onOpenClose, ...props }, ref) => { const [open, setOpen] = React.useState(false); const styles = useStyles(OLIVE_MENU_STYLES, variant, ctv); const device = useMediaDevice(); const innerRef = React.useRef(null); const actionBottomSheetRef = React.useRef(null); React.useImperativeHandle(ref, () => innerRef.current, []); const handlePressScape = React.useCallback(() => { // Do nothing if already closed if (!open) { return; } setOpen(false); onOpenClose?.(false); // Focus the trigger button since its not handled automatically by the popover // and the focus in inside the component that is going to be closed const trigger = innerRef.current?.querySelector('button'); trigger?.focus(); }, [open]); // It is handled internally by the component to allow close when the focus is on the button useEscPressedV2({ ref: innerRef, onEscPress: handlePressScape }); const handleTriggerClick = e => { setOpen(!open); onOpenClose?.(!open, e); trigger?.onClick?.(e); }; const handleCloseIconClick = e => { setOpen(false); onOpenClose?.(false, e); actionBottomSheetStructure?.closeIcon?.onClick?.(e); }; const handleCloseInternally = () => { setOpen(false); onOpenClose?.(false); props.popover?.onCloseInternally?.(); }; const handleBlur = e => { // Do nothing if: // * Is device with popover (mobile or tablet) // * the new focus is inside the component // * it is already closed if ([DeviceBreakpointsType.MOBILE, DeviceBreakpointsType.TABLET].includes(device) || e.currentTarget.contains(e.relatedTarget) || !open) { return; } setOpen(false); onOpenClose?.(false, e); }; const { setPopoverRef, setDragIconRef } = useSwipeDown(props.popover?.animationOptions, handleCloseInternally); const setInnerRef = React.useCallback(node => { actionBottomSheetRef.current = node; const dragIcon = actionBottomSheetRef.current?.querySelector('[data-drag-icon]'); if (dragIcon instanceof HTMLElement) { setDragIconRef(dragIcon); } }, []); return (_jsx(OliveMenuStandAlone, { ...props, ref: innerRef, actionBottomSheetStructure: { ...actionBottomSheetStructure, forwardedRef: setInnerRef, closeIcon: { ...actionBottomSheetStructure?.closeIcon, onClick: handleCloseIconClick }, }, device: device, open: open, popover: { ...props.popover, forwardedRef: setPopoverRef, onCloseInternally: handleCloseInternally, }, styles: styles, trigger: trigger && { ...trigger, onClick: handleTriggerClick }, onBlur: handleBlur })); }); OliveMenuComponent.displayName = 'OliveMenuComponent'; const OliveMenuBoundary = (props, ref) => (_jsx(ErrorBoundary, { fallBackComponent: _jsx(FallbackComponent, { children: _jsx(OliveMenuStandAlone, { ...props, ref: ref }) }), children: _jsx(OliveMenuComponent, { ...props, ref: ref }) })); const OliveMenu = React.forwardRef(OliveMenuBoundary); export { OliveMenu }; //# sourceMappingURL=oliveMenu.js.map