import React, { useState, useRef, useEffect, useLayoutEffect } from "react"; import { isIOS, isMobile } from "react-device-detect"; import styled from "styled-components"; import ButtonAlertReactSvg from "PUBLIC_DIR/images/button.alert.react.svg"; import { IconSizeType, classNames, commonIconsStyles } from "../../utils"; import { Scrollbar } from "../scrollbar"; import { Backdrop } from "../backdrop"; import { FloatingButtonIcons } from "../floating-button"; import { StyledFloatingButton, StyledDropDown, StyledDropDownItem, StyledContainerAction, StyledProgressContainer, StyledButtonOptions, StyledAlertIcon, StyledRenderItem, } from "./MainButtonMobile.styled"; import SubmenuItem from "./sub-components/SubmenuItem"; import { ActionOption, ButtonOption, MainButtonMobileProps, ProgressOption, } from "./MainButtonMobile.types"; import { ProgressBarMobile } from "./sub-components/ProgressBar"; const StyledButtonAlertIcon = styled(ButtonAlertReactSvg)` cursor: pointer; vertical-align: top !important; ${commonIconsStyles}; `; const MainButtonMobile = (props: MainButtonMobileProps) => { const { className, style, opened, actionOptions, progressOptions, buttonOptions, percent, withoutButton, manualWidth, isOpenButton, onClose, alert, withMenu, onClick, onAlertClick, withAlertClick, dropdownStyle, } = props; const [isOpen, setIsOpen] = useState(opened); const [isUploading, setIsUploading] = useState(false); const [height, setHeight] = useState(`${window.innerHeight - 48}px`); const [openedSubmenuKey, setOpenedSubmenuKey] = useState(""); const divRef = useRef(null); const ref = useRef(null); const dropDownRef = useRef(null); const scrollElem = useRef(null); const currentPosition = useRef(null); const prevPosition = useRef(null); const buttonBackground = useRef(false); useEffect(() => { setIsOpen(opened); }, [opened]); const setDialogBackground = (scrollHeight: number) => { if (!buttonBackground) { document .getElementsByClassName("section-scroll")[0] .classList.add("dialog-background-scroll"); } if (currentPosition.current && currentPosition.current < scrollHeight / 3) { buttonBackground.current = false; } }; const setButtonBackground = React.useCallback(() => { buttonBackground.current = true; if (scrollElem.current) scrollElem.current.classList.remove("dialog-background-scroll"); }, []); const scrollChangingBackground = React.useCallback(() => { if (scrollElem.current) { currentPosition.current = scrollElem.current.scrollTop; const scrollHeight = scrollElem.current.scrollHeight; if (currentPosition < prevPosition) { setDialogBackground(scrollHeight); } else if ( currentPosition.current && prevPosition.current && currentPosition.current > 0 && currentPosition.current > prevPosition.current ) { setButtonBackground(); } prevPosition.current = currentPosition.current; } }, [setButtonBackground]); useEffect(() => { if (!isIOS) return; scrollElem.current = document.getElementsByClassName( "section-scroll", )[0] as HTMLElement; if (scrollElem.current && scrollElem.current.scrollTop === 0) { scrollElem.current.classList.add("dialog-background-scroll"); } scrollElem.current.addEventListener("scroll", scrollChangingBackground); return () => { if (scrollElem.current) scrollElem.current.removeEventListener( "scroll", scrollChangingBackground, ); }; }, [scrollChangingBackground]); const onAlertClickAction = () => { if (withAlertClick) onAlertClick?.(); }; const recalculateHeight = React.useCallback(() => { if (divRef.current) { const h = divRef?.current?.getBoundingClientRect()?.height || window.innerHeight; if (h >= window.innerHeight) setHeight(`${window.innerHeight - 48}px`); else setHeight(`${h}px`); } }, []); useLayoutEffect(() => { if (divRef.current) { const { height: h } = divRef.current.getBoundingClientRect(); setHeight(`${h}px`); } }, [isOpen]); useLayoutEffect(() => { recalculateHeight(); }, [isOpen, isOpenButton, isUploading, recalculateHeight]); useEffect(() => { window.addEventListener("resize", recalculateHeight); return () => { window.removeEventListener("resize", recalculateHeight); }; }, [recalculateHeight]); const toggle = (value: boolean) => { if (isOpenButton && onClose) { onClose(); } return setIsOpen(value); }; const onMainButtonClick = (e: React.MouseEvent) => { if (!withMenu) { onClick?.(e); return; } toggle(!isOpen); }; const outsideClick = (e: React.MouseEvent) => { const target = e.target as HTMLElement; if (isOpen && ref.current && ref.current.contains(target)) return; toggle(false); }; React.useEffect(() => { if (progressOptions) { const openProgressOptions = progressOptions.filter( (option: ProgressOption) => option.open, ); setIsUploading(openProgressOptions.length > 0); } }, [progressOptions]); const noHover = isMobile; const renderItems = () => { return ( {actionOptions?.map((option: ActionOption) => { const optionOnClickAction = () => { toggle(false); option.onClick?.({ action: option.action }); }; if (option.items) return ( ); return ( ); })} {progressOptions && progressOptions.map((option: ProgressOption) => ( toggle(false)} error={option.error} /> ))} {buttonOptions && ( {buttonOptions.map((option: ButtonOption) => option.isSeparator ? (
) : ( ), )} )} ); }; const children = renderItems(); return ( <>
{isMobile ? ( {children} ) : ( children )} {alert && !isOpen && ( )}
); }; MainButtonMobile.defaultProps = { withMenu: true, }; export { MainButtonMobile };