hooks#useOnClickOutside JavaScript Examples

The following examples show how to use hooks#useOnClickOutside. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From dstack-server with Apache License 2.0 4 votes vote down vote up
Frames = ({frame, frames, headId, onChange, onMarkAsHead, className}: Props) => {
    const {t} = useTranslation();
    const [isShowDropdown, setIsShowDropdown] = useState(false);
    const toggleDropdown = () => setIsShowDropdown(!isShowDropdown);
    const [frameForMarkingAsHead, setFrameForMarkingAsHead] = useState(null);
    const dropdownRef = useRef(null);

    useOnClickOutside(dropdownRef, () => isShowDropdown && toggleDropdown());

    if (!frames.length)
        return null;

    const activeFrame = frames.find(f => f.id === frame);

    const onClickItem = frameId => () => {
        toggleDropdown();

        if (frame !== frameId && onChange)
            onChange(frameId);
    };

    const onClickMarkAsHead = frameId => event => {
        event.stopPropagation();
        setFrameForMarkingAsHead(frameId);
        toggleDropdown();
    };

    const hideConfirmation = () => setFrameForMarkingAsHead(null);

    const confirmMarkFrameAsHead = () => {
        if (onMarkAsHead)
            onMarkAsHead(frameForMarkingAsHead.id);

        setFrameForMarkingAsHead(null);
    };

    if (!activeFrame) {
        return null;
    }

    return (
        <div className={cx(css.frames, className)} ref={dropdownRef}>
            <div
                className={cx(css['frames-dropdown'])}
                ref={dropdownRef}
            >
                <div className={css.button} onClick={toggleDropdown}>
                    <span className={css.name}>
                        {getFrameName(activeFrame)}
                    </span>

                    {headId === activeFrame.id && <span className={css.label}>{t('head')}</span>}
                    <span className="mdi mdi-chevron-down" />
                </div>

                <div className={cx(css.dropdown, {show: isShowDropdown})}>
                    {frames.map(f => (
                        <Tooltip
                            key={f.id}
                            placement="rightTop"
                            trigger={Boolean(f.description) ? ['hover'] : []}
                            align={{offset: [-20, -20]}}
                            onClick={onClickItem(f.id)}
                            overlayContent={f.description}
                        >
                            <div
                                className={css.item}
                            >
                                <span className={css.name}>
                                    {getFrameName(f)}
                                </span>

                                {headId === f.id && <span className={css.label}>{t('head')}</span>}

                                {headId !== f.id && <div
                                    className={css.mark}
                                    onClick={onClickMarkAsHead(f)}
                                >{t('markAsHead')}</div>}
                            </div>
                        </Tooltip>
                    ))}
                </div>
            </div>

            {activeFrame && activeFrame.description && (
                <Tooltip overlayContent={activeFrame.description}>
                    <div className={cx(css.info)}>
                        <span className="mdi mdi-information-variant" />
                    </div>
                </Tooltip>
            )}

            <Modal
                isShow={Boolean(frameForMarkingAsHead)}
                onClose={hideConfirmation}
                size="confirmation"
                title={t('changeHeadRevision')}
                className={css.modal}
            >
                <div className={css.description}>
                    {t(
                        'areYouSureYouWantToChangeTheCurrentHeadRevisionToByName',
                        {frame: frameForMarkingAsHead && getFrameName(frameForMarkingAsHead)},
                    )}
                </div>

                <div className={css.buttons}>
                    <Button
                        variant="contained"
                        color="primary"
                        onClick={confirmMarkFrameAsHead}
                        className={css.button}
                    >{t('yesChangeHead')}</Button>

                    <Button
                        color="secondary"
                        variant="contained"
                        onClick={hideConfirmation}
                        className={css.button}
                    >{t('cancel')}</Button>
                </div>
            </Modal>
        </div>
    );
}
Example #2
Source File: index.js    From dstack-server with Apache License 2.0 4 votes vote down vote up
Sidebar = ({
    className, currentUser, isShow, toggleMenu, userLoading,
    fetchStacksList, startAppProgress, completeAppProgress,
}: Props) => {
    const {t} = useTranslation();
    const {path} = useRouteMatch();
    const params = useParams();
    const {pathname} = useLocation();
    const sidebarRef = useRef(null);

    useOnClickOutside(sidebarRef, () => isShow && toggleMenu());

    const getMenuItemClick = item => () => {
        if (isShow)
            toggleMenu();

        if (item.onClick)
            item.onClick();
    };

    const refreshStacks = () => {
        if (pathname === routes.stacks(params.user)) {
            startAppProgress();
            fetchStacksList(params.user, completeAppProgress);
        }
    };

    const menuItems = [
        {
            to: routes.stacks(currentUser),
            label: t('stacks'),

            isActive: () => (
                new RegExp(path).test(routes.stacks())
                && (!currentUser || (currentUser === params.user))
                && !new RegExp(path + '$').test(routes.dashboards())
            ),

            onClick: refreshStacks,
        },

        {
            to: routes.dashboards(currentUser),
            label: t('dashboards'),
        },

        {
            to: routes.settings(),
            label: t('settings'),
        },
    ];

    return <div className={cx(css.sidebar, className, {show: isShow})} ref={sidebarRef}>
        <div className={cx(css.close, 'mdi mdi-close')} onClick={toggleMenu} />

        <div className={css.logo}>
            <Link to="/">
                <img width="129" height="35" src={logo} alt="logo"/>
            </Link>
        </div>

        {isSignedIn() && !userLoading && <ul className={css.links}>
            {menuItems.map((item, index) => (
                <li key={index} className={css.item}>
                    <NavLink
                        onClick={getMenuItemClick(item)}
                        to={item.to}
                        activeClassName="active"
                        isActive={item.isActive}
                    >
                        <span className={css.label}>{item.label}</span>

                        {item.beta && <sub className={cx(css.sub, 'green-text')}>
                            {t('beta')}
                        </sub>}
                    </NavLink>
                </li>
            ))}

            <li className={css.item}>
                <a
                    href={config.DOCS_URL}
                    target="_blank"
                >
                    <span className={css.label}>{t('docs')}</span>
                </a>
            </li>
        </ul>}
    </div>;
}